mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 10:12:45 +00:00
Co-authored-by: Cameron Lennox <killer65311@gmail.com> Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
290 lines
9.9 KiB
Plaintext
290 lines
9.9 KiB
Plaintext
//See comp_helpers.dm for helper procs.
|
|
/datum/component/shadekin
|
|
VAR_PRIVATE/mob/living/owner
|
|
dupe_mode = COMPONENT_DUPE_UNIQUE
|
|
|
|
//Energy Vars
|
|
///How much energy we have RIGHT NOW
|
|
var/dark_energy = 100
|
|
///How much energy we can have
|
|
var/max_dark_energy = 100
|
|
///Always be at our max_dark_energy
|
|
var/dark_energy_infinite = FALSE
|
|
///How much energy we generate in the dark
|
|
var/energy_dark = 0.75
|
|
///How much energy we generate in the light
|
|
var/energy_light = 0.25
|
|
///If we care about eye color when it comes to factoring in energy
|
|
var/eye_color_influences_energy = TRUE
|
|
///Energy gain from nutrition
|
|
var/nutrition_conversion_scaling = 0.5
|
|
///If we convert nutrition to energy
|
|
var/nutrition_energy_conversion = FALSE
|
|
|
|
//Phase Vars
|
|
///Are we currently in a phase transition?
|
|
var/doing_phase = FALSE
|
|
///Are we currently phased?
|
|
var/in_phase = FALSE
|
|
///Chance to break lights on phase-in
|
|
var/flicker_break_chance = 0
|
|
///Color that lights will flicker to on phase-in. Off by default.
|
|
var/flicker_color
|
|
///Time that lights will flicker on phase-in. Default is 10 times.
|
|
var/flicker_time = 10
|
|
///Range that we flicker lights. Default is 10.
|
|
var/flicker_distance = 10
|
|
///If we can get the 'phase debuff' applied to us. (No using guns, dropping things in hands, etc).
|
|
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
|
|
var/in_dark_respite = FALSE
|
|
var/manual_respite = FALSE
|
|
var/respite_activating = FALSE
|
|
///If we return to The Dark upon death or not.
|
|
var/no_retreat = FALSE
|
|
|
|
//Dark Tunneling Vars (Unused on Virgo)
|
|
///If we have already made a dark tunnel
|
|
var/created_dark_tunnel = FALSE
|
|
|
|
//Dark Maw Vars (Unused on Virgo)
|
|
///Our current active dark maws
|
|
var/list/active_dark_maws = list()
|
|
|
|
//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 holder. Largely ignore this.
|
|
var/list/shadekin_ability_datums = list()
|
|
|
|
//Misc Vars
|
|
///Eyecolor
|
|
var/eye_color = BLUE_EYES
|
|
///For downstream. Enables some extra verbs. Causes things to drop in hand when you phase.
|
|
var/extended_kin = FALSE
|
|
|
|
/datum/component/shadekin/phase_only
|
|
shadekin_abilities = list(/datum/power/shadekin/phase_shift)
|
|
|
|
/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)
|
|
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.
|
|
dark_energy_infinite = TRUE
|
|
normal_phase = FALSE
|
|
|
|
/datum/component/shadekin/Initialize()
|
|
//normal component bs
|
|
if(!isliving(parent) || issilicon(parent))
|
|
return COMPONENT_INCOMPATIBLE
|
|
owner = parent
|
|
if(ishuman(owner))
|
|
RegisterSignal(owner, COMSIG_SHADEKIN_COMPONENT, PROC_REF(handle_comp)) //Happens every species tick.
|
|
else
|
|
RegisterSignal(owner, COMSIG_LIVING_LIFE, PROC_REF(handle_comp)) //Happens every life tick (mobs)
|
|
|
|
//generates powers and then adds them
|
|
build_and_add_abilities()
|
|
|
|
handle_comp() //First hit is free!
|
|
|
|
//decides what 'eye color' we are and how much energy we should get
|
|
set_shadekin_eyecolor() //Gets what eye color we are.
|
|
set_eye_energy() //Sets the energy values based on our eye color.
|
|
|
|
//Misc stuff we need to do
|
|
add_verb(owner, /mob/living/proc/shadekin_control_panel)
|
|
|
|
/datum/component/shadekin/Destroy(force)
|
|
if(ishuman(owner))
|
|
UnregisterSignal(owner, COMSIG_SHADEKIN_COMPONENT)
|
|
else
|
|
UnregisterSignal(owner, COMSIG_LIVING_LIFE)
|
|
remove_verb(owner, /mob/living/proc/shadekin_control_panel)
|
|
for(var/datum/power in shadekin_ability_datums)
|
|
qdel(power)
|
|
for(var/obj/effect/abstract/dark_maw/dm as anything in active_dark_maws) //if the component gets destroyed so does your precious maws
|
|
if(!QDELETED(dm))
|
|
qdel(dm)
|
|
if(owner.shadekin_display)
|
|
owner.shadekin_display.invisibility = INVISIBILITY_ABSTRACT //hide it
|
|
replace_shadekin_master()
|
|
active_dark_maws.Cut()
|
|
shadekin_abilities.Cut()
|
|
shadekin_ability_datums.Cut()
|
|
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
|
|
if(QDELETED(parent))
|
|
return
|
|
if(owner.stat == DEAD) //dead, don't process.
|
|
return
|
|
handle_shade()
|
|
|
|
///Handles the shadekin's energy gain and loss.
|
|
/datum/component/shadekin/proc/handle_shade()
|
|
//Shifted kin don't gain/lose energy (and save time if we're at the cap)
|
|
var/darkness = 1
|
|
var/dark_gains = 0
|
|
|
|
var/suit = owner.get_equipped_item(slot_wear_suit)
|
|
if(istype(suit, /obj/item/clothing/suit/space))
|
|
if(dark_energy)
|
|
to_chat(owner, span_warning("You feel your energy waning and your powers being blocked from the heavy equipment you're wearing!"))
|
|
dark_energy = 0
|
|
return
|
|
|
|
var/turf/T = get_turf(owner)
|
|
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(in_phase)
|
|
dark_gains = 0
|
|
else
|
|
//Heal (very) slowly in good darkness
|
|
if(is_dark)
|
|
//The below sends a DB query...This needs to be fixed before this can be enabled as we're now dealing with signal handlers.
|
|
//Reenable once that mess is taken care of.
|
|
owner.adjustFireLoss((-0.10)*darkness)
|
|
owner.adjustBruteLoss((-0.10)*darkness)
|
|
owner.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
|
|
|
|
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
|
|
|
|
///Sees if the savefile we have selected in CHARACTER SETUP is the same as our ACTIVE CHARACTER savefile.
|
|
/datum/component/shadekin/proc/correct_savefile_selected()
|
|
if(owner.client.prefs.default_slot == owner.mind.loaded_from_slot)
|
|
return TRUE
|
|
return FALSE
|
|
|
|
/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,
|
|
"no_retreat" = no_retreat,
|
|
"nutrition_energy_conversion" = nutrition_energy_conversion,
|
|
"extended_kin" = extended_kin,
|
|
"savefile_selected" = correct_savefile_selected()
|
|
)
|
|
|
|
return data
|
|
|
|
/datum/component/shadekin/tgui_close(mob/user)
|
|
SScharacter_setup.queue_preferences_save(user?.client?.prefs)
|
|
. = ..()
|
|
|
|
/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"])
|
|
new_time = CLAMP(new_time, 2, 20)
|
|
if(!isnum(new_time))
|
|
return FALSE
|
|
flicker_time = new_time
|
|
ui.user.write_preference_directly(/datum/preference/numeric/living/flicker_time, new_time, WRITE_PREF_MANUAL, save_to_played_slot = TRUE)
|
|
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, WRITE_PREF_MANUAL, save_to_played_slot = TRUE)
|
|
return TRUE
|
|
if("adjust_break")
|
|
var/new_break_chance = text2num(params["val"])
|
|
new_break_chance = CLAMP(new_break_chance, 0, 25)
|
|
if(!isnum(new_break_chance))
|
|
return FALSE
|
|
flicker_break_chance = new_break_chance
|
|
ui.user.write_preference_directly(/datum/preference/numeric/living/flicker_break_chance, new_break_chance, WRITE_PREF_MANUAL, save_to_played_slot = TRUE)
|
|
return TRUE
|
|
if("adjust_distance")
|
|
var/new_distance = text2num(params["val"])
|
|
new_distance = CLAMP(new_distance, 4, 10)
|
|
if(!isnum(new_distance))
|
|
return FALSE
|
|
flicker_distance = new_distance
|
|
ui.user.write_preference_directly(/datum/preference/numeric/living/flicker_distance, new_distance, WRITE_PREF_MANUAL, save_to_played_slot = TRUE)
|
|
return TRUE
|
|
if("toggle_retreat")
|
|
var/new_retreat = !no_retreat
|
|
no_retreat = !no_retreat
|
|
ui.user.write_preference_directly(/datum/preference/toggle/living/dark_retreat_toggle, new_retreat, WRITE_PREF_MANUAL, save_to_played_slot = TRUE)
|
|
if("toggle_nutrition")
|
|
var/new_retreat = !nutrition_energy_conversion
|
|
nutrition_energy_conversion = !nutrition_energy_conversion
|
|
ui.user.write_preference_directly(/datum/preference/toggle/living/shadekin_nutrition_conversion, new_retreat, WRITE_PREF_MANUAL, save_to_played_slot = TRUE)
|
|
|
|
/mob/living/proc/shadekin_control_panel()
|
|
set name = "Shadekin Control Panel"
|
|
set desc = "Allows you to adjust the settings of various shadekin settings!"
|
|
set category = "Abilities.Shadekin"
|
|
|
|
var/datum/component/shadekin/SK = get_shadekin_component()
|
|
if(!SK)
|
|
to_chat(src, span_warning("Only a shadekin can use that!"))
|
|
return FALSE
|
|
|
|
SK.tgui_interact(src)
|