Skip to content
This repository was archived by the owner on May 22, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
02ea2b5
hecata clan
Marmio64 May 23, 2023
5ee8f64
Merge remote-tracking branch 'upstream/master' into retry-of-hecata
Marmio64 May 26, 2023
f692d0e
Merge remote-tracking branch 'upstream/master' into retry-of-hecata
Marmio64 May 26, 2023
98db169
adapts the clan to the new changes
Marmio64 May 26, 2023
99fc3d5
vassal fix
Marmio64 May 26, 2023
0555cd7
first cleanup batch
Marmio64 May 29, 2023
6d1cbeb
Update code/modules/mob/living/carbon/human/species_types/zombies.dm
Marmio64 May 29, 2023
5e46d6c
Update code/modules/antagonists/bloodsuckers/powers/targeted/hecata.dm
Marmio64 May 29, 2023
2b8d3ec
Update code/modules/antagonists/bloodsuckers/powers/targeted/hecata.dm
Marmio64 May 29, 2023
f47b033
Update code/modules/antagonists/bloodsuckers/powers/targeted/hecata.dm
Marmio64 May 29, 2023
248b058
Update code/modules/antagonists/bloodsuckers/powers/targeted/hecata.dm
Marmio64 May 29, 2023
4e96bb9
Update code/modules/antagonists/bloodsuckers/powers/targeted/hecata.dm
Marmio64 May 29, 2023
5985a26
Update code/modules/antagonists/bloodsuckers/powers/targeted/hecata.dm
Marmio64 May 29, 2023
151d5d4
Update code/modules/antagonists/bloodsuckers/powers/targeted/hecata.dm
Marmio64 May 29, 2023
48150f5
Update code/modules/antagonists/bloodsuckers/powers/targeted/hecata.dm
Marmio64 May 29, 2023
f782be9
Update code/modules/antagonists/bloodsuckers/powers/targeted/hecata.dm
Marmio64 May 29, 2023
9e53fda
Update code/modules/antagonists/bloodsuckers/powers/targeted/hecata.dm
Marmio64 May 29, 2023
589e2ff
Update code/modules/antagonists/bloodsuckers/powers/targeted/hecata.dm
Marmio64 May 29, 2023
2a9751c
Update code/modules/antagonists/bloodsuckers/powers/targeted/hecata.dm
Marmio64 May 29, 2023
fae54d8
Update code/modules/antagonists/bloodsuckers/powers/targeted/hecata.dm
Marmio64 May 29, 2023
a228ab8
more stuff
Marmio64 May 29, 2023
77aedaf
Update code/modules/antagonists/bloodsuckers/powers/targeted/hecata.dm
Marmio64 Jun 1, 2023
fed7f1a
Update code/modules/antagonists/bloodsuckers/powers/feed.dm
Marmio64 Jun 1, 2023
bad7801
Update code/modules/antagonists/bloodsuckers/bloodsucker_mobs.dm
Marmio64 Jul 5, 2023
33c19f8
Update code/modules/antagonists/bloodsuckers/powers/targeted/hecata.dm
Marmio64 Jul 5, 2023
2d830ca
switches and multiline
Marmio64 Jul 5, 2023
3bfb697
autodoc
Marmio64 Jul 5, 2023
d118f50
fix
Marmio64 Jul 5, 2023
2f8f4c1
tgui input and sanitize, snake case, owner
Marmio64 Jul 7, 2023
05c89a0
Merge remote-tracking branch 'upstream/master' into retry-of-hecata
Marmio64 Jul 24, 2023
b0fed43
implements lifedrain element
Marmio64 Jul 24, 2023
ce93b45
Update code/modules/mob/living/carbon/human/species_types/zombies.dm
Marmio64 Aug 3, 2023
4032cc1
Update code/modules/mob/living/carbon/human/species_types/zombies.dm
Marmio64 Aug 3, 2023
431a4f1
Update code/modules/antagonists/bloodsuckers/powers/targeted/hecata.dm
Marmio64 Aug 3, 2023
8976f58
Update code/modules/antagonists/bloodsuckers/powers/targeted/hecata.dm
Marmio64 Aug 3, 2023
d6e7a8a
Update code/modules/mob/living/carbon/human/species_types/zombies.dm
Marmio64 Aug 3, 2023
9f9a8ba
Update code/datums/elements/life_drain.dm
JohnFulpWillard Aug 3, 2023
a33b05d
Update code/modules/antagonists/bloodsuckers/bloodsucker_objectives.dm
JohnFulpWillard Aug 3, 2023
375472b
Update code/modules/antagonists/bloodsuckers/powers/targeted/hecata.dm
Marmio64 Aug 8, 2023
3f666b9
Update code/modules/mob/living/carbon/human/species_types/zombies.dm
Marmio64 Aug 8, 2023
6ca8fe7
Update code/modules/mob/living/carbon/human/species_types/zombies.dm
Marmio64 Aug 8, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions code/__DEFINES/bloodsuckers.dm
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#define BLOODSUCKER_DRINK_SNOBBY "bloodsucker_drink_snobby"
///Drinks blood from disgusting creatures without Humanity consequences.
#define BLOODSUCKER_DRINK_INHUMANELY "bloodsucker_drink_imhumanely"
///Drinks blood only from aggressive or higher grabs, no silent feeding.
#define BLOODSUCKER_DRINK_PAINFUL "bloodsucker_drink_painful"

