Skip to content

Commit

Permalink
Rework how darkspawn devour will works (#22957)
Browse files Browse the repository at this point in the history
* rework progress

* Update thrall_tumor.dm

* tweaks

* more words and number tweaks

* Update thrall_tumor.dm
  • Loading branch information
Moltijoe authored Jan 14, 2025
1 parent 3d35c4f commit 4c9f485
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 166 deletions.
2 changes: 0 additions & 2 deletions code/__DEFINES/status_effects.dm
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,6 @@

#define STATUS_EFFECT_BROKEN_WILL /datum/status_effect/broken_will //A 30-second sleep effect, ends instantly upon taking enough damage in a single hit. //Yogs

#define STATUS_EFFECT_DEVOURED_WILL /datum/status_effect/devoured_will //A 3 minute long status effect that prevents using devour will on the owner

#define STATUS_EFFECT_AMOK /datum/status_effect/amok //Makes the target automatically strike out at adjecent non-heretics.

#define STATUS_EFFECT_CLOUDSTRUCK /datum/status_effect/cloudstruck //blinds and applies an overlay.
Expand Down
7 changes: 0 additions & 7 deletions code/datums/status_effects/debuffs/debuffs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -1084,13 +1084,6 @@
icon_state = "broken_will"
alerttooltipstyle = "alien"

//used to prevent the use of devour will on the target
/datum/status_effect/devoured_will
id = "devoured_will"
status_type = STATUS_EFFECT_UNIQUE
duration = 3 MINUTES
alert_type = null

/datum/status_effect/eldritch
duration = 15 SECONDS
status_type = STATUS_EFFECT_REPLACE
Expand Down
4 changes: 2 additions & 2 deletions code/modules/surgery/organ_manipulation.dm
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,8 @@
H.leave_victim()
return FALSE
if(I && I.owner == target)
if(istype(I, /obj/item/organ/shadowtumor))//Thralls resist deconversion
var/obj/item/organ/shadowtumor/tumor = I
if(istype(I, /obj/item/organ/shadowtumor/thrall))//Thralls resist deconversion
var/obj/item/organ/shadowtumor/thrall/tumor = I
if(tumor.resist(target))
return FALSE
display_results(user, target, span_notice("You successfully extract [I] from [target]'s [parse_zone(target_zone)]."),
Expand Down
2 changes: 1 addition & 1 deletion yogstation/code/modules/antagonists/darkspawn/_psi_web.dm
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
name = "darkspawn progression abilities"
desc = "me no think so good"
shadow_flags = ALL_DARKSPAWN_CLASSES
learned_abilities = list(/datum/action/cooldown/spell/sacrament, /datum/action/cooldown/spell/touch/restrain_body, /datum/action/cooldown/spell/touch/devour_will)
learned_abilities = list(/datum/action/cooldown/spell/sacrament, /datum/action/cooldown/spell/touch/devour_will)

////////////////////////////////////////////////////////////////////////////////////
//----------------------Specialization innate Upgrades----------------------------//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
//////////////////////////////////////////////////////////////////////////
/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.<br>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.\
<br>Being interrupted will knock you down for a time."
panel = "Darkspawn"
button_icon = 'yogstation/icons/mob/actions/actions_darkspawn.dmi'
sound = null
Expand Down Expand Up @@ -61,11 +62,16 @@
if(target.stat == DEAD)
to_chat(caster, span_warning("[target] is too weak to drain."))
return
if(target.has_status_effect(STATUS_EFFECT_DEVOURED_WILL))
to_chat(caster, span_warning("[target]'s mind has not yet recovered enough willpower to be worth devouring."))
return
if(get_shadow_tumor(target))
to_chat(owner, span_danger("[target] already has a dark bead lodged within their psyche."))
return FALSE

var/datum/team/darkspawn/team = darkspawn.get_team()
if(!team)
CRASH("darkspawn without a team is trying to thrall someone")

caster.Immobilize(1 SECONDS) // So they don't accidentally move while beading
target.Immobilize(10 SECONDS) //we remove this if it's canceled early
target.silent += 5

caster.balloon_alert(caster, "Cera ko...")
Expand All @@ -76,134 +82,53 @@

eating = TRUE
if(!do_after(caster, 5 SECONDS, target))
to_chat(caster, span_danger("Being interrupted causes a backlash of psionic power."))
caster.Immobilize(5 SECONDS)
caster.Knockdown(10 SECONDS)
to_chat(target, span_boldwarning("All right... You're all right."))
caster.Knockdown(5 SECONDS)
target.SetImmobilized(0)
eating = FALSE
return FALSE
eating = FALSE

if(target.has_status_effect(STATUS_EFFECT_DEVOURED_WILL))
to_chat(caster, span_warning("[target]'s mind has not yet recovered enough willpower to be worth devouring."))
return
if(get_shadow_tumor(target))
to_chat(owner, span_danger("[target] already has a dark bead lodged within their psyche."))
return FALSE

//put the victim to sleep before the visible_message proc so the victim doesn't see it
to_chat(target, span_progenitor("You suddenly feel... empty. Thoughts try to form, but flit away. You slip into a deep, deep slumber..."))
playsound(target, 'yogstation/sound/magic/devour_will_end.ogg', 75, FALSE)
target.playsound_local(target, 'yogstation/sound/magic/devour_will_victim.ogg', 50, FALSE)
target.Unconscious(5 SECONDS)

//get how much lucidity and willpower will be given
var/willpower_amount = 2
var/lucidity_amount = 1
if(HAS_TRAIT(target, TRAIT_DARKSPAWN_DEVOURED)) //change the numbers before text
lucidity_amount = 0
willpower_amount *= 0.5
willpower_amount = round(willpower_amount) //make sure it's a whole number still

//format the text output to the darkspawn
var/list/self_text = list()

caster.balloon_alert(caster, "...akkraup'dej")
self_text += span_velvet("You devour [target]'s will.")
if(HAS_TRAIT(target, TRAIT_DARKSPAWN_DEVOURED))
self_text += span_warning("[target]'s mind is already damaged by previous devouring and has granted less willpower and no lucidity.")
else
self_text += span_velvet("This individual's lucidity brings you one step closer to the sacrament...")
self_text += span_warning("After meddling with [target]'s mind, they will grant less willpower and no lucidity any future times their will is devoured.")
self_text += span_warning("[target] is now severely weakened and will take some time to recover.")
caster.visible_message(span_warning("[caster] gently lowers [target] to the ground..."), self_text.Join("<br>"))

//pass out the willpower and lucidity to the darkspawns
var/datum/team/darkspawn/team = darkspawn.get_team()
if(team)
team.grant_willpower(willpower_amount)
team.grant_lucidity(lucidity_amount)

//apply the long-term debuffs to the victim
target.apply_status_effect(STATUS_EFFECT_BROKEN_WILL)
target.apply_status_effect(STATUS_EFFECT_DEVOURED_WILL)
ADD_TRAIT(target, TRAIT_DARKSPAWN_DEVOURED, type)
return TRUE

//////////////////////////////////////////////////////////////////////////
//--------------------------Glorified handcuffs-------------------------//
//////////////////////////////////////////////////////////////////////////
/datum/action/cooldown/spell/touch/restrain_body
name = "Restrain body"
desc = "Forms rudimentary restraints on a target's hands."
panel = "Darkspawn"
button_icon = 'yogstation/icons/mob/actions/actions_darkspawn.dmi'
sound = null
background_icon_state = "bg_alien"
overlay_icon_state = "bg_alien_border"
buttontooltipstyle = "alien"
button_icon_state = "restrain_body"
check_flags = AB_CHECK_HANDS_BLOCKED | AB_CHECK_IMMOBILE | AB_CHECK_LYING | AB_CHECK_CONSCIOUS
spell_requirements = SPELL_REQUIRES_HUMAN
invocation_type = INVOCATION_NONE
hand_path = /obj/item/melee/touch_attack/darkspawn
resource_costs = list(ANTAG_RESOURCE_DARKSPAWN = 5)
//Boolean on whether we're tying someone's hands
var/tying = FALSE

/datum/action/cooldown/spell/touch/restrain_body/can_cast_spell(feedback)
if(tying)
return
return ..()

/datum/action/cooldown/spell/touch/restrain_body/is_valid_target(atom/cast_on)
return iscarbon(cast_on)

/datum/action/cooldown/spell/touch/restrain_body/cast_on_hand_hit(obj/item/melee/touch_attack/hand, mob/living/carbon/target, mob/living/carbon/caster)
var/datum/antagonist/darkspawn/darkspawn = isdarkspawn(caster)
if(!darkspawn || tying || target == caster) //no tying yourself
return
if(is_team_darkspawn(target))
to_chat(caster, span_warning("You cannot restrain allies."))
return
if(!istype(target))
to_chat(caster, span_warning("[target]'s mind is too pitiful to be of any use."))
return
if(target.handcuffed)
to_chat(caster, span_warning("[target] is already restrained."))
return

caster.balloon_alert(caster, "Koce ra...")
to_chat(caster, span_velvet("You begin restraining [target]..."))
playsound(target, 'yogstation/sound/ambience/antag/veil_mind_gasp.ogg', 50, TRUE)
tying = TRUE
if(!do_after(caster, 1.5 SECONDS, target, progress = FALSE))
tying = FALSE
return FALSE
tying = FALSE
var/obj/item/organ/shadowtumor/bead = target.getorganslot(ORGAN_SLOT_BRAIN_TUMOR)
if(!bead || !istype(bead))
bead = new
bead.Insert(target, FALSE, FALSE)
bead.antag_team = team

target.silent += 5

if(target.handcuffed)
to_chat(caster, span_warning("[target] is already restrained."))
return
//pass out the willpower and lucidity to the darkspawns
if(!HAS_TRAIT(target, TRAIT_DARKSPAWN_DEVOURED))
ADD_TRAIT(target, TRAIT_DARKSPAWN_DEVOURED, type)
self_text += span_velvet("You place a dark bead deep within [target]'s psyche.")
self_text += span_velvet("This individual's lucidity brings you one step closer to the sacrament...")
self_text += span_velvet("You also feed off their will to fuel your growth, generating 2 willpower.")
self_text += span_velvet("No further attempts to drain this individual will provide willpower or lucidity.")
team.grant_willpower(2)
team.grant_lucidity(1)
else
self_text += span_velvet("You replace the dark bead deep within [target]'s psyche.")

playsound(target, 'yogstation/sound/magic/devour_will_form.ogg', 50, TRUE)
target.set_handcuffed(new /obj/item/restraints/handcuffs/darkspawn(target))
target.update_handcuffed()
caster.visible_message(span_warning("[caster] gently lowers [target] to the ground..."), self_text.Join("<br>"))

//apply the long-term debuff to the victim
target.apply_status_effect(STATUS_EFFECT_BROKEN_WILL)
return TRUE

//the restrains in question
/obj/item/restraints/handcuffs/darkspawn
name = "shadow stitched restraints"
desc = "Bindings created by stitching together shadows."
icon_state = "handcuffAlien"
lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
breakouttime = 30 SECONDS
flags_1 = NONE
item_flags = DROPDEL

/obj/item/restraints/handcuffs/darkspawn/Initialize(mapload)
. = ..()
add_atom_colour(COLOR_VELVET, FIXED_COLOUR_PRIORITY)

//////////////////////////////////////////////////////////////////////////
//-----------------------Recall shuttle ability-------------------------//
//////////////////////////////////////////////////////////////////////////
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@
var/datum/antagonist/darkspawn/master = isdarkspawn(caster)

if(!isthrall(target))
if(!target.has_status_effect(STATUS_EFFECT_DEVOURED_WILL))
to_chat(owner, span_danger("[target]'s will is still too strong to thrall."))
return FALSE
if(master.willpower < willpower_cost)
to_chat(owner, span_danger("You do not have enough will to thrall [target]."))
return FALSE
if(!get_shadow_tumor(target))
to_chat(owner, span_danger("[target] does not have a shadow bead for you to enhance."))
return FALSE

owner.balloon_alert(owner, "Krx'lna tyhx graha...")
to_chat(owner, span_velvet("You begin to channel your psionic powers through [target]'s mind."))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
slot = ORGAN_SLOT_BRAIN_TUMOR
///How many process ticks the organ can be in light before it evaporates
var/organ_health = 3
///adds a cooldown to the resist so a thrall ipc or preternis can't weaponize it
COOLDOWN_DECLARE(resist_cooldown)
///How long the resist cooldown is
var/cooldown_length = 15 SECONDS
///Cached darkspawn team that gets the willpower
var/datum/team/darkspawn/antag_team
///How much willpower is granted by this tumor
var/willpower_amount = 1

/obj/item/organ/shadowtumor/New()
..()
Expand All @@ -22,9 +22,6 @@
..()

/obj/item/organ/shadowtumor/process()
if(!isthrall(owner))
qdel(src)
return
if(isturf(loc))
var/turf/T = loc
var/light_count = T.get_lumcount()
Expand All @@ -37,12 +34,31 @@
qdel(src)
else
organ_health = min(organ_health+0.5, 3)
if(owner && owner.stat != DEAD && antag_team)
antag_team.willpower_progress(willpower_amount)

/obj/item/organ/shadowtumor/on_find(mob/living/finder)
. = ..()
finder.visible_message(span_danger("[finder] opens up [owner]'s skull, revealing a pulsating black mass, with red tendrils attaching it to [owner.p_their()] brain."))

/obj/item/organ/shadowtumor/proc/resist(mob/living/carbon/M)
////////////////////////////////////////////////////////////////////////////////////
//------------------------------Thrall version------------------------------------//
////////////////////////////////////////////////////////////////////////////////////
/obj/item/organ/shadowtumor/thrall
//provides extra willpower because willpower was spent to thrall someone
willpower_amount = 2
///adds a cooldown to the resist so a thrall ipc or preternis can't weaponize it
COOLDOWN_DECLARE(resist_cooldown)
///How long the resist cooldown is
var/cooldown_length = 15 SECONDS

/obj/item/organ/shadowtumor/thrall/process()
if(!isthrall(owner))
qdel(src)
return
return ..()

/obj/item/organ/shadowtumor/thrall/proc/resist(mob/living/carbon/M)
if(QDELETED(src))
return FALSE
if(!(M.stat == CONSCIOUS))//Thralls cannot be deconverted while awake
Expand Down
16 changes: 13 additions & 3 deletions yogstation/code/modules/antagonists/darkspawn/darkspawn_team.dm
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
var/list/datum/mind/thralls = list()
///The number of drains required to perform the sacrament
var/required_succs = 10 //How many succs are needed (this is changed in pre_setup, so it scales based on pop)
///How much progress towards generating a willpower via tumors
var/current_willpower_progress = 0
///How much progress until another willpower is awarded
var/max_willpower_progress = 100
///How many drains have happened so far
var/lucidity = 0
///The max number of people that can be actively converted
Expand Down Expand Up @@ -109,13 +113,19 @@
////////////////////////////////////////////////////////////////////////////////////
//-----------------------------Special antag procs--------------------------------//
////////////////////////////////////////////////////////////////////////////////////
/datum/team/darkspawn/proc/grant_willpower(amount = 1, silent = FALSE)
/datum/team/darkspawn/proc/willpower_progress(amount = 1)
current_willpower_progress += amount
if(current_willpower_progress >= max_willpower_progress)
current_willpower_progress -= max_willpower_progress
max_willpower_progress *= 1.1 //gets harder to get more willpower with every willpower granted to reduce snowballing
grant_willpower(1)

//give a willpower to every darkspawn on the team
/datum/team/darkspawn/proc/grant_willpower(amount = 1)
for(var/datum/mind/master in members)
if(master.has_antag_datum(/datum/antagonist/darkspawn)) //sanity check
var/datum/antagonist/darkspawn/antag = master.has_antag_datum(/datum/antagonist/darkspawn)
antag.willpower += amount
if(!silent && master.current)
to_chat(master.current, span_velvet("You have gained [amount] willpower."))

/datum/team/darkspawn/proc/grant_lucidity(amount = 1)
lucidity += amount
Expand Down
Loading

0 comments on commit 4c9f485

Please sign in to comment.