Files

1178 lines
44 KiB
Plaintext

/// The damage healed per tick while sleeping without any modifiers
#define HEALING_SLEEP_DEFAULT 0.2
/// The sleep healing multiplier for organ passive healing (since organs heal slowly)
#define HEALING_SLEEP_ORGAN_MULTIPLIER 5
/// The sleep multiplier for fitness xp conversion
#define SLEEP_QUALITY_WORKOUT_MULTIPLER 10
//Largely negative status effects go here, even if they have small beneficial effects
//STUN EFFECTS
/datum/status_effect/incapacitating
id = STATUS_EFFECT_ID_ABSTRACT
tick_interval = STATUS_EFFECT_NO_TICK
status_type = STATUS_EFFECT_REPLACE
alert_type = null
processing_speed = STATUS_EFFECT_PRIORITY
remove_on_fullheal = TRUE
heal_flag_necessary = HEAL_CC_STATUS
var/needs_update_stat = FALSE
/// Suffixes attached to the force_say when applied, uses the "hurt" suffixes by default
var/list/alter_phrases
/datum/status_effect/incapacitating/on_creation(mob/living/new_owner, set_duration)
if(isnum(set_duration))
duration = set_duration
. = ..()
if(!.)
return
if(needs_update_stat || issilicon(owner))
owner.update_stat()
/datum/status_effect/incapacitating/on_remove()
if(needs_update_stat || issilicon(owner)) //silicons need stat updates in addition to normal canmove updates
owner.update_stat()
return ..()
/datum/status_effect/incapacitating/on_apply()
SHOULD_CALL_PARENT(TRUE)
. = ..()
if(!.)
return
force_say()
/datum/status_effect/incapacitating/proc/force_say()
SHOULD_CALL_PARENT(TRUE)
var/mob/living/carbon/human/human = owner
if(istype(human))
human.force_say(alter_phrases, immediate = TRUE)
//STUN
/datum/status_effect/incapacitating/stun
id = "stun"
/datum/status_effect/incapacitating/stun/on_apply()
. = ..()
if(!.)
return
owner.add_traits(list(TRAIT_INCAPACITATED, TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED), TRAIT_STATUS_EFFECT(id))
/datum/status_effect/incapacitating/stun/on_remove()
owner.remove_traits(list(TRAIT_INCAPACITATED, TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED), TRAIT_STATUS_EFFECT(id))
return ..()
//KNOCKDOWN
/datum/status_effect/incapacitating/knockdown
id = "knockdown"
/datum/status_effect/incapacitating/knockdown/on_apply()
. = ..()
if(!.)
return
ADD_TRAIT(owner, TRAIT_FLOORED, TRAIT_STATUS_EFFECT(id))
/datum/status_effect/incapacitating/knockdown/on_remove()
REMOVE_TRAIT(owner, TRAIT_FLOORED, TRAIT_STATUS_EFFECT(id))
return ..()
//IMMOBILIZED
/datum/status_effect/incapacitating/immobilized
id = "immobilized"
/datum/status_effect/incapacitating/immobilized/on_apply()
. = ..()
if(!.)
return
ADD_TRAIT(owner, TRAIT_IMMOBILIZED, TRAIT_STATUS_EFFECT(id))
/datum/status_effect/incapacitating/immobilized/on_remove()
REMOVE_TRAIT(owner, TRAIT_IMMOBILIZED, TRAIT_STATUS_EFFECT(id))
return ..()
//PARALYZED
/datum/status_effect/incapacitating/paralyzed
id = "paralyzed"
alter_phrases = list("") // "Why am I about to be froz-"
/datum/status_effect/incapacitating/paralyzed/on_apply()
. = ..()
if(!.)
return
owner.add_traits(list(TRAIT_INCAPACITATED, TRAIT_IMMOBILIZED, TRAIT_FLOORED, TRAIT_HANDS_BLOCKED), TRAIT_STATUS_EFFECT(id))
/datum/status_effect/incapacitating/paralyzed/on_remove()
owner.remove_traits(list(TRAIT_INCAPACITATED, TRAIT_IMMOBILIZED, TRAIT_FLOORED, TRAIT_HANDS_BLOCKED), TRAIT_STATUS_EFFECT(id))
return ..()
//INCAPACITATED
/// This status effect represents anything that leaves a character unable to perform basic tasks (interrupting do-afters, for example), but doesn't incapacitate them further than that (no stuns etc..)
/datum/status_effect/incapacitating/incapacitated
id = "incapacitated"
// What happens when you get the incapacitated status. You get TRAIT_INCAPACITATED added to you for the duration of the status effect.
/datum/status_effect/incapacitating/incapacitated/on_apply()
. = ..()
if(!.)
return
ADD_TRAIT(owner, TRAIT_INCAPACITATED, TRAIT_STATUS_EFFECT(id))
// When the status effect runs out, your TRAIT_INCAPACITATED is removed.
/datum/status_effect/incapacitating/incapacitated/on_remove()
REMOVE_TRAIT(owner, TRAIT_INCAPACITATED, TRAIT_STATUS_EFFECT(id))
return ..()
//UNCONSCIOUS
/datum/status_effect/incapacitating/unconscious
id = "unconscious"
needs_update_stat = TRUE
/datum/status_effect/incapacitating/unconscious/on_apply()
. = ..()
if(!.)
return
ADD_TRAIT(owner, TRAIT_KNOCKEDOUT, TRAIT_STATUS_EFFECT(id))
/datum/status_effect/incapacitating/unconscious/on_remove()
REMOVE_TRAIT(owner, TRAIT_KNOCKEDOUT, TRAIT_STATUS_EFFECT(id))
return ..()
/datum/status_effect/incapacitating/unconscious/tick(seconds_between_ticks)
if(owner.get_stamina_loss())
owner.adjust_stamina_loss(-0.3) //reduce stamina loss by 0.3 per tick, 6 per 2 seconds
//SLEEPING
/datum/status_effect/incapacitating/sleeping
id = "sleeping"
alert_type = /atom/movable/screen/alert/status_effect/asleep
needs_update_stat = TRUE
tick_interval = 2 SECONDS
alter_phrases = list("Zzz...", "ZZz...", "ZZZ...", "zzZ...", "zZZ...", "ZzZ...", "zzz...", "zZz...", "mimimimimimi...")
/datum/status_effect/incapacitating/sleeping/on_apply()
. = ..()
if(!.)
return
if(HAS_TRAIT(owner, TRAIT_SLEEPIMMUNE))
tick_interval = STATUS_EFFECT_NO_TICK
else
ADD_TRAIT(owner, TRAIT_KNOCKEDOUT, TRAIT_STATUS_EFFECT(id))
RegisterSignal(owner, SIGNAL_ADDTRAIT(TRAIT_SLEEPIMMUNE), PROC_REF(on_owner_insomniac))
RegisterSignal(owner, SIGNAL_REMOVETRAIT(TRAIT_SLEEPIMMUNE), PROC_REF(on_owner_sleepy))
/datum/status_effect/incapacitating/sleeping/on_remove()
UnregisterSignal(owner, list(SIGNAL_ADDTRAIT(TRAIT_SLEEPIMMUNE), SIGNAL_REMOVETRAIT(TRAIT_SLEEPIMMUNE)))
if(!HAS_TRAIT(owner, TRAIT_SLEEPIMMUNE))
REMOVE_TRAIT(owner, TRAIT_KNOCKEDOUT, TRAIT_STATUS_EFFECT(id))
tick_interval = initial(tick_interval)
return ..()
/datum/status_effect/incapacitating/sleeping/force_say()
if(!HAS_TRAIT(owner, TRAIT_SLEEPIMMUNE))
..()
///If the mob is sleeping and gain the TRAIT_SLEEPIMMUNE we remove the TRAIT_KNOCKEDOUT and stop the tick() from happening
/datum/status_effect/incapacitating/sleeping/proc/on_owner_insomniac(mob/living/source)
SIGNAL_HANDLER
REMOVE_TRAIT(owner, TRAIT_KNOCKEDOUT, TRAIT_STATUS_EFFECT(id))
tick_interval = STATUS_EFFECT_NO_TICK
///If the mob has the TRAIT_SLEEPIMMUNE but somehow looses it we make him sleep and restart the tick()
/datum/status_effect/incapacitating/sleeping/proc/on_owner_sleepy(mob/living/source)
SIGNAL_HANDLER
ADD_TRAIT(owner, TRAIT_KNOCKEDOUT, TRAIT_STATUS_EFFECT(id))
tick_interval = initial(tick_interval)
/datum/status_effect/incapacitating/sleeping/tick(seconds_between_ticks)
if(owner.maxHealth)
var/health_ratio = owner.health / owner.maxHealth
var/sleep_quality = HEALING_SLEEP_DEFAULT
// having high spirits helps us recover
if(owner.mob_mood)
switch(owner.mob_mood.sanity_level)
if(SANITY_LEVEL_GREAT)
sleep_quality = 0.2
if(SANITY_LEVEL_NEUTRAL)
sleep_quality = 0.1
if(SANITY_LEVEL_DISTURBED)
sleep_quality = 0
if(SANITY_LEVEL_UNSTABLE)
sleep_quality = 0
if(SANITY_LEVEL_CRAZY)
sleep_quality = -0.1
if(SANITY_LEVEL_INSANE)
sleep_quality = -0.2
var/turf/rest_turf = get_turf(owner)
var/is_sleeping_in_darkness = rest_turf.get_lumcount() <= LIGHTING_TILE_IS_DARK
// sleeping with a blindfold or in the dark helps us rest
if(owner.is_blind_from(EYES_COVERED) || is_sleeping_in_darkness)
sleep_quality += 0.1
// sleeping in silence is always better
if(HAS_TRAIT(owner, TRAIT_DEAF))
sleep_quality += 0.1
// check for beds
if((locate(/obj/structure/bed) in owner.loc))
sleep_quality += 0.2
else if((locate(/obj/structure/table) in owner.loc))
sleep_quality += 0.1
// don't forget the bedsheet
if(locate(/obj/item/bedsheet) in owner.loc)
sleep_quality += 0.1
// you forgot the pillow
if(locate(/obj/item/pillow) in owner.loc)
sleep_quality += 0.1
var/need_mob_update = FALSE
if(sleep_quality > 0)
if(iscarbon(owner))
var/mob/living/carbon/carbon_owner = owner
for(var/obj/item/organ/target_organ as anything in carbon_owner.organs)
// no healing boost for robotic or dying organs
if(IS_ROBOTIC_ORGAN(target_organ) || !target_organ.damage || target_organ.organ_flags & ORGAN_FAILING)
continue
// organ regeneration is very low so we crank up the healing rate to give a good bonus
var/healing_bonus = target_organ.healing_factor * sleep_quality * HEALING_SLEEP_ORGAN_MULTIPLIER
target_organ.apply_organ_damage(-healing_bonus * target_organ.maxHealth)
var/datum/status_effect/exercised/exercised = carbon_owner.has_status_effect(/datum/status_effect/exercised)
if(exercised && carbon_owner.mind)
// the better you sleep, the more xp you gain
carbon_owner.mind.adjust_experience(/datum/skill/athletics, seconds_between_ticks * sleep_quality * SLEEP_QUALITY_WORKOUT_MULTIPLER)
carbon_owner.adjust_timed_status_effect(-1 * seconds_between_ticks * sleep_quality * SLEEP_QUALITY_WORKOUT_MULTIPLER, /datum/status_effect/exercised)
if(prob(2))
to_chat(carbon_owner, span_notice("You feel your fitness improving!"))
if(health_ratio > 0.8) // only heals minor physical damage
need_mob_update += owner.adjust_brute_loss(-0.4 * sleep_quality * seconds_between_ticks, updating_health = FALSE, required_bodytype = BODYTYPE_ORGANIC)
need_mob_update += owner.adjust_fire_loss(-0.4 * sleep_quality * seconds_between_ticks, updating_health = FALSE, required_bodytype = BODYTYPE_ORGANIC)
need_mob_update += owner.adjust_tox_loss(-0.2 * sleep_quality * seconds_between_ticks, updating_health = FALSE, forced = TRUE, required_biotype = MOB_ORGANIC)
need_mob_update += owner.adjust_stamina_loss(min(-0.4 * sleep_quality * seconds_between_ticks, -0.4 * HEALING_SLEEP_DEFAULT * seconds_between_ticks), updating_stamina = FALSE)
if(need_mob_update)
owner.updatehealth()
// Drunkenness gets reduced by 0.3% per tick (6% per 2 seconds)
owner.set_drunk_effect(owner.get_drunk_amount() * 0.997)
if(iscarbon(owner))
var/mob/living/carbon/carbon_owner = owner
carbon_owner.handle_dreams()
if(prob(8) && owner.health > owner.crit_threshold)
owner.emote("snore")
/atom/movable/screen/alert/status_effect/asleep
name = "Asleep"
desc = "You've fallen asleep. Wait a bit and you should wake up. Unless you don't, considering how helpless you are."
use_user_hud_icon = USER_HUD_STYLE_INHERIT
overlay_state = "asleep"
//STASIS
/datum/status_effect/grouped/stasis
id = "stasis"
duration = STATUS_EFFECT_PERMANENT
alert_type = /atom/movable/screen/alert/status_effect/stasis
var/last_dead_time
/datum/status_effect/grouped/stasis/proc/update_time_of_death()
if(last_dead_time)
var/delta = world.time - last_dead_time
var/new_timeofdeath = owner.timeofdeath + delta
owner.timeofdeath = new_timeofdeath
owner.station_timestamp_timeofdeath = round_timestamp(wtime=new_timeofdeath)
last_dead_time = null
if(owner.stat == DEAD)
last_dead_time = world.time
/datum/status_effect/grouped/stasis/on_creation(mob/living/new_owner, set_duration)
. = ..()
if(.)
update_time_of_death()
owner.reagents?.end_metabolization(owner, FALSE)
/datum/status_effect/grouped/stasis/on_apply()
. = ..()
if(!.)
return
owner.add_traits(list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED, TRAIT_STASIS, TRAIT_TUMOR_SUPPRESSED), TRAIT_STATUS_EFFECT(id))
owner.add_filter("stasis_status_ripple", 2, list("type" = "ripple", "flags" = WAVE_BOUNDED, "radius" = 0, "size" = 2))
var/filter = owner.get_filter("stasis_status_ripple")
animate(filter, radius = 0, time = 0.2 SECONDS, size = 2, easing = JUMP_EASING, loop = -1, flags = ANIMATION_PARALLEL)
animate(radius = 32, time = 1.5 SECONDS, size = 0)
if(iscarbon(owner))
var/mob/living/carbon/carbon_owner = owner
carbon_owner.update_bodypart_bleed_overlays()
/datum/status_effect/grouped/stasis/tick(seconds_between_ticks)
update_time_of_death()
if(owner.stat >= UNCONSCIOUS) //SKYRAT EDIT START - STASIS KEEPS SLEEP GOING
owner.Sleeping(15 SECONDS) //SKYRAT EDIT END
/datum/status_effect/grouped/stasis/on_remove()
owner.remove_traits(list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED, TRAIT_STASIS, TRAIT_TUMOR_SUPPRESSED), TRAIT_STATUS_EFFECT(id))
owner.remove_filter("stasis_status_ripple")
update_time_of_death()
if(iscarbon(owner))
var/mob/living/carbon/carbon_owner = owner
carbon_owner.update_bodypart_bleed_overlays()
return ..()
/atom/movable/screen/alert/status_effect/stasis
name = "Stasis"
desc = "Your biological functions have halted. You could live forever this way, but it's pretty boring."
use_user_hud_icon = USER_HUD_STYLE_INHERIT
overlay_state = "stasis"
/datum/status_effect/his_wrath //does minor damage over time unless holding His Grace
id = "his_wrath"
duration = STATUS_EFFECT_PERMANENT
tick_interval = 0.4 SECONDS
alert_type = /atom/movable/screen/alert/status_effect/his_wrath
/datum/status_effect/his_wrath/on_creation(mob/living/new_owner, His, Him)
. = ..()
linked_alert.name = "[His] Wrath"
linked_alert.desc = "You fled from [His] Grace instead of feeding [Him], and now you suffer."
linked_alert.icon_state = "[LOWER_TEXT(His)]_grace"
/atom/movable/screen/alert/status_effect/his_wrath
name = "His Wrath"
desc = "You fled from His Grace instead of feeding Him, and now you suffer."
icon_state = "his_grace"
alerttooltipstyle = "hisgrace"
/datum/status_effect/his_wrath/tick(seconds_between_ticks)
for(var/obj/item/his_grace/HG in owner.held_items)
qdel(src)
return
var/need_mob_update
need_mob_update = owner.adjust_brute_loss(0.04 * seconds_between_ticks, updating_health = FALSE)
need_mob_update += owner.adjust_fire_loss(0.04 * seconds_between_ticks, updating_health = FALSE)
need_mob_update += owner.adjust_tox_loss(0.08 * seconds_between_ticks, updating_health = FALSE, forced = TRUE)
if(need_mob_update)
owner.updatehealth()
/datum/status_effect/cultghost //is a cult ghost and can't use manifest runes
id = "cult_ghost"
duration = STATUS_EFFECT_PERMANENT
alert_type = null
/datum/status_effect/cultghost/on_apply()
owner.set_invis_see(SEE_INVISIBLE_OBSERVER)
return TRUE
/datum/status_effect/cultghost/tick(seconds_between_ticks)
if(owner.reagents)
owner.reagents.del_reagent(/datum/reagent/water/holywater) //can't be deconverted
/datum/status_effect/crusher_mark
id = "crusher_mark"
duration = 300 //if you leave for 30 seconds you lose the mark, deal with it
status_type = STATUS_EFFECT_REFRESH
alert_type = null
/// The bubble that is added to the mob as a visual
var/obj/effect/abstract/crusher_mark/marked_underlay
/// If the projectile that applies this was boosted, the mark will also be boosted
var/boosted = FALSE
/// How long before the mark is ready to be detonated. Used for both the visual overlay and to determine when it's ready
var/ready_delay = 0.8 SECONDS
/datum/status_effect/crusher_mark/on_creation(mob/living/new_owner, was_boosted)
. = ..()
boosted = was_boosted
/datum/status_effect/crusher_mark/on_apply()
if(owner.mob_size < MOB_SIZE_LARGE)
return FALSE
marked_underlay = new()
marked_underlay.pixel_w = -(owner.base_pixel_x + owner.base_pixel_w)
marked_underlay.pixel_z = -(owner.base_pixel_y + owner.base_pixel_z)
marked_underlay.transform *= 0.5
owner.vis_contents += marked_underlay
animate(marked_underlay, ready_delay, transform = matrix() * 1.2, flags = CIRCULAR_EASING | EASE_IN)
addtimer(CALLBACK(src, PROC_REF(scale_back)), ready_delay) // Animate chains do not function with vis_contents
return TRUE
/datum/status_effect/crusher_mark/proc/scale_back()
animate(marked_underlay, time = 0.1 SECONDS, transform = matrix(), flags = CUBIC_EASING | EASE_OUT)
/datum/status_effect/crusher_mark/Destroy()
if(owner)
owner.underlays -= marked_underlay
QDEL_NULL(marked_underlay)
return ..()
// Object used to apply a underlay to the mob that gets this status applied
/obj/effect/abstract/crusher_mark
name = "Crusher mark underlay"
icon = 'icons/effects/effects.dmi'
icon_state = "shield"
appearance_flags = TILE_BOUND|LONG_GLIDE|RESET_COLOR|PIXEL_SCALE|KEEP_APART
vis_flags = VIS_UNDERLAY
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
/datum/status_effect/stacking/saw_bleed
id = "saw_bleed"
tick_interval = 0.6 SECONDS
delay_before_decay = 5
stack_threshold = 10
max_stacks = 10
overlay_file = 'icons/effects/bleed.dmi'
overlay_state = "bleed"
var/bleed_damage = 200
/datum/status_effect/stacking/saw_bleed/fadeout_effect()
new /obj/effect/temp_visual/bleed(get_turf(owner))
/datum/status_effect/stacking/saw_bleed/threshold_cross_effect()
owner.adjust_brute_loss(bleed_damage)
new /obj/effect/temp_visual/bleed/explode(get_turf(owner))
for(var/splatter_dir in GLOB.alldirs)
owner.create_splatter(splatter_dir)
playsound(owner, SFX_DESECRATION, 100, TRUE, -1)
/datum/status_effect/stacking/saw_bleed/bloodletting
id = "bloodletting"
stack_threshold = 7
max_stacks = 7
bleed_damage = 20
/datum/status_effect/neck_slice
id = "neck_slice"
status_type = STATUS_EFFECT_UNIQUE
alert_type = null
duration = STATUS_EFFECT_PERMANENT
/datum/status_effect/neck_slice/on_apply()
if(!ishuman(owner))
return FALSE
if(!owner.get_bodypart(BODY_ZONE_HEAD))
return FALSE
return TRUE
/datum/status_effect/neck_slice/tick(seconds_between_ticks)
var/obj/item/bodypart/throat = owner.get_bodypart(BODY_ZONE_HEAD)
if(owner.stat == DEAD || !throat) // they can lose their head while it's going.
qdel(src)
return
var/still_bleeding = FALSE
for(var/datum/wound/bleeding_thing as anything in throat.wounds)
var/datum/wound_pregen_data/pregen_data = GLOB.all_wound_pregen_data[bleeding_thing.type]
if(pregen_data.wounding_types_valid(WOUND_SLASH) && bleeding_thing.severity > WOUND_SEVERITY_MODERATE && bleeding_thing.blood_flow > 0)
still_bleeding = TRUE
break
if(!still_bleeding)
qdel(src)
return
if(prob(10))
owner.emote(pick("gasp", "gag", "choke"))
/datum/status_effect/neck_slice/get_examine_text()
return span_warning("[owner.p_Their()] neck is cut and is bleeding profusely!")
/// Applies a curse with various possible effects
/mob/living/proc/apply_necropolis_curse(set_curse)
var/datum/status_effect/necropolis_curse/curse = has_status_effect(/datum/status_effect/necropolis_curse)
if(!set_curse)
set_curse = pick(CURSE_BLINDING, CURSE_WASTING, CURSE_GRASPING)
if(QDELETED(curse))
apply_status_effect(/datum/status_effect/necropolis_curse, set_curse)
else
curse.apply_curse(set_curse)
curse.duration += 5 MINUTES //time added by additional curses
return curse
/// A curse that does up to three nasty things to you
/datum/status_effect/necropolis_curse
id = "necrocurse"
duration = 10 MINUTES //you're cursed for 10 minutes have fun
tick_interval = 5 SECONDS
alert_type = null
/// Which nasty things are we doing? [CURSE_BLINDING / CURSE_WASTING / CURSE_GRASPING]]
var/curse_flags = NONE
/// When should we next throw hands?
var/effect_next_activation = 0
/// How long between throwing hands?
var/effect_cooldown = 10 SECONDS
/// Visuals for the wasting effect
var/obj/effect/temp_visual/curse/wasting_effect
/datum/status_effect/necropolis_curse/on_creation(mob/living/new_owner, set_curse)
. = ..()
if(.)
apply_curse(set_curse)
/datum/status_effect/necropolis_curse/Destroy()
if(!QDELETED(wasting_effect))
qdel(wasting_effect)
wasting_effect = null
return ..()
/datum/status_effect/necropolis_curse/on_remove()
remove_curse(curse_flags)
/datum/status_effect/necropolis_curse/proc/apply_curse(set_curse)
curse_flags |= set_curse
if(curse_flags & CURSE_BLINDING)
owner.overlay_fullscreen("curse", /atom/movable/screen/fullscreen/curse, 1)
if(curse_flags & CURSE_WASTING && !wasting_effect)
wasting_effect = new
/datum/status_effect/necropolis_curse/proc/remove_curse(remove_curse)
if(remove_curse & CURSE_BLINDING)
owner.clear_fullscreen("curse", 50)
curse_flags &= ~remove_curse
/datum/status_effect/necropolis_curse/tick(seconds_between_ticks)
if(owner.stat == DEAD)
return
if(curse_flags & CURSE_WASTING)
wasting_effect.forceMove(owner.loc)
wasting_effect.setDir(owner.dir)
wasting_effect.transform = owner.transform //if the owner has been stunned the overlay should inherit that position
wasting_effect.alpha = 255
animate(wasting_effect, alpha = 0, time = 32)
playsound(owner, 'sound/effects/curse/curse5.ogg', 20, TRUE, -1)
owner.adjust_fire_loss(0.75)
if(curse_flags & CURSE_GRASPING)
if(effect_next_activation > world.time)
return
effect_next_activation = world.time + effect_cooldown
fire_curse_hand(owner, range = 5, projectile_type = /obj/projectile/curse_hand) // This one stuns people
/obj/effect/temp_visual/curse
icon_state = "curse"
/obj/effect/temp_visual/curse/Initialize(mapload)
. = ..()
deltimer(timerid)
/datum/status_effect/gonbola_pacify
id = "gonbolaPacify"
status_type = STATUS_EFFECT_MULTIPLE
tick_interval = STATUS_EFFECT_NO_TICK
alert_type = null
/datum/status_effect/gonbola_pacify/on_apply()
. = ..()
owner.add_traits(list(TRAIT_PACIFISM, TRAIT_MUTE), REF(src))
owner.add_mood_event(REF(src), /datum/mood_event/gondola)
to_chat(owner, span_notice("You suddenly feel at peace and feel no need to make any sudden or rash actions..."))
/datum/status_effect/gonbola_pacify/on_remove()
owner.remove_traits(list(TRAIT_PACIFISM, TRAIT_MUTE), REF(src))
owner.clear_mood_event(REF(src))
return ..()
/datum/status_effect/trance
id = "trance"
status_type = STATUS_EFFECT_UNIQUE
duration = 300
tick_interval = 1 SECONDS
var/stun = TRUE
alert_type = /atom/movable/screen/alert/status_effect/trance
/atom/movable/screen/alert/status_effect/trance
name = "Trance"
desc = "Everything feels so distant, and you can feel your thoughts forming loops inside your head..."
use_user_hud_icon = USER_HUD_STYLE_INHERIT
overlay_state = "high"
/datum/status_effect/trance/tick(seconds_between_ticks)
if(stun)
owner.Stun(6 SECONDS, TRUE)
owner.set_dizzy(40 SECONDS)
/datum/status_effect/trance/on_apply()
if(!iscarbon(owner))
return FALSE
RegisterSignal(owner, COMSIG_MOVABLE_HEAR, PROC_REF(hypnotize))
ADD_TRAIT(owner, TRAIT_MUTE, TRAIT_STATUS_EFFECT(id))
owner.add_client_colour(/datum/client_colour/monochrome, REF(src))
owner.visible_message("[stun ? span_warning("[owner] stands still as [owner.p_their()] eyes seem to focus on a distant point.") : ""]", \
span_warning(pick("You feel your thoughts slow down...", "You suddenly feel extremely dizzy...", "You feel like you're in the middle of a dream...","You feel incredibly relaxed...")))
return TRUE
/datum/status_effect/trance/on_creation(mob/living/new_owner, _duration, _stun = TRUE)
duration = _duration
stun = _stun
return ..()
/datum/status_effect/trance/on_remove()
UnregisterSignal(owner, COMSIG_MOVABLE_HEAR)
REMOVE_TRAIT(owner, TRAIT_MUTE, TRAIT_STATUS_EFFECT(id))
owner.remove_status_effect(/datum/status_effect/dizziness)
owner.remove_client_colour(REF(src))
to_chat(owner, span_warning("You snap out of your trance!"))
/datum/status_effect/trance/get_examine_text()
return span_warning("[owner.p_They()] seem[owner.p_s()] slow and unfocused.")
/datum/status_effect/trance/proc/hypnotize(datum/source, list/hearing_args)
SIGNAL_HANDLER
if(HAS_TRAIT(owner, TRAIT_DEAF) || owner == hearing_args[HEARING_SPEAKER])
return
var/mob/hearing_speaker = hearing_args[HEARING_SPEAKER]
var/mob/living/carbon/C = owner
C.cure_trauma_type(/datum/brain_trauma/hypnosis, TRAUMA_RESILIENCE_SURGERY) //clear previous hypnosis
// The brain trauma itself does its own set of logging, but this is the only place the source of the hypnosis phrase can be found.
hearing_speaker.log_message("hypnotised [key_name(C)] with the phrase '[hearing_args[HEARING_RAW_MESSAGE]]'", LOG_ATTACK, color="red")
C.log_message("has been hypnotised by the phrase '[hearing_args[HEARING_RAW_MESSAGE]]' spoken by [key_name(hearing_speaker)]", LOG_VICTIM, color="orange", log_globally = FALSE)
addtimer(CALLBACK(C, TYPE_PROC_REF(/mob/living/carbon, gain_trauma), /datum/brain_trauma/hypnosis, TRAUMA_RESILIENCE_SURGERY, hearing_args[HEARING_RAW_MESSAGE]), 1 SECONDS)
addtimer(CALLBACK(C, TYPE_PROC_REF(/mob/living, Stun), 60, TRUE, TRUE), 15) //Take some time to think about it
qdel(src)
/datum/status_effect/spasms
id = "spasms"
status_type = STATUS_EFFECT_MULTIPLE
alert_type = null
/datum/status_effect/spasms/tick(seconds_between_ticks)
if(owner.stat >= UNCONSCIOUS || owner.incapacitated || HAS_TRAIT(owner, TRAIT_HANDS_BLOCKED) || HAS_TRAIT(owner, TRAIT_IMMOBILIZED))
return
if(!prob(15))
return
switch(rand(1,5))
if(1)
if((owner.mobility_flags & MOBILITY_MOVE) && isturf(owner.loc))
to_chat(owner, span_warning("Your leg spasms!"))
step(owner, pick(GLOB.cardinals))
if(2)
var/obj/item/held_item = owner.get_active_held_item()
if(!held_item)
return
to_chat(owner, span_warning("Your fingers spasm!"))
owner.log_message("used [held_item] due to a Muscle Spasm", LOG_ATTACK)
held_item.attack_self(owner)
if(3)
owner.set_combat_mode(TRUE)
var/range = 1
if(istype(owner.get_active_held_item(), /obj/item/gun)) //get targets to shoot at
range = 7
var/list/mob/living/targets = list()
for(var/mob/living/nearby_mobs in oview(owner, range))
targets += nearby_mobs
if(LAZYLEN(targets))
to_chat(owner, span_warning("Your arm spasms!"))
owner.log_message(" attacked someone due to a Muscle Spasm", LOG_ATTACK) //the following attack will log itself
owner.ClickOn(pick(targets))
owner.set_combat_mode(FALSE)
if(4)
owner.set_combat_mode(TRUE)
to_chat(owner, span_warning("Your arm spasms!"))
owner.log_message("attacked [owner.p_them()]self to a Muscle Spasm", LOG_ATTACK)
owner.ClickOn(owner)
owner.set_combat_mode(FALSE)
if(5)
var/obj/item/held_item = owner.get_active_held_item()
var/list/turf/targets = list()
for(var/turf/nearby_turfs in oview(owner, 3))
targets += nearby_turfs
if(LAZYLEN(targets) && held_item)
to_chat(owner, span_warning("Your arm spasms!"))
owner.log_message("threw [held_item] due to a Muscle Spasm", LOG_ATTACK)
owner.throw_item(pick(targets))
/datum/status_effect/convulsing
id = "convulsing"
duration = 150
status_type = STATUS_EFFECT_REFRESH
alert_type = /atom/movable/screen/alert/status_effect/convulsing
show_duration = TRUE
/datum/status_effect/convulsing/on_creation(mob/living/zappy_boy)
. = ..()
to_chat(zappy_boy, span_boldwarning("You feel a shock moving through your body! Your hands start shaking!"))
/datum/status_effect/convulsing/tick(seconds_between_ticks)
var/mob/living/carbon/H = owner
if(prob(40))
var/obj/item/I = H.get_active_held_item()
if(I && H.dropItemToGround(I))
H.visible_message(
span_notice("[H]'s hand convulses, and they drop their [I.name]!"),
span_userdanger("Your hand convulses violently, and you drop what you were holding!"),
)
H.adjust_jitter(10 SECONDS)
/atom/movable/screen/alert/status_effect/convulsing
name = "Shaky Hands"
desc = "You've been zapped with something and your hands can't stop shaking! You can't seem to hold on to anything."
use_user_hud_icon = USER_HUD_STYLE_INHERIT
overlay_state = "convulsing"
/datum/status_effect/dna_melt
id = "dna_melt"
duration = 600
status_type = STATUS_EFFECT_REPLACE
alert_type = /atom/movable/screen/alert/status_effect/dna_melt
var/kill_either_way = FALSE //no amount of removing mutations is gonna save you now
/datum/status_effect/dna_melt/on_creation(mob/living/new_owner, set_duration)
. = ..()
to_chat(new_owner, span_boldwarning("My body can't handle the mutations! I need to get my mutations removed fast!"))
/datum/status_effect/dna_melt/on_remove()
if(!ishuman(owner))
owner.gib(DROP_ALL_REMAINS) //fuck you in particular
return
var/mob/living/carbon/human/H = owner
INVOKE_ASYNC(H, TYPE_PROC_REF(/mob/living/carbon/human, something_horrible), kill_either_way)
/atom/movable/screen/alert/status_effect/dna_melt
name = "Genetic Breakdown"
desc = "I don't feel so good. Your body can't handle the mutations! You have one minute to remove your mutations, or you will be met with a horrible fate."
use_user_hud_icon = USER_HUD_STYLE_INHERIT
overlay_state = "dna_melt"
/datum/status_effect/go_away
id = "go_away"
duration = 10 SECONDS
status_type = STATUS_EFFECT_REPLACE
tick_interval = 0.2 SECONDS
alert_type = /atom/movable/screen/alert/status_effect/go_away
var/direction
/datum/status_effect/go_away/on_creation(mob/living/new_owner, set_duration)
. = ..()
direction = pick(NORTH, SOUTH, EAST, WEST)
new_owner.setDir(direction)
owner.add_traits(list(TRAIT_NO_FLOATING_ANIM, TRAIT_MOVE_FLYING), TRAIT_STATUS_EFFECT(id)) //I believe I can fly!
/datum/status_effect/go_away/tick(seconds_between_ticks)
owner.AdjustStun(1, ignore_canstun = TRUE)
var/turf/turf = get_step(owner, direction)
if(!turf)
qdel(src)
return
owner.forceMove(turf)
/datum/status_effect/go_away/on_remove()
. = ..()
owner.remove_traits(list(TRAIT_NO_FLOATING_ANIM, TRAIT_MOVE_FLYING), TRAIT_STATUS_EFFECT(id))
///Subtype of the go away effect (phases the mob in one direction) that deletes the owner on z-level change or when the time's up.
/datum/status_effect/go_away/deletes_mob
id = "go_away_deletes_mob"
duration = 30 SECONDS
/// Timer that tracks when we should vanish
var/deletion_timer
/datum/status_effect/go_away/deletes_mob/on_creation(mob/living/new_owner, set_duration)
. = ..()
deletion_timer = addtimer(CALLBACK(src, PROC_REF(wipe_bozo)), duration - 5 SECONDS, TIMER_STOPPABLE | TIMER_DELETE_ME)
ADD_TRAIT(owner, TRAIT_IMMOBILIZED, REF(src))
RegisterSignals(new_owner, list(COMSIG_MOVABLE_Z_CHANGED, COMSIG_LIVING_DEATH), PROC_REF(wipe_bozo))
/datum/status_effect/go_away/deletes_mob/proc/wipe_bozo()
deltimer(deletion_timer)
owner.fade_into_nothing()
UnregisterSignal(owner, list(COMSIG_MOVABLE_Z_CHANGED, COMSIG_LIVING_DEATH))
/datum/status_effect/go_away/deletes_mob/on_remove()
. = ..()
deltimer(deletion_timer)
REMOVE_TRAIT(owner, TRAIT_IMMOBILIZED, REF(src))
UnregisterSignal(owner, list(COMSIG_MOVABLE_Z_CHANGED, COMSIG_LIVING_DEATH))
/atom/movable/screen/alert/status_effect/go_away
name = "TO THE STARS AND BEYOND!"
desc = "I must go, my people need me!"
use_user_hud_icon = USER_HUD_STYLE_INHERIT
overlay_state = "high"
/datum/status_effect/fake_virus
id = "fake_virus"
duration = 3 MINUTES //3 minutes
status_type = STATUS_EFFECT_REPLACE
tick_interval = 0.2 SECONDS
alert_type = null
var/msg_stage = 0//so you don't get the most intense messages immediately
/datum/status_effect/fake_virus/on_apply()
if(HAS_TRAIT(owner, TRAIT_VIRUSIMMUNE))
return FALSE
if(owner.stat != CONSCIOUS)
return FALSE
return TRUE
/datum/status_effect/fake_virus/tick(seconds_between_ticks)
var/fake_msg = ""
var/fake_emote = ""
switch(msg_stage)
if(0 to 300)
if(prob(1))
fake_msg = pick(
span_warning(pick("Your head hurts.", "Your head pounds.")),
span_warning(pick("You're having difficulty breathing.", "Your breathing becomes heavy.")),
span_warning(pick("You feel dizzy.", "Your head spins.")),
span_warning(pick("You swallow excess mucus.", "You lightly cough.")),
span_warning(pick("Your head hurts.", "Your mind blanks for a moment.")),
span_warning(pick("Your throat hurts.", "You clear your throat.")))
if(301 to 600)
if(prob(2))
fake_msg = pick(
span_warning(pick("Your head hurts a lot.", "Your head pounds incessantly.")),
span_warning(pick("Your windpipe feels like a straw.", "Your breathing becomes tremendously difficult.")),
span_warning("You feel very [pick("dizzy","woozy","faint")]."),
span_warning(pick("You hear a ringing in your ear.", "Your ears pop.")),
span_warning("You nod off for a moment."))
else
if(prob(3))
if(prob(50))// coin flip to throw a message or an emote
fake_msg = pick(
span_userdanger(pick("Your head hurts!", "You feel a burning knife inside your brain!", "A wave of pain fills your head!")),
span_userdanger(pick("Your lungs hurt!", "It hurts to breathe!")),
span_warning(pick("You feel nauseated.", "You feel like you're going to throw up!")))
else
if(prob(40))
fake_emote = "cough"
else
fake_emote = "sneeze"
if(fake_emote)
owner.emote(fake_emote)
else if(fake_msg)
to_chat(owner, fake_msg)
msg_stage++
//Deals with ants covering someone.
/datum/status_effect/ants
id = "ants"
status_type = STATUS_EFFECT_REFRESH
alert_type = /atom/movable/screen/alert/status_effect/ants
duration = 2 MINUTES //Keeping the normal timer makes sure people can't somehow dump 300+ ants on someone at once so they stay there for like 30 minutes. Max w/ 1 dump is 57.6 brute.
processing_speed = STATUS_EFFECT_NORMAL_PROCESS
/// Will act as the main timer as well as changing how much damage the ants do.
var/ants_remaining = 0
/// Amount of damage done per ant on the victim
var/damage_per_ant = 0.0016
/// Common phrases people covered in ants scream
var/static/list/ant_debuff_speech = list(
"GET THEM OFF ME!!",
"OH GOD THE ANTS!!",
"MAKE IT END!!",
"THEY'RE EVERYWHERE!!",
"GET THEM OFF!!",
"SOMEBODY HELP ME!!"
)
/datum/status_effect/ants/on_creation(mob/living/new_owner, amount_left)
if(isnum(amount_left) && new_owner.stat < HARD_CRIT)
if(new_owner.stat < UNCONSCIOUS) // Unconscious people won't get messages
to_chat(new_owner, span_userdanger("You're covered in ants!"))
ants_remaining += amount_left
RegisterSignal(new_owner, COMSIG_COMPONENT_CLEAN_ACT, PROC_REF(ants_washed))
. = ..()
/datum/status_effect/ants/refresh(effect, amount_left)
var/mob/living/carbon/human/victim = owner
if(isnum(amount_left) && ants_remaining >= 1 && victim.stat < HARD_CRIT)
if(victim.stat < UNCONSCIOUS) // Unconscious people won't get messages
if(!prob(1)) // 99%
to_chat(victim, span_userdanger("You're covered in MORE ants!"))
else // 1%
victim.say("AAHH! THIS SITUATION HAS ONLY BEEN MADE WORSE WITH THE ADDITION OF YET MORE ANTS!!", forced = /datum/status_effect/ants)
ants_remaining += amount_left
. = ..()
/datum/status_effect/ants/on_remove()
ants_remaining = 0
to_chat(owner, span_notice("All of the ants are off of your body!"))
UnregisterSignal(owner, COMSIG_COMPONENT_CLEAN_ACT)
. = ..()
/datum/status_effect/ants/proc/ants_washed()
SIGNAL_HANDLER
. = NONE
if(owner.remove_status_effect(/datum/status_effect/ants))
return COMPONENT_CLEANED|COMPONENT_CLEANED_GAIN_XP
/datum/status_effect/ants/get_examine_text()
return span_warning("[owner.p_They()] [owner.p_are()] covered in ants!")
/datum/status_effect/ants/tick(seconds_between_ticks)
var/mob/living/carbon/human/victim = owner
victim.apply_damage(max(0.1, round((ants_remaining * damage_per_ant), 0.1)) * seconds_between_ticks, BRUTE, spread_damage = TRUE) //Scales with # of ants (lowers with time). Roughly 10 brute over 50 seconds.
if(victim.stat <= SOFT_CRIT) //Makes sure people don't scratch at themselves while they're in a critical condition
if(prob(15))
switch(rand(1,2))
if(1)
victim.say(pick(ant_debuff_speech), forced = /datum/status_effect/ants)
if(2)
victim.emote("scream")
if(prob(50)) // Most of the damage is done through random chance. When tested yielded an average 100 brute with 200u ants.
switch(rand(1,50))
if (1 to 8) //16% Chance
to_chat(victim, span_danger("You scratch at the ants on your scalp!."))
owner.apply_damage(0.4 * seconds_between_ticks, BRUTE, BODY_ZONE_HEAD)
if (9 to 29) //40% chance
to_chat(victim, span_danger("You scratch at the ants on your arms!"))
owner.apply_damage(1.2 * seconds_between_ticks, BRUTE, pick(GLOB.arm_zones))
if (30 to 49) //38% chance
to_chat(victim, span_danger("You scratch at the ants on your leg!"))
owner.apply_damage(1.2 * seconds_between_ticks, BRUTE, pick(GLOB.leg_zones))
if(50) // 2% chance
to_chat(victim, span_danger("You rub some ants away from your eyes!"))
victim.set_eye_blur_if_lower(6 SECONDS)
ants_remaining -= 5 // To balance out the blindness, it'll be a little shorter.
ants_remaining--
if(ants_remaining <= 0 || victim.stat >= HARD_CRIT)
qdel(src) //If this person has no more ants on them or are dead, they are no longer affected.
/atom/movable/screen/alert/status_effect/ants
name = "Ants!"
desc = span_warning("JESUS FUCKING CHRIST! CLICK TO GET THOSE THINGS OFF!")
use_user_hud_icon = USER_HUD_STYLE_INHERIT
overlay_state = "antalert"
clickable_glow = TRUE
/atom/movable/screen/alert/status_effect/ants/Click()
. = ..()
if(!.)
return
var/mob/living/living = owner
if(!istype(living) || !living.can_resist() || living != owner)
return
to_chat(living, span_notice("You start to shake the ants off!"))
if(!do_after(living, 2 SECONDS, target = living))
return
for (var/datum/status_effect/ants/ant_covered in living.status_effects)
to_chat(living, span_notice("You manage to get some of the ants off!"))
ant_covered.ants_remaining -= 10 // 5 Times more ants removed per second than just waiting in place
/datum/status_effect/ants/fire
id = "fire_ants"
alert_type = /atom/movable/screen/alert/status_effect/ants/fire
damage_per_ant = 0.0064
/atom/movable/screen/alert/status_effect/ants/fire
name = "Fire Ants!"
desc = span_warning("JESUS FUCKING CHRIST IT BURNS! CLICK TO GET THOSE THINGS OFF!")
/datum/status_effect/rebuked
id = "rebuked"
status_type = STATUS_EFFECT_REFRESH
duration = 30 SECONDS
tick_interval = 1 SECONDS
alert_type = null
/// By how much we should increase the attack cooldown
var/cd_increase = 2.5
/datum/status_effect/rebuked/on_apply()
owner.next_move_modifier *= 2
if(ishostile(owner))
var/mob/living/simple_animal/hostile/simple_owner = owner
simple_owner.ranged_cooldown_time *= cd_increase
return TRUE
/datum/status_effect/rebuked/on_remove()
. = ..()
if(QDELETED(owner))
return
owner.next_move_modifier *= 0.5
if(ishostile(owner))
var/mob/living/simple_animal/hostile/simple_owner = owner
simple_owner.ranged_cooldown_time /= cd_increase
/datum/status_effect/freezing_blast
id = "freezing_blast"
alert_type = /atom/movable/screen/alert/status_effect/freezing_blast
duration = 5 SECONDS
status_type = STATUS_EFFECT_REPLACE
/atom/movable/screen/alert/status_effect/freezing_blast
name = "Freezing Blast"
desc = "You've been struck by a freezing blast! Your body moves more slowly!"
icon_state = "frozen"
/datum/status_effect/freezing_blast/on_apply()
owner.add_movespeed_modifier(/datum/movespeed_modifier/freezing_blast, update = TRUE)
return ..()
/datum/status_effect/freezing_blast/on_remove()
owner.remove_movespeed_modifier(/datum/movespeed_modifier/freezing_blast, update = TRUE)
/datum/movespeed_modifier/freezing_blast
multiplicative_slowdown = 1
/datum/status_effect/discoordinated
id = "discoordinated"
status_type = STATUS_EFFECT_UNIQUE
alert_type = /atom/movable/screen/alert/status_effect/discoordinated
/atom/movable/screen/alert/status_effect/discoordinated
name = "Discoordinated"
desc = "You can't seem to properly use anything..."
use_user_hud_icon = USER_HUD_STYLE_INHERIT
overlay_state = "convulsing"
/datum/status_effect/discoordinated/on_apply()
ADD_TRAIT(owner, TRAIT_DISCOORDINATED_TOOL_USER, TRAIT_STATUS_EFFECT(id))
return ..()
/datum/status_effect/discoordinated/on_remove()
REMOVE_TRAIT(owner, TRAIT_DISCOORDINATED_TOOL_USER, TRAIT_STATUS_EFFECT(id))
return ..()
///Maddly teleports the victim around all of space for 10 seconds
/datum/status_effect/teleport_madness
id = "teleport_madness"
duration = 10 SECONDS
status_type = STATUS_EFFECT_REPLACE
tick_interval = 0.2 SECONDS
alert_type = null
/datum/status_effect/teleport_madness/tick(seconds_between_ticks)
dump_in_space(owner)
/datum/status_effect/careful_driving
id = "careful_driving"
alert_type = /atom/movable/screen/alert/status_effect/careful_driving
duration = 5 SECONDS
status_type = STATUS_EFFECT_REPLACE
/datum/status_effect/careful_driving/on_apply()
. = ..()
owner.add_movespeed_modifier(/datum/movespeed_modifier/careful_driving, update = TRUE)
/datum/status_effect/careful_driving/on_remove()
. = ..()
owner.remove_movespeed_modifier(/datum/movespeed_modifier/careful_driving, update = TRUE)
/atom/movable/screen/alert/status_effect/careful_driving
name = "Careful Driving"
desc = "That was close! You almost ran that one over!"
use_user_hud_icon = USER_HUD_STYLE_INHERIT
overlay_state = "paralysis"
/datum/movespeed_modifier/careful_driving
multiplicative_slowdown = 3
/datum/status_effect/midas_blight
id = "midas_blight"
alert_type = /atom/movable/screen/alert/status_effect/midas_blight
status_type = STATUS_EFFECT_REPLACE
tick_interval = 0.2 SECONDS
remove_on_fullheal = TRUE
/// The visual overlay state, helps tell both you and enemies how much gold is in your system
var/midas_state = "midas_1"
/// How fast the gold in a person's system scales.
var/goldscale = 30 // x2.8 - Gives ~ 15u for 1 second
/datum/status_effect/midas_blight/on_creation(mob/living/new_owner, duration = 1)
// Duration is already input in SECONDS
src.duration = duration
RegisterSignal(new_owner, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(on_update_overlays))
return ..()
/atom/movable/screen/alert/status_effect/midas_blight
name = "Midas Blight"
desc = "Your blood is being turned to gold, slowing your movements!"
use_user_hud_icon = USER_HUD_STYLE_INHERIT
overlay_state = "midas_blight"
/datum/status_effect/midas_blight/tick(seconds_between_ticks)
var/mob/living/carbon/human/victim = owner
// We're transmuting blood, time to lose some.
victim.adjust_blood_volume(-5 * seconds_between_ticks, minimum = BLOOD_VOLUME_SURVIVE + 50)
// This has been hell to try and balance so that you'll actually get anything out of it
victim.reagents.add_reagent(/datum/reagent/gold/cursed, amount = seconds_between_ticks * goldscale, no_react = TRUE)
var/current_gold_amount = victim.reagents.get_reagent_amount(/datum/reagent/gold, type_check = REAGENT_SUB_TYPE)
switch(current_gold_amount)
if(-INFINITY to 50)
victim.add_movespeed_modifier(/datum/movespeed_modifier/status_effect/midas_blight/soft, update = TRUE)
victim.add_actionspeed_modifier(/datum/actionspeed_modifier/status_effect/midas_blight/soft, update = TRUE)
midas_state = "midas_1"
if(50 to 100)
victim.add_movespeed_modifier(/datum/movespeed_modifier/status_effect/midas_blight/medium, update = TRUE)
victim.add_actionspeed_modifier(/datum/actionspeed_modifier/status_effect/midas_blight/medium, update = TRUE)
midas_state = "midas_2"
if(100 to 200)
victim.add_movespeed_modifier(/datum/movespeed_modifier/status_effect/midas_blight/hard, update = TRUE)
victim.add_actionspeed_modifier(/datum/actionspeed_modifier/status_effect/midas_blight/hard, update = TRUE)
midas_state = "midas_3"
if(200 to INFINITY)
victim.add_movespeed_modifier(/datum/movespeed_modifier/status_effect/midas_blight/gold, update = TRUE)
victim.add_actionspeed_modifier(/datum/actionspeed_modifier/status_effect/midas_blight/gold, update = TRUE)
midas_state = "midas_4"
victim.update_icon()
if(victim.stat == DEAD)
qdel(src) // Dead people stop being turned to gold. Don't want people sitting on dead bodies.
/datum/status_effect/midas_blight/proc/on_update_overlays(atom/parent_atom, list/overlays)
SIGNAL_HANDLER
if(midas_state)
var/mutable_appearance/midas_overlay = mutable_appearance('icons/mob/effects/debuff_overlays.dmi', midas_state)
midas_overlay.blend_mode = BLEND_MULTIPLY
overlays += midas_overlay
/datum/status_effect/midas_blight/on_remove()
owner.remove_movespeed_modifier(MOVESPEED_ID_MIDAS_BLIGHT, update = TRUE)
owner.remove_actionspeed_modifier(ACTIONSPEED_ID_MIDAS_BLIGHT, update = TRUE)
UnregisterSignal(owner, COMSIG_ATOM_UPDATE_OVERLAYS)
owner.update_icon()
// Desginated Target - Applied typically by Flare lasers
/atom/movable/screen/alert/status_effect/designated_target
name = "Designated Target"
desc = "You've been lit up by some kind of bright energy! Wash it off to get rid of it, or you'll be a lot easier to hit!"
use_user_hud_icon = USER_HUD_STYLE_INHERIT
overlay_state = "designated_target"
/datum/status_effect/designated_target
id = "designated_target"
duration = 2 MINUTES
alert_type = /atom/movable/screen/alert/status_effect/designated_target
status_type = STATUS_EFFECT_REFRESH
/// Dummy lighting object for our flare attached to our mob
var/obj/effect/dummy/lighting_obj/moblight/mob_flare
/datum/status_effect/designated_target/on_apply()
mob_flare = owner.mob_light(3, 15, LIGHT_COLOR_FLARE)
ADD_TRAIT(owner, TRAIT_DESIGNATED_TARGET, id)
owner.add_filter("designated_target", 3, list("type" = "outline", "color" = COLOR_RED, "size" = 1))
return TRUE
/datum/status_effect/designated_target/tick(seconds_between_ticks)
// If we are ever wet, remove our flare status effect
var/datum/status_effect/fire_handler/wet_stacks/splashed_with_water = locate() in owner.status_effects
if(istype(splashed_with_water))
qdel(src)
/datum/status_effect/designated_target/on_remove()
QDEL_NULL(mob_flare)
owner.remove_filter("designated_target")
REMOVE_TRAIT(owner, TRAIT_DESIGNATED_TARGET, id)
#undef HEALING_SLEEP_DEFAULT
#undef HEALING_SLEEP_ORGAN_MULTIPLIER
#undef SLEEP_QUALITY_WORKOUT_MULTIPLER