Adds bodypart visuals for different implants, improves eye color/blinking handling (#90010)

## About The Pull Request

Added visual overlays for all arm implants, HUD implants (not the
headrev one), internal thrusters, breathing tube, nutriment pumps and
reviver implant.


![dreamseeker_wd79oYLszL](https://github.com/user-attachments/assets/76582c23-8639-4261-8414-622a0419dc5b)

![dreamseeker_MnlpCHD0nQ](https://github.com/user-attachments/assets/c4692105-0435-401b-aa30-66a33a813fc4)

![dreamseeker_nLJrSPGC63](https://github.com/user-attachments/assets/5b43a1a6-45d6-454e-9348-c119db3cfb43)

Additionally, added a wrapper for eye color setting which solves the
issue where non-pref sourced eyecolors got reset after changing them,
and changed how blinking works so now update_body calls don't force you
to blink.

## Why It's Good For The Game

Gives you incredible drip (which makes augments feel more impactful) and
allows others to see if you have certain important augments (reviver)
that could matter.
As for technical changes, both were required for this to HUDs to work
nicely and fix some bugs as a side effect.

## Changelog
🆑
add: Certain implants now have visuals when implanted
fix: You no longer blink when you adjust your clothing
fix: Fixed an issue where some NPC/midround humans would not get their
eye color set correctly
/🆑
This commit is contained in:
SmArtKar
2025-03-17 19:09:55 +01:00
committed by GitHub
parent 520fcaa953
commit 64cf28cc4f
18 changed files with 242 additions and 63 deletions
+3 -2
View File
@@ -486,8 +486,9 @@ GLOBAL_LIST_INIT(heretic_path_to_color, list(
#define EYE_COLOR_ATOM_COLOR_PRIORITY 2
#define EYE_COLOR_SPECIES_PRIORITY 10
#define EYE_COLOR_WEED_PRIORITY 20
#define EYE_COLOR_LUMINESCENT_PRIORITY 30
#define EYE_COLOR_CULT_PRIORITY 40
#define EYE_COLOR_HUD_PRIORITY 30
#define EYE_COLOR_LUMINESCENT_PRIORITY 40
#define EYE_COLOR_CULT_PRIORITY 50
// Client color priorities
+1 -2
View File
@@ -640,8 +640,7 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block())
..()
var/structure = dna.unique_identity
skin_tone = GLOB.skin_tones[deconstruct_block(get_uni_identity_block(structure, DNA_SKIN_TONE_BLOCK), GLOB.skin_tones.len)]
eye_color_left = sanitize_hexcolor(get_uni_identity_block(structure, DNA_EYE_COLOR_LEFT_BLOCK))
eye_color_right = sanitize_hexcolor(get_uni_identity_block(structure, DNA_EYE_COLOR_RIGHT_BLOCK))
set_eye_color(sanitize_hexcolor(get_uni_identity_block(structure, DNA_EYE_COLOR_LEFT_BLOCK)), sanitize_hexcolor(get_uni_identity_block(structure, DNA_EYE_COLOR_RIGHT_BLOCK)))
set_haircolor(sanitize_hexcolor(get_uni_identity_block(structure, DNA_HAIR_COLOR_BLOCK)), update = FALSE)
set_facial_haircolor(sanitize_hexcolor(get_uni_identity_block(structure, DNA_FACIAL_HAIR_COLOR_BLOCK)), update = FALSE)
set_hair_gradient_color(sanitize_hexcolor(get_uni_identity_block(structure, DNA_HAIR_COLOR_GRADIENT_BLOCK)), update = FALSE)
+1 -2
View File
@@ -250,8 +250,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror/broken, 28)
var/new_eye_color = input(user, "Choose your eye color", "Eye Color", user.eye_color_left) as color|null
if(isnull(new_eye_color))
return TRUE
user.eye_color_left = sanitize_hexcolor(new_eye_color)
user.eye_color_right = sanitize_hexcolor(new_eye_color)
user.set_eye_color(sanitize_hexcolor(new_eye_color))
user.dna.update_ui_block(DNA_EYE_COLOR_LEFT_BLOCK)
user.dna.update_ui_block(DNA_EYE_COLOR_RIGHT_BLOCK)
user.update_body()
+2 -4
View File
@@ -22,8 +22,7 @@
human.set_facial_hairstyle(random_facial_hairstyle(human.gender), update = FALSE)
human.set_haircolor("#[random_color()]", update = FALSE)
human.set_facial_haircolor(human.hair_color, update = FALSE)
human.eye_color_left = random_eye_color()
human.eye_color_right = human.eye_color_left
human.set_eye_color(random_eye_color())
human.skin_tone = pick(GLOB.skin_tones)
human.dna.species.randomize_active_underwear_only(human)
// Needs to be called towards the end to update all the UIs just set above
@@ -43,8 +42,7 @@
human.physique = human.gender
human.real_name = human.generate_random_mob_name()
human.name = human.get_visible_name()
human.eye_color_left = random_eye_color()
human.eye_color_right = human.eye_color_left
human.set_eye_color(random_eye_color())
human.skin_tone = pick(GLOB.skin_tones)
// No underwear generation handled here
var/picked_color = random_hair_color()
+1 -2
View File
@@ -8,8 +8,7 @@
r_hand = /obj/item/melee/blood_magic/stun
/datum/outfit/cultist/post_equip(mob/living/carbon/human/equipped, visuals_only)
equipped.eye_color_left = BLOODCULT_EYE
equipped.eye_color_right = BLOODCULT_EYE
equipped.set_eye_color(BLOODCULT_EYE)
equipped.update_body()
///Returns whether the given mob is convertable to the blood cult
@@ -36,8 +36,7 @@
if(visuals_only)
return
equipped_on.fully_replace_character_name(null, "Waldo")
equipped_on.eye_color_left = COLOR_BLACK
equipped_on.eye_color_right = COLOR_BLACK
equipped_on.set_eye_color(COLOR_BLACK)
equipped_on.gender = MALE
equipped_on.skin_tone = "caucasian3"
equipped_on.hairstyle = "Business Hair 3"
@@ -183,8 +183,7 @@
"lizard_markings" = "Dark Tiger Body",
"legs" = DIGITIGRADE_LEGS,
)
consumer.eye_color_left = "#FEE5A3"
consumer.eye_color_right = "#FEE5A3"
consumer.set_eye_color("#FEE5A3")
consumer.set_species(/datum/species/lizard)
if(2)
to_chat(user, span_danger("Your flesh begins to melt! Miraculously, you seem fine otherwise."))
@@ -186,8 +186,8 @@
/datum/emote/living/carbon/human/blink/run_emote(mob/living/carbon/human/user, params, type_override, intentional)
. = ..()
// Set to update_body until update_body_parts_head_only is fixed
user.update_body() // Refreshing instantly makes the user blink
var/obj/item/organ/eyes/eyes = user.get_organ_slot(ORGAN_SLOT_EYES)
eyes.blink()
/datum/emote/living/carbon/human/blink_r
key = "blink_r"
@@ -204,9 +204,10 @@
/datum/emote/living/carbon/human/blink_r/run_emote(mob/user, params, type_override, intentional)
. = ..()
// Set to update_body until update_body_parts_head_only is fixed
var/obj/item/organ/eyes/eyes = user.get_organ_slot(ORGAN_SLOT_EYES)
for (var/i in 1 to 3)
addtimer(CALLBACK(user, TYPE_PROC_REF(/mob, update_body)), i * 0.3 SECONDS)
addtimer(CALLBACK(eyes, TYPE_PROC_REF(/obj/item/organ/eyes, blink), 0.1 SECONDS, FALSE), i * 0.2 SECONDS)
eyes.animate_eyelids(user)
///Snowflake emotes only for le epic chimp
/datum/emote/living/carbon/human/monkey
@@ -370,3 +370,17 @@
user.visible_message(span_notice("[user] fixes some of the [message] [src]'s [affecting.name]."), \
span_notice("You fix some of the [message] [src == user ? "your" : "[src]'s"] [affecting.name]."))
return TRUE
/// Sets both mob's and eye organ's eye color values
/// If color_right is not passed, its assumed to be the same as color_left
/mob/living/carbon/human/proc/set_eye_color(color_left, color_right)
if (!color_right)
color_right = color_left
eye_color_left = color_left
eye_color_right = color_right
// Doesn't assign eye color if they already have one from their type
var/obj/item/organ/eyes/eyes = get_organ_by_type(/obj/item/organ/eyes)
if (istype(eyes) && !initial(eyes.eye_color_left) && !initial(eyes.eye_color_right))
eyes.eye_color_left = color_left
eyes.eye_color_right = color_right
eyes.refresh(src, FALSE)
@@ -3279,6 +3279,7 @@
if (eyes && !IS_ROBOTIC_ORGAN(eyes))
eyes.eye_color_left = color
eyes.eye_color_right = color
affected_human.update_body()
/datum/reagent/luminescent_fluid/red
name = "Red Luminiscent Fluid"
@@ -22,6 +22,8 @@
var/extend_sound = 'sound/vehicles/mecha/mechmove03.ogg'
/// Sound played when retracting
var/retract_sound = 'sound/vehicles/mecha/mechmove03.ogg'
/// Do we have a separate icon_state for the hand overlay?
var/hand_state = TRUE
/obj/item/organ/cyberimp/arm/Initialize(mapload)
. = ..()
@@ -89,6 +91,25 @@
// give the owner an idea about why his implant is glitching
Retract()
/obj/item/organ/cyberimp/arm/get_overlay_state(image_layer, obj/item/bodypart/limb)
return "[aug_overlay][zone == BODY_ZONE_L_ARM ? "_left" : "_right"]"
/obj/item/organ/cyberimp/arm/get_overlay(image_layer, obj/item/bodypart/limb)
if (!hand_state)
return ..()
var/mutable_appearance/arm_overlay = mutable_appearance(
icon = aug_icon,
icon_state = get_overlay_state(),
layer = image_layer,
)
var/mutable_appearance/hand_overlay = mutable_appearance(
icon = aug_icon,
icon_state = "[get_overlay_state()]_hand",
layer = -BODYPARTS_HIGH_LAYER,
)
return list(arm_overlay, hand_overlay)
/**
* Called when the mob uses the "drop item" hotkey
*
@@ -223,6 +244,7 @@
name = "integrated toolset implant"
desc = "A stripped-down version of the engineering cyborg toolset, designed to be installed on subject's arm. Contain advanced versions of every tool."
icon_state = "toolkit_engineering"
aug_overlay = "toolkit_engi"
actions_types = list(/datum/action/item_action/organ_action/toggle/toolkit)
items_to_create = list(
/obj/item/screwdriver/cyborg,
@@ -238,6 +260,7 @@
name = "integrated paperwork implant"
desc = "A highly sought out implant among heads of personnel, and other high up command staff in Nanotrasen. This implant allows the user to always have the tools necessary for paperwork handy"
icon_state = "toolkit_engineering"
aug_overlay = "toolkit_engi"
actions_types = list(/datum/action/item_action/organ_action/toggle/toolkit)
items_to_create = list(
/obj/item/pen/fountain,
@@ -277,11 +300,14 @@
/obj/item/organ/cyberimp/arm/medibeam
name = "integrated medical beamgun"
desc = "A cybernetic implant that allows the user to project a healing beam from their hand."
icon_state = "toolkit_surgical"
aug_overlay = "toolkit_med"
items_to_create = list(/obj/item/gun/medbeam)
/obj/item/organ/cyberimp/arm/flash
name = "integrated high-intensity photon projector" //Why not
desc = "An integrated projector mounted onto a user's arm that is able to be used as a powerful flash."
aug_overlay = "toolkit"
items_to_create = list(/obj/item/assembly/flash/armimplant)
/obj/item/organ/cyberimp/arm/flash/Initialize(mapload)
@@ -306,11 +332,13 @@
/obj/item/organ/cyberimp/arm/baton
name = "arm electrification implant"
desc = "An illegal combat implant that allows the user to administer disabling shocks from their arm."
aug_overlay = "toolkit"
items_to_create = list(/obj/item/borg/stun)
/obj/item/organ/cyberimp/arm/combat
name = "combat cybernetics implant"
desc = "A powerful cybernetic implant that contains combat modules built into the user's arm."
aug_overlay = "toolkit"
items_to_create = list(
/obj/item/melee/energy/blade/hardlight,
/obj/item/gun/medbeam,
@@ -331,6 +359,7 @@
name = "surgical toolset implant"
desc = "A set of surgical tools hidden behind a concealed panel on the user's arm."
icon_state = "toolkit_surgical"
aug_overlay = "toolkit_med"
actions_types = list(/datum/action/item_action/organ_action/toggle/toolkit)
items_to_create = list(
/obj/item/retractor/augment,
@@ -345,6 +374,7 @@
/obj/item/organ/cyberimp/arm/surgery/emagged
name = "hacked surgical toolset implant"
desc = "A set of surgical tools hidden behind a concealed panel on the user's arm. This one seems to have been tampered with."
aug_overlay = "toolkit_med"
items_to_create = list(
/obj/item/retractor/augment,
/obj/item/hemostat/augment,
@@ -374,6 +404,8 @@
)
actions_types = list()
aug_overlay = "strongarm"
hand_state = FALSE
///The amount of damage the implant adds to our unarmed attacks.
var/punch_damage = 5
@@ -7,6 +7,7 @@
name = "nutriment pump implant"
desc = "This implant will synthesize and pump into your bloodstream a small amount of nutriment when you are starving."
icon_state = "nutriment_implant"
aug_overlay = "nutripump"
var/hunger_threshold = NUTRITION_LEVEL_STARVING
var/synthesizing = 0
var/poison_amount = 5
@@ -37,6 +38,7 @@
name = "nutriment pump implant PLUS"
desc = "This implant will synthesize and pump into your bloodstream a small amount of nutriment when you are hungry."
icon_state = "adv_nutriment_implant"
aug_overlay = "nutripump_adv"
hunger_threshold = NUTRITION_LEVEL_HUNGRY
poison_amount = 10
@@ -44,6 +46,8 @@
name = "reviver implant"
desc = "This implant will attempt to revive and heal you if you lose consciousness. For the faint of heart!"
icon_state = "reviver_implant"
aug_overlay = "reviver"
emissive_overlay = TRUE
slot = ORGAN_SLOT_HEART_AID
var/revive_cost = 0
var/reviving = FALSE
@@ -159,7 +163,8 @@
slot = ORGAN_SLOT_THRUSTERS
icon_state = "imp_jetpack"
base_icon_state = "imp_jetpack"
implant_color = null
aug_overlay = "imp_jetpack"
emissive_overlay = TRUE
actions_types = list(/datum/action/item_action/organ_action/toggle)
w_class = WEIGHT_CLASS_NORMAL
var/on = FALSE
@@ -208,6 +213,7 @@
if(!silent)
to_chat(owner, span_notice("You turn your thrusters set on."))
update_appearance()
owner.update_body_parts()
/obj/item/organ/cyberimp/chest/thrusters/proc/deactivate(silent = FALSE)
if(!on)
@@ -218,6 +224,7 @@
to_chat(owner, span_notice("You turn your thrusters set off."))
on = FALSE
update_appearance()
owner.update_body_parts()
/obj/item/organ/cyberimp/chest/thrusters/update_icon_state()
icon_state = "[base_icon_state][on ? "-on" : null]"
@@ -258,6 +265,14 @@
deactivate(silent = TRUE)
return FALSE
/obj/item/organ/cyberimp/chest/thrusters/get_overlay_state(image_layer, obj/item/bodypart/limb)
return "[aug_overlay][on ? "_on" : ""]"
/obj/item/organ/cyberimp/chest/thrusters/get_overlay(image_layer, obj/item/bodypart/limb)
. = ..()
for (var/image/overlay as anything in .)
overlay.layer = -BODYPARTS_HIGH_LAYER // makes absolutely zero sense why it would layer ontop of jumpsuits but it looks cool
/obj/item/organ/cyberimp/chest/spine
name = "\improper Herculean gravitronic spinal implant"
desc = "This gravitronic spinal interface is able to improve the athletics of a user, allowing them greater physical ability. \
@@ -304,23 +319,24 @@
remove_organ_trait(TRAIT_STURDY_FRAME)
/obj/item/organ/cyberimp/chest/spine/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
. = ..()
if(!istype(tool, /obj/item/assembly/signaler/anomaly/grav))
return NONE
if(core_applied)
user.balloon_alert(user, "core already installed!")
return ITEM_INTERACT_BLOCKING
if(istype(tool, /obj/item/assembly/signaler/anomaly/grav))
user.balloon_alert(user, "core installed.")
name = /obj/item/organ/cyberimp/chest/spine/atlas::name
desc = /obj/item/organ/cyberimp/chest/spine/atlas::desc
athletics_boost_multiplier = /obj/item/organ/cyberimp/chest/spine/atlas::athletics_boost_multiplier
added_throw_range = /obj/item/organ/cyberimp/chest/spine/atlas::added_throw_range
added_throw_speed = /obj/item/organ/cyberimp/chest/spine/atlas::added_throw_speed
strength_bonus = /obj/item/organ/cyberimp/chest/spine/atlas::strength_bonus
core_applied = TRUE
update_appearance()
qdel(tool)
return ITEM_INTERACT_SUCCESS
user.balloon_alert(user, "core installed")
name = /obj/item/organ/cyberimp/chest/spine/atlas::name
desc = /obj/item/organ/cyberimp/chest/spine/atlas::desc
athletics_boost_multiplier = /obj/item/organ/cyberimp/chest/spine/atlas::athletics_boost_multiplier
added_throw_range = /obj/item/organ/cyberimp/chest/spine/atlas::added_throw_range
added_throw_speed = /obj/item/organ/cyberimp/chest/spine/atlas::added_throw_speed
strength_bonus = /obj/item/organ/cyberimp/chest/spine/atlas::strength_bonus
core_applied = TRUE
update_appearance()
qdel(tool)
return ITEM_INTERACT_SUCCESS
/obj/item/organ/cyberimp/chest/spine/atlas
name = "\improper Atlas gravitonic spinal implant"
@@ -15,48 +15,61 @@
var/HUD_traits = list()
/// Whether the HUD implant is on or off
var/toggled_on = TRUE
/// Eyecolor from the HUD
var/hud_color = "#3CB8A5"
/obj/item/organ/cyberimp/eyes/hud/proc/toggle_hud(mob/living/carbon/eye_owner)
/obj/item/organ/cyberimp/eyes/hud/proc/toggle_hud(mob/living/carbon/human/eye_owner)
if(toggled_on)
toggled_on = FALSE
eye_owner.remove_traits(HUD_traits, ORGAN_TRAIT)
balloon_alert(eye_owner, "hud disabled")
if(hud_color)
eye_owner.remove_eye_color(EYE_COLOR_HUD_PRIORITY)
return
toggled_on = TRUE
eye_owner.add_traits(HUD_traits, ORGAN_TRAIT)
balloon_alert(eye_owner, "hud enabled")
if(hud_color)
eye_owner.add_eye_color_right(hud_color, EYE_COLOR_HUD_PRIORITY)
/obj/item/organ/cyberimp/eyes/hud/on_mob_insert(mob/living/carbon/eye_owner, special = FALSE, movement_flags)
/obj/item/organ/cyberimp/eyes/hud/on_mob_insert(mob/living/carbon/human/eye_owner, special = FALSE, movement_flags)
. = ..()
eye_owner.add_traits(HUD_traits, ORGAN_TRAIT)
toggled_on = TRUE
if(hud_color)
eye_owner.add_eye_color_right(hud_color, EYE_COLOR_HUD_PRIORITY, !special)
/obj/item/organ/cyberimp/eyes/hud/on_mob_remove(mob/living/carbon/eye_owner, special, movement_flags)
/obj/item/organ/cyberimp/eyes/hud/on_mob_remove(mob/living/carbon/human/eye_owner, special, movement_flags)
. = ..()
eye_owner.remove_traits(HUD_traits, ORGAN_TRAIT)
toggled_on = FALSE
if(hud_color)
eye_owner.remove_eye_color(EYE_COLOR_HUD_PRIORITY, !special)
/obj/item/organ/cyberimp/eyes/hud/medical
name = "medical HUD implant"
desc = "These cybernetic eye implants will display a medical HUD over everything you see."
icon_state = "eye_implant_medical"
HUD_traits = list(TRAIT_MEDICAL_HUD)
hud_color = "#1D8FEC"
/obj/item/organ/cyberimp/eyes/hud/security
name = "security HUD implant"
desc = "These cybernetic eye implants will display a security HUD over everything you see."
icon_state = "eye_implant_security"
HUD_traits = list(TRAIT_SECURITY_HUD)
hud_color = "#9A151E"
/obj/item/organ/cyberimp/eyes/hud/diagnostic
name = "diagnostic HUD implant"
desc = "These cybernetic eye implants will display a diagnostic HUD over everything you see."
icon_state = "eye_implant_diagnostic"
HUD_traits = list(TRAIT_DIAGNOSTIC_HUD, TRAIT_BOT_PATH_HUD)
hud_color = "#CC6E33"
/obj/item/organ/cyberimp/eyes/hud/security/syndicate
name = "contraband security HUD implant"
desc = "A Cybersun Industries brand Security HUD Implant. These illicit cybernetic eye implants will display a security HUD over everything you see."
icon_state = "eye_implant_syndicate"
organ_flags = ORGAN_ROBOTIC | ORGAN_HIDDEN
hud_color = null
@@ -5,7 +5,72 @@
organ_flags = ORGAN_ROBOTIC
failing_desc = "seems to be broken."
var/implant_color = COLOR_WHITE
/// icon of the bodypart overlay we're going to be applying to our owner
var/aug_icon = 'icons/mob/human/species/misc/bodypart_overlay_augmentations.dmi'
/// icon_state of the bodypart overlay we're going to be applying to our owner
var/aug_overlay = null
/// Does the implant have an emissive overlay too?
var/emissive_overlay = FALSE
/// Bodypart overlay we're going to apply to whoever we're implanted into
var/datum/bodypart_overlay/augment/bodypart_aug = null
/obj/item/organ/cyberimp/Initialize(mapload)
. = ..()
if (aug_overlay)
bodypart_aug = new(src)
/obj/item/organ/cyberimp/Destroy()
QDEL_NULL(bodypart_aug)
return ..()
/obj/item/organ/cyberimp/proc/get_overlay_state()
return aug_overlay
/obj/item/organ/cyberimp/proc/get_overlay(image_layer, obj/item/bodypart/limb)
. = list()
. += image(icon = aug_icon, icon_state = get_overlay_state(), layer = image_layer)
if (emissive_overlay)
. += emissive_appearance(aug_icon, "[get_overlay_state()]_e", limb.owner || limb, image_layer)
/obj/item/organ/cyberimp/on_bodypart_insert(obj/item/bodypart/limb)
. = ..()
if (bodypart_aug)
limb.add_bodypart_overlay(bodypart_aug)
/obj/item/organ/cyberimp/on_bodypart_remove(obj/item/bodypart/limb)
. = ..()
if (bodypart_aug)
limb.remove_bodypart_overlay(bodypart_aug)
/datum/bodypart_overlay/augment
layers = EXTERNAL_ADJACENT
/// Implant that owns this overlay
var/obj/item/organ/cyberimp/implant
/datum/bodypart_overlay/augment/New(obj/item/organ/cyberimp/implant)
. = ..()
src.implant = implant
/datum/bodypart_overlay/augment/Destroy(force)
implant = null
return ..()
/datum/bodypart_overlay/augment/generate_icon_cache()
. = ..()
. += implant.get_overlay_state()
/datum/bodypart_overlay/augment/get_overlay(layer, obj/item/bodypart/limb)
layer = bitflag_to_layer(layer)
var/list/imageset = implant.get_overlay(layer, limb)
if(blocks_emissive == EMISSIVE_BLOCK_NONE || !limb)
return imageset
var/list/all_images = list()
for(var/image/overlay as anything in imageset)
all_images += overlay
all_images += emissive_blocker(overlay.icon, overlay.icon_state, limb, layer = overlay.layer, alpha = overlay.alpha)
return all_images
/obj/item/organ/cyberimp/feel_for_damage(self_aware)
// No feeling in implants (yet?)
@@ -284,6 +349,7 @@
icon_state = "implant_mask"
slot = ORGAN_SLOT_BREATHING_TUBE
w_class = WEIGHT_CLASS_TINY
aug_overlay = "breathing_tube"
/obj/item/organ/cyberimp/mouth/breathing_tube/emp_act(severity)
. = ..()
@@ -37,8 +37,8 @@
/// Are these eyes immune to pepperspray?
var/pepperspray_protect = FALSE
var/eye_color_left = "" //set to a hex code to override a mob's left eye color
var/eye_color_right = "" //set to a hex code to override a mob's right eye color
var/eye_color_left = null // set to a hex code to override a mob's left eye color
var/eye_color_right = null // set to a hex code to override a mob's right eye color
var/eye_icon_state = "eyes"
/// Do these eyes have blinking animations
var/blink_animation = TRUE
@@ -74,6 +74,13 @@
. = ..()
receiver.cure_blind(NO_EYES)
apply_damaged_eye_effects()
// Ensures that non-player mobs get their eye colors assigned, as players get them from prefs
if (ishuman(receiver))
var/mob/living/carbon/human/as_human = receiver
if (!eye_color_left)
eye_color_left = as_human.eye_color_left
if (!eye_color_right)
eye_color_right = as_human.eye_color_right
refresh(receiver, call_update = !special)
RegisterSignal(receiver, COMSIG_ATOM_BULLET_ACT, PROC_REF(on_bullet_act))
RegisterSignal(receiver, COMSIG_COMPONENT_CLEAN_FACE_ACT, PROC_REF(on_face_wash))
@@ -90,9 +97,9 @@
return
var/mob/living/carbon/human/affected_human = eye_owner
if(length(eye_color_left))
if(eye_color_left)
affected_human.add_eye_color_left(eye_color_left, EYE_COLOR_ORGAN_PRIORITY, update_body = FALSE)
if(length(eye_color_right))
if(eye_color_right)
affected_human.add_eye_color_right(eye_color_right, EYE_COLOR_ORGAN_PRIORITY, update_body = FALSE)
refresh_atom_color_overrides()
@@ -152,9 +159,9 @@
var/left_color = COLOR_WHITE
var/right_color = COLOR_WHITE
if (length(eye_color_left))
if (eye_color_left)
left_color = eye_color_left
if (length(eye_color_right))
if (eye_color_right)
right_color = eye_color_right
if (checked_color[ATOM_COLOR_TYPE_INDEX] == ATOM_COLOR_TYPE_FILTER)
@@ -295,7 +302,7 @@
left_scar.blend_mode = BLEND_INSET_OVERLAY
. += left_scar
if (iris_overlay && length(eye_color_left) && length(eye_color_right))
if (iris_overlay && eye_color_left && eye_color_right)
var/mutable_appearance/left_iris = mutable_appearance(icon, "[iris_overlay]_l")
var/mutable_appearance/right_iris = mutable_appearance(icon, "[iris_overlay]_r")
var/list/color_left = rgb2num(eye_color_left, COLORSPACE_HSL)
@@ -427,15 +434,7 @@
eyelid_right.render_target = "*[REF(parent)]_eyelid_right"
parent.vis_contents += eyelid_left
parent.vis_contents += eyelid_right
var/sync_blinking = synchronized_blinking && (parent.get_organ_loss(ORGAN_SLOT_BRAIN) < ASYNC_BLINKING_BRAIN_DAMAGE)
// Randomize order for unsynched animations
if (sync_blinking || prob(50))
var/list/anim_times = animate_eyelid(eyelid_left, parent, sync_blinking)
animate_eyelid(eyelid_right, parent, sync_blinking, anim_times)
else
var/list/anim_times = animate_eyelid(eyelid_right, parent, sync_blinking)
animate_eyelid(eyelid_left, parent, sync_blinking, anim_times)
animate_eyelids(parent)
var/mutable_appearance/left_eyelid_overlay = mutable_appearance(layer = -BODY_LAYER, offset_spokesman = parent)
var/mutable_appearance/right_eyelid_overlay = mutable_appearance(layer = -BODY_LAYER, offset_spokesman = parent)
left_eyelid_overlay.render_source = "*[REF(parent)]_eyelid_left"
@@ -447,14 +446,28 @@
. = list()
var/prevent_loops = HAS_TRAIT(parent, TRAIT_PREVENT_BLINK_LOOPS)
animate(eyelid, alpha = 0, time = 0, loop = (prevent_loops ? 0 : -1))
for (var/i in 1 to (prevent_loops ? 1 : BLINK_LOOPS))
var/wait_time = rand(BASE_BLINKING_DELAY - RAND_BLINKING_DELAY, BASE_BLINKING_DELAY + RAND_BLINKING_DELAY)
var/wait_time = rand(BASE_BLINKING_DELAY - RAND_BLINKING_DELAY, BASE_BLINKING_DELAY + RAND_BLINKING_DELAY)
if (anim_times)
if (sync_blinking)
wait_time = anim_times[1]
anim_times.Cut(1, 2)
else
wait_time = rand(max(BASE_BLINKING_DELAY - RAND_BLINKING_DELAY, anim_times[1] - RAND_BLINKING_DELAY), anim_times[1])
animate(time = wait_time)
. += wait_time
var/cycles = (prevent_loops ? 1 : BLINK_LOOPS)
for (var/i in 1 to cycles)
if (anim_times)
if (sync_blinking)
wait_time = anim_times[1]
anim_times.Cut(1, 2)
else
wait_time = rand(max(BASE_BLINKING_DELAY - RAND_BLINKING_DELAY, anim_times[1] - RAND_BLINKING_DELAY), anim_times[1])
else
wait_time = rand(BASE_BLINKING_DELAY - RAND_BLINKING_DELAY, BASE_BLINKING_DELAY + RAND_BLINKING_DELAY)
. += wait_time
if (anim_times && !sync_blinking)
// Make sure that we're somewhat in sync with the other eye
@@ -462,8 +475,38 @@
anim_times.Cut(1, 2)
animate(alpha = 255, time = 0)
animate(time = BLINK_DURATION)
animate(alpha = 0, time = 0)
animate(time = wait_time)
if (i != cycles)
animate(alpha = 0, time = 0)
animate(time = wait_time)
/obj/item/organ/eyes/proc/blink(duration = BLINK_DURATION, restart_animation = TRUE)
var/left_delayed = rand(50)
// Storing blink delay so mistimed blinks of lizards don't get cut short
var/blink_delay = synchronized_blinking ? rand(0, RAND_BLINKING_DELAY) : 0
animate(eyelid_left, alpha = 0, time = 0)
if (!synchronized_blinking && left_delayed)
animate(time = blink_delay)
animate(alpha = 255, time = 0)
animate(time = duration)
animate(alpha = 0, time = 0)
animate(eyelid_right, alpha = 0, time = 0)
if (!synchronized_blinking && !left_delayed)
animate(time = blink_delay)
animate(alpha = 255, time = 0)
animate(time = duration)
animate(alpha = 0, time = 0)
if (restart_animation)
addtimer(CALLBACK(src, PROC_REF(animate_eyelids), owner), blink_delay + duration)
/obj/item/organ/eyes/proc/animate_eyelids(mob/living/carbon/human/parent)
var/sync_blinking = synchronized_blinking && (parent.get_organ_loss(ORGAN_SLOT_BRAIN) < ASYNC_BLINKING_BRAIN_DAMAGE)
// Randomize order for unsynched animations
if (sync_blinking || prob(50))
var/list/anim_times = animate_eyelid(eyelid_left, parent, sync_blinking)
animate_eyelid(eyelid_right, parent, sync_blinking, anim_times)
else
var/list/anim_times = animate_eyelid(eyelid_right, parent, sync_blinking)
animate_eyelid(eyelid_left, parent, sync_blinking, anim_times)
/obj/effect/abstract/eyelid_effect
name = "eyelid"
@@ -640,8 +683,8 @@
/obj/item/organ/eyes/robotic/flashlight
name = "flashlight eyes"
desc = "It's two flashlights rigged together with some wire. Why would you put these in someone's head?"
eye_color_left ="fee5a3"
eye_color_right ="fee5a3"
eye_color_left ="#fee5a3"
eye_color_right ="#fee5a3"
icon = 'icons/obj/lighting.dmi'
icon_state = "flashlight_eyes"
flash_protect = FLASH_PROTECTION_WELDER
+1 -2
View File
@@ -82,8 +82,7 @@
ling.dna.features["spines"] = "Long + Membrane"
ling.dna.features["lizard_markings"] = "Light Belly"
ling.dna.features["legs"] = DIGITIGRADE_LEGS
ling.eye_color_left = COLOR_WHITE
ling.eye_color_right = COLOR_WHITE
ling.set_eye_color(COLOR_WHITE)
ling.dna.update_ui_block(DNA_EYE_COLOR_LEFT_BLOCK)
ling.dna.update_ui_block(DNA_EYE_COLOR_RIGHT_BLOCK)
ling.set_species(/datum/species/lizard)
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB