diff --git a/code/__defines/items_clothing.dm b/code/__defines/items_clothing.dm index 8cb0d04bab..8f67815583 100644 --- a/code/__defines/items_clothing.dm +++ b/code/__defines/items_clothing.dm @@ -80,29 +80,34 @@ #define BLOCKHEADHAIR 0x20 // Hides the user's hair overlay. Leaves facial hair. #define BLOCKHAIR 0x40 // Hides the user's hair, facial and otherwise. -// Slots. -#define slot_back 1 -#define slot_wear_mask 2 -#define slot_handcuffed 3 -#define slot_l_hand 4 -#define slot_r_hand 5 -#define slot_belt 6 -#define slot_wear_id 7 -#define slot_l_ear 8 -#define slot_glasses 9 +// Slots as numbers // +//Hands +#define slot_l_hand 1 +#define slot_r_hand 2 //Some things may reference this, try to keep it here +//Shown unless F12 pressed +#define slot_back 3 +#define slot_belt 4 +#define slot_wear_id 5 +#define slot_l_store 6 +#define slot_r_store 7 //Some things may reference this, try to keep it here +//Shown when inventory unhidden +#define slot_glasses 8 +#define slot_wear_mask 9 #define slot_gloves 10 #define slot_head 11 #define slot_shoes 12 #define slot_wear_suit 13 #define slot_w_uniform 14 -#define slot_l_store 15 -#define slot_r_store 16 -#define slot_s_store 17 -#define slot_in_backpack 18 -#define slot_legcuffed 19 -#define slot_r_ear 20 -#define slot_legs 21 -#define slot_tie 22 +#define slot_s_store 15 +#define slot_l_ear 16 +#define slot_r_ear 17 +//Secret slots +#define slot_legs 18 +#define slot_tie 19 +#define slot_handcuffed 20 +#define slot_legcuffed 21 +#define slot_in_backpack 22 +#define SLOT_TOTAL 22 // Inventory slot strings. // since numbers cannot be used as associative list keys. @@ -120,7 +125,7 @@ #define slot_head_str "slot_head" #define slot_wear_mask_str "slot_wear_mask" #define slot_handcuffed_str "slot_handcuffed" -#define slot_legcuffed_str "slot_legcuffed" +#define slot_legcuffed_str "slot_legcuffed" #define slot_wear_mask_str "slot_wear_mask" #define slot_wear_id_str "slot_wear_id" #define slot_gloves_str "slot_gloves" diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm index 6b162504b9..7a4563f6db 100644 --- a/code/__defines/mobs.dm +++ b/code/__defines/mobs.dm @@ -98,9 +98,17 @@ #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_SUIT_DEF_ICON 'icons/mob/ties.dmi' +#define INV_TIE_DEF_ICON 'icons/mob/ties.dmi' #define INV_SUIT_DEF_ICON 'icons/mob/suit.dmi' -#define MAX_SUPPLIED_LAW_NUMBER 50 +#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" @@ -255,4 +263,7 @@ #define VIS_MESONS 20 -#define VIS_COUNT 20 //Must be highest number from above. \ No newline at end of file +#define VIS_COUNT 20 //Must be highest number from above. + +//Some mob icon layering defines +#define BODY_LAYER -100 diff --git a/code/_helpers/icons.dm b/code/_helpers/icons.dm index 64460aa889..da4385ef6f 100644 --- a/code/_helpers/icons.dm +++ b/code/_helpers/icons.dm @@ -634,175 +634,211 @@ as a single icon. Useful for when you want to manipulate an icon via the above a The _flatIcons list is a cache for generated icon files. */ -proc // Creates a single icon from a given /atom or /image. Only the first argument is required. - getFlatIcon(image/A, defdir=2, deficon=null, defstate="", defblend=BLEND_DEFAULT, always_use_defdir = 0, picture_planes = list(PLANE_WORLD)) - // We start with a blank canvas, otherwise some icon procs crash silently - var/icon/flat = icon('icons/effects/effects.dmi', "icon_state"="nothing") // Final flattened icon - if(!A) - return flat - if(A.alpha <= 0) - return flat - var/noIcon = FALSE +// Creates a single icon from a given /atom or /image. Only the first argument is required. +/proc/getFlatIcon(image/A, defdir, deficon, defstate, defblend, start = TRUE, no_anim = FALSE) + // We start with a blank canvas, otherwise some icon procs crash silently + var/icon/flat = icon('icons/effects/effects.dmi', "nothing") // Final flattened icon + if(!A) + return flat + if(A.alpha <= 0) + return flat + var/noIcon = FALSE - var/curicon - if(A.icon) - curicon = A.icon + if(start) + if(!defdir) + defdir = A.dir + if(!deficon) + deficon = A.icon + if(!defstate) + defstate = A.icon_state + if(!defblend) + defblend = A.blend_mode + + var/curicon + if(A.icon) + curicon = A.icon + else + curicon = deficon + + if(!curicon) + noIcon = TRUE // Do not render this object. + + var/curstate + if(A.icon_state) + curstate = A.icon_state + else + curstate = defstate + + if(!noIcon && !(curstate in icon_states(curicon))) + if("" in icon_states(curicon)) + curstate = "" else - curicon = deficon - - if(!curicon) noIcon = TRUE // Do not render this object. - var/curstate - if(A.icon_state) - curstate = A.icon_state - else - curstate = defstate + var/curdir + var/base_icon_dir //We'll use this to get the icon state to display if not null BUT NOT pass it to overlays as the dir we have + + //These should use the parent's direction (most likely) + if(!A.dir || A.dir == SOUTH) + curdir = defdir + else + curdir = A.dir - if(!noIcon && !(curstate in icon_states(curicon))) - if("" in icon_states(curicon)) - curstate = "" - else - noIcon = TRUE // Do not render this object. + //Let's check if the icon actually contains any diagonals, just skip if it's south to save (lot of) time + if(curdir != SOUTH) + var/icon/test_icon + var/directionals_exist = FALSE + var/list/dirs_to_check = cardinal - SOUTH + outer: + for(var/possible_dir in dirs_to_check) + test_icon = icon(curicon,curstate,possible_dir,frame=1) + for(var/x in 1 to world.icon_size) + for(var/y in 1 to world.icon_size) + if(!isnull(test_icon.GetPixel(x,y))) + directionals_exist = TRUE + break outer + if(!directionals_exist) + base_icon_dir = SOUTH + if(!base_icon_dir) + base_icon_dir = curdir - var/curdir - if(A.dir != 2 && !always_use_defdir) - curdir = A.dir - else - curdir = defdir + var/curblend + if(A.blend_mode == BLEND_DEFAULT) + curblend = defblend + else + curblend = A.blend_mode - var/curblend - if(A.blend_mode == BLEND_DEFAULT) - curblend = defblend - else - curblend = A.blend_mode + // Before processing overlays, make sure any pending overlays are applied + if (isloc(A)) + var/atom/aAtom = A + if(aAtom.flags & OVERLAY_QUEUED) + COMPILE_OVERLAYS(aAtom) - // Layers will be a sorted list of icons/overlays, based on the order in which they are displayed - var/list/layers = list() - var/image/copy - // Add the atom's icon itself, without pixel_x/y offsets. - if(!noIcon) - copy = image(icon=curicon, icon_state=curstate, layer=A.layer, dir=curdir) - copy.color = A.color - copy.alpha = A.alpha - copy.blend_mode = curblend - layers[copy] = A.layer - - // Loop through the underlays, then overlays, sorting them into the layers list - var/list/process = A.underlays // Current list being processed - var/pSet=0 // Which list is being processed: 0 = underlays, 1 = overlays - var/curIndex=1 // index of 'current' in list being processed - var/current // Current overlay being sorted - var/currentLayer // Calculated layer that overlay appears on (special case for FLOAT_LAYER) - var/compare // The overlay 'add' is being compared against - var/cmpIndex // The index in the layers list of 'compare' - while(TRUE) - if(curIndex<=process.len) - current = process[curIndex] - if(current) - var/currentPlane = current:plane - if (currentPlane != FLOAT_PLANE && !(currentPlane in picture_planes)) - curIndex++ - continue; - currentLayer = current:layer - if(currentLayer<0) // Special case for FLY_LAYER - if(currentLayer <= -1000) return flat - if(pSet == 0) // Underlay - currentLayer = A.layer+currentLayer/1000 - else // Overlay - currentLayer = A.layer+(1000+currentLayer)/1000 - - // Sort add into layers list - for(cmpIndex=1,cmpIndex<=layers.len,cmpIndex++) - compare = layers[cmpIndex] - if(currentLayer < layers[compare]) // Associated value is the calculated layer - layers.Insert(cmpIndex,current) - layers[current] = currentLayer - break - if(cmpIndex>layers.len) // Reached end of list without inserting - layers[current]=currentLayer // Place at end + // Layers will be a sorted list of icons/overlays, based on the order in which they are displayed + var/list/layers = list() + var/image/copy + // Add the atom's icon itself, without pixel_x/y offsets. + if(!noIcon) + copy = image(icon=curicon, icon_state=curstate, layer=A.layer, dir=base_icon_dir) + copy.color = A.color + copy.alpha = A.alpha + copy.blend_mode = curblend + layers[copy] = A.layer + // Loop through the underlays, then overlays, sorting them into the layers list + var/list/process = A.underlays // Current list being processed + var/pSet=0 // Which list is being processed: 0 = underlays, 1 = overlays + var/curIndex=1 // index of 'current' in list being processed + var/current // Current overlay being sorted + var/currentLayer // Calculated layer that overlay appears on (special case for FLOAT_LAYER) + var/compare // The overlay 'add' is being compared against + var/cmpIndex // The index in the layers list of 'compare' + while(TRUE) + if(curIndex<=process.len) + current = process[curIndex] + if(!current) + curIndex++ //Try the next layer + continue + var/image/I = current + if(I.plane != FLOAT_PLANE && I.plane != A.plane) curIndex++ - else if(pSet == 0) // Switch to overlays + continue + currentLayer = I.layer + if(currentLayer<0) // Special case for FLOAT_LAYER + if(currentLayer <= -1000) + return flat + if(pSet == 0) // Underlay + currentLayer = A.layer+currentLayer/1000 + else // Overlay + currentLayer = A.layer+(1000+currentLayer)/1000 + + // Sort add into layers list + for(cmpIndex=1,cmpIndex<=layers.len,cmpIndex++) + compare = layers[cmpIndex] + if(currentLayer < layers[compare]) // Associated value is the calculated layer + layers.Insert(cmpIndex,current) + layers[current] = currentLayer + break + if(cmpIndex>layers.len) // Reached end of list without inserting + layers[current]=currentLayer // Place at end + + curIndex++ + + if(curIndex>process.len) + if(pSet == 0) // Switch to overlays curIndex = 1 pSet = 1 process = A.overlays else // All done break - var/icon/add // Icon of overlay being added + var/icon/add // Icon of overlay being added - // Current dimensions of flattened icon - var/{flatX1=1;flatX2=flat.Width();flatY1=1;flatY2=flat.Height()} - // Dimensions of overlay being added - var/{addX1;addX2;addY1;addY2} + // Current dimensions of flattened icon + var/flatX1=1 + var/flatX2=flat.Width() + var/flatY1=1 + var/flatY2=flat.Height() + // Dimensions of overlay being added + var/addX1 + var/addX2 + var/addY1 + var/addY2 - for(var/I in layers) + for(var/V in layers) + var/image/I = V + if(I.alpha == 0) + continue - if(I:alpha == 0) - continue + if(I == copy) // 'I' is an /image based on the object being flattened. + curblend = BLEND_OVERLAY + add = icon(I.icon, I.icon_state, base_icon_dir) + else // 'I' is an appearance object. + add = getFlatIcon(new/image(I), curdir, curicon, curstate, curblend, FALSE, no_anim) - if(I == copy) // 'I' is an /image based on the object being flattened. - curblend = BLEND_OVERLAY - add = icon(I:icon, I:icon_state, I:dir) - // This checks for a silent failure mode of the icon routine. If the requested dir - // doesn't exist in this icon state it returns a 32x32 icon with 0 alpha. - if (I:dir != SOUTH && add.Width() == 32 && add.Height() == 32) - // Check every pixel for blank (computationally expensive, but the process is limited - // by the amount of film on the station, only happens when we hit something that's - // turned, and bails at the very first pixel it sees. - var/blankpixel; - for(var/y;y<=32;y++) - for(var/x;x<32;x++) - blankpixel = isnull(add.GetPixel(x,y)) - if(!blankpixel) - break - if(!blankpixel) - break - // If we ALWAYS returned a null (which happens when GetPixel encounters something with alpha 0) - if (blankpixel) - // Pull the default direction. - add = icon(I:icon, I:icon_state) - else // 'I' is an appearance object. - add = getFlatIcon(new/image(I), curdir, curicon, curstate, curblend, picture_planes = picture_planes) + // Find the new dimensions of the flat icon to fit the added overlay + addX1 = min(flatX1, I.pixel_x+1) + addX2 = max(flatX2, I.pixel_x+add.Width()) + addY1 = min(flatY1, I.pixel_y+1) + addY2 = max(flatY2, I.pixel_y+add.Height()) - // Find the new dimensions of the flat icon to fit the added overlay - addX1 = min(flatX1, I:pixel_x+1) - addX2 = max(flatX2, I:pixel_x+add.Width()) - addY1 = min(flatY1, I:pixel_y+1) - addY2 = max(flatY2, I:pixel_y+add.Height()) + if(addX1!=flatX1 || addX2!=flatX2 || addY1!=flatY1 || addY2!=flatY2) + // Resize the flattened icon so the new icon fits + flat.Crop(addX1-flatX1+1, addY1-flatY1+1, addX2-flatX1+1, addY2-flatY1+1) + flatX1=addX1;flatX2=addX2 + flatY1=addY1;flatY2=addY2 - if(addX1!=flatX1 || addX2!=flatX2 || addY1!=flatY1 || addY2!=flatY2) - // Resize the flattened icon so the new icon fits - flat.Crop(addX1-flatX1+1, addY1-flatY1+1, addX2-flatX1+1, addY2-flatY1+1) - flatX1=addX1;flatX2=addX2 - flatY1=addY1;flatY2=addY2 + // Blend the overlay into the flattened icon + flat.Blend(add, blendMode2iconMode(curblend), I.pixel_x + 2 - flatX1, I.pixel_y + 2 - flatY1) - // Blend the overlay into the flattened icon - flat.Blend(add, blendMode2iconMode(curblend), I:pixel_x + 2 - flatX1, I:pixel_y + 2 - flatY1) - - if(A.color) - flat.Blend(A.color, ICON_MULTIPLY) - if(A.alpha < 255) - flat.Blend(rgb(255, 255, 255, A.alpha), ICON_MULTIPLY) + if(A.color) + flat.Blend(A.color, ICON_MULTIPLY) + if(A.alpha < 255) + flat.Blend(rgb(255, 255, 255, A.alpha), ICON_MULTIPLY) + if(no_anim) + //Clean up repeated frames + var/icon/cleaned = new /icon() + cleaned.Insert(flat, "", SOUTH, 1, 0) + return cleaned + else return icon(flat, "", SOUTH) - getIconMask(atom/A)//By yours truly. Creates a dynamic mask for a mob/whatever. /N - var/icon/alpha_mask = new(A.icon,A.icon_state)//So we want the default icon and icon state of A. - for(var/I in A.overlays)//For every image in overlays. var/image/I will not work, don't try it. - if(I:layer>A.layer) continue//If layer is greater than what we need, skip it. - var/icon/image_overlay = new(I:icon,I:icon_state)//Blend only works with icon objects. - //Also, icons cannot directly set icon_state. Slower than changing variables but whatever. - alpha_mask.Blend(image_overlay,ICON_OR)//OR so they are lumped together in a nice overlay. - return alpha_mask//And now return the mask. +/proc/getIconMask(atom/A)//By yours truly. Creates a dynamic mask for a mob/whatever. /N + var/icon/alpha_mask = new(A.icon,A.icon_state)//So we want the default icon and icon state of A. + for(var/I in A.overlays)//For every image in overlays. var/image/I will not work, don't try it. + if(I:layer>A.layer) continue//If layer is greater than what we need, skip it. + var/icon/image_overlay = new(I:icon,I:icon_state)//Blend only works with icon objects. + //Also, icons cannot directly set icon_state. Slower than changing variables but whatever. + alpha_mask.Blend(image_overlay,ICON_OR)//OR so they are lumped together in a nice overlay. + return alpha_mask//And now return the mask. //getFlatIcon but generates an icon that can face ALL four directions. The only four. /proc/getCompoundIcon(atom/A) - var/icon/north = getFlatIcon(A,defdir=NORTH,always_use_defdir=1) - var/icon/south = getFlatIcon(A,defdir=SOUTH,always_use_defdir=1) - var/icon/east = getFlatIcon(A,defdir=EAST,always_use_defdir=1) - var/icon/west = getFlatIcon(A,defdir=WEST,always_use_defdir=1) + var/icon/north = getFlatIcon(A,defdir=NORTH) + var/icon/south = getFlatIcon(A,defdir=SOUTH) + var/icon/east = getFlatIcon(A,defdir=EAST) + var/icon/west = getFlatIcon(A,defdir=WEST) //Starts with a blank icon because of byond bugs. var/icon/full = icon('icons/effects/effects.dmi', "icon_state"="nothing") @@ -818,7 +854,7 @@ proc // Creates a single icon from a given /atom or /image. Only the first argu return full /proc/downloadImage(atom/A, dir) - var/icon/this_icon = getFlatIcon(A,defdir=dir||A.dir,always_use_defdir=1) + var/icon/this_icon = getFlatIcon(A,defdir=dir) usr << ftp(this_icon,"[A.name].png") @@ -886,7 +922,8 @@ proc/sort_atoms_by_layer(var/list/atoms) /proc/gen_hud_image(var/file, var/person, var/state, var/plane) var/image/img = image(file, person, state) img.plane = plane //Thanks Byond. - img.appearance_flags = APPEARANCE_UI|KEEP_APART + img.layer = MOB_LAYER-0.2 + img.appearance_flags = APPEARANCE_UI return img /** diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index 786c7cdd04..3a251f71fa 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -164,6 +164,7 @@ var/list/global_huds = list( var/obj/screen/movable/action_button/hide_toggle/hide_actions_toggle var/action_buttons_hidden = 0 + var/list/slot_info datum/hud/New(mob/owner) mymob = owner diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index e1b141ecb7..1c903700b0 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -14,6 +14,7 @@ src.adding = list() src.other = list() src.hotkeybuttons = list() //These can be disabled for hotkey users + src.slot_info = list() var/list/hud_elements = list() var/obj/screen/using @@ -33,6 +34,7 @@ inv_box.screen_loc = slot_data["loc"] inv_box.slot_id = slot_data["slot"] inv_box.icon_state = slot_data["state"] + slot_info["[inv_box.slot_id]"] = inv_box.screen_loc if(slot_data["dir"]) inv_box.set_dir(slot_data["dir"]) @@ -164,9 +166,9 @@ inv_box.slot_id = slot_r_hand inv_box.color = ui_color inv_box.alpha = ui_alpha - src.r_hand_hud_object = inv_box src.adding += inv_box + slot_info["[slot_r_hand]"] = inv_box.screen_loc inv_box = new /obj/screen/inventory/hand() inv_box.hud = src @@ -181,6 +183,7 @@ inv_box.alpha = ui_alpha src.l_hand_hud_object = inv_box src.adding += inv_box + slot_info["[slot_l_hand]"] = inv_box.screen_loc using = new /obj/screen/inventory() using.name = "hand" diff --git a/code/controllers/subsystems/overlays.dm b/code/controllers/subsystems/overlays.dm index 352102e175..052cb96cba 100644 --- a/code/controllers/subsystems/overlays.dm +++ b/code/controllers/subsystems/overlays.dm @@ -11,6 +11,8 @@ SUBSYSTEM_DEF(overlays) var/list/overlay_icon_state_caches // Cache thing var/list/overlay_icon_cache // Cache thing +var/global/image/stringbro = new() // Temporarily super-global because of BYOND init order dumbness. +var/global/image/iconbro = new() // Temporarily super-global because of BYOND init order dumbness. var/global/image/appearance_bro = new() // Temporarily super-global because of BYOND init order dumbness. /datum/controller/subsystem/overlays/PreInit() @@ -66,7 +68,7 @@ var/global/image/appearance_bro = new() // Temporarily super-global because of B count = 0 /proc/iconstate2appearance(icon, iconstate) - var/static/image/stringbro = new() + // var/static/image/stringbro = new() // Moved to be superglobal due to BYOND insane init order stupidness. var/list/icon_states_cache = SSoverlays.overlay_icon_state_caches var/list/cached_icon = icon_states_cache[icon] if (cached_icon) @@ -83,7 +85,7 @@ var/global/image/appearance_bro = new() // Temporarily super-global because of B return cached_appearance /proc/icon2appearance(icon) - var/static/image/iconbro = new() + // var/static/image/iconbro = new() // Moved to be superglobal due to BYOND insane init order stupidness. var/list/icon_cache = SSoverlays.overlay_icon_cache . = icon_cache[icon] if (!.) diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index 274c0c0903..a9b6249cc3 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -425,8 +425,8 @@ var/icon/front var/icon/side if(H) - front = getFlatIcon(H, SOUTH, always_use_defdir = 1) - side = getFlatIcon(H, WEST, always_use_defdir = 1) + front = getFlatIcon(H, SOUTH) + side = getFlatIcon(H, WEST) else var/mob/living/carbon/human/dummy = new() front = new(get_id_photo(dummy), dir = SOUTH) diff --git a/code/datums/underwear/underwear.dm b/code/datums/underwear/underwear.dm index bac96bf55c..f418f3e8d1 100644 --- a/code/datums/underwear/underwear.dm +++ b/code/datums/underwear/underwear.dm @@ -63,11 +63,11 @@ datum/category_group/underwear/dd_SortValue() /datum/category_item/underwear/proc/is_default(var/gender) return is_default -/datum/category_item/underwear/proc/generate_image(var/list/metadata) +/datum/category_item/underwear/proc/generate_image(var/list/metadata, var/layer = FLOAT_LAYER) if(!icon_state) return - var/image/I = image(icon = icon, icon_state = icon_state) + var/image/I = image(icon = icon, icon_state = icon_state, layer = layer) for(var/datum/gear_tweak/gt in tweaks) gt.tweak_item(I, metadata && metadata["[gt]"] ? metadata["[gt]"] : gt.get_default()) return I \ No newline at end of file diff --git a/code/game/antagonist/outsider/mercenary.dm b/code/game/antagonist/outsider/mercenary.dm index 157d590b78..94b362fca8 100644 --- a/code/game/antagonist/outsider/mercenary.dm +++ b/code/game/antagonist/outsider/mercenary.dm @@ -50,8 +50,6 @@ var/datum/antagonist/mercenary/mercs var/obj/item/device/radio/uplink/U = new(player.loc, player.mind, DEFAULT_TELECRYSTAL_AMOUNT) player.put_in_hands(U) - player.update_icons_layers() - create_id("Mercenary", player) create_radio(SYND_FREQ, player) return 1 diff --git a/code/game/antagonist/outsider/technomancer.dm b/code/game/antagonist/outsider/technomancer.dm index 33dc33b5e8..2cb7532308 100644 --- a/code/game/antagonist/outsider/technomancer.dm +++ b/code/game/antagonist/outsider/technomancer.dm @@ -47,7 +47,6 @@ var/datum/antagonist/technomancer/technomancers technomancer_mob.equip_to_slot_or_del(new /obj/item/device/flashlight(technomancer_mob), slot_belt) technomancer_mob.equip_to_slot_or_del(new /obj/item/clothing/shoes/laceup(technomancer_mob), slot_shoes) technomancer_mob.equip_to_slot_or_del(new /obj/item/clothing/head/technomancer/master(technomancer_mob), slot_head) - technomancer_mob.update_icons_layers() return 1 /datum/antagonist/technomancer/proc/equip_apprentice(var/mob/living/carbon/human/technomancer_mob) @@ -67,7 +66,6 @@ var/datum/antagonist/technomancer/technomancers technomancer_mob.equip_to_slot_or_del(new /obj/item/device/flashlight(technomancer_mob), slot_belt) technomancer_mob.equip_to_slot_or_del(new /obj/item/clothing/shoes/laceup(technomancer_mob), slot_shoes) technomancer_mob.equip_to_slot_or_del(new /obj/item/clothing/head/technomancer/apprentice(technomancer_mob), slot_head) - technomancer_mob.update_icons() return 1 /datum/antagonist/technomancer/check_victory() diff --git a/code/game/antagonist/outsider/wizard.dm b/code/game/antagonist/outsider/wizard.dm index ad5cc10479..feaf8857ba 100644 --- a/code/game/antagonist/outsider/wizard.dm +++ b/code/game/antagonist/outsider/wizard.dm @@ -87,7 +87,6 @@ var/datum/antagonist/wizard/wizards wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/box(wizard_mob), slot_in_backpack) wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/teleportation_scroll(wizard_mob), slot_r_store) wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/spellbook(wizard_mob), slot_r_hand) - wizard_mob.update_icons_layers() return 1 /datum/antagonist/wizard/check_victory() diff --git a/code/game/gamemodes/changeling/generic_equip_procs.dm b/code/game/gamemodes/changeling/generic_equip_procs.dm index 7ff76ff9f6..ef1ab650a1 100644 --- a/code/game/gamemodes/changeling/generic_equip_procs.dm +++ b/code/game/gamemodes/changeling/generic_equip_procs.dm @@ -122,7 +122,6 @@ playsound(src, 'sound/effects/splat.ogg', 30, 1) visible_message("[src] pulls on their clothes, peeling it off along with parts of their skin attached!", "We remove and deform our equipment.") - M.update_icons_layers() M.mind.changeling.armor_deployed = 0 return success @@ -138,7 +137,6 @@ M.equip_to_slot_or_del(I, slot_head) grown_items_list.Add("a helmet") playsound(src, 'sound/effects/blobattack.ogg', 30, 1) - M.update_icons_layers() success = 1 sleep(1 SECOND) @@ -148,7 +146,6 @@ M.equip_to_slot_or_del(I, slot_w_uniform) grown_items_list.Add("a uniform") playsound(src, 'sound/effects/blobattack.ogg', 30, 1) - M.update_icons_layers() success = 1 sleep(1 SECOND) @@ -158,7 +155,6 @@ M.equip_to_slot_or_del(I, slot_gloves) grown_items_list.Add("some gloves") playsound(src, 'sound/effects/splat.ogg', 30, 1) - M.update_icons_layers() success = 1 sleep(1 SECOND) @@ -168,7 +164,6 @@ M.equip_to_slot_or_del(I, slot_shoes) grown_items_list.Add("shoes") playsound(src, 'sound/effects/splat.ogg', 30, 1) - M.update_icons_layers() success = 1 sleep(1 SECOND) @@ -178,7 +173,6 @@ M.equip_to_slot_or_del(I, slot_belt) grown_items_list.Add("a belt") playsound(src, 'sound/effects/splat.ogg', 30, 1) - M.update_icons_layers() success = 1 sleep(1 SECOND) @@ -188,7 +182,6 @@ M.equip_to_slot_or_del(I, slot_glasses) grown_items_list.Add("some glasses") playsound(src, 'sound/effects/splat.ogg', 30, 1) - M.update_icons_layers() success = 1 sleep(1 SECOND) @@ -198,7 +191,6 @@ M.equip_to_slot_or_del(I, slot_wear_mask) grown_items_list.Add("a mask") playsound(src, 'sound/effects/splat.ogg', 30, 1) - M.update_icons_layers() success = 1 sleep(1 SECOND) @@ -208,7 +200,6 @@ M.equip_to_slot_or_del(I, slot_back) grown_items_list.Add("a backpack") playsound(src, 'sound/effects/blobattack.ogg', 30, 1) - M.update_icons_layers() success = 1 sleep(1 SECOND) @@ -218,7 +209,6 @@ M.equip_to_slot_or_del(I, slot_wear_suit) grown_items_list.Add("an exosuit") playsound(src, 'sound/effects/blobattack.ogg', 30, 1) - M.update_icons_layers() success = 1 sleep(1 SECOND) @@ -228,20 +218,13 @@ M.equip_to_slot_or_del(I, slot_wear_id) grown_items_list.Add("an ID card") playsound(src, 'sound/effects/splat.ogg', 30, 1) - M.update_icons_layers() success = 1 sleep(1 SECOND) var/feedback = english_list(grown_items_list, nothing_text = "nothing", and_text = " and ", comma_text = ", ", final_comma_text = "" ) M << "We have grown [feedback]." - /* - for(var/I in stuff_to_equip) - world << I - world << stuff_to_equip - world << "Proc ended." - */ - M.update_icons() + if(success) M.mind.changeling.armor_deployed = 1 M.mind.changeling.chem_charges -= 10 diff --git a/code/game/gamemodes/changeling/powers/fabricate_clothing.dm b/code/game/gamemodes/changeling/powers/fabricate_clothing.dm index aad702ea49..d79af62b4c 100644 --- a/code/game/gamemodes/changeling/powers/fabricate_clothing.dm +++ b/code/game/gamemodes/changeling/powers/fabricate_clothing.dm @@ -56,7 +56,6 @@ var/global/list/changeling_fabricated_clothing = list( visible_message("[H] tears off [src]!", "We remove [src].") qdel(src) - H.update_icons_layers() /obj/item/clothing/head/chameleon/changeling name = "malformed head" @@ -78,7 +77,6 @@ var/global/list/changeling_fabricated_clothing = list( visible_message("[H] tears off [src]!", "We remove [src].") qdel(src) - H.update_icons_layers() /obj/item/clothing/suit/chameleon/changeling name = "chitinous chest" @@ -104,7 +102,6 @@ var/global/list/changeling_fabricated_clothing = list( visible_message("[H] tears off [src]!", "We remove [src].") qdel(src) - H.update_icons_layers() /obj/item/clothing/shoes/chameleon/changeling name = "malformed feet" @@ -130,7 +127,6 @@ var/global/list/changeling_fabricated_clothing = list( visible_message("[H] tears off [src]!", "We remove [src].") qdel(src) - H.update_icons_layers() /obj/item/weapon/storage/backpack/chameleon/changeling name = "backpack" @@ -158,7 +154,6 @@ var/global/list/changeling_fabricated_clothing = list( for(var/atom/movable/AM in src.contents) //Dump whatever's in the bag before deleting. AM.forceMove(get_turf(loc)) qdel(src) - H.update_icons_layers() /obj/item/clothing/gloves/chameleon/changeling name = "malformed hands" @@ -185,8 +180,6 @@ var/global/list/changeling_fabricated_clothing = list( visible_message("[H] tears off [src]!", "We remove [src].") qdel(src) - H.update_icons_layers() - /obj/item/clothing/mask/chameleon/changeling name = "chitin visor" @@ -213,7 +206,6 @@ var/global/list/changeling_fabricated_clothing = list( visible_message("[H] tears off [src]!", "We remove [src].") qdel(src) - H.update_icons_layers() /obj/item/clothing/glasses/chameleon/changeling name = "chitin goggles" @@ -235,7 +227,6 @@ var/global/list/changeling_fabricated_clothing = list( visible_message("[H] tears off [src]!", "We remove [src].") qdel(src) - H.update_icons_layers() /obj/item/weapon/storage/belt/chameleon/changeling name = "waist pouch" @@ -261,7 +252,6 @@ var/global/list/changeling_fabricated_clothing = list( visible_message("[H] tears off [src]!", "We remove [src].") qdel(src) - H.update_icons_layers() /obj/item/weapon/card/id/syndicate/changeling name = "chitinous card" @@ -291,8 +281,6 @@ var/global/list/changeling_fabricated_clothing = list( visible_message("[H] tears off [src]!", "We remove [src].") qdel(src) - H.update_icons_layers() - /obj/item/weapon/card/id/syndicate/changeling/Click() //Since we can't hold it in our hands, and attack_hand() doesn't work if it in inventory... if(!registered_user) diff --git a/code/game/machinery/computer3/computers/HolodeckControl.dm b/code/game/machinery/computer3/computers/HolodeckControl.dm index 4d63b95673..a629354d7b 100644 --- a/code/game/machinery/computer3/computers/HolodeckControl.dm +++ b/code/game/machinery/computer3/computers/HolodeckControl.dm @@ -155,7 +155,6 @@ var/mob/M = obj.loc if(ismob(M)) M.remove_from_mob(obj) - M.update_icons_layers() //so their overlays update if(!silent) var/obj/oldobj = obj diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index a24676156e..18700ec8bc 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -982,7 +982,9 @@ if(suit) suit.name = "engineering voidsuit" suit.icon_state = "rig-engineering" - suit.item_state = "eng_voidsuit" + suit.item_state = "rig-engineering" + suit.item_state_slots[slot_r_hand_str] = "eng_voidsuit" + suit.item_state_slots[slot_l_hand_str] = "eng_voidsuit" if("Mining") if(helmet) helmet.name = "mining voidsuit helmet" @@ -991,7 +993,9 @@ if(suit) suit.name = "mining voidsuit" suit.icon_state = "rig-mining" - suit.item_state = "mining_voidsuit" + suit.item_state = "rig-mining" + suit.item_state_slots[slot_r_hand_str] = "mining_voidsuit" + suit.item_state_slots[slot_l_hand_str] = "mining_voidsuit" if("Medical") if(helmet) helmet.name = "medical voidsuit helmet" @@ -1000,7 +1004,9 @@ if(suit) suit.name = "medical voidsuit" suit.icon_state = "rig-medical" - suit.item_state = "medical_voidsuit" + suit.item_state = "rig-medical" + suit.item_state_slots[slot_r_hand_str] = "medical_voidsuit" + suit.item_state_slots[slot_l_hand_str] = "medical_voidsuit" if("Security") if(helmet) helmet.name = "security voidsuit helmet" @@ -1009,7 +1015,9 @@ if(suit) suit.name = "security voidsuit" suit.icon_state = "rig-sec" - suit.item_state = "sec_voidsuit" + suit.item_state = "rig-sec" + suit.item_state_slots[slot_r_hand_str] = "sec_voidsuit" + suit.item_state_slots[slot_l_hand_str] = "sec_voidsuit" if("Crowd Control") if(helmet) helmet.name = "crowd control voidsuit helmet" @@ -1018,7 +1026,9 @@ if(suit) suit.name = "crowd control voidsuit" suit.icon_state = "rig-sec_riot" - suit.item_state = "sec_voidsuit_riot" + suit.item_state = "rig-sec_riot" + suit.item_state_slots[slot_r_hand_str] = "sec_voidsuit_riot" + suit.item_state_slots[slot_l_hand_str] = "sec_voidsuit_riot" if("Atmos") if(helmet) helmet.name = "atmospherics voidsuit helmet" @@ -1027,7 +1037,9 @@ if(suit) suit.name = "atmospherics voidsuit" suit.icon_state = "rig-atmos" - suit.item_state = "atmos_voidsuit" + suit.item_state = "rig-atmos" + suit.item_state_slots[slot_r_hand_str] = "atmos_voidsuit" + suit.item_state_slots[slot_l_hand_str] = "atmos_voidsuit" if("HAZMAT") if(helmet) helmet.name = "HAZMAT voidsuit helmet" @@ -1036,7 +1048,9 @@ if(suit) suit.name = "HAZMAT voidsuit" suit.icon_state = "rig-engineering_rad" - suit.item_state = "eng_voidsuit_rad" + suit.item_state = "rig-engineering_rad" + suit.item_state_slots[slot_r_hand_str] = "eng_voidsuit_rad" + suit.item_state_slots[slot_l_hand_str] = "eng_voidsuit_rad" if("Construction") if(helmet) helmet.name = "Construction voidsuit helmet" @@ -1045,7 +1059,9 @@ if(suit) suit.name = "Construction voidsuit" suit.icon_state = "rig-engineering_con" - suit.item_state = "eng_voidsuit_con" + suit.item_state = "rig-engineering_con" + suit.item_state_slots[slot_r_hand_str] = "eng_voidsuit_con" + suit.item_state_slots[slot_l_hand_str] = "eng_voidsuit_con" if("Biohazard") if(helmet) helmet.name = "Biohazard voidsuit helmet" @@ -1054,7 +1070,9 @@ if(suit) suit.name = "Biohazard voidsuit" suit.icon_state = "rig-medical_bio" - suit.item_state = "medical_voidsuit_bio" + suit.item_state = "rig-medical_bio" + suit.item_state_slots[slot_r_hand_str] = "medical_voidsuit_bio" + suit.item_state_slots[slot_l_hand_str] = "medical_voidsuit_bio" if("Emergency Medical Response") if(helmet) helmet.name = "emergency medical response voidsuit helmet" @@ -1063,7 +1081,9 @@ if(suit) suit.name = "emergency medical response voidsuit" suit.icon_state = "rig-medical_emt" - suit.item_state = "medical_voidsuit_emt" + suit.item_state = "rig-medical_emt" + suit.item_state_slots[slot_r_hand_str] = "medical_voidsuit_emt" + suit.item_state_slots[slot_l_hand_str] = "medical_voidsuit_emt" if("^%###^%$" || "Mercenary") if(helmet) helmet.name = "blood-red voidsuit helmet" @@ -1071,8 +1091,10 @@ helmet.item_state = "rig0-syndie" if(suit) suit.name = "blood-red voidsuit" - suit.item_state = "syndie_voidsuit" + suit.item_state = "rig-syndie" suit.icon_state = "rig-syndie" + suit.item_state_slots[slot_r_hand_str] = "syndie_voidsuit" + suit.item_state_slots[slot_l_hand_str] = "syndie_voidsuit" if("Charring") if(helmet) helmet.name = "soot-covered voidsuit helmet" @@ -1082,6 +1104,8 @@ suit.name = "soot-covered voidsuit" suit.item_state = "rig-firebug" suit.icon_state = "rig-firebug" + suit.item_state_slots[slot_r_hand_str] = "rig-firebug" + suit.item_state_slots[slot_l_hand_str] = "rig-firebug" if(helmet) helmet.name = "refitted [helmet.name]" if(suit) suit.name = "refitted [suit.name]" diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm index 1b38fae182..46b9d3645c 100644 --- a/code/game/objects/effects/decals/Cleanable/humans.dm +++ b/code/game/objects/effects/decals/Cleanable/humans.dm @@ -96,18 +96,18 @@ var/global/list/image/splatter_cache=list() S.overlays.Cut() S.overlays += S.blood_overlay S.blood_DNA |= blood_DNA.Copy() + perp.update_inv_shoes() else if (hasfeet)//Or feet perp.feet_blood_color = basecolor perp.track_blood = max(amount,perp.track_blood) - if(!perp.feet_blood_DNA) - perp.feet_blood_DNA = list() + LAZYINITLIST(perp.feet_blood_DNA) perp.feet_blood_DNA |= blood_DNA.Copy() + perp.update_bloodied() else if (perp.buckled && istype(perp.buckled, /obj/structure/bed/chair/wheelchair)) var/obj/structure/bed/chair/wheelchair/W = perp.buckled W.bloodiness = 4 - perp.update_inv_shoes(1) amount-- /obj/effect/decal/cleanable/blood/proc/dry() diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index d42864c99d..484df24866 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -84,6 +84,9 @@ var/reach = 1 // Length of tiles it can reach, 1 is adjacent. var/addblends // Icon overlay for ADD highlights when applicable. + var/icon/default_worn_icon //Default on-mob icon + var/worn_layer //Default on-mob layer + /obj/item/New() ..() if(embed_chance < 0) @@ -280,6 +283,7 @@ // note this isn't called during the initial dressing of a player /obj/item/proc/equipped(var/mob/user, var/slot) hud_layerise() + user.position_hud_item(src,slot) if(user.client) user.client.screen |= src if(user.pulling == src) user.stop_pulling() return @@ -678,4 +682,116 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. // My best guess as to why this is here would be that it does so little. Still, keep it under all the procs, for sanity's sake. /obj/item/device - icon = 'icons/obj/device.dmi' \ No newline at end of file + icon = 'icons/obj/device.dmi' + +//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) + //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/state2use = get_worn_icon_state(slot_name = slot_name) + var/layer2use = get_worn_layer(default_layer = default_layer) + + //Snowflakey inhand icons in a specific slot + if(inhands && icon2use == icon_override) + switch(slot_name) + if(slot_r_hand_str) + state2use += "_r" + 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]") + + //Generate the base onmob icon + var/icon/standing_icon = icon(icon = icon2use, icon_state = state2use) + + 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 any special features + if(!inhands) + apply_blood(standing) //Some items show blood when bloodied + apply_accessories(standing) //Some items sport accessories like webbing + + //Return our icon + 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) + + //1: icon_override var + if(icon_override) + return icon_override + + //2: species-specific sprite sheets (skipped for inhands) + var/sheet = sprite_sheets[body_type] + if(sheet && !inhands) + return sheet + + //3: slot-specific sprite sheets + sheet = 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 + +//Returns the state that should be used for the worn icon +/obj/item/proc/get_worn_icon_state(var/slot_name) + + //1: slot-specific sprite sheets + var/state = item_state_slots[slot_name] + if(state) + return state + + //2: item_state variable + if(item_state) + return item_state + + //3: icon_state variable + if(icon_state) + return icon_state + +//Returns the layer that should be used for the worn icon (as a FLOAT_LAYER layer, so negative) +/obj/item/proc/get_worn_layer(var/default_layer = 0) + + //1: worn_layer variable + if(!isnull(worn_layer)) //Can be zero, so... + return BODY_LAYER+worn_layer + + //2: your default + return BODY_LAYER+default_layer + +//Apply the addblend blends onto the icon +/obj/item/proc/apply_addblends(var/source_icon, var/icon/standing_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) + return standing + +//STUB +/obj/item/proc/apply_accessories(var/image/standing) + return standing + diff --git a/code/game/objects/items/devices/defib.dm b/code/game/objects/items/devices/defib.dm index 9eb4991f69..4b9ea5137a 100644 --- a/code/game/objects/items/devices/defib.dm +++ b/code/game/objects/items/devices/defib.dm @@ -487,7 +487,6 @@ M.timeofdeath = 0 M.stat = UNCONSCIOUS //Life() can bring them back to consciousness if it needs to. - M.regenerate_icons() M.failed_last_breath = 0 //So mobs that died of oxyloss don't revive and have perpetual out of breath. M.reload_fullscreen() diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm index 01b52affc5..53e21f8533 100644 --- a/code/game/objects/items/devices/radio/headset.dm +++ b/code/game/objects/items/devices/radio/headset.dm @@ -3,6 +3,7 @@ desc = "An updated, modular intercom that fits over the head. Takes encryption keys" var/radio_desc = "" icon_state = "headset" + item_state = null //To remove the radio's state matter = list(DEFAULT_WALL_MATERIAL = 75) subspace_transmission = 1 canhear_range = 0 // can't hear headsets from very far away @@ -63,6 +64,17 @@ return ..(freq, level) return -1 +/obj/item/device/radio/headset/get_worn_icon_state(var/slot_name) + var/append = "" + if(icon_override) + switch(slot_name) + if(slot_l_ear_str) + append = "_l" + if(slot_r_ear_str) + append = "_r" + + return "[..()][append]" + /obj/item/device/radio/headset/syndicate origin_tech = list(TECH_ILLEGAL = 3) syndie = 1 diff --git a/code/game/objects/items/weapons/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm index 729ef1d066..c39c7e0067 100644 --- a/code/game/objects/items/weapons/cigs_lighters.dm +++ b/code/game/objects/items/weapons/cigs_lighters.dm @@ -89,6 +89,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM var/weldermes = "USER lights NAME with FLAME" var/ignitermes = "USER lights NAME with FLAME" var/brand + blood_sprite_state = null //Can't bloody these /obj/item/clothing/mask/smokable/New() ..() diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm index ea838cce0b..344387f8cd 100644 --- a/code/game/objects/items/weapons/handcuffs.dm +++ b/code/game/objects/items/weapons/handcuffs.dm @@ -20,6 +20,12 @@ var/use_time = 30 sprite_sheets = list("Teshari" = 'icons/mob/species/seromi/handcuffs.dmi') +/obj/item/weapon/handcuffs/get_worn_icon_state(var/slot_name) + if(slot_name == slot_handcuffed_str) + return "handcuff1" //Simple + + return ..() + /obj/item/weapon/handcuffs/attack(var/mob/living/carbon/C, var/mob/living/user) if(!user.IsAdvancedToolUser()) @@ -97,6 +103,13 @@ target.update_inv_handcuffed() return 1 +/obj/item/weapon/handcuffs/equipped(var/mob/living/user,var/slot) + . = ..() + if(slot == slot_handcuffed) + user.drop_r_hand() + user.drop_l_hand() + user.stop_pulling() + var/last_chew = 0 /mob/living/carbon/human/RestrainedClickOn(var/atom/A) if (A != src) return ..() @@ -210,6 +223,12 @@ var/last_chew = 0 breakouttime = 30 cuff_sound = 'sound/weapons/towelwipe.ogg' //Is there anything this sound can't do? +/obj/item/weapon/handcuffs/legcuffs/get_worn_icon_state(var/slot_name) + if(slot_name == slot_legcuffed_str) + return "legcuff1" + + return ..() + /obj/item/weapon/handcuffs/legcuffs/bola/can_place(var/mob/target, var/mob/user) if(user) //A ranged legcuff, until proper implementation as items it remains a projectile-only thing. return 1 @@ -303,3 +322,11 @@ var/last_chew = 0 target.legcuffed = lcuffs target.update_inv_legcuffed() return 1 + +/obj/item/weapon/handcuffs/legcuffs/equipped(var/mob/living/user,var/slot) + . = ..() + if(slot == slot_legcuffed) + if(user.m_intent != "walk") + user.m_intent = "walk" + if(user.hud_used && user.hud_used.move_intent) + user.hud_used.move_intent.icon_state = "walking" diff --git a/code/game/objects/items/weapons/id cards/station_ids.dm b/code/game/objects/items/weapons/id cards/station_ids.dm index f4b6d68f1e..c242794b9a 100644 --- a/code/game/objects/items/weapons/id cards/station_ids.dm +++ b/code/game/objects/items/weapons/id cards/station_ids.dm @@ -55,8 +55,8 @@ name = "[src.registered_name]'s ID Card ([src.assignment])" /obj/item/weapon/card/id/proc/set_id_photo(var/mob/M) - front = getFlatIcon(M, SOUTH, always_use_defdir = 1) - side = getFlatIcon(M, WEST, always_use_defdir = 1) + front = getFlatIcon(M, SOUTH) + side = getFlatIcon(M, WEST) /mob/proc/set_id_info(var/obj/item/weapon/card/id/id_card) id_card.age = 0 @@ -112,6 +112,12 @@ usr << "The fingerprint hash on the card is [fingerprint_hash]." return +/obj/item/weapon/card/id/get_worn_icon_state(var/slot_name) + if(slot_name == slot_wear_id_str) + return "id" //Legacy, just how it is. There's only one sprite. + + return ..() + /obj/item/weapon/card/id/initialize() . = ..() var/datum/job/J = job_master.GetJob(rank) diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index 23fccf51ac..3f39fbce92 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -22,6 +22,16 @@ show_above_suit = !show_above_suit update_icon() +//Some belts have sprites to show icons +/obj/item/weapon/storage/belt/make_worn_icon(var/body_type,var/slot_name,var/inhands,var/default_icon,var/default_layer = 0) + var/image/standing = ..() + if(!inhands && contents.len) + for(var/obj/item/i in contents) + var/i_state = i.item_state + if(!i_state) i_state = i.icon_state + standing.add_overlay(image(icon = INV_BELT_DEF_ICON, icon_state = i_state)) + return standing + /obj/item/weapon/storage/update_icon() if (ismob(src.loc)) var/mob/M = src.loc diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index 09e1c9b139..f7e43ac718 100644 --- a/code/game/objects/items/weapons/storage/boxes.dm +++ b/code/game/objects/items/weapons/storage/boxes.dm @@ -23,7 +23,7 @@ name = "box" desc = "It's just an ordinary box." icon_state = "box" - item_state_slots = list(slot_r_hand_str = "syringe_kit", slot_l_hand_str = "syringe_kit") + item_state = "syringe_kit" var/foldable = /obj/item/stack/material/cardboard // BubbleWrap - if set, can be folded (when empty) into a sheet of cardboard max_w_class = ITEMSIZE_SMALL max_storage_space = INVENTORY_BOX_SPACE diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm index 799169bad5..ca2d76d9f2 100644 --- a/code/game/objects/items/weapons/storage/storage.dm +++ b/code/game/objects/items/weapons/storage/storage.dm @@ -354,12 +354,10 @@ //such as when picking up all the items on a tile with one click. /obj/item/weapon/storage/proc/handle_item_insertion(obj/item/W as obj, prevent_warning = 0) if(!istype(W)) return 0 + if(usr) - usr.remove_from_mob(W) - usr.update_icons() //update our overlays - W.forceMove(src) - W.on_enter_storage(src) - if(usr) + usr.remove_from_mob(W,target = src) //If given a target, handles forceMove() + W.on_enter_storage(src) if (usr.client && usr.s_active != src) usr.client.screen -= W W.dropped(usr) @@ -377,6 +375,10 @@ src.orient2hud(usr) if(usr.s_active) usr.s_active.show_to(usr) + else + W.forceMove(src) + W.on_enter_storage(src) + update_icon() return 1 diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 502461cd69..358df91af6 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1001,11 +1001,6 @@ //strip their stuff and stick it in the crate for(var/obj/item/I in M) M.drop_from_inventory(I, locker) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - H.update_icons_layers() //Cheaper - else - M.update_icons() //so they black out before warping M.Paralyse(5) @@ -1188,10 +1183,8 @@ usr << "This can only be used on instances of type /mob/living/carbon/human" return var/block=text2num(href_list["block"]) - //testing("togmutate([href_list["block"]] -> [block])") usr.client.cmd_admin_toggle_block(H,block) show_player_panel(H) - //H.regenerate_icons() else if(href_list["adminplayeropts"]) var/mob/M = locate(href_list["adminplayeropts"]) diff --git a/code/modules/admin/verbs/possess.dm b/code/modules/admin/verbs/possess.dm index 6de30853ce..aa100623ff 100644 --- a/code/modules/admin/verbs/possess.dm +++ b/code/modules/admin/verbs/possess.dm @@ -37,7 +37,6 @@ if(ishuman(usr)) var/mob/living/carbon/human/H = usr H.name = H.get_visible_name() -// usr.regenerate_icons() //So the name is updated properly usr.loc = O.loc // Appear where the object you were controlling is -- TLE usr.client.eye = usr diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 915ea1758d..db297cde3f 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -287,10 +287,10 @@ datum/preferences if(icon_updates) character.force_update_limbs() - character.update_mutations(0) - character.update_underwear(0) - character.update_hair(0) - character.update_icons_all() + character.update_icons_body() + character.update_mutations() + character.update_underwear() + character.update_hair() /datum/preferences/proc/open_load_dialog(mob/user) var/dat = "
" diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 58b6a613a9..4a31a40fbc 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -22,6 +22,7 @@ */ var/list/sprite_sheets_refit = null var/ear_protection = 0 + var/blood_sprite_state //Updates the icons of the mob wearing the clothing item, if any. /obj/item/clothing/proc/update_clothing_icon() @@ -90,10 +91,8 @@ //Set icon if (sprite_sheets_refit && (target_species in sprite_sheets_refit)) - icon_override = sprite_sheets_refit[target_species] - else - icon_override = initial(icon_override) - + 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] else @@ -113,9 +112,7 @@ //Set icon if (sprite_sheets_refit && (target_species in sprite_sheets_refit)) - icon_override = sprite_sheets_refit[target_species] - else - icon_override = initial(icon_override) + 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] @@ -197,6 +194,7 @@ w_class = ITEMSIZE_SMALL icon = 'icons/obj/clothing/gloves.dmi' siemens_coefficient = 0.9 + blood_sprite_state = "bloodyhands" var/wired = 0 var/obj/item/weapon/cell/cell = 0 var/fingerprint_chance = 0 //How likely the glove is to let fingerprints through @@ -318,11 +316,13 @@ body_parts_covered = HEAD slot_flags = SLOT_HEAD w_class = ITEMSIZE_SMALL + blood_sprite_state = "helmetblood" var/light_overlay = "helmet_light" var/light_applied var/brightness_on var/on = 0 + var/image/helmet_light sprite_sheets = list( "Teshari" = 'icons/mob/species/seromi/head.dmi', @@ -386,29 +386,29 @@ return 1 /obj/item/clothing/head/update_icon(var/mob/user) - - overlays.Cut() var/mob/living/carbon/human/H - if(istype(user,/mob/living/carbon/human)) + if(ishuman(user)) H = user if(on) - // Generate object icon. if(!light_overlay_cache["[light_overlay]_icon"]) - light_overlay_cache["[light_overlay]_icon"] = image("icon" = 'icons/obj/light_overlays.dmi', "icon_state" = "[light_overlay]") - overlays |= light_overlay_cache["[light_overlay]_icon"] + light_overlay_cache["[light_overlay]_icon"] = image(icon = 'icons/obj/light_overlays.dmi', icon_state = "[light_overlay]") + helmet_light = light_overlay_cache["[light_overlay]_icon"] + add_overlay(helmet_light) // Generate and cache the on-mob icon, which is used in update_inv_head(). - var/cache_key = "[light_overlay][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]" : ""]" if(!light_overlay_cache[cache_key]) - var/use_icon = 'icons/mob/light_overlays.dmi' - if(H && sprite_sheets[H.species.get_bodytype(H)]) - use_icon = sprite_sheets[H.species.get_bodytype(H)] - light_overlay_cache[cache_key] = image("icon" = use_icon, "icon_state" = "[light_overlay]") + 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]") + + else if(helmet_light) + cut_overlay(helmet_light) + helmet_light = null - if(H) - H.update_inv_head() + user.update_inv_head() //Will redraw the helmet with the light on the mob /obj/item/clothing/head/update_clothing_icon() if (ismob(src.loc)) @@ -427,6 +427,7 @@ body_parts_covered = HEAD slot_flags = SLOT_MASK body_parts_covered = FACE|EYES + blood_sprite_state = "maskblood" sprite_sheets = list( "Teshari" = 'icons/mob/species/seromi/masks.dmi', "Vox" = 'icons/mob/species/vox/masks.dmi', @@ -460,6 +461,7 @@ siemens_coefficient = 0.9 body_parts_covered = FEET slot_flags = SLOT_FEET + blood_sprite_state = "shoeblood" var/can_hold_knife = 0 var/obj/item/holding @@ -574,6 +576,7 @@ w_class = ITEMSIZE_NORMAL preserve_item = 1 + sprite_sheets = list( "Teshari" = 'icons/mob/species/seromi/suit.dmi', "Vox" = 'icons/mob/species/vox/suit.dmi' @@ -602,6 +605,7 @@ armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) w_class = ITEMSIZE_NORMAL show_messages = 1 + blood_sprite_state = "uniformblood" var/has_sensor = 1 //For the crew computer 2 = unable to change mode var/sensor_mode = 0 diff --git a/code/modules/clothing/clothing_icons.dm b/code/modules/clothing/clothing_icons.dm new file mode 100644 index 0000000000..33e1da6000 --- /dev/null +++ b/code/modules/clothing/clothing_icons.dm @@ -0,0 +1,34 @@ +/obj/item/clothing/apply_accessories(var/image/standing) + if(LAZYLEN(accessories)) + for(var/obj/item/clothing/accessory/A in accessories) + standing.add_overlay(A.get_mob_overlay()) + +/obj/item/clothing/apply_blood(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) + +//UNIFORM: Always appends "_s" to iconstate, stupidly. +/obj/item/clothing/under/get_worn_icon_state(var/slot_name) + var/state2use = ..() + state2use += "_s" + return state2use + +//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/image/standing = ..() + if(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]) + 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) + 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_overlay_type]blood") + bloodsies.color = blood_color + standing.add_overlay(bloodsies) diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm index 75d8943b81..ac191acf5e 100644 --- a/code/modules/clothing/spacesuits/rig/rig.dm +++ b/code/modules/clothing/spacesuits/rig/rig.dm @@ -179,6 +179,15 @@ spark_system = null return ..() +/obj/item/weapon/rig/get_worn_icon_file(var/body_type,var/slot_name,var/default_icon,var/inhands) + if(!inhands && slot_name == slot_back_str) + if(icon_override) + return icon_override + else if(mob_icon) + return mob_icon + + return ..() + /obj/item/weapon/rig/proc/suit_is_deployed() if(!istype(wearer) || src.loc != wearer || wearer.back != src) return 0 @@ -330,7 +339,6 @@ piece.item_flags &= ~(STOPPRESSUREDAMAGE|AIRTIGHT) else piece.item_flags |= (STOPPRESSUREDAMAGE|AIRTIGHT) - update_icon(1) /obj/item/weapon/rig/ui_action_click() toggle_cooling(usr) @@ -598,7 +606,7 @@ // 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)] - mob_icon = image("icon" = species_icon, "icon_state" = "[icon_state]") + mob_icon = icon(icon = species_icon, icon_state = "[icon_state]") if(installed_modules.len) for(var/obj/item/rig_module/module in installed_modules) diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm index 1392da3e46..9e0c0a0196 100644 --- a/code/modules/clothing/suits/miscellaneous.dm +++ b/code/modules/clothing/suits/miscellaneous.dm @@ -265,6 +265,15 @@ return ..() +/obj/item/clothing/suit/straight_jacket/equipped(var/mob/living/user,var/slot) + . = ..() + if(slot == slot_wear_suit) + user.drop_l_hand() + user.drop_r_hand() + if(ishuman(user)) + var/mob/living/carbon/human/H = user + H.drop_from_inventory(H.handcuffed) + /obj/item/clothing/suit/ianshirt name = "worn shirt" desc = "A worn out, curiously comfortable t-shirt with a picture of Ian. You wouldn't go so far as to say it feels like being hugged when you wear it but it's pretty close. Good for sleeping in." diff --git a/code/modules/holodeck/HolodeckControl.dm b/code/modules/holodeck/HolodeckControl.dm index 8560e71f34..59575eb603 100644 --- a/code/modules/holodeck/HolodeckControl.dm +++ b/code/modules/holodeck/HolodeckControl.dm @@ -247,7 +247,6 @@ var/mob/M = obj.loc if(ismob(M)) M.remove_from_mob(obj) - M.update_icons_layers() //so their overlays update if(!silent) var/obj/oldobj = obj diff --git a/code/modules/holodeck/HolodeckObjects.dm b/code/modules/holodeck/HolodeckObjects.dm index 7892865a5f..7432cda589 100644 --- a/code/modules/holodeck/HolodeckObjects.dm +++ b/code/modules/holodeck/HolodeckObjects.dm @@ -104,8 +104,8 @@ base_icon = 'icons/turf/flooring/asteroid.dmi' initial_flooring = null -/turf/simulated/floor/holofloor/desert/New() - ..() +/turf/simulated/floor/holofloor/desert/initialize() + . = ..() if(prob(10)) add_overlay("asteroid[rand(0,9)]") diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 13cd4d4c36..143ef9ef7f 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -103,8 +103,7 @@ if (ishuman(body)) var/mob/living/carbon/human/H = body icon = H.icon - LAZYCLEARLIST(H.list_huds) - H.update_icons() + underlays = H.underlays overlays = H.overlays else icon = body.icon diff --git a/code/modules/mob/holder.dm b/code/modules/mob/holder.dm index 5d0796f77c..8815a6a176 100644 --- a/code/modules/mob/holder.dm +++ b/code/modules/mob/holder.dm @@ -83,8 +83,6 @@ var/list/holder_mob_icon_cache = list() H.update_inv_l_hand() else if(H.r_hand == src) H.update_inv_r_hand() - else - H.regenerate_icons() //Mob specific holders. /obj/item/weapon/holder/diona diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index 439aed4ec7..a7f278cb6a 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -138,7 +138,6 @@ var/list/slot_equipment_priority = list( \ remove_from_mob(W, target) if(!(W && W.loc)) return 1 // self destroying objects (tk, grabs) - update_icons_layers() return 1 return 0 @@ -180,7 +179,7 @@ var/list/slot_equipment_priority = list( \ /mob/proc/get_inventory_slot(obj/item/I) var/slot = 0 - for(var/s in slot_back to slot_tie) //kind of worries me + for(var/s in 1 to SLOT_TOTAL) if(get_equipped_item(s) == I) slot = s break diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index dfa385f43c..3fb0c6e65e 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -277,23 +277,6 @@ // ++++ROCKDTBEN++++ MOB PROCS //END -/mob/living/carbon/clean_blood() - . = ..() - if(ishuman(src)) - var/mob/living/carbon/human/H = src - if(H.gloves) - if(H.gloves.clean_blood()) - H.update_inv_gloves(0) - H.gloves.germ_level = 0 - else - if(H.bloody_hands) - H.bloody_hands = 0 - H.update_inv_gloves(0) - H.germ_level = 0 - update_icons_layers(FALSE) //apply the now updated overlays to the mob - update_icons_body() - - /mob/living/carbon/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) ..() var/temp_inc = max(min(BODYTEMP_HEATING_MAX*(1-get_heat_protection()), exposed_temperature - bodytemperature), 0) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 4742e42c1d..bda56bcfbf 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -5,7 +5,8 @@ icon = 'icons/effects/effects.dmi' //We have an ultra-complex update icons that overlays everything, don't load some stupid random male human icon_state = "nothing" - var/list/hud_list[TOTAL_HUDS] + has_huds = TRUE //We do have HUDs (like health, wanted, status, not inventory slots) + var/embedded_flag //To check if we've need to roll for damage on movement while an item is imbedded in us. var/obj/item/weapon/rig/wearing_rig // This is very not good, but it's much much better than calling get_rig() every update_canmove() call. var/last_push_time //For human_attackhand.dm, keeps track of the last use of disarm @@ -40,9 +41,8 @@ nutrition = rand(200,400) - make_hud_overlays() - human_mob_list |= src + ..() hide_underwear.Cut() @@ -53,20 +53,12 @@ dna.ready_dna(src) dna.real_name = real_name sync_organ_dna() - make_blood() /mob/living/carbon/human/Destroy() human_mob_list -= src for(var/organ in organs) qdel(organ) - LAZYCLEARLIST(list_layers) - list_layers = null //Be free! - LAZYCLEARLIST(list_body) - list_body = null - LAZYCLEARLIST(list_huds) - list_huds = null - return ..() /mob/living/carbon/human/Stat() @@ -1015,7 +1007,7 @@ if(!blood_DNA[M.dna.unique_enzymes]) blood_DNA[M.dna.unique_enzymes] = M.dna.b_type hand_blood_color = blood_color - src.update_inv_gloves() //handles bloody hands overlays and updating + update_bloodied() verbs += /mob/living/carbon/human/proc/bloody_doodle return 1 //we applied blood to the item @@ -1025,14 +1017,30 @@ return md5(dna.uni_identity) /mob/living/carbon/human/clean_blood(var/washshoes) - .=..() + . = ..() + gunshot_residue = null - if(washshoes && !shoes && istype(feet_blood_DNA, /list) && feet_blood_DNA.len) - feet_blood_color = null - feet_blood_DNA.Cut() + + //Always do hands (or whatever's on our hands) + if(gloves) + gloves.clean_blood() + update_inv_gloves() + gloves.germ_level = 0 + else + bloody_hands = 0 + germ_level = 0 + + //Sometimes do shoes if asked (or feet if no shoes) + if(washshoes && shoes) + shoes.clean_blood() + update_inv_shoes() + shoes.germ_level = 0 + else if(washshoes && (feet_blood_color || LAZYLEN(feet_blood_DNA))) + LAZYCLEARLIST(feet_blood_DNA) feet_blood_DNA = null - update_inv_shoes(1) - return 1 + feet_blood_color = null + + update_bloodied() /mob/living/carbon/human/get_visible_implants(var/class = 0) @@ -1168,7 +1176,7 @@ maxHealth = species.total_health spawn(0) - regenerate_icons() + make_blood() if(vessel.total_volume < species.blood_volume) vessel.maximum_volume = species.blood_volume vessel.add_reagent("blood", species.blood_volume - vessel.total_volume) @@ -1184,6 +1192,9 @@ qdel(hud_used) hud_used = new /datum/hud(src) + //A slew of bits that may be affected by our species change + regenerate_icons() + if(species) if(mind) apply_traits() @@ -1538,22 +1549,17 @@ return species.fire_icon_state // Called by job_controller. Makes drones start with a permit, might be useful for other people later too. -/mob/living/carbon/human/equip_post_job() +/mob/living/carbon/human/equip_post_job() //Drone Permit moved to equip_survival_gear() var/braintype = get_FBP_type() if(braintype == FBP_DRONE) var/turf/T = get_turf(src) var/obj/item/clothing/accessory/permit/drone/permit = new(T) permit.set_name(real_name) - equip_to_slot_or_del(permit, slot_in_backpack) + equip_to_appropriate_slot(permit) // If for some reason it can't find room, it'll still be on the floor. -/mob/living/carbon/human/proc/update_icon_special(var/mutable_appearance/ma, var/update_icons = TRUE) //For things such as teshari hiding and whatnot. +/mob/living/carbon/human/proc/update_icon_special() //For things such as teshari hiding and whatnot. if(hiding) // Hiding? Carry on. if(stat == DEAD || paralysis || weakened || stunned) //stunned/knocked down by something that isn't the rest verb? Note: This was tried with INCAPACITATION_STUNNED, but that refused to work. hiding = FALSE //No hiding for you. Mob layer should be updated naturally, but it actually doesn't. else - ma.layer = HIDING_LAYER - - //Can put special species icon update proc calls here, if any are ever invented. - - if(update_icons) - update_icons() + layer = HIDING_LAYER diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 8439df5398..244c22e80b 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -102,8 +102,6 @@ can_be_antagged = TRUE - var/has_huds = TRUE //Do they have all the fancy life huds? Not for mannequins. - // Used by mobs in virtual reality to point back to the "real" mob the client belongs to. var/mob/living/carbon/human/vr_holder = null // Used by "real" mobs after they leave a VR session diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm index 5ad867a156..9eec76bdb7 100644 --- a/code/modules/mob/living/carbon/human/human_helpers.dm +++ b/code/modules/mob/living/carbon/human/human_helpers.dm @@ -108,7 +108,7 @@ return FBP_NONE -/mob/living/carbon/human/proc/make_hud_overlays() +/mob/living/carbon/human/make_hud_overlays() hud_list[HEALTH_HUD] = gen_hud_image(ingame_hud_med, src, "100", plane = PLANE_CH_HEALTH) if(isSynthetic()) hud_list[STATUS_HUD] = gen_hud_image(ingame_hud, src, "hudrobo", plane = PLANE_CH_STATUS) @@ -123,6 +123,7 @@ hud_list[IMPTRACK_HUD] = gen_hud_image(ingame_hud, src, "hudblank", plane = PLANE_CH_IMPTRACK) hud_list[SPECIALROLE_HUD] = gen_hud_image(ingame_hud, src, "hudblank", plane = PLANE_CH_SPECIAL) hud_list[STATUS_HUD_OOC] = gen_hud_image(ingame_hud, src, "hudhealthy", plane = PLANE_CH_STATUS_OOC) + add_overlay(hud_list) /mob/living/carbon/human/recalculate_vis() if(!vis_enabled || !plane_holder) diff --git a/code/modules/mob/living/carbon/human/human_organs.dm b/code/modules/mob/living/carbon/human/human_organs.dm index 7c4e38730f..0e1c5cfda6 100644 --- a/code/modules/mob/living/carbon/human/human_organs.dm +++ b/code/modules/mob/living/carbon/human/human_organs.dm @@ -2,7 +2,8 @@ var/obj/item/organ/internal/eyes/eyes = internal_organs_by_name[O_EYES] if(eyes) eyes.update_colour() - regenerate_icons() + update_icons_body() //Body handles eyes + update_eyes() //For floating eyes only /mob/living/carbon/var/list/internal_organs = list() /mob/living/carbon/human/var/list/organs = list() diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index 947b844ad2..9319893175 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -152,12 +152,14 @@ This saves us from having to call add_fingerprint() any time something is put in else if (W == wear_id) wear_id = null update_inv_wear_id() + BITSET(hud_updateflag, ID_HUD) + BITSET(hud_updateflag, WANTED_HUD) else if (W == r_store) r_store = null - update_inv_pockets() + //update_inv_pockets() //Doesn't do anything. else if (W == l_store) l_store = null - update_inv_pockets() + //update_inv_pockets() //Doesn't do anything. else if (W == s_store) s_store = null update_inv_s_store() @@ -195,8 +197,7 @@ This saves us from having to call add_fingerprint() any time something is put in //This is an UNSAFE proc. Use mob_can_equip() before calling this one! Or rather use equip_to_slot_if_possible() or advanced_equip_to_slot_if_possible() -//set redraw_mob to 0 if you don't wish the hud to be updated - if you're doing it manually in your own proc. -/mob/living/carbon/human/equip_to_slot(obj/item/W as obj, slot, redraw_mob = 1) +/mob/living/carbon/human/equip_to_slot(obj/item/W as obj, slot) if(!slot) return @@ -213,39 +214,41 @@ This saves us from having to call add_fingerprint() any time something is put in src.back = W W.equipped(src, slot) worn_clothing += back - update_inv_back(redraw_mob) + update_inv_back() if(slot_wear_mask) src.wear_mask = W if(wear_mask.flags_inv & (BLOCKHAIR|BLOCKHEADHAIR)) - update_hair(redraw_mob) //rebuild hair - update_inv_ears(0) + update_hair() //rebuild hair + update_inv_ears() W.equipped(src, slot) worn_clothing += wear_mask - update_inv_wear_mask(redraw_mob) + update_inv_wear_mask() if(slot_handcuffed) src.handcuffed = W - update_inv_handcuffed(redraw_mob) + update_inv_handcuffed() if(slot_legcuffed) src.legcuffed = W W.equipped(src, slot) - update_inv_legcuffed(redraw_mob) + update_inv_legcuffed() if(slot_l_hand) src.l_hand = W W.equipped(src, slot) - update_inv_l_hand(redraw_mob) + update_inv_l_hand() if(slot_r_hand) src.r_hand = W W.equipped(src, slot) - update_inv_r_hand(redraw_mob) + update_inv_r_hand() if(slot_belt) src.belt = W W.equipped(src, slot) worn_clothing += belt - update_inv_belt(redraw_mob) + update_inv_belt() if(slot_wear_id) src.wear_id = W W.equipped(src, slot) - update_inv_wear_id(redraw_mob) + update_inv_wear_id() + BITSET(hud_updateflag, ID_HUD) + BITSET(hud_updateflag, WANTED_HUD) if(slot_l_ear) src.l_ear = W if(l_ear.slot_flags & SLOT_TWOEARS) @@ -254,7 +257,7 @@ This saves us from having to call add_fingerprint() any time something is put in src.r_ear = O O.hud_layerise() W.equipped(src, slot) - update_inv_ears(redraw_mob) + update_inv_ears() if(slot_r_ear) src.r_ear = W if(r_ear.slot_flags & SLOT_TWOEARS) @@ -263,54 +266,54 @@ This saves us from having to call add_fingerprint() any time something is put in src.l_ear = O O.hud_layerise() W.equipped(src, slot) - update_inv_ears(redraw_mob) + update_inv_ears() if(slot_glasses) src.glasses = W W.equipped(src, slot) - update_inv_glasses(redraw_mob) + update_inv_glasses() if(slot_gloves) src.gloves = W W.equipped(src, slot) worn_clothing += glasses - update_inv_gloves(redraw_mob) + update_inv_gloves() if(slot_head) src.head = W if(head.flags_inv & (BLOCKHAIR|BLOCKHEADHAIR|HIDEMASK)) - update_hair(redraw_mob) //rebuild hair + update_hair() //rebuild hair update_inv_ears(0) update_inv_wear_mask(0) if(istype(W,/obj/item/clothing/head/kitty)) W.update_icon(src) W.equipped(src, slot) worn_clothing += head - update_inv_head(redraw_mob) + update_inv_head() if(slot_shoes) src.shoes = W W.equipped(src, slot) worn_clothing += shoes - update_inv_shoes(redraw_mob) + update_inv_shoes() if(slot_wear_suit) src.wear_suit = W W.equipped(src, slot) worn_clothing += wear_suit - update_inv_wear_suit(redraw_mob) + update_inv_wear_suit() if(slot_w_uniform) src.w_uniform = W W.equipped(src, slot) worn_clothing += w_uniform - update_inv_w_uniform(redraw_mob) + update_inv_w_uniform() if(slot_l_store) src.l_store = W W.equipped(src, slot) - update_inv_pockets(redraw_mob) + //update_inv_pockets() //Doesn't do anything if(slot_r_store) src.r_store = W W.equipped(src, slot) - update_inv_pockets(redraw_mob) + //update_inv_pockets() //Doesn't do anything if(slot_s_store) src.s_store = W W.equipped(src, slot) - update_inv_s_store(redraw_mob) + update_inv_s_store() if(slot_in_backpack) if(src.get_active_hand() == W) src.remove_from_mob(W) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 44ee6350ab..0ab36159cc 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -1583,26 +1583,24 @@ we only set those statuses and icons upon changes. Then those HUD items will simply add those pre-made images. This proc below is only called when those HUD elements need to change as determined by the mobs hud_updateflag. */ - - /mob/living/carbon/human/proc/handle_hud_list() if (BITTEST(hud_updateflag, HEALTH_HUD)) - var/image/holder = hud_list[HEALTH_HUD] + var/image/holder = grab_hud(HEALTH_HUD) if(stat == DEAD) holder.icon_state = "-100" // X_X else holder.icon_state = RoundHealth((health-config.health_threshold_crit)/(getMaxHealth()-config.health_threshold_crit)*100) - hud_list[HEALTH_HUD] = holder + apply_hud(HEALTH_HUD, holder) if (BITTEST(hud_updateflag, LIFE_HUD)) - var/image/holder = hud_list[LIFE_HUD] + var/image/holder = grab_hud(LIFE_HUD) if(isSynthetic()) holder.icon_state = "hudrobo" else if(stat == DEAD) holder.icon_state = "huddead" else holder.icon_state = "hudhealthy" - hud_list[LIFE_HUD] = holder + apply_hud(LIFE_HUD, holder) if (BITTEST(hud_updateflag, STATUS_HUD)) var/foundVirus = 0 @@ -1611,8 +1609,8 @@ foundVirus = 1 break - var/image/holder = hud_list[STATUS_HUD] - var/image/holder2 = hud_list[STATUS_HUD_OOC] + var/image/holder = grab_hud(STATUS_HUD) + var/image/holder2 = grab_hud(STATUS_HUD_OOC) if (isSynthetic()) holder.icon_state = "hudrobo" else if(stat == DEAD) @@ -1634,11 +1632,11 @@ else holder2.icon_state = "hudhealthy" - hud_list[STATUS_HUD] = holder - hud_list[STATUS_HUD_OOC] = holder2 + apply_hud(STATUS_HUD, holder) + apply_hud(STATUS_HUD_OOC, holder2) if (BITTEST(hud_updateflag, ID_HUD)) - var/image/holder = hud_list[ID_HUD] + var/image/holder = grab_hud(ID_HUD) if(wear_id) var/obj/item/weapon/card/id/I = wear_id.GetID() if(I) @@ -1648,11 +1646,10 @@ else holder.icon_state = "hudunknown" - - hud_list[ID_HUD] = holder + apply_hud(ID_HUD, holder) if (BITTEST(hud_updateflag, WANTED_HUD)) - var/image/holder = hud_list[WANTED_HUD] + var/image/holder = grab_hud(WANTED_HUD) holder.icon_state = "hudblank" var/perpname = name if(wear_id) @@ -1675,15 +1672,16 @@ else if((R.fields["id"] == E.fields["id"]) && (R.fields["criminal"] == "Released")) holder.icon_state = "hudreleased" break - hud_list[WANTED_HUD] = holder + + apply_hud(WANTED_HUD, holder) if ( BITTEST(hud_updateflag, IMPLOYAL_HUD) \ || BITTEST(hud_updateflag, IMPCHEM_HUD) \ || BITTEST(hud_updateflag, IMPTRACK_HUD)) - var/image/holder1 = hud_list[IMPTRACK_HUD] - var/image/holder2 = hud_list[IMPLOYAL_HUD] - var/image/holder3 = hud_list[IMPCHEM_HUD] + var/image/holder1 = grab_hud(IMPTRACK_HUD) + var/image/holder2 = grab_hud(IMPLOYAL_HUD) + var/image/holder3 = grab_hud(IMPCHEM_HUD) holder1.icon_state = "hudblank" holder2.icon_state = "hudblank" @@ -1699,21 +1697,21 @@ if(istype(I,/obj/item/weapon/implant/chem)) holder3.icon_state = "hud_imp_chem" - hud_list[IMPTRACK_HUD] = holder1 - hud_list[IMPLOYAL_HUD] = holder2 - hud_list[IMPCHEM_HUD] = holder3 + apply_hud(IMPTRACK_HUD, holder1) + apply_hud(IMPLOYAL_HUD, holder2) + apply_hud(IMPCHEM_HUD, holder3) if (BITTEST(hud_updateflag, SPECIALROLE_HUD)) - var/image/holder = hud_list[SPECIALROLE_HUD] + var/image/holder = grab_hud(SPECIALROLE_HUD) holder.icon_state = "hudblank" if(mind && mind.special_role) if(hud_icon_reference[mind.special_role]) holder.icon_state = hud_icon_reference[mind.special_role] else holder.icon_state = "hudsyndicate" - hud_list[SPECIALROLE_HUD] = holder + apply_hud(SPECIALROLE_HUD, holder) + hud_updateflag = 0 - update_icons_huds() /mob/living/carbon/human/handle_stunned() if(!can_feel_pain()) diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 85eae14cee..5c10ea509e 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -1,133 +1,99 @@ /* Global associative list for caching humanoid icons. Index format m or f, followed by a string of 0 and 1 to represent bodyparts followed by husk fat hulk skeleton 1 or 0. - TODO: Proper documentation - icon_key is [species.race_key][g][husk][fat][hulk][skeleton][s_tone] */ -var/global/list/human_icon_cache = list() +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/light_overlay_cache = list() +var/global/list/light_overlay_cache = list() //see make_worn_icon() on helmets +var/global/list/damage_icon_parts = list() //see UpdateDamageIcon() - /////////////////////// - //UPDATE_ICONS SYSTEM// - /////////////////////// -/* -Calling this a system is perhaps a bit trumped up. It is essentially update_clothing dismantled into its -core parts. The key difference is that when we generate overlays we do not generate either lying or standing -versions. Instead, we generate both and store them in two fixed-length lists, both using the same list-index -(The indexes are in update_icons.dm): Each list for humans is (at the time of writing) of length 19. -This will hopefully be reduced as the system is refined. - var/overlays_lying[19] //For the lying down stance - var/overlays_standing[19] //For the standing stance -When we call update_icons, the 'lying' variable is checked and then the appropriate list is assigned to our overlays! -That in itself uses a tiny bit more memory (no more than all the ridiculous lists the game has already mind you). -On the other-hand, it should be very CPU cheap in comparison to the old system. -In the old system, we updated all our overlays every life() call, even if we were standing still inside a crate! -or dead!. 25ish overlays, all generated from scratch every second for every xeno/human/monkey and then applied. -More often than not update_clothing was being called a few times in addition to that! CPU was not the only issue, -all those icons had to be sent to every client. So really the cost was extremely cumulative. To the point where -update_clothing would frequently appear in the top 10 most CPU intensive procs during profiling. -Another feature of this new system is that our lists are indexed. This means we can update specific overlays! -So we only regenerate icons when we need them to be updated! This is the main saving for this system. -In practice this means that: - everytime you fall over, we just switch between precompiled lists. Which is fast and cheap. - Everytime you do something minor like take a pen out of your pocket, we only update the in-hand overlay - etc... -There are several things that need to be remembered: -> Whenever we do something that should cause an overlay to update (which doesn't use standard procs - ( i.e. you do something like l_hand = /obj/item/something new(src) ) - You will need to call the relevant update_inv_* proc: - update_inv_head() - update_inv_wear_suit() - update_inv_gloves() - update_inv_shoes() - update_inv_w_uniform() - update_inv_glasse() - update_inv_l_hand() - update_inv_r_hand() - update_inv_belt() - update_inv_wear_id() - update_inv_ears() - update_inv_s_store() - update_inv_pockets() - update_inv_back() - update_inv_handcuffed() - update_inv_wear_mask() - All of these are named after the variable they update from. They are defined at the mob/ level like - update_clothing was, so you won't cause undefined proc runtimes with usr.update_inv_wear_id() if the usr is a - slime etc. Instead, it'll just return without doing any work. So no harm in calling it for slimes and such. -> There are also these special cases: - update_mutations() //handles updating your appearance for certain mutations. e.g TK head-glows - UpdateDamageIcon() //handles damage overlays for brute/burn damage //(will rename this when I geta round to it) - update_icons_body() //Handles updating your mob's icon to reflect their gender/race/complexion etc - update_hair() //Handles updating your hair overlay (used to be update_face, but mouth and - ...eyes were merged into update_body) - update_targeted() // Updates the target overlay when someone points a gun at you -> All of these procs update our overlays_lying and overlays_standing, and then call update_icons() by default. - If you wish to update several overlays at once, you can set the argument to 0 to disable the update and call - it manually: - e.g. - update_inv_head(0) - update_inv_l_hand(0) - update_inv_r_hand() //<---calls update_icons() - or equivillantly: - update_inv_head(0) - update_inv_l_hand(0) - update_inv_r_hand(0) - update_icons() -> If you need to update all overlays you can use regenerate_icons(). it works exactly like update_clothing used to. -> I reimplimented an old unused variable which was in the code called (coincidentally) var/update_icon - It can be used as another method of triggering regenerate_icons(). It's basically a flag that when set to non-zero - will call regenerate_icons() at the next life() call and then reset itself to 0. - The idea behind it is icons are regenerated only once, even if multiple events requested it. -This system is confusing and is still a WIP. It's primary goal is speeding up the controls of the game whilst -reducing processing costs. So please bear with me while I iron out the kinks. It will be worth it, I promise. -If I can eventually free var/lying stuff from the life() process altogether, stuns/death/status stuff -will become less affected by lag-spikes and will be instantaneous! :3 -If you have any questions/constructive-comments/bugs-to-report/or have a massivly devestated butt... -Please contact me on #coderbus IRC. ~Carn x -*/ +//////////////////////////////////////////////////////////////////////////////////////////////// +// # Human Icon Updating System +// +// This system takes care of the "icon" for human mobs. Of course humans don't just have a single +// icon+icon_state, but a combination of dozens of little sprites including including the body, +// clothing, equipment, in-universe HUD images, etc. +// +// # Basic Operation +// Whenever you do something that should update the on-mob appearance of a worn or held item, You +// will need to call the relevant update_inv_* proc. All of these are named after the variable they +// update from. They are defined at the /mob level so you don't even need to cast to carbon/human. +// +// The new system leverages SSoverlays to actually add/remove the overlays from mob.overlays +// Since SSoverlays already manages batching updates to reduce apperance churn etc, we don't need +// to worry about that. (In short, you can call add/cut overlay as many times as you want, it will +// only get assigned to the mob once per tick.) +// As a corrolary, this means users of this system do NOT need to tell the system when you're done +// making changes. +// +// There are also these special cases: +// update_icons_body() //Handles updating your mob's icon to reflect their gender/race/complexion etc +// UpdateDamageIcon() //Handles damage overlays for brute/burn damage //(will rename this when I geta round to it) ~Carn +// update_skin() //Handles updating skin for species that have a skin overlay. +// update_bloodied() //Handles adding/clearing the blood overlays for hands & feet. Call when bloodied or cleaned. +// update_underwear() //Handles updating the sprite for underwear. +// update_hair() //Handles updating your hair and eyes overlay +// update_mutations() //Handles updating your appearance for certain mutations. e.g TK head-glows +// update_fire() //Handles overlay from being on fire. +// update_water() //Handles overlay from being submerged. +// update_surgery() //Handles overlays from open external organs. +// +// # History (i.e. I'm used to the old way, what is different?) +// You used to have to call update_icons(FALSE) if you planned to make more changes, and call update_icons(TRUE) +// on the final update. All that is gone, just call update_inv_whatever() and it handles the rest. +// +//////////////////////////////////////////////////////////////////////////////////////////////// +//Add an entry to overlays, assuming it exists +/mob/living/carbon/human/proc/apply_layer(cache_index) + if((. = overlays_standing[cache_index])) + add_overlay(.) + +//Remove an entry from overlays, and from the list +/mob/living/carbon/human/proc/remove_layer(cache_index) + var/I = overlays_standing[cache_index] + if(I) + cut_overlay(I) + overlays_standing[cache_index] = null + +// These are used as the layers for the icons, as well as indexes in a list that holds onto them. +// Technically the layers used are all -100+layer to make them FLOAT_LAYER overlays. //Human Overlays Indexes///////// -#define MUTATIONS_LAYER 1 -#define SKIN_LAYER 2 -#define DAMAGE_LAYER 3 -#define SURGERY_LEVEL 4 //bs12 specific. -#define UNDERWEAR_LAYER 5 -#define SHOES_LAYER_ALT 6 -#define UNIFORM_LAYER 7 -#define ID_LAYER 8 -#define SHOES_LAYER 9 -#define GLOVES_LAYER 10 -#define BELT_LAYER 11 -#define SUIT_LAYER 12 -#define TAIL_LAYER 13 //bs12 specific. //In a perfect world the parts of the tail that show between legs would be on a new layer. Until then, sprite's been tweaked -#define GLASSES_LAYER 14 -#define BELT_LAYER_ALT 15 -#define SUIT_STORE_LAYER 16 -#define BACK_LAYER 17 -#define HAIR_LAYER 18 //TODO: make part of head layer? -#define EARS_LAYER 19 -#define EYES_LAYER 20 -#define FACEMASK_LAYER 21 -#define HEAD_LAYER 22 -#define COLLAR_LAYER 23 -#define HANDCUFF_LAYER 24 -#define LEGCUFF_LAYER 25 -#define L_HAND_LAYER 26 -#define R_HAND_LAYER 27 -#define MODIFIER_EFFECTS_LAYER 28 -#define FIRE_LAYER 29 //If you're on fire -#define WATER_LAYER 30 //If you're submerged in water. -#define TARGETED_LAYER 31 //BS12: Layer for the target overlay from weapon targeting system -#define TOTAL_LAYERS 31 +#define MUTATIONS_LAYER 1 //Mutations like fat, and lasereyes +#define SKIN_LAYER 2 //Skin things added by a call on species +#define BLOOD_LAYER 3 //Bloodied hands/feet/anything else +#define DAMAGE_LAYER 4 //Injury overlay sprites like open wounds +#define SURGERY_LAYER 5 //Overlays for open surgical sites +#define UNDERWEAR_LAYER 6 //Underwear/bras/etc +#define SHOES_LAYER_ALT 7 //Shoe-slot item (when set to be under uniform via verb) +#define UNIFORM_LAYER 8 //Uniform-slot item +#define ID_LAYER 9 //ID-slot item +#define SHOES_LAYER 10 //Shoe-slot item +#define GLOVES_LAYER 11 //Glove-slot item +#define BELT_LAYER 12 //Belt-slot item +#define SUIT_LAYER 13 //Suit-slot item +#define TAIL_LAYER 14 //Some species have tails to render +#define GLASSES_LAYER 15 //Eye-slot item +#define BELT_LAYER_ALT 16 //Belt-slot item (when set to be above suit via verb) +#define SUIT_STORE_LAYER 17 //Suit storage-slot item +#define BACK_LAYER 18 //Back-slot item +#define HAIR_LAYER 19 //The human's hair +#define EARS_LAYER 20 //Both ear-slot items (combined image) +#define EYES_LAYER 21 //Mob's eyes (used for glowing eyes) +#define FACEMASK_LAYER 22 //Mask-slot item +#define HEAD_LAYER 23 //Head-slot item +#define HANDCUFF_LAYER 24 //Handcuffs, if the human is handcuffed, in a secret inv slot +#define LEGCUFF_LAYER 25 //Same as handcuffs, for legcuffs +#define L_HAND_LAYER 26 //Left-hand item +#define R_HAND_LAYER 27 //Right-hand item +#define MODIFIER_EFFECTS_LAYER 28 //Effects drawn by modifiers +#define FIRE_LAYER 29 //'Mob on fire' overlay layer +#define WATER_LAYER 30 //'Mob submerged' overlay layer +#define TARGETED_LAYER 31 //'Aimed at' overlay layer +#define TOTAL_LAYERS 31//<---- KEEP THIS UPDATED, should always equal the highest number here, used to initialize a list. ////////////////////////////////// /mob/living/carbon/human - var/list/list_huds = list() - var/list/list_body = list() - var/list/list_layers = list() - var/list/overlays_standing[TOTAL_LAYERS] var/previous_damage_appearance // store what the body last looked like, so we only have to update it if something changed @@ -137,40 +103,23 @@ Please contact me on #coderbus IRC. ~Carn x if(QDESTROYING(src)) return - lying_prev = lying //so we don't update overlays for lying/standing unless our stance changes again + crash_with("CANARY: Old human update_icons was called.") + update_hud() //TODO: remove the need for this - //0: We start with their existing appearance (this contains their verbs, important to keep those!) - var/mutable_appearance/ma_compiled = new(src) + //Do any species specific layering updates, such as when hiding. + update_icon_special() - //1: HUDs because these are hidden behind a backplane. See update_icons_huds() - ma_compiled.overlays = list_huds //The first one can set instead of add +/mob/living/carbon/human/update_icons_layers() + crash_with("CANARY: Old human update_icons_layers was called.") - //2: The body itself, all the organs and whatnot - ma_compiled.overlays += list_body +/mob/living/carbon/human/update_icons_all() + crash_with("CANARY: Old human update_icons_all was called.") - //3: The 'layers' list (overlays_standing), from the defines above - ma_compiled.overlays += list_layers - - //4: Apply transforms based on situation - update_transform(ma_compiled) - - //5: Do any species specific layering updates, such as when hiding. - update_icon_special(ma_compiled, FALSE) - - //6: Set appearance once - appearance = ma_compiled - -/mob/living/carbon/human/update_transform(var/mutable_appearance/passed_ma) - if(QDESTROYING(src)) - return - - var/mutable_appearance/ma - if(passed_ma) - ma = passed_ma - else - ma = new(src) +/mob/living/carbon/human/update_icons_huds() + crash_with("CANARY: Old human update_icons_huds was called.") +/mob/living/carbon/human/update_transform() // First, get the correct size. var/desired_scale = icon_scale @@ -181,94 +130,34 @@ Please contact me on #coderbus IRC. ~Carn x desired_scale *= M.icon_scale_percent // Regular stuff again. + var/matrix/M = matrix() + var/anim_time = 3 + + //Due to some involuntary means, you're laying now + if(lying && !resting && !sleeping) + anim_time = 1 //Thud + if(lying && !species.prone_icon) //Only rotate them if we're not drawing a specific icon for being prone. - var/matrix/M = matrix() M.Turn(90) M.Scale(desired_scale) M.Translate(1,-6) - ma.transform = M - ma.layer = MOB_LAYER -0.01 // Fix for a byond bug where turf entry order no longer matters + layer = MOB_LAYER -0.01 // Fix for a byond bug where turf entry order no longer matters else - var/matrix/M = matrix() M.Scale(desired_scale) M.Translate(0, 16*(desired_scale-1)) - ma.transform = M - ma.layer = MOB_LAYER // Fix for a byond bug where turf entry order no longer matters + layer = MOB_LAYER // Fix for a byond bug where turf entry order no longer matters - if(!passed_ma) - update_icon_special(ma) - appearance = ma + animate(src, transform = M, time = anim_time) + update_icon_special() //May contain transform-altering things -//Update the layers from the defines above -/mob/living/carbon/human/update_icons_layers(var/update_icons = 1) - if(QDESTROYING(src)) - return - - list_layers.Cut() - - for(var/entry in overlays_standing) - if(istype(entry, /image)) - list_layers += entry - else if(istype(entry, /list)) //Is this necessary? What adds a list to this? - for(var/inner_entry in entry) - list_layers += inner_entry - - if(species && species.has_floating_eyes) - list_layers += species.get_eyes(src) - - if(update_icons) - update_icons() - -//HUD Icons (ingame huds, not the user interface) -//Update things like med/sec hud icons -/mob/living/carbon/human/update_icons_huds(var/update_icons = 1) - if(QDESTROYING(src)) - return - - list_huds.Cut() - - if(has_huds) - list_huds = hud_list.Copy() - list_huds += backplane // Required to mask HUDs in context menus: http://www.byond.com/forum/?post=2336679 - - //Typing indicator code - if(client && !stat) //They have a client & aren't dead/KO'd? Continue on! - if(typing_indicator && hud_typing) //They already have the indicator and are still typing - list_huds += typing_indicator - typing_indicator.invisibility = invisibility - - else if(!typing_indicator && hud_typing) //Are they in their body, NOT dead, have hud_typing, do NOT have a typing indicator. and have it enabled? - typing_indicator = new - typing_indicator.icon = 'icons/mob/talk.dmi' - typing_indicator.icon_state = "[speech_bubble_appearance()]_typing" - list_huds += typing_indicator - - else if(typing_indicator && !hud_typing) //Did they stop typing? - typing = FALSE - hud_typing = FALSE - - if(update_icons) - update_icons() - -//A full, crunchy reprocess of all three cached lists -/mob/living/carbon/human/update_icons_all(var/update_icons = 1) - if(QDESTROYING(src)) - return - - update_icons_huds(FALSE) - update_icons_body(FALSE) - update_icons_layers(FALSE) - - if(update_icons) - update_icons() - -var/global/list/damage_icon_parts = list() //DAMAGE OVERLAYS //constructs damage icon for each organ from mask * damage field and saves it in our overlays_ lists -/mob/living/carbon/human/UpdateDamageIcon(var/update_icons=1) +/mob/living/carbon/human/UpdateDamageIcon() if(QDESTROYING(src)) return + remove_layer(DAMAGE_LAYER) + // first check whether something actually changed about damage appearance var/damage_appearance = "" @@ -283,9 +172,7 @@ var/global/list/damage_icon_parts = list() previous_damage_appearance = damage_appearance - var/icon/standing = new /icon(species.damage_overlays, "00") - - var/image/standing_image = new /image("icon" = standing) + var/image/standing_image = image(icon = species.damage_overlays, icon_state = "00", layer = BODY_LAYER+DAMAGE_LAYER) // blend the individual damage states with our icons for(var/obj/item/organ/external/O in organs) @@ -297,8 +184,8 @@ var/global/list/damage_icon_parts = list() var/icon/DI var/cache_index = "[O.damage_state]/[O.icon_name]/[species.get_blood_colour(src)]/[species.get_bodytype(src)]" if(damage_icon_parts[cache_index] == null) - DI = new /icon(species.get_damage_overlays(src), O.damage_state) // the damage icon for whole human - DI.Blend(new /icon(species.get_damage_mask(src), O.icon_name), ICON_MULTIPLY) // mask with this organ's pixels + DI = icon(species.get_damage_overlays(src), O.damage_state) // the damage icon for whole human + DI.Blend(icon(species.get_damage_mask(src), O.icon_name), ICON_MULTIPLY) // mask with this organ's pixels DI.Blend(species.get_blood_colour(src), ICON_MULTIPLY) damage_icon_parts[cache_index] = DI else @@ -307,12 +194,10 @@ var/global/list/damage_icon_parts = list() standing_image.overlays += DI overlays_standing[DAMAGE_LAYER] = standing_image - - if(update_icons) - update_icons_layers() + apply_layer(DAMAGE_LAYER) //BASE MOB SPRITE -/mob/living/carbon/human/update_icons_body(var/update_icons=1) +/mob/living/carbon/human/update_icons_body() if(QDESTROYING(src)) return @@ -324,17 +209,14 @@ var/global/list/damage_icon_parts = list() var/hulk = (HULK in src.mutations) var/skeleton = (SKELETON in src.mutations) - robolimb_count = 0 + robolimb_count = 0 //TODO, here, really tho? robobody_count = 0 //CACHING: Generate an index key from visible bodyparts. //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',"blank") - - //Clean old list_body - list_body.Cut() + var/icon/stand_icon = new(species.icon_template ? species.icon_template : 'icons/mob/human.dmi', icon_state = "blank") var/g = "male" if(gender == FEMALE) @@ -434,27 +316,55 @@ var/global/list/damage_icon_parts = list() //END CACHED ICON GENERATION. stand_icon.Blend(base_icon,ICON_OVERLAY) - list_body += stand_icon //A little silly, almost pointless to use a list for this, but can come back later and make this proc itself better - - if(update_icons) - update_icons() + icon = stand_icon //tail - update_tail_showing(0) + update_tail_showing() -/mob/living/carbon/human/proc/update_skin(var/update_icons=1) +/mob/living/carbon/human/proc/update_skin() if(QDESTROYING(src)) return - overlays_standing[SKIN_LAYER] = species.update_skin(src) - if(update_icons) update_icons_layers() + remove_layer(SKIN_LAYER) + + var/image/skin = species.update_skin(src) + if(skin) + skin.layer = BODY_LAYER+SKIN_LAYER + overlays_standing[SKIN_LAYER] = skin + apply_layer(SKIN_LAYER) + +/mob/living/carbon/human/proc/update_bloodied() + if(QDESTROYING(src)) + return + + remove_layer(BLOOD_LAYER) + if(!blood_DNA && !feet_blood_DNA) + return + + var/image/both = image(icon = 'icons/effects/effects.dmi', icon_state = "nothing", layer = BODY_LAYER+BLOOD_LAYER) + + //Bloody hands + if(blood_DNA) + var/image/bloodsies = image(icon = species.get_blood_mask(src), icon_state = "bloodyhands", layer = BODY_LAYER+BLOOD_LAYER) + bloodsies.color = hand_blood_color + both.add_overlay(bloodsies) + + //Bloody feet + if(feet_blood_DNA) + var/image/bloodsies = image(icon = species.get_blood_mask(src), icon_state = "shoeblood", layer = BODY_LAYER+BLOOD_LAYER) + bloodsies.color = feet_blood_color + both.add_overlay(bloodsies) + + overlays_standing[BLOOD_LAYER] = both + + apply_layer(BLOOD_LAYER) //UNDERWEAR OVERLAY -/mob/living/carbon/human/proc/update_underwear(var/update_icons=1) +/mob/living/carbon/human/proc/update_underwear() if(QDESTROYING(src)) return - overlays_standing[UNDERWEAR_LAYER] = null + remove_layer(UNDERWEAR_LAYER) if(species.appearance_flags & HAS_UNDERWEAR) overlays_standing[UNDERWEAR_LAYER] = list() @@ -462,31 +372,30 @@ var/global/list/damage_icon_parts = list() if(hide_underwear[category]) continue var/datum/category_item/underwear/UWI = all_underwear[category] - overlays_standing[UNDERWEAR_LAYER] += UWI.generate_image(all_underwear_metadata[category]) + var/image/wear = UWI.generate_image(all_underwear_metadata[category], layer = BODY_LAYER+UNDERWEAR_LAYER) + overlays_standing[UNDERWEAR_LAYER] += wear - if(update_icons) update_icons_layers() + apply_layer(UNDERWEAR_LAYER) //HAIR OVERLAY -/mob/living/carbon/human/proc/update_hair(var/update_icons=1) +/mob/living/carbon/human/proc/update_hair() if(QDESTROYING(src)) return //Reset our hair - overlays_standing[HAIR_LAYER] = null - update_eyes(0) //Pirated out of here, for glowing eyes. + remove_layer(HAIR_LAYER) + update_eyes() //Pirated out of here, for glowing eyes. var/obj/item/organ/external/head/head_organ = get_organ(BP_HEAD) if(!head_organ || head_organ.is_stump() ) - if(update_icons) update_icons_layers() return //masks and helmets can obscure our hair. if( (head && (head.flags_inv & BLOCKHAIR)) || (wear_mask && (wear_mask.flags_inv & BLOCKHAIR))) - if(update_icons) update_icons_layers() return //base icons - var/icon/face_standing = new /icon('icons/mob/human_face.dmi',"bald_s") + var/icon/face_standing = icon(icon = 'icons/mob/human_face.dmi', icon_state = "bald_s") if(f_style) var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[f_style] @@ -511,36 +420,34 @@ var/global/list/damage_icon_parts = list() if(head_organ.nonsolid) face_standing += rgb(,,,120) - overlays_standing[HAIR_LAYER] = image(face_standing) - if(update_icons) update_icons_layers() + overlays_standing[HAIR_LAYER] = image(face_standing, layer = BODY_LAYER+HAIR_LAYER) + apply_layer(HAIR_LAYER) -/mob/living/carbon/human/update_eyes(var/update_icons=1) +/mob/living/carbon/human/update_eyes() if(QDESTROYING(src)) return //Reset our eyes - overlays_standing[EYES_LAYER] = null + remove_layer(EYES_LAYER) + + //TODO: Probably redo this. I know I wrote it, but... //This is ONLY for glowing eyes for now. Boring flat eyes are done by the head's own proc. if(!species.has_glowing_eyes) - if(update_icons) update_icons_layers() return //Our glowy eyes should be hidden if some equipment hides them. if(!should_have_organ(O_EYES) || (head && (head.flags_inv & BLOCKHAIR)) || (wear_mask && (wear_mask.flags_inv & BLOCKHAIR))) - if(update_icons) update_icons_layers() return //Get the head, we'll need it later. var/obj/item/organ/external/head/head_organ = get_organ(BP_HEAD) if(!head_organ || head_organ.is_stump() ) - if(update_icons) update_icons_layers() return //The eyes store the color themselves, funny enough. var/obj/item/organ/internal/eyes/eyes = internal_organs_by_name[O_EYES] if(!head_organ.eye_icon) - if(update_icons) update_icons_layers() return var/icon/eyes_icon = new/icon(head_organ.eye_icon_location, head_organ.eye_icon) @@ -552,650 +459,292 @@ var/global/list/damage_icon_parts = list() var/image/eyes_image = image(eyes_icon) eyes_image.plane = PLANE_LIGHTING_ABOVE - overlays_standing[EYES_LAYER] = eyes_image + overlays_standing[EYES_LAYER] = eyes_image + apply_layer(EYES_LAYER) - if(update_icons) update_icons_layers() - -/mob/living/carbon/human/update_mutations(var/update_icons=1) +/mob/living/carbon/human/update_mutations() if(QDESTROYING(src)) return + remove_layer(MUTATIONS_LAYER) + + if(!LAZYLEN(mutations)) + return //No mutations, no icons. + + //TODO: THIS PROC??? var/fat if(FAT in mutations) fat = "fat" - var/image/standing = image("icon" = 'icons/effects/genetics.dmi') - var/add_image = 0 - var/g = "m" - if(gender == FEMALE) g = "f" - // DNA2 - Drawing underlays. + var/image/standing = image(icon = 'icons/effects/genetics.dmi', layer = BODY_LAYER+MUTATIONS_LAYER) + var/g = gender == FEMALE ? "f" : "m" + for(var/datum/dna/gene/gene in dna_genes) if(!gene.block) continue if(gene.is_active(src)) - var/underlay=gene.OnDrawUnderlays(src,g,fat) + var/underlay = gene.OnDrawUnderlays(src,g,fat) if(underlay) standing.underlays += underlay - add_image = 1 + for(var/mut in mutations) - switch(mut) - /* - if(HULK) - if(fat) - standing.underlays += "hulk_[fat]_s" - else - standing.underlays += "hulk_[g]_s" - add_image = 1 - if(COLD_RESISTANCE) - standing.underlays += "fire[fat]_s" - add_image = 1 - if(TK) - standing.underlays += "telekinesishead[fat]_s" - add_image = 1 - */ - if(LASER) - standing.overlays += "lasereyes_s" - add_image = 1 - if(add_image) - overlays_standing[MUTATIONS_LAYER] = standing - else - overlays_standing[MUTATIONS_LAYER] = null - if(update_icons) update_icons_layers() + if(LASER) + standing.overlays += "lasereyes_s" //TODO + + overlays_standing[MUTATIONS_LAYER] = standing + apply_layer(MUTATIONS_LAYER) /* --------------------------------------- */ -//For legacy support. +//Recomputes every icon on the mob. Expensive. +//Useful if the species changed, or there's some +//other drastic body-shape change, but otherwise avoid. /mob/living/carbon/human/regenerate_icons() ..() - if(transforming || QDELETED(src)) return + if(transforming || QDELETED(src)) + return - update_mutations(0) - update_skin(0) - update_icons_body(0) - update_underwear(0) - update_hair(0) - update_inv_w_uniform(0) - update_inv_wear_id(0) - update_inv_gloves(0) - update_inv_glasses(0) - update_inv_ears(0) - update_inv_shoes(0) - update_inv_s_store(0) - update_inv_wear_mask(0) - update_inv_head(0) - update_inv_belt(0) - update_inv_back(0) - update_inv_wear_suit(0) - update_inv_r_hand(0) - update_inv_l_hand(0) - update_inv_handcuffed(0) - update_inv_legcuffed(0) - update_inv_pockets(0) - update_fire(0) - update_water(0) - update_surgery(0) - UpdateDamageIcon(0) - update_icons_layers(0) - update_icons_huds(0) - update_icons() - //Hud Stuff - update_hud() + update_icons_body() + UpdateDamageIcon() + update_mutations() + update_skin() + update_underwear() + update_hair() + update_inv_w_uniform() + update_inv_wear_id() + update_inv_gloves() + update_inv_glasses() + update_inv_ears() + update_inv_shoes() + update_inv_s_store() + update_inv_wear_mask() + update_inv_head() + update_inv_belt() + update_inv_back() + update_inv_wear_suit() + update_inv_r_hand() + update_inv_l_hand() + update_inv_handcuffed() + update_inv_legcuffed() + //update_inv_pockets() //Doesn't do anything + update_fire() + update_water() + update_surgery() /* --------------------------------------- */ //vvvvvv UPDATE_INV PROCS vvvvvv -/mob/living/carbon/human/update_inv_w_uniform(var/update_icons=1) +/mob/living/carbon/human/update_inv_w_uniform() if(QDESTROYING(src)) return - if( (w_uniform && istype(w_uniform, /obj/item/clothing/under)) && !(wear_suit && istype(wear_suit, /obj/item/clothing/suit/space) && wear_suit.flags_inv & HIDEJUMPSUIT && !istype(wear_suit, /obj/item/clothing/suit/space/rig) )) - w_uniform.screen_loc = ui_iclothing + remove_layer(UNIFORM_LAYER) - //determine the icon to use - var/icon/under_icon - if(w_uniform.icon_override) - under_icon = w_uniform.icon_override - else if(w_uniform.sprite_sheets && w_uniform.sprite_sheets[species.get_bodytype(src)]) - under_icon = w_uniform.sprite_sheets[species.get_bodytype(src)] - else if(w_uniform.item_icons && w_uniform.item_icons[slot_w_uniform_str]) - under_icon = w_uniform.item_icons[slot_w_uniform_str] - else - under_icon = INV_W_UNIFORM_DEF_ICON + //Shoes can be affected by uniform being drawn onto them + update_inv_shoes() + + if(!w_uniform) + return - //determine state to use - var/under_state - if(w_uniform.item_state_slots && w_uniform.item_state_slots[slot_w_uniform_str]) - under_state = w_uniform.item_state_slots[slot_w_uniform_str] - else if(w_uniform.item_state) - under_state = w_uniform.item_state - else - under_state = w_uniform.icon_state + if(wear_suit && (wear_suit.flags_inv & HIDEJUMPSUIT) && !istype(wear_suit, /obj/item/clothing/suit/space/rig)) + return //Wearing a suit that prevents uniform rendering - //need to append _s to the icon state for legacy compatibility - var/image/standing = image(icon = under_icon, icon_state = "[under_state]_s") + //Build a uniform sprite + overlays_standing[UNIFORM_LAYER] = w_uniform.make_worn_icon(body_type = species.get_bodytype(), slot_name = slot_w_uniform_str, default_icon = INV_W_UNIFORM_DEF_ICON, default_layer = UNIFORM_LAYER) + apply_layer(UNIFORM_LAYER) - if(w_uniform.addblends) - var/icon/base = new/icon("icon" = standing.icon, "icon_state" = standing.icon_state) - var/addblend_icon = new/icon("icon" = standing.icon, "icon_state" = w_uniform.addblends) - if(w_uniform.color) - base.Blend(w_uniform.color, ICON_MULTIPLY) - base.Blend(addblend_icon, ICON_ADD) - standing = image(base) - else - standing.color = w_uniform.color - - //apply blood overlay - if(w_uniform.blood_DNA) - var/image/bloodsies = image(icon = species.get_blood_mask(src), icon_state = "uniformblood") - bloodsies.color = w_uniform.blood_color - standing.overlays += bloodsies - - //accessories - var/obj/item/clothing/under/under = w_uniform - if(under.accessories.len) - for(var/obj/item/clothing/accessory/A in under.accessories) - standing.overlays |= A.get_mob_overlay() - - overlays_standing[UNIFORM_LAYER] = standing - else - overlays_standing[UNIFORM_LAYER] = null - - //hiding/revealing shoes if necessary - update_inv_shoes(1) - - if(update_icons) - update_icons_layers() - -/mob/living/carbon/human/update_inv_wear_id(var/update_icons=1) +/mob/living/carbon/human/update_inv_wear_id() if(QDESTROYING(src)) return - if(wear_id) - wear_id.screen_loc = ui_id //TODO - if(w_uniform && w_uniform:displays_id) - var/image/standing - if(wear_id.icon_override) - standing = image("icon" = wear_id.icon_override, "icon_state" = "[icon_state]") - else if(wear_id.sprite_sheets && wear_id.sprite_sheets[species.get_bodytype(src)]) - standing = image("icon" = wear_id.sprite_sheets[species.get_bodytype(src)], "icon_state" = "[icon_state]") - else - standing = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "id") - overlays_standing[ID_LAYER] = standing - else - overlays_standing[ID_LAYER] = null - else - overlays_standing[ID_LAYER] = null + remove_layer(ID_LAYER) + + if(!wear_id) + return //Not wearing an ID - BITSET(hud_updateflag, ID_HUD) - BITSET(hud_updateflag, WANTED_HUD) + //Only draw the ID on the mob if the uniform allows for it + 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(), slot_name = slot_wear_id_str, default_icon = INV_WEAR_ID_DEF_ICON, default_layer = ID_LAYER) + + apply_layer(ID_LAYER) - if(update_icons) update_icons_layers() - -/mob/living/carbon/human/update_inv_gloves(var/update_icons=1) +/mob/living/carbon/human/update_inv_gloves() if(QDESTROYING(src)) return - if(gloves) - var/t_state = gloves.item_state - if(!t_state) t_state = gloves.icon_state + remove_layer(GLOVES_LAYER) - var/image/standing - if(gloves.icon_override) - standing = image("icon" = gloves.icon_override, "icon_state" = "[t_state]") - else if(gloves.sprite_sheets && gloves.sprite_sheets[species.get_bodytype(src)]) - standing = image("icon" = gloves.sprite_sheets[species.get_bodytype(src)], "icon_state" = "[t_state]") - else - standing = image("icon" = 'icons/mob/hands.dmi', "icon_state" = "[t_state]") + if(!gloves) + return //No gloves, no reason to be here. - if(gloves.blood_DNA) - var/image/bloodsies = image("icon" = species.get_blood_mask(src), "icon_state" = "bloodyhands") - bloodsies.color = gloves.blood_color - standing.overlays += bloodsies - gloves.screen_loc = ui_gloves - if(gloves.addblends) - var/icon/base = new/icon("icon" = standing.icon, "icon_state" = standing.icon_state) - var/addblend_icon = new/icon("icon" = standing.icon, "icon_state" = gloves.addblends) - if(gloves.color) - base.Blend(gloves.color, ICON_MULTIPLY) - base.Blend(addblend_icon, ICON_ADD) - standing = image(base) - else - standing.color = gloves.color - overlays_standing[GLOVES_LAYER] = standing - else - if(blood_DNA) - var/image/bloodsies = image("icon" = species.get_blood_mask(src), "icon_state" = "bloodyhands") - bloodsies.color = hand_blood_color - overlays_standing[GLOVES_LAYER] = bloodsies - else - overlays_standing[GLOVES_LAYER] = null - if(update_icons) update_icons_layers() + overlays_standing[GLOVES_LAYER] = gloves.make_worn_icon(body_type = species.get_bodytype(), slot_name = slot_gloves_str, default_icon = INV_GLOVES_DEF_ICON, default_layer = GLOVES_LAYER) + + apply_layer(GLOVES_LAYER) - -/mob/living/carbon/human/update_inv_glasses(var/update_icons=1) +/mob/living/carbon/human/update_inv_glasses() if(QDESTROYING(src)) return - if(glasses) - var/image/standing - if(glasses.icon_override) - standing = image("icon" = glasses.icon_override, "icon_state" = "[glasses.icon_state]") - else if(glasses.sprite_sheets && glasses.sprite_sheets[species.get_bodytype(src)]) - standing = image("icon" = glasses.sprite_sheets[species.get_bodytype(src)], "icon_state" = "[glasses.icon_state]") - else - standing = image("icon" = 'icons/mob/eyes.dmi', "icon_state" = "[glasses.icon_state]") - if(glasses.addblends) - var/icon/base = new/icon("icon" = standing.icon, "icon_state" = standing.icon_state) - var/addblend_icon = new/icon("icon" = standing.icon, "icon_state" = glasses.addblends) - if(glasses.color) - base.Blend(glasses.color, ICON_MULTIPLY) - base.Blend(addblend_icon, ICON_ADD) - standing = image(base) - else - standing.color = glasses.color - overlays_standing[GLASSES_LAYER] = standing + remove_layer(GLASSES_LAYER) - else - overlays_standing[GLASSES_LAYER] = null - if(update_icons) update_icons_layers() + if(!glasses) + return //Not wearing glasses, no need to update anything. -/mob/living/carbon/human/update_inv_ears(var/update_icons=1) + overlays_standing[GLASSES_LAYER] = glasses.make_worn_icon(body_type = species.get_bodytype(), slot_name = slot_gloves_str, default_icon = INV_EYES_DEF_ICON, default_layer = GLASSES_LAYER) + + apply_layer(GLASSES_LAYER) + +/mob/living/carbon/human/update_inv_ears() if(QDESTROYING(src)) return - overlays_standing[EARS_LAYER] = null - if( (head && (head.flags_inv & (BLOCKHAIR | BLOCKHEADHAIR))) || (wear_mask && (wear_mask.flags_inv & (BLOCKHAIR | BLOCKHEADHAIR)))) - if(update_icons) update_icons_layers() - return + remove_layer(EARS_LAYER) - if(l_ear || r_ear) - // Blank image upon which to layer left & right overlays. - var/image/both = image("icon" = 'icons/effects/effects.dmi', "icon_state" = "nothing") + if((head && head.flags_inv & (BLOCKHAIR | BLOCKHEADHAIR)) || (wear_mask && wear_mask.flags_inv & (BLOCKHAIR | BLOCKHEADHAIR))) + return //Ears are blocked (by hair being blocked, overloaded) - if(l_ear) - var/image/standing - var/t_type = l_ear.icon_state - if(l_ear.icon_override) - t_type = "[t_type]_l" - standing = image("icon" = l_ear.icon_override, "icon_state" = "[t_type]") - else if(l_ear.sprite_sheets && l_ear.sprite_sheets[species.get_bodytype(src)]) - t_type = "[t_type]_l" - standing = image("icon" = l_ear.sprite_sheets[species.get_bodytype(src)], "icon_state" = "[t_type]") - else - standing = image("icon" = 'icons/mob/ears.dmi', "icon_state" = "[t_type]") - if(l_ear.addblends) - var/icon/base = new/icon("icon" = standing.icon, "icon_state" = standing.icon_state) - var/addblend_icon = new/icon("icon" = standing.icon, "icon_state" = l_ear.addblends) - if(l_ear.color) - base.Blend(l_ear.color, ICON_MULTIPLY) - base.Blend(addblend_icon, ICON_ADD) - standing = image(base) - else - standing.color = l_ear.color - both.overlays += standing + if(!l_ear && !r_ear) + return //Why bother, if no ear sprites + + // Blank image upon which to layer left & right overlays. + var/image/both = image(icon = 'icons/effects/effects.dmi', icon_state = "nothing", layer = BODY_LAYER+EARS_LAYER) - if(r_ear) - var/image/standing - var/t_type = r_ear.icon_state - if(r_ear.icon_override) - t_type = "[t_type]_r" - standing = image("icon" = r_ear.icon_override, "icon_state" = "[t_type]") - else if(r_ear.sprite_sheets && r_ear.sprite_sheets[species.get_bodytype(src)]) - t_type = "[t_type]_r" - standing = image("icon" = r_ear.sprite_sheets[species.get_bodytype(src)], "icon_state" = "[t_type]") - else - standing = image("icon" = 'icons/mob/ears.dmi', "icon_state" = "[t_type]") - if(r_ear.addblends) - var/icon/base = new/icon("icon" = standing.icon, "icon_state" = standing.icon_state) - var/addblend_icon = new/icon("icon" = standing.icon, "icon_state" = r_ear.addblends) - if(r_ear.color) - base.Blend(r_ear.color, ICON_MULTIPLY) - base.Blend(addblend_icon, ICON_ADD) - standing = image(base) - else - standing.color = r_ear.color - both.overlays += standing + if(l_ear) + var/image/standing = l_ear.make_worn_icon(body_type = species.get_bodytype(), slot_name = slot_l_ear_str, default_icon = INV_EARS_DEF_ICON, default_layer = EARS_LAYER) + both.add_overlay(standing) - overlays_standing[EARS_LAYER] = both + if(r_ear) + var/image/standing = r_ear.make_worn_icon(body_type = species.get_bodytype(), slot_name = slot_r_ear_str, default_icon = INV_EARS_DEF_ICON, default_layer = EARS_LAYER) + both.add_overlay(standing) - else - overlays_standing[EARS_LAYER] = null - if(update_icons) update_icons_layers() + overlays_standing[EARS_LAYER] = both + apply_layer(EARS_LAYER) -/mob/living/carbon/human/update_inv_shoes(var/update_icons=1) +/mob/living/carbon/human/update_inv_shoes() if(QDESTROYING(src)) return - if(shoes && !((wear_suit && wear_suit.flags_inv & HIDESHOES) || (w_uniform && w_uniform.flags_inv & HIDESHOES))) + remove_layer(SHOES_LAYER) + remove_layer(SHOES_LAYER_ALT) //Dumb alternate layer for shoes being under the uniform. - var/image/standing - if(shoes.icon_override) - standing = image("icon" = shoes.icon_override, "icon_state" = "[shoes.icon_state]") - else if(shoes.sprite_sheets && shoes.sprite_sheets[species.get_bodytype(src)]) - standing = image("icon" = shoes.sprite_sheets[species.get_bodytype(src)], "icon_state" = "[shoes.icon_state]") - else - standing = image("icon" = 'icons/mob/feet.dmi', "icon_state" = "[shoes.icon_state]") + if(!shoes || (wear_suit && wear_suit.flags_inv & HIDESHOES) || (w_uniform && w_uniform.flags_inv & HIDESHOES)) + return //Either nothing to draw, or it'd be hidden. - var/shoe_layer = SHOES_LAYER - if(istype(shoes, /obj/item/clothing/shoes)) - var/obj/item/clothing/shoes/ushoes = shoes - if(ushoes.shoes_under_pants == 1) - overlays_standing[SHOES_LAYER] = null - shoe_layer = SHOES_LAYER_ALT - else - overlays_standing[SHOES_LAYER_ALT] = null - shoe_layer = SHOES_LAYER + //Allow for shoe layer toggle nonsense + var/shoe_layer = SHOES_LAYER + if(istype(shoes, /obj/item/clothing/shoes)) + var/obj/item/clothing/shoes/ushoes = shoes + if(ushoes.shoes_under_pants == 1) + shoe_layer = SHOES_LAYER_ALT - if(shoes.blood_DNA) - var/image/bloodsies = image("icon" = species.get_blood_mask(src), "icon_state" = "shoeblood") - bloodsies.color = shoes.blood_color - standing.overlays += bloodsies - - if(shoes.addblends) - var/icon/base = new/icon("icon" = standing.icon, "icon_state" = standing.icon_state) - var/addblend_icon = new/icon("icon" = standing.icon, "icon_state" = shoes.addblends) - if(shoes.color) - base.Blend(shoes.color, ICON_MULTIPLY) - base.Blend(addblend_icon, ICON_ADD) - standing = image(base) - else - standing.color = shoes.color - overlays_standing[shoe_layer] = standing - - else - if(feet_blood_DNA) - var/image/bloodsies = image("icon" = species.get_blood_mask(src), "icon_state" = "shoeblood") - bloodsies.color = feet_blood_color - overlays_standing[SHOES_LAYER] = bloodsies - else - overlays_standing[SHOES_LAYER] = null - overlays_standing[SHOES_LAYER_ALT] = null - if(update_icons) update_icons_layers() - -/mob/living/carbon/human/update_inv_s_store(var/update_icons=1) + //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(), slot_name = slot_shoes_str, default_icon = INV_FEET_DEF_ICON, default_layer = shoe_layer) + + apply_layer(SHOES_LAYER) + apply_layer(SHOES_LAYER_ALT) + +/mob/living/carbon/human/update_inv_s_store() if(QDESTROYING(src)) return - if(s_store) - var/t_state = s_store.item_state - if(!t_state) t_state = s_store.icon_state - overlays_standing[SUIT_STORE_LAYER] = image("icon" = species.suit_storage_icon, "icon_state" = "[t_state]") - s_store.screen_loc = ui_sstore1 //TODO - else - overlays_standing[SUIT_STORE_LAYER] = null - if(update_icons) update_icons_layers() + remove_layer(SUIT_STORE_LAYER) + if(!s_store) + return //Why bother, nothing there. + + //TODO, this is unlike the rest of the things + //Basically has no variety in slot icon choices at all. WHY SPECIES ONLY?? + var/t_state = s_store.item_state + if(!t_state) + t_state = s_store.icon_state + overlays_standing[SUIT_STORE_LAYER] = image(icon = species.suit_storage_icon, icon_state = t_state, layer = BODY_LAYER+SUIT_STORE_LAYER) + + apply_layer(SUIT_STORE_LAYER) -/mob/living/carbon/human/update_inv_head(var/update_icons=1) +/mob/living/carbon/human/update_inv_head() if(QDESTROYING(src)) return - if(head) - head.screen_loc = ui_head //TODO + remove_layer(HEAD_LAYER) + + if(!head) + return //No head item, why bother. - //Determine the icon to use - var/t_icon - if(head.icon_override) - t_icon = head.icon_override - else if(head.sprite_sheets && head.sprite_sheets[species.get_bodytype(src)]) - t_icon = head.sprite_sheets[species.get_bodytype(src)] + overlays_standing[HEAD_LAYER] = head.make_worn_icon(body_type = species.get_bodytype(), slot_name = slot_head_str, default_icon = INV_HEAD_DEF_ICON, default_layer = HEAD_LAYER) + + apply_layer(HEAD_LAYER) - else if(head.item_icons && (slot_head_str in head.item_icons)) - t_icon = head.item_icons[slot_head_str] - else - t_icon = INV_HEAD_DEF_ICON - - //Determine the state to use - var/t_state - if(istype(head, /obj/item/weapon/paper)) - /* I don't like this, but bandaid to fix half the hats in the game - being completely broken without re-breaking paper hats */ - t_state = "paper" - else - if(head.item_state_slots && head.item_state_slots[slot_head_str]) - t_state = head.item_state_slots[slot_head_str] - else if(head.item_state) - t_state = head.item_state - else - t_state = head.icon_state - - //Create the image - var/image/standing = image(icon = t_icon, icon_state = t_state) - - if(head.blood_DNA) - var/image/bloodsies = image("icon" = species.get_blood_mask(src), "icon_state" = "helmetblood") - bloodsies.color = head.blood_color - standing.overlays += bloodsies - - if(istype(head,/obj/item/clothing/head)) - var/obj/item/clothing/head/hat = head - var/cache_key = "[hat.light_overlay]_[species.get_bodytype(src)]" - if(hat.on && light_overlay_cache[cache_key]) - standing.overlays |= light_overlay_cache[cache_key] - - if(head.addblends) - var/icon/base = new/icon("icon" = standing.icon, "icon_state" = standing.icon_state) - var/addblend_icon = new/icon("icon" = standing.icon, "icon_state" = head.addblends) - if(head.color) - base.Blend(head.color, ICON_MULTIPLY) - base.Blend(addblend_icon, ICON_ADD) - standing = image(base) - else - standing.color = head.color - - // Accessories - copied from uniform, BOILERPLATE because fuck this system. - var/obj/item/clothing/head/hat = head - if(istype(hat) && hat.accessories.len) - for(var/obj/item/clothing/accessory/A in hat.accessories) - standing.overlays |= A.get_mob_overlay() - - overlays_standing[HEAD_LAYER] = standing - - else - overlays_standing[HEAD_LAYER] = null - if(update_icons) update_icons_layers() - -/mob/living/carbon/human/update_inv_belt(var/update_icons=1) +/mob/living/carbon/human/update_inv_belt() if(QDESTROYING(src)) return - if(belt) - belt.screen_loc = ui_belt //TODO - var/t_state = belt.item_state - if(!t_state) t_state = belt.icon_state - var/image/standing = image("icon_state" = "[t_state]") + remove_layer(BELT_LAYER) + remove_layer(BELT_LAYER_ALT) //Because you can toggle belt layer with a verb - if(belt.icon_override) - standing.icon = belt.icon_override - else if(belt.sprite_sheets && belt.sprite_sheets[species.get_bodytype(src)]) - standing.icon = belt.sprite_sheets[species.get_bodytype(src)] - else - standing.icon = 'icons/mob/belt.dmi' + if(!belt) + return //No belt, why bother. + + //Toggle for belt layering with uniform + var/belt_layer = BELT_LAYER + if(istype(belt, /obj/item/weapon/storage/belt)) + var/obj/item/weapon/storage/belt/ubelt = belt + if(ubelt.show_above_suit) + belt_layer = BELT_LAYER_ALT - var/belt_layer = BELT_LAYER - if(istype(belt, /obj/item/weapon/storage/belt)) - var/obj/item/weapon/storage/belt/ubelt = belt - if(ubelt.show_above_suit) - overlays_standing[BELT_LAYER] = null - belt_layer = BELT_LAYER_ALT - else - overlays_standing[BELT_LAYER_ALT] = null - if(belt.contents.len) - for(var/obj/item/i in belt.contents) - var/i_state = i.item_state - if(!i_state) i_state = i.icon_state - standing.overlays += image("icon" = 'icons/mob/belt.dmi', "icon_state" = "[i_state]") + //NB: this uses a var from above + overlays_standing[belt_layer] = belt.make_worn_icon(body_type = species.get_bodytype(), slot_name = slot_belt_str, default_icon = INV_BELT_DEF_ICON, default_layer = belt_layer) + + apply_layer(belt_layer) - if(belt.addblends) - var/icon/base = new/icon("icon" = standing.icon, "icon_state" = standing.icon_state) - var/addblend_icon = new/icon("icon" = standing.icon, "icon_state" = belt.addblends) - if(belt.color) - base.Blend(belt.color, ICON_MULTIPLY) - base.Blend(addblend_icon, ICON_ADD) - standing = image(base) - else - standing.color = belt.color - - overlays_standing[belt_layer] = standing - else - overlays_standing[BELT_LAYER] = null - overlays_standing[BELT_LAYER_ALT] = null - if(update_icons) update_icons_layers() - - -/mob/living/carbon/human/update_inv_wear_suit(var/update_icons=1) +/mob/living/carbon/human/update_inv_wear_suit() if(QDESTROYING(src)) return - if( wear_suit && istype(wear_suit, /obj/item/) ) - wear_suit.screen_loc = ui_oclothing - - var/image/standing - - var/t_icon = INV_SUIT_DEF_ICON - if(wear_suit.icon_override) - t_icon = wear_suit.icon_override - else if(wear_suit.sprite_sheets && wear_suit.sprite_sheets[species.get_bodytype(src)]) - t_icon = wear_suit.sprite_sheets[species.name] - else if(wear_suit.item_icons && wear_suit.item_icons[slot_wear_suit_str]) - t_icon = wear_suit.item_icons[slot_wear_suit_str] - - standing = image("icon" = t_icon, "icon_state" = "[wear_suit.icon_state]") - - if(wear_suit.addblends) - var/icon/base = new/icon("icon" = standing.icon, "icon_state" = standing.icon_state) - var/addblend_icon = new/icon("icon" = standing.icon, "icon_state" = wear_suit.addblends) - if(wear_suit.color) - base.Blend(wear_suit.color, ICON_MULTIPLY) - base.Blend(addblend_icon, ICON_ADD) - standing = image(base) - else - standing.color = wear_suit.color - - if( istype(wear_suit, /obj/item/clothing/suit/straight_jacket) ) - drop_from_inventory(handcuffed) - drop_l_hand() - drop_r_hand() - - if(wear_suit.blood_DNA) - var/obj/item/clothing/suit/S = wear_suit - if(istype(S)) //You can put non-suits in your suit slot (diona nymphs etc). - var/image/bloodsies = image("icon" = species.get_blood_mask(src), "icon_state" = "[S.blood_overlay_type]blood") - bloodsies.color = wear_suit.blood_color - standing.overlays += bloodsies - - // Accessories - copied from uniform, BOILERPLATE because fuck this system. - var/obj/item/clothing/suit/suit = wear_suit - if(istype(suit) && suit.accessories.len) - for(var/obj/item/clothing/accessory/A in suit.accessories) - standing.overlays |= A.get_mob_overlay() - - overlays_standing[SUIT_LAYER] = standing - - else - overlays_standing[SUIT_LAYER] = null + remove_layer(SUIT_LAYER) //Hide/show other layers if necessary - update_collar(0) - update_inv_w_uniform(0) - update_inv_shoes(0) - update_tail_showing(0) + update_inv_w_uniform() + update_inv_shoes() + update_tail_showing() - if(update_icons) update_icons_layers() + if(!wear_suit) + return //No point, no suit. -/mob/living/carbon/human/update_inv_pockets(var/update_icons=1) + overlays_standing[SUIT_LAYER] = wear_suit.make_worn_icon(body_type = species.get_bodytype(), slot_name = slot_wear_suit_str, default_icon = INV_SUIT_DEF_ICON, default_layer = SUIT_LAYER) + + apply_layer(SUIT_LAYER) + +/mob/living/carbon/human/update_inv_pockets() + crash_with("Someone called update_inv_pockets even though it's dumb") + +/mob/living/carbon/human/update_inv_wear_mask() if(QDESTROYING(src)) return - if(l_store) l_store.screen_loc = ui_storage1 //TODO - if(r_store) r_store.screen_loc = ui_storage2 //TODO - if(update_icons) update_icons_layers() + remove_layer(FACEMASK_LAYER) + 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(), slot_name = slot_wear_mask_str, default_icon = INV_MASK_DEF_ICON, default_layer = FACEMASK_LAYER) + + apply_layer(FACEMASK_LAYER) -/mob/living/carbon/human/update_inv_wear_mask(var/update_icons=1) +/mob/living/carbon/human/update_inv_back() if(QDESTROYING(src)) return - if( wear_mask && ( istype(wear_mask, /obj/item/clothing/mask) || istype(wear_mask, /obj/item/clothing/accessory) || istype(wear_mask, /obj/item/weapon/grenade) ) && !(head && head.flags_inv & HIDEMASK)) - wear_mask.screen_loc = ui_mask //TODO + remove_layer(BACK_LAYER) - var/image/standing - if(wear_mask.icon_override) - standing = image("icon" = wear_mask.icon_override, "icon_state" = "[wear_mask.icon_state]") - else if(wear_mask.sprite_sheets && wear_mask.sprite_sheets[species.get_bodytype(src)]) - standing = image("icon" = wear_mask.sprite_sheets[species.get_bodytype(src)], "icon_state" = "[wear_mask.icon_state]") - else - standing = image("icon" = 'icons/mob/mask.dmi', "icon_state" = "[wear_mask.icon_state]") - if(wear_mask.addblends) - var/icon/base = new/icon("icon" = standing.icon, "icon_state" = standing.icon_state) - var/addblend_icon = new/icon("icon" = standing.icon, "icon_state" = wear_mask.addblends) - if(wear_mask.color) - base.Blend(wear_mask.color, ICON_MULTIPLY) - base.Blend(addblend_icon, ICON_ADD) - standing = image(base) - else - standing.color = wear_mask.color + if(!back) + return //Why do anything - if( !istype(wear_mask, /obj/item/clothing/mask/smokable/cigarette) && wear_mask.blood_DNA ) - var/image/bloodsies = image("icon" = species.get_blood_mask(src), "icon_state" = "maskblood") - bloodsies.color = wear_mask.blood_color - standing.overlays += bloodsies - overlays_standing[FACEMASK_LAYER] = standing - else - overlays_standing[FACEMASK_LAYER] = null - if(update_icons) update_icons_layers() - - -/mob/living/carbon/human/update_inv_back(var/update_icons=1) - if(QDESTROYING(src)) - return - - if(back) - back.screen_loc = ui_back //TODO - - //determine the icon to use - var/icon/overlay_icon - if(back.icon_override) - overlay_icon = back.icon_override - else if(istype(back, /obj/item/weapon/rig)) - //If this is a rig and a mob_icon is set, it will take species into account in the rig update_icon() proc. - var/obj/item/weapon/rig/rig = back - overlay_icon = rig.mob_icon - else if(back.sprite_sheets && back.sprite_sheets[species.get_bodytype(src)]) - overlay_icon = back.sprite_sheets[species.get_bodytype(src)] - else if(back.item_icons && (slot_back_str in back.item_icons)) - overlay_icon = back.item_icons[slot_back_str] - else - overlay_icon = INV_BACK_DEF_ICON - - //determine state to use - var/overlay_state - if(back.item_state_slots && back.item_state_slots[slot_back_str]) - overlay_state = back.item_state_slots[slot_back_str] - else if(back.item_state) - overlay_state = back.item_state - else - overlay_state = back.icon_state - - //apply color - var/image/standing = image(icon = overlay_icon, icon_state = overlay_state) - if(back.addblends) - var/icon/base = new/icon("icon" = standing.icon, "icon_state" = standing.icon_state) - var/addblend_icon = new/icon("icon" = standing.icon, "icon_state" = back.addblends) - if(back.color) - base.Blend(back.color, ICON_MULTIPLY) - base.Blend(addblend_icon, ICON_ADD) - standing = image(base) - else - standing.color = back.color - - //create the image - overlays_standing[BACK_LAYER] = standing - else - overlays_standing[BACK_LAYER] = null - - if(update_icons) - update_icons_layers() + overlays_standing[BACK_LAYER] = back.make_worn_icon(body_type = species.get_bodytype(), slot_name = slot_back_str, default_icon = INV_BACK_DEF_ICON, default_layer = BACK_LAYER) + + apply_layer(BACK_LAYER) +//TODO: Carbon procs in my human update_icons?? /mob/living/carbon/human/update_hud() //TODO: do away with this if possible if(QDESTROYING(src)) return @@ -1211,148 +760,73 @@ var/global/list/damage_icon_parts = list() hud_used.l_hand_hud_object.update_icon() hud_used.r_hand_hud_object.update_icon() -/mob/living/carbon/human/update_inv_handcuffed(var/update_icons=1) +/mob/living/carbon/human/update_inv_handcuffed() if(QDESTROYING(src)) return - if(handcuffed) - drop_r_hand() - drop_l_hand() - stop_pulling() //TODO: should be handled elsewhere + remove_layer(HANDCUFF_LAYER) + update_hud_handcuffed() //TODO - var/image/standing - if(handcuffed.icon_override) - standing = image("icon" = handcuffed.icon_override, "icon_state" = "handcuff1") - else if(handcuffed.sprite_sheets && handcuffed.sprite_sheets[species.get_bodytype(src)]) - standing = image("icon" = handcuffed.sprite_sheets[species.get_bodytype(src)], "icon_state" = "handcuff1") - else - standing = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "handcuff1") - overlays_standing[HANDCUFF_LAYER] = standing + if(!handcuffed) + return //Not cuffed, why bother - else - overlays_standing[HANDCUFF_LAYER] = null + overlays_standing[HANDCUFF_LAYER] = handcuffed.make_worn_icon(body_type = species.get_bodytype(), slot_name = slot_handcuffed_str, default_icon = INV_HCUFF_DEF_ICON, default_layer = HANDCUFF_LAYER) + + apply_layer(HANDCUFF_LAYER) - update_hud_handcuffed() - if(update_icons) update_icons_layers() - -/mob/living/carbon/human/update_inv_legcuffed(var/update_icons=1) +/mob/living/carbon/human/update_inv_legcuffed() if(QDESTROYING(src)) return - if(legcuffed) + remove_layer(LEGCUFF_LAYER) - var/image/standing - if(legcuffed.icon_override) - standing = image("icon" = legcuffed.icon_override, "icon_state" = "legcuff1") - else if(legcuffed.sprite_sheets && legcuffed.sprite_sheets[species.get_bodytype(src)]) - standing = image("icon" = legcuffed.sprite_sheets[species.get_bodytype(src)], "icon_state" = "legcuff1") - else - standing = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "legcuff1") - overlays_standing[LEGCUFF_LAYER] = standing + if(!legcuffed) + return //Not legcuffed, why bother. - if(src.m_intent != "walk") - src.m_intent = "walk" - if(src.hud_used && src.hud_used.move_intent) - src.hud_used.move_intent.icon_state = "walking" + overlays_standing[LEGCUFF_LAYER] = handcuffed.make_worn_icon(body_type = species.get_bodytype(), slot_name = slot_legcuffed_str, default_icon = INV_LCUFF_DEF_ICON, default_layer = LEGCUFF_LAYER) + + apply_layer(LEGCUFF_LAYER) - else - overlays_standing[LEGCUFF_LAYER] = null - if(update_icons) update_icons_layers() - - -/mob/living/carbon/human/update_inv_r_hand(var/update_icons=1) +/mob/living/carbon/human/update_inv_r_hand() if(QDESTROYING(src)) return - if(r_hand) - r_hand.screen_loc = ui_rhand //TODO + remove_layer(R_HAND_LAYER) - //determine icon state to use - var/t_state - if(r_hand.item_state_slots && r_hand.item_state_slots[slot_r_hand_str]) - t_state = r_hand.item_state_slots[slot_r_hand_str] - else if(r_hand.item_state) - t_state = r_hand.item_state - else - t_state = r_hand.icon_state + if(!r_hand) + return //No hand, no bother. - //determine icon to use - var/icon/t_icon - if(r_hand.item_icons && (slot_r_hand_str in r_hand.item_icons)) - t_icon = r_hand.item_icons[slot_r_hand_str] - else if(r_hand.icon_override) - t_state += "_r" - t_icon = r_hand.icon_override - else - t_icon = INV_R_HAND_DEF_ICON + overlays_standing[R_HAND_LAYER] = r_hand.make_worn_icon(body_type = species.get_bodytype(), inhands = TRUE, slot_name = slot_r_hand_str, default_icon = INV_R_HAND_DEF_ICON, default_layer = R_HAND_LAYER) + + apply_layer(R_HAND_LAYER) - //apply color - var/image/standing = image(icon = t_icon, icon_state = t_state) - standing.color = r_hand.color - - overlays_standing[R_HAND_LAYER] = standing - - if (handcuffed) drop_r_hand() //this should be moved out of icon code - else - overlays_standing[R_HAND_LAYER] = null - - if(update_icons) update_icons_layers() - - -/mob/living/carbon/human/update_inv_l_hand(var/update_icons=1) +/mob/living/carbon/human/update_inv_l_hand() if(QDESTROYING(src)) return - if(l_hand) - l_hand.screen_loc = ui_lhand //TODO + remove_layer(L_HAND_LAYER) - //determine icon state to use - var/t_state - if(l_hand.item_state_slots && l_hand.item_state_slots[slot_l_hand_str]) - t_state = l_hand.item_state_slots[slot_l_hand_str] - else if(l_hand.item_state) - t_state = l_hand.item_state - else - t_state = l_hand.icon_state + if(!l_hand) + return //No hand, no bother. - //determine icon to use - var/icon/t_icon - if(l_hand.item_icons && (slot_l_hand_str in l_hand.item_icons)) - t_icon = l_hand.item_icons[slot_l_hand_str] - else if(l_hand.icon_override) - t_state += "_l" - t_icon = l_hand.icon_override - else - t_icon = INV_L_HAND_DEF_ICON + overlays_standing[L_HAND_LAYER] = l_hand.make_worn_icon(body_type = species.get_bodytype(), inhands = TRUE, slot_name = slot_l_hand_str, default_icon = INV_L_HAND_DEF_ICON, default_layer = L_HAND_LAYER) - //apply color - var/image/standing = image(icon = t_icon, icon_state = t_state) - standing.color = l_hand.color + apply_layer(L_HAND_LAYER) - overlays_standing[L_HAND_LAYER] = standing - - if (handcuffed) drop_l_hand() //This probably should not be here - else - overlays_standing[L_HAND_LAYER] = null - - if(update_icons) update_icons_layers() - -/mob/living/carbon/human/proc/update_tail_showing(var/update_icons=1) +/mob/living/carbon/human/proc/update_tail_showing() if(QDESTROYING(src)) return - overlays_standing[TAIL_LAYER] = null - - var/species_tail = species.get_tail(src) + remove_layer(TAIL_LAYER) + var/species_tail = species.get_tail(src) // Species tail icon_state prefix. + //This one is actually not that bad I guess. if(species_tail && !(wear_suit && wear_suit.flags_inv & HIDETAIL)) var/icon/tail_s = get_tail_icon() - overlays_standing[TAIL_LAYER] = image(tail_s, icon_state = "[species_tail]_s") - animate_tail_reset(0) - - if(update_icons) - update_icons_layers() + overlays_standing[TAIL_LAYER] = image(icon = tail_s, icon_state = "[species_tail]_s", layer = BODY_LAYER+TAIL_LAYER) + animate_tail_reset() +//TODO: Is this the appropriate place for this, and not on species...? /mob/living/carbon/human/proc/get_tail_icon() var/icon_key = "[species.get_race_key(src)][r_skin][g_skin][b_skin][r_hair][g_hair][b_hair]" var/icon/tail_icon = tail_icon_cache[icon_key] @@ -1372,18 +846,23 @@ var/global/list/damage_icon_parts = list() return tail_icon - /mob/living/carbon/human/proc/set_tail_state(var/t_state) var/image/tail_overlay = overlays_standing[TAIL_LAYER] - - if(tail_overlay && species.get_tail_animation(src)) - tail_overlay.icon_state = t_state - return tail_overlay - return null + + remove_layer(TAIL_LAYER) + + if(tail_overlay) + overlays_standing[TAIL_LAYER] = tail_overlay + if(species.get_tail_animation(src)) + tail_overlay.icon_state = t_state + . = tail_overlay + + apply_layer(TAIL_LAYER) //Not really once, since BYOND can't do that. //Update this if the ability to flick() images or make looping animation start at the first frame is ever added. -/mob/living/carbon/human/proc/animate_tail_once(var/update_icons=1) +//You can sort of flick images now with flick_overlay -Aro +/mob/living/carbon/human/proc/animate_tail_once() if(QDESTROYING(src)) return @@ -1393,35 +872,26 @@ var/global/list/damage_icon_parts = list() if(tail_overlay && tail_overlay.icon_state == t_state) return //let the existing animation finish - tail_overlay = set_tail_state(t_state) + tail_overlay = set_tail_state(t_state) // Calls remove_layer & apply_layer if(tail_overlay) spawn(20) //check that the animation hasn't changed in the meantime if(overlays_standing[TAIL_LAYER] == tail_overlay && tail_overlay.icon_state == t_state) - animate_tail_stop() + animate_tail_stop() - if(update_icons) - update_icons_layers() - -/mob/living/carbon/human/proc/animate_tail_start(var/update_icons=1) +/mob/living/carbon/human/proc/animate_tail_start() if(QDESTROYING(src)) return set_tail_state("[species.get_tail(src)]_slow[rand(0,9)]") - if(update_icons) - update_icons_layers() - -/mob/living/carbon/human/proc/animate_tail_fast(var/update_icons=1) +/mob/living/carbon/human/proc/animate_tail_fast() if(QDESTROYING(src)) return set_tail_state("[species.get_tail(src)]_loop[rand(0,9)]") - if(update_icons) - update_icons_layers() - -/mob/living/carbon/human/proc/animate_tail_reset(var/update_icons=1) +/mob/living/carbon/human/proc/animate_tail_reset() if(QDESTROYING(src)) return @@ -1430,113 +900,104 @@ var/global/list/damage_icon_parts = list() else set_tail_state("[species.get_tail(src)]_static") - if(update_icons) - update_icons_layers() - -/mob/living/carbon/human/proc/animate_tail_stop(var/update_icons=1) +/mob/living/carbon/human/proc/animate_tail_stop() if(QDESTROYING(src)) return set_tail_state("[species.get_tail(src)]_static") - if(update_icons) - update_icons_layers() - - -//Adds a collar overlay above the helmet layer if the suit has one -// Suit needs an identically named sprite in icons/mob/collar.dmi -/mob/living/carbon/human/proc/update_collar(var/update_icons=1) +/mob/living/carbon/human/update_modifier_visuals() if(QDESTROYING(src)) return - var/icon/C = new('icons/mob/collar.dmi') - var/image/standing = null + remove_layer(MODIFIER_EFFECTS_LAYER) - if(wear_suit) - if(wear_suit.icon_state in C.IconStates()) - standing = image("icon" = C, "icon_state" = "[wear_suit.icon_state]") + if(!LAZYLEN(modifiers)) + return //No modifiers, no effects. - overlays_standing[COLLAR_LAYER] = standing - - if(update_icons) update_icons_layers() - -/mob/living/carbon/human/update_modifier_visuals(var/update_icons=1) - if(QDESTROYING(src)) - return - - overlays_standing[MODIFIER_EFFECTS_LAYER] = null var/image/effects = new() for(var/datum/modifier/M in modifiers) if(M.mob_overlay_state) - var/image/I = image("icon" = 'icons/mob/modifier_effects.dmi', "icon_state" = M.mob_overlay_state) - effects.overlays += I + var/image/I = image(icon = 'icons/mob/modifier_effects.dmi', icon_state = M.mob_overlay_state) + effects.overlays += I //TODO, this compositing is annoying. overlays_standing[MODIFIER_EFFECTS_LAYER] = effects + + apply_layer(MODIFIER_EFFECTS_LAYER) - if(update_icons) - update_icons_layers() - -/mob/living/carbon/human/update_fire(var/update_icons=1) +/mob/living/carbon/human/update_fire() if(QDESTROYING(src)) return - overlays_standing[FIRE_LAYER] = null - if(on_fire) - overlays_standing[FIRE_LAYER] = image("icon"='icons/mob/OnFire.dmi', "icon_state" = get_fire_icon_state()) + remove_layer(FIRE_LAYER) + + if(!on_fire) + return + + overlays_standing[FIRE_LAYER] = image(icon = 'icons/mob/OnFire.dmi', icon_state = get_fire_icon_state(), layer = BODY_LAYER+FIRE_LAYER) + + apply_layer(FIRE_LAYER) - if(update_icons) update_icons_layers() - -/mob/living/carbon/human/update_water(var/update_icons=1) +/mob/living/carbon/human/update_water() if(QDESTROYING(src)) return - overlays_standing[WATER_LAYER] = null + remove_layer(WATER_LAYER) + var/depth = check_submerged() - if(depth) - if(!lying) - overlays_standing[WATER_LAYER] = image("icon" = 'icons/mob/submerged.dmi', "icon_state" = "human_swimming_[depth]") - // Lying sideways with the overlay looked strange. Another overlay will be needed in the future. + if(!depth || lying) + return - if(update_icons) - update_icons_layers() + overlays_standing[WATER_LAYER] = image(icon = 'icons/mob/submerged.dmi', icon_state = "human_swimming_[depth]", layer = BODY_LAYER+WATER_LAYER) //TODO: Improve + + apply_layer(WATER_LAYER) -/mob/living/carbon/human/proc/update_surgery(var/update_icons=1) +/mob/living/carbon/human/proc/update_surgery() if(QDESTROYING(src)) return - overlays_standing[SURGERY_LEVEL] = null + remove_layer(SURGERY_LAYER) + var/image/total = new for(var/obj/item/organ/external/E in organs) if(E.open) - var/image/I = image("icon"='icons/mob/surgery.dmi', "icon_state"="[E.icon_name][round(E.open)]", "layer"=-SURGERY_LEVEL) - total.overlays += I - overlays_standing[SURGERY_LEVEL] = total - if(update_icons) update_icons_layers() + var/image/I = image(icon = 'icons/mob/surgery.dmi', icon_state = "[E.icon_name][round(E.open)]", layer = BODY_LAYER+SURGERY_LAYER) + total.overlays += I //TODO: This compositing is annoying + + if(total.overlays.len) + overlays_standing[SURGERY_LAYER] = total + apply_layer(SURGERY_LAYER) //Human Overlays Indexes///////// #undef MUTATIONS_LAYER +#undef SKIN_LAYER #undef DAMAGE_LAYER -#undef SURGERY_LEVEL +#undef SURGERY_LAYER +#undef UNDERWEAR_LAYER +#undef SHOES_LAYER_ALT #undef UNIFORM_LAYER #undef ID_LAYER #undef SHOES_LAYER #undef GLOVES_LAYER -#undef EARS_LAYER +#undef BELT_LAYER #undef SUIT_LAYER #undef TAIL_LAYER #undef GLASSES_LAYER -#undef FACEMASK_LAYER -#undef BELT_LAYER +#undef BELT_LAYER_ALT #undef SUIT_STORE_LAYER #undef BACK_LAYER #undef HAIR_LAYER +#undef EARS_LAYER +#undef EYES_LAYER +#undef FACEMASK_LAYER #undef HEAD_LAYER #undef COLLAR_LAYER #undef HANDCUFF_LAYER #undef LEGCUFF_LAYER #undef L_HAND_LAYER #undef R_HAND_LAYER -#undef TARGETED_LAYER +#undef MODIFIER_EFFECTS_LAYER #undef FIRE_LAYER #undef WATER_LAYER +#undef TARGETED_LAYER #undef TOTAL_LAYERS \ No newline at end of file diff --git a/code/modules/mob/living/inventory.dm b/code/modules/mob/living/inventory.dm index 60be7fb8b5..4a651af999 100644 --- a/code/modules/mob/living/inventory.dm +++ b/code/modules/mob/living/inventory.dm @@ -72,16 +72,16 @@ /mob/living/u_equip(obj/W as obj) if (W == r_hand) r_hand = null - update_inv_r_hand(0) + update_inv_r_hand() else if (W == l_hand) l_hand = null - update_inv_l_hand(0) + update_inv_l_hand() else if (W == back) back = null - update_inv_back(0) + update_inv_back() else if (W == wear_mask) wear_mask = null - update_inv_wear_mask(0) + update_inv_wear_mask() return /mob/living/get_equipped_item(var/slot) diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 6b02734a7e..e81308423d 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -111,15 +111,11 @@ /mob/living/proc/handle_stunned() if(stunned) AdjustStunned(-1) - if(!stunned) - update_icons() return stunned /mob/living/proc/handle_weakened() if(weakened) weakened = max(weakened-1,0) - if(!weakened) - update_icons() return weakened /mob/living/proc/handle_stuttering() @@ -145,8 +141,6 @@ /mob/living/proc/handle_paralysed() if(paralysis) AdjustParalysis(-1) - if(!paralysis) - update_icons() return paralysis /mob/living/proc/handle_disabilities() diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 228fa7853d..39520be29d 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1,6 +1,13 @@ /mob/living/New() ..() + //Prime this list if we need it. + if(has_huds) + add_overlay(backplane,TRUE) //Strap this on here, to block HUDs from appearing in rightclick menus: http://www.byond.com/forum/?post=2336679 + hud_list = list() + hud_list.len = TOTAL_HUDS + make_hud_overlays() + //I'll just hang my coat up over here dsoverlay = image('icons/mob/darksight.dmi',global_hud.darksight) //This is a secret overlay! Go look at the file, you'll see. var/mutable_appearance/dsma = new(dsoverlay) //Changing like ten things, might as well. @@ -855,6 +862,7 @@ default behaviour is: resting = !resting to_chat(src, "You are now [resting ? "resting" : "getting up"]") + update_canmove() /mob/living/proc/cannot_use_vents() if(mob_size > MOB_SMALL) @@ -1002,14 +1010,10 @@ default behaviour is: canmove = 0 break - //Temporarily moved here from the various life() procs - //I'm fixing stuff incrementally so this will likely find a better home. - //It just makes sense for now. ~Carn - if( update_icon ) //forces a full overlay update - update_icon = 0 - regenerate_icons() - else if( lying != lying_prev ) - update_icons() + if(lying != lying_prev) + lying_prev = lying + update_transform() + return canmove // Adds overlays for specific modifiers. @@ -1162,3 +1166,22 @@ default behaviour is: item.throw_at(target, throw_range, item.throw_speed, src) + +//Add an entry to overlays, assuming it exists +/mob/living/proc/apply_hud(cache_index, var/image/I) + hud_list[cache_index] = I + if((. = hud_list[cache_index])) + //underlays += . + add_overlay(.) + +//Remove an entry from overlays, and from the list +/mob/living/proc/grab_hud(cache_index) + var/I = hud_list[cache_index] + if(I) + //underlays -= I + cut_overlay(I) + hud_list[cache_index] = null + return I + +/mob/living/proc/make_hud_overlays() + return \ No newline at end of file diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index b36cd29d21..23dbb6fc09 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -54,3 +54,6 @@ var/glow_range = 2 var/glow_intensity = null var/glow_color = "#FFFFFF" // The color they're glowing! + + var/list/hud_list //Holder for health hud, status hud, wanted hud, etc (not like inventory slots) + var/has_huds = FALSE //Whether or not we should bother initializing the above list diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index 09321af981..0d88e0c96f 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -7,7 +7,7 @@ var/list/stating_laws = list()// Channels laws are currently being stated on var/obj/item/device/radio/common_radio - var/list/hud_list[10] + has_huds = TRUE var/list/speech_synthesizer_langs = list() //which languages can be vocalized by the speech synthesizer //Used in say.dm. diff --git a/code/modules/mob/living/simple_animal/simple_hud.dm b/code/modules/mob/living/simple_animal/simple_hud.dm index cd3ed61355..5da7e8a696 100644 --- a/code/modules/mob/living/simple_animal/simple_hud.dm +++ b/code/modules/mob/living/simple_animal/simple_hud.dm @@ -12,6 +12,7 @@ var/list/adding = list() var/list/other = list() var/list/hotkeybuttons = list() + var/list/slot_info = list() hud.adding = adding hud.other = other @@ -34,6 +35,7 @@ inv_box.screen_loc = slot_data["loc"] inv_box.slot_id = slot_data["slot"] inv_box.icon_state = slot_data["state"] + slot_info["[inv_box.slot_id]"] = inv_box.screen_loc if(slot_data["dir"]) inv_box.set_dir(slot_data["dir"]) @@ -249,9 +251,9 @@ inv_box.slot_id = slot_r_hand inv_box.color = ui_color inv_box.alpha = ui_alpha - hud.r_hand_hud_object = inv_box hud.adding += inv_box + slot_info["[slot_r_hand]"] = inv_box.screen_loc inv_box = new /obj/screen/inventory/hand() inv_box.hud = src @@ -266,6 +268,7 @@ inv_box.alpha = ui_alpha hud.l_hand_hud_object = inv_box hud.adding += inv_box + slot_info["[slot_l_hand]"] = inv_box.screen_loc //Swaphand titlebar using = new /obj/screen/inventory() diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 062b950b97..00864d0a04 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -858,14 +858,17 @@ /mob/proc/Resting(amount) facing_dir = null resting = max(max(resting,amount),0) + update_canmove() return /mob/proc/SetResting(amount) resting = max(amount,0) + update_canmove() return /mob/proc/AdjustResting(amount) resting = max(resting + amount,0) + update_canmove() return /mob/proc/AdjustLosebreath(amount) diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index a7b965d74f..9671bcb0c9 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -624,6 +624,28 @@ var/global/image/backplane backplane = image('icons/misc/win32.dmi') backplane.alpha = 0 backplane.plane = -100 + backplane.layer = MOB_LAYER-0.1 backplane.mouse_opacity = 0 return TRUE + +/mob/proc/position_hud_item(var/obj/item/item, var/slot) + if(!istype(hud_used) || !slot || !LAZYLEN(hud_used.slot_info)) + return + + //They may have hidden their entire hud but the hands + if(!hud_used.hud_shown && slot > slot_r_hand) + item.screen_loc = null + return + + //They may have hidden the icons in the bottom left with the hide button + if(!hud_used.inventory_shown && slot > slot_r_store) + item.screen_loc = null + return + + var/screen_place = hud_used.slot_info["[slot]"] + if(!screen_place) + item.screen_loc = null + return + + item.screen_loc = screen_place diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index 37b6d77a9e..d941a16c40 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -485,8 +485,8 @@ // Do the initial caching of the player's body icons. new_character.force_update_limbs() + new_character.update_icons_body() new_character.update_eyes() - new_character.regenerate_icons() new_character.key = key //Manually transfer the key to log them in diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm index 1852d3ef61..108a316840 100644 --- a/code/modules/mob/new_player/preferences_setup.dm +++ b/code/modules/mob/new_player/preferences_setup.dm @@ -194,30 +194,29 @@ b_skin = blue /datum/preferences/proc/dress_preview_mob(var/mob/living/carbon/human/mannequin) - var/update_icon = FALSE copy_to(mannequin, TRUE) - var/datum/job/previewJob - if(equip_preview_mob) - // Determine what job is marked as 'High' priority, and dress them up as such. - if(job_civilian_low & ASSISTANT) - previewJob = job_master.GetJob("Assistant") - else - for(var/datum/job/job in job_master.occupations) - var/job_flag - switch(job.department_flag) - if(CIVILIAN) - job_flag = job_civilian_high - if(MEDSCI) - job_flag = job_medsci_high - if(ENGSEC) - job_flag = job_engsec_high - if(job.flag == job_flag) - previewJob = job - break - else + if(!equip_preview_mob) return + var/datum/job/previewJob + // Determine what job is marked as 'High' priority, and dress them up as such. + if(job_civilian_low & ASSISTANT) + previewJob = job_master.GetJob("Assistant") + else + for(var/datum/job/job in job_master.occupations) + var/job_flag + switch(job.department_flag) + if(CIVILIAN) + job_flag = job_civilian_high + if(MEDSCI) + job_flag = job_medsci_high + if(ENGSEC) + job_flag = job_engsec_high + if(job.flag == job_flag) + previewJob = job + break + if((equip_preview_mob & EQUIP_PREVIEW_LOADOUT) && !(previewJob && (equip_preview_mob & EQUIP_PREVIEW_JOB) && (previewJob.type == /datum/job/ai || previewJob.type == /datum/job/cyborg))) var/list/equipped_slots = list() //If more than one item takes the same slot only spawn the first for(var/thing in gear) @@ -243,15 +242,10 @@ var/metadata = gear[G.display_name] if(mannequin.equip_to_slot_or_del(G.spawn_item(mannequin, metadata), G.slot)) equipped_slots += G.slot - update_icon = TRUE if((equip_preview_mob & EQUIP_PREVIEW_JOB) && previewJob) mannequin.job = previewJob.title previewJob.equip_preview(mannequin, player_alt_titles[previewJob.title]) - update_icon = TRUE - - if(update_icon) - mannequin.update_icons_all() /datum/preferences/proc/update_preview_icon() var/mob/living/carbon/human/dummy/mannequin/mannequin = get_mannequin(client_ckey) @@ -261,16 +255,13 @@ preview_icon = icon('icons/effects/128x48.dmi', bgstate) preview_icon.Scale(48+32, 16+32) - mannequin.dir = NORTH - var/icon/stamp = getFlatIcon(mannequin) + var/icon/stamp = getFlatIcon(mannequin, defdir=NORTH) preview_icon.Blend(stamp, ICON_OVERLAY, 25, 17) - mannequin.dir = WEST - stamp = getFlatIcon(mannequin) + stamp = getFlatIcon(mannequin, defdir=WEST) preview_icon.Blend(stamp, ICON_OVERLAY, 1, 9) - mannequin.dir = SOUTH - stamp = getFlatIcon(mannequin) + stamp = getFlatIcon(mannequin, defdir=SOUTH) preview_icon.Blend(stamp, ICON_OVERLAY, 49, 1) - preview_icon.Scale(preview_icon.Width() * 2, preview_icon.Height() * 2) // Scaling here to prevent blurring in the browser. \ No newline at end of file + preview_icon.Scale(preview_icon.Width() * 2, preview_icon.Height() * 2) // Scaling here to prevent blurring in the browser. diff --git a/code/modules/mob/typing_indicator.dm b/code/modules/mob/typing_indicator.dm index 1565567f8f..5b164a8499 100644 --- a/code/modules/mob/typing_indicator.dm +++ b/code/modules/mob/typing_indicator.dm @@ -8,15 +8,15 @@ if(client && !stat) typing_indicator.invisibility = invisibility if(!is_preference_enabled(/datum/client_preference/show_typing_indicator)) - overlays -= typing_indicator + add_overlay(typing_indicator) else if(state) if(!typing) - overlays += typing_indicator + add_overlay(typing_indicator) typing = 1 else if(typing) - overlays -= typing_indicator + cut_overlay(typing_indicator) typing = 0 return state @@ -28,7 +28,6 @@ set_typing_indicator(1) else if(is_preference_enabled(/datum/client_preference/show_typing_indicator)) hud_typing = 1 - update_icons_huds() var/message = input("","say (text)") as text @@ -36,7 +35,6 @@ set_typing_indicator(0) else if(is_preference_enabled(/datum/client_preference/show_typing_indicator)) hud_typing = 0 - update_icons_huds() if(message) say_verb(message) @@ -49,13 +47,11 @@ set_typing_indicator(1) else if(is_preference_enabled(/datum/client_preference/show_typing_indicator)) hud_typing = 1 - update_icons_huds() var/message = input("","me (text)") as text if(is_preference_enabled(/datum/client_preference/show_typing_indicator)) hud_typing = 0 - update_icons_huds() else if(!ishuman(src)) //If they're a mob, use the old code. set_typing_indicator(0) diff --git a/code/modules/mob/update_icons.dm b/code/modules/mob/update_icons.dm index ae6e01a249..6004ca3e4c 100644 --- a/code/modules/mob/update_icons.dm +++ b/code/modules/mob/update_icons.dm @@ -1,31 +1,26 @@ //Most of these are defined at this level to reduce on checks elsewhere in the code. //Having them here also makes for a nice reference list of the various overlay-updating procs available -/mob/proc/regenerate_icons() //TODO: phase this out completely if possible +/mob/proc/regenerate_icons() //Update every aspect of the mob's icons (expensive, resist the urge to use unless you need it) return /mob/proc/update_icons() update_icon() //Ugh. return -/mob/proc/update_icons_layers(var/update_icons = TRUE) - if(update_icons) - update_icons() +// Obsolete +/mob/proc/update_icons_layers() + return -/mob/proc/update_icons_huds(var/update_icons = TRUE) - if(update_icons) - update_icons() +/mob/proc/update_icons_huds() + return -/mob/proc/update_icons_body(var/update_icons = TRUE) - if(update_icons) - update_icons() +/mob/proc/update_icons_body() + return /mob/proc/update_icons_all() - update_icons_huds(FALSE) - update_icons_body(FALSE) - update_icons_layers(FALSE) - - update_icons() + return +// End obsolete /mob/proc/update_hud() return diff --git a/code/modules/organs/blood.dm b/code/modules/organs/blood.dm index 9b0bef6aaa..50c326277d 100644 --- a/code/modules/organs/blood.dm +++ b/code/modules/organs/blood.dm @@ -27,8 +27,6 @@ var/const/CE_STABLE_THRESHOLD = 0.5 return vessel.add_reagent("blood",species.blood_volume) - spawn(1) - fixblood() //Resets blood data /mob/living/carbon/human/proc/fixblood() diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index 7253d35049..86a9f589e4 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -873,7 +873,7 @@ Note that amputating the affected organ does in fact remove the infection from t spawn(1) victim.updatehealth() victim.UpdateDamageIcon() - victim.regenerate_icons() + victim.update_icons_body() dir = 2 switch(disintegrate) diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index 9b4eaf639e..9e090c2095 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -457,6 +457,10 @@ update_icon() +/obj/item/weapon/paper/get_worn_icon_state(var/slot_name) + if(slot_name == slot_head_str) + return "paper" //Gross, but required for now. + return ..() /obj/item/weapon/paper/attackby(obj/item/weapon/P as obj, mob/user as mob) ..() @@ -495,13 +499,13 @@ B.loc = h_user B.hud_layerise() h_user.l_store = B - h_user.update_inv_pockets() + //h_user.update_inv_pockets() //Doesn't do anything else if (h_user.r_store == src) h_user.drop_from_inventory(src) B.loc = h_user B.hud_layerise() h_user.r_store = B - h_user.update_inv_pockets() + //h_user.update_inv_pockets() //Doesn't do anything else if (h_user.head == src) h_user.u_equip(src) h_user.put_in_hands(B) diff --git a/icons/mob/mob.dmi b/icons/mob/mob.dmi index 33133bda47..aeffd11f4d 100644 Binary files a/icons/mob/mob.dmi and b/icons/mob/mob.dmi differ diff --git a/icons/mob/species/skrell/helmet.dmi b/icons/mob/species/skrell/helmet.dmi index 4d56c2a68a..31f409043f 100644 Binary files a/icons/mob/species/skrell/helmet.dmi and b/icons/mob/species/skrell/helmet.dmi differ diff --git a/icons/mob/species/tajaran/helmet.dmi b/icons/mob/species/tajaran/helmet.dmi index 0aafc2d8ea..cac6e5f53d 100644 Binary files a/icons/mob/species/tajaran/helmet.dmi and b/icons/mob/species/tajaran/helmet.dmi differ diff --git a/icons/mob/species/unathi/helmet.dmi b/icons/mob/species/unathi/helmet.dmi index 9f43a8d664..ec10064bcf 100644 Binary files a/icons/mob/species/unathi/helmet.dmi and b/icons/mob/species/unathi/helmet.dmi differ diff --git a/polaris.dme b/polaris.dme index 4cc0dedf45..08797dc063 100644 --- a/polaris.dme +++ b/polaris.dme @@ -1340,6 +1340,7 @@ #include "code\modules\clothing\chameleon.dm" #include "code\modules\clothing\clothing.dm" #include "code\modules\clothing\clothing_accessories.dm" +#include "code\modules\clothing\clothing_icons.dm" #include "code\modules\clothing\ears\ears.dm" #include "code\modules\clothing\glasses\glasses.dm" #include "code\modules\clothing\glasses\hud.dm"