mirror of
https://github.com/fulpstation/fulpstation.git
synced 2025-12-09 07:54:14 +00:00
Compare commits
2 Commits
1dc4f8a4ad
...
ddc5d38154
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ddc5d38154 | ||
|
|
672183ae53 |
@@ -52,6 +52,7 @@
|
||||
#define CLAN_VENTRUE "Ventrue Clan"
|
||||
#define CLAN_MALKAVIAN "Malkavian Clan"
|
||||
#define CLAN_TZIMISCE "Tzimisce Clan"
|
||||
#define CLAN_HECATA "Hecata Clan"
|
||||
#define CLAN_VASSAL "your Master"
|
||||
|
||||
#define TREMERE_VASSAL "tremere_vassal"
|
||||
@@ -83,6 +84,8 @@
|
||||
#define VASSAL_CAN_BUY (1<<3)
|
||||
/// This Power is exclusive to Brujah Bloodsuckers, who will gain them upon joining Brujah.
|
||||
#define BRUJAH_DEFAULT_POWER (1<<4)
|
||||
/// This Power can be purchased by Hecata Bloodsuckers
|
||||
#define HECATA_CAN_BUY (1<<5)
|
||||
|
||||
/// This Power is a Toggled Power
|
||||
#define BP_AM_TOGGLE (1<<0)
|
||||
@@ -124,6 +127,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"
|
||||
|
||||
/**
|
||||
* Role defines
|
||||
@@ -141,3 +146,5 @@
|
||||
*/
|
||||
/// The attack bonus added to the punch damage of the Brujah clan's favorite vassals.
|
||||
#define BRUJAH_FAVORITE_VASSAL_ATTACK_BONUS 4
|
||||
/// The attack bonus added to the punch damage of Hecata zombies.
|
||||
#define HECATA_ZOMBIE_ATTACK_BONUS 10
|
||||
|
||||
@@ -39,8 +39,10 @@
|
||||
#define COMSIG_GAIN_INSIGHT "gain_insight"
|
||||
#define COMSIG_BEASTIFY "beastify"
|
||||
|
||||
///Define for the 'Rabbits' Faction.
|
||||
///Define for the "Rabbits" faction.
|
||||
#define FACTION_RABBITS "rabbits"
|
||||
///Define for the "Bloodhungry"/bloodsucker monster faction.
|
||||
#define FACTION_BLOODHUNGRY "bloodhungry"
|
||||
|
||||
///Define for the Syndicate Engineer Ruin, used in 'syndicate_engineer.dm"
|
||||
#define ROLE_SYNDICATE_ENGINEER "Syndicate Engineer"
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.0 KiB |
@@ -0,0 +1,4 @@
|
||||
author: "Marmio64, QuiteLiterallyAnything"
|
||||
delete-after: True
|
||||
changes:
|
||||
- rscadd: "Ported Hecata bloodsuckers (by Marmio64) from Yogstation."
|
||||
@@ -0,0 +1,20 @@
|
||||
# Notice:
|
||||
|
||||
Some content featured as part of the bloodsucker antagonist has been ported
|
||||
from codebases external to Fulpstation. While the antagonist was originally
|
||||
developed for Fulpstation, it has been ported and further developed by other
|
||||
servers at various points in time. Permission has been acquired by assorted
|
||||
parties to then port these new features back to Fulpstation. Attribution
|
||||
for each feature ported can be found below, including links to the GitHub pull
|
||||
request which originally introduced the feature, the GitHub pull request which
|
||||
ported the feature to Fulpstation, and the GitHub user page of the feature's
|
||||
original developer.
|
||||
|
||||
|
||||
# Attribution Listing for Ported Features
|
||||
|
||||
## Hecata Bloodsucker Clan
|
||||
|
||||
Original PR: https://github.com/yogstation13/Yogstation/pull/18971
|
||||
Porting PR: https://github.com/fulpstation/fulpstation/pull/1391
|
||||
Original Developer's GitHub Profile: https://github.com/Marmio64
|
||||
@@ -0,0 +1,50 @@
|
||||
/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 |= 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)
|
||||
|
||||
/**
|
||||
* Clan objective
|
||||
* Hecata's objective is to raise a certain number of people from the dead.
|
||||
*/
|
||||
/datum/objective/bloodsucker/necromance
|
||||
name = "necromance"
|
||||
|
||||
/datum/objective/bloodsucker/necromance/New()
|
||||
var/crew_count = length(get_crewmember_minds())
|
||||
target_amount = rand(1, ceil(crew_count/5))
|
||||
update_explanation_text()
|
||||
..()
|
||||
|
||||
/datum/objective/bloodsucker/necromance/update_explanation_text()
|
||||
. = ..()
|
||||
explanation_text = "Using Necromancy, revive [target_amount] [target_amount > 1 ? "people" : "person"]."
|
||||
|
||||
/datum/objective/bloodsucker/necromance/check_completion()
|
||||
var/datum/antagonist/bloodsucker/bloodsuckerdatum = owner.current.mind.has_antag_datum(/datum/antagonist/bloodsucker)
|
||||
if(!bloodsuckerdatum)
|
||||
return FALSE
|
||||
var/datum/action/cooldown/bloodsucker/targeted/hecata/necromancy/power_with_revive_count
|
||||
for(var/datum/action/cooldown/bloodsucker/targeted/hecata/necromancy/necromancy_power in bloodsuckerdatum.powers)
|
||||
power_with_revive_count = necromancy_power
|
||||
if(power_with_revive_count.revive_count >= target_amount)
|
||||
return TRUE
|
||||
return FALSE
|
||||
@@ -0,0 +1,39 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// By Marmio64 as part of the Hecata bloodsucker clan //
|
||||
// (see 'fulp_modules\features\antagonists\bloodsuckers\_attribution.md') //
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///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)
|
||||
@@ -0,0 +1,21 @@
|
||||
/mob/living/basic/bloodsucker
|
||||
icon = 'fulp_modules/icons/antagonists/bloodsuckers/bloodsucker_mobs.dmi'
|
||||
|
||||
melee_damage_lower = 20
|
||||
melee_damage_upper = 20
|
||||
attack_sound = 'sound/items/weapons/slash.ogg'
|
||||
|
||||
see_in_dark = 10
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
gold_core_spawnable = FALSE
|
||||
movement_type = GROUND
|
||||
faction = list(FACTION_HOSTILE, FACTION_BLOODHUNGRY)
|
||||
|
||||
response_help_continuous = "touches"
|
||||
response_help_simple = "touch"
|
||||
response_disarm_continuous = "flails at"
|
||||
response_disarm_simple = "flail at"
|
||||
response_harm_continuous = "punches"
|
||||
response_harm_simple = "punch"
|
||||
|
||||
var/mob/living/bloodsucker
|
||||
@@ -0,0 +1,64 @@
|
||||
//Wraith - Hecata mob
|
||||
|
||||
/mob/living/basic/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)
|
||||
status_flags = 0
|
||||
status_flags = CANPUSH
|
||||
movement_type = FLYING
|
||||
basic_mob_flags = DEL_ON_DEATH
|
||||
|
||||
maxHealth = 30
|
||||
health = 30
|
||||
melee_damage_lower = 6
|
||||
melee_damage_upper = 6
|
||||
|
||||
speak_emote = list("hisses")
|
||||
response_help_continuous = "puts their hand through"
|
||||
response_help_simple = "put your hand through"
|
||||
response_disarm_continuous = "flails at"
|
||||
response_disarm_simple = "flail at"
|
||||
response_harm_continuous = "punches"
|
||||
response_harm_simple = "punch"
|
||||
attack_verb_continuous = "metaphysically strikes"
|
||||
attack_verb_simple = "metaphysically strike"
|
||||
death_message = "withers away into nothing."
|
||||
|
||||
ai_controller = /datum/ai_controller/basic_controller/wraith
|
||||
minimum_survivable_temperature = 0
|
||||
maximum_survivable_temperature = INFINITY
|
||||
unsuitable_atmos_damage = 0
|
||||
|
||||
/mob/living/basic/bloodsucker/wraith/Initialize(mapload)
|
||||
ADD_TRAIT(src, TRAIT_FREE_HYPERSPACE_MOVEMENT, INNATE_TRAIT)
|
||||
. = ..()
|
||||
ADD_TRAIT(src, TRAIT_SPACEWALK, INNATE_TRAIT)
|
||||
|
||||
AddElement(/datum/element/life_draining)
|
||||
AddElement(/datum/element/simple_flying)
|
||||
|
||||
/mob/living/basic/bloodsucker/wraith/death(gibbed)
|
||||
. = ..()
|
||||
new /obj/item/ectoplasm(src.loc)
|
||||
|
||||
/// Copied from '/datum/ai_controller/basic_controller/ghost' with minor alteration.
|
||||
/datum/ai_controller/basic_controller/wraith
|
||||
blackboard = list(
|
||||
BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic,
|
||||
)
|
||||
|
||||
ai_movement = /datum/ai_movement/basic_avoidance
|
||||
idle_behavior = /datum/idle_behavior/idle_random_walk
|
||||
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/simple_find_target,
|
||||
/datum/ai_planning_subtree/attack_obstacle_in_path,
|
||||
/datum/ai_planning_subtree/basic_melee_attack_subtree,
|
||||
/datum/ai_planning_subtree/random_speech/faithless,
|
||||
)
|
||||
@@ -28,7 +28,7 @@
|
||||
/// Requirement flags for checks
|
||||
check_flags = BP_CANT_USE_IN_TORPOR|BP_CANT_USE_IN_FRENZY|BP_CANT_USE_WHILE_STAKED|BP_CANT_USE_WHILE_INCAPACITATED|BP_CANT_USE_WHILE_UNCONSCIOUS
|
||||
/// Who can purchase the Power
|
||||
var/purchase_flags = NONE // BLOODSUCKER_CAN_BUY|BLOODSUCKER_DEFAULT_POWER|TREMERE_CAN_BUY|VASSAL_CAN_BUY
|
||||
var/purchase_flags = NONE // BLOODSUCKER_CAN_BUY|BLOODSUCKER_DEFAULT_POWER|TREMERE_CAN_BUY|BRUJAH_CAN_BUY|HECATA_CAN_BUY|VASSAL_CAN_BUY
|
||||
|
||||
// VARS //
|
||||
/// If the Power is currently active, differs from action cooldown because of how powers are handled.
|
||||
|
||||
@@ -36,6 +36,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
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* ⸸ Blood altars are not implemented on Fulpstation, but this comment has been kept regardless.
|
||||
*/
|
||||
/datum/action/cooldown/bloodsucker/targeted/hecata
|
||||
purchase_flags = HECATA_CAN_BUY
|
||||
background_icon = 'fulp_modules/icons/antagonists/bloodsuckers/actions_hecata_bloodsucker.dmi'
|
||||
button_icon = 'fulp_modules/icons/antagonists/bloodsuckers/actions_hecata_bloodsucker.dmi'
|
||||
active_background_icon_state = "hecata_power_on"
|
||||
base_background_icon_state = "hecata_power_off"
|
||||
|
||||
/datum/action/cooldown/bloodsucker/hecata
|
||||
purchase_flags = HECATA_CAN_BUY
|
||||
background_icon = 'fulp_modules/icons/antagonists/bloodsuckers/actions_hecata_bloodsucker.dmi'
|
||||
button_icon = 'fulp_modules/icons/antagonists/bloodsuckers/actions_hecata_bloodsucker.dmi'
|
||||
active_background_icon_state = "hecata_power_on"
|
||||
base_background_icon_state = "hecata_power_off"
|
||||
@@ -0,0 +1,35 @@
|
||||
/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_cult_large("<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()
|
||||
@@ -0,0 +1,102 @@
|
||||
/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."
|
||||
|
||||
/// The number of people "revived" with this power.
|
||||
/// Used to determine Hecata clan objective completion status.
|
||||
var/revive_count = 0
|
||||
|
||||
/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_after(user, 6 SECONDS, target, NONE, TRUE))
|
||||
return FALSE
|
||||
if(IS_VASSAL(target))
|
||||
power_activated_sucessfully()
|
||||
owner.balloon_alert(owner, "we revive [target]!")
|
||||
zombify(target)
|
||||
revive_count++ //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()
|
||||
revive_count++ //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
|
||||
else
|
||||
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/victim)
|
||||
victim.mind.remove_antag_datum(/datum/antagonist/vassal)
|
||||
to_chat(victim, span_warning("You feel the shadows around you weaken, your form falling limp like a puppet cut from its strings!"))
|
||||
victim.set_species(/datum/species/human/krokodil_addict) //they will turn into a fake zombie on death, that still retains blood and isnt so powerful.
|
||||
victim.death()
|
||||
|
||||
/datum/action/cooldown/bloodsucker/targeted/hecata/necromancy/proc/zombify(mob/living/victim)
|
||||
victim.mind.grab_ghost()
|
||||
victim.set_species(/datum/species/zombie/hecata) //imitation zombies that shamble around and beat people with their fists
|
||||
victim.revive(HEAL_ALL)
|
||||
victim.visible_message(span_danger("[victim.name] suddenly convulses, as [victim.p_they()] stagger to [victim.p_their()] feet and gain a ravenous hunger in [victim.p_their()] eyes!"), span_alien("You RISE!"))
|
||||
playsound(get_turf(victim), 'sound/effects/hallucinations/far_noise.ogg', 50, 1)
|
||||
to_chat(victim, 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(victim, 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."))
|
||||
@@ -0,0 +1,61 @@
|
||||
///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()
|
||||
. = ..()
|
||||
var/mob/user = owner
|
||||
switch(level_current)
|
||||
if(0)
|
||||
num_spirits = 1
|
||||
if(1)
|
||||
num_spirits = 2
|
||||
if(2)
|
||||
num_spirits = 3
|
||||
else
|
||||
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(get_path_to(user, T, 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/basic/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/effects/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.
|
||||
@@ -0,0 +1,59 @@
|
||||
//Hecata necromancy bloodsucker zombie. Kind of like a weakened Szlachta that can also wear clothes still
|
||||
/datum/species/zombie/hecata
|
||||
name = "Sanguine Zombie"
|
||||
id = "hecatazombie"
|
||||
examine_limb_id = SPECIES_ZOMBIE
|
||||
damage_modifier = -10
|
||||
stunmod = 0.5
|
||||
///no guns or soft crit
|
||||
inherent_traits = list(
|
||||
TRAIT_STABLELIVER,
|
||||
TRAIT_STABLEHEART,
|
||||
TRAIT_RESISTCOLD,
|
||||
TRAIT_RESISTHIGHPRESSURE,
|
||||
TRAIT_RESISTLOWPRESSURE,
|
||||
TRAIT_RADIMMUNE,
|
||||
TRAIT_EASYDISMEMBER,
|
||||
TRAIT_EASILY_WOUNDED,
|
||||
TRAIT_LIMBATTACHMENT,
|
||||
TRAIT_NOBREATH,
|
||||
TRAIT_NODEATH,
|
||||
TRAIT_FAKEDEATH,
|
||||
TRAIT_NOGUNS,
|
||||
TRAIT_NOSOFTCRIT,
|
||||
)
|
||||
changesource_flags = MIRROR_BADMIN | WABBAJACK | ERT_SPAWN
|
||||
|
||||
// Same as infectious zombies for the slow legs.
|
||||
bodypart_overrides = list(
|
||||
BODY_ZONE_HEAD = /obj/item/bodypart/head/zombie,
|
||||
BODY_ZONE_CHEST = /obj/item/bodypart/chest/zombie,
|
||||
BODY_ZONE_L_ARM = /obj/item/bodypart/arm/left/zombie,
|
||||
BODY_ZONE_R_ARM = /obj/item/bodypart/arm/right/zombie,
|
||||
BODY_ZONE_L_LEG = /obj/item/bodypart/leg/left/zombie/infectious,
|
||||
BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/zombie/infectious,
|
||||
)
|
||||
|
||||
/datum/species/zombie/hecata/on_species_gain(mob/living/carbon/human/human_who_gained_species, datum/species/old_species, pref_load, regenerate_icons)
|
||||
. = ..()
|
||||
human_who_gained_species.faction |= FACTION_BLOODHUNGRY
|
||||
var/mob/living/carbon/our_zombie = human_who_gained_species
|
||||
|
||||
var/obj/item/bodypart/zombie_left_hand = our_zombie.get_bodypart(BODY_ZONE_L_ARM)
|
||||
var/obj/item/bodypart/zombie_right_hand = our_zombie.get_bodypart(BODY_ZONE_R_ARM)
|
||||
zombie_left_hand.unarmed_damage_low += HECATA_ZOMBIE_ATTACK_BONUS
|
||||
zombie_right_hand.unarmed_damage_low += HECATA_ZOMBIE_ATTACK_BONUS
|
||||
zombie_left_hand.unarmed_damage_high += HECATA_ZOMBIE_ATTACK_BONUS
|
||||
zombie_right_hand.unarmed_damage_high += HECATA_ZOMBIE_ATTACK_BONUS
|
||||
|
||||
/datum/species/zombie/hecata/on_species_loss(mob/living/carbon/human/human, datum/species/new_species, pref_load)
|
||||
. = ..()
|
||||
human.faction -= FACTION_BLOODHUNGRY
|
||||
var/mob/living/carbon/our_zombie = human
|
||||
|
||||
var/obj/item/bodypart/zombie_left_hand = our_zombie.get_bodypart(BODY_ZONE_L_ARM)
|
||||
var/obj/item/bodypart/zombie_right_hand = our_zombie.get_bodypart(BODY_ZONE_R_ARM)
|
||||
zombie_left_hand.unarmed_damage_low = initial(zombie_left_hand.unarmed_damage_low)
|
||||
zombie_right_hand.unarmed_damage_low = initial(zombie_right_hand.unarmed_damage_low)
|
||||
zombie_left_hand.unarmed_damage_high = initial(zombie_left_hand.unarmed_damage_high)
|
||||
zombie_right_hand.unarmed_damage_high = initial(zombie_right_hand.unarmed_damage_high)
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 4.1 KiB |
BIN
fulp_modules/icons/antagonists/bloodsuckers/bloodsucker_mobs.dmi
Normal file
BIN
fulp_modules/icons/antagonists/bloodsuckers/bloodsucker_mobs.dmi
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 764 B |
Binary file not shown.
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 18 KiB |
@@ -29,7 +29,17 @@
|
||||
- code/__DEFINES/fulp_defines > Contains all of our defines
|
||||
- _maps/fulp_maps > Contains all of our non-station maps (Ruins, Deathmatch maps, etc.)
|
||||
- tgui/packages/fulpui-patches > Adds all Fulp TGUI files
|
||||
- code/modules/unit_tests/screenshots > Contains Fulp antag & species screenshots for unit tests.
|
||||
|
||||
- code/modules/unit_tests/screenshots > Contains Fulp antag & species screenshots for unit tests. This includes **BUT IS NOT LIMITED TO** the following:
|
||||
|
||||
1. screenshot_antag_icons_bloodsucker.png
|
||||
2. screenshot_antag_icons_bloodsuckerbreakout.png
|
||||
3. screenshot_antag_icons_infiltrator.png
|
||||
4. screenshot_antag_icons_monsterhunter.png
|
||||
5. screenshot_antag_icons_vampiricaccident.png
|
||||
6. screenshot_humanoids__datum_species_beefman.png
|
||||
7. screenshot_humanoids__datum_species_protogen.png
|
||||
8. screenshot_humanoids__datum_species_zombie_hecata.png
|
||||
|
||||
#### Maps & Shuttles
|
||||
- _maps/map_files/Heliostation/Heliostation.dmm
|
||||
|
||||
@@ -6595,11 +6595,15 @@
|
||||
#include "fulp_modules\features\antagonists\bloodsuckers\code\clans\_clan.dm"
|
||||
#include "fulp_modules\features\antagonists\bloodsuckers\code\clans\clan_brujah.dm"
|
||||
#include "fulp_modules\features\antagonists\bloodsuckers\code\clans\clan_flavortext.dm"
|
||||
#include "fulp_modules\features\antagonists\bloodsuckers\code\clans\clan_hecata.dm"
|
||||
#include "fulp_modules\features\antagonists\bloodsuckers\code\clans\clan_malkavian.dm"
|
||||
#include "fulp_modules\features\antagonists\bloodsuckers\code\clans\clan_nosferatu.dm"
|
||||
#include "fulp_modules\features\antagonists\bloodsuckers\code\clans\clan_tremere.dm"
|
||||
#include "fulp_modules\features\antagonists\bloodsuckers\code\clans\clan_vassal.dm"
|
||||
#include "fulp_modules\features\antagonists\bloodsuckers\code\clans\clan_ventrue.dm"
|
||||
#include "fulp_modules\features\antagonists\bloodsuckers\code\elements\lifedrain.dm"
|
||||
#include "fulp_modules\features\antagonists\bloodsuckers\code\mobs\_bloodsucker_mob.dm"
|
||||
#include "fulp_modules\features\antagonists\bloodsuckers\code\mobs\wraith.dm"
|
||||
#include "fulp_modules\features\antagonists\bloodsuckers\code\objects\bloodsucker_blood_containers.dm"
|
||||
#include "fulp_modules\features\antagonists\bloodsuckers\code\objects\bloodsucker_book.dm"
|
||||
#include "fulp_modules\features\antagonists\bloodsuckers\code\objects\bloodsucker_stakes.dm"
|
||||
@@ -6612,6 +6616,10 @@
|
||||
#include "fulp_modules\features\antagonists\bloodsuckers\code\powers\masquerade.dm"
|
||||
#include "fulp_modules\features\antagonists\bloodsuckers\code\powers\veil.dm"
|
||||
#include "fulp_modules\features\antagonists\bloodsuckers\code\powers\brujah\brash.dm"
|
||||
#include "fulp_modules\features\antagonists\bloodsuckers\code\powers\hecata\_powers_hecata.dm"
|
||||
#include "fulp_modules\features\antagonists\bloodsuckers\code\powers\hecata\communion.dm"
|
||||
#include "fulp_modules\features\antagonists\bloodsuckers\code\powers\hecata\necromancy.dm"
|
||||
#include "fulp_modules\features\antagonists\bloodsuckers\code\powers\hecata\spirit_call.dm"
|
||||
#include "fulp_modules\features\antagonists\bloodsuckers\code\powers\targeted\_powers_targeted.dm"
|
||||
#include "fulp_modules\features\antagonists\bloodsuckers\code\powers\targeted\brawn.dm"
|
||||
#include "fulp_modules\features\antagonists\bloodsuckers\code\powers\targeted\haste.dm"
|
||||
@@ -6625,6 +6633,7 @@
|
||||
#include "fulp_modules\features\antagonists\bloodsuckers\code\powers\vassal\distress.dm"
|
||||
#include "fulp_modules\features\antagonists\bloodsuckers\code\powers\vassal\recuperate.dm"
|
||||
#include "fulp_modules\features\antagonists\bloodsuckers\code\powers\vassal\vassal_fold.dm"
|
||||
#include "fulp_modules\features\antagonists\bloodsuckers\code\species\bloodsucker_zombies.dm"
|
||||
#include "fulp_modules\features\antagonists\bloodsuckers\code\structures\_bloodsucker_structure.dm"
|
||||
#include "fulp_modules\features\antagonists\bloodsuckers\code\structures\bloodsucker_coffin.dm"
|
||||
#include "fulp_modules\features\antagonists\bloodsuckers\code\structures\bloodsucker_lighting.dm"
|
||||
|
||||
Reference in New Issue
Block a user