Skip to content
This repository was archived by the owner on May 22, 2025. It is now read-only.

Commit 4c9f485

Browse files
authored
Rework how darkspawn devour will works (#22957)
* rework progress * Update thrall_tumor.dm * tweaks * more words and number tweaks * Update thrall_tumor.dm
1 parent 3d35c4f commit 4c9f485

File tree

9 files changed

+98
-166
lines changed

9 files changed

+98
-166
lines changed

code/__DEFINES/status_effects.dm

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,6 @@
144144

145145
#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
146146

147-
#define STATUS_EFFECT_DEVOURED_WILL /datum/status_effect/devoured_will //A 3 minute long status effect that prevents using devour will on the owner
148-
149147
#define STATUS_EFFECT_AMOK /datum/status_effect/amok //Makes the target automatically strike out at adjecent non-heretics.
150148

151149
#define STATUS_EFFECT_CLOUDSTRUCK /datum/status_effect/cloudstruck //blinds and applies an overlay.

code/datums/status_effects/debuffs/debuffs.dm

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,13 +1084,6 @@
10841084
icon_state = "broken_will"
10851085
alerttooltipstyle = "alien"
10861086

1087-
//used to prevent the use of devour will on the target
1088-
/datum/status_effect/devoured_will
1089-
id = "devoured_will"
1090-
status_type = STATUS_EFFECT_UNIQUE
1091-
duration = 3 MINUTES
1092-
alert_type = null
1093-
10941087
/datum/status_effect/eldritch
10951088
duration = 15 SECONDS
10961089
status_type = STATUS_EFFECT_REPLACE

code/modules/surgery/organ_manipulation.dm

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,8 @@
170170
H.leave_victim()
171171
return FALSE
172172
if(I && I.owner == target)
173-
if(istype(I, /obj/item/organ/shadowtumor))//Thralls resist deconversion
174-
var/obj/item/organ/shadowtumor/tumor = I
173+
if(istype(I, /obj/item/organ/shadowtumor/thrall))//Thralls resist deconversion
174+
var/obj/item/organ/shadowtumor/thrall/tumor = I
175175
if(tumor.resist(target))
176176
return FALSE
177177
display_results(user, target, span_notice("You successfully extract [I] from [target]'s [parse_zone(target_zone)]."),

yogstation/code/modules/antagonists/darkspawn/_psi_web.dm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@
8686
name = "darkspawn progression abilities"
8787
desc = "me no think so good"
8888
shadow_flags = ALL_DARKSPAWN_CLASSES
89-
learned_abilities = list(/datum/action/cooldown/spell/sacrament, /datum/action/cooldown/spell/touch/restrain_body, /datum/action/cooldown/spell/touch/devour_will)
89+
learned_abilities = list(/datum/action/cooldown/spell/sacrament, /datum/action/cooldown/spell/touch/devour_will)
9090

9191
////////////////////////////////////////////////////////////////////////////////////
9292
//----------------------Specialization innate Upgrades----------------------------//

yogstation/code/modules/antagonists/darkspawn/darkspawn_abilities/core_abilities.dm

Lines changed: 36 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
//////////////////////////////////////////////////////////////////////////
1919
/datum/action/cooldown/spell/touch/devour_will
2020
name = "Devour Will"
21-
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."
21+
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.\
22+
<br>Being interrupted will knock you down for a time."
2223
panel = "Darkspawn"
2324
button_icon = 'yogstation/icons/mob/actions/actions_darkspawn.dmi'
2425
sound = null
@@ -61,11 +62,16 @@
6162
if(target.stat == DEAD)
6263
to_chat(caster, span_warning("[target] is too weak to drain."))
6364
return
64-
if(target.has_status_effect(STATUS_EFFECT_DEVOURED_WILL))
65-
to_chat(caster, span_warning("[target]'s mind has not yet recovered enough willpower to be worth devouring."))
66-
return
65+
if(get_shadow_tumor(target))
66+
to_chat(owner, span_danger("[target] already has a dark bead lodged within their psyche."))
67+
return FALSE
68+
69+
var/datum/team/darkspawn/team = darkspawn.get_team()
70+
if(!team)
71+
CRASH("darkspawn without a team is trying to thrall someone")
6772

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

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

7783
eating = TRUE
7884
if(!do_after(caster, 5 SECONDS, target))
85+
to_chat(caster, span_danger("Being interrupted causes a backlash of psionic power."))
86+
caster.Immobilize(5 SECONDS)
87+
caster.Knockdown(10 SECONDS)
7988
to_chat(target, span_boldwarning("All right... You're all right."))
80-
caster.Knockdown(5 SECONDS)
89+
target.SetImmobilized(0)
8190
eating = FALSE
8291
return FALSE
8392
eating = FALSE
8493

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

8998
//put the victim to sleep before the visible_message proc so the victim doesn't see it
9099
to_chat(target, span_progenitor("You suddenly feel... empty. Thoughts try to form, but flit away. You slip into a deep, deep slumber..."))
91100
playsound(target, 'yogstation/sound/magic/devour_will_end.ogg', 75, FALSE)
92101
target.playsound_local(target, 'yogstation/sound/magic/devour_will_victim.ogg', 50, FALSE)
93-
target.Unconscious(5 SECONDS)
94-
95-
//get how much lucidity and willpower will be given
96-
var/willpower_amount = 2
97-
var/lucidity_amount = 1
98-
if(HAS_TRAIT(target, TRAIT_DARKSPAWN_DEVOURED)) //change the numbers before text
99-
lucidity_amount = 0
100-
willpower_amount *= 0.5
101-
willpower_amount = round(willpower_amount) //make sure it's a whole number still
102102

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

106106
caster.balloon_alert(caster, "...akkraup'dej")
107-
self_text += span_velvet("You devour [target]'s will.")
108-
if(HAS_TRAIT(target, TRAIT_DARKSPAWN_DEVOURED))
109-
self_text += span_warning("[target]'s mind is already damaged by previous devouring and has granted less willpower and no lucidity.")
110-
else
111-
self_text += span_velvet("This individual's lucidity brings you one step closer to the sacrament...")
112-
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.")
113-
self_text += span_warning("[target] is now severely weakened and will take some time to recover.")
114-
caster.visible_message(span_warning("[caster] gently lowers [target] to the ground..."), self_text.Join("<br>"))
115-
116-
//pass out the willpower and lucidity to the darkspawns
117-
var/datum/team/darkspawn/team = darkspawn.get_team()
118-
if(team)
119-
team.grant_willpower(willpower_amount)
120-
team.grant_lucidity(lucidity_amount)
121-
122-
//apply the long-term debuffs to the victim
123-
target.apply_status_effect(STATUS_EFFECT_BROKEN_WILL)
124-
target.apply_status_effect(STATUS_EFFECT_DEVOURED_WILL)
125-
ADD_TRAIT(target, TRAIT_DARKSPAWN_DEVOURED, type)
126-
return TRUE
127-
128-
//////////////////////////////////////////////////////////////////////////
129-
//--------------------------Glorified handcuffs-------------------------//
130-
//////////////////////////////////////////////////////////////////////////
131-
/datum/action/cooldown/spell/touch/restrain_body
132-
name = "Restrain body"
133-
desc = "Forms rudimentary restraints on a target's hands."
134-
panel = "Darkspawn"
135-
button_icon = 'yogstation/icons/mob/actions/actions_darkspawn.dmi'
136-
sound = null
137-
background_icon_state = "bg_alien"
138-
overlay_icon_state = "bg_alien_border"
139-
buttontooltipstyle = "alien"
140-
button_icon_state = "restrain_body"
141-
check_flags = AB_CHECK_HANDS_BLOCKED | AB_CHECK_IMMOBILE | AB_CHECK_LYING | AB_CHECK_CONSCIOUS
142-
spell_requirements = SPELL_REQUIRES_HUMAN
143-
invocation_type = INVOCATION_NONE
144-
hand_path = /obj/item/melee/touch_attack/darkspawn
145-
resource_costs = list(ANTAG_RESOURCE_DARKSPAWN = 5)
146-
//Boolean on whether we're tying someone's hands
147-
var/tying = FALSE
148-
149-
/datum/action/cooldown/spell/touch/restrain_body/can_cast_spell(feedback)
150-
if(tying)
151-
return
152-
return ..()
153-
154-
/datum/action/cooldown/spell/touch/restrain_body/is_valid_target(atom/cast_on)
155-
return iscarbon(cast_on)
156-
157-
/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)
158-
var/datum/antagonist/darkspawn/darkspawn = isdarkspawn(caster)
159-
if(!darkspawn || tying || target == caster) //no tying yourself
160-
return
161-
if(is_team_darkspawn(target))
162-
to_chat(caster, span_warning("You cannot restrain allies."))
163-
return
164-
if(!istype(target))
165-
to_chat(caster, span_warning("[target]'s mind is too pitiful to be of any use."))
166-
return
167-
if(target.handcuffed)
168-
to_chat(caster, span_warning("[target] is already restrained."))
169-
return
170107

171-
caster.balloon_alert(caster, "Koce ra...")
172-
to_chat(caster, span_velvet("You begin restraining [target]..."))
173-
playsound(target, 'yogstation/sound/ambience/antag/veil_mind_gasp.ogg', 50, TRUE)
174-
tying = TRUE
175-
if(!do_after(caster, 1.5 SECONDS, target, progress = FALSE))
176-
tying = FALSE
177-
return FALSE
178-
tying = FALSE
108+
var/obj/item/organ/shadowtumor/bead = target.getorganslot(ORGAN_SLOT_BRAIN_TUMOR)
109+
if(!bead || !istype(bead))
110+
bead = new
111+
bead.Insert(target, FALSE, FALSE)
112+
bead.antag_team = team
179113

180-
target.silent += 5
181-
182-
if(target.handcuffed)
183-
to_chat(caster, span_warning("[target] is already restrained."))
184-
return
114+
//pass out the willpower and lucidity to the darkspawns
115+
if(!HAS_TRAIT(target, TRAIT_DARKSPAWN_DEVOURED))
116+
ADD_TRAIT(target, TRAIT_DARKSPAWN_DEVOURED, type)
117+
self_text += span_velvet("You place a dark bead deep within [target]'s psyche.")
118+
self_text += span_velvet("This individual's lucidity brings you one step closer to the sacrament...")
119+
self_text += span_velvet("You also feed off their will to fuel your growth, generating 2 willpower.")
120+
self_text += span_velvet("No further attempts to drain this individual will provide willpower or lucidity.")
121+
team.grant_willpower(2)
122+
team.grant_lucidity(1)
123+
else
124+
self_text += span_velvet("You replace the dark bead deep within [target]'s psyche.")
185125

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

128+
//apply the long-term debuff to the victim
129+
target.apply_status_effect(STATUS_EFFECT_BROKEN_WILL)
190130
return TRUE
191131

192-
//the restrains in question
193-
/obj/item/restraints/handcuffs/darkspawn
194-
name = "shadow stitched restraints"
195-
desc = "Bindings created by stitching together shadows."
196-
icon_state = "handcuffAlien"
197-
lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi'
198-
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
199-
breakouttime = 30 SECONDS
200-
flags_1 = NONE
201-
item_flags = DROPDEL
202-
203-
/obj/item/restraints/handcuffs/darkspawn/Initialize(mapload)
204-
. = ..()
205-
add_atom_colour(COLOR_VELVET, FIXED_COLOUR_PRIORITY)
206-
207132
//////////////////////////////////////////////////////////////////////////
208133
//-----------------------Recall shuttle ability-------------------------//
209134
//////////////////////////////////////////////////////////////////////////

yogstation/code/modules/antagonists/darkspawn/darkspawn_abilities/thrall_spells.dm

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,12 @@
5151
var/datum/antagonist/darkspawn/master = isdarkspawn(caster)
5252

5353
if(!isthrall(target))
54-
if(!target.has_status_effect(STATUS_EFFECT_DEVOURED_WILL))
55-
to_chat(owner, span_danger("[target]'s will is still too strong to thrall."))
56-
return FALSE
5754
if(master.willpower < willpower_cost)
5855
to_chat(owner, span_danger("You do not have enough will to thrall [target]."))
5956
return FALSE
57+
if(!get_shadow_tumor(target))
58+
to_chat(owner, span_danger("[target] does not have a shadow bead for you to enhance."))
59+
return FALSE
6060

6161
owner.balloon_alert(owner, "Krx'lna tyhx graha...")
6262
to_chat(owner, span_velvet("You begin to channel your psionic powers through [target]'s mind."))

yogstation/code/modules/antagonists/darkspawn/darkspawn_objects/thrall_tumor.dm

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
slot = ORGAN_SLOT_BRAIN_TUMOR
99
///How many process ticks the organ can be in light before it evaporates
1010
var/organ_health = 3
11-
///adds a cooldown to the resist so a thrall ipc or preternis can't weaponize it
12-
COOLDOWN_DECLARE(resist_cooldown)
13-
///How long the resist cooldown is
14-
var/cooldown_length = 15 SECONDS
11+
///Cached darkspawn team that gets the willpower
12+
var/datum/team/darkspawn/antag_team
13+
///How much willpower is granted by this tumor
14+
var/willpower_amount = 1
1515

1616
/obj/item/organ/shadowtumor/New()
1717
..()
@@ -22,9 +22,6 @@
2222
..()
2323

2424
/obj/item/organ/shadowtumor/process()
25-
if(!isthrall(owner))
26-
qdel(src)
27-
return
2825
if(isturf(loc))
2926
var/turf/T = loc
3027
var/light_count = T.get_lumcount()
@@ -37,12 +34,31 @@
3734
qdel(src)
3835
else
3936
organ_health = min(organ_health+0.5, 3)
37+
if(owner && owner.stat != DEAD && antag_team)
38+
antag_team.willpower_progress(willpower_amount)
4039

4140
/obj/item/organ/shadowtumor/on_find(mob/living/finder)
4241
. = ..()
4342
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."))
4443

45-
/obj/item/organ/shadowtumor/proc/resist(mob/living/carbon/M)
44+
////////////////////////////////////////////////////////////////////////////////////
45+
//------------------------------Thrall version------------------------------------//
46+
////////////////////////////////////////////////////////////////////////////////////
47+
/obj/item/organ/shadowtumor/thrall
48+
//provides extra willpower because willpower was spent to thrall someone
49+
willpower_amount = 2
50+
///adds a cooldown to the resist so a thrall ipc or preternis can't weaponize it
51+
COOLDOWN_DECLARE(resist_cooldown)
52+
///How long the resist cooldown is
53+
var/cooldown_length = 15 SECONDS
54+
55+
/obj/item/organ/shadowtumor/thrall/process()
56+
if(!isthrall(owner))
57+
qdel(src)
58+
return
59+
return ..()
60+
61+
/obj/item/organ/shadowtumor/thrall/proc/resist(mob/living/carbon/M)
4662
if(QDELETED(src))
4763
return FALSE
4864
if(!(M.stat == CONSCIOUS))//Thralls cannot be deconverted while awake

yogstation/code/modules/antagonists/darkspawn/darkspawn_team.dm

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
var/list/datum/mind/thralls = list()
99
///The number of drains required to perform the sacrament
1010
var/required_succs = 10 //How many succs are needed (this is changed in pre_setup, so it scales based on pop)
11+
///How much progress towards generating a willpower via tumors
12+
var/current_willpower_progress = 0
13+
///How much progress until another willpower is awarded
14+
var/max_willpower_progress = 100
1115
///How many drains have happened so far
1216
var/lucidity = 0
1317
///The max number of people that can be actively converted
@@ -109,13 +113,19 @@
109113
////////////////////////////////////////////////////////////////////////////////////
110114
//-----------------------------Special antag procs--------------------------------//
111115
////////////////////////////////////////////////////////////////////////////////////
112-
/datum/team/darkspawn/proc/grant_willpower(amount = 1, silent = FALSE)
116+
/datum/team/darkspawn/proc/willpower_progress(amount = 1)
117+
current_willpower_progress += amount
118+
if(current_willpower_progress >= max_willpower_progress)
119+
current_willpower_progress -= max_willpower_progress
120+
max_willpower_progress *= 1.1 //gets harder to get more willpower with every willpower granted to reduce snowballing
121+
grant_willpower(1)
122+
123+
//give a willpower to every darkspawn on the team
124+
/datum/team/darkspawn/proc/grant_willpower(amount = 1)
113125
for(var/datum/mind/master in members)
114126
if(master.has_antag_datum(/datum/antagonist/darkspawn)) //sanity check
115127
var/datum/antagonist/darkspawn/antag = master.has_antag_datum(/datum/antagonist/darkspawn)
116128
antag.willpower += amount
117-
if(!silent && master.current)
118-
to_chat(master.current, span_velvet("You have gained [amount] willpower."))
119129

120130
/datum/team/darkspawn/proc/grant_lucidity(amount = 1)
121131
lucidity += amount

0 commit comments

Comments
 (0)