/obj/item/organ/internal/eyes name = "eyeballs" icon_state = "eyes" gender = PLURAL organ_tag = "eyes" parent_organ = "head" slot = "eyes" var/eye_color = "#000000" // Should never be null var/list/colourmatrix = null var/list/colourblind_matrix = MATRIX_GREYSCALE //Special colourblindness parameters. By default, it's black-and-white. var/list/replace_colours = GREYSCALE_COLOR_REPLACE var/dependent_disabilities = list() //Gets set by eye-dependent disabilities such as colourblindness so the eyes can transfer the disability during transplantation. var/weld_proof = FALSE //If set, the eyes will not take damage during welding. eg. IPC optical sensors do not take damage when they weld things while all other eyes will. var/vision_flags = 0 var/see_in_dark = 2 var/tint = FLASH_PROTECTION_NONE var/flash_protect = FLASH_PROTECTION_NONE var/see_invisible = SEE_INVISIBLE_LIVING var/lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE /obj/item/organ/internal/eyes/proc/update_colour() dna.write_eyes_attributes(src) /obj/item/organ/internal/eyes/proc/generate_icon(mob/living/carbon/human/HA) var/mob/living/carbon/human/H = HA if(!istype(H)) H = owner var/icon/eyes_icon = new /icon('icons/mob/human_face.dmi', H.dna.species.eyes) eyes_icon.Blend(eye_color, ICON_ADD) return eyes_icon /obj/item/organ/internal/eyes/proc/get_colourmatrix() //Returns a special colour matrix if the eyes are organic and the mob is colourblind, otherwise it uses the current one. if(!is_robotic() && HAS_TRAIT(owner, TRAIT_COLORBLIND)) return colourblind_matrix else return colourmatrix /obj/item/organ/internal/eyes/proc/shine() if(is_robotic() || (see_in_dark > EYE_SHINE_THRESHOLD)) return TRUE /obj/item/organ/internal/eyes/insert(mob/living/carbon/human/M, special = 0) ..() if(istype(M) && eye_color) M.update_body() //Apply our eye colour to the target. M.update_tint() M.update_sight() if(!HAS_TRAIT(M, TRAIT_COLORBLIND) && (TRAIT_COLORBLIND in dependent_disabilities)) //If the eyes are colourblind and we're not, carry over the gene. dependent_disabilities -= TRAIT_COLORBLIND M.dna.SetSEState(GLOB.colourblindblock, TRUE) singlemutcheck(M, GLOB.colourblindblock, MUTCHK_FORCED) else M.update_client_colour() //If we're here, that means the mob acquired the colourblindness gene while they didn't have eyes. Better handle it. /obj/item/organ/internal/eyes/remove(mob/living/carbon/human/M, special = 0) if(!special && HAS_TRAIT(M, TRAIT_COLORBLIND)) //If special is set, that means these eyes are getting deleted (i.e. during set_species()) if(!(TRAIT_COLORBLIND in dependent_disabilities)) //We only want to change COLOURBLINDBLOCK and such it the eyes are being surgically removed. dependent_disabilities |= TRAIT_COLORBLIND M.dna.SetSEState(GLOB.colourblindblock, FALSE) singlemutcheck(M, GLOB.colourblindblock, MUTCHK_FORCED) . = ..() M.update_tint() M.update_sight() /obj/item/organ/internal/eyes/surgeryize() if(!owner) return owner.cure_nearsighted(EYE_DAMAGE) owner.cure_blind(EYE_DAMAGE) owner.SetEyeBlurry(0) owner.SetEyeBlind(0) /obj/item/organ/internal/eyes/night_vision name = "shadow eyes" desc = "A spooky set of eyes that can see in the dark." see_in_dark = 8 lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE actions_types = list(/datum/action/item_action/organ_action/use) /obj/item/organ/internal/eyes/night_vision/ui_action_click() vision_flags = initial(vision_flags) switch(lighting_alpha) if(LIGHTING_PLANE_ALPHA_VISIBLE) lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE if(LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE) lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE if(LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE) lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE else lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE vision_flags &= ~SEE_BLACKNESS owner.update_sight() /obj/item/organ/internal/eyes/night_vision/nightmare name = "burning red eyes" desc = "Even without their shadowy owner, looking at these eyes gives you a sense of dread." icon_state = "burning_eyes" /obj/item/organ/internal/eyes/robotize(make_tough) colourmatrix = null ..() //Make sure the organ's got the robotic status indicators before updating the client colour. if(owner) owner.update_client_colour(0) //Since mechanical eyes give see_in_dark of 2 and full colour vision atm, just having this here is fine. /obj/item/organ/internal/eyes/cybernetic name = "cybernetic eyes" icon_state = "eyes-c" desc = "An electronic device designed to mimic the functions of a pair of human eyes. It has no benefits over organic eyes, but is easy to produce." origin_tech = "biotech=4" status = ORGAN_ROBOT var/flash_intensity = 1 /obj/item/organ/internal/eyes/cybernetic/emp_act(severity) if(!owner || emp_proof) return if(prob(10 * severity)) return to_chat(owner, "Static obfuscates your vision!") owner.flash_eyes(flash_intensity, visual = TRUE) ..() /obj/item/organ/internal/eyes/cybernetic/meson name = "meson eyes" desc = "These cybernetic eyes will allow you to see the structural layout of the station, and, well, everything else." icon_state = "eyes-c-meson" eye_color = "#199900" lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE origin_tech = "materials=4;engineering=4;biotech=4;magnets=4" /obj/item/organ/internal/eyes/cybernetic/meson/insert(mob/living/carbon/human/M, special = FALSE) ADD_TRAIT(M, TRAIT_MESON_VISION, "meson_vision[UID()]") return ..() /obj/item/organ/internal/eyes/cybernetic/meson/remove(mob/living/carbon/human/M, special = FALSE) REMOVE_TRAIT(M, TRAIT_MESON_VISION, "meson_vision[UID()]") return ..() /obj/item/organ/internal/eyes/cybernetic/xray name = "\improper X-ray eyes" desc = "These cybernetic eyes will give you X-ray vision. Blinking is futile." icon_state = "eyes-c-xray" see_in_dark = 8 vision_flags = SEE_MOBS | SEE_OBJS | SEE_TURFS origin_tech = "materials=4;programming=4;biotech=7;magnets=4" /obj/item/organ/internal/eyes/cybernetic/xray/hardened name = "hardened X-ray eyes" desc = "These cybernetic eyes will give you X-ray vision. Blinking is futile. This pair has been hardened for special operations personnel." eye_color = "#FFCC00" emp_proof = TRUE origin_tech = "materials=6;programming=5;biotech=7;magnets=6;syndicate=3" /obj/item/organ/internal/eyes/cybernetic/thermals name = "thermal eyes" desc = "These cybernetic eye implants will give you thermal vision. Vertical slit pupil included." icon_state = "eyes-c-thermal" eye_color = "#E12224" vision_flags = SEE_MOBS lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE flash_protect = FLASH_PROTECTION_SENSITIVE see_in_dark = 8 origin_tech = "materials=5;programming=4;biotech=4;magnets=4;syndicate=1" /obj/item/organ/internal/eyes/cybernetic/thermals/hardened name = "hardened thermal eyes" desc = "These cybernetic eye implants will give you thermal vision. Vertical slit pupil included. This pair has been hardened for special operations personnel." emp_proof = TRUE origin_tech = "materials=6;programming=5;biotech=6;magnets=6;syndicate=3" /obj/item/organ/internal/eyes/cybernetic/scope name = "\improper Kaleido Optics eyes" desc = "These cybernetic eye implants will let you zoom in on far away objects. Many users find it disorienting, and find it hard to interact with things near them when active." icon_state = "eyes-c-kaleido" eye_color = "#6f00ff" flash_protect = FLASH_PROTECTION_EXTRA_SENSITIVE origin_tech = "materials=5;programming=4;biotech=4;magnets=4" var/scope_range = 0.8 //Only used in initialize. Greatly nerfed zoom range, since you are not taking the time zoom delay the lwap has. var/active = FALSE /obj/item/organ/internal/eyes/cybernetic/scope/Initialize(mapload) . = ..() AddComponent(/datum/component/scope, range_modifier = scope_range, item_action_type = /datum/action/item_action/organ_action/toggle, flags = SCOPE_CLICK_MIDDLE) /obj/item/organ/internal/eyes/cybernetic/scope/insert(mob/living/carbon/human/M, special) . = ..() flash_protect = FLASH_PROTECTION_NONE //Resets it to none, so we can just flip to inital each time it is used. /obj/item/organ/internal/eyes/cybernetic/scope/ui_action_click(mob/user, actiontype) active = !active if(active) flash_protect = initial(flash_protect) else flash_protect = FLASH_PROTECTION_NONE /obj/item/organ/internal/eyes/cybernetic/scope/hardened name = "\improper Hardened Kaleido Optics eyes" desc = "These cybernetic eye implants will let you zoom in on far away objects. Many users find it disorienting, and find it hard to interact with things near them when active. This pair has been hardened for special operations personnel, and has enhanced zoom functionality." flash_protect = FLASH_PROTECTION_SENSITIVE origin_tech = "materials=6;programming=5;biotech=6;magnets=6;syndicate=3" scope_range = 1.25 emp_proof = TRUE /obj/item/organ/internal/eyes/cybernetic/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 ="#FEE5A3" icon = 'icons/obj/lighting.dmi' icon_state = "flashlight_eyes" flash_protect = FLASH_PROTECTION_WELDER tint = INFINITY var/obj/item/flashlight/eyelight/eye /obj/item/organ/internal/eyes/cybernetic/flashlight/emp_act(severity) return /obj/item/organ/internal/eyes/cybernetic/flashlight/insert(mob/living/carbon/M, special = FALSE) ..() if(!eye) eye = new /obj/item/flashlight/eyelight() eye.on = TRUE eye.forceMove(M) eye.update_brightness(M) M.become_blind("flashlight_eyes") /obj/item/organ/internal/eyes/cybernetic/flashlight/remove(mob/living/carbon/M, special = FALSE) if(eye) eye.on = FALSE eye.update_brightness(M) eye.forceMove(src) M.cure_blind("flashlight_eyes") . = ..() // Welding shield implant /obj/item/organ/internal/eyes/cybernetic/shield name = "shielded robotic eyes" desc = "These reactive micro-shields will protect you from welders and flashes without obscuring your vision." flash_protect = FLASH_PROTECTION_WELDER eye_color = "#101010" origin_tech = "materials=4;biotech=3;engineering=4;plasmatech=3" flash_intensity = 3 #define INTACT 0 #define ONE_SHATTERED 1 #define BOTH_SHATTERED 2 // no occuline allowed /obj/item/organ/internal/eyes/cybernetic/eyesofgod name = "\improper Eyes of the Gods" desc = "Two eyes said to belong to the gods. But such vision comes at a price." icon_state = "eyesofgod" eye_color = "#58a5ec" see_in_dark = 8 flash_protect = FLASH_PROTECTION_SENSITIVE lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE emp_proof = TRUE //They are crystal artifacts, not metal min_bruised_damage = 30 min_broken_damage = 60 actions_types = list(/datum/action/item_action/organ_action/use/eyesofgod) var/active = FALSE var/shatter_state = INTACT /obj/item/organ/internal/eyes/cybernetic/eyesofgod/Destroy() deactivate() return ..() /obj/item/organ/internal/eyes/cybernetic/eyesofgod/remove(mob/living/carbon/human/M, special) owner.cure_nearsighted() //Let's not leave the owner with blindness permamently that only admins / re-adding the eyes can remove owner.cure_blind() deactivate() return ..() /obj/item/organ/internal/eyes/cybernetic/eyesofgod/on_life() . = ..() if(is_mining_level(owner.z)) //More lavaland use cause magic or something. Don't worry about the ash in peoples eyes. heal_internal_damage(0.75, 1) if(!active) switch(damage) if(0 to 10) heal_internal_damage(1, 1) if(prob(25)) owner.cure_nearsighted() owner.cure_blind() unshatter() if(10 to 30) heal_internal_damage(0.75, 1) if(prob(10)) owner.cure_blind() unshatter() if(30 to 60) heal_internal_damage(0.5, 1) if(60 to INFINITY) heal_internal_damage(0.33, 1) else owner.mob_light("#58a5ec", 3, _duration = 2 SECONDS) receive_damage(1, 1) for(var/obj/O in range(7, owner)) var/turf/T = get_turf(O) for(var/mob/M in O.contents) receive_damage(0.25, 1) new /obj/effect/temp_visual/eyesofgod(T) if(prob(25)) to_chat(M, "You feel like you are being watched...") switch(damage) if(25 to 30) if(prob(50)) to_chat(owner, "Your eyes are burning in your skull!") owner.apply_damage(0.5, BURN, parent_organ) if(30 to 54) receive_damage(0.25, 1) //more pain when damaged if(prob(15)) //Warning that you are still hurting yourself still to_chat(owner, "Your eyes are burning in your skull!") owner.apply_damage(0.5, BURN, parent_organ) if(55 to 60) if(prob(50)) to_chat(owner, "Your eyes feel like they are going to explode!") owner.apply_damage(1, BURN, parent_organ) /obj/item/organ/internal/eyes/cybernetic/eyesofgod/proc/unshatter() if(shatter_state == INTACT) return if(damage <= 10) shatter_state = INTACT else if(shatter_state == ONE_SHATTERED) return shatter_state = ONE_SHATTERED to_chat(owner, "Your feel better as your [shatter_state ? "left eye" : "right eye"] fixes itself!") /obj/item/organ/internal/eyes/cybernetic/eyesofgod/receive_damage(amount, silent) . = ..() if(damage >= 30 && shatter_state == INTACT || damage >= 60 && shatter_state == ONE_SHATTERED) shatter() /obj/item/organ/internal/eyes/cybernetic/eyesofgod/proc/shatter() var/msg = "no eye?" switch(shatter_state) if(ONE_SHATTERED) shatter_state = BOTH_SHATTERED msg = "left eye" owner.become_blind(EYES_OF_GOD) //Special flag otherwise occuline heals it :gatto: if(INTACT) shatter_state = ONE_SHATTERED msg = "right eye" owner.become_nearsighted(EYES_OF_GOD) to_chat(owner, "You scream out in pain as your [msg] shatters!") owner.emote("scream") owner.bleed(5) deactivate() /obj/item/organ/internal/eyes/cybernetic/eyesofgod/proc/activate() receive_damage(2, 1) //No flicky flicky on / off to fully negate damage RegisterSignal(owner, COMSIG_CARBON_FLASH_EYES, PROC_REF(got_flashed)) active = TRUE see_invisible = SEE_INVISIBLE_LEVEL_TWO vision_flags = SEE_MOBS | SEE_OBJS | SEE_TURFS lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE flash_protect = FLASH_PROTECTION_VERYVUNERABLE //Flashing is it's weakness. I don't care how many protections you have up owner?.client?.color = LIGHT_COLOR_PURE_CYAN colourmatrix = list(0, 0, 0,\ 0, 1, 0,\ 0, 0, 1) owner.update_sight() owner.update_eyes_overlay_layer() /obj/item/organ/internal/eyes/cybernetic/eyesofgod/proc/deactivate() UnregisterSignal(owner, COMSIG_CARBON_FLASH_EYES) active = FALSE see_invisible = initial(see_invisible) vision_flags = initial(vision_flags) lighting_alpha = initial(lighting_alpha) flash_protect = initial(flash_protect) owner?.client?.color = null colourmatrix = null owner.update_sight() owner.update_eyes_overlay_layer() /obj/item/organ/internal/eyes/cybernetic/eyesofgod/proc/got_flashed(mob/living/carbon/C, laser_pointer) if(active && !laser_pointer) //Should be active but double checking, and no laser pointer memes, since that is ranged flashes with no skill / counter, unlike a more predectable flashbang addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/item/organ, receive_damage), 22), 0.1 SECONDS)//Enough with base flashing to kick people out of vision in a moment due to damage. Don't want to do it instantly, or it lets people take less damage from the base flash /obj/item/organ/internal/eyes/cybernetic/eyesofgod/ui_action_click() if(!active && shatter_state < BOTH_SHATTERED) activate() return deactivate() /obj/effect/temp_visual/eyesofgod name = "eye mark" icon_state = "shield_reversed" duration = 2 SECONDS invisibility = INVISIBILITY_LEVEL_TWO #undef INTACT #undef ONE_SHATTERED #undef BOTH_SHATTERED