diff --git a/code/_onclick/hud/action_button.dm b/code/_onclick/hud/action_button.dm
index 83df0c300879..29eec274c224 100644
--- a/code/_onclick/hud/action_button.dm
+++ b/code/_onclick/hud/action_button.dm
@@ -59,10 +59,10 @@
if(usr.next_click > world.time)
return
usr.next_click = world.time + 1
-// var/trigger_flags
-// if(LAZYACCESS(modifiers, RIGHT_CLICK)) FUCK COMBAT MODE!!!!
-// trigger_flags |= TRIGGER_SECONDARY_ACTION
- linked_action.Trigger()
+ var/trigger_flags
+ if(LAZYACCESS(modifiers, RIGHT_CLICK))
+ trigger_flags |= TRIGGER_SECONDARY_ACTION
+ linked_action.Trigger(trigger_flags)
SEND_SOUND(usr, get_sfx(SFX_TERMINAL_TYPE))
transform = turn(matrix() * 0.9, pick(-8, 8))
alpha = 200
diff --git a/code/datums/status_effects/debuffs/fire_stacks.dm b/code/datums/status_effects/debuffs/fire_stacks.dm
index 5263a0c39a82..fc4c1c41823c 100644
--- a/code/datums/status_effects/debuffs/fire_stacks.dm
+++ b/code/datums/status_effects/debuffs/fire_stacks.dm
@@ -126,7 +126,7 @@
id = "fire_stacks" //fire_stacks and wet_stacks should have different IDs or else has_status_effect won't work
remove_on_fullheal = TRUE
- enemy_types = list(/datum/status_effect/fire_handler/wet_stacks)
+ enemy_types = list(/datum/status_effect/fire_handler/wet_stacks, /datum/status_effect/fire_handler/shadowflame)
stack_modifier = 1
/// If we're on fire
@@ -278,7 +278,7 @@
/datum/status_effect/fire_handler/wet_stacks
id = "wet_stacks"
- enemy_types = list(/datum/status_effect/fire_handler/fire_stacks)
+ enemy_types = list(/datum/status_effect/fire_handler/fire_stacks, /datum/status_effect/fire_handler/shadowflame)
stack_modifier = -1
/datum/status_effect/fire_handler/wet_stacks/tick(delta_time, times_fired)
diff --git a/yogstation.dme b/yogstation.dme
index 3d2cdc363ce1..af23e904daf3 100644
--- a/yogstation.dme
+++ b/yogstation.dme
@@ -4238,6 +4238,7 @@
#include "yogstation\code\modules\antagonists\darkspawn\darkspawn_objects\scout_traps.dm"
#include "yogstation\code\modules\antagonists\darkspawn\darkspawn_objects\shadow_caster.dm"
#include "yogstation\code\modules\antagonists\darkspawn\darkspawn_objects\shadow_step.dm"
+#include "yogstation\code\modules\antagonists\darkspawn\darkspawn_objects\shadowflame.dm"
#include "yogstation\code\modules\antagonists\darkspawn\darkspawn_objects\thrall_tumor.dm"
#include "yogstation\code\modules\antagonists\darkspawn\darkspawn_objects\umbral_tendrils.dm"
#include "yogstation\code\modules\antagonists\darkspawn\darkspawn_objects\veil_camera.dm"
diff --git a/yogstation/code/modules/antagonists/darkspawn/_psi_web.dm b/yogstation/code/modules/antagonists/darkspawn/_psi_web.dm
index 08cee37c0bf5..1f349f1f4e8f 100644
--- a/yogstation/code/modules/antagonists/darkspawn/_psi_web.dm
+++ b/yogstation/code/modules/antagonists/darkspawn/_psi_web.dm
@@ -124,7 +124,7 @@
name = "warlock innate abilities"
desc = "apartment \"complex\"... really? I find it quite simple"
shadow_flags = DARKSPAWN_WARLOCK
- learned_abilities = list(/datum/action/cooldown/spell/touch/thrall_mind, /datum/action/cooldown/spell/release_thrall, /datum/action/cooldown/spell/pointed/darkspawn_build/thrall_cam, /datum/action/cooldown/spell/pointed/darkspawn_build/thrall_eye, /datum/action/cooldown/spell/toggle/dark_staff)
+ learned_abilities = list(/datum/action/cooldown/spell/touch/thrall_mind, /datum/action/cooldown/spell/pointed/darkspawn_build/thrall_cam, /datum/action/cooldown/spell/pointed/darkspawn_build/thrall_eye, /datum/action/cooldown/spell/toggle/dark_staff)
/datum/psi_web/warlock/on_gain()
darkspawn.psi_cap *= 2
diff --git a/yogstation/code/modules/antagonists/darkspawn/darkspawn_abilities/core_abilities.dm b/yogstation/code/modules/antagonists/darkspawn/darkspawn_abilities/core_abilities.dm
index 613553ce3768..37aa5cedd69e 100644
--- a/yogstation/code/modules/antagonists/darkspawn/darkspawn_abilities/core_abilities.dm
+++ b/yogstation/code/modules/antagonists/darkspawn/darkspawn_abilities/core_abilities.dm
@@ -18,7 +18,7 @@
//////////////////////////////////////////////////////////////////////////
/datum/action/cooldown/spell/touch/devour_will
name = "Devour Will"
- desc = "Creates a dark bead that can be used on a human to begin draining the lucidity and willpower from a living target, knocking them unconscious for a time. Being interrupted will knock you down for a time."
+ desc = "Creates a dark bead that can be used on a human to begin draining the lucidity and willpower from a living target, knocking them unconscious for a time.
Being interrupted will knock you down for a time."
panel = "Darkspawn"
button_icon = 'yogstation/icons/mob/actions/actions_darkspawn.dmi'
sound = null
diff --git a/yogstation/code/modules/antagonists/darkspawn/darkspawn_abilities/thrall_spells.dm b/yogstation/code/modules/antagonists/darkspawn/darkspawn_abilities/thrall_spells.dm
index 84203a019fbb..39791f140ca2 100644
--- a/yogstation/code/modules/antagonists/darkspawn/darkspawn_abilities/thrall_spells.dm
+++ b/yogstation/code/modules/antagonists/darkspawn/darkspawn_abilities/thrall_spells.dm
@@ -3,7 +3,7 @@
//////////////////////////////////////////////////////////////////////////
/datum/action/cooldown/spell/touch/thrall_mind
name = "Thrall mind"
- desc = "Consume 1 willpower to thrall a target's mind. To be eligible, they must be alive and recently drained by Devour Will. Can also be used to revive deceased thralls."
+ desc = "Consume 1 willpower to thrall a target's mind.
To be eligible, they must be alive and recently drained by Devour Will.
Can also be used to revive deceased thralls.
Right-click to release thralls from your control."
button_icon = 'yogstation/icons/mob/actions/actions_darkspawn.dmi'
background_icon_state = "bg_alien"
overlay_icon_state = "bg_alien_border"
@@ -19,6 +19,12 @@
///Willpower spent by the darkspawn datum to thrall a mind
var/willpower_cost = 1
+/datum/action/cooldown/spell/touch/thrall_mind/Trigger(trigger_flags, atom/target)
+ if(trigger_flags & TRIGGER_SECONDARY_ACTION)
+ release_thrall()
+ return
+ return ..()
+
/datum/action/cooldown/spell/touch/thrall_mind/can_cast_spell(feedback)
var/datum/antagonist/darkspawn/master = isdarkspawn(owner)
if(master && master.willpower < willpower_cost)
@@ -116,34 +122,10 @@
to_chat(owner, span_velvet("Your power is incapable of controlling [target]."))
return TRUE
-//////////////////////////////////////////////////////////////////////////
-//----------------------------Get rid of a thrall-----------------------//
-//////////////////////////////////////////////////////////////////////////
-/datum/action/cooldown/spell/release_thrall
- name = "Release thrall"
- desc = "Release a thrall from your control, freeing your power to be redistributed and restoring a portion of the spent willpower."
- button_icon = 'yogstation/icons/mob/actions/actions_darkspawn.dmi'
- background_icon_state = "bg_alien"
- overlay_icon_state = "bg_alien_border"
- buttontooltipstyle = "alien"
- button_icon_state = "veiling_touch"
- antimagic_flags = NONE
- panel = "Darkspawn"
- check_flags = AB_CHECK_CONSCIOUS
- spell_requirements = SPELL_CASTABLE_AS_BRAIN
-
-/datum/action/cooldown/spell/release_thrall/can_cast_spell(feedback)
- var/datum/antagonist/darkspawn/dude = isdarkspawn(owner)
- if(dude && istype(dude))
- var/datum/team/darkspawn/team = dude.get_team()
- if(team &&!LAZYLEN(team.thralls))
- if(feedback)
- to_chat(owner, "You have no thralls to release.")
- return
- return ..()
-
-/datum/action/cooldown/spell/release_thrall/cast(atom/cast_on)
- . = ..()
+/**
+ * Release a thrall if right click
+ */
+/datum/action/cooldown/spell/touch/thrall_mind/proc/release_thrall()
if(!isdarkspawn(owner))
return
@@ -153,6 +135,10 @@
var/datum/team/darkspawn/team = dude.get_team()
+ if(!LAZYLEN(team.thralls))
+ to_chat(owner, "You have no thralls to release.")
+ return
+
var/loser = tgui_input_list(owner, "Select a thrall to release from your control.", "Release a thrall", team.thralls)
if(!loser || !istype(loser, /datum/mind))
return
diff --git a/yogstation/code/modules/antagonists/darkspawn/darkspawn_abilities/warlock_abilities.dm b/yogstation/code/modules/antagonists/darkspawn/darkspawn_abilities/warlock_abilities.dm
index b3181329c853..b20ce79834b4 100644
--- a/yogstation/code/modules/antagonists/darkspawn/darkspawn_abilities/warlock_abilities.dm
+++ b/yogstation/code/modules/antagonists/darkspawn/darkspawn_abilities/warlock_abilities.dm
@@ -552,6 +552,8 @@
name = "echoing void"
icon = 'yogstation/icons/effects/effects.dmi'
icon_state = "nothing"
+ anchored = TRUE
+ move_resist = INFINITY
/obj/effect/temp_visual/darkspawn/chasm //a slow field that eventually explodes
icon_state = "consuming"
@@ -693,3 +695,42 @@
/datum/action/cooldown/spell/pointed/null_burst/proc/spawn_ground(turf/target)
new /obj/effect/temp_visual/darkspawn/chasm(target)
+
+//////////////////////////////////////////////////////////////////////////
+//----------------------I stole genetics fire breath--------------------//
+//////////////////////////////////////////////////////////////////////////
+/datum/action/cooldown/spell/cone/staggered/shadowflame
+ name = "Shadowflame Gout"
+ desc = "Release a burst of shadowflame, rapidly sapping the heat of any individual."
+ button_icon = 'yogstation/icons/mob/actions/actions_darkspawn.dmi'
+ background_icon_state = "bg_alien"
+ overlay_icon_state = "bg_alien_border"
+ buttontooltipstyle = "alien"
+ button_icon_state = "veiling_touch"
+ panel = "Darkspawn"
+ sound = 'sound/magic/demon_dies.ogg'
+
+ school = SCHOOL_EVOCATION
+ invocation_type = INVOCATION_NONE
+ spell_requirements = NONE
+ antimagic_flags = MAGIC_RESISTANCE_MIND
+ check_flags = AB_CHECK_CONSCIOUS
+ cooldown_time = 60 SECONDS
+ resource_costs = list(ANTAG_RESOURCE_DARKSPAWN = 100) //dangerous, high CC, and area denial
+
+ delay_between_level = 0.3 SECONDS //longer delay
+ cone_levels = 5 //longer cone
+ respect_density = TRUE
+
+/datum/action/cooldown/spell/cone/staggered/shadowflame/do_turf_cone_effect(turf/target_turf, atom/caster, level)
+ target_turf.extinguish_turf()
+ new /obj/effect/temp_visual/darkspawn/shadowflame(target_turf) // for style
+
+/datum/action/cooldown/spell/cone/staggered/shadowflame/do_mob_cone_effect(mob/living/target_mob, atom/caster, level)
+ target_mob.set_wet_stacks(20, /datum/status_effect/fire_handler/shadowflame)
+
+/datum/action/cooldown/spell/cone/staggered/shadowflame/calculate_cone_shape(current_level)
+ // This makes the cone shoot out into a 3 wide column of flames.
+ // You may be wondering, "that equation doesn't seem like it'd make a 3 wide column"
+ // well it does, and that's all that matters.
+ return (2 * current_level) - 1
diff --git a/yogstation/code/modules/antagonists/darkspawn/darkspawn_objects/shadowflame.dm b/yogstation/code/modules/antagonists/darkspawn/darkspawn_objects/shadowflame.dm
new file mode 100644
index 000000000000..257e4cea14c9
--- /dev/null
+++ b/yogstation/code/modules/antagonists/darkspawn/darkspawn_objects/shadowflame.dm
@@ -0,0 +1,77 @@
+//////////////////////////////////////////////////////////////////////////
+//--------------------------Cold Fire instead of hot--------------------//
+//////////////////////////////////////////////////////////////////////////
+/obj/effect/dummy/lighting_obj/moblight/shadowflame
+ name = "fire"
+ light_power = -1
+ light_range = LIGHT_RANGE_FIRE
+ light_color = COLOR_VELVET
+
+/datum/status_effect/fire_handler/shadowflame
+ id = "shadowflame"
+ override_types = list(/datum/status_effect/fire_handler/fire_stacks, /datum/status_effect/fire_handler/wet_stacks)
+ stack_modifier = -1
+ /// Reference to the mob light emitter itself
+ var/obj/effect/dummy/lighting_obj/moblight
+ /// Type of mob light emitter we use when on fire
+ var/moblight_type = /obj/effect/dummy/lighting_obj/moblight/shadowflame
+ //how cold this fire is
+ var/temperature = 0
+
+/datum/status_effect/fire_handler/shadowflame/on_apply()
+ . = ..()
+ owner.add_emitter(/obj/emitter/fire/shadow, "shadowflame")
+
+/datum/status_effect/fire_handler/shadowflame/on_remove()
+ owner.remove_emitter("shadowflame")
+ return ..()
+
+/datum/status_effect/fire_handler/shadowflame/tick(delta_time, times_fired)
+ adjust_stacks(-0.75 * delta_time SECONDS) //change this number to make it last a shorter duration
+ if(stacks <= 0)
+ qdel(src)
+ return
+
+ if(is_team_darkspawn(owner) || !ishuman(owner))
+ return
+
+ var/mob/living/carbon/human/victim = owner
+ var/thermal_multiplier = 1 - victim.get_cold_protection(temperature)
+
+ var/calculated_cooling = (BODYTEMP_COOLING_MAX - (stacks * 12)) * 0.5 * (delta_time SECONDS) * thermal_multiplier
+ victim.adjust_bodytemperature(calculated_cooling, temperature)
+
+ if(HAS_TRAIT(victim, TRAIT_RESISTCOLD) || !calculated_cooling)
+ SEND_SIGNAL(owner, COMSIG_CLEAR_MOOD_EVENT, "on_fire")
+ else
+ SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "on_fire", /datum/mood_event/on_fire)
+
+/// Cold purple turf fire
+/obj/effect/temp_visual/darkspawn/shadowflame
+ icon = 'icons/effects/turf_fire.dmi'
+ icon_state = "white_big"
+ layer = GASFIRE_LAYER
+ light_system = MOVABLE_LIGHT //we make it a movable light because static lights colour is handled weirdly
+ light_power = -1
+ light_range = LIGHT_RANGE_FIRE
+ light_color = COLOR_VELVET
+ color = COLOR_DARKSPAWN_PSI
+ mouse_opacity = FALSE
+ duration = 10 SECONDS
+
+/obj/effect/temp_visual/darkspawn/shadowflame/Initialize(mapload)
+ . = ..()
+ START_PROCESSING(SSfastprocess, src)
+
+/obj/effect/temp_visual/darkspawn/shadowflame/Destroy()
+ STOP_PROCESSING(SSfastprocess, src)
+ return ..()
+
+/obj/effect/temp_visual/darkspawn/shadowflame/process(delta_time)
+ var/turf/placement = get_turf(src)
+ for(var/mob/living/target_mob in placement.contents)
+ target_mob.set_wet_stacks(20, /datum/status_effect/fire_handler/shadowflame)
+
+/obj/emitter/fire/shadow
+ pixel_y = -16 //so it aligns with the floor
+ fire_colour = COLOR_VELVET
diff --git a/yogstation/code/modules/antagonists/darkspawn/darkspawn_upgrades/offensive_upgrades.dm b/yogstation/code/modules/antagonists/darkspawn/darkspawn_upgrades/offensive_upgrades.dm
index ab83a590c68b..77647eca3bef 100644
--- a/yogstation/code/modules/antagonists/darkspawn/darkspawn_upgrades/offensive_upgrades.dm
+++ b/yogstation/code/modules/antagonists/darkspawn/darkspawn_upgrades/offensive_upgrades.dm
@@ -147,7 +147,7 @@
desc = "Empower your staff with the ability to consume the light of anything shot."
lore_description = "The Aaah'ryt sigil, representing consumption, is etched onto the staff."
icon_state = "lighteater_sign"
- willpower_cost = 2
+ willpower_cost = 1
shadow_flags = DARKSPAWN_WARLOCK
menu_tab = STORE_OFFENSE
flag_to_add = STAFF_UPGRADE_LIGHTEATER
@@ -193,6 +193,16 @@
menu_tab = STORE_OFFENSE
learned_abilities = list(/datum/action/cooldown/spell/pointed/darkspawn_build/abyssal_call)
+/datum/psi_web/shadowflame
+ name = "Shadowflame Gout"
+ desc = "Release a burst of shadowflame, rapidly sapping the heat of any individual."
+ lore_description = "An abhorrent inversion of the natural laws of thermodynamics."
+ icon_state = "veiling_touch" //needs an icon
+ willpower_cost = 2
+ shadow_flags = DARKSPAWN_WARLOCK
+ menu_tab = STORE_OFFENSE
+ learned_abilities = list(/datum/action/cooldown/spell/cone/staggered/shadowflame)
+
/datum/psi_web/shadow_beam
name = "Void Beam"
desc = "After a short delay, fire a huge beam of void terrain across the entire station."
@@ -207,7 +217,7 @@
name = "Null Burst"
desc = "After a short delay, create an explosion of void terrain at the targeted location."
lore_description = "Tears a portion of reality into the void for a short duration."
- icon_state = "null_burst" //needs an icon
+ icon_state = "null_burst"
willpower_cost = 3
shadow_flags = DARKSPAWN_WARLOCK
menu_tab = STORE_OFFENSE