mirror of
https://github.com/yogstation13/Yogstation.git
synced 2025-02-26 09:04:50 +00:00
Rework how darkspawn devour will works (#22957)
* rework progress * Update thrall_tumor.dm * tweaks * more words and number tweaks * Update thrall_tumor.dm
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)]."),
|
||||
|
||||
@@ -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----------------------------//
|
||||
|
||||
@@ -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
|
||||
@@ -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...")
|
||||
@@ -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>"))
|
||||
|
||||
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
|
||||
|
||||
//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)
|
||||
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.")
|
||||
|
||||
//apply the long-term debuffs to the victim
|
||||
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)
|
||||
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
|
||||
|
||||
target.silent += 5
|
||||
|
||||
if(target.handcuffed)
|
||||
to_chat(caster, span_warning("[target] is already restrained."))
|
||||
return
|
||||
|
||||
playsound(target, 'yogstation/sound/magic/devour_will_form.ogg', 50, TRUE)
|
||||
target.set_handcuffed(new /obj/item/restraints/handcuffs/darkspawn(target))
|
||||
target.update_handcuffed()
|
||||
|
||||
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-------------------------//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -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."))
|
||||
|
||||
@@ -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()
|
||||
..()
|
||||
@@ -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()
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
/**
|
||||
* Helper proc to check if someone has a shadow tumor
|
||||
*/
|
||||
/proc/get_shadow_tumor(mob/living/source)
|
||||
if(!istype(source))
|
||||
return
|
||||
var/obj/item/organ/tumor = source.getorganslot(ORGAN_SLOT_BRAIN_TUMOR)
|
||||
if(!tumor || !istype(tumor, /obj/item/organ/shadowtumor)) //if they somehow lose their tumor in an unusual way
|
||||
return
|
||||
return tumor
|
||||
|
||||
|
||||
/datum/antagonist/thrall
|
||||
name = "Darkspawn Thrall"
|
||||
job_rank = ROLE_DARKSPAWN
|
||||
@@ -7,10 +19,6 @@
|
||||
antag_moodlet = /datum/mood_event/thrall
|
||||
///The abilities granted to the thrall
|
||||
var/list/abilities = list(/datum/action/cooldown/spell/toggle/nightvision, /datum/action/cooldown/spell/pointed/darkspawn_build/thrall_eye/thrall)
|
||||
///How many ticks towards willpower generation has happened so far
|
||||
var/current_willpower_progress = 0
|
||||
///Amount of progress required to generate willpower, increases every time
|
||||
var/current_willpower_max = 80
|
||||
///The darkspawn team that the thrall is on
|
||||
var/datum/team/darkspawn/team
|
||||
|
||||
@@ -70,10 +78,12 @@
|
||||
new_spell.Grant(current_mob)
|
||||
|
||||
if(isliving(current_mob))
|
||||
var/obj/item/organ/shadowtumor/ST = current_mob.getorganslot(ORGAN_SLOT_BRAIN_TUMOR)
|
||||
var/obj/item/organ/shadowtumor/thrall/ST = current_mob.getorganslot(ORGAN_SLOT_BRAIN_TUMOR)
|
||||
if(!ST || !istype(ST))
|
||||
ST = new
|
||||
ST.Insert(current_mob, FALSE, FALSE)
|
||||
if(team)
|
||||
ST.antag_team = team
|
||||
|
||||
/datum/antagonist/thrall/remove_innate_effects(mob/living/mob_override)
|
||||
var/mob/living/current_mob = mob_override || owner.current
|
||||
@@ -94,8 +104,8 @@
|
||||
if(spells.type in abilities)//no keeping your abilities
|
||||
spells.Remove(current_mob)
|
||||
qdel(spells)
|
||||
var/obj/item/organ/tumor = current_mob.getorganslot(ORGAN_SLOT_BRAIN_TUMOR)
|
||||
if(tumor && istype(tumor, /obj/item/organ/shadowtumor))
|
||||
var/obj/item/organ/tumor = get_shadow_tumor(current_mob)
|
||||
if(tumor)
|
||||
qdel(tumor)
|
||||
current_mob.update_sight()
|
||||
|
||||
@@ -132,33 +142,13 @@
|
||||
overlays += overlay
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
//--------------------------Passive willpower gen---------------------------------//
|
||||
//-----------Check if the thrall has a tumor, if not, dethrall them---------------//
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/datum/antagonist/thrall/proc/thrall_life(mob/living/source, seconds_per_tick, times_fired)
|
||||
if(!source || source.stat == DEAD)
|
||||
return
|
||||
var/obj/item/organ/tumor = source.getorganslot(ORGAN_SLOT_BRAIN_TUMOR)
|
||||
if(!tumor || !istype(tumor, /obj/item/organ/shadowtumor)) //if they somehow lose their tumor in an unusual way
|
||||
if(!get_shadow_tumor(source)) //if they somehow lose their tumor in an unusual way
|
||||
source.remove_thrall()
|
||||
return
|
||||
|
||||
var/found_other = FALSE
|
||||
for(var/mob/living/thing in range(10, source))
|
||||
if(!thing.client) //gotta be an actual player (hope no one goes afk)
|
||||
continue
|
||||
if(is_team_darkspawn(thing))
|
||||
continue
|
||||
if(!can_see(source, thing, 10))
|
||||
continue
|
||||
found_other = TRUE
|
||||
|
||||
if(found_other)
|
||||
current_willpower_progress += seconds_per_tick
|
||||
|
||||
if(current_willpower_progress >= current_willpower_max)
|
||||
current_willpower_max *= 2
|
||||
current_willpower_progress = 0
|
||||
team.grant_willpower(1, TRUE)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
//-------------------------------Antag greet--------------------------------------//
|
||||
|
||||
Reference in New Issue
Block a user