diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index 1f0768ba9b0..d87150ad2de 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -204,40 +204,44 @@
#define MFOAM_IRON 2
//Human Overlays Indexes/////////
-#define MUTANTRACE_LAYER 1
-#define TAIL_UNDERLIMBS_LAYER 2 //Tail split-rendering.
-#define LIMBS_LAYER 3
-#define MARKINGS_LAYER 4
-#define UNDERWEAR_LAYER 5
-#define MUTATIONS_LAYER 6
-#define H_DAMAGE_LAYER 7
-#define UNIFORM_LAYER 8
-#define ID_LAYER 9
-#define SHOES_LAYER 10
-#define GLOVES_LAYER 11
-#define EARS_LAYER 12
-#define SUIT_LAYER 13
-#define BELT_LAYER 14 //Possible make this an overlay of somethign required to wear a belt?
-#define SUIT_STORE_LAYER 15
-#define BACK_LAYER 16
-#define HEAD_ACCESSORY_LAYER 17
+#define BODY_LAYER 37
+#define MUTANTRACE_LAYER 36
+#define TAIL_UNDERLIMBS_LAYER 35 //Tail split-rendering.
+#define LIMBS_LAYER 34
+#define INTORGAN_LAYER 33
+#define MARKINGS_LAYER 32
+#define UNDERWEAR_LAYER 31
+#define MUTATIONS_LAYER 30
+#define H_DAMAGE_LAYER 29
+#define UNIFORM_LAYER 28
+#define ID_LAYER 27
+#define SHOES_LAYER 26
+#define GLOVES_LAYER 25
+#define EARS_LAYER 24
+#define SUIT_LAYER 23
+#define BELT_LAYER 22 //Possible make this an overlay of somethign required to wear a belt?
+#define SUIT_STORE_LAYER 21
+#define BACK_LAYER 20
+#define HEAD_ACCESSORY_LAYER 19
#define FHAIR_LAYER 18
-#define GLASSES_LAYER 19
-#define HAIR_LAYER 20 //TODO: make part of head layer?
-#define HEAD_ACC_OVER_LAYER 21 //Select-layer rendering.
-#define FHAIR_OVER_LAYER 22 //Select-layer rendering.
-#define GLASSES_OVER_LAYER 23 //Select-layer rendering.
-#define TAIL_LAYER 24 //bs12 specific. this hack is probably gonna come back to haunt me
-#define FACEMASK_LAYER 25
-#define HEAD_LAYER 26
-#define COLLAR_LAYER 27
-#define HANDCUFF_LAYER 28
-#define LEGCUFF_LAYER 29
-#define L_HAND_LAYER 30
-#define R_HAND_LAYER 31
-#define TARGETED_LAYER 32 //BS12: Layer for the target overlay from weapon targeting system
-#define FIRE_LAYER 33 //If you're on fire
-#define TOTAL_LAYERS 33
+#define GLASSES_LAYER 17
+#define HAIR_LAYER 16 //TODO: make part of head layer?
+#define HEAD_ACC_OVER_LAYER 15 //Select-layer rendering.
+#define FHAIR_OVER_LAYER 14 //Select-layer rendering.
+#define GLASSES_OVER_LAYER 13 //Select-layer rendering.
+#define TAIL_LAYER 12 //bs12 specific. this hack is probably gonna come back to haunt me
+#define FACEMASK_LAYER 11
+#define HEAD_LAYER 10
+#define COLLAR_LAYER 9
+#define HANDCUFF_LAYER 8
+#define LEGCUFF_LAYER 7
+#define L_HAND_LAYER 6
+#define R_HAND_LAYER 5
+#define TARGETED_LAYER 4 //BS12: Layer for the target overlay from weapon targeting system
+#define FIRE_LAYER 3 //If you're on fire
+#define MISC_LAYER 2
+#define FROZEN_LAYER 1
+#define TOTAL_LAYERS 37
///Access Region Codes///
#define REGION_ALL 0
diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm
index 580cb85d696..139b029f55e 100644
--- a/code/__DEFINES/mobs.dm
+++ b/code/__DEFINES/mobs.dm
@@ -143,6 +143,7 @@
#define STATUS_UPDATE_NONE 0
#define STATUS_UPDATE_ALL (~0)
+#define UNHEALING_EAR_DAMAGE 100
//Human sub-species
#define isshadowling(A) (is_species(A, /datum/species/shadow/ling))
diff --git a/code/game/dna/genes/disabilities.dm b/code/game/dna/genes/disabilities.dm
index b346a3fecd9..2f6bf234de2 100644
--- a/code/game/dna/genes/disabilities.dm
+++ b/code/game/dna/genes/disabilities.dm
@@ -147,7 +147,7 @@
/datum/dna/gene/disability/deaf/activate(var/mob/M, var/connected, var/flags)
..()
- M.EarDeaf(1)
+ M.MinimumDeafTicks(1)
/datum/dna/gene/disability/nearsighted
name="Nearsightedness"
diff --git a/code/game/gamemodes/changeling/powers/revive.dm b/code/game/gamemodes/changeling/powers/revive.dm
index 9993388afec..147fdd2d327 100644
--- a/code/game/gamemodes/changeling/powers/revive.dm
+++ b/code/game/gamemodes/changeling/powers/revive.dm
@@ -16,8 +16,7 @@
user.radiation = 0
user.SetEyeBlind(0, FALSE)
user.SetEyeBlurry(0, FALSE)
- user.SetEarDamage(0)
- user.SetEarDeaf(0)
+ user.RestoreEars()
user.heal_overall_damage(user.getBruteLoss(), user.getFireLoss(), updating_health = FALSE)
user.CureBlind(FALSE)
user.CureDeaf()
diff --git a/code/game/gamemodes/changeling/powers/shriek.dm b/code/game/gamemodes/changeling/powers/shriek.dm
index 5185b61e508..1c60013fbb8 100644
--- a/code/game/gamemodes/changeling/powers/shriek.dm
+++ b/code/game/gamemodes/changeling/powers/shriek.dm
@@ -11,7 +11,7 @@
for(var/mob/living/M in get_mobs_in_view(4, user))
if(iscarbon(M))
if(!M.mind || !M.mind.changeling)
- M.AdjustEarDeaf(30)
+ M.MinimumDeafTicks(30)
M.AdjustConfused(20)
M.Jitter(50)
else
diff --git a/code/game/gamemodes/vampire/vampire_powers.dm b/code/game/gamemodes/vampire/vampire_powers.dm
index 6d82f6c48e1..c45da8ac279 100644
--- a/code/game/gamemodes/vampire/vampire_powers.dm
+++ b/code/game/gamemodes/vampire/vampire_powers.dm
@@ -265,7 +265,7 @@
continue
to_chat(C, "You hear a ear piercing shriek and your senses dull!")
C.Weaken(4)
- C.AdjustEarDeaf(20)
+ C.MinimumDeafTicks(20)
C.Stuttering(20)
C.Stun(4)
C.Jitter(150)
diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm
index 4c0aaac77da..18aba4ca69f 100644
--- a/code/game/gamemodes/wizard/artefact.dm
+++ b/code/game/gamemodes/wizard/artefact.dm
@@ -785,7 +785,7 @@ var/global/list/multiverse = list()
else if(istype(I,/obj/item/bikehorn))
to_chat(target, "HONK")
target << 'sound/items/AirHorn.ogg'
- target.AdjustEarDeaf(3)
+ target.MinimumDeafTicks(3)
GiveHint(target)
cooldown = world.time +cooldown_time
return
diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm
index 6d83b8fa927..011b2c6fab8 100644
--- a/code/game/mecha/equipment/weapons/weapons.dm
+++ b/code/game/mecha/equipment/weapons/weapons.dm
@@ -212,7 +212,7 @@
to_chat(M, "HONK")
M.SetSleeping(0)
M.Stuttering(20)
- M.AdjustEarDeaf(30)
+ M.MinimumDeafTicks(30)
M.Weaken(3)
if(prob(30))
M.Stun(10)
diff --git a/code/game/objects/items/weapons/clown_items.dm b/code/game/objects/items/weapons/clown_items.dm
index 895c2809cca..165a61baa75 100644
--- a/code/game/objects/items/weapons/clown_items.dm
+++ b/code/game/objects/items/weapons/clown_items.dm
@@ -68,6 +68,6 @@
for(M in ohearers(7, T))
if(istype(M, /mob/living/carbon/human))
var/mob/living/carbon/human/H = M
- if(istype(H.l_ear, /obj/item/clothing/ears/earmuffs) || istype(H.r_ear, /obj/item/clothing/ears/earmuffs) || H.ear_deaf)
+ if(!H.can_hear())
continue
M.emote("flip")
diff --git a/code/game/objects/items/weapons/grenades/flashbang.dm b/code/game/objects/items/weapons/grenades/flashbang.dm
index 3e9336fc5a7..884265ec55b 100644
--- a/code/game/objects/items/weapons/grenades/flashbang.dm
+++ b/code/game/objects/items/weapons/grenades/flashbang.dm
@@ -59,13 +59,16 @@
if(!ear_safety)
M.Stun(max(10/distance, 3))
M.Weaken(max(10/distance, 3))
- M.EarDeaf(15)
- M.AdjustEarDamage(rand(0, 5))
- if(M.ear_damage >= 15)
- to_chat(M, "Your ears start to ring badly!")
- if(prob(M.ear_damage - 5))
- to_chat(M, "You can't hear anything!")
- M.BecomeDeaf()
- else
- if(M.ear_damage >= 5)
- to_chat(M, "Your ears start to ring!")
+ M.AdjustEarDamage(rand(0, 5), 15)
+ if(iscarbon(M))
+ var/mob/living/carbon/C = M
+ var/obj/item/organ/internal/ears/ears = C.get_int_organ(/obj/item/organ/internal/ears)
+ if(istype(ears))
+ if(ears.ear_damage >= 15)
+ to_chat(M, "Your ears start to ring badly!")
+ if(prob(ears.ear_damage - 5))
+ to_chat(M, "You can't hear anything!")
+ M.BecomeDeaf()
+ else
+ if(ears.ear_damage >= 5)
+ to_chat(M, "Your ears start to ring!")
diff --git a/code/modules/admin/verbs/freeze.dm b/code/modules/admin/verbs/freeze.dm
index 8dc852e9221..de91530eabe 100644
--- a/code/modules/admin/verbs/freeze.dm
+++ b/code/modules/admin/verbs/freeze.dm
@@ -26,14 +26,15 @@ var/global/list/frozen_mob_list = list()
/mob/living/var/frozen = null //used for preventing attacks on admin-frozen mobs
/mob/living/var/admin_prev_sleeping = 0 //used for keeping track of previous sleeping value with admin freeze
-/mob/living/proc/admin_Freeze(var/client/admin)
+/mob/living/proc/admin_Freeze(var/client/admin, skip_overlays = FALSE)
if(istype(admin))
to_chat(src, "You have been frozen by [key_name(admin)]")
message_admins("[key_name_admin(admin)] froze [key_name_admin(src)]")
log_admin("[key_name(admin)] froze [key_name(src)]")
var/obj/effect/overlay/adminoverlay/AO = new
- src.overlays += AO
+ if(skip_overlays)
+ src.overlays += AO
anchored = 1
frozen = AO
@@ -42,14 +43,15 @@ var/global/list/frozen_mob_list = list()
if(!(src in frozen_mob_list))
frozen_mob_list += src
-/mob/living/proc/admin_unFreeze(var/client/admin)
+/mob/living/proc/admin_unFreeze(var/client/admin, skip_overlays = FALSE)
if(istype(admin))
to_chat(src, "You have been unfrozen by [key_name(admin)]")
message_admins("[key_name_admin(admin)] unfroze [key_name_admin(src)]")
log_admin("[key_name(admin)] unfroze [key_name(src)]")
anchored = 0
- overlays -= frozen
+ if(skip_overlays)
+ overlays -= frozen
frozen = null
SetSleeping(admin_prev_sleeping)
admin_prev_sleeping = null
diff --git a/code/modules/client/preference/preferences.dm b/code/modules/client/preference/preferences.dm
index e0ab0087b97..9d13b58d3e3 100644
--- a/code/modules/client/preference/preferences.dm
+++ b/code/modules/client/preference/preferences.dm
@@ -1195,18 +1195,18 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
if("age")
age = rand(AGE_MIN, AGE_MAX)
if("hair")
- if(species in list("Human", "Unathi", "Tajaran", "Skrell", "Machine", "Wryn", "Vulpkanin", "Vox"))
+ if(species in list("Human", "Felinid", "Unathi", "Tajaran", "Skrell", "Machine", "Wryn", "Vulpkanin", "Vox"))
h_colour = rand_hex_color()
if("secondary_hair")
- if(species in list("Human", "Unathi", "Tajaran", "Skrell", "Machine", "Wryn", "Vulpkanin", "Vox"))
+ if(species in list("Human", "Felinid", "Unathi", "Tajaran", "Skrell", "Machine", "Wryn", "Vulpkanin", "Vox"))
h_sec_colour = rand_hex_color()
if("h_style")
h_style = random_hair_style(gender, species, robohead)
if("facial")
- if(species in list("Human", "Unathi", "Tajaran", "Skrell", "Machine", "Wryn", "Vulpkanin", "Vox"))
+ if(species in list("Human", "Felinid", "Unathi", "Tajaran", "Skrell", "Machine", "Wryn", "Vulpkanin", "Vox"))
f_colour = rand_hex_color()
if("secondary_facial")
- if(species in list("Human", "Unathi", "Tajaran", "Skrell", "Machine", "Wryn", "Vulpkanin", "Vox"))
+ if(species in list("Human", "Felinid", "Unathi", "Tajaran", "Skrell", "Machine", "Wryn", "Vulpkanin", "Vox"))
f_sec_colour = rand_hex_color()
if("f_style")
f_style = random_facial_hair_style(gender, species, robohead)
@@ -1276,7 +1276,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
if(new_age)
age = max(min(round(text2num(new_age)), AGE_MAX),AGE_MIN)
if("species")
- var/list/new_species = list("Human", "Tajaran", "Skrell", "Unathi", "Diona", "Vulpkanin")
+ var/list/new_species = list("Human", "Felinid", "Tajaran", "Skrell", "Unathi", "Diona", "Vulpkanin")
var/prev_species = species
// var/whitelisted = 0
@@ -1407,14 +1407,14 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
b_type = new_b_type
if("hair")
- if(species in list("Human", "Unathi", "Tajaran", "Skrell", "Machine", "Vulpkanin", "Vox")) //Species that have hair. (No HAS_HAIR flag)
+ if(species in list("Human", "Felinid", "Unathi", "Tajaran", "Skrell", "Machine", "Vulpkanin", "Vox")) //Species that have hair. (No HAS_HAIR flag)
var/input = "Choose your character's hair colour:"
var/new_hair = input(user, input, "Character Preference", h_colour) as color|null
if(new_hair)
h_colour = new_hair
if("secondary_hair")
- if(species in list("Human", "Unathi", "Tajaran", "Skrell", "Machine", "Vulpkanin", "Vox"))
+ if(species in list("Human", "Felinid", "Unathi", "Tajaran", "Skrell", "Machine", "Vulpkanin", "Vox"))
var/datum/sprite_accessory/hair_style = GLOB.hair_styles_public_list[h_style]
if(hair_style.secondary_theme && !hair_style.no_sec_colour)
var/new_hair = input(user, "Choose your character's secondary hair colour:", "Character Preference", h_sec_colour) as color|null
@@ -1609,13 +1609,13 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
body_accessory = (new_body_accessory == "None") ? null : new_body_accessory
if("facial")
- if(species in list("Human", "Unathi", "Tajaran", "Skrell", "Machine", "Vulpkanin", "Vox")) //Species that have facial hair. (No HAS_HAIR_FACIAL flag)
+ if(species in list("Human", "Felinid", "Unathi", "Tajaran", "Skrell", "Machine", "Vulpkanin", "Vox")) //Species that have facial hair. (No HAS_HAIR_FACIAL flag)
var/new_facial = input(user, "Choose your character's facial-hair colour:", "Character Preference", f_colour) as color|null
if(new_facial)
f_colour = new_facial
if("secondary_facial")
- if(species in list("Human", "Unathi", "Tajaran", "Skrell", "Machine", "Vulpkanin", "Vox"))
+ if(species in list("Human", "Felinid", "Unathi", "Tajaran", "Skrell", "Machine", "Vulpkanin", "Vox"))
var/datum/sprite_accessory/facial_hair_style = GLOB.facial_hair_styles_list[f_style]
if(facial_hair_style.secondary_theme && !facial_hair_style.no_sec_colour)
var/new_facial = input(user, "Choose your character's secondary facial-hair colour:", "Character Preference", f_sec_colour) as color|null
diff --git a/code/modules/clothing/ears/ears.dm b/code/modules/clothing/ears/ears.dm
index 672df573858..2e3a1d40bda 100644
--- a/code/modules/clothing/ears/ears.dm
+++ b/code/modules/clothing/ears/ears.dm
@@ -4,6 +4,7 @@
icon_state = "earmuffs"
item_state = "earmuffs"
flags = EARBANGPROTECT
+ flags_2 = HEALS_EARS_2
strip_delay = 15
put_on_delay = 25
burn_state = FLAMMABLE
diff --git a/code/modules/lighting/lighting_overlay.dm b/code/modules/lighting/lighting_overlay.dm
index dd28f990322..a8f87338ae8 100644
--- a/code/modules/lighting/lighting_overlay.dm
+++ b/code/modules/lighting/lighting_overlay.dm
@@ -6,6 +6,7 @@
anchored = 1
icon = LIGHTING_ICON
layer = LIGHTING_LAYER
+ plane = LIGHTING_PLANE
invisibility = INVISIBILITY_LIGHTING
color = LIGHTING_BASE_MATRIX
icon_state = "light1"
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 26f77a31adc..065e5c4611e 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -48,8 +48,7 @@ var/list/image/ghost_darkness_images = list() //this is a list of images for thi
if(ishuman(body))
var/mob/living/carbon/human/H = body
- icon = H.stand_icon
- overlays = H.overlays_standing
+ appearance = H.appearance
else
icon = body.icon
icon_state = body.icon_state
diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm
index dea7c447191..6982d7f41c0 100644
--- a/code/modules/mob/living/carbon/alien/alien.dm
+++ b/code/modules/mob/living/carbon/alien/alien.dm
@@ -27,6 +27,7 @@
verbs += /mob/living/verb/lay_down
alien_organs += new /obj/item/organ/internal/brain/xeno
alien_organs += new /obj/item/organ/internal/xenos/hivenode
+ alien_organs += new /obj/item/organ/internal/ears
for(var/obj/item/organ/internal/I in alien_organs)
I.insert(src)
..()
diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
index da47f8c80b5..00aacd91b09 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
@@ -63,15 +63,12 @@
f_loss += 60
- AdjustEarDamage(30)
- AdjustEarDeaf(120)
-
+ AdjustEarDamage(30, 120)
if(3.0)
b_loss += 30
if(prob(50) && !shielded)
Paralyse(1)
- AdjustEarDamage(15)
- AdjustEarDeaf(60)
+ AdjustEarDamage(15, 60)
take_overall_damage(b_loss, f_loss)
diff --git a/code/modules/mob/living/carbon/alien/humanoid/life.dm b/code/modules/mob/living/carbon/alien/humanoid/life.dm
index 7771f1f5f90..6012a8fb7f3 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/life.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/life.dm
@@ -78,14 +78,6 @@
else if(eye_blurry) //blurry eyes heal slowly
AdjustEyeBlurry(-1)
- //Ears
- if(disabilities & DEAF) //disabled-deaf, doesn't get better on its own
- EarDeaf(1)
- else if(ear_deaf) //deafness, heals slowly over time
- AdjustEarDeaf(-1)
- else if(ear_damage < 25) //ear damage heals slowly under this threshold. otherwise you'll need earmuffs
- AdjustEarDamage(-0.05)
-
if(stuttering)
AdjustStuttering(-1)
diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm
index d0deac3e132..0b8aa891dde 100644
--- a/code/modules/mob/living/carbon/alien/larva/larva.dm
+++ b/code/modules/mob/living/carbon/alien/larva/larva.dm
@@ -56,15 +56,13 @@
f_loss += 60
- AdjustEarDamage(30)
- AdjustEarDeaf(120)
+ AdjustEarDamage(30, 120)
if(3.0)
b_loss += 30
if(prob(50))
Paralyse(1)
- AdjustEarDamage(15)
- AdjustEarDeaf(60)
+ AdjustEarDamage(15, 60)
adjustBruteLoss(b_loss)
adjustFireLoss(f_loss)
diff --git a/code/modules/mob/living/carbon/alien/larva/life.dm b/code/modules/mob/living/carbon/alien/larva/life.dm
index 654e9e27af3..a4b783e08fb 100644
--- a/code/modules/mob/living/carbon/alien/larva/life.dm
+++ b/code/modules/mob/living/carbon/alien/larva/life.dm
@@ -46,14 +46,6 @@
else if(eye_blurry) //blurry eyes heal slowly
AdjustEyeBlurry(-1)
- //Ears
- if(disabilities & DEAF) //disabled-deaf, doesn't get better on its own
- EarDeaf(1)
- else if(ear_deaf) //deafness, heals slowly over time
- AdjustEarDeaf(-1)
- else if(ear_damage < 25) //ear damage heals slowly under this threshold.
- AdjustEarDamage(-0.05)
-
if(stuttering)
AdjustStuttering(-1)
diff --git a/code/modules/mob/living/carbon/brain/brain.dm b/code/modules/mob/living/carbon/brain/brain.dm
index c64318d804b..0f7d4230587 100644
--- a/code/modules/mob/living/carbon/brain/brain.dm
+++ b/code/modules/mob/living/carbon/brain/brain.dm
@@ -108,8 +108,5 @@ I'm using this for Stat to give it a more nifty interface to work with
/mob/living/carbon/brain/can_safely_leave_loc()
return 0 //You're not supposed to be ethereal jaunting, brains
-/mob/living/carbon/brain/SetEarDamage() // no ears to damage or heal
- return
-
-/mob/living/carbon/brain/SetEarDeaf()
- return
+/mob/living/carbon/brain/can_hear()
+ . = TRUE
diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm
index 0a8f6fb3b83..03675f282e5 100644
--- a/code/modules/mob/living/carbon/brain/brain_item.dm
+++ b/code/modules/mob/living/carbon/brain/brain_item.dm
@@ -19,12 +19,6 @@
var/mmi_icon = 'icons/obj/assemblies.dmi'
var/mmi_icon_state = "mmi_full"
-/obj/item/organ/internal/brain/surgeryize()
- if(!owner)
- return
- owner.SetEarDeaf(0)
- owner.SetEarDamage(0) //Yeah, didn't you...hear? The ears are totally inside the brain.
-
/obj/item/organ/internal/brain/xeno
name = "xenomorph brain"
desc = "We barely understand the brains of terrestial animals. Who knows what we may find in the brain of such an advanced species?"
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 731380b68d4..7ffceaceef6 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -7,6 +7,7 @@
var/obj/item/rig/wearing_rig // This is very not good, but it's much much better than calling get_rig() every update_canmove() call.
/mob/living/carbon/human/New(loc)
+ icon = null // This is now handled by overlays -- we just keep an icon for the sake of the map editor.
if(length(args) > 1)
log_runtime(EXCEPTION("human/New called with more than 1 argument (REPORT THIS ENTIRE RUNTIME TO A CODER)"))
. = ..()
@@ -264,8 +265,7 @@
else valid_limbs -= processing_dismember
if(!istype(l_ear, /obj/item/clothing/ears/earmuffs) && !istype(r_ear, /obj/item/clothing/ears/earmuffs))
- AdjustEarDamage(30)
- AdjustEarDeaf(120)
+ AdjustEarDamage(30, 120)
if(prob(70) && !shielded)
Paralyse(10)
@@ -289,8 +289,7 @@
else valid_limbs -= processing_dismember
if(!istype(l_ear, /obj/item/clothing/ears/earmuffs) && !istype(r_ear, /obj/item/clothing/ears/earmuffs))
- AdjustEarDamage(15)
- AdjustEarDeaf(60)
+ AdjustEarDamage(15, 60)
if(prob(50) && !shielded)
Paralyse(10)
@@ -1527,8 +1526,9 @@
var/obj/item/organ/external/head/head_organ = get_organ("head")
var/datum/sprite_accessory/hair/hair_style = GLOB.hair_styles_full_list[head_organ.h_style]
var/icon/hair = new /icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s")
-
- return image(get_icon_difference(get_eyecon(), hair), layer = LIGHTING_LAYER + 1) //Cut the hair's pixels from the eyes icon so eyes covered by bangs stay hidden even while on a higher layer.
+ var/mutable_appearance/MA = mutable_appearance(get_icon_difference(get_eyecon(), hair), layer = LIGHTING_LAYER + 1)
+ MA.plane = LIGHTING_PLANE
+ return MA //Cut the hair's pixels from the eyes icon so eyes covered by bangs stay hidden even while on a higher layer.
/*Used to check if eyes should shine in the dark. Returns the image of the eyes on the layer where they will appear to shine.
Eyes need to have significantly high darksight to shine unless the mob has the XRAY vision mutation. Eyes will not shine if they are covered in any way.*/
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index f13d948842c..ce1d9a7f56e 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -786,20 +786,6 @@
AdjustEyeBlurry(-1)
- //Ears
- if(disabilities & DEAF) //disabled-deaf, doesn't get better on its own
- EarDeaf(1)
-
- else if(ear_deaf) //deafness, heals slowly over time
- AdjustEarDeaf(-1)
-
- else if(istype(l_ear, /obj/item/clothing/ears/earmuffs) || istype(r_ear, /obj/item/clothing/ears/earmuffs)) //resting your ears with earmuffs heals ear damage faster
- AdjustEarDamage(-0.15)
- EarDeaf(1)
-
- else if(ear_damage < 25) //ear damage heals slowly under this threshold. otherwise you'll need earmuffs
- AdjustEarDamage(-0.05)
-
if(flying)
animate(src, pixel_y = pixel_y + 5 , time = 10, loop = 1, easing = SINE_EASING)
animate(pixel_y = pixel_y - 5, time = 10, loop = 1, easing = SINE_EASING)
diff --git a/code/modules/mob/living/carbon/human/species/_species.dm b/code/modules/mob/living/carbon/human/species/_species.dm
index 90088f49926..3912e73a373 100644
--- a/code/modules/mob/living/carbon/human/species/_species.dm
+++ b/code/modules/mob/living/carbon/human/species/_species.dm
@@ -153,6 +153,9 @@
"l_foot" = list("path" = /obj/item/organ/external/foot),
"r_foot" = list("path" = /obj/item/organ/external/foot/right))
+ // Mutant pieces
+ var/obj/item/organ/internal/ears/mutantears = /obj/item/organ/internal/ears
+
/datum/species/New()
//If the species has eyes, they are the default vision organ
if(!vision_organ && has_organ["eyes"])
@@ -165,7 +168,6 @@
return species_language.get_random_name(gender)
/datum/species/proc/create_organs(mob/living/carbon/human/H) //Handles creation of mob organs.
-
QDEL_LIST(H.internal_organs)
QDEL_LIST(H.bodyparts)
@@ -184,12 +186,21 @@
// organ new code calls `insert` on its own
new organ(H)
+ create_mutant_organs(H)
+
for(var/name in H.bodyparts_by_name)
H.bodyparts |= H.bodyparts_by_name[name]
for(var/obj/item/organ/external/O in H.bodyparts)
O.owner = H
+/datum/species/proc/create_mutant_organs(mob/living/carbon/human/H)
+ var/obj/item/organ/internal/ears/ears = H.get_int_organ(/obj/item/organ/internal/ears)
+ if(ears)
+ qdel(ears)
+
+ ears = new mutantears(H)
+
/datum/species/proc/breathe(mob/living/carbon/human/H)
if((NO_BREATHE in species_traits) || (BREATHLESS in H.mutations))
return TRUE
diff --git a/code/modules/mob/living/carbon/human/species/human.dm b/code/modules/mob/living/carbon/human/species/human.dm
index 2a161ab9318..7009af295ac 100644
--- a/code/modules/mob/living/carbon/human/species/human.dm
+++ b/code/modules/mob/living/carbon/human/species/human.dm
@@ -17,4 +17,11 @@
worlds tumultous at best."
reagent_tag = PROCESS_ORG
- //Has standard darksight of 2.
\ No newline at end of file
+ //Has standard darksight of 2.
+
+/datum/species/human/cat
+ name = "Felinid"
+ name_plural = "Felinids"
+ blurb = "CATGIRLS OMG"
+
+ mutantears = /obj/item/organ/internal/ears/cat
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index 8dff1863061..4357584a18e 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -105,68 +105,20 @@ Please contact me on #coderbus IRC. ~Carn x
/mob/living/carbon/human
var/list/overlays_standing[TOTAL_LAYERS]
- var/list/misc_effect_overlays = list() //Overlays that are applied at a custom layer (defined in each image's .layer property) outside of standard overlay application. Updated in update_misc_effects()
var/previous_damage_appearance // store what the body last looked like, so we only have to update it if something changed
var/icon/skeleton
var/list/cached_standing_overlays = list() // List of everything currently in a human's actual overlays
-//UPDATES OVERLAYS FROM OVERLAYS_LYING/OVERLAYS_STANDING
-//this proc is messy as I was forced to include some old laggy cloaking code to it so that I don't break cloakers
-//I'll work on removing that stuff by rewriting some of the cloaking stuff at a later date.
-/mob/living/carbon/human/update_icons()
- var/stealth = 0
- var/obj/item/clothing/suit/armor/abductor/vest/V // Begin the most snowflakey bullshit code I've ever written. I'm so sorry, but there was no other way.
+/mob/living/carbon/human/proc/apply_overlay(cache_index)
+ if((. = overlays_standing[cache_index]))
+ add_overlay(.)
- for(V in list(wear_suit))
- if(V.stealth_active)
- stealth = 1
- break
+/mob/living/carbon/human/proc/remove_overlay(cache_index)
+ var/I = overlays_standing[cache_index]
+ if(I)
+ cut_overlay(I)
+ overlays_standing[cache_index] = null
- if(stealth)
- icon = V.disguise.icon //if the suit is active, reference the suit's current loaded icon and overlays; this does not include hand overlays
- overlays.Cut()
- cached_standing_overlays.Cut() // Make sure the cache gets rebuilt once the disguise is gone
-
- for(var/thing in V.disguise.overlays)
- if(thing)
- overlays += thing
-
- var/image/I = overlays_standing[L_HAND_LAYER] //manually add both left and right hand, so its independently updated
- if(istype(I))
- overlays += I
- I = overlays_standing[R_HAND_LAYER]
- if(istype(I))
- overlays += I
- else
- icon = stand_icon
- var/list/new_overlays = list()
- var/list/old_overlays = cached_standing_overlays
-
- // Totally regenerate if something touched our overlays
- if(overlays.len != old_overlays.len)
- overlays.Cut()
- old_overlays.Cut()
-
- for(var/i in 1 to TOTAL_LAYERS)
- var/image/I = overlays_standing[i]
- if(I)
- if(istype(I))
- // Since we avoid full overlay rebuilds, we have to reorganize the layers manually
- I.layer = (-2 - (TOTAL_LAYERS - i)) // Highest layer gets -2, each prior layer is 1 lower
- new_overlays += I
-
- update_misc_effects()
- if(misc_effect_overlays)
- new_overlays += misc_effect_overlays
-
- if(frozen) // Admin freeze overlay
- new_overlays += frozen
-
- overlays += (new_overlays - old_overlays)
- overlays -= (old_overlays - new_overlays)
- cached_standing_overlays = new_overlays
-
- update_transform()
var/global/list/damage_icon_parts = list()
@@ -185,38 +137,42 @@ var/global/list/damage_icon_parts = list()
previous_damage_appearance = damage_appearance
- var/icon/standing = new /icon(dna.species.damage_overlays, "00")
-
- var/image/standing_image = new /image("icon" = standing)
+ remove_overlay(H_DAMAGE_LAYER)
+ var/mutable_appearance/damage_overlay = mutable_appearance(dna.species.damage_overlays, "00", layer = -H_DAMAGE_LAYER)
+ overlays_standing[H_DAMAGE_LAYER] = damage_overlay
// blend the individual damage states with our icons
- for(var/obj/item/organ/external/O in bodyparts)
- O.update_icon()
- if(O.damage_state == "00") continue
+ for(var/D in bodyparts)
+ var/obj/item/organ/external/E = D
+ E.update_icon()
+ if(E.damage_state == "00")
+ continue
+
var/icon/DI
- var/cache_index = "[O.damage_state]/[O.icon_name]/[dna.species.blood_color]/[dna.species.name]"
+ var/cache_index = "[E.damage_state]/[E.icon_name]/[dna.species.blood_color]/[dna.species.name]"
if(damage_icon_parts[cache_index] == null)
- DI = new /icon(dna.species.damage_overlays, O.damage_state) // the damage icon for whole human
- DI.Blend(new /icon(dna.species.damage_mask, O.icon_name), ICON_MULTIPLY) // mask with this organ's pixels
+ DI = new /icon(dna.species.damage_overlays, E.damage_state) // the damage icon for whole human
+ DI.Blend(new /icon(dna.species.damage_mask, E.icon_name), ICON_MULTIPLY) // mask with this organ's pixels
DI.Blend(dna.species.blood_color, ICON_MULTIPLY)
damage_icon_parts[cache_index] = DI
else
DI = damage_icon_parts[cache_index]
- standing_image.overlays += DI
+ damage_overlay.overlays += DI
- overlays_standing[H_DAMAGE_LAYER] = standing_image
+ apply_overlay(H_DAMAGE_LAYER)
- if(update_icons) update_icons()
//BASE MOB SPRITE
/mob/living/carbon/human/proc/update_body(var/update_icons=1, var/rebuild_base=0)
+ remove_overlay(BODY_LAYER)
+ remove_overlay(LIMBS_LAYER) // So we don't get the old species' sprite splatted on top of the new one's
+ remove_overlay(UNDERWEAR_LAYER)
- var/husk_color_mod = rgb(96,88,80)
- var/hulk_color_mod = rgb(48,224,40)
+ var/husk_color_mod = rgb(96, 88, 80)
+ var/hulk_color_mod = rgb(48, 224, 40)
var/husk = (HUSK in mutations)
- var/fat = (FAT in mutations)
var/hulk = (HULK in mutations)
var/skeleton = (SKELETON in mutations)
@@ -228,42 +184,18 @@ var/global/list/damage_icon_parts = list()
//Create a new, blank icon for our mob to use.
if(stand_icon)
qdel(stand_icon)
- stand_icon = new(dna.species.icon_template ? dna.species.icon_template : 'icons/mob/human.dmi',"blank")
- var/icon_key = ""
- var/obj/item/organ/internal/eyes/eyes = get_int_organ(/obj/item/organ/internal/eyes)
- if(eyes)
- icon_key += "[eyes.eye_colour]"
- else
- icon_key += "#000000"
+ update_misc_effects()
+ stand_icon = new (dna.species.icon_template ? dna.species.icon_template : 'icons/mob/human.dmi', "blank")
+ var/list/standing = list()
+ var/icon_key = generate_icon_render_key()
- for(var/organ_tag in dna.species.has_limbs)
- var/obj/item/organ/external/part = bodyparts_by_name[organ_tag]
- if(isnull(part))
- icon_key += "0"
- else if(part.is_robotic())
- icon_key += "2[part.model ? "-[part.model]": ""]"
- else if(part.status & ORGAN_DEAD)
- icon_key += "3"
- else
- icon_key += "1"
-
- if(part)
- var/datum/species/S = GLOB.all_species[part.dna.species.name] //This has to reference the species datums from round start, since they're global and unchanging
- icon_key += "[S.race_key]"
- icon_key += "[part.dna.GetUIState(DNA_UI_GENDER)]"
- icon_key += "[part.dna.GetUIValue(DNA_UI_SKIN_TONE)]"
- if(part.s_col)
- icon_key += "[part.s_col]"
- if(part.s_tone)
- icon_key += "[part.s_tone]"
-
- icon_key = "[icon_key][husk ? 1 : 0][fat ? 1 : 0][hulk ? 1 : 0][skeleton ? 1 : 0]"
-
- var/icon/base_icon
+ var/mutable_appearance/base
if(human_icon_cache[icon_key] && !rebuild_base)
- base_icon = human_icon_cache[icon_key]
+ base = human_icon_cache[icon_key]
+ standing += base
else
+ var/icon/base_icon
//BEGIN CACHED ICON GENERATION.
var/obj/item/organ/external/chest = get_organ("chest")
base_icon = chest.get_icon(skeleton)
@@ -272,7 +204,7 @@ var/global/list/damage_icon_parts = list()
var/icon/temp = part.get_icon(skeleton)
//That part makes left and right legs drawn topmost and lowermost when human looks WEST or EAST
//And no change in rendering for other parts (they icon_position is 0, so goes to 'else' part)
- if(part.icon_position&(LEFT|RIGHT))
+ if(part.icon_position & (LEFT | RIGHT))
var/icon/temp2 = new('icons/mob/human.dmi',"blank")
temp2.Insert(new/icon(temp,dir=NORTH),dir=NORTH)
temp2.Insert(new/icon(temp,dir=SOUTH),dir=SOUTH)
@@ -304,19 +236,16 @@ var/global/list/damage_icon_parts = list()
husk_over.Blend(mask, ICON_ADD)
base_icon.Blend(husk_over, ICON_OVERLAY)
- human_icon_cache[icon_key] = base_icon
+ var/mutable_appearance/new_base = mutable_appearance(base_icon, layer = -LIMBS_LAYER)
+ human_icon_cache[icon_key] = new_base
+ standing += new_base
+ //END CACHED ICON GENERATION.
- //END CACHED ICON GENERATION.
- stand_icon.Blend(base_icon,ICON_OVERLAY)
- if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && dna.species.bodyflags & TAIL_OVERLAPPED) // If the user's species is flagged to have a tail that needs to be overlapped by limbs... (having a non-tail body accessory like the snake body will override this)
- overlays_standing[LIMBS_LAYER] = image(stand_icon) // Diverts limbs to their own layer so they can overlay things (i.e. tails).
- else
- overlays_standing[LIMBS_LAYER] = null // So we don't get the old species' sprite splatted on top of the new one's
+ overlays_standing[LIMBS_LAYER] = standing
+ apply_overlay(LIMBS_LAYER)
//Underwear
- overlays_standing[UNDERWEAR_LAYER] = null
- var/icon/underwear_standing = new/icon('icons/mob/underwear.dmi',"nude")
-
+ var/icon/underwear_standing = new /icon('icons/mob/underwear.dmi', "nude")
if(underwear && dna.species.clothing_flags & HAS_UNDERWEAR)
var/datum/sprite_accessory/underwear/U = GLOB.underwear_list[underwear]
if(U)
@@ -327,27 +256,25 @@ var/global/list/damage_icon_parts = list()
if(U2)
underwear_standing.Blend(new /icon(U2.icon, "us_[U2.icon_state]_s"), ICON_OVERLAY)
-
if(socks && dna.species.clothing_flags & HAS_SOCKS)
var/datum/sprite_accessory/socks/U3 = GLOB.socks_list[socks]
if(U3)
underwear_standing.Blend(new /icon(U3.icon, "sk_[U3.icon_state]_s"), ICON_OVERLAY)
if(underwear_standing)
- overlays_standing[UNDERWEAR_LAYER] = image(underwear_standing)
-
-
- if(update_icons)
- update_icons()
+ overlays_standing[UNDERWEAR_LAYER] = mutable_appearance(underwear_standing, layer = -UNDERWEAR_LAYER)
+ apply_overlay(UNDERWEAR_LAYER)
if(lip_style && (LIPS in dna.species.species_traits))
- var/icon/lips = icon("icon"='icons/mob/human_face.dmi', "icon_state"="lips_[lip_style]_s")
+ var/icon/lips = icon("icon" = 'icons/mob/human_face.dmi', "icon_state" = "lips_[lip_style]_s")
lips.Blend(lip_color, ICON_ADD)
+ standing += mutable_appearance(lips, layer = -BODY_LAYER)
- stand_icon.Blend(lips, ICON_OVERLAY)
-
+ overlays_standing[BODY_LAYER] = standing
+ apply_overlay(BODY_LAYER)
//tail
update_tail_layer(0)
+ update_int_organs()
//head accessory
update_head_accessory(0)
//markings
@@ -360,10 +287,10 @@ var/global/list/damage_icon_parts = list()
//MARKINGS OVERLAY
/mob/living/carbon/human/proc/update_markings(var/update_icons=1)
//Reset our markings.
- overlays_standing[MARKINGS_LAYER] = null
+ remove_overlay(MARKINGS_LAYER)
//Base icon.
- var/icon/markings_standing = new/icon('icons/mob/body_accessory.dmi',"accessory_none_s")
+ var/icon/markings_standing = icon("icon" = 'icons/mob/body_accessory.dmi', "icon_state" = "accessory_none_s")
//Body markings.
var/obj/item/organ/external/chest/chest_organ = get_organ("chest")
@@ -371,7 +298,7 @@ var/global/list/damage_icon_parts = list()
var/body_marking = m_styles["body"]
var/datum/sprite_accessory/body_marking_style = GLOB.marking_styles_list[body_marking]
if(body_marking_style && body_marking_style.species_allowed && (dna.species.name in body_marking_style.species_allowed))
- var/icon/b_marking_s = new/icon("icon" = body_marking_style.icon, "icon_state" = "[body_marking_style.icon_state]_s")
+ var/icon/b_marking_s = icon("icon" = body_marking_style.icon, "icon_state" = "[body_marking_style.icon_state]_s")
if(body_marking_style.do_colouration)
b_marking_s.Blend(m_colours["body"], ICON_ADD)
markings_standing.Blend(b_marking_s, ICON_OVERLAY)
@@ -381,33 +308,30 @@ var/global/list/damage_icon_parts = list()
var/head_marking = m_styles["head"]
var/datum/sprite_accessory/head_marking_style = GLOB.marking_styles_list[head_marking]
if(head_marking_style && head_marking_style.species_allowed && (head_organ.dna.species.name in head_marking_style.species_allowed))
- var/icon/h_marking_s = new/icon("icon" = head_marking_style.icon, "icon_state" = "[head_marking_style.icon_state]_s")
+ var/icon/h_marking_s = icon("icon" = head_marking_style.icon, "icon_state" = "[head_marking_style.icon_state]_s")
if(head_marking_style.do_colouration)
h_marking_s.Blend(m_colours["head"], ICON_ADD)
markings_standing.Blend(h_marking_s, ICON_OVERLAY)
- overlays_standing[MARKINGS_LAYER] = image(markings_standing)
-
- if(update_icons) update_icons()
+ overlays_standing[MARKINGS_LAYER] = mutable_appearance(markings_standing, layer = -MARKINGS_LAYER)
+ apply_overlay(MARKINGS_LAYER)
//HEAD ACCESSORY OVERLAY
/mob/living/carbon/human/proc/update_head_accessory(var/update_icons=1)
//Reset our head accessory
- overlays_standing[HEAD_ACCESSORY_LAYER] = null
- overlays_standing[HEAD_ACC_OVER_LAYER] = null
+ remove_overlay(HEAD_ACCESSORY_LAYER)
+ remove_overlay(HEAD_ACC_OVER_LAYER)
var/obj/item/organ/external/head/head_organ = get_organ("head")
if(!head_organ)
- if(update_icons) update_icons()
return
//masks and helmets can obscure our head accessory
if((head && (head.flags & BLOCKHAIR)) || (wear_mask && (wear_mask.flags & BLOCKHAIR)))
- if(update_icons) update_icons()
return
//base icons
- var/icon/head_accessory_standing = new /icon('icons/mob/body_accessory.dmi',"accessory_none_s")
+ var/icon/head_accessory_standing = new /icon('icons/mob/body_accessory.dmi',"accessory_none_s")
if(head_organ.ha_style && (head_organ.dna.species.bodyflags & HAS_HEAD_ACCESSORY))
var/datum/sprite_accessory/head_accessory/head_accessory_style = GLOB.head_accessory_styles_list[head_organ.ha_style]
if(head_accessory_style && head_accessory_style.species_allowed)
@@ -419,38 +343,33 @@ var/global/list/damage_icon_parts = list()
//Having it this way preserves animations. Useful for animated antennae.
if(head_accessory_style.over_hair) //Select which layer to use based on the properties of the head accessory style.
- overlays_standing[HEAD_ACC_OVER_LAYER] = image(head_accessory_standing)
+ overlays_standing[HEAD_ACC_OVER_LAYER] = mutable_appearance(head_accessory_standing, layer = -HEAD_ACC_OVER_LAYER)
+ apply_overlay(HEAD_ACC_OVER_LAYER)
else
- overlays_standing[HEAD_ACCESSORY_LAYER] = image(head_accessory_standing)
+ overlays_standing[HEAD_ACCESSORY_LAYER] = mutable_appearance(head_accessory_standing, layer = -HEAD_ACCESSORY_LAYER)
+ apply_overlay(HEAD_ACCESSORY_LAYER)
else
//warning("Invalid ha_style for [species.name]: [ha_style]")
- if(update_icons) update_icons()
//HAIR OVERLAY
/mob/living/carbon/human/proc/update_hair(var/update_icons=1)
//Reset our hair
- overlays_standing[HAIR_LAYER] = null
+ remove_overlay(HAIR_LAYER)
var/obj/item/organ/external/head/head_organ = get_organ("head")
if(!head_organ)
- if(update_icons) update_icons()
return
//masks and helmets can obscure our hair, unless we're a synthetic
if((head && (head.flags & BLOCKHAIR)) || (wear_mask && (wear_mask.flags & BLOCKHAIR)))
- if(update_icons) update_icons()
return
//base icons
var/icon/hair_standing = new /icon('icons/mob/human_face.dmi',"bald_s")
- //var/icon/debrained_s = new /icon("icon"='icons/mob/human_face.dmi', "icon_state" = "debrained_s")
-
if(head_organ.h_style && !(head && (head.flags & BLOCKHEADHAIR) && !(isSynthetic())))
var/datum/sprite_accessory/hair/hair_style = GLOB.hair_styles_full_list[head_organ.h_style]
- //if(!src.get_int_organ(/obj/item/organ/internal/brain) && !ismachine(src))//make it obvious we have NO BRAIN
- // hair_standing.Blend(debrained_s, ICON_OVERLAY)
if(hair_style && hair_style.species_allowed)
if((head_organ.dna.species.name in hair_style.species_allowed) || (head_organ.dna.species.bodyflags & ALL_RPARTS)) //If the head's species is in the list of allowed species for the hairstyle, or the head's species is one flagged to have bodies comprised wholly of cybernetics...
var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s")
@@ -471,30 +390,26 @@ var/global/list/damage_icon_parts = list()
//warning("Invalid h_style for [species.name]: [h_style]")
//hair_standing.Blend(debrained_s, ICON_OVERLAY)//how does i overlay for fish?
- overlays_standing[HAIR_LAYER] = image(hair_standing)
-
- if(update_icons) update_icons()
+ overlays_standing[HAIR_LAYER] = mutable_appearance(hair_standing, layer = -HAIR_LAYER)
+ apply_overlay(HAIR_LAYER)
//FACIAL HAIR OVERLAY
/mob/living/carbon/human/proc/update_fhair(var/update_icons=1)
//Reset our facial hair
- overlays_standing[FHAIR_LAYER] = null
- overlays_standing[FHAIR_OVER_LAYER] = null
+ remove_overlay(FHAIR_LAYER)
+ remove_overlay(FHAIR_OVER_LAYER)
var/obj/item/organ/external/head/head_organ = get_organ("head")
if(!head_organ)
- if(update_icons) update_icons()
return
//masks and helmets can obscure our facial hair, unless we're a synthetic
if((head && (head.flags & BLOCKHAIR)) || (wear_mask && (wear_mask.flags & BLOCKHAIR)))
- if(update_icons) update_icons()
return
//base icons
var/icon/face_standing = new /icon('icons/mob/human_face.dmi',"bald_s")
-
if(head_organ.f_style)
var/datum/sprite_accessory/facial_hair/facial_hair_style = GLOB.facial_hair_styles_list[head_organ.f_style]
if(facial_hair_style && facial_hair_style.species_allowed)
@@ -514,46 +429,49 @@ var/global/list/damage_icon_parts = list()
face_standing.Blend(facial_s, ICON_OVERLAY)
if(facial_hair_style.over_hair) //Select which layer to use based on the properties of the facial hair style.
- overlays_standing[FHAIR_OVER_LAYER] = image(face_standing)
+ overlays_standing[FHAIR_OVER_LAYER] = mutable_appearance(face_standing, layer = -FHAIR_OVER_LAYER)
+ apply_overlay(FHAIR_OVER_LAYER)
else
- overlays_standing[FHAIR_LAYER] = image(face_standing)
+ overlays_standing[FHAIR_LAYER] = mutable_appearance(face_standing, layer = -FHAIR_LAYER)
+ apply_overlay(FHAIR_LAYER)
else
//warning("Invalid f_style for [species.name]: [f_style]")
- if(update_icons) update_icons()
+
/mob/living/carbon/human/update_mutations(var/update_icons=1)
+ remove_overlay(MUTATIONS_LAYER)
var/fat
if(FAT in mutations)
fat = "fat"
- var/image/standing = image("icon" = 'icons/effects/genetics.dmi')
+ var/mutable_appearance/standing = mutable_appearance('icons/effects/genetics.dmi', layer = -MUTATIONS_LAYER)
var/add_image = 0
var/g = "m"
- if(gender == FEMALE) g = "f"
+ if(gender == FEMALE)
+ g = "f"
// DNA2 - Drawing underlays.
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(LASER)
- standing.overlays += "lasereyes_s"
+ standing.overlays += "lasereyes_s"
add_image = 1
if((COLDRES in mutations) && (HEATRES in mutations))
- standing.underlays -= "cold[fat]_s"
- standing.underlays -= "fire[fat]_s"
- standing.underlays += "coldfire[fat]_s"
+ standing.underlays -= "cold[fat]_s"
+ standing.underlays -= "fire[fat]_s"
+ standing.underlays += "coldfire[fat]_s"
+
if(add_image)
- overlays_standing[MUTATIONS_LAYER] = standing
- else
- overlays_standing[MUTATIONS_LAYER] = null
- if(update_icons) update_icons()
+ overlays_standing[MUTATIONS_LAYER] = standing
+ apply_overlay(MUTATIONS_LAYER)
/mob/living/carbon/human/proc/update_mutantrace(var/update_icons=1)
@@ -566,17 +484,14 @@ var/global/list/damage_icon_parts = list()
update_hair(0)
update_fhair(0)
- if(update_icons) update_icons()
/mob/living/carbon/human/update_fire()
+ remove_overlay(FIRE_LAYER)
if(on_fire)
if(!overlays_standing[FIRE_LAYER])
- overlays_standing[FIRE_LAYER] = image("icon"=fire_dmi, "icon_state"=fire_sprite)
- update_icons()
- else
- overlays_standing[FIRE_LAYER] = null
- update_icons()
+ overlays_standing[FIRE_LAYER] = mutable_appearance(fire_dmi, fire_sprite, layer = -FIRE_LAYER)
+ apply_overlay(FIRE_LAYER)
/* --------------------------------------- */
//For legacy support.
@@ -617,7 +532,7 @@ var/global/list/damage_icon_parts = list()
//vvvvvv UPDATE_INV PROCS vvvvvv
/mob/living/carbon/human/update_inv_w_uniform(var/update_icons=1)
-
+ remove_overlay(UNIFORM_LAYER)
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_w_uniform]
if(inv)
@@ -630,9 +545,10 @@ var/global/list/damage_icon_parts = list()
client.screen += w_uniform //Either way, add the item to the HUD
var/t_color = w_uniform.item_color
- if(!t_color) t_color = icon_state
- var/image/standing = image("icon_state" = "[t_color]_s")
+ if(!t_color)
+ t_color = icon_state
+ var/mutable_appearance/standing = mutable_appearance('icons/mob/uniform.dmi', "[t_color]_s", layer = -UNIFORM_LAYER)
if(FAT in mutations)
if(w_uniform.flags_size & ONESIZEFITSALL)
standing.icon = 'icons/mob/uniform_fat.dmi'
@@ -640,8 +556,6 @@ var/global/list/damage_icon_parts = list()
to_chat(src, "You burst out of \the [w_uniform]!")
unEquip(w_uniform)
return
- else
- standing.icon = 'icons/mob/uniform.dmi'
if(w_uniform.icon_override)
standing.icon = w_uniform.icon_override
@@ -650,13 +564,14 @@ var/global/list/damage_icon_parts = list()
if(w_uniform.blood_DNA)
var/image/bloodsies = image("icon" = dna.species.blood_mask, "icon_state" = "uniformblood")
- bloodsies.color = w_uniform.blood_color
- standing.overlays += bloodsies
+ bloodsies.color = w_uniform.blood_color
+ standing.overlays += bloodsies
- if(w_uniform:accessories.len) //WE CHECKED THE TYPE ABOVE. THIS REALLY SHOULD BE FINE.
+ if(w_uniform:accessories.len) //WE CHECKED THE TYPE ABOVE. THIS REALLY SHOULD BE FINE. // oh my god kys whoever made this if statement jfc :gun:
for(var/obj/item/clothing/accessory/A in w_uniform:accessories)
var/tie_color = A.item_color
- if(!tie_color) tie_color = A.icon_state
+ if(!tie_color)
+ tie_color = A.icon_state
if(A.icon_override)
standing.overlays += image("icon" = A.icon_override, "icon_state" = "[A.icon_state]")
else if(A.sprite_sheets && A.sprite_sheets[dna.species.name])
@@ -664,25 +579,24 @@ var/global/list/damage_icon_parts = list()
else
standing.overlays += image("icon" = 'icons/mob/ties.dmi', "icon_state" = "[tie_color]")
- overlays_standing[UNIFORM_LAYER] = standing
+ overlays_standing[UNIFORM_LAYER] = standing
else
- overlays_standing[UNIFORM_LAYER] = null
// Automatically drop anything in store / id / belt if you're not wearing a uniform. //CHECK IF NECESARRY
- for( var/obj/item/thing in list(r_store, l_store, wear_id, wear_pda, belt) ) //
- if(thing) //
- unEquip(thing) //
- if(client) //
- client.screen -= thing //
- //
+ for(var/obj/item/thing in list(r_store, l_store, wear_id, wear_pda, belt)) // whoever made this
+ if(thing) // you're a piece of fucking garbage
+ unEquip(thing) // why the fuck would you goddamn do this motherfucking shit
+ if(client) // INVENTORY CODE IN FUCKING ICON CODE
+ client.screen -= thing // WHAT THE FUCKING FUCK BAY GODDAMNIT
+ // **I FUCKING HATE YOU AAAAAAAAAA**
if(thing) //
thing.loc = loc //
thing.dropped(src) //
thing.layer = initial(thing.layer)
thing.plane = initial(thing.plane)
- if(update_icons) update_icons()
+ apply_overlay(UNIFORM_LAYER)
/mob/living/carbon/human/update_inv_wear_id(var/update_icons=1)
-
+ remove_overlay(ID_LAYER)
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_wear_id]
if(inv)
@@ -694,16 +608,11 @@ var/global/list/damage_icon_parts = list()
client.screen += wear_id
if(w_uniform && w_uniform:displays_id)
- overlays_standing[ID_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "id")
- else
- overlays_standing[ID_LAYER] = null
- else
- overlays_standing[ID_LAYER] = null
-
- if(update_icons) update_icons()
+ overlays_standing[ID_LAYER] = mutable_appearance('icons/mob/mob.dmi', "id", layer = -ID_LAYER)
+ apply_overlay(ID_LAYER)
/mob/living/carbon/human/update_inv_gloves(var/update_icons=1)
-
+ remove_overlay(GLOVES_LAYER)
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_gloves]
if(inv)
@@ -718,32 +627,30 @@ var/global/list/damage_icon_parts = list()
var/t_state = gloves.item_state
if(!t_state) t_state = gloves.icon_state
- var/image/standing
+ var/mutable_appearance/standing
if(gloves.icon_override)
- standing = image("icon" = gloves.icon_override, "icon_state" = "[t_state]")
+ standing = mutable_appearance(gloves.icon_override, "[t_state]", layer = -GLOVES_LAYER)
else if(gloves.sprite_sheets && gloves.sprite_sheets[dna.species.name])
- standing = image("icon" = gloves.sprite_sheets[dna.species.name], "icon_state" = "[t_state]")
+ standing = mutable_appearance(gloves.sprite_sheets[dna.species.name], "[t_state]", layer = -GLOVES_LAYER)
else
- standing = image("icon" = 'icons/mob/hands.dmi', "icon_state" = "[t_state]")
+ standing = mutable_appearance('icons/mob/hands.dmi', "[t_state]", layer = -GLOVES_LAYER)
if(gloves.blood_DNA)
var/image/bloodsies = image("icon" = dna.species.blood_mask, "icon_state" = "bloodyhands")
bloodsies.color = gloves.blood_color
- standing.overlays += bloodsies
+ standing.overlays += bloodsies
overlays_standing[GLOVES_LAYER] = standing
else
if(blood_DNA)
- var/image/bloodsies = image("icon" = dna.species.blood_mask, "icon_state" = "bloodyhands")
+ var/mutable_appearance/bloodsies = mutable_appearance(dna.species.blood_mask, "bloodyhands", layer = -GLOVES_LAYER)
bloodsies.color = hand_blood_color
overlays_standing[GLOVES_LAYER] = bloodsies
- else
- overlays_standing[GLOVES_LAYER] = null
- if(update_icons) update_icons()
+ apply_overlay(GLOVES_LAYER)
/mob/living/carbon/human/update_inv_glasses(var/update_icons=1)
- overlays_standing[GLASSES_LAYER] = null
- overlays_standing[GLASSES_OVER_LAYER] = null
+ remove_overlay(GLASSES_LAYER)
+ remove_overlay(GLASSES_OVER_LAYER)
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_glasses]
@@ -751,7 +658,7 @@ var/global/list/damage_icon_parts = list()
inv.update_icon()
if(glasses)
- var/image/new_glasses
+ var/mutable_appearance/new_glasses
var/obj/item/organ/external/head/head_organ = get_organ("head")
if(client && hud_used && hud_used.hud_shown)
if(hud_used.inventory_shown) //if the inventory is open ...
@@ -759,22 +666,23 @@ var/global/list/damage_icon_parts = list()
client.screen += glasses //Either way, add the item to the HUD
if(glasses.icon_override)
- new_glasses = image("icon" = glasses.icon_override, "icon_state" = "[glasses.icon_state]")
+ new_glasses = mutable_appearance(glasses.icon_override, "[glasses.icon_state]", layer = -GLASSES_LAYER)
else if(glasses.sprite_sheets && glasses.sprite_sheets[head_organ.dna.species.name])
- new_glasses = image("icon" = glasses.sprite_sheets[head_organ.dna.species.name], "icon_state" = "[glasses.icon_state]")
+ new_glasses = mutable_appearance(glasses.sprite_sheets[head_organ.dna.species.name], "[glasses.icon_state]", layer = -GLASSES_LAYER)
else
- new_glasses = image("icon" = 'icons/mob/eyes.dmi', "icon_state" = "[glasses.icon_state]")
+ new_glasses = mutable_appearance('icons/mob/eyes.dmi', "[glasses.icon_state]", layer = -GLASSES_LAYER)
var/datum/sprite_accessory/hair/hair_style = GLOB.hair_styles_full_list[head_organ.h_style]
if(hair_style && hair_style.glasses_over) //Select which layer to use based on the properties of the hair style. Hair styles with hair that don't overhang the arms of the glasses should have glasses_over set to a positive value.
+ new_glasses.layer = -GLASSES_OVER_LAYER
overlays_standing[GLASSES_OVER_LAYER] = new_glasses
+ apply_overlay(GLASSES_OVER_LAYER)
else
overlays_standing[GLASSES_LAYER] = new_glasses
-
- if(update_icons) update_icons()
+ apply_overlay(GLASSES_LAYER)
/mob/living/carbon/human/update_inv_ears(var/update_icons=1)
-
+ remove_overlay(EARS_LAYER)
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_l_ear]
if(inv)
@@ -795,12 +703,12 @@ var/global/list/damage_icon_parts = list()
var/t_type = l_ear.icon_state
if(l_ear.icon_override)
t_type = "[t_type]_l"
- overlays_standing[EARS_LAYER] = image("icon" = l_ear.icon_override, "icon_state" = "[t_type]")
+ overlays_standing[EARS_LAYER] = mutable_appearance(l_ear.icon_override, "[t_type]", layer = -EARS_LAYER)
else if(l_ear.sprite_sheets && l_ear.sprite_sheets[dna.species.name])
t_type = "[t_type]_l"
- overlays_standing[EARS_LAYER] = image("icon" = l_ear.sprite_sheets[dna.species.name], "icon_state" = "[t_type]")
+ overlays_standing[EARS_LAYER] = mutable_appearance(l_ear.sprite_sheets[dna.species.name], "[t_type]", layer = -EARS_LAYER)
else
- overlays_standing[EARS_LAYER] = image("icon" = 'icons/mob/ears.dmi', "icon_state" = "[t_type]")
+ overlays_standing[EARS_LAYER] = mutable_appearance('icons/mob/ears.dmi', "[t_type]", layer = -EARS_LAYER)
if(r_ear)
if(client && hud_used && hud_used.hud_shown)
@@ -811,19 +719,16 @@ var/global/list/damage_icon_parts = list()
var/t_type = r_ear.icon_state
if(r_ear.icon_override)
t_type = "[t_type]_r"
- overlays_standing[EARS_LAYER] = image("icon" = r_ear.icon_override, "icon_state" = "[t_type]")
+ overlays_standing[EARS_LAYER] = mutable_appearance(r_ear.icon_override, "[t_type]", layer = -EARS_LAYER)
else if(r_ear.sprite_sheets && r_ear.sprite_sheets[dna.species.name])
t_type = "[t_type]_r"
- overlays_standing[EARS_LAYER] = image("icon" = r_ear.sprite_sheets[dna.species.name], "icon_state" = "[t_type]")
+ overlays_standing[EARS_LAYER] = mutable_appearance(r_ear.sprite_sheets[dna.species.name], "[t_type]", layer = -EARS_LAYER)
else
- overlays_standing[EARS_LAYER] = image("icon" = 'icons/mob/ears.dmi', "icon_state" = "[t_type]")
-
- else
- overlays_standing[EARS_LAYER] = null
- if(update_icons) update_icons()
+ overlays_standing[EARS_LAYER] = mutable_appearance('icons/mob/ears.dmi', "[t_type]", layer = -EARS_LAYER)
+ apply_overlay(EARS_LAYER)
/mob/living/carbon/human/update_inv_shoes(var/update_icons=1)
-
+ remove_overlay(SHOES_LAYER)
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_shoes]
if(inv)
@@ -835,13 +740,13 @@ var/global/list/damage_icon_parts = list()
shoes.screen_loc = ui_shoes //...draw the item in the inventory screen
client.screen += shoes //Either way, add the item to the HUD
- var/image/standing
+ var/mutable_appearance/standing
if(shoes.icon_override)
- standing = image("icon" = shoes.icon_override, "icon_state" = "[shoes.icon_state]")
+ standing = mutable_appearance(shoes.icon_override, "[shoes.icon_state]", layer = -SHOES_LAYER)
else if(shoes.sprite_sheets && shoes.sprite_sheets[dna.species.name])
- standing = image("icon" = shoes.sprite_sheets[dna.species.name], "icon_state" = "[shoes.icon_state]")
+ standing = mutable_appearance(shoes.sprite_sheets[dna.species.name], "[shoes.icon_state]", layer = -SHOES_LAYER)
else
- standing = image("icon" = 'icons/mob/feet.dmi', "icon_state" = "[shoes.icon_state]")
+ standing = mutable_appearance('icons/mob/feet.dmi', "[shoes.icon_state]", layer = -SHOES_LAYER)
if(shoes.blood_DNA)
@@ -851,15 +756,13 @@ var/global/list/damage_icon_parts = list()
overlays_standing[SHOES_LAYER] = standing
else
if(feet_blood_DNA)
- var/image/bloodsies = image("icon" = dna.species.blood_mask, "icon_state" = "shoeblood")
+ var/mutable_appearance/bloodsies = mutable_appearance(dna.species.blood_mask, "shoeblood", layer = -SHOES_LAYER)
bloodsies.color = feet_blood_color
overlays_standing[SHOES_LAYER] = bloodsies
- else
- overlays_standing[SHOES_LAYER] = null
- if(update_icons) update_icons()
+ apply_overlay(SHOES_LAYER)
/mob/living/carbon/human/update_inv_s_store(var/update_icons=1)
-
+ remove_overlay(SUIT_STORE_LAYER)
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_s_store]
if(inv)
@@ -874,42 +777,37 @@ var/global/list/damage_icon_parts = list()
if(!t_state)
t_state = s_store.icon_state
var/dmi='icons/mob/belt_mirror.dmi'
- overlays_standing[SUIT_STORE_LAYER] = image("icon" = dmi, "icon_state" = "[t_state]")
+ overlays_standing[SUIT_STORE_LAYER] = mutable_appearance(dmi, "[t_state]", layer = -SUIT_STORE_LAYER)
s_store.screen_loc = ui_sstore1 //TODO
- else
- overlays_standing[SUIT_STORE_LAYER] = null
- if(update_icons) update_icons()
+ apply_overlay(SUIT_STORE_LAYER)
/mob/living/carbon/human/update_inv_head(var/update_icons=1)
..()
+ remove_overlay(HEAD_LAYER)
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_head]
if(inv)
inv.update_icon()
if(head)
- var/image/standing
+ var/mutable_appearance/standing
if(head.icon_override)
- standing = image("icon" = head.icon_override, "icon_state" = "[head.icon_state]")
+ standing = mutable_appearance(head.icon_override, "[head.icon_state]", layer = -HEAD_LAYER)
else if(head.sprite_sheets && head.sprite_sheets[dna.species.name])
- standing = image("icon" = head.sprite_sheets[dna.species.name], "icon_state" = "[head.icon_state]")
+ standing = mutable_appearance(head.sprite_sheets[dna.species.name], "[head.icon_state]", layer = -HEAD_LAYER)
else
- standing = image("icon" = 'icons/mob/head.dmi', "icon_state" = "[head.icon_state]")
+ standing = mutable_appearance('icons/mob/head.dmi', "[head.icon_state]", layer = -HEAD_LAYER)
if(head.blood_DNA)
var/image/bloodsies = image("icon" = dna.species.blood_mask, "icon_state" = "helmetblood")
bloodsies.color = head.blood_color
- standing.overlays += bloodsies
- overlays_standing[HEAD_LAYER] = standing
-
-
- else
- overlays_standing[HEAD_LAYER] = null
- if(update_icons) update_icons()
+ standing.overlays += bloodsies
+ overlays_standing[HEAD_LAYER] = standing
+ apply_overlay(HEAD_LAYER)
/mob/living/carbon/human/update_inv_belt(var/update_icons=1)
-
+ remove_overlay(BELT_LAYER)
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_belt]
if(inv)
@@ -921,21 +819,21 @@ var/global/list/damage_icon_parts = list()
if(belt)
var/t_state = belt.item_state
- if(!t_state) t_state = belt.icon_state
+ if(!t_state)
+ t_state = belt.icon_state
if(belt.icon_override)
t_state = "[t_state]_be"
- overlays_standing[BELT_LAYER] = image("icon" = belt.icon_override, "icon_state" = "[t_state]")
+ overlays_standing[BELT_LAYER] = mutable_appearance(belt.icon_override, "[t_state]", layer = -BELT_LAYER)
else if(belt.sprite_sheets && belt.sprite_sheets[dna.species.name])
- overlays_standing[BELT_LAYER] = image("icon" = belt.sprite_sheets[dna.species.name], "icon_state" = "[t_state]")
+ overlays_standing[BELT_LAYER] = mutable_appearance(belt.sprite_sheets[dna.species.name], "[t_state]", layer = -BELT_LAYER)
else
- overlays_standing[BELT_LAYER] = image("icon" = 'icons/mob/belt.dmi', "icon_state" = "[t_state]")
- else
- overlays_standing[BELT_LAYER] = null
- if(update_icons) update_icons()
+ overlays_standing[BELT_LAYER] = mutable_appearance('icons/mob/belt.dmi', "[t_state]", layer = -BELT_LAYER)
+ apply_overlay(BELT_LAYER)
/mob/living/carbon/human/update_inv_wear_suit(var/update_icons=1)
+ remove_overlay(SUIT_LAYER)
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_wear_suit]
if(inv)
@@ -947,47 +845,37 @@ var/global/list/damage_icon_parts = list()
wear_suit.screen_loc = ui_oclothing //TODO //...draw the item in the inventory screen
client.screen += wear_suit //Either way, add the item to the HUD
- var/image/standing
+ var/mutable_appearance/standing
if(wear_suit.icon_override)
- standing = image("icon" = wear_suit.icon_override, "icon_state" = "[wear_suit.icon_state]")
+ standing = mutable_appearance(wear_suit.icon_override, "[wear_suit.icon_state]", layer = -SUIT_LAYER)
else if(wear_suit.sprite_sheets && wear_suit.sprite_sheets[dna.species.name])
- standing = image("icon" = wear_suit.sprite_sheets[dna.species.name], "icon_state" = "[wear_suit.icon_state]")
+ standing = mutable_appearance(wear_suit.sprite_sheets[dna.species.name], "[wear_suit.icon_state]", layer = -SUIT_LAYER)
else if(FAT in mutations)
if(wear_suit.flags_size & ONESIZEFITSALL)
- standing = image("icon" = 'icons/mob/suit_fat.dmi', "icon_state" = "[wear_suit.icon_state]")
+ standing = mutable_appearance('icons/mob/suit_fat.dmi', "[wear_suit.icon_state]", layer = -SUIT_LAYER)
else
to_chat(src, "You burst out of \the [wear_suit]!")
unEquip(wear_suit)
return
else
- standing = image("icon" = 'icons/mob/suit.dmi', "icon_state" = "[wear_suit.icon_state]")
-
+ standing = mutable_appearance('icons/mob/suit.dmi', "[wear_suit.icon_state]", layer = -SUIT_LAYER)
if(wear_suit.breakouttime)
drop_l_hand()
drop_r_hand()
-
if(wear_suit.blood_DNA)
var/obj/item/clothing/suit/S = wear_suit
var/image/bloodsies = image("icon" = dna.species.blood_mask, "icon_state" = "[S.blood_overlay_type]blood")
bloodsies.color = wear_suit.blood_color
- standing.overlays += bloodsies
+ standing.overlays += bloodsies
+ overlays_standing[SUIT_LAYER] = standing
- overlays_standing[SUIT_LAYER] = standing
-
- update_tail_layer(0)
-
- else
- overlays_standing[SUIT_LAYER] = null
-
- update_tail_layer(0)
-
+ apply_overlay(SUIT_LAYER)
+ update_tail_layer(0)
update_collar(0)
- if(update_icons) update_icons()
-
/mob/living/carbon/human/update_inv_pockets()
if(client && hud_used)
var/obj/screen/inventory/inv
@@ -1021,6 +909,7 @@ var/global/list/damage_icon_parts = list()
/mob/living/carbon/human/update_inv_wear_mask(var/update_icons = 1)
..()
+ remove_overlay(FACEMASK_LAYER)
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_wear_mask]
if(inv)
@@ -1031,107 +920,94 @@ var/global/list/damage_icon_parts = list()
if(head_organ.alt_head && head_organ.alt_head != "None")
alternate_head = GLOB.alt_heads_list[head_organ.alt_head]
- var/image/standing
+ var/mutable_appearance/standing
var/icon/mask_icon = new(wear_mask.icon)
if(wear_mask.icon_override)
mask_icon = new(wear_mask.icon_override)
- standing = image("icon" = wear_mask.icon_override, "icon_state" = "[wear_mask.icon_state][(alternate_head && ("[wear_mask.icon_state]_[alternate_head.suffix]" in mask_icon.IconStates())) ? "_[alternate_head.suffix]" : ""]")
+ standing = mutable_appearance(wear_mask.icon_override, "[wear_mask.icon_state][(alternate_head && ("[wear_mask.icon_state]_[alternate_head.suffix]" in mask_icon.IconStates())) ? "_[alternate_head.suffix]" : ""]", layer = -FACEMASK_LAYER)
else if(wear_mask.sprite_sheets && wear_mask.sprite_sheets[dna.species.name])
mask_icon = new(wear_mask.sprite_sheets[dna.species.name])
- standing = image("icon" = wear_mask.sprite_sheets[dna.species.name], "icon_state" = "[wear_mask.icon_state][(alternate_head && ("[wear_mask.icon_state]_[alternate_head.suffix]" in mask_icon.IconStates())) ? "_[alternate_head.suffix]" : ""]")
+ standing = mutable_appearance(wear_mask.sprite_sheets[dna.species.name], "[wear_mask.icon_state][(alternate_head && ("[wear_mask.icon_state]_[alternate_head.suffix]" in mask_icon.IconStates())) ? "_[alternate_head.suffix]" : ""]", layer = -FACEMASK_LAYER)
else
- standing = image("icon" = 'icons/mob/mask.dmi', "icon_state" = "[wear_mask.icon_state][(alternate_head && ("[wear_mask.icon_state]_[alternate_head.suffix]" in mask_icon.IconStates())) ? "_[alternate_head.suffix]" : ""]")
+ standing = mutable_appearance('icons/mob/mask.dmi', "[wear_mask.icon_state][(alternate_head && ("[wear_mask.icon_state]_[alternate_head.suffix]" in mask_icon.IconStates())) ? "_[alternate_head.suffix]" : ""]", layer = -FACEMASK_LAYER)
if(!istype(wear_mask, /obj/item/clothing/mask/cigarette) && wear_mask.blood_DNA)
var/image/bloodsies = image("icon" = dna.species.blood_mask, "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()
+ overlays_standing[FACEMASK_LAYER] = standing
+ apply_overlay(FACEMASK_LAYER)
/mob/living/carbon/human/update_inv_back(var/update_icons=1)
..()
+ remove_overlay(BACK_LAYER)
if(back)
//determine the icon to use
- var/icon/standing
+ var/mutable_appearance/standing
if(back.icon_override)
- standing = image("icon" = back.icon_override, "icon_state" = "[back.icon_state]")
+ standing = mutable_appearance(back.icon_override, "[back.icon_state]", layer = -BACK_LAYER)
else if(istype(back, /obj/item/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/rig/rig = back
standing = rig.mob_icon
else if(back.sprite_sheets && back.sprite_sheets[dna.species.name])
- standing = image("icon" = back.sprite_sheets[dna.species.name], "icon_state" = "[back.icon_state]")
+ standing = mutable_appearance(back.sprite_sheets[dna.species.name], "[back.icon_state]", layer = -BACK_LAYER)
else
- standing = image("icon" = 'icons/mob/back.dmi', "icon_state" = "[back.icon_state]")
+ standing = mutable_appearance('icons/mob/back.dmi', "[back.icon_state]", layer = -BACK_LAYER)
//create the image
overlays_standing[BACK_LAYER] = standing
- else
- overlays_standing[BACK_LAYER] = null
-
- if(update_icons) update_icons()
+ apply_overlay(BACK_LAYER)
/mob/living/carbon/human/update_inv_handcuffed(var/update_icons=1)
- overlays_standing[HANDCUFF_LAYER] = null
+ remove_overlay(HANDCUFF_LAYER)
if(handcuffed)
if(istype(handcuffed, /obj/item/restraints/handcuffs/pinkcuffs))
- overlays_standing[HANDCUFF_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "pinkcuff1")
+ overlays_standing[HANDCUFF_LAYER] = mutable_appearance('icons/mob/mob.dmi', "pinkcuff1", layer = -HANDCUFF_LAYER)
else
- overlays_standing[HANDCUFF_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "handcuff1")
-
- if(update_icons)
- update_icons()
+ overlays_standing[HANDCUFF_LAYER] = mutable_appearance('icons/mob/mob.dmi', "handcuff1", layer = -HANDCUFF_LAYER)
+ apply_overlay(HANDCUFF_LAYER)
/mob/living/carbon/human/update_inv_legcuffed(var/update_icons=1)
+ remove_overlay(LEGCUFF_LAYER)
clear_alert("legcuffed")
if(legcuffed)
- overlays_standing[LEGCUFF_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "legcuff1")
+ overlays_standing[LEGCUFF_LAYER] = mutable_appearance('icons/mob/mob.dmi', "legcuff1", layer = -LEGCUFF_LAYER)
throw_alert("legcuffed", /obj/screen/alert/restrained/legcuffed, new_master = legcuffed)
if(m_intent != MOVE_INTENT_WALK)
m_intent = MOVE_INTENT_WALK
if(hud_used && hud_used.move_intent)
hud_used.move_intent.icon_state = "walking"
-
- else
- overlays_standing[LEGCUFF_LAYER] = null
- if(update_icons)
- update_icons()
+ apply_overlay(LEGCUFF_LAYER)
/mob/living/carbon/human/update_inv_r_hand(var/update_icons=1)
..()
+ remove_overlay(R_HAND_LAYER)
if(r_hand)
var/t_state = r_hand.item_state
if(!t_state)
t_state = r_hand.icon_state
- var/image/I = image("icon" = r_hand.righthand_file, "icon_state" = "[t_state]")
+ var/mutable_appearance/I = mutable_appearance(r_hand.righthand_file, "[t_state]", layer = -R_HAND_LAYER)
I = center_image(I, r_hand.inhand_x_dimension, r_hand.inhand_y_dimension)
overlays_standing[R_HAND_LAYER] = I
- else
- overlays_standing[R_HAND_LAYER] = null
- if(update_icons)
- update_icons()
+ apply_overlay(R_HAND_LAYER)
/mob/living/carbon/human/update_inv_l_hand(var/update_icons=1)
..()
+ remove_overlay(L_HAND_LAYER)
if(l_hand)
var/t_state = l_hand.item_state
if(!t_state)
t_state = l_hand.icon_state
- var/image/I = image("icon" = l_hand.lefthand_file, "icon_state" = "[t_state]")
+ var/mutable_appearance/I = mutable_appearance(l_hand.lefthand_file, "[t_state]", layer = -L_HAND_LAYER)
I = center_image(I, l_hand.inhand_x_dimension, l_hand.inhand_y_dimension)
overlays_standing[L_HAND_LAYER] = I
- else
- overlays_standing[L_HAND_LAYER] = null
- if(update_icons)
- update_icons()
+ apply_overlay(L_HAND_LAYER)
//human HUD updates for items in our inventory
@@ -1157,10 +1033,11 @@ var/global/list/damage_icon_parts = list()
/mob/living/carbon/human/proc/update_tail_layer(var/update_icons=1)
- overlays_standing[TAIL_UNDERLIMBS_LAYER] = null // SEW direction icons, overlayed by LIMBS_LAYER.
- overlays_standing[TAIL_LAYER] = null /* This will be one of two things:
- If the species' tail is overlapped by limbs, this will be only the N direction icon so tails can still appear on the outside of uniforms and such.
- Otherwise, since the user's tail isn't overlapped by limbs, it will be a full icon with all directions. */
+ remove_overlay(TAIL_UNDERLIMBS_LAYER) // SEW direction icons, overlayed by LIMBS_LAYER.
+ remove_overlay(TAIL_LAYER) /* This will be one of two things:
+ If the species' tail is overlapped by limbs, this will be only the N direction icon so tails
+ can still appear on the outside of uniforms and such.
+ Otherwise, since the user's tail isn't overlapped by limbs, it will be a full icon with all directions. */
var/icon/tail_marking_icon
var/datum/sprite_accessory/body_markings/tail/tail_marking_style
@@ -1184,16 +1061,25 @@ var/global/list/damage_icon_parts = list()
under.Insert(new/icon(accessory_s, dir=EAST), dir=EAST)
under.Insert(new/icon(accessory_s, dir=WEST), dir=WEST)
- overlays_standing[TAIL_UNDERLIMBS_LAYER] = image(under, "pixel_x" = body_accessory.pixel_x_offset, "pixel_y" = body_accessory.pixel_y_offset)
+ var/mutable_appearance/underlimbs = mutable_appearance(under, layer = -TAIL_UNDERLIMBS_LAYER)
+ underlimbs.pixel_x = body_accessory.pixel_x_offset
+ underlimbs.pixel_y = body_accessory.pixel_y_offset
+ overlays_standing[TAIL_UNDERLIMBS_LAYER] = underlimbs
// Creates a blank icon, and copies accessory_s' north direction sprite into it
// before passing that to the tail layer that overlays uniforms and such.
var/icon/over = new/icon("icon" = 'icons/mob/body_accessory.dmi', "icon_state" = "accessory_none_s")
over.Insert(new/icon(accessory_s, dir=NORTH), dir=NORTH)
- overlays_standing[TAIL_LAYER] = image(over, "pixel_x" = body_accessory.pixel_x_offset, "pixel_y" = body_accessory.pixel_y_offset)
+ var/mutable_appearance/tail = mutable_appearance(over, layer = -TAIL_LAYER)
+ tail.pixel_x = body_accessory.pixel_x_offset
+ tail.pixel_y = body_accessory.pixel_y_offset
+ overlays_standing[TAIL_LAYER] = tail
else // Otherwise, since the user's tail isn't overlapped by limbs, go ahead and use default icon generation.
- overlays_standing[TAIL_LAYER] = image(accessory_s, "pixel_x" = body_accessory.pixel_x_offset, "pixel_y" = body_accessory.pixel_y_offset)
+ var/mutable_appearance/tail = mutable_appearance(accessory_s, layer = -TAIL_LAYER)
+ tail.pixel_x = body_accessory.pixel_x_offset
+ tail.pixel_y = body_accessory.pixel_y_offset
+ overlays_standing[TAIL_LAYER] = tail
else if(tail && dna.species.bodyflags & HAS_TAIL) //no tailless tajaran
if(!wear_suit || !(wear_suit.flags_inv & HIDETAIL) && !istype(wear_suit, /obj/item/clothing/suit/space))
@@ -1209,25 +1095,24 @@ var/global/list/damage_icon_parts = list()
under.Insert(new/icon(tail_s, dir=EAST), dir=EAST)
under.Insert(new/icon(tail_s, dir=WEST), dir=WEST)
- overlays_standing[TAIL_UNDERLIMBS_LAYER] = image(under)
+ overlays_standing[TAIL_UNDERLIMBS_LAYER] = mutable_appearance(under, layer = -TAIL_UNDERLIMBS_LAYER)
// Creates a blank icon, and copies accessory_s' north direction sprite into it before passing that to the tail layer that overlays uniforms and such.
var/icon/over = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "blank")
over.Insert(new/icon(tail_s, dir=NORTH), dir=NORTH)
- overlays_standing[TAIL_LAYER] = image(over)
+ overlays_standing[TAIL_LAYER] = mutable_appearance(over, layer = -TAIL_LAYER)
else // Otherwise, since the user's tail isn't overlapped by limbs, go ahead and use default icon generation.
- overlays_standing[TAIL_LAYER] = image(tail_s)
-
- if(update_icons)
- update_icons()
-
+ overlays_standing[TAIL_LAYER] = mutable_appearance(tail_s, layer = -TAIL_LAYER)
+ apply_overlay(TAIL_LAYER)
+ apply_overlay(TAIL_UNDERLIMBS_LAYER)
/mob/living/carbon/human/proc/start_tail_wagging(var/update_icons=1)
- overlays_standing[TAIL_UNDERLIMBS_LAYER] = null // SEW direction icons, overlayed by LIMBS_LAYER.
- overlays_standing[TAIL_LAYER] = null /* This will be one of two things:
- If the species' tail is overlapped by limbs, this will be only the N direction icon so tails can still appear on the outside of uniforms and such.
- Otherwise, since the user's tail isn't overlapped by limbs, it will be a full icon with all directions. */
+ remove_overlay(TAIL_UNDERLIMBS_LAYER) // SEW direction icons, overlayed by LIMBS_LAYER.
+ remove_overlay(TAIL_LAYER) /* This will be one of two things:
+ If the species' tail is overlapped by limbs, this will be only the N direction icon so tails
+ can still appear on the outside of uniforms and such.
+ Otherwise, since the user's tail isn't overlapped by limbs, it will be a full icon with all directions. */
var/icon/tail_marking_icon
var/datum/sprite_accessory/body_markings/tail/tail_marking_style
@@ -1252,7 +1137,10 @@ var/global/list/damage_icon_parts = list()
under.Insert(new/icon(accessory_s, dir=EAST), dir=EAST)
under.Insert(new/icon(accessory_s, dir=WEST), dir=WEST)
- overlays_standing[TAIL_UNDERLIMBS_LAYER] = image(under, "pixel_x" = body_accessory.pixel_x_offset, "pixel_y" = body_accessory.pixel_y_offset)
+ var/mutable_appearance/underlimbs = mutable_appearance(under, layer = -TAIL_UNDERLIMBS_LAYER)
+ underlimbs.pixel_x = body_accessory.pixel_x_offset
+ underlimbs.pixel_y = body_accessory.pixel_y_offset
+ overlays_standing[TAIL_UNDERLIMBS_LAYER] = underlimbs
// Creates a blank icon, and copies accessory_s' north direction sprite into it before passing that to the tail layer that overlays uniforms and such.
var/icon/over = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "Vulpkanin_tail_delay")
@@ -1260,9 +1148,15 @@ var/global/list/damage_icon_parts = list()
over = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[dna.species.name]_tail_delay")
over.Insert(new/icon(accessory_s, dir=NORTH), dir=NORTH)
- overlays_standing[TAIL_LAYER] = image(over, "pixel_x" = body_accessory.pixel_x_offset, "pixel_y" = body_accessory.pixel_y_offset)
+ var/mutable_appearance/tail = mutable_appearance(over, layer = -TAIL_LAYER)
+ tail.pixel_x = body_accessory.pixel_x_offset
+ tail.pixel_y = body_accessory.pixel_y_offset
+ overlays_standing[TAIL_LAYER] = tail
else // Otherwise, since the user's tail isn't overlapped by limbs, go ahead and use default icon generation.
- overlays_standing[TAIL_LAYER] = image(accessory_s, "pixel_x" = body_accessory.pixel_x_offset, "pixel_y" = body_accessory.pixel_y_offset)
+ var/mutable_appearance/tail = mutable_appearance(accessory_s, layer = -TAIL_LAYER)
+ tail.pixel_x = body_accessory.pixel_x_offset
+ tail.pixel_y = body_accessory.pixel_y_offset
+ overlays_standing[TAIL_LAYER] = tail
else if(tail && dna.species.bodyflags & HAS_TAIL)
var/icon/tailw_s = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[tail]w_s")
@@ -1277,25 +1171,36 @@ var/global/list/damage_icon_parts = list()
under.Insert(new/icon(tailw_s, dir=EAST), dir=EAST)
under.Insert(new/icon(tailw_s, dir=WEST), dir=WEST)
- overlays_standing[TAIL_UNDERLIMBS_LAYER] = image(under)
+ overlays_standing[TAIL_UNDERLIMBS_LAYER] = mutable_appearance(under, layer = -TAIL_UNDERLIMBS_LAYER)
// Creates a blank icon, and copies accessory_s' north direction sprite into it before passing that to the tail layer that overlays uniforms and such.
var/icon/over = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[dna.species.name]_tail_delay")
over.Insert(new/icon(tailw_s, dir=NORTH), dir=NORTH)
- overlays_standing[TAIL_LAYER] = image(over)
+ overlays_standing[TAIL_LAYER] = mutable_appearance(over, layer = -TAIL_LAYER)
else // Otherwise, since the user's tail isn't overlapped by limbs, go ahead and use default icon generation.
- overlays_standing[TAIL_LAYER] = image(tailw_s)
-
- if(update_icons)
- update_icons()
+ overlays_standing[TAIL_LAYER] = mutable_appearance(tailw_s, layer = -TAIL_LAYER)
+ apply_overlay(TAIL_LAYER)
+ apply_overlay(TAIL_UNDERLIMBS_LAYER)
/mob/living/carbon/human/proc/stop_tail_wagging(var/update_icons=1)
- overlays_standing[TAIL_UNDERLIMBS_LAYER] = null
- overlays_standing[TAIL_LAYER] = null
-
+ remove_overlay(TAIL_UNDERLIMBS_LAYER)
+ remove_overlay(TAIL_LAYER)
update_tail_layer(update_icons) //just trigger a full update for normal stationary sprites
+/mob/living/carbon/human/proc/update_int_organs()
+ remove_overlay(INTORGAN_LAYER)
+
+ var/list/standing = list()
+ for(var/organ in internal_organs)
+ var/obj/item/organ/internal/I = organ
+ var/render = I.render()
+ if(render)
+ standing += render
+
+ overlays_standing[INTORGAN_LAYER] = standing
+ apply_overlay(INTORGAN_LAYER)
+
/mob/living/carbon/human/handle_transform_change()
..()
update_tail_layer()
@@ -1304,8 +1209,9 @@ var/global/list/damage_icon_parts = list()
// Suit needs an identically named sprite in icons/mob/collar.dmi
// For suits with species_fit and sprite_sheets, an identically named sprite needs to exist in a file like this icons/mob/species/[species_name_here]/collar.dmi.
/mob/living/carbon/human/proc/update_collar(var/update_icons=1)
+ remove_overlay(COLLAR_LAYER)
var/icon/C = new('icons/mob/collar.dmi')
- var/image/standing = null
+ var/mutable_appearance/standing = null
if(wear_suit)
if(wear_suit.icon_override)
@@ -1314,28 +1220,39 @@ var/global/list/damage_icon_parts = list()
if(fexists(icon_path)) //Just ensuring the nonexistance of a file with the above path won't cause a runtime.
var/icon/icon_file = new(icon_path)
if(wear_suit.icon_state in icon_file.IconStates())
- standing = image("icon" = icon_file, "icon_state" = "[wear_suit.icon_state]")
+ standing = mutable_appearance(icon_file, "[wear_suit.icon_state]", layer = -COLLAR_LAYER)
else if(wear_suit.sprite_sheets && wear_suit.sprite_sheets[dna.species.name])
var/icon_path = "[wear_suit.sprite_sheets[dna.species.name]]"
icon_path = "[copytext(icon_path, 1, findtext(icon_path, "/suit.dmi"))]/collar.dmi" //If this file doesn't exist, the end result is that COLLAR_LAYER will be unchanged (empty).
if(fexists(icon_path)) //Just ensuring the nonexistance of a file with the above path won't cause a runtime.
var/icon/icon_file = new(icon_path)
if(wear_suit.icon_state in icon_file.IconStates())
- standing = image("icon" = icon_file, "icon_state" = "[wear_suit.icon_state]")
+ standing = mutable_appearance(icon_file, "[wear_suit.icon_state]", layer = -COLLAR_LAYER)
else
if(wear_suit.icon_state in C.IconStates())
- standing = image("icon" = C, "icon_state" = "[wear_suit.icon_state]")
+ standing = mutable_appearance(C, "[wear_suit.icon_state]", layer = -COLLAR_LAYER)
- overlays_standing[COLLAR_LAYER] = standing
-
- if(update_icons) update_icons()
+ overlays_standing[COLLAR_LAYER] = standing
+ apply_overlay(COLLAR_LAYER)
/mob/living/carbon/human/proc/update_misc_effects()
- misc_effect_overlays.Cut()
+ remove_overlay(MISC_LAYER)
//Begin appending miscellaneous effects.
if(eyes_shine())
- misc_effect_overlays += get_eye_shine() //Image layer is specified in get_eye_shine() proc as LIGHTING_LAYER + 1.
+ overlays_standing[MISC_LAYER] = get_eye_shine() //Image layer is specified in get_eye_shine() proc as LIGHTING_LAYER + 1.
+
+ apply_overlay(MISC_LAYER)
+
+/mob/living/carbon/human/admin_Freeze(client/admin, skip_overlays = TRUE)
+ . = ..()
+ overlays_standing[FROZEN_LAYER] = mutable_appearance(frozen, layer = -FROZEN_LAYER)
+ apply_overlay(FROZEN_LAYER)
+
+/mob/living/carbon/human/admin_unFreeze(client/admin, skip_overlays = TRUE)
+ . = ..()
+ remove_overlay(FROZEN_LAYER)
+
/mob/living/carbon/human/proc/force_update_limbs()
for(var/obj/item/organ/external/O in bodyparts)
@@ -1350,3 +1267,40 @@ var/global/list/damage_icon_parts = list()
continue
out += overlays_standing[i]
return out
+
+/mob/living/carbon/human/proc/generate_icon_render_key()
+ var/husk = (HUSK in mutations)
+ var/fat = (FAT in mutations)
+ var/hulk = (HULK in mutations)
+ var/skeleton = (SKELETON in mutations)
+
+ . = ""
+
+ var/obj/item/organ/internal/eyes/eyes = get_int_organ(/obj/item/organ/internal/eyes)
+ if(eyes)
+ . += "[eyes.eye_colour]"
+ else
+ . += "#000000"
+
+ for(var/organ_tag in dna.species.has_limbs)
+ var/obj/item/organ/external/part = bodyparts_by_name[organ_tag]
+ if(isnull(part))
+ . += "0"
+ else if(part.is_robotic())
+ . += "2[part.model ? "-[part.model]" : ""]"
+ else if(part.status & ORGAN_DEAD)
+ . += "3"
+ else
+ . += "1"
+
+ if(part)
+ var/datum/species/S = GLOB.all_species[part.dna.species.name]
+ . += "[S.race_key]"
+ . += "[part.dna.GetUIState(DNA_UI_GENDER)]"
+ . += "[part.dna.GetUIValue(DNA_UI_SKIN_TONE)]"
+ if(part.s_col)
+ . += "[part.s_col]"
+ if(part.s_tone)
+ . += "[part.s_tone]"
+
+ . = "[.][!!husk][!!fat][!!hulk][!!skeleton]"
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/slime/life.dm b/code/modules/mob/living/carbon/slime/life.dm
index 2f2c05c9452..649ec7b3f00 100644
--- a/code/modules/mob/living/carbon/slime/life.dm
+++ b/code/modules/mob/living/carbon/slime/life.dm
@@ -218,15 +218,8 @@
if(src.eye_blind)
src.SetEyeBlind(0)
- if(src.ear_deaf > 0) SetEarDeaf(0)
- if(src.ear_damage < 25)
- SetEarDamage(0)
-
src.density = !( src.lying )
- if(src.disabilities & DEAF)
- EarDeaf(1)
-
if(src.eye_blurry > 0)
SetEyeBlurry(0)
diff --git a/code/modules/mob/living/carbon/slime/slime.dm b/code/modules/mob/living/carbon/slime/slime.dm
index be25de1ac14..914c810da27 100644
--- a/code/modules/mob/living/carbon/slime/slime.dm
+++ b/code/modules/mob/living/carbon/slime/slime.dm
@@ -489,4 +489,7 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75
if(istype(toEat, /obj/item/reagent_containers/food/drinks))
return 1
to_chat(user, "This creature does not seem to have a mouth!")
- return 0
\ No newline at end of file
+ return 0
+
+/mob/living/carbon/slime/can_hear()
+ . = TRUE //honestly fuck slimes and organ bullshit
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/update_status.dm b/code/modules/mob/living/carbon/update_status.dm
index 63d34788a98..22030c78f4b 100644
--- a/code/modules/mob/living/carbon/update_status.dm
+++ b/code/modules/mob/living/carbon/update_status.dm
@@ -27,3 +27,9 @@
setStaminaLoss(health - 2)
handle_hud_icons_health()
return
+
+/mob/living/carbon/can_hear()
+ . = FALSE
+ var/obj/item/organ/internal/ears/ears = get_int_organ(/obj/item/organ/internal/ears)
+ if(istype(ears) && !ears.deaf)
+ . = TRUE
\ No newline at end of file
diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm
index 032f46d42dd..d365f30d7d0 100644
--- a/code/modules/mob/living/life.dm
+++ b/code/modules/mob/living/life.dm
@@ -170,15 +170,6 @@
else if(eye_blurry) //blurry eyes heal slowly
AdjustEyeBlurry(-1)
- //Ears
- if(disabilities & DEAF) //disabled-deaf, doesn't get better on its own
- EarDeaf(1)
- else
- // deafness heals slowly over time, unless ear_damage is over 100
- if(ear_damage < 100)
- AdjustEarDamage(-0.05)
- AdjustEarDeaf(-1)
-
//this handles hud updates. Calls update_vision() and handle_hud_icons()
/mob/living/proc/handle_regular_hud_updates()
if(!client) return 0
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 2a384dec214..bf49d5b2598 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -404,8 +404,7 @@
CureNervous()
SetEyeBlind(0)
SetEyeBlurry(0)
- SetEarDamage(0)
- SetEarDeaf(0)
+ RestoreEars()
heal_overall_damage(1000, 1000)
ExtinguishMob()
fire_stacks = 0
diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm
index b667dbd15bd..e5bc8582de8 100644
--- a/code/modules/mob/living/silicon/silicon.dm
+++ b/code/modules/mob/living/silicon/silicon.dm
@@ -330,9 +330,5 @@
return 1
/////////////////////////////////// EAR DAMAGE ////////////////////////////////////
-
-/mob/living/silicon/SetEarDamage()
- return
-
-/mob/living/silicon/SetEarDeaf()
- return
+/mob/living/silicon/can_hear()
+ . = TRUE
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index 046d55c4566..df3f185dad4 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -578,9 +578,5 @@
if(A.update_remote_sight(src)) //returns 1 if we override all other sight updates.
return
-/mob/living/simple_animal/SetEarDamage()
- return
-
-/mob/living/simple_animal/SetEarDeaf()
- return
-
+/mob/living/simple_animal/can_hear()
+ . = TRUE
\ No newline at end of file
diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm
index e9253f78d59..4e5c778b7fb 100644
--- a/code/modules/mob/living/status_procs.dm
+++ b/code/modules/mob/living/status_procs.dm
@@ -43,10 +43,6 @@
A trippy overlay appears.
* Drunk *
Essentially what your "BAC" is - the higher it is, the more alcohol you have in you
- * EarDamage *
- Doesn't do much, but if it's 25+, you go deaf. Heals much slower than other statuses - 0.05 normally
- * EarDeaf *
- You cannot hear. Prevents EarDamage from healing naturally.
* EyeBlind *
You cannot see. Prevents EyeBlurry from healing naturally.
* EyeBlurry *
@@ -115,8 +111,6 @@
var/drowsyness = 0
var/druggy = 0
var/drunk = 0
- var/ear_damage = 0
- var/ear_deaf = 0
var/eye_blind = 0
var/eye_blurry = 0
var/hallucination = 0
@@ -233,30 +227,6 @@
var/new_value = directional_bounded_sum(druggy, amount, bound_lower, bound_upper)
return SetDruggy(new_value, updating)
-// EAR_DAMAGE
-
-/mob/living/EarDamage(amount)
- SetEarDamage(max(ear_damage, amount))
-
-/mob/living/SetEarDamage(amount)
- ear_damage = max(amount, 0)
-
-/mob/living/AdjustEarDamage(amount, bound_lower = 0, bound_upper = INFINITY)
- var/new_value = directional_bounded_sum(ear_damage, amount, bound_lower, bound_upper)
- SetEarDamage(new_value)
-
-// EAR_DEAF
-
-/mob/living/EarDeaf(amount)
- SetEarDeaf(max(ear_deaf, amount))
-
-/mob/living/SetEarDeaf(amount)
- ear_deaf = max(amount, 0)
-
-/mob/living/AdjustEarDeaf(amount, bound_lower = 0, bound_upper = INFINITY)
- var/new_value = directional_bounded_sum(ear_deaf, amount, bound_lower, bound_upper)
- SetEarDeaf(new_value)
-
// EYE_BLIND
/mob/living/EyeBlind(amount, updating = TRUE)
diff --git a/code/modules/mob/living/update_status.dm b/code/modules/mob/living/update_status.dm
index 40d4cdc9cb2..94769baf94b 100644
--- a/code/modules/mob/living/update_status.dm
+++ b/code/modules/mob/living/update_status.dm
@@ -41,7 +41,7 @@
// Whether the mob can hear things
/mob/living/can_hear()
- return !(ear_deaf || (disabilities & DEAF))
+ . = !(disabilities & DEAF)
// Whether the mob is able to see
// `information_only` is for stuff that's purely informational - like understanding nonverbal languages, or blindness overlays
@@ -137,10 +137,6 @@
SetEyeBlind(eye_blind)
if("eye_blurry")
SetEyeBlurry(eye_blurry)
- if("ear_deaf")
- SetEarDeaf(ear_deaf)
- if("ear_damage")
- SetEarDamage(ear_damage)
if("druggy")
SetDruggy(druggy)
if("maxHealth")
diff --git a/code/modules/mob/new_player/sprite_accessories.dm b/code/modules/mob/new_player/sprite_accessories.dm
index bdf93fbd4eb..8beb5352b6a 100644
--- a/code/modules/mob/new_player/sprite_accessories.dm
+++ b/code/modules/mob/new_player/sprite_accessories.dm
@@ -48,7 +48,7 @@
var/gender = NEUTER //Determines if the accessory will be skipped or included in random hair generations
// Restrict some styles to specific species
- var/list/species_allowed = list("Human", "Slime People")
+ var/list/species_allowed = list("Human", "Felinid", "Slime People")
var/list/models_allowed = list() //Specifies which, if any, hairstyles or markings can be accessed by which prosthetics. Should equal the manufacturing company name in robolimbs.dm.
var/list/heads_allowed = null //Specifies which, if any, alt heads a head marking, hairstyle or facial hair style is compatible with.
var/list/tails_allowed = null //Specifies which, if any, tails a tail marking is compatible with.
@@ -75,7 +75,7 @@
/datum/sprite_accessory/hair/bald
name = "Bald"
icon_state = "bald"
- species_allowed = list("Human", "Unathi", "Vox", "Diona", "Kidan", "Grey", "Plasmaman", "Skeleton", "Vulpkanin", "Tajaran")
+ species_allowed = list("Human", "Felinid", "Unathi", "Vox", "Diona", "Kidan", "Grey", "Plasmaman", "Skeleton", "Vulpkanin", "Tajaran")
glasses_over = 1
/datum/sprite_accessory/hair/short
@@ -169,7 +169,7 @@
name = "Pompadour"
icon_state = "hair_pompadour"
gender = MALE
- species_allowed = list("Human", "Slime People", "Unathi")
+ species_allowed = list("Human", "Felinid", "Slime People", "Unathi")
glasses_over = 1
/datum/sprite_accessory/hair/quiff
@@ -194,19 +194,19 @@
name = "Beehive"
icon_state = "hair_beehive"
gender = FEMALE
- species_allowed = list("Human", "Slime People", "Unathi")
+ species_allowed = list("Human", "Felinid", "Slime People", "Unathi")
/datum/sprite_accessory/hair/bobcurl
name = "Bobcurl"
icon_state = "hair_bobcurl"
gender = FEMALE
- species_allowed = list("Human", "Slime People", "Unathi")
+ species_allowed = list("Human", "Felinid", "Slime People", "Unathi")
/datum/sprite_accessory/hair/bob
name = "Bob"
icon_state = "hair_bobcut"
gender = FEMALE
- species_allowed = list("Human", "Slime People", "Unathi")
+ species_allowed = list("Human", "Felinid", "Slime People", "Unathi")
/datum/sprite_accessory/hair/bowl
name = "Bowl"
@@ -234,7 +234,7 @@
name = "Buzzcut"
icon_state = "hair_buzzcut"
gender = MALE
- species_allowed = list("Human", "Slime People", "Unathi")
+ species_allowed = list("Human", "Felinid", "Slime People", "Unathi")
glasses_over = 1
/datum/sprite_accessory/hair/crew
@@ -303,7 +303,7 @@
/datum/sprite_accessory/hair/mohawk
name = "Mohawk"
icon_state = "hair_d"
- species_allowed = list("Human", "Slime People", "Unathi")
+ species_allowed = list("Human", "Felinid", "Slime People", "Unathi")
glasses_over = 1
/datum/sprite_accessory/hair/jensen
@@ -338,7 +338,7 @@
/datum/sprite_accessory/hair/spiky
name = "Spiky"
icon_state = "hair_spikey"
- species_allowed = list("Human", "Slime People", "Unathi")
+ species_allowed = list("Human", "Felinid", "Slime People", "Unathi")
glasses_over = 1
/datum/sprite_accessory/hair/kusanagi
@@ -1535,7 +1535,7 @@
name = "Shaved"
icon_state = "bald"
gender = NEUTER
- species_allowed = list("Human", "Unathi", "Tajaran", "Skrell", "Vox", "Diona", "Kidan", "Greys", "Vulpkanin", "Slime People")
+ species_allowed = list("Human", "Felinid", "Unathi", "Tajaran", "Skrell", "Vox", "Diona", "Kidan", "Greys", "Vulpkanin", "Slime People")
/datum/sprite_accessory/facial_hair/watson
name = "Watson Mustache"
@@ -1576,7 +1576,7 @@
/datum/sprite_accessory/facial_hair/elvis
name = "Elvis Sideburns"
icon_state = "facial_elvis"
- species_allowed = list("Human", "Slime People", "Unathi")
+ species_allowed = list("Human", "Felinid", "Slime People", "Unathi")
/datum/sprite_accessory/facial_hair/abe
name = "Abraham Lincoln Beard"
@@ -1813,7 +1813,7 @@
/datum/sprite_accessory/skin/human
name = "Default human skin"
icon_state = "default"
- species_allowed = list("Human")
+ species_allowed = list("Human", "Felinid")
/datum/sprite_accessory/skin/human/human_tatt01
name = "Tatt01 human skin"
@@ -1848,13 +1848,13 @@
///////////////////////////
/datum/sprite_accessory/underwear
icon = 'icons/mob/underwear.dmi'
- species_allowed = list("Human", "Unathi", "Diona", "Vulpkanin", "Tajaran", "Kidan", "Grey", "Plasmaman", "Machine", "Skrell", "Slime People", "Skeleton", "Drask")
+ species_allowed = list("Human", "Felinid", "Unathi", "Diona", "Vulpkanin", "Tajaran", "Kidan", "Grey", "Plasmaman", "Machine", "Skrell", "Slime People", "Skeleton", "Drask")
gender = NEUTER
/datum/sprite_accessory/underwear/nude
name = "Nude"
icon_state = null
- species_allowed = list("Human", "Unathi", "Diona", "Vulpkanin", "Tajaran", "Kidan", "Grey", "Plasmaman", "Machine", "Skrell", "Slime People", "Skeleton", "Drask", "Vox")
+ species_allowed = list("Human", "Felinid", "Unathi", "Diona", "Vulpkanin", "Tajaran", "Kidan", "Grey", "Plasmaman", "Machine", "Skrell", "Slime People", "Skeleton", "Drask", "Vox")
/datum/sprite_accessory/underwear/male
gender = MALE
@@ -1974,13 +1974,13 @@
////////////////////////////
/datum/sprite_accessory/undershirt
icon = 'icons/mob/underwear.dmi'
- species_allowed = list("Human", "Unathi", "Diona", "Vulpkanin", "Tajaran", "Kidan", "Grey", "Plasmaman", "Machine", "Skrell", "Slime People", "Skeleton", "Drask")
+ species_allowed = list("Human", "Felinid", "Unathi", "Diona", "Vulpkanin", "Tajaran", "Kidan", "Grey", "Plasmaman", "Machine", "Skrell", "Slime People", "Skeleton", "Drask")
gender = NEUTER
/datum/sprite_accessory/undershirt/nude
name = "Nude"
icon_state = null
- species_allowed = list("Human", "Unathi", "Diona", "Vulpkanin", "Tajaran", "Kidan", "Grey", "Plasmaman", "Machine", "Skrell", "Slime People", "Skeleton", "Drask", "Vox")
+ species_allowed = list("Human", "Felinid", "Unathi", "Diona", "Vulpkanin", "Tajaran", "Kidan", "Grey", "Plasmaman", "Machine", "Skrell", "Slime People", "Skeleton", "Drask", "Vox")
//plain color shirts
/datum/sprite_accessory/undershirt/shirt_white
@@ -2210,13 +2210,13 @@
///////////////////////
/datum/sprite_accessory/socks
icon = 'icons/mob/underwear.dmi'
- species_allowed = list("Human", "Unathi", "Diona", "Vulpkanin", "Tajaran", "Kidan", "Grey", "Plasmaman", "Machine", "Skrell", "Slime People", "Skeleton", "Drask")
+ species_allowed = list("Human", "Felinid", "Unathi", "Diona", "Vulpkanin", "Tajaran", "Kidan", "Grey", "Plasmaman", "Machine", "Skrell", "Slime People", "Skeleton", "Drask")
gender = NEUTER
/datum/sprite_accessory/socks/nude
name = "Nude"
icon_state = null
- species_allowed = list("Human", "Unathi", "Diona", "Vulpkanin", "Tajaran", "Kidan", "Grey", "Plasmaman", "Machine", "Skrell", "Slime People", "Skeleton", "Drask", "Vox")
+ species_allowed = list("Human", "Felinid", "Unathi", "Diona", "Vulpkanin", "Tajaran", "Kidan", "Grey", "Plasmaman", "Machine", "Skrell", "Slime People", "Skeleton", "Drask", "Vox")
/datum/sprite_accessory/socks/white_norm
name = "Normal White"
@@ -2342,7 +2342,7 @@
/datum/sprite_accessory/head_accessory/none
name = "None"
- species_allowed = list("Human", "Unathi", "Diona", "Grey", "Kidan", "Machine", "Tajaran", "Vulpkanin", "Skrell", "Slime People", "Skeleton", "Vox")
+ species_allowed = list("Human", "Felinid", "Unathi", "Diona", "Grey", "Kidan", "Machine", "Tajaran", "Vulpkanin", "Skrell", "Slime People", "Skeleton", "Vox")
icon_state = "accessory_none"
/datum/sprite_accessory/head_accessory/unathi
@@ -2595,7 +2595,7 @@
/datum/sprite_accessory/body_markings/none
name = "None"
- species_allowed = list("Human", "Unathi", "Diona", "Grey", "Machine", "Tajaran", "Vulpkanin", "Skrell", "Slime People", "Skeleton", "Vox", "Kidan")
+ species_allowed = list("Human", "Felinid", "Unathi", "Diona", "Grey", "Machine", "Tajaran", "Vulpkanin", "Skrell", "Slime People", "Skeleton", "Vox", "Kidan")
icon_state = "accessory_none"
/datum/sprite_accessory/body_markings/tiger
@@ -2863,7 +2863,7 @@
models_allowed = list("Xion Manufacturing Group alt.")
/datum/sprite_accessory/body_markings/tattoo // Tattoos applied post-round startup with tattoo guns in item_defines.dm
- species_allowed = list("Human", "Unathi", "Vulpkanin", "Tajaran", "Skrell")
+ species_allowed = list("Human", "Felinid", "Unathi", "Vulpkanin", "Tajaran", "Skrell")
icon_state = "accessory_none"
/datum/sprite_accessory/body_markings/tattoo/elliot
@@ -2873,7 +2873,7 @@
/datum/sprite_accessory/body_markings/tattoo/tiger_body
name = "Tiger-stripe Tattoo"
- species_allowed = list("Human", "Unathi", "Vulpkanin", "Tajaran", "Skrell")
+ species_allowed = list("Human", "Felinid", "Unathi", "Vulpkanin", "Tajaran", "Skrell")
icon_state = "markings_tiger"
/datum/sprite_accessory/body_markings/tattoo/heart
diff --git a/code/modules/mob/status_procs.dm b/code/modules/mob/status_procs.dm
index 4cbbe9c51c9..f6e6e07673f 100644
--- a/code/modules/mob/status_procs.dm
+++ b/code/modules/mob/status_procs.dm
@@ -52,23 +52,13 @@
return
-/mob/proc/EarDamage()
- return
-
-/mob/proc/SetEarDamage()
+/mob/proc/RestoreEars()
return
/mob/proc/AdjustEarDamage()
return
-
-/mob/proc/EarDeaf()
- return
-
-/mob/proc/SetEarDeaf()
- return
-
-/mob/proc/AdjustEarDeaf()
+/mob/proc/MinimumDeafTicks()
return
diff --git a/code/modules/mob/update_status.dm b/code/modules/mob/update_status.dm
index 52a6fb7769d..446c2aaed8f 100644
--- a/code/modules/mob/update_status.dm
+++ b/code/modules/mob/update_status.dm
@@ -35,7 +35,7 @@
// Procs that give information about the status of the mob
/mob/proc/can_hear()
- return 1
+ . = 1
/mob/proc/has_vision(information_only = FALSE)
return 1
diff --git a/code/modules/reagents/chemistry/reagents/medicine.dm b/code/modules/reagents/chemistry/reagents/medicine.dm
index 7007643e652..7a211780446 100644
--- a/code/modules/reagents/chemistry/reagents/medicine.dm
+++ b/code/modules/reagents/chemistry/reagents/medicine.dm
@@ -543,21 +543,23 @@
/datum/reagent/medicine/oculine/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
if(prob(80))
- if(ishuman(M))
- var/mob/living/carbon/human/H = M
- var/obj/item/organ/internal/eyes/E = H.get_int_organ(/obj/item/organ/internal/eyes)
+ if(iscarbon(M))
+ var/mob/living/carbon/C = M
+ var/obj/item/organ/internal/eyes/E = C.get_int_organ(/obj/item/organ/internal/eyes)
if(istype(E))
E.heal_internal_damage(1)
+ var/obj/item/organ/internal/ears/ears = C.get_int_organ(/obj/item/organ/internal/ears)
+ if(istype(ears))
+ ears.AdjustEarDamage(-1)
+ if(ears.ear_damage < 25 && prob(30))
+ ears.deaf = 0
update_flags |= M.AdjustEyeBlurry(-1, FALSE)
- update_flags |= M.AdjustEarDamage(-1, FALSE)
+ update_flags |= M.AdjustEarDamage(-1)
if(prob(50))
update_flags |= M.CureNearsighted(FALSE)
if(prob(30))
update_flags |= M.CureBlind(FALSE)
update_flags |= M.SetEyeBlind(0, FALSE)
- if(M.ear_damage <= 25)
- if(prob(30))
- M.SetEarDeaf(0)
return ..() | update_flags
/datum/reagent/medicine/atropine
diff --git a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm
index 7dcdd1e81b6..8739acc9664 100644
--- a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm
+++ b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm
@@ -283,16 +283,19 @@ datum/chemical_reaction/flash_powder
if(!ear_safety)
M.Stun(max(10/distance, 3))
M.Weaken(max(10/distance, 3))
- M.AdjustEarDamage(rand(0, 5))
- M.EarDeaf(15)
- if(M.ear_damage >= 15)
- to_chat(M, "Your ears start to ring badly!")
- if(prob(M.ear_damage - 5))
- to_chat(M, "You can't hear anything!")
- M.disabilities |= DEAF
- else
- if(M.ear_damage >= 5)
- to_chat(M, "Your ears start to ring!")
+ M.AdjustEarDamage(rand(0, 5), 15)
+ if(iscarbon(M))
+ var/mob/living/carbon/C = M
+ var/obj/item/organ/internal/ears/ears = C.get_int_organ(/obj/item/organ/internal/ears)
+ if(istype(ears))
+ if(ears.ear_damage >= 15)
+ to_chat(M, "Your ears start to ring badly!")
+ if(prob(ears.ear_damage - 5))
+ to_chat(M, "You can't hear anything!")
+ M.BecomeDeaf()
+ else
+ if(ears.ear_damage >= 5)
+ to_chat(M, "Your ears start to ring!")
holder.remove_reagent("sonic_powder", created_volume)
/datum/chemical_reaction/sonic_powder_deafen
@@ -318,16 +321,20 @@ datum/chemical_reaction/flash_powder
if(!ear_safety)
M.Stun(max(10/distance, 3))
M.Weaken(max(10/distance, 3))
- M.AdjustEarDamage(rand(0, 5))
- M.EarDeaf(15)
- if(M.ear_damage >= 15)
- to_chat(M, "Your ears start to ring badly!")
- if(prob(M.ear_damage - 5))
- to_chat(M, "You can't hear anything!")
- M.BecomeDeaf()
- else
- if(M.ear_damage >= 5)
- to_chat(M, "Your ears start to ring!")
+ M.AdjustEarDamage(rand(0, 5), 15)
+ if(iscarbon(M))
+ var/mob/living/carbon/C = M
+ var/obj/item/organ/internal/ears/ears = C.get_int_organ(/obj/item/organ/internal/ears)
+ if(istype(ears))
+ if(ears.ear_damage >= 15)
+ to_chat(M, "Your ears start to ring badly!")
+ if(prob(ears.ear_damage - 5))
+ to_chat(M, "You can't hear anything!")
+ M.BecomeDeaf()
+ else
+ if(ears.ear_damage >= 5)
+ to_chat(M, "Your ears start to ring!")
+
/datum/chemical_reaction/phlogiston
name = "phlogiston"
diff --git a/code/modules/surgery/organs/ears.dm b/code/modules/surgery/organs/ears.dm
new file mode 100644
index 00000000000..20179905f23
--- /dev/null
+++ b/code/modules/surgery/organs/ears.dm
@@ -0,0 +1,76 @@
+/obj/item/organ/internal/ears
+ name = "ears"
+ icon_state = "ears"
+ gender = PLURAL
+ organ_tag = "ears"
+ parent_organ = "head"
+ slot = "ears"
+
+ // `deaf` measures "ticks" of deafness. While > 0, the person is deaf.
+ var/deaf = 0
+
+ // `ear_damage` measures long term damage to the ears, if too high,
+ // the person will not have either `deaf` or `ear_damage` decrease
+ // without external aid (earmuffs, drugs)
+ var/ear_damage = 0
+
+/obj/item/organ/internal/ears/on_life()
+ if(!iscarbon(owner))
+ return
+ var/mob/living/carbon/C = owner
+ // genetic deafness prevents the body from using the ears, even if healthy
+ if(C.disabilities & DEAF)
+ deaf = max(deaf, 1)
+ else
+ if(ishuman(C))
+ var/mob/living/carbon/human/H = C
+ if((H.l_ear && H.l_ear.flags_2 & HEALS_EARS_2) || (H.r_ear && H.r_ear.flags_2 & HEALS_EARS_2))
+ deaf = max(deaf - 1, 1)
+ ear_damage = max(ear_damage - 0.10, 0)
+ // if higher than UNHEALING_EAR_DAMAGE, no natural healing occurs.
+ if(ear_damage < UNHEALING_EAR_DAMAGE)
+ ear_damage = max(ear_damage - 0.05, 0)
+ deaf = max(deaf - 1, 0)
+
+/obj/item/organ/internal/ears/proc/RestoreEars()
+ deaf = 0
+ ear_damage = 0
+
+ var/mob/living/carbon/C = owner
+ if(istype(C) && C.disabilities & DEAF)
+ deaf = 1
+
+/obj/item/organ/internal/ears/proc/AdjustEarDamage(ddmg, ddeaf)
+ ear_damage = max(ear_damage + ddmg, 0)
+ deaf = max(deaf + ddeaf, 0)
+
+/obj/item/organ/internal/ears/proc/MinimumDeafTicks(value)
+ deaf = max(deaf, value)
+
+// Mob procs
+/mob/living/carbon/RestoreEars()
+ var/obj/item/organ/internal/ears/ears = get_int_organ(/obj/item/organ/internal/ears)
+ if(ears)
+ ears.RestoreEars()
+
+/mob/living/carbon/AdjustEarDamage(ddmg, ddeaf)
+ var/obj/item/organ/internal/ears/ears = get_int_organ(/obj/item/organ/internal/ears)
+ if(ears)
+ ears.AdjustEarDamage(ddmg, ddeaf)
+
+/mob/living/carbon/MinimumDeafTicks(value)
+ var/obj/item/organ/internal/ears/ears = get_int_organ(/obj/item/organ/internal/ears)
+ if(ears)
+ ears.MinimumDeafTicks(value)
+
+
+// Kitty ears!!
+/obj/item/organ/internal/ears/cat
+ name = "cat ears"
+ icon = 'icons/obj/clothing/hats.dmi'
+ icon_state = "kitty"
+ color = "#aa4444"
+ transform = matrix(0.7, 0, 0, 0, 0.7, 0)
+
+/obj/item/organ/internal/ears/cat/render()
+ . = mutable_appearance('icons/mob/head.dmi', "kitty", layer = -HEAD_ACC_OVER_LAYER)
\ No newline at end of file
diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm
index 4858435cc5f..2dbf85a3b45 100644
--- a/code/modules/surgery/organs/organ_internal.dm
+++ b/code/modules/surgery/organs/organ_internal.dm
@@ -64,6 +64,7 @@
log_runtime(EXCEPTION("[src] attempted to remove from a [parent_organ], but [parent_organ] didn't exist! [atom_loc_line(M)]"), src)
else
parent.internal_organs -= src
+ H.update_int_organs()
for(var/X in actions)
var/datum/action/A = X
@@ -105,6 +106,10 @@
insert(H)
return 1
+// Rendering!
+/obj/item/organ/internal/proc/render()
+ return
+
/obj/item/reagent_containers/food/snacks/organ
name = "appendix"
icon_state = "appendix"
@@ -247,7 +252,7 @@
to_chat(owner, "HONK")
owner.SetSleeping(0)
owner.Stuttering(20)
- owner.AdjustEarDeaf(30)
+ owner.MinimumDeafTicks(30)
owner.Weaken(3)
owner << 'sound/items/AirHorn.ogg'
if(prob(30))
diff --git a/code/modules/surgery/organs/vocal_cords.dm b/code/modules/surgery/organs/vocal_cords.dm
index c13c4da83f6..eedcb52be00 100644
--- a/code/modules/surgery/organs/vocal_cords.dm
+++ b/code/modules/surgery/organs/vocal_cords.dm
@@ -122,7 +122,7 @@ var/static/regex/multispin_words = regex("like a record baby")
var/mob/living/list/listeners = list()
for(var/mob/living/L in get_mobs_in_view(8, owner, TRUE))
- if(!L.ear_deaf && !L.null_rod_check() && L != owner && L.stat != DEAD)
+ if(L.can_hear() && !L.null_rod_check() && L != owner && L.stat != DEAD)
if(ishuman(L))
var/mob/living/carbon/human/H = L
if(istype(H.l_ear, /obj/item/clothing/ears/earmuffs) || istype(H.r_ear, /obj/item/clothing/ears/earmuffs))
diff --git a/icons/obj/surgery.dmi b/icons/obj/surgery.dmi
index 6a211451466..4ff367c4cc3 100644
Binary files a/icons/obj/surgery.dmi and b/icons/obj/surgery.dmi differ
diff --git a/paradise.dme b/paradise.dme
index dfe436fd566..f49173cf856 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -2244,6 +2244,7 @@
#include "code\modules\surgery\organs\autoimplanter.dm"
#include "code\modules\surgery\organs\blood.dm"
#include "code\modules\surgery\organs\body_egg.dm"
+#include "code\modules\surgery\organs\ears.dm"
#include "code\modules\surgery\organs\eyes.dm"
#include "code\modules\surgery\organs\heart.dm"
#include "code\modules\surgery\organs\helpers.dm"