///Controls blood, just like all Bloodsuckers do
#define BLOODSUCKER_CONTROL_BLOOD 1
Expand Down Expand Up @@ -69,6 +71,7 @@
#define CLAN_GANGREL "Gangrel Clan"
#define CLAN_LASOMBRA "Lasombra Clan"
#define CLAN_TZIMISCE "Tzimisce Clan"
#define CLAN_HECATA "Hecata Clan"

#define TREMERE_VASSAL "tremere_vassal"
#define FAVORITE_VASSAL "favorite_vassal"
Expand Down Expand Up @@ -108,6 +111,8 @@
#define HUNTER_CAN_BUY (1<<5)
/// This Power can be purchased by Tzimisce Bloodsuckers
#define TZIMISCE_CAN_BUY (1<<6)
/// This Power can be purchased by Hecata Bloodsuckers
#define HECATA_CAN_BUY (1<<7)

/// This Power is a Toggled Power
#define BP_AM_TOGGLE (1<<0)
Expand Down
34 changes: 34 additions & 0 deletions code/datums/elements/life_drain.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
///Slowly drains HP from a living mob.
/datum/element/life_draining
element_flags = ELEMENT_BESPOKE
argument_hash_start_idx = 2

///How much damage to deal overtime.
var/damage_overtime
///The callback we will use to cancel damage, if any
var/datum/callback/check_damage_callback

/datum/element/life_draining/Attach(
mob/living/target,
damage_overtime = 1,
datum/callback/check_damage_callback,
)
. = ..()
if(!isliving(target))
return ELEMENT_INCOMPATIBLE
src.damage_overtime = damage_overtime
src.check_damage_callback = check_damage_callback
RegisterSignal(target, COMSIG_LIVING_LIFE, PROC_REF(on_mob_life))

/datum/element/life_draining/Detach(mob/living/source, ...)
UnregisterSignal(source, COMSIG_LIVING_LIFE)
return ..()

///Handles removing HP from the mob, as long as they're not dead.
/datum/element/life_draining/proc/on_mob_life(mob/living/source, seconds_per_tick, times_fired)
SIGNAL_HANDLER
if(source.stat == DEAD)
return
if(check_damage_callback?.Invoke())
return
source.adjustBruteLoss(damage_overtime)
41 changes: 40 additions & 1 deletion code/modules/antagonists/bloodsuckers/bloodsucker_mobs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,6 @@

/mob/living/simple_animal/hostile/bloodsucker/werewolf/Life(delta_time = (SSmobs.wait/10), times_fired)
. = ..()
SEND_SIGNAL(src, COMSIG_LIVING_LIFE, delta_time, times_fired)
if(bloodsucker)
if(ishuman(bloodsucker))
var/mob/living/carbon/human/user = bloodsucker
Expand Down Expand Up @@ -263,3 +262,43 @@
else
new /obj/structure/bloodsucker/possessedarmor(src.loc)
qdel(src)

//Wraith - Hecata mob

/mob/living/simple_animal/hostile/bloodsucker/wraith
name = "wraith"
real_name = "Wraith"
desc = "An angry, tormented spirit, which looks to let out it's wrath on whoever is nearby."
gender = PLURAL
icon_state = "wraith"
icon_living = "wraith"
mob_biotypes = list(MOB_SPIRIT)
maxHealth = 30
health = 30
spacewalk = TRUE
healable = 0
speak_emote = list("hisses")
emote_hear = list("wails.","screeches.")
response_help = "puts their hand through"
response_disarm = "flails at"
response_harm = "punches"
speak_chance = 1
melee_damage_lower = 6
melee_damage_upper = 6
attacktext = "torments"
minbodytemp = 0
maxbodytemp = INFINITY
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
status_flags = 0
status_flags = CANPUSH
movement_type = FLYING
loot = list(/obj/item/ectoplasm)
deathmessage = "withers away into nothing."

/mob/living/simple_animal/hostile/bloodsucker/wraith/Initialize(mapload)
. = ..()
AddElement(/datum/element/life_draining)

/mob/living/simple_animal/hostile/bloodsucker/wraith/death()
qdel(src) //Del on death for some reason doesn't work, might be due to previous code preventing it for /bloodsucker mobs.
..()
21 changes: 21 additions & 0 deletions code/modules/antagonists/bloodsuckers/bloodsucker_objectives.dm
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,27 @@
return TRUE
return FALSE

/// Necromance X amount of people (Hecata)
/datum/objective/bloodsucker/necromance
name = "necromance"

/datum/objective/bloodsucker/necromance/New()
target_amount = rand(6,8)
..()


/datum/objective/bloodsucker/necromance/update_explanation_text()
. = ..()
explanation_text = "Using Necromancy, revive [target_amount] people."

/datum/objective/bloodsucker/necromance/check_completion()
var/datum/antagonist/bloodsucker/bloodsuckerdatum = owner.current.mind.has_antag_datum(/datum/antagonist/bloodsucker)
if(!bloodsuckerdatum)
return FALSE
if(bloodsuckerdatum.clanprogress >= target_amount)
return TRUE
return FALSE

//////////////////////////////////////////////////////////////////////////////////////

/// Mutilate a certain amount of Vassals
Expand Down
22 changes: 22 additions & 0 deletions code/modules/antagonists/bloodsuckers/clans/clan_hecata.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/datum/bloodsucker_clan/hecata
name = CLAN_HECATA
description = "This Clan is composed of curious practioners of dark magic who enjoy toying with the dead. \n\
Often compared to the Lasombra, they sometimes act in similar ways and draw power from the void. \n\
However, they are also very different, and place an emphasis on creating zombie like puppets from the dead. \n\
They are able to raise the dead as temporary vassals, permanently revive dead vassals, communicate to their vassals from afar, and summon wraiths. \n\
Their Favorite Vassal also has inherited a small fraction of their power, being able to call wraiths into the world as well."
clan_objective = /datum/objective/bloodsucker/necromance
join_icon_state = "hecata"
join_description = "Raise zombie hordes from the dead, and then coordinate them from anywhere anytime."
blood_drink_type = BLOODSUCKER_DRINK_PAINFUL

/datum/bloodsucker_clan/hecata/New(datum/antagonist/bloodsucker/owner_datum)
. = ..()
bloodsuckerdatum.BuyPower(new /datum/action/cooldown/bloodsucker/targeted/hecata/necromancy)
bloodsuckerdatum.BuyPower(new /datum/action/cooldown/bloodsucker/hecata/spiritcall)
bloodsuckerdatum.BuyPower(new /datum/action/cooldown/bloodsucker/hecata/communion)
bloodsuckerdatum.owner.current.faction |= "bloodhungry"
bloodsuckerdatum.owner.current.update_body()

/datum/bloodsucker_clan/hecata/on_favorite_vassal(datum/antagonist/bloodsucker/source, datum/antagonist/vassal/vassaldatum)
vassaldatum.BuyPower(new /datum/action/cooldown/bloodsucker/hecata/spiritcall)
3 changes: 3 additions & 0 deletions code/modules/antagonists/bloodsuckers/powers/feed.dm
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@
if(user.is_mouth_covered() && !isplasmaman(user))
owner.balloon_alert(owner, "mouth covered!")
return FALSE
if(bloodsuckerdatum_power.my_clan.blood_drink_type == BLOODSUCKER_DRINK_PAINFUL && owner.grab_state <= GRAB_PASSIVE)
owner.balloon_alert(owner, "can't silent feed!")
return FALSE
//Find target, it will alert what the problem is, if any.
if(!find_target())
return FALSE
Expand Down
220 changes: 220 additions & 0 deletions code/modules/antagonists/bloodsuckers/powers/targeted/hecata.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
/**
* Hecata, the unified clan of death.
*
* Focuses more on their vassals than other clans.
* Has to rely more on vassals for ranks and blood, as they cannot use the blood altar for leveling up and cannot silent feed.
* In exchange, they can raise the dead as temporary vassals to do their bidding, or permanently revive dead existing vassals.
* In addition, they can summon Wraiths (shades) around them for both offense and defense
* And can send messages to vassals anywhere globally via Dark Communion.
* In addition, raising the dead with Necromancy turns them into Sanguine Zombies
* They are pseudo zombies, which have high punch damage and special resistances, but aren't infectious nor can they use guns.
*/
/datum/action/cooldown/bloodsucker/targeted/hecata
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hecata spells should follow what Tremere spells did and be in their own folder, but not in the same file

purchase_flags = HECATA_CAN_BUY
background_icon = 'icons/mob/actions/actions_hecata_bloodsucker.dmi'
button_icon = 'icons/mob/actions/actions_hecata_bloodsucker.dmi'
active_background_icon_state = "hecata_power_on"
base_background_icon_state = "hecata_power_off"

/datum/action/cooldown/bloodsucker/targeted/hecata/necromancy
name = "Necromancy"
button_icon_state = "power_necromancy"
desc = "Raise the dead as temporary vassals, or revive a dead vassal as a zombie permanently. Temporary vassals last longer as this ability ranks up."
power_explanation = "Necromancy:\n\
Click on a corpse in order to attempt to resurrect them.\n\
Non-vassals will become temporary zombies that will follow your orders. Dead vassals are also turned, but last permanently.\n\
Temporary vassals tend to not last long, their form quickly falling apart, make sure you set them out to do what you want as soon as possible.\n\
Vassaling people this way does not grant ranks. In addition, after their time is up they will die and no longer be your vassal."
check_flags = BP_CANT_USE_IN_TORPOR|BP_CANT_USE_IN_FRENZY|BP_CANT_USE_WHILE_UNCONSCIOUS
power_flags = BP_AM_STATIC_COOLDOWN
bloodcost = 35
cooldown_time = 45 SECONDS
target_range = 1
prefire_message = "Select a target."

/datum/action/cooldown/bloodsucker/targeted/hecata/necromancy/CheckValidTarget(atom/target_atom)
. = ..()
if(!.)
return FALSE
return isliving(target_atom)

/datum/action/cooldown/bloodsucker/targeted/hecata/necromancy/CheckCanTarget(mob/living/carbon/target_atom)
. = ..()
if(!.)
return FALSE
// No mind
if(!target_atom.mind)
to_chat(owner, span_warning("[target_atom] is mindless."))
return FALSE
// Bloodsucker
if(IS_BLOODSUCKER(target_atom))
to_chat(owner, span_notice("Bloodsuckers are immune to [src]."))
return FALSE
// Alive
if(target_atom.stat != DEAD)
to_chat(owner, span_notice("[target_atom] is still alive."))
return FALSE
return TRUE

/datum/action/cooldown/bloodsucker/targeted/hecata/necromancy/FireTargetedPower(atom/target_atom)
. = ..()
var/mob/living/target = target_atom
var/mob/living/user = owner
var/datum/antagonist/bloodsucker/bloodsuckerdatum = user.mind.has_antag_datum(/datum/antagonist/bloodsucker)
if(target.stat == DEAD && user.Adjacent(target))
owner.balloon_alert(owner, "attempting to revive...")
if(!do_mob(user, target, 6 SECONDS, NONE, TRUE))
return FALSE
if(IS_VASSAL(target))
power_activated_sucessfully()
owner.balloon_alert(owner, "we revive [target]!")
zombify(target)
bloodsuckerdatum.clanprogress++ //counts a succesful necromancy towards your objective progress
return
if(IS_MONSTERHUNTER(target))
owner.balloon_alert(owner, "their body refuses to react...")
DeactivatePower()
return
zombify(target)
bloodsuckerdatum.make_vassal(target)
power_activated_sucessfully()
bloodsuckerdatum.clanprogress++ //counts a succesful necromancy towards your objective progress
to_chat(user, span_warning("We revive [target]!"))
var/living_time
switch(level_current)
if(0)
living_time = 2 MINUTES
if(1)
living_time = 5 MINUTES
if(2)
living_time = 8 MINUTES
if(3)
living_time = 11 MINUTES
if(4)
living_time = 14 MINUTES
if(5 to 99)
living_time = 17 MINUTES //in general, they don't last long, make the most of them.
addtimer(CALLBACK(src, PROC_REF(end_necromance), target), living_time)
else //extra check, but this shouldn't happen
owner.balloon_alert(owner, "out of range/not dead.")
return FALSE
DeactivatePower()

/datum/action/cooldown/bloodsucker/targeted/hecata/necromancy/proc/end_necromance(mob/living/user)
user.mind.remove_antag_datum(/datum/antagonist/vassal)
to_chat(user, span_warning("You feel the shadows around you weaken, your form falling limp like a puppet cut from its strings!"))
user.set_species(/datum/species/krokodil_addict) //they will turn into a fake zombie on death, that still retains blood and isnt so powerful.
user.death()

/datum/action/cooldown/bloodsucker/targeted/hecata/necromancy/proc/zombify(mob/living/user)
user.mind.grab_ghost()
user.set_species(/datum/species/zombie/hecata) //imitation zombies that shamble around and beat people with their fists
user.revive(full_heal = TRUE, admin_revive = TRUE)
user.visible_message(span_danger("[user] suddenly convulses, as [user.p_they()] stagger to their feet and gain a ravenous hunger in [user.p_their()] eyes!"), span_alien("You RISE!"))
playsound(owner.loc, 'sound/hallucinations/far_noise.ogg', 50, 1)
to_chat(user, span_warning("Your broken form is picked up by strange shadows. If you were previously not a vassal, it is unlikely these shadows will be strong enough to keep you going for very long."))
to_chat(user, span_notice("You are resilient to many things like the vacuum of space, can punch harder, and can take more damage before dropping. However, you are unable to use guns and are slower."))

/datum/action/cooldown/bloodsucker/hecata
purchase_flags = HECATA_CAN_BUY
background_icon = 'icons/mob/actions/actions_hecata_bloodsucker.dmi'
button_icon = 'icons/mob/actions/actions_hecata_bloodsucker.dmi'
active_background_icon_state = "hecata_power_on"
base_background_icon_state = "hecata_power_off"

///summon wraiths (weakened shades) to attack anyone who isn't a zombie. This includes non-zombified vassals. However, you can get around this by zombifying your vassals.
///to do this, you can make someone your favorite vassal, or you can kill them and then revive them with necromancy.
/datum/action/cooldown/bloodsucker/hecata/spiritcall
name = "Spirit Call"
desc = "Summon angry wraiths which will attack anyone whose flesh is still alive. Summon amount increases as this ability levels up."
button_icon_state = "power_spiritcall"
power_explanation = "Spirit Call:\n\
Summon angry wraiths which enact vengeance from beyond the grave on those still connected to this world.\n\
Note, that includes any of your vassals who are not undead, as wraiths will seek to kill them too!\n\
Summons more wraiths as this ability ranks up.\n\
These wraiths aren't very powerful, and best serve as a distraction, but in a pinch can help in a fight. \n\
The spirits will eventually return back to their realm if not otherwise destroyed."
check_flags = BP_CANT_USE_IN_TORPOR|BP_CANT_USE_IN_FRENZY|BP_CANT_USE_WHILE_UNCONSCIOUS
power_flags = BP_AM_STATIC_COOLDOWN
bloodcost = 15
cooldown_time = 60 SECONDS
///How many spirits should be summoned when cast
var/num_spirits = 1

/datum/action/cooldown/bloodsucker/hecata/spiritcall/vassal //this variant has to exist, as hecata favorite vassals are technically in 'torpor'
check_flags = BP_CANT_USE_WHILE_INCAPACITATED|BP_CANT_USE_WHILE_UNCONSCIOUS

/datum/action/cooldown/bloodsucker/hecata/spiritcall/ActivatePower(mob/user = owner)
. = ..()
switch(level_current)
if(0)
num_spirits = 1
if(1)
num_spirits = 2
if(2)
num_spirits = 3
if(3 to 99)
num_spirits = 4
var/list/turf/locs = list()
for(var/direction in GLOB.alldirs) //looking for spirit spawns
if(locs.len == num_spirits) //we found the number of spots needed and thats all we need
break
var/turf/T = get_step(owner, direction) //getting a loc in that direction
if(AStar(user, T, /turf/proc/Distance, 1, simulated_only = 0)) // if a path exists, so no dense objects in the way its valid salid
locs += T
// pad with player location
for(var/i = locs.len + 1 to num_spirits)
locs += user.loc
summon_wraiths(locs, user = owner)
cast_effect() // POOF
DeactivatePower()

/datum/action/cooldown/bloodsucker/hecata/spiritcall/proc/summon_wraiths(list/targets, mob/living/user)
for(var/T in targets)
new /mob/living/simple_animal/hostile/bloodsucker/wraith(T)

/datum/action/cooldown/bloodsucker/hecata/spiritcall/proc/cast_effect() //same as veil of many faces, makes smoke and stuff when casted
// Effect
playsound(get_turf(owner), 'sound/magic/smoke.ogg', 20, TRUE)
var/datum/effect_system/steam_spread/puff = new /datum/effect_system/steam_spread/bloodsucker()
puff.effect_type = /obj/effect/particle_effect/fluid/smoke/vampsmoke
puff.set_up(3, 0, get_turf(owner))
puff.attach(owner) //OPTIONAL
puff.start()
owner.spin(8, 1) //Spin around like a loon.

/datum/action/cooldown/bloodsucker/hecata/communion
name = "Deathly Communion"
desc = "Send a message to all your vassals."
button_icon_state = "power_communion"
power_explanation = "Deathly Communion:\n\
Send a message directly to all vassals under your control, temporary or permanent.\n\
They will not be able to respond to you through any supernatural means in the way you can.\n\
Note, nearby humans can hear you talk when using this.\n\
The cooldown of Communion will decrease as it levels up."
check_flags = BP_CANT_USE_IN_TORPOR|BP_CANT_USE_IN_FRENZY
power_flags = NONE
bloodcost = 8
cooldown_time = 30 SECONDS

/datum/action/cooldown/bloodsucker/hecata/communion/ActivatePower()
. = ..()
var/input = sanitize(tgui_input_text(usr, "Enter a message to tell your vassals.", "Voice of Blood"))
if(!input || !IsAvailable())
return FALSE
deathly_commune(usr, input)

/datum/action/cooldown/bloodsucker/hecata/communion/proc/deathly_commune(mob/living/user, message) //code from Fulpstation
var/rendered = span_cultlarge("<b>Master [user.real_name] announces:</b> [message]")
user.log_talk(message, LOG_SAY, tag=ROLE_BLOODSUCKER)
var/datum/antagonist/bloodsucker/bloodsuckerdatum = user.mind.has_antag_datum(/datum/antagonist/bloodsucker)
for(var/datum/antagonist/vassal/receiver as anything in bloodsuckerdatum.vassals)
if(!receiver.owner.current)
continue
var/mob/receiver_mob = receiver.owner.current
to_chat(receiver_mob, rendered)
to_chat(user, rendered) // tell yourself, too.
for(var/mob/dead_mob in GLOB.dead_mob_list)
var/link = FOLLOW_LINK(dead_mob, user)
to_chat(dead_mob, "[link] [rendered]")
DeactivatePower()
Loading