Minor fixes (#17966)

* Stops some abilities from being done in VR

* yeh

* Update comp_helpers.dm

* anti exploit

* i am speed

* Update areas.dm

* Update areas.dm

* Update dark_tunneling.dm

* get rid of these unused abilities

incompatible with new system.

* forgot the human handling whoops

* byeeee

* Update shadekin.dm

* voucher qdel fix

* nutriment

* Update shadekin.dm

* mooore

* Update shadekin.dm

* yea

* Update comp_helpers.dm

* more fixes

* bunch of fixes

* type and default

* dynamic

* store settings

* .

---------

Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
This commit is contained in:
Cameron Lennox
2025-07-08 19:11:11 -07:00
committed by GitHub
co-authored by Kashargul
parent df8cf1c0fd
commit 41ce944736
24 changed files with 531 additions and 284 deletions
@@ -50,28 +50,35 @@
//Blue has constant, steady (slow) regen and ignores darkness.
if(BLUE_EYES)
set_light_and_darkness(0.75,0.75)
nutrition_conversion_scaling = 0.5
if(RED_EYES)
set_light_and_darkness(-0.5,0.5)
nutrition_conversion_scaling = 2
if(PURPLE_EYES)
set_light_and_darkness(-0.5,1)
nutrition_conversion_scaling = 1
if(YELLOW_EYES)
set_light_and_darkness(-2,3)
nutrition_conversion_scaling = 0.5
if(GREEN_EYES)
set_light_and_darkness(0.125,2)
nutrition_conversion_scaling = 0.5
if(ORANGE_EYES)
set_light_and_darkness(-0.25,0.75)
nutrition_conversion_scaling = 1.5
///Sets our eye color.
/datum/component/shadekin/proc/set_shadekin_eyecolor(var/mob/living/carbon/human/H)
/datum/component/shadekin/proc/set_shadekin_eyecolor()
if(!ishuman(owner))
return eye_color //revert to default if we're not a human
else
H = owner
var/mob/living/carbon/human/H = owner
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]
var/list/hsv_color = rgb2num(eyecolor_rgb, COLORSPACE_HSV)
var/eyecolor_hue = hsv_color[1]
var/eyecolor_sat = hsv_color[2]
var/eyecolor_val = hsv_color[3]
//First, clamp the saturation/value to prevent black/grey/white eyes
if(eyecolor_sat < 10)
@@ -81,9 +88,10 @@
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]
var/list/rgb_color = rgb2num(eyecolor_rgb)
H.r_eyes = rgb_color[1]
H.g_eyes = rgb_color[2]
H.b_eyes = rgb_color[3]
//Now determine what color we fall into.
switch(eyecolor_hue)
@@ -159,3 +167,47 @@
if(!isnum(amount))
return //No
shadekin_set_energy(dark_energy + amount)
/datum/component/shadekin/proc/handle_nutrition_conversion(dark_gains)
if(!nutrition_energy_conversion)
return
if(shadekin_get_energy() == 100 && dark_gains > 0)
owner.nutrition += dark_gains * 5 * nutrition_conversion_scaling
else if(shadekin_get_energy() < 50 && owner.nutrition > 500)
owner.nutrition -= nutrition_conversion_scaling * 50
dark_gains += nutrition_conversion_scaling
/datum/component/shadekin/proc/attack_dephase(var/turf/T = null, atom/dephaser)
// no assigned dephase-target, just use our own
if(!T)
T = get_turf(owner)
if(!in_phase || doing_phase)
return FALSE
// make sure it's possible to be dephased (and we're in phase)
if(!T || !T.CanPass(owner,T))
return FALSE
log_admin("[key_name_admin(owner)] was stunned out of phase at [T.x],[T.y],[T.z] by [dephaser.name], last touched by [dephaser.forensic_data?.get_lastprint()].")
message_admins("[key_name_admin(owner)] 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
owner.phase_in(T, src)
shadekin_adjust_energy(-20) // loss of energy for the interception
// apply a little extra stun for good measure
owner.Weaken(3)
/mob/living/carbon/human/is_incorporeal()
var/datum/component/shadekin/SK = get_shadekin_component()
if(SK && SK.in_phase) //Shadekin
return TRUE
return ..()
///Proc that takes in special considerations, such as 'no abilities in VR' and the such
///Returns TRUE if we try to do something forbidden
/datum/component/shadekin/proc/special_considerations(allow_vr)
if(!allow_vr && istype(get_area(owner), /area/vr))
to_chat(owner, span_danger("The VR systems cannot comprehend this power! This is useless to you!"))
return TRUE
return FALSE
@@ -18,6 +18,8 @@
if(!istype(SK))
to_chat(src, span_warning("Only a shadekin can use that!"))
return FALSE
else if(SK.special_considerations(TRUE))
return FALSE
else if(stat)
to_chat(src, span_warning("Can't use that ability in your state!"))
return FALSE
@@ -14,6 +14,8 @@
var/datum/component/shadekin/SK = get_shadekin_component()
if(!SK)
return FALSE
if(SK.special_considerations())
return FALSE
if(stat)
to_chat(src, span_warning("Can't use that ability in your state!"))
return FALSE
@@ -14,6 +14,8 @@
var/datum/component/shadekin/SK = get_shadekin_component()
if(!SK)
return FALSE
if(SK.special_considerations())
return FALSE
if(stat)
to_chat(src, span_warning("Can't use that ability in your state!"))
return FALSE
@@ -20,6 +20,8 @@
var/datum/component/shadekin/SK = get_shadekin_component()
if(!SK)
return FALSE
if(SK.special_considerations())
return FALSE
if(stat)
to_chat(src, span_warning("Can't use that ability in your state!"))
return FALSE
@@ -63,6 +65,9 @@
src.visible_message(span_notice("[src] begins pulling dark energies around themselves."))
if(do_after(src, tunnel_time))
if(SK.created_dark_tunnel) //check again because the user may have queued this up multiple times.
to_chat(src, span_warning("You have already made a tunnel to the Dark!"))
return FALSE
playsound(src, 'sound/effects/phasein.ogg', 100, 1)
src.visible_message(span_notice("[src] finishes pulling dark energies around themselves, creating a portal."))
@@ -27,6 +27,8 @@
var/datum/component/shadekin/SK = get_shadekin_component()
if(!SK)
return FALSE
if(SK.special_considerations())
return FALSE
if(stat)
to_chat(src, span_warning("Can't use that ability in your state!"))
return FALSE
@@ -50,10 +52,24 @@
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!
for(var/mob/living/thing in orange(7, src)) //Fun fact, doing two typed loops is faster than doing one untyped loop. Check it with Tracy!
if(istype(thing, /mob/living/carbon/human))
var/mob/living/carbon/human/watchers = thing
if(watchers in oviewers(7,src))
var/datum/component/shadekin/watcher_SK = watchers.get_shadekin_component()
if(!watcher_SK && !(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!
if(istype(thing, /mob/living/silicon/robot))
var/mob/living/silicon/robot/watchers = thing
var/datum/component/shadekin/watcher_SK = watchers.get_shadekin_component() //you never know, man.
if(watchers in oviewers(7,src))
if(!watcher_SK && !watchers.stat && !isbelly(watchers.loc))
watcher++ //The robot is watching us!
if(SK.camera_counts_as_watcher)
for(var/obj/machinery/camera/watchers in orange(7, src))
if(watchers.can_use())
if(src in watchers.can_see())
watcher++ //The camera is watching us!
ability_cost = CLAMP(ability_cost/(0.01+darkness*2),50, 80)//This allows for 1 watcher in full light
if(watcher>0)
@@ -85,7 +101,6 @@
else
phase_out(T, SK)
/mob/living/proc/phase_in(var/turf/T, var/datum/component/shadekin/SK)
if(SK.in_phase)
@@ -163,6 +178,8 @@
held_lights.update_brightness()
SK.doing_phase = FALSE
if(SK.flicker_time < 5 || SK.flicker_distance < 5 || SK.flicker_break_chance < 5)
Stun(SK.calculate_stun())
if(!SK.flicker_time)
return //Early return. No time, no flickering.
//Affect nearby lights
@@ -17,6 +17,8 @@
var/datum/component/shadekin/SK = get_shadekin_component()
if(!SK)
return FALSE
if(SK.special_considerations(TRUE))
return FALSE
if(stat)
to_chat(src, span_warning("Can't use that ability in your state!"))
return FALSE
@@ -38,6 +38,8 @@
var/normal_phase = TRUE
///If we drop items on phase.
var/drop_items_on_phase = FALSE
///If cameras count as watchers for us
var/camera_counts_as_watcher = FALSE
//Dark Respite Vars (Unused on Virgo)
///If we are in dark respite or not
@@ -56,8 +58,8 @@
//Ability Vars
///The innate abilities we start with
var/list/shadekin_abilities = list(/datum/power/shadekin/phase_shift,
/datum/power/shadekin/regenerate_other,
/datum/power/shadekin/create_shade)
/datum/power/shadekin/regenerate_other,
/datum/power/shadekin/create_shade)
///Datum holder. Largely ignore this.
var/list/shadekin_ability_datums = list()
@@ -72,13 +74,14 @@
/datum/component/shadekin/full
shadekin_abilities = list(/datum/power/shadekin/phase_shift,
/datum/power/shadekin/regenerate_other,
/datum/power/shadekin/create_shade,
/datum/power/shadekin/dark_maw,
/datum/power/shadekin/dark_respite,
/datum/power/shadekin/dark_tunneling)
/datum/power/shadekin/regenerate_other,
/datum/power/shadekin/create_shade,
/datum/power/shadekin/dark_maw,
/datum/power/shadekin/dark_respite,
/datum/power/shadekin/dark_tunneling)
extended_kin = TRUE
drop_items_on_phase = TRUE
camera_counts_as_watcher = TRUE
/datum/component/shadekin/full/rakshasa
flicker_time = 0 //Rakshasa don't flicker lights when they phase in.
@@ -132,6 +135,10 @@
owner = null
. = ..()
/datum/component/shadekin/proc/recalc_values()
set_shadekin_eyecolor() //Gets what eye color we are.
set_eye_energy() //Sets the energy values based on our eye color.
///Handles the component running.
/datum/component/shadekin/proc/handle_comp()
SIGNAL_HANDLER
@@ -172,11 +179,74 @@
else
dark_gains = energy_light
handle_nutrition_conversion(dark_gains)
shadekin_adjust_energy(dark_gains)
//Update huds
update_shadekin_hud()
/datum/component/shadekin/proc/calculate_stun()
var/stun_time = 3
if(flicker_time > 0)
stun_time -= min(flicker_time / 5, 1)
if(flicker_distance > 0)
stun_time -= min(flicker_distance / 5, 1)
if(flicker_break_chance > 0)
stun_time -= min(flicker_break_chance / 5, 1)
return stun_time
/datum/component/shadekin/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "ShadekinConfig", "Shadekin Config")
ui.open()
/datum/component/shadekin/tgui_data(mob/user)
var/data = list(
"stun_time" = calculate_stun(),
"flicker_time" = flicker_time,
"flicker_color" = flicker_color,
"flicker_break_chance" = flicker_break_chance,
"flicker_distance" = flicker_distance,
)
return data
/datum/component/shadekin/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
if(..())
return TRUE
switch(action)
if("adjust_time")
var/new_time = text2num(params["val"])
if(!isnum(new_time))
return FALSE
flicker_time = new_time
ui.user.write_preference_directly(/datum/preference/numeric/living/flicker_time, new_time)
return TRUE
if("adjust_color")
var/set_new_color = tgui_color_picker(ui.user, "Select a color you wish the lights to flicker as (Default is #E0EFF0)", "Color Selector", flicker_color)
if(!set_new_color)
return FALSE
flicker_color = set_new_color
ui.user.write_preference_directly(/datum/preference/color/living/flicker_color, set_new_color)
return TRUE
if("adjust_break")
var/new_brack_chance = text2num(params["val"])
if(!isnum(new_brack_chance))
return FALSE
flicker_break_chance = new_brack_chance
ui.user.write_preference_directly(/datum/preference/numeric/living/flicker_break_chance, new_brack_chance)
return TRUE
if("adjust_distance")
var/new_distance = text2num(params["val"])
if(!isnum(new_distance))
return FALSE
flicker_distance = new_distance
ui.user.write_preference_directly(/datum/preference/numeric/living/flicker_distance, new_distance)
return TRUE
/mob/living/proc/nutrition_conversion_toggle()
set name = "Toggle Energy <-> Nutrition conversions"
@@ -204,21 +274,5 @@
if(!SK)
to_chat(src, span_warning("Only a shadekin can use that!"))
return FALSE
var/flicker_timer = tgui_input_number(src, "Adjust how long lights flicker when you phase in! (Min 10 Max 20 times!)", "Set Flicker", SK.flicker_time, 20, 10)
if(flicker_timer > 20 || flicker_timer < 10)
to_chat(src,"<span class='warning'>You must choose a number between 10 and 20</span>")
return
SK.flicker_time = flicker_timer
to_chat(src,"<span class='warning'>Flicker timer set to [SK.flicker_time] seconds!</span>")
var/set_new_color = tgui_color_picker(src,"Select a color you wish the lights to flicker as (Default is #E0EFF0)","Color Selector", SK.flicker_color)
if(set_new_color)
SK.flicker_color = set_new_color
to_chat(src,"<span class='warning'>Flicker color set to [SK.flicker_color]!</span>")
var/break_chance = tgui_input_number(src, "Adjust the % chance for lights to break when you phase in! (Default 0. Min 0. Max 25)", "Set Break Chance", 0, 25, 0)
if(break_chance > 25 || break_chance < 0)
to_chat(src,"<span class='warning'>You must choose a number between 0 and 25</span>")
return
SK.flicker_break_chance = break_chance
to_chat(src,"<span class='warning'>Break chance set to [SK.flicker_break_chance]%</span>")
SK.tgui_interact(src)