diff --git a/code/__DEFINES/bloodsuckers.dm b/code/__DEFINES/bloodsuckers.dm index c4b0c967dd46..d8be795f7d80 100644 --- a/code/__DEFINES/bloodsuckers.dm +++ b/code/__DEFINES/bloodsuckers.dm @@ -42,6 +42,8 @@ #define ARMMY_MONSTER "Armmy (100 Blood)" #define CALCIUM_MONSTER "Calcium (150 Blood)" #define HUSK_MONSTER "Husk" +#define TOREADOR_MAX_HUMANITY_LOSS 10 + /** * Power defines */ @@ -77,3 +79,7 @@ #define BP_AM_STATIC_COOLDOWN (1<<2) /// This Power doesn't cost bloot to run while unconscious #define BP_AM_COSTLESS_UNCONSCIOUS (1<<3) + +// Signals + +#define COMSIG_BLOODSUCKER_RANKS_SPENT \ No newline at end of file diff --git a/code/modules/antagonists/bloodsuckers/bloodsucker_flaws.dm b/code/modules/antagonists/bloodsuckers/bloodsucker_flaws.dm index 21dfc2d05144..f032766db4c9 100644 --- a/code/modules/antagonists/bloodsuckers/bloodsucker_flaws.dm +++ b/code/modules/antagonists/bloodsuckers/bloodsucker_flaws.dm @@ -22,13 +22,15 @@ var/static/list/clans = list( CLAN_GANGREL, CLAN_LASOMBRA, + CLAN_TOREADOR, ) var/list/options = list() options = clans // Brief descriptions in case they don't read the Wiki. to_chat(owner, span_announce("List of all Clans:\n\ Gangrel - Prone to Frenzy, strange outcomes from being on frenzy, special power.\n\ - Lasombra - Life in the shadows, very weak to fire but no brute damage, upgradable abilities through tasks.")) + Lasombra - Life in the shadows, very weak to fire but no brute damage, upgradable abilities through tasks.\n\ + Toreador - More human then other bloodsucker, easily disguise among crew, but bound with moral.")) var/answer = input("You have Ranked up far enough to remember your clan. Which clan are you part of?", "Our mind feels luxurious...") in options if(!answer) @@ -76,4 +78,22 @@ to_chat(owner, span_notice("You have also learned how to channel the abyss's power into an iron knight's armor that can be build in the structure ta and activated as a trap for your lair.")) owner.teach_crafting_recipe(/datum/crafting_recipe/possessedarmor) owner.teach_crafting_recipe(/datum/crafting_recipe/restingplace) + if(CLAN_TOREADOR) + my_clan = CLAN_TOREADOR + to_chat(owner, span_announce("You have Ranked up enough to learn: You are part of the Toreador Clan!\n\ + * As part of the Toreador, you can't ignore your own emotions and disrespect inhuman actions.\n\ + * Being in Masquarade doesn't spend your blood, as well as having any negative effects on your immortal powers.\n\ + * You passively rise morale of your living vassals around you.\n\ + * Also you get really sad when comitting inhumane actions, but your humanity loss can't go above a certain treashold.\n\ + * Remember, that those bloodsuckers who dare to act inhuman or break the Masquarade shouldn't be forgiven, and deserve only death.\n\ + * Finally, your Favorite Vassal will gain the Mesmerise ability to help you in non-lethaly dealing with enemies or vassalising people.")) + if(owner.current && ishuman(owner.current) && !owner.current.GetComponent(/datum/component/mood)) + owner.current.AddComponent(/datum/component/mood) //You are not a emotionless beast! + + for(var/datum/action/bloodsucker/masquerade/masquarade_spell in powers) + if(!istype(masquarade_spell)) + continue + masquarade_spell.bloodcost = 0 + masquarade_spell.constant_bloodcost = 0 //Wow very cool code, good job + owner.announce_objectives() \ No newline at end of file diff --git a/code/modules/antagonists/bloodsuckers/bloodsuckers.dm b/code/modules/antagonists/bloodsuckers/bloodsuckers.dm index f89c72c7c269..06cba0d50be0 100644 --- a/code/modules/antagonists/bloodsuckers/bloodsuckers.dm +++ b/code/modules/antagonists/bloodsuckers/bloodsuckers.dm @@ -740,13 +740,14 @@ continue if(!isliving(clan_minds.current)) continue - to_chat(clan_minds, span_userdanger("[owner.current] has broken the Masquerade! Ensure they are eliminated at all costs!")) var/datum/antagonist/bloodsucker/bloodsuckerdatum = clan_minds.has_antag_datum(/datum/antagonist/bloodsucker) - var/datum/objective/assassinate/masquerade_objective = new /datum/objective/assassinate - masquerade_objective.target = owner.current - masquerade_objective.explanation_text = "Ensure [owner.current], who has broken the Masquerade, is Final Death'ed." - bloodsuckerdatum.objectives += masquerade_objective - clan_minds.announce_objectives() + to_chat(clan_minds, span_userdanger("[owner.current] has broken the Masquerade![bloodsuckerdatum.my_clan == CLAN_TOREADOR ? "Ensure they are eliminated at all costs!" : ""]")) + if(bloodsuckerdatum.my_clan == CLAN_TOREADOR) + var/datum/objective/assassinate/masquerade_objective = new /datum/objective/assassinate + masquerade_objective.target = owner.current + masquerade_objective.explanation_text = "Ensure [owner.current], who has broken the Masquerade, is Final Death'ed." + bloodsuckerdatum.objectives += masquerade_objective + clan_minds.announce_objectives() ///This is admin-only of reverting a broken masquerade, sadly it doesn't remove the Malkavian objectives yet. /datum/antagonist/bloodsucker/proc/fix_masquerade() diff --git a/code/modules/antagonists/bloodsuckers/bloodsuckers_objects.dm b/code/modules/antagonists/bloodsuckers/bloodsuckers_objects.dm index d6ef5186e937..3957ec320fe8 100644 --- a/code/modules/antagonists/bloodsuckers/bloodsuckers_objects.dm +++ b/code/modules/antagonists/bloodsuckers/bloodsuckers_objects.dm @@ -338,7 +338,7 @@ They can be best defined as 'The most humane kind of vampire', due to their kindred with an obsession with perfectionism and beauty
\ Favorite Vassal: Their favorite Vassal gains the Mesmerize ability \ Strength: Highly charismatic and influential.
\ - Weakness: Physically and Morally weak." + Weakness: Morally weak." if(CLAN_NOSFERATU) dat += "This Clan has been the most obvious to find information about.
\ They are disfigured, ghoul-like vampires upon embrace by their Sire, scouts that travel through desolate paths to avoid violating the Masquerade.
\ diff --git a/code/modules/antagonists/bloodsuckers/powers/feed.dm b/code/modules/antagonists/bloodsuckers/powers/feed.dm index 0f5c19e440e4..d6ca9eeb4af8 100644 --- a/code/modules/antagonists/bloodsuckers/powers/feed.dm +++ b/code/modules/antagonists/bloodsuckers/powers/feed.dm @@ -147,6 +147,11 @@ // Checks: Step 2 - Is it a Mouse? if(istype(feed_target, /mob/living/simple_animal/mouse)) + if(bloodsuckerdatum_power.my_clan == CLAN_TOREADOR) + to_chat(user, span_danger("I am not going to drink blood of a lesser lifeform.")) + bloodsuckerdatum_power.AddHumanityLost(1) //Even attempting to do this disguisting action is against your morale, so get humanity loss + DeactivatePower() + return var/mob/living/simple_animal/mouse_target = feed_target bloodsuckerdatum_power.AddBloodVolume(25) to_chat(user, span_notice("You recoil at the taste of a lesser lifeform.")) diff --git a/code/modules/antagonists/bloodsuckers/structures/bloodsucker_life.dm b/code/modules/antagonists/bloodsuckers/structures/bloodsucker_life.dm index 4a94505bec52..28fc5ead0926 100644 --- a/code/modules/antagonists/bloodsuckers/structures/bloodsucker_life.dm +++ b/code/modules/antagonists/bloodsuckers/structures/bloodsucker_life.dm @@ -23,6 +23,17 @@ INVOKE_ASYNC(src, .proc/HandleStarving) INVOKE_ASYNC(src, .proc/HandleTorpor) + if(my_clan == CLAN_TOREADOR && owner.current.stat != DEAD) + for(var/datum/antagonist/vassal/vassal in vassals) + if(vassal.master != src) + continue + if(!vassal.owner.current || vassal.owner.current == DEAD) + continue + if(get_dist(get_turf(owner.current), get_turf(vassal.owner.current)) > 5) + continue + SEND_SIGNAL(vassal.owner.current, COMSIG_ADD_MOOD_EVENT, /datum/mood_event/toreador_vassal) + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // BLOOD ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -35,6 +46,12 @@ if(humanity_lost >= 500) to_chat(owner.current, span_warning("You hit the maximum amount of lost Humanity, you are far from Human.")) return + if(my_clan == CLAN_TOREADOR) + if(humanity_lost >= TOREADOR_MAX_HUMANITY_LOSS) + to_chat(owner.current, span_warning("Your moral prevents you from becoming more ihuman.")) + SEND_SIGNAL(owner.current, COMSIG_ADD_MOOD_EVENT, /datum/mood_event/toreador_inhuman2) + return + SEND_SIGNAL(owner.current, COMSIG_ADD_MOOD_EVENT, /datum/mood_event/toreador_inhuman) humanity_lost += value to_chat(owner.current, span_warning("You feel as if you lost some of your humanity, you will now enter Frenzy at [FRENZY_THRESHOLD_ENTER + humanity_lost * 10] Blood.")) @@ -90,7 +107,7 @@ /datum/antagonist/bloodsucker/proc/HandleHealing(mult = 1) var/actual_regen = bloodsucker_regen_rate + additional_regen // Don't heal if I'm staked or on Masquerade (+ not in a Coffin). Masqueraded Bloodsuckers in a Coffin however, will heal. - if(owner.current.AmStaked() || (HAS_TRAIT(owner.current, TRAIT_MASQUERADE) && !HAS_TRAIT(owner.current, TRAIT_NODEATH))) + if(owner.current.AmStaked() || (HAS_TRAIT(owner.current, TRAIT_MASQUERADE) && !HAS_TRAIT(owner.current, TRAIT_NODEATH) && my_clan != CLAN_TOREADOR)) return FALSE owner.current.adjustCloneLoss(-1 * (actual_regen * 4) * mult, 0) owner.current.adjustOrganLoss(ORGAN_SLOT_BRAIN, -1 * (actual_regen * 4) * mult) //adjustBrainLoss(-1 * (actual_regen * 4) * mult, 0) @@ -103,7 +120,7 @@ /// Checks if you're in a coffin here, additionally checks for Torpor right below it. var/amInCoffin = istype(user.loc, /obj/structure/closet/crate/coffin) if(amInCoffin && HAS_TRAIT(user, TRAIT_NODEATH)) - if(HAS_TRAIT(owner.current, TRAIT_MASQUERADE)) + if(HAS_TRAIT(owner.current, TRAIT_MASQUERADE) && my_clan != CLAN_TOREADOR) to_chat(user, span_warning("You will not heal while your Masquerade ability is active.")) return fireheal = min(user.getFireLoss_nonProsthetic(), actual_regen) @@ -481,6 +498,21 @@ mood_change = -6 timeout = 6 MINUTES +/datum/mood_event/toreador_inhuman + description = "I commited inhuman actions. I feel... bad.\n" + mood_change = -4 + timeout = 6 MINUTES + +/datum/mood_event/toreador_inhuman2 + description = "I should stop acting like this. What am I turning into?\n" + mood_change = -10 + timeout = 10 MINUTES + +/datum/mood_event/toreador_vassal + description = "My master is near me. I love them.\n" + mood_change = 4 + timeout = 30 SECONDS + ///Candelabrum's mood event to non Bloodsucker/Vassals /datum/mood_event/vampcandle description = "Something is making your mind feel... loose.\n" diff --git a/code/modules/antagonists/bloodsuckers/vassal.dm b/code/modules/antagonists/bloodsuckers/vassal.dm index 49bbc2f6336c..ca9a601126d2 100644 --- a/code/modules/antagonists/bloodsuckers/vassal.dm +++ b/code/modules/antagonists/bloodsuckers/vassal.dm @@ -67,6 +67,7 @@ //Remove Language & Hud owner.current.remove_language(/datum/language/vampiric) update_vassal_icons_removed(owner.current) + UnregisterSignal(master, COMSIG_BLOODSUCKER_RANKS_SPENT) return ..() /datum/antagonist/vassal/on_body_transfer(mob/living/old_body, mob/living/new_body) @@ -132,6 +133,15 @@ return playsound(vassal.loc, 'sound/effects/splat.ogg', 50, TRUE) vassal.set_species(/datum/species/szlachta) + if(CLAN_TOREADOR) + BuyPower(/datum/action/bloodsucker/targeted/mesmerize) + RegisterSignal(master, COMSIG_BLOODSUCKER_RANKS_SPENT, .proc/toreador_levelup_mesmerize) + +/datum/antagonist/vassal/proc/toreador_levelup_mesmerize() //Don't need stupid args + for(var/datum/action/bloodsucker/targeted/mesmerize/mesmerize_power in powers) + if(!istype(mesmerize_power)) + continue + mesmerize_power.level_current = max(master.bloodsucker_level, 1) /// If we weren't created by a bloodsucker, then we cannot be a vassal (assigned from antag panel) /datum/antagonist/vassal/can_be_owned(datum/mind/new_owner)