Completes the /datum/component/shadekin work (#17895)

* Makes shadekin a component

* Update shadekin.dm

* Update human.dm

* a

* i love typos

* Update life.dm

* guh

* Upports the shadekin stuff

Also fixes an 8 year bug where the ability master would delete itself

* boh

* flashlight flickering

* flickery

* Update flashlight.dm

* i hate lightcode

* no clue

* reenable

* more changes

* evil

* Update living.dm

* simplekin fix

* yeah

* maw fixes
This commit is contained in:
Cameron Lennox
2025-07-05 20:04:24 +02:00
committed by GitHub
parent ab408df1e6
commit 5917c7bdee
66 changed files with 1823 additions and 1031 deletions
@@ -332,12 +332,13 @@
return if_no_id
//repurposed proc. Now it combines get_id_name() and get_face_name() to determine a mob's name variable. Made into a seperate proc as it'll be useful elsewhere
/mob/living/carbon/human/proc/get_visible_name()
if(ability_flags & AB_PHASE_SHIFTED)
/mob/living/carbon/human/get_visible_name()
var/datum/component/shadekin/SK = get_shadekin_component()
if(SK && SK.in_phase)
return "Something" // Something
if( wear_mask && (wear_mask.flags_inv&HIDEFACE) ) //Wearing a mask which hides our face, use id-name if possible
if(wear_mask && (wear_mask.flags_inv&HIDEFACE)) //Wearing a mask which hides our face, use id-name if possible
return get_id_name("Unknown")
if( head && (head.flags_inv&HIDEFACE) )
if(head && (head.flags_inv&HIDEFACE))
return get_id_name("Unknown") //Likewise for hats
var/face_name = get_face_name()
var/id_name = get_id_name("")
@@ -12,43 +12,3 @@
var/low_sorting_priority = FALSE
tail_alt = TAIL_UPPER_LAYER // not a toggle for humans but a pointer for what layer the tail should be when facing North/East/West
/mob/living/carbon/human/proc/shadekin_get_energy()
var/datum/species/shadekin/SK = species
if(!istype(SK))
return 0
return SK.get_energy(src)
/mob/living/carbon/human/proc/shadekin_get_max_energy()
var/datum/species/shadekin/SK = species
if(!istype(SK))
return 0
return SK.get_max_energy(src)
/mob/living/carbon/human/proc/shadekin_set_energy(var/new_energy)
var/datum/species/shadekin/SK = species
if(!istype(SK))
return 0
SK.set_energy(src, new_energy)
/mob/living/carbon/human/proc/shadekin_set_max_energy(var/new_max_energy)
var/datum/species/shadekin/SK = species
if(!istype(SK))
return 0
SK.set_max_energy(src, new_max_energy)
/mob/living/carbon/human/proc/shadekin_adjust_energy(var/amount)
var/datum/species/shadekin/SK = species
if(!istype(SK))
return 0
SK.set_energy(src, SK.get_energy(src) + amount)
+2 -1
View File
@@ -1,5 +1,6 @@
/mob/living/carbon/human/GetAltName()
if(ability_flags & AB_PHASE_SHIFTED)
var/datum/component/shadekin/SK = get_shadekin_component()
if(SK && SK.in_phase)
return ""
if(name != GetVoice())
return " (as [get_id_name("Unknown")])"
@@ -68,7 +68,6 @@
breath_type = null
poison_type = null
water_breather = TRUE //They don't quite breathe
var/doing_phase = FALSE // Prevent bugs when spamming phase button
vision_flags = SEE_SELF|SEE_MOBS
appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_SKIN_COLOR | HAS_EYE_COLOR | HAS_UNDERWEAR
@@ -101,22 +100,8 @@
BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right)
)
//SHADEKIN-UNIQUE STUFF GOES HERE
var/list/shadekin_abilities = list(/datum/power/shadekin/phase_shift,
/datum/power/shadekin/regenerate_other,
/datum/power/shadekin/create_shade)
var/list/shadekin_ability_datums = list()
var/kin_type
var/energy_light = 0.25
var/energy_dark = 0.75
species_component = /datum/component/shadekin
/datum/species/shadekin/New()
..()
for(var/power in shadekin_abilities)
var/datum/power/shadekin/SKP = new power(src)
shadekin_ability_datums.Add(SKP)
/datum/species/shadekin/handle_death(var/mob/living/carbon/human/H)
spawn(1)
for(var/obj/item/W in H)
@@ -129,212 +114,33 @@
/datum/species/shadekin/get_random_name()
return "shadekin"
/datum/species/shadekin/handle_environment_special(var/mob/living/carbon/human/H)
handle_shade(H)
..()
/datum/species/shadekin/add_inherent_verbs(var/mob/living/carbon/human/H)
..()
add_shadekin_abilities(H)
/datum/species/shadekin/proc/add_shadekin_abilities(var/mob/living/carbon/human/H)
if(!H.ability_master || !istype(H.ability_master, /obj/screen/movable/ability_master/shadekin))
H.ability_master = null
H.ability_master = new /obj/screen/movable/ability_master/shadekin(H)
for(var/datum/power/shadekin/P in shadekin_ability_datums)
if(!(P.verbpath in H.verbs))
add_verb(H, P.verbpath)
H.ability_master.add_shadekin_ability(
object_given = H,
verb_given = P.verbpath,
name_given = P.name,
ability_icon_given = P.ability_icon_state,
arguments = list()
)
/datum/species/shadekin/proc/handle_shade(var/mob/living/carbon/human/H)
//Shifted kin don't gain/lose energy (and save time if we're at the cap)
var/darkness = 1
var/dark_gains = 0
var/turf/T = get_turf(H)
if(!T)
dark_gains = 0
return
var/brightness = T.get_lumcount() //Brightness in 0.0 to 1.0
darkness = 1-brightness //Invert
var/is_dark = (darkness >= 0.5)
if(H.ability_flags & AB_PHASE_SHIFTED)
dark_gains = 0
else
//Heal (very) slowly in good darkness
if(is_dark)
H.adjustFireLoss((-0.10)*darkness)
H.adjustBruteLoss((-0.10)*darkness)
H.adjustToxLoss((-0.10)*darkness)
//energy_dark and energy_light are set by the shadekin eye traits.
//These are balanced around their playstyles and 2 planned new aggressive abilities
dark_gains = energy_dark
else
dark_gains = energy_light
set_energy(H, get_energy(H) + dark_gains)
//Update huds
update_shadekin_hud(H)
/datum/species/shadekin/proc/get_energy(var/mob/living/carbon/human/H)
var/datum/component/shadekin/comp = H.GetComponent(/datum/component/shadekin)
if(!comp)
return FALSE //No component, no energy to be had.
if(comp.dark_energy_infinite)
return comp.max_dark_energy
return comp.dark_energy
/datum/species/shadekin/proc/get_max_energy(var/mob/living/carbon/human/H)
var/datum/component/shadekin/comp = H.GetComponent(/datum/component/shadekin)
if(!comp)
return FALSE //No component, no energy to be had.
return comp.max_dark_energy
/datum/species/shadekin/proc/set_energy(var/mob/living/carbon/human/H, var/new_energy)
var/datum/component/shadekin/comp = H.GetComponent(/datum/component/shadekin)
if(!comp)
return FALSE //No component, no energy to be had.
comp.dark_energy = CLAMP(new_energy, 0, get_max_energy(H))
/datum/species/shadekin/proc/set_max_energy(var/mob/living/carbon/human/H, var/new_max_energy)
var/datum/component/shadekin/comp = H.GetComponent(/datum/component/shadekin)
if(!comp)
return FALSE //No component, no energy to be had.
comp.max_dark_energy = new_max_energy
/datum/species/shadekin/proc/update_shadekin_hud(var/mob/living/carbon/human/H)
var/turf/T = get_turf(H)
if(H.shadekin_display)
var/l_icon = 0
var/e_icon = 0
H.shadekin_display.invisibility = INVISIBILITY_NONE
if(T)
var/brightness = T.get_lumcount() //Brightness in 0.0 to 1.0
var/darkness = 1-brightness //Invert
switch(darkness)
if(0.80 to 1.00)
l_icon = 0
if(0.60 to 0.80)
l_icon = 1
if(0.40 to 0.60)
l_icon = 2
if(0.20 to 0.40)
l_icon = 3
if(0.00 to 0.20)
l_icon = 4
switch(get_energy(H))
if(0 to 24)
e_icon = 0
if(25 to 49)
e_icon = 1
if(50 to 74)
e_icon = 2
if(75 to 99)
e_icon = 3
if(100 to INFINITY)
e_icon = 4
H.shadekin_display.icon_state = "shadekin-[l_icon]-[e_icon]"
return
/datum/species/shadekin/proc/get_shadekin_eyecolor(var/mob/living/carbon/human/H)
var/eyecolor_rgb = rgb(H.r_eyes, H.g_eyes, H.b_eyes)
var/eyecolor_hue = rgb2num(eyecolor_rgb, COLORSPACE_HSV)[1]
var/eyecolor_sat = rgb2num(eyecolor_rgb, COLORSPACE_HSV)[2]
var/eyecolor_val = rgb2num(eyecolor_rgb, COLORSPACE_HSV)[3]
//First, clamp the saturation/value to prevent black/grey/white eyes
if(eyecolor_sat < 10)
eyecolor_sat = 10
if(eyecolor_val < 40)
eyecolor_val = 40
eyecolor_rgb = rgb(eyecolor_hue, eyecolor_sat, eyecolor_val, space=COLORSPACE_HSV)
H.r_eyes = rgb2num(eyecolor_rgb)[1]
H.g_eyes = rgb2num(eyecolor_rgb)[2]
H.b_eyes = rgb2num(eyecolor_rgb)[3]
//Now determine what color we fall into.
var/eyecolor_type = BLUE_EYES
switch(eyecolor_hue)
if(0 to 20)
eyecolor_type = RED_EYES
if(21 to 50)
eyecolor_type = ORANGE_EYES
if(51 to 70)
eyecolor_type = YELLOW_EYES
if(71 to 160)
eyecolor_type = GREEN_EYES
if(161 to 260)
eyecolor_type = BLUE_EYES
if(261 to 340)
eyecolor_type = PURPLE_EYES
if(341 to 360)
eyecolor_type = RED_EYES
return eyecolor_type
/datum/species/shadekin/post_spawn_special(var/mob/living/carbon/human/H)
.=..()
var/eyecolor_type = get_shadekin_eyecolor(H)
var/datum/component/shadekin/SK = H.get_shadekin_component()
if(!SK)
CRASH("A shadekin [H] somehow is missing their shadekin component post-spawn!")
switch(eyecolor_type)
switch(SK.eye_color)
if(BLUE_EYES)
total_health = 100
energy_light = 0.5
energy_dark = 0.5
if(RED_EYES)
total_health = 200
energy_light = -1
energy_dark = 0.1
if(PURPLE_EYES)
total_health = 150
energy_light = -0.5
energy_dark = 1
if(YELLOW_EYES)
total_health = 100
energy_light = -2
energy_dark = 3
if(GREEN_EYES)
total_health = 100
energy_light = 0.125
energy_dark = 2
if(ORANGE_EYES)
total_health = 175
energy_light = -0.5
energy_dark = 0.25
H.maxHealth = total_health
H.health = H.getMaxHealth()
/datum/species/shadekin/produceCopy(var/list/traits, var/mob/living/carbon/human/H, var/custom_base, var/reset_dna = TRUE) // Traitgenes reset_dna flag required, or genes get reset on resleeve
var/datum/species/shadekin/new_copy = ..()
new_copy.total_health = total_health
new_copy.energy_light = energy_light
new_copy.energy_dark = energy_dark
return new_copy
@@ -1,364 +1,22 @@
/datum/power/shadekin
/mob/living/carbon/human/is_incorporeal()
if(ability_flags & AB_PHASE_SHIFTED) //Shadekin
var/datum/component/shadekin/SK = get_shadekin_component()
if(SK && SK.in_phase) //Shadekin
return TRUE
return ..()
/////////////////////
/// PHASE SHIFT ///
/////////////////////
//Visual effect for phase in/out
/obj/effect/temp_visual/shadekin
randomdir = FALSE
duration = 5
icon = 'icons/mob/vore_shadekin.dmi'
/obj/effect/temp_visual/shadekin/phase_in
icon_state = "tp_in"
/obj/effect/temp_visual/shadekin/phase_out
icon_state = "tp_out"
/datum/power/shadekin/phase_shift
name = "Phase Shift (100)"
desc = "Shift yourself out of alignment with realspace to travel quickly to different areas."
verbpath = /mob/living/carbon/human/proc/phase_shift
ability_icon_state = "tech_passwall"
/mob/living/carbon/human/proc/phase_shift()
set name = "Phase Shift (100)"
set desc = "Shift yourself out of alignment with realspace to travel quickly to different areas."
set category = "Abilities.Shadekin"
//RS Port #658 Start
var/area/A = get_area(src)
if(!client?.holder && A.flag_check(AREA_BLOCK_PHASE_SHIFT))
to_chat(src, span_warning("You can't do that here!"))
return
//RS Port #658 End
var/ability_cost = 100
var/darkness = 1
var/turf/T = get_turf(src)
if(!T)
to_chat(src,span_warning("You can't use that here!"))
return FALSE
if(ability_flags & AB_PHASE_SHIFTING)
return FALSE
var/brightness = T.get_lumcount() //Brightness in 0.0 to 1.0
darkness = 1-brightness //Invert
var/watcher = 0
for(var/mob/living/carbon/human/watchers in oview(7,src )) // If we can see them...
if(watchers in oviewers(7,src)) // And they can see us...
if(!(watchers.stat) && !isbelly(watchers.loc) && !istype(watchers.loc, /obj/item/holder)) // And they are alive and not being held by someone...
watcher++ // They are watching us!
ability_cost = CLAMP(ability_cost/(0.01+darkness*2),50, 80)//This allows for 1 watcher in full light
if(watcher>0)
ability_cost = ability_cost + ( 15 * watcher )
if(!(ability_flags & AB_PHASE_SHIFTED))
log_debug("[src] attempted to shift with [watcher] visible Carbons with a cost of [ability_cost] in a darkness level of [darkness]")
var/datum/species/shadekin/SK = species
if(!istype(SK))
to_chat(src, span_warning("Only a shadekin can use that!"))
return FALSE
else if(stat)
to_chat(src, span_warning("Can't use that ability in your state!"))
return FALSE
else if(SK.doing_phase)
to_chat(src, span_warning("You are already trying to phase!"))
return FALSE
else if(shadekin_get_energy() < ability_cost && !(ability_flags & AB_PHASE_SHIFTED))
to_chat(src, span_warning("Not enough energy for that ability!"))
return FALSE
if(!(ability_flags & AB_PHASE_SHIFTED))
shadekin_adjust_energy(-ability_cost)
playsound(src, 'sound/effects/stealthoff.ogg', 75, 1)
if(!T.CanPass(src,T) || loc != T)
to_chat(src,span_warning("You can't use that here!"))
return FALSE
SK.doing_phase = TRUE // Prevent bugs when spamming phase button
//Shifting in
if(ability_flags & AB_PHASE_SHIFTED)
phase_in(T)
//Shifting out
else
phase_out(T)
SK.doing_phase = FALSE // Prevent bugs when spamming phase button
/mob/living/carbon/human/proc/phase_in(var/turf/T)
if(ability_flags & AB_PHASE_SHIFTED)
// pre-change
forceMove(T)
var/original_canmove = canmove
SetStunned(0)
SetWeakened(0)
if(buckled)
buckled.unbuckle_mob()
if(pulledby)
pulledby.stop_pulling()
stop_pulling()
// change
canmove = FALSE
ability_flags &= ~AB_PHASE_SHIFTED
ability_flags |= AB_PHASE_SHIFTING
throwpass = FALSE
name = get_visible_name()
for(var/obj/belly/B as anything in vore_organs)
B.escapable = initial(B.escapable)
//cut_overlays()
invisibility = initial(invisibility)
see_invisible = initial(see_invisible)
incorporeal_move = initial(incorporeal_move)
density = initial(density)
force_max_speed = initial(force_max_speed)
update_icon()
//Cosmetics mostly
var/obj/effect/temp_visual/shadekin/phase_in/phaseanim = new /obj/effect/temp_visual/shadekin/phase_in(src.loc)
phaseanim.pixel_y = (src.size_multiplier - 1) * 16 // Pixel shift for the animation placement
phaseanim.adjust_scale(src.size_multiplier, src.size_multiplier)
phaseanim.dir = dir
alpha = 0
automatic_custom_emote(VISIBLE_MESSAGE,"phases in!")
addtimer(CALLBACK(src, PROC_REF(shadekin_complete_phase_in), original_canmove), 5, TIMER_DELETE_ME)
/mob/living/carbon/human/proc/shadekin_complete_phase_in(var/original_canmove)
canmove = original_canmove
alpha = initial(alpha)
remove_modifiers_of_type(/datum/modifier/shadekin_phase_vision)
//Potential phase-in vore
if(can_be_drop_pred) //Toggleable in vore panel
var/list/potentials = living_mobs(0)
if(potentials.len)
var/mob/living/target = pick(potentials)
if(istype(target) && target.devourable && target.can_be_drop_prey && target.phase_vore && vore_selected && phase_vore)
target.forceMove(vore_selected)
to_chat(target,span_vwarning("\The [src] phases in around you, [vore_selected.vore_verb]ing you into their [vore_selected.name]!"))
ability_flags &= ~AB_PHASE_SHIFTING
//Affect nearby lights
var/destroy_lights = 0
for(var/obj/machinery/light/L in GLOB.machines)
if(L.z != z || get_dist(src,L) > 10)
continue
if(prob(destroy_lights))
addtimer(CALLBACK(L, TYPE_PROC_REF(/obj/machinery/light, broken)), rand(5,25), TIMER_DELETE_ME)
else
L.flicker(10)
/mob/living/carbon/human/proc/phase_out(var/turf/T)
if(!(ability_flags & AB_PHASE_SHIFTED))
// pre-change
forceMove(T)
var/original_canmove = canmove
SetStunned(0)
SetWeakened(0)
if(buckled)
buckled.unbuckle_mob()
if(pulledby)
pulledby.stop_pulling()
stop_pulling()
canmove = FALSE
// change
ability_flags |= AB_PHASE_SHIFTED
ability_flags |= AB_PHASE_SHIFTING
throwpass = TRUE
automatic_custom_emote(VISIBLE_MESSAGE,"phases out!")
name = get_visible_name()
for(var/obj/belly/B as anything in vore_organs)
B.escapable = FALSE
var/obj/effect/temp_visual/shadekin/phase_out/phaseanim = new /obj/effect/temp_visual/shadekin/phase_out(src.loc)
phaseanim.pixel_y = (src.size_multiplier - 1) * 16 // Pixel shift for the animation placement
phaseanim.adjust_scale(src.size_multiplier, src.size_multiplier)
phaseanim.dir = dir
alpha = 0
add_modifier(/datum/modifier/shadekin_phase_vision)
sleep(5)
invisibility = INVISIBILITY_SHADEKIN
see_invisible = INVISIBILITY_SHADEKIN
see_invisible_default = INVISIBILITY_SHADEKIN // Allow seeing phased entities while phased.
//cut_overlays()
update_icon()
alpha = 127
canmove = original_canmove
incorporeal_move = TRUE
density = FALSE
force_max_speed = TRUE
ability_flags &= ~AB_PHASE_SHIFTING
/datum/modifier/shadekin_phase_vision
name = "Shadekin Phase Vision"
vision_flags = SEE_THRU
//////////////////////////
/// REGENERATE OTHER ///
//////////////////////////
/datum/power/shadekin/regenerate_other
name = "Regenerate Other (50)"
desc = "Spend energy to heal physical wounds in another creature."
verbpath = /mob/living/carbon/human/proc/regenerate_other
ability_icon_state = "tech_biomedaura"
/mob/living/carbon/human/proc/regenerate_other()
set name = "Regenerate Other (50)"
set desc = "Spend energy to heal physical wounds in another creature."
set category = "Abilities.Shadekin"
var/ability_cost = 50
var/datum/species/shadekin/SK = species
if(!istype(SK))
to_chat(src, span_warning("Only a shadekin can use that!"))
return FALSE
else if(stat)
to_chat(src, span_warning("Can't use that ability in your state!"))
return FALSE
else if(shadekin_get_energy() < ability_cost)
to_chat(src, span_warning("Not enough energy for that ability!"))
return FALSE
else if(ability_flags & AB_PHASE_SHIFTED)
to_chat(src, span_warning("You can't use that while phase shifted!"))
return FALSE
var/list/viewed = oview(1)
var/list/targets = list()
for(var/mob/living/L in viewed)
targets += L
if(!targets.len)
to_chat(src,span_warning("Nobody nearby to mend!"))
return FALSE
var/mob/living/target = tgui_input_list(src,"Pick someone to mend:","Mend Other", targets)
if(!target)
return FALSE
target.add_modifier(/datum/modifier/shadekin/heal_boop,1 MINUTE)
playsound(src, 'sound/effects/EMPulse.ogg', 75, 1)
shadekin_adjust_energy(-ability_cost)
visible_message(span_notice("\The [src] gently places a hand on \the [target]..."))
face_atom(target)
return TRUE
/datum/modifier/shadekin/heal_boop
name = "Shadekin Regen"
desc = "You feel serene and well rested."
mob_overlay_state = "green_sparkles"
on_created_text = span_notice("Sparkles begin to appear around you, and all your ills seem to fade away.")
on_expired_text = span_notice("The sparkles have faded, although you feel much healthier than before.")
stacks = MODIFIER_STACK_EXTEND
/datum/modifier/shadekin/heal_boop/tick()
if(!holder.getBruteLoss() && !holder.getFireLoss() && !holder.getToxLoss() && !holder.getOxyLoss() && !holder.getCloneLoss()) // No point existing if the spell can't heal.
expire()
return
holder.adjustBruteLoss(-2)
holder.adjustFireLoss(-2)
holder.adjustToxLoss(-2)
holder.adjustOxyLoss(-2)
holder.adjustCloneLoss(-2)
//////////////////////
/// CREATE SHADE ///
//////////////////////
/datum/power/shadekin/create_shade
name = "Create Shade (25)"
desc = "Create a field of darkness that follows you."
verbpath = /mob/living/carbon/human/proc/create_shade
ability_icon_state = "tech_dispelold"
/mob/living/carbon/human/proc/create_shade()
set name = "Create Shade (25)"
set desc = "Create a field of darkness that follows you."
set category = "Abilities.Shadekin"
var/ability_cost = 25
var/datum/species/shadekin/SK = species
if(!istype(SK))
to_chat(src, span_warning("Only a shadekin can use that!"))
return FALSE
else if(stat)
to_chat(src, span_warning("Can't use that ability in your state!"))
return FALSE
else if(shadekin_get_energy() < ability_cost)
to_chat(src, span_warning("Not enough energy for that ability!"))
return FALSE
else if(ability_flags & AB_PHASE_SHIFTED)
to_chat(src, span_warning("You can't use that while phase shifted!"))
return FALSE
playsound(src, 'sound/effects/bamf.ogg', 75, 1)
add_modifier(/datum/modifier/shadekin/create_shade,20 SECONDS)
shadekin_adjust_energy(-ability_cost)
return TRUE
/datum/modifier/shadekin/create_shade
name = "Shadekin Shadegen"
desc = "Darkness envelops you."
mob_overlay_state = ""
on_created_text = span_notice("You drag part of The Dark into realspace, enveloping yourself.")
on_expired_text = span_warning("You lose your grasp on The Dark and realspace reasserts itself.")
stacks = MODIFIER_STACK_EXTEND
var/mob/living/simple_mob/shadekin/my_kin
/datum/modifier/shadekin/create_shade/tick()
if(my_kin.ability_flags & AB_PHASE_SHIFTED)
expire()
/datum/modifier/shadekin/create_shade/on_applied()
my_kin = holder
holder.glow_toggle = TRUE
holder.glow_range = 8
holder.glow_intensity = -10
holder.glow_color = "#FFFFFF"
holder.set_light(8, -10, "#FFFFFF")
/datum/modifier/shadekin/create_shade/on_expire()
holder.glow_toggle = initial(holder.glow_toggle)
holder.glow_range = initial(holder.glow_range)
holder.glow_intensity = initial(holder.glow_intensity)
holder.glow_color = initial(holder.glow_color)
holder.set_light(0)
my_kin = null
// force dephase proc, to be called by other procs to dephase the shadekin. T is the target to force dephase them to.
/mob/living/carbon/human/proc/attack_dephase(var/turf/T = null, atom/dephaser)
var/datum/species/shadekin/SK = species
var/datum/component/shadekin/SK = get_shadekin_component()
if(!SK)
return FALSE
// no assigned dephase-target, just use our own
if(!T)
T = get_turf(src)
// make sure it's possible to be dephased (and we're in phase)
if(!istype(SK) || SK.doing_phase || !T.CanPass(src,T) || loc != T || !(ability_flags & AB_PHASE_SHIFTED) )
if(SK.doing_phase || !T.CanPass(src,T) || loc != T || !(SK.in_phase) )
return FALSE
@@ -366,6 +24,6 @@
message_admins("[key_name_admin(src)] was stunned out of phase at [T.x],[T.y],[T.z] by [dephaser.name], last touched by [dephaser.forensic_data?.get_lastprint()]. (<A href='byond://?_src_=holder;[HrefToken()];adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>JMP</a>)", 1)
// start the dephase
phase_in(T)
shadekin_adjust_energy(-20) // loss of energy for the interception
SK.shadekin_adjust_energy(-20) // loss of energy for the interception
// apply a little extra stun for good measure
src.Weaken(3)
@@ -26,6 +26,7 @@
/obj/screen/ability/verb_based/shadekin
icon_state = "grey_spell_base"
background_base_state = "grey"
icon = 'icons/mob/shadekin_abilities.dmi'
/obj/screen/movable/ability_master/proc/add_shadekin_ability(var/object_given, var/verb_given, var/name_given, var/ability_icon_given, var/arguments)
if(!object_given)
@@ -594,12 +594,11 @@
SEND_SIGNAL(H, COMSIG_XENOCHIMERA_COMPONENT)
//Shadekin Species Component.
/* //For when shadekin actually have their component control everything.
var/datum/component/shadekin/sk = H.get_xenochimera_component()
//For when shadekin actually have their component control everything.
var/datum/component/shadekin/sk = H.get_shadekin_component()
if(sk)
if(!H.stat || !(xc.revive_ready == REVIVING_NOW || xc.revive_ready == REVIVING_DONE))
if(!H.stat)
SEND_SIGNAL(H, COMSIG_SHADEKIN_COMPONENT)
*/
// Used to update alien icons for aliens.
/datum/species/proc/handle_login_special(var/mob/living/carbon/human/H)
@@ -153,14 +153,18 @@
/datum/unarmed_attack/claws/shadekin/apply_effects(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage)
..()
if(!(target == user))
user.shadekin_adjust_energy(attack_damage)
var/datum/component/shadekin/SK = user.get_shadekin_component()
if(SK)
SK.shadekin_adjust_energy(attack_damage)
/datum/unarmed_attack/bite/sharp/shadekin
/datum/unarmed_attack/bite/sharp/shadekin/apply_effects(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage)
..()
if(!(target == user))
user.shadekin_adjust_energy(attack_damage)
var/datum/component/shadekin/SK = user.get_shadekin_component()
if(SK)
SK.shadekin_adjust_energy(attack_damage)
/datum/unarmed_attack/claws/chimera //special feral attack that gets stronger as they get angrier
+10 -1
View File
@@ -18,6 +18,15 @@
selected_image = image(icon = GLOB.buildmode_hud, loc = src, icon_state = "ai_sel")
/mob/living/proc/get_visible_name()
var/datum/component/shadekin/SK = get_shadekin_component()
if(SK && SK.in_phase)
return "Something"
if(real_name)
return real_name
else
return name
/mob/living/Destroy()
SSradiation.listeners -= src
remove_all_modifiers(TRUE)
@@ -1257,7 +1266,7 @@
swap_hand()
/mob/living/throw_item(atom/target)
if(incapacitated() || !target || istype(target, /obj/screen))
if(incapacitated() || !target || istype(target, /obj/screen) || is_incorporeal())
return FALSE
var/atom/movable/item = src.get_active_hand()
@@ -345,9 +345,10 @@
if(get_dist(get_turf(T), get_turf(src)) > leap_distance) return
if(ishuman(T))
var/mob/living/carbon/human/H = T
if(H.get_species() == SPECIES_SHADEKIN && (H.ability_flags & AB_PHASE_SHIFTED))
if(isliving(T))
var/mob/living/M = T
var/datum/component/shadekin/SK = M.get_shadekin_component()
if(SK && SK.in_phase)
power_cost *= 2
if(!use_direct_power(power_cost, minimum_power - power_cost))
@@ -419,18 +419,18 @@
for(var/datum/matter_synth/our_synth in module.synths)
switch(our_synth.name)
if(METAL_SYNTH)
if(has_glass)
possible_synths[/obj/item/stack/material/cyborg/glass/reinforced] = list(our_synth, has_glass)
possible_synths += list(/obj/item/stack/material/cyborg/steel = list(our_synth))
possible_synths += list(/obj/item/stack/tile/floor/cyborg = list(our_synth))
possible_synths += list(/obj/item/stack/rods/cyborg = list(our_synth))
possible_synths += list(/obj/item/stack/tile/roofing/cyborg = list(our_synth))
if(has_glass)
possible_synths |= list(/obj/item/stack/material/cyborg/glass/reinforced = list(our_synth, has_glass))
if(PLASTEEL_SYNTH)
possible_synths += list(/obj/item/stack/material/cyborg/plasteel = list(our_synth))
if(GLASS_SYNTH)
possible_synths += list(/obj/item/stack/material/cyborg/glass = list(our_synth))
if(has_steel)
possible_synths |= list(/obj/item/stack/material/cyborg/glass/reinforced = list(our_synth, has_steel))
possible_synths[/obj/item/stack/material/cyborg/glass/reinforced] = list(our_synth, has_steel)
possible_synths += list(/obj/item/stack/material/cyborg/glass = list(our_synth))
if(WOOD_SYNTH)
possible_synths += list(/obj/item/stack/tile/wood/cyborg = list(our_synth))
possible_synths += list(/obj/item/stack/material/cyborg/wood = list(our_synth))
@@ -105,6 +105,8 @@
if(in_stasis)
return 1 // return early to skip atmos checks
if(is_incorporeal())
return 1
var/atom/A = src.loc
@@ -203,6 +203,11 @@
zone_sel.update_icon()
hud_elements |= zone_sel
//Component hud elements. Made in /mob/living/create_mob_hud
hud_elements |= shadekin_display
hud_elements |= xenochimera_danger_display
hud_elements |= lleill_display
//Hand things
if(has_hands)
//Drop button
@@ -105,7 +105,7 @@
density = FALSE
force_max_speed = TRUE
/mob/living/simple_mob/vore/demon/verb/phase_shift()
/mob/living/simple_mob/vore/demon/verb/demonic_phase_shift()
set name = "Phase Shift"
set desc = "Shift out of reality temporarily"
set category = "Abilities.Demon"
@@ -4,4 +4,4 @@
/mob/living/simple_mob/clowns/big/c_shift/Initialize(mapload)
. = ..()
add_verb(src, /mob/living/simple_mob/clowns/big/c_shift/proc/phase_shift)
comp = LoadComponent(comp)
@@ -1,92 +1,20 @@
/mob/living/simple_mob/clowns/big/c_shift
var/ability_flags = 0 //Flags for active abilities
// Phase shifting procs (and related procs)
/mob/living/simple_mob/clowns/big/c_shift/proc/phase_shift()
var/turf/T = get_turf(src)
if(!T.CanPass(src,T) || loc != T)
to_chat(src,span_warning("You can't use that here!"))
return FALSE
forceMove(T)
var/original_canmove = canmove
SetStunned(0)
SetWeakened(0)
if(buckled)
buckled.unbuckle_mob()
if(pulledby)
pulledby.stop_pulling()
stop_pulling()
canmove = FALSE
//Shifting in
if(ability_flags & AB_PHASE_SHIFTED)
ability_flags &= ~AB_PHASE_SHIFTED
mouse_opacity = 2
name = real_name
cut_overlays()
alpha = initial(alpha)
invisibility = initial(invisibility)
see_invisible = initial(see_invisible)
incorporeal_move = initial(incorporeal_move)
density = initial(density)
force_max_speed = initial(force_max_speed)
//Cosmetics mostly
flick("tp_in",src)
automatic_custom_emote(VISIBLE_MESSAGE,"phases in!")
sleep(5) //The duration of the TP animation
canmove = original_canmove
// Do this after the potential vore, so we get the belly
update_icon()
//Affect nearby lights
for(var/obj/machinery/light/L in GLOB.machines)
if(L.z != z || get_dist(src,L) > 10)
continue
L.flicker(10)
//Shifting out
else
ability_flags |= AB_PHASE_SHIFTED
mouse_opacity = 0
automatic_custom_emote(VISIBLE_MESSAGE,"phases out!")
real_name = name
name = "Something"
cut_overlays()
flick("tp_out",src)
sleep(5)
invisibility = INVISIBILITY_LEVEL_TWO
see_invisible = INVISIBILITY_LEVEL_TWO
update_icon()
alpha = 127
canmove = original_canmove
incorporeal_move = TRUE
density = FALSE
force_max_speed = TRUE
var/datum/component/shadekin/comp = /datum/component/shadekin/phase_only //Component that holds all the shadekin vars.
/mob/living/simple_mob/clowns/big/c_shift/UnarmedAttack()
if(ability_flags & AB_PHASE_SHIFTED)
if(comp.in_phase)
return FALSE //Nope.
. = ..()
/mob/living/simple_mob/clowns/big/c_shift/can_fall()
if(ability_flags & AB_PHASE_SHIFTED)
if(comp.in_phase)
return FALSE //Nope!
return ..()
/mob/living/simple_mob/clowns/big/c_shift/zMove(direction)
if(ability_flags & AB_PHASE_SHIFTED)
if(comp.in_phase)
var/turf/destination = (direction == UP) ? GetAbove(src) : GetBelow(src)
if(destination)
forceMove(destination)
@@ -20,10 +20,9 @@
/obj/effect/shadekin_ability/proc/atom_button_text()
var/shift_denial
if(shift_mode == NOT_WHILE_SHIFTED && (my_kin.ability_flags & AB_PHASE_SHIFTED))
if(shift_mode == NOT_WHILE_SHIFTED && my_kin.comp.in_phase)
shift_denial = "Physical Only"
else if(shift_mode == ONLY_WHILE_SHIFTED && !(my_kin.ability_flags & AB_PHASE_SHIFTED))
else if(shift_mode == ONLY_WHILE_SHIFTED && !(my_kin.comp.in_phase))
shift_denial = "Shifted Only"
if(shift_denial)
@@ -47,10 +46,10 @@
if(my_kin.stat)
to_chat(my_kin,span_warning("Can't use that ability in your state!"))
return FALSE
if(shift_mode == NOT_WHILE_SHIFTED && (my_kin.ability_flags & AB_PHASE_SHIFTED))
if(shift_mode == NOT_WHILE_SHIFTED && (my_kin.comp.in_phase))
to_chat(my_kin,span_warning("Can't use that ability while phase shifted!"))
return FALSE
else if(shift_mode == ONLY_WHILE_SHIFTED && !(my_kin.ability_flags & AB_PHASE_SHIFTED))
else if(shift_mode == ONLY_WHILE_SHIFTED && !(my_kin.comp.in_phase))
to_chat(my_kin,span_warning("Can only use that ability while phase shifted!"))
return FALSE
else if(my_kin.comp.dark_energy < cost)
@@ -75,7 +74,7 @@
if(!..())
return
my_kin.phase_shift()
if(my_kin.ability_flags & AB_PHASE_SHIFTED)
if(my_kin.comp.in_phase)
cost = 0 //Shifting back is free (but harmful in light)
else
cost = initial(cost)
@@ -136,7 +135,7 @@
var/mob/living/simple_mob/shadekin/my_kin
/datum/modifier/shadekin/create_shade/tick()
if(my_kin.ability_flags & AB_PHASE_SHIFTED)
if(my_kin.comp.in_phase)
expire()
/datum/modifier/shadekin/create_shade/on_applied()
@@ -1,15 +1,13 @@
// Phase shifting procs (and related procs)
/mob/living/simple_mob/shadekin/proc/phase_shift()
/mob/living/simple_mob/shadekin/phase_shift()
var/turf/T = get_turf(src)
var/area/A = T.loc //RS Port #658
var/area/A = T.loc
if(!T.CanPass(src,T) || loc != T)
to_chat(src,span_warning("You can't use that here!"))
return FALSE
//RS Port #658 Start
if(!client?.holder && A.flag_check(AREA_BLOCK_PHASE_SHIFT))
to_chat(src,span_warning("You can't use that here!"))
return FALSE
//RS Port #658 End
else if(doing_phase)
to_chat(src, span_warning("You are already trying to phase!"))
@@ -17,133 +15,27 @@
doing_phase = TRUE
//Shifting in
if(ability_flags & AB_PHASE_SHIFTED)
if(comp.in_phase)
phase_in(T)
//Shifting out
else
phase_out(T)
doing_phase = FALSE
/mob/living/simple_mob/shadekin/proc/phase_in(var/turf/T)
if(ability_flags & AB_PHASE_SHIFTED)
// pre-change
forceMove(T)
var/original_canmove = canmove
SetStunned(0)
SetWeakened(0)
if(buckled)
buckled.unbuckle_mob()
if(pulledby)
pulledby.stop_pulling()
stop_pulling()
canmove = FALSE
// change
ability_flags &= ~AB_PHASE_SHIFTED
throwpass = FALSE
name = real_name
for(var/obj/belly/B as anything in vore_organs)
B.escapable = initial(B.escapable)
cut_overlays()
alpha = initial(alpha)
invisibility = initial(invisibility)
see_invisible = initial(see_invisible)
incorporeal_move = initial(incorporeal_move)
density = initial(density)
force_max_speed = initial(force_max_speed)
//Cosmetics mostly
flick("tp_in",src)
automatic_custom_emote(VISIBLE_MESSAGE,"phases in!")
addtimer(CALLBACK(src, PROC_REF(shadekin_complete_phase_in), original_canmove), 5, TIMER_DELETE_ME)
/mob/living/simple_mob/shadekin/proc/shadekin_complete_phase_in(var/original_canmove)
canmove = original_canmove
//Potential phase-in vore
if(can_be_drop_pred) //Toggleable in vore panel
var/list/potentials = living_mobs(0)
if(potentials.len)
var/mob/living/target = pick(potentials)
if(istype(target) && target.devourable && target.can_be_drop_prey && vore_selected)
target.forceMove(vore_selected)
to_chat(target,span_vwarning("\The [src] phases in around you, [vore_selected.vore_verb]ing you into their [vore_selected.name]!"))
// Do this after the potential vore, so we get the belly
update_icon()
//Affect nearby lights
var/destroy_lights = 0
if(eye_state == RED_EYES)
destroy_lights = 80
if(eye_state == PURPLE_EYES)
destroy_lights = 25
for(var/obj/machinery/light/L in GLOB.machines)
if(L.z != z || get_dist(src,L) > 10)
continue
if(prob(destroy_lights))
addtimer(CALLBACK(L, TYPE_PROC_REF(/obj/machinery/light, broken)), rand(5,25), TIMER_DELETE_ME)
else
L.flicker(10)
/mob/living/simple_mob/shadekin/proc/phase_out(var/turf/T)
if(!(ability_flags & AB_PHASE_SHIFTED))
// pre-change
forceMove(T)
var/original_canmove = canmove
SetStunned(0)
SetWeakened(0)
if(buckled)
buckled.unbuckle_mob()
if(pulledby)
pulledby.stop_pulling()
stop_pulling()
canmove = FALSE
// change
ability_flags |= AB_PHASE_SHIFTED
throwpass = TRUE
automatic_custom_emote(VISIBLE_MESSAGE,"phases out!")
real_name = name
name = "Something"
for(var/obj/belly/B as anything in vore_organs)
B.escapable = FALSE
cut_overlays()
flick("tp_out",src)
sleep(5)
invisibility = INVISIBILITY_LEVEL_TWO
see_invisible = INVISIBILITY_LEVEL_TWO
update_icon()
alpha = 127
canmove = original_canmove
incorporeal_move = TRUE
density = FALSE
force_max_speed = TRUE
/mob/living/simple_mob/shadekin/UnarmedAttack()
if(ability_flags & AB_PHASE_SHIFTED)
if(comp.in_phase)
return FALSE //Nope.
. = ..()
/mob/living/simple_mob/shadekin/can_fall()
if(ability_flags & AB_PHASE_SHIFTED)
if(comp.in_phase)
return FALSE //Nope!
return ..()
/mob/living/simple_mob/shadekin/zMove(direction)
if(ability_flags & AB_PHASE_SHIFTED)
if(comp.in_phase)
var/turf/destination = (direction == UP) ? GetAbove(src) : GetBelow(src)
if(destination)
forceMove(destination)
@@ -71,8 +71,6 @@
var/datum/component/shadekin/comp = /datum/component/shadekin //Component that holds all the shadekin vars.
var/dark_gains = 0 //Last tick's change in energy
var/ability_flags = 0 //Flags for active abilities
var/obj/screen/darkhud //Holder to update this icon
var/obj/screen/energyhud //Holder to update this icon
var/list/shadekin_abilities
var/check_for_observer = FALSE
@@ -97,6 +95,7 @@
flags |= ATOM_INITIALIZED
return INITIALIZE_HINT_QDEL
comp = LoadComponent(comp)
set_eye_energy()
if(icon_state == "map_example")
icon_state = pick("white","dark","brown")
@@ -201,7 +200,7 @@
/mob/living/simple_mob/shadekin/Life()
. = ..()
if(ability_flags & AB_PHASE_SHIFTED)
if(comp.in_phase)
density = FALSE
//Convert spare nutrition into energy at a certain ratio
@@ -215,9 +214,9 @@
if(!issimplekin(M))
non_kin_count ++
// Technically can be combined with ||, they call the same function, but readability is poor
if(!non_kin_count && (ability_flags & AB_PHASE_SHIFTED))
if(!non_kin_count && (comp.in_phase))
phase_shift() // shifting back in, nobody present
else if (non_kin_count && !(ability_flags & AB_PHASE_SHIFTED))
else if (non_kin_count && !(comp.in_phase))
phase_shift() // shifting out, scaredy
/mob/living/simple_mob/shadekin/update_icon()
@@ -248,13 +247,89 @@
//They phase back to the dark when killed
/mob/living/simple_mob/shadekin/death(gibbed, deathmessage = "phases to somewhere far away!")
cut_overlays()
icon_state = ""
flick("tp_out",src)
spawn(1 SECOND)
qdel(src) //Back from whence you came!
var/special_handling = FALSE //varswitch for downstream
if(!special_handling)
cut_overlays()
icon_state = ""
flick("tp_out",src)
QDEL_IN(src, 1 SECOND)
. = ..(FALSE, deathmessage)
else
if(comp.respite_activating)
return
cut_overlays()
flick("tp_out",src)
var/area/current_area = get_area(src)
if((comp.in_dark_respite) || current_area.flag_check(AREA_LIMIT_DARK_RESPITE))
icon_state = ""
spawn(1 SECOND)
qdel(src) //Back from whence you came!
return ..(FALSE, deathmessage)
if(!LAZYLEN(GLOB.latejoin_thedark))
log_and_message_admins("[src] died outside of the dark but there were no valid floors to warp to")
icon_state = ""
spawn(1 SECOND)
qdel(src) //Back from whence you came!
return ..(FALSE, deathmessage)
visible_message("<b>\The [src.name]</b> [deathmessage]")
comp.respite_activating = TRUE
drop_l_hand()
drop_r_hand()
comp.dark_energy = 0
comp.in_dark_respite = TRUE
invisibility = INVISIBILITY_LEVEL_TWO
adjustFireLoss(-(getFireLoss() / 2))
adjustBruteLoss(-(getBruteLoss() / 2))
adjustToxLoss(-(getToxLoss() / 2))
Stun(10)
movement_cooldown = 5
nutrition = 0
if(istype(src.loc, /obj/belly))
//Yay digestion... presumably...
var/obj/belly/belly = src.loc
add_attack_logs(belly.owner, src, "Digested in [lowertext(belly.name)]")
to_chat(belly.owner, span_notice("\The [src.name] suddenly vanishes within your [belly.name]"))
forceMove(pick(GLOB.latejoin_thedark))
flick("tp_in",src)
comp.respite_activating = FALSE
comp.in_dark_respite = TRUE
belly.owner.handle_belly_update()
clear_fullscreen("belly")
if(hud_used)
if(!hud_used.hud_shown)
toggle_hud_vis()
stop_sound_channel(CHANNEL_PREYLOOP)
addtimer(CALLBACK(src, PROC_REF(can_leave_dark)), 10 MINUTES, TIMER_DELETE_ME)
else
addtimer(CALLBACK(src, PROC_REF(enter_the_dark)), 1 SECOND, TIMER_DELETE_ME)
addtimer(CALLBACK(src, PROC_REF(can_leave_dark)), 15 MINUTES, TIMER_DELETE_ME)
/mob/living/simple_mob/shadekin/proc/enter_the_dark()
comp.respite_activating = FALSE
comp.in_dark_respite = TRUE
forceMove(pick(GLOB.latejoin_thedark))
update_icon()
flick("tp_in",src)
invisibility = initial(invisibility)
comp.respite_activating = FALSE
/mob/living/simple_mob/shadekin/proc/can_leave_dark()
comp.in_dark_respite = FALSE
movement_cooldown = initial(movement_cooldown)
to_chat(src, span_notice("You feel like you can leave the Dark again"))
. = ..(FALSE, deathmessage)
/* //VOREStation AI Temporary Removal
//Blue-eyes want to nom people to heal them
@@ -270,97 +345,34 @@
//They reach nutritional equilibrium (important for blue-eyes healbelly)
/mob/living/simple_mob/shadekin/Life()
if((. = ..()))
handle_shade()
comp.handle_comp()
/mob/living/simple_mob/shadekin/proc/set_eye_energy()
switch(eye_state)
//Blue has constant, steady (slow) regen and ignores darkness.
if(BLUE_EYES)
comp.set_light_and_darkness(0.75,0.75)
if(RED_EYES)
comp.set_light_and_darkness(-0.5,0.5)
if(PURPLE_EYES)
comp.set_light_and_darkness(-0.5,1)
if(YELLOW_EYES)
comp.set_light_and_darkness(-2,3)
if(GREEN_EYES)
comp.set_light_and_darkness(0.125,2)
if(ORANGE_EYES)
comp.set_light_and_darkness(-0.25,0.75)
/mob/living/simple_mob/shadekin/is_incorporeal()
if(ability_flags & AB_PHASE_SHIFTED)
if(comp.in_phase)
return TRUE
return FALSE
/mob/living/simple_mob/shadekin/handle_atmos()
if(ability_flags & AB_PHASE_SHIFTED)
if(comp.in_phase)
return
else
return .=..()
/mob/living/simple_mob/shadekin/proc/handle_shade()
//Shifted kin don't gain/lose energy (and save time if we're at the cap)
var/darkness = 1
var/turf/T = get_turf(src)
if(!T)
dark_gains = 0
return
var/brightness = T.get_lumcount() //Brightness in 0.0 to 1.0
darkness = 1-brightness //Invert
if(ability_flags & AB_PHASE_SHIFTED)
dark_gains = 0
else
//Heal (very) slowly in good darkness
if(darkness >= 0.75)
adjustFireLoss(-0.05)
adjustBruteLoss(-0.05)
adjustToxLoss(-0.05)
switch(eye_state)
//Blue has constant, steady (slow) regen and ignores darkness.
if(BLUE_EYES)
dark_gains = 0.5
//Red has extremely tiny energy buildup in dark, none in light, and hunts for energy.
if(RED_EYES)
if(darkness >= 0.75)
dark_gains = 0.25
//Purple eyes have moderate gains in darkness and loss in light.
if(PURPLE_EYES)
dark_gains = round((darkness - 0.5) * 2, 0.1)
//Yellow has extreme gains in darkness and loss in light.
if(YELLOW_EYES)
dark_gains = round((darkness - 0.5) * 4, 0.1)
//Similar to blues, but passive is less, and affected by dark
if(GREEN_EYES)
dark_gains = 0.25
dark_gains += round((darkness - 0.5), 0.1)
//More able to get energy out of the dark, worse attack gains tho
if(ORANGE_EYES)
if(darkness >= 0.65)
dark_gains = 0.30
comp.dark_energy = max(0,min(initial(comp.dark_energy),comp.dark_energy + dark_gains))
if(comp.dark_energy_infinite)
comp.dark_energy = 100
//Update turf darkness hud
if(darkhud)
switch(darkness)
if(0.80 to 1.00)
darkhud.icon_state = "dark2"
if(0.60 to 0.80)
darkhud.icon_state = "dark1"
if(0.40 to 0.60)
darkhud.icon_state = "dark"
if(0.20 to 0.40)
darkhud.icon_state = "dark-1"
if(0.00 to 0.20)
darkhud.icon_state = "dark-2"
//Update energy storage hud
if(energyhud)
switch(comp.dark_energy)
if(80 to INFINITY)
energyhud.icon_state = "energy0"
if(60 to 80)
energyhud.icon_state = "energy1"
if(40 to 60)
energyhud.icon_state = "energy2"
if(20 to 40)
energyhud.icon_state = "energy3"
if(0 to 20)
energyhud.icon_state = "energy4"
/* //VOREStation AI Removal
//Friendly ones wander towards people, maybe shy-ly if they are set to shy
/mob/living/simple_mob/shadekin/handle_wander_movement()
@@ -443,26 +455,6 @@
comp.dark_energy += gains
//Special hud elements for darkness and energy gains
/mob/living/simple_mob/shadekin/extra_huds(var/datum/hud/hud,var/icon/ui_style,var/list/hud_elements)
//Darkness hud
darkhud = new /obj/screen()
darkhud.icon = ui_style
darkhud.icon_state = "dark"
darkhud.name = "darkness"
darkhud.screen_loc = "CENTER-2:16,SOUTH:5" //Left of the left hand
darkhud.alpha = 150
hud_elements |= darkhud
//Energy hud
energyhud = new /obj/screen()
energyhud.icon = ui_style
energyhud.icon_state = "energy0"
energyhud.name = "energy"
energyhud.screen_loc = "CENTER+1:16,SOUTH:5" //Right of the right hand
energyhud.alpha = 150
hud_elements |= energyhud
// When someone clicks us with an empty hand
/mob/living/simple_mob/shadekin/attack_hand(mob/living/carbon/human/M as mob)
. = ..()