From 814f59cf29d1bfa19bf491351f5ee69fc61d1f46 Mon Sep 17 00:00:00 2001 From: Neerti Date: Sun, 10 Jul 2016 06:22:44 -0400 Subject: [PATCH] New Limb HUD System, from Bay Manually ports https://github.com/Baystation12/Baystation12/pull/13530, and https://github.com/Baystation12/Baystation12/pull/13561 from bay. Adjusts the scaling on the coloration, since it seems Bay has different shading than us for species, otherwise some species would be dark, and others would be superbright. Credit goes to Zuhayr for the code. --- code/modules/mob/death.dm | 1 + code/modules/mob/living/carbon/human/life.dm | 103 +++++++++++------- .../living/carbon/human/species/species.dm | 1 + .../carbon/human/species/station/monkey.dm | 1 + .../human/species/station/prometheans.dm | 1 + .../carbon/human/species/station/seromi.dm | 1 + .../carbon/human/species/station/station.dm | 5 + code/modules/organs/organ_external.dm | 2 + code/modules/organs/organ_icon.dm | 57 ++++++++++ code/modules/organs/robolimbs.dm | 1 + icons/mob/screen1_health.dmi | Bin 0 -> 887 bytes 11 files changed, 131 insertions(+), 42 deletions(-) create mode 100644 icons/mob/screen1_health.dmi diff --git a/code/modules/mob/death.dm b/code/modules/mob/death.dm index c867e642b4..9fe7f221e1 100644 --- a/code/modules/mob/death.dm +++ b/code/modules/mob/death.dm @@ -74,6 +74,7 @@ drop_l_hand() if(healths) + healths.overlays = null // This is specific to humans but the relevant code is here; shouldn't mess with other mobs. healths.icon_state = "health6" timeofdeath = world.time diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 7a29b140b2..c2906783ec 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -1032,37 +1032,38 @@ var/obj/machinery/camera/cam = client.eye client.screen |= cam.client_huds - if(stat == UNCONSCIOUS && health <= 0) - //Critical damage passage overlay - var/severity = 0 - switch(health) - if(-20 to -10) severity = 1 - if(-30 to -20) severity = 2 - if(-40 to -30) severity = 3 - if(-50 to -40) severity = 4 - if(-60 to -50) severity = 5 - if(-70 to -60) severity = 6 - if(-80 to -70) severity = 7 - if(-90 to -80) severity = 8 - if(-95 to -90) severity = 9 - if(-INFINITY to -95) severity = 10 - overlay_fullscreen("crit", /obj/screen/fullscreen/crit, severity) - else - clear_fullscreen("crit") - //Oxygen damage overlay - if(oxyloss) + if(stat != DEAD) + if(stat == UNCONSCIOUS && health <= 0) + //Critical damage passage overlay var/severity = 0 - switch(oxyloss) - if(10 to 20) severity = 1 - if(20 to 25) severity = 2 - if(25 to 30) severity = 3 - if(30 to 35) severity = 4 - if(35 to 40) severity = 5 - if(40 to 45) severity = 6 - if(45 to INFINITY) severity = 7 - overlay_fullscreen("oxy", /obj/screen/fullscreen/oxy, severity) + switch(health) + if(-20 to -10) severity = 1 + if(-30 to -20) severity = 2 + if(-40 to -30) severity = 3 + if(-50 to -40) severity = 4 + if(-60 to -50) severity = 5 + if(-70 to -60) severity = 6 + if(-80 to -70) severity = 7 + if(-90 to -80) severity = 8 + if(-95 to -90) severity = 9 + if(-INFINITY to -95) severity = 10 + overlay_fullscreen("crit", /obj/screen/fullscreen/crit, severity) else - clear_fullscreen("oxy") + clear_fullscreen("crit") + //Oxygen damage overlay + if(oxyloss) + var/severity = 0 + switch(oxyloss) + if(10 to 20) severity = 1 + if(20 to 25) severity = 2 + if(25 to 30) severity = 3 + if(30 to 35) severity = 4 + if(35 to 40) severity = 5 + if(40 to 45) severity = 6 + if(45 to INFINITY) severity = 7 + overlay_fullscreen("oxy", /obj/screen/fullscreen/oxy, severity) + else + clear_fullscreen("oxy") //Fire and Brute damage overlay (BSSR) var/hurtdamage = src.getBruteLoss() + src.getFireLoss() + damageoverlaytemp @@ -1138,19 +1139,37 @@ if (analgesic > 100) healths.icon_state = "health_numb" else - switch(hal_screwyhud) - if(1) healths.icon_state = "health6" - if(2) healths.icon_state = "health7" - else - //switch(health - halloss) - switch(100 - (!can_feel_pain() ? 0 : traumatic_shock)) - if(100 to INFINITY) healths.icon_state = "health0" - if(80 to 100) healths.icon_state = "health1" - if(60 to 80) healths.icon_state = "health2" - if(40 to 60) healths.icon_state = "health3" - if(20 to 40) healths.icon_state = "health4" - if(0 to 20) healths.icon_state = "health5" - else healths.icon_state = "health6" + // Generate a by-limb health display. + healths.icon_state = "blank" + healths.overlays = null + + var/no_damage = 1 + var/trauma_val = 0 // Used in calculating softcrit/hardcrit indicators. + if(!(species.flags & NO_PAIN)) + trauma_val = max(traumatic_shock,halloss)/species.total_health + var/limb_trauma_val = trauma_val*0.3 + // Collect and apply the images all at once to avoid appearance churn. + var/list/health_images = list() + for(var/obj/item/organ/external/E in organs) + if(no_damage && (E.brute_dam || E.burn_dam)) + no_damage = 0 + health_images += E.get_damage_hud_image(limb_trauma_val) + + // Apply a fire overlay if we're burning. + if(on_fire) + health_images += image('icons/mob/screen1_health.dmi',"burning") + + // Show a general pain/crit indicator if needed. + if(trauma_val) + if(!(species.flags & NO_PAIN)) + if(trauma_val > 0.7) + health_images += image('icons/mob/screen1_health.dmi',"softcrit") + if(trauma_val >= 1) + health_images += image('icons/mob/screen1_health.dmi',"hardcrit") + else if(no_damage) + health_images += image('icons/mob/screen1_health.dmi',"fullhealth") + + healths.overlays += health_images if(nutrition_icon) switch(nutrition) diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index def9ae59f2..5a8fcba715 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -108,6 +108,7 @@ // HUD data vars. var/datum/hud_data/hud var/hud_type + var/health_hud_intensity = 1 // This modifies how intensely the health hud is colored. // Body/form vars. var/list/inherent_verbs // Species-specific verbs. diff --git a/code/modules/mob/living/carbon/human/species/station/monkey.dm b/code/modules/mob/living/carbon/human/species/station/monkey.dm index 6074934cec..738284dd38 100644 --- a/code/modules/mob/living/carbon/human/species/station/monkey.dm +++ b/code/modules/mob/living/carbon/human/species/station/monkey.dm @@ -14,6 +14,7 @@ mob_size = MOB_SMALL has_fine_manipulation = 0 show_ssd = null + health_hud_intensity = 2 gibbed_anim = "gibbed-m" dusted_anim = "dust-m" diff --git a/code/modules/mob/living/carbon/human/species/station/prometheans.dm b/code/modules/mob/living/carbon/human/species/station/prometheans.dm index 2ada0dd7c7..5eae3da61e 100644 --- a/code/modules/mob/living/carbon/human/species/station/prometheans.dm +++ b/code/modules/mob/living/carbon/human/species/station/prometheans.dm @@ -23,6 +23,7 @@ var/datum/species/shapeshifter/promethean/prometheans flags = NO_SCAN | NO_SLIP | NO_MINOR_CUT appearance_flags = HAS_SKIN_COLOR | HAS_EYE_COLOR | HAS_HAIR_COLOR | RADIATION_GLOWS spawn_flags = SPECIES_IS_RESTRICTED + health_hud_intensity = 2 breath_type = null poison_type = null diff --git a/code/modules/mob/living/carbon/human/species/station/seromi.dm b/code/modules/mob/living/carbon/human/species/station/seromi.dm index 12e87f9328..d6744f252e 100644 --- a/code/modules/mob/living/carbon/human/species/station/seromi.dm +++ b/code/modules/mob/living/carbon/human/species/station/seromi.dm @@ -11,6 +11,7 @@ name_language = "Schechi" min_age = 12 max_age = 45 + health_hud_intensity = 3 blood_color = "#D514F7" flesh_color = "#5F7BB0" diff --git a/code/modules/mob/living/carbon/human/species/station/station.dm b/code/modules/mob/living/carbon/human/species/station/station.dm index a903433fda..bcd204e499 100644 --- a/code/modules/mob/living/carbon/human/species/station/station.dm +++ b/code/modules/mob/living/carbon/human/species/station/station.dm @@ -13,6 +13,7 @@ name_language = null // Use the first-name last-name generator rather than a language scrambler min_age = 17 max_age = 110 + health_hud_intensity = 1.5 spawn_flags = SPECIES_CAN_JOIN appearance_flags = HAS_HAIR_COLOR | HAS_SKIN_TONE | HAS_LIPS | HAS_UNDERWEAR | HAS_EYE_COLOR @@ -36,6 +37,7 @@ num_alternate_languages = 2 secondary_langs = list("Sinta'unathi") name_language = "Sinta'unathi" + health_hud_intensity = 2.5 min_age = 18 max_age = 60 @@ -96,6 +98,7 @@ num_alternate_languages = 2 secondary_langs = list("Siik'tajr") name_language = "Siik'tajr" + health_hud_intensity = 2.5 min_age = 17 max_age = 80 @@ -151,6 +154,7 @@ num_alternate_languages = 2 secondary_langs = list("Skrellian", "Schechi") name_language = "Skrellian" + health_hud_intensity = 2 min_age = 19 max_age = 80 @@ -193,6 +197,7 @@ show_ssd = "completely quiescent" num_alternate_languages = 1 name_language = "Rootspeak" + health_hud_intensity = 2.5 min_age = 1 max_age = 300 diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index d3b309fd84..d50d5009e7 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -68,6 +68,8 @@ var/stage = 0 var/cavity = 0 + // HUD element variable, see organ_icon.dm get_damage_hud_image() + var/image/hud_damage_image /obj/item/organ/external/Destroy() diff --git a/code/modules/organs/organ_icon.dm b/code/modules/organs/organ_icon.dm index 035a0692c3..e68df75218 100644 --- a/code/modules/organs/organ_icon.dm +++ b/code/modules/organs/organ_icon.dm @@ -89,6 +89,9 @@ var/global/list/limb_icon_cache = list() if(owner && owner.gender == MALE) gender = "m" + icon_cache_key = "[icon_name]_[species ? species.name : "Human"]" + world << "ICON: Added species. icon_cache_key is now [icon_cache_key]." + if(force_icon) mob_icon = new /icon(force_icon, "[icon_name][gendered_icon ? "_[gender]" : ""]") else @@ -134,22 +137,30 @@ var/global/list/limb_icon_cache = list() applying.SetIntensity(0.7) else if(status & ORGAN_DEAD) + icon_cache_key += "_dead" applying.ColorTone(rgb(10,50,0)) applying.SetIntensity(0.7) + world << "ICON: Added deadness. icon_cache_key is now [icon_cache_key]." if(!isnull(s_tone)) if(s_tone >= 0) applying.Blend(rgb(s_tone, s_tone, s_tone), ICON_ADD) else applying.Blend(rgb(-s_tone, -s_tone, -s_tone), ICON_SUBTRACT) + icon_cache_key += "_tone_[s_tone]" + world << "ICON: Added skin tone. icon_cache_key is now [icon_cache_key]." else if(s_col && s_col.len >= 3) applying.Blend(rgb(s_col[1], s_col[2], s_col[3]), ICON_ADD) + icon_cache_key += "_color_[s_col[1]]_[s_col[2]]_[s_col[3]]" + world << "ICON: Added skin color. icon_cache_key is now [icon_cache_key]." // Translucency. if(nonsolid) applying += rgb(,,,180) // SO INTUITIVE TY BYOND return applying +/obj/item/organ/external/var/icon_cache_key + // new damage icon system // adjusted to set damage_state to brute/burn code only (without r_name0 as before) /obj/item/organ/external/update_icon() @@ -158,3 +169,49 @@ var/global/list/limb_icon_cache = list() damage_state = n_is return 1 return 0 + + +// Returns an image for use by the human health dolly HUD element. +// If the user has traumatic shock, it will be passed in as a minimum +// damage amount to represent the pain of the injuries involved. + +// Global scope, used in code below. +var/list/flesh_hud_colours = list("#02BA08","#9ECF19","#DEDE10","#FFAA00","#FF0000","#AA0000","#660000") +var/list/robot_hud_colours = list("#CFCFCF","#AFAFAF","#8F8F8F","#6F6F6F","#4F4F4F","#2F2F2F","#000000") + +/obj/item/organ/external/proc/get_damage_hud_image(var/min_dam_state) + world << "get_damage_hud_image([min_dam_state]) called." + + // Generate the greyscale base icon and cache it for later. + // icon_cache_key is set by any get_icon() calls that are made. + // This looks convoluted, but it's this way to avoid icon proc calls. + if(!hud_damage_image) + var/cache_key = "dambase-[icon_cache_key]" + if(!icon_cache_key || !limb_icon_cache[cache_key]) + limb_icon_cache[cache_key] = icon(get_icon(), null, SOUTH) + var/image/temp = image(limb_icon_cache[cache_key]) + if((robotic < ORGAN_ROBOT) && species) + // Calculate the required colour matrix. + var/r = 0.30 * species.health_hud_intensity + var/g = 0.59 * species.health_hud_intensity + var/b = 0.11 * species.health_hud_intensity + temp.color = list(r, r, r, g, g, g, b, b, b) + else if(model) + var/datum/robolimb/R = all_robolimbs[model] + if(istype(R)) + var/r = 0.30 * R.health_hud_intensity + var/g = 0.59 * R.health_hud_intensity + var/b = 0.11 * R.health_hud_intensity + temp.color = list(r, r, r, g, g, g, b, b, b) + hud_damage_image = image(null) + hud_damage_image.overlays += temp + + // Calculate the required color index. + var/dam_state = min(1,((brute_dam+burn_dam)/max_damage)) + // Apply traumatic shock min damage state. + if(!isnull(min_dam_state) && dam_state < min_dam_state) + dam_state = min_dam_state + // Apply colour and return product. + var/list/hud_colours = (robotic < ORGAN_ROBOT) ? flesh_hud_colours : robot_hud_colours + hud_damage_image.color = hud_colours[max(1,min(ceil(dam_state*hud_colours.len),hud_colours.len))] + return hud_damage_image diff --git a/code/modules/organs/robolimbs.dm b/code/modules/organs/robolimbs.dm index e1dac6efe9..b0f16372ee 100644 --- a/code/modules/organs/robolimbs.dm +++ b/code/modules/organs/robolimbs.dm @@ -42,6 +42,7 @@ var/const/standard_monitor_styles = "blank=ipc_blank;\ var/list/species_cannot_use = list("Teshari") var/list/monitor_styles //If empty, the model of limbs offers a head compatible with monitors. var/parts = BP_ALL //Defines what parts said brand can replace on a body. + var/health_hud_intensity = 1 // Intensity modifier for the health GUI indicator. /datum/robolimb/nanotrasen company = "NanoTrasen" diff --git a/icons/mob/screen1_health.dmi b/icons/mob/screen1_health.dmi new file mode 100644 index 0000000000000000000000000000000000000000..6905268a1353d23ff28d755cb844d3d1a9b91268 GIT binary patch literal 887 zcmV--1Bm>IP)fFDZ*Bkpc$`yKaB_9`^iy#0_2eo`Eh^5;&r`5fFwryM z;w;ZhDainGjE%TBGg33tGfE(w;*!LYR3KBSI6tiDfo>knsBni4)mF(*?k!K z*L_)(%VJr6o@=nN*zP8SrNzFCFt7<+1Dhbu01}k32~uBSJ0{rtG1!j@mU9h~xABfU z?r>plDPT>^phvEI7^+=`VUHhz4yK~Mc6be(kRz&=^3LH+EjSw(_t3y-)`iDCpuNUl zfKj*t{=3XP{*lWT+J$lKApe;O#gN8?64~i{mw$7)InCjojGq=i+y@%UgrIhLGvskO zJsgk4vG_Id$_gl-_(5`RiCTA@9*W}tVIYtJ?O@y{5C$!YJ+m{i!|6#kU@_^yMW`On z1g=3xS>uimyawLN2(SxwQaA-34_?OC2yW2>iXVn2On!QUx1ZUF&H&Vcj9ItXx z@T_n+M?P|yz;Xtz0!tQNQP%n!mTu(X&O$dU?K7da>nmVlGsqBE$g$s>sMi`wo@hLS zVb#C*^aVZ1{%=cQ+%9R~11h}fVhwHrEHfNexXp!rk36VmJkQ3vzX3qMw@%rNPq7K- ze*fJ~)ONF~&IsJ~EV}PKkzBDp_I~%U1<$b+0{eY;TGu$#@ZNnF>+sJbxhxxntNKhT zOvFVxp~_)OwS6N{F#jSs0+u}Zd*TwX-{aS;iXIGxiVz2{|3~Vt#cy~Cy12V6>-7Kt N002ovPDHLkV1lE}mbL%@ literal 0 HcmV?d00001