From 4b6ebc50c612b4fd2b49950d3c850c3412672520 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sun, 8 Mar 2026 17:47:43 +0300 Subject: [PATCH 001/149] =?UTF-8?q?=D0=9F=D1=80=D0=B8=D0=B2=D0=B5=D1=82,?= =?UTF-8?q?=20=D0=BC=D0=B5=D0=BD=D1=8F=20=D0=B7=D0=B0=D0=B2=D1=83=D1=82=20?= =?UTF-8?q?=D0=A1=D0=B0=D0=BA=D1=83=D0=BA=D0=B8=D0=BA=D0=BE=D1=83=D0=BA?= =?UTF-8?q?=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Вампиры, снова! --- .../_globalvars/traits/declarations.dm | 6 + code/__DEFINES/~ff_defines/bloodsucker.dm | 311 +++++++++ code/modules/surgery/organs/organ_movement.dm | 2 +- .../bloodsucker/bloodsuckers/assets.dm | 15 + .../bloodsucker/bloodsuckers/bloodsucker.dm | 607 +++++++++++++++++ .../modules/bloodsucker/bloodsuckers/clans.dm | 48 ++ .../bloodsucker/bloodsuckers/conversion.dm | 97 +++ .../bloodsucker/bloodsuckers/crafts.dm | 87 +++ .../modules/bloodsucker/bloodsuckers/hud.dm | 101 +++ .../bloodsucker/bloodsuckers/integration.dm | 118 ++++ .../modules/bloodsucker/bloodsuckers/life.dm | 495 ++++++++++++++ .../bloodsucker/bloodsuckers/movable_hud.dm | 207 ++++++ .../modules/bloodsucker/bloodsuckers/names.dm | 136 ++++ .../bloodsucker/bloodsuckers/objectives.dm | 372 ++++++++++ .../modules/bloodsucker/bloodsuckers/procs.dm | 381 +++++++++++ .../bloodsuckers/shaded_bloodsucker.dm | 5 + .../modules/bloodsucker/bloodsuckers/sol.dm | 154 +++++ .../bloodsucker/bloodsuckers/species.dm | 84 +++ .../bloodsucker/bloodsuckers/trauma.dm | 169 +++++ tff_modular/modules/bloodsucker/clans/clan.dm | 339 +++++++++ .../bloodsucker/clans/clan_flavortext.dm | 47 ++ .../bloodsucker/clans/clan_malkavian.dm | 100 +++ .../bloodsucker/clans/clan_nosferatu.dm | 103 +++ .../modules/bloodsucker/clans/clan_tremere.dm | 63 ++ .../modules/bloodsucker/clans/clan_ventrue.dm | 153 +++++ .../modules/bloodsucker/credit_file.md | 32 + .../modules/bloodsucker/icons/bloodsucker.dmi | Bin 0 -> 20484 bytes .../icons/bloodsucker_lefthand.dmi | Bin 0 -> 6531 bytes .../icons/bloodsucker_righthand.dmi | Bin 0 -> 6751 bytes .../modules/bloodsucker/icons/clan_icons.dmi | Bin 0 -> 16483 bytes tff_modular/modules/bloodsucker/icons/hud.dmi | Bin 0 -> 1342 bytes .../modules/bloodsucker/icons/language.dmi | Bin 0 -> 722 bytes .../bloodsucker/icons/phobetor_tear.dmi | Bin 0 -> 1927 bytes .../modules/bloodsucker/icons/stakes.dmi | Bin 0 -> 866 bytes .../bloodsucker/icons/tremere_bloodsucker.dmi | Bin 0 -> 5371 bytes .../modules/bloodsucker/icons/vamp_obj.dmi | Bin 0 -> 10653 bytes .../modules/bloodsucker/icons/vamp_obj_64.dmi | Bin 0 -> 1109 bytes .../modules/bloodsucker/powers/_powers.dm | 319 +++++++++ .../modules/bloodsucker/powers/cloak.dm | 86 +++ .../modules/bloodsucker/powers/feed.dm | 458 +++++++++++++ .../modules/bloodsucker/powers/fortitude.dm | 112 +++ .../modules/bloodsucker/powers/gohome.dm | 138 ++++ .../modules/bloodsucker/powers/masquerade.dm | 115 ++++ .../powers/targeted/_powers_targeted.dm | 119 ++++ .../bloodsucker/powers/targeted/brawn.dm | 229 +++++++ .../bloodsucker/powers/targeted/haste.dm | 120 ++++ .../bloodsucker/powers/targeted/lunge.dm | 191 ++++++ .../bloodsucker/powers/targeted/mesmerize.dm | 243 +++++++ .../bloodsucker/powers/targeted/trespass.dm | 109 +++ .../powers/tremere/_powers_tremere.dm | 22 + .../bloodsucker/powers/tremere/auspex.dm | 120 ++++ .../bloodsucker/powers/tremere/dominate.dm | 217 ++++++ .../bloodsucker/powers/tremere/thaumaturgy.dm | 288 ++++++++ .../bloodsucker/powers/vassal/distress.dm | 24 + .../bloodsucker/powers/vassal/recuperate.dm | 75 ++ .../bloodsucker/powers/vassal/vassal_fold.dm | 90 +++ .../modules/bloodsucker/powers/veil.dm | 162 +++++ .../bloodsucker/sound/BloodsuckerAlert.ogg | Bin 0 -> 218645 bytes .../modules/bloodsucker/sound/griffin_1.ogg | Bin 0 -> 4117 bytes .../modules/bloodsucker/sound/griffin_10.ogg | Bin 0 -> 7282 bytes .../modules/bloodsucker/sound/griffin_2.ogg | Bin 0 -> 4352 bytes .../modules/bloodsucker/sound/griffin_3.ogg | Bin 0 -> 4912 bytes .../modules/bloodsucker/sound/griffin_4.ogg | Bin 0 -> 5274 bytes .../modules/bloodsucker/sound/griffin_5.ogg | Bin 0 -> 5512 bytes .../modules/bloodsucker/sound/griffin_6.ogg | Bin 0 -> 5895 bytes .../modules/bloodsucker/sound/griffin_7.ogg | Bin 0 -> 6307 bytes .../modules/bloodsucker/sound/griffin_8.ogg | Bin 0 -> 6620 bytes .../modules/bloodsucker/sound/griffin_9.ogg | Bin 0 -> 6913 bytes .../modules/bloodsucker/sound/lunge_warn.ogg | Bin 0 -> 73076 bytes .../modules/bloodsucker/sound/owl_1.ogg | Bin 0 -> 4208 bytes .../modules/bloodsucker/sound/owl_10.ogg | Bin 0 -> 7811 bytes .../modules/bloodsucker/sound/owl_2.ogg | Bin 0 -> 4615 bytes .../modules/bloodsucker/sound/owl_3.ogg | Bin 0 -> 5030 bytes .../modules/bloodsucker/sound/owl_5.ogg | Bin 0 -> 5796 bytes .../modules/bloodsucker/sound/owl_6.ogg | Bin 0 -> 6211 bytes .../modules/bloodsucker/sound/owl_7.ogg | Bin 0 -> 6591 bytes .../modules/bloodsucker/sound/owl_8.ogg | Bin 0 -> 7037 bytes .../modules/bloodsucker/sound/owl_9.ogg | Bin 0 -> 7381 bytes .../modules/bloodsucker/structures/coffin.dm | 348 ++++++++++ .../modules/bloodsucker/structures/crypt.dm | 642 ++++++++++++++++++ .../modules/bloodsucker/structures/objects.dm | 358 ++++++++++ .../modules/bloodsucker/vassal/batform.dm | 61 ++ .../bloodsucker/vassal/vassal_datum.dm | 185 +++++ .../bloodsucker/vassal/vassal_pinpointer.dm | 31 + .../bloodsucker/vassal/vassal_procs.dm | 77 +++ .../vassal/vassal_types/ex_vassal.dm | 103 +++ .../vassal/vassal_types/favorite_vassal.dm | 28 + .../vassal/vassal_types/revenge_vassal.dm | 68 ++ .../strings/malkavian_revelations.json | 58 ++ tgstation.dme | 52 ++ .../tgui/interfaces/AntagInfoBloodsucker.tsx | 229 +++++++ tgui/packages/tgui/interfaces/KindredBook.tsx | 43 ++ 92 files changed, 9751 insertions(+), 1 deletion(-) create mode 100644 code/__DEFINES/~ff_defines/bloodsucker.dm create mode 100644 tff_modular/modules/bloodsucker/bloodsuckers/assets.dm create mode 100644 tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm create mode 100644 tff_modular/modules/bloodsucker/bloodsuckers/clans.dm create mode 100644 tff_modular/modules/bloodsucker/bloodsuckers/conversion.dm create mode 100644 tff_modular/modules/bloodsucker/bloodsuckers/crafts.dm create mode 100644 tff_modular/modules/bloodsucker/bloodsuckers/hud.dm create mode 100644 tff_modular/modules/bloodsucker/bloodsuckers/integration.dm create mode 100644 tff_modular/modules/bloodsucker/bloodsuckers/life.dm create mode 100644 tff_modular/modules/bloodsucker/bloodsuckers/movable_hud.dm create mode 100644 tff_modular/modules/bloodsucker/bloodsuckers/names.dm create mode 100644 tff_modular/modules/bloodsucker/bloodsuckers/objectives.dm create mode 100644 tff_modular/modules/bloodsucker/bloodsuckers/procs.dm create mode 100644 tff_modular/modules/bloodsucker/bloodsuckers/shaded_bloodsucker.dm create mode 100644 tff_modular/modules/bloodsucker/bloodsuckers/sol.dm create mode 100644 tff_modular/modules/bloodsucker/bloodsuckers/species.dm create mode 100644 tff_modular/modules/bloodsucker/bloodsuckers/trauma.dm create mode 100644 tff_modular/modules/bloodsucker/clans/clan.dm create mode 100644 tff_modular/modules/bloodsucker/clans/clan_flavortext.dm create mode 100644 tff_modular/modules/bloodsucker/clans/clan_malkavian.dm create mode 100644 tff_modular/modules/bloodsucker/clans/clan_nosferatu.dm create mode 100644 tff_modular/modules/bloodsucker/clans/clan_tremere.dm create mode 100644 tff_modular/modules/bloodsucker/clans/clan_ventrue.dm create mode 100644 tff_modular/modules/bloodsucker/credit_file.md create mode 100644 tff_modular/modules/bloodsucker/icons/bloodsucker.dmi create mode 100644 tff_modular/modules/bloodsucker/icons/bloodsucker_lefthand.dmi create mode 100644 tff_modular/modules/bloodsucker/icons/bloodsucker_righthand.dmi create mode 100644 tff_modular/modules/bloodsucker/icons/clan_icons.dmi create mode 100644 tff_modular/modules/bloodsucker/icons/hud.dmi create mode 100644 tff_modular/modules/bloodsucker/icons/language.dmi create mode 100644 tff_modular/modules/bloodsucker/icons/phobetor_tear.dmi create mode 100644 tff_modular/modules/bloodsucker/icons/stakes.dmi create mode 100644 tff_modular/modules/bloodsucker/icons/tremere_bloodsucker.dmi create mode 100644 tff_modular/modules/bloodsucker/icons/vamp_obj.dmi create mode 100644 tff_modular/modules/bloodsucker/icons/vamp_obj_64.dmi create mode 100644 tff_modular/modules/bloodsucker/powers/_powers.dm create mode 100644 tff_modular/modules/bloodsucker/powers/cloak.dm create mode 100644 tff_modular/modules/bloodsucker/powers/feed.dm create mode 100644 tff_modular/modules/bloodsucker/powers/fortitude.dm create mode 100644 tff_modular/modules/bloodsucker/powers/gohome.dm create mode 100644 tff_modular/modules/bloodsucker/powers/masquerade.dm create mode 100644 tff_modular/modules/bloodsucker/powers/targeted/_powers_targeted.dm create mode 100644 tff_modular/modules/bloodsucker/powers/targeted/brawn.dm create mode 100644 tff_modular/modules/bloodsucker/powers/targeted/haste.dm create mode 100644 tff_modular/modules/bloodsucker/powers/targeted/lunge.dm create mode 100644 tff_modular/modules/bloodsucker/powers/targeted/mesmerize.dm create mode 100644 tff_modular/modules/bloodsucker/powers/targeted/trespass.dm create mode 100644 tff_modular/modules/bloodsucker/powers/tremere/_powers_tremere.dm create mode 100644 tff_modular/modules/bloodsucker/powers/tremere/auspex.dm create mode 100644 tff_modular/modules/bloodsucker/powers/tremere/dominate.dm create mode 100644 tff_modular/modules/bloodsucker/powers/tremere/thaumaturgy.dm create mode 100644 tff_modular/modules/bloodsucker/powers/vassal/distress.dm create mode 100644 tff_modular/modules/bloodsucker/powers/vassal/recuperate.dm create mode 100644 tff_modular/modules/bloodsucker/powers/vassal/vassal_fold.dm create mode 100644 tff_modular/modules/bloodsucker/powers/veil.dm create mode 100644 tff_modular/modules/bloodsucker/sound/BloodsuckerAlert.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/griffin_1.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/griffin_10.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/griffin_2.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/griffin_3.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/griffin_4.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/griffin_5.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/griffin_6.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/griffin_7.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/griffin_8.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/griffin_9.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/lunge_warn.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/owl_1.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/owl_10.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/owl_2.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/owl_3.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/owl_5.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/owl_6.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/owl_7.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/owl_8.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/owl_9.ogg create mode 100644 tff_modular/modules/bloodsucker/structures/coffin.dm create mode 100644 tff_modular/modules/bloodsucker/structures/crypt.dm create mode 100644 tff_modular/modules/bloodsucker/structures/objects.dm create mode 100644 tff_modular/modules/bloodsucker/vassal/batform.dm create mode 100644 tff_modular/modules/bloodsucker/vassal/vassal_datum.dm create mode 100644 tff_modular/modules/bloodsucker/vassal/vassal_pinpointer.dm create mode 100644 tff_modular/modules/bloodsucker/vassal/vassal_procs.dm create mode 100644 tff_modular/modules/bloodsucker/vassal/vassal_types/ex_vassal.dm create mode 100644 tff_modular/modules/bloodsucker/vassal/vassal_types/favorite_vassal.dm create mode 100644 tff_modular/modules/bloodsucker/vassal/vassal_types/revenge_vassal.dm create mode 100644 tff_modular/strings/malkavian_revelations.json create mode 100644 tgui/packages/tgui/interfaces/AntagInfoBloodsucker.tsx create mode 100644 tgui/packages/tgui/interfaces/KindredBook.tsx diff --git a/code/__DEFINES/~ff_defines/_globalvars/traits/declarations.dm b/code/__DEFINES/~ff_defines/_globalvars/traits/declarations.dm index 9b3ae25f1ff..b34af8f4b10 100644 --- a/code/__DEFINES/~ff_defines/_globalvars/traits/declarations.dm +++ b/code/__DEFINES/~ff_defines/_globalvars/traits/declarations.dm @@ -4,3 +4,9 @@ #define TRAIT_XENO_ABILITY_GIVEN "xeno_ability_given" /// Determines if something can receive healing from a xeno #define TRAIT_XENO_HEAL_AURA "trait_xeno_heal_aura" + +#define GHOUL_SCAN_MIN_DISTANCE 5 +#define GHOUL_SCAN_MAX_DISTANCE 500 +/// 2s update time. +#define GHOUL_SCAN_PING_TIME 20 +#define TRAIT_TORPOR "torpor" diff --git a/code/__DEFINES/~ff_defines/bloodsucker.dm b/code/__DEFINES/~ff_defines/bloodsucker.dm new file mode 100644 index 00000000000..3230a3372be --- /dev/null +++ b/code/__DEFINES/~ff_defines/bloodsucker.dm @@ -0,0 +1,311 @@ +///Uncomment this to enable testing of Bloodsucker features (such as ghoulizing people with a mind instead of a client). +// #define BLOODSUCKER_TESTING // if this isn't commented out, someone is a dumbfuck + +//Torpor softlock prevention - define it high as it is a failsafe +#define BLOODSUCKER_TORPOR_MAX_TIME (120 SECONDS) +/// You have special interactions with Bloodsuckers +#define TRAIT_BLOODSUCKER_HUNTER "bloodsucker_hunter" + +#define ROLE_BLOODSUCKER "Bloodsucker" +#define ROLE_VAMPIRICACCIDENT "Bloodsucker (Midround)" +#define ROLE_BLOODSUCKERBREAKOUT "Bloodsucker (Latejoin)" +#define ROLE_VASSAL "Vassal" + +///The mob is some kind of vampire, species or antag +#define MOB_VAMPIRIC (1 << 16) + +// how much to multiply the coffin size by mob_size +#define COFFIN_ENLARGE_MULT 0.5 + +/// At what health to burn damage ratio you Final Death +#define FINAL_DEATH_HEALTH_TO_BURN 2.5 +/** + * Blood-level defines + */ +/// Determines Bloodsucker regeneration rate +#define BS_BLOOD_VOLUME_MAX_REGEN 700 +/// Cost to torture someone halfway, in blood. Called twice for full cost +#define TORTURE_BLOOD_HALF_COST 4 +/// Cost to convert someone after successful torture, in blood +#define TORTURE_CONVERSION_COST 10 +/// How much blood it costs you to make a ghoul into a special ghoul +#define SPECIAL_GHOUL_COST 150 +/// Minimum and maximum frenzy blood thresholds +/// Once blood is this low, will enter Frenzy +#define FRENZY_THRESHOLD_ENTER 25 +/// Once blood is this high, will exit Frenzy +#define FRENZY_THRESHOLD_EXIT 250 + +/// a bloodsucker can't loose more humanity than this, and looses the masquerade ability when reaching it +#define HUMANITY_LOST_MAXIMUM 50 + +/// Level up blood cost define, max_blood * this = blood cost +#define BLOODSUCKER_LEVELUP_PERCENTAGE 0.40 +#define BLOODSUCKER_LEVELUP_PERCENTAGE_VENTRUE BLOODSUCKER_LEVELUP_PERCENTAGE - 0.1 + +///The level when at a bloodsucker becomes snobby about who they drink from and gain their non-fledling reputation +#define BLOODSUCKER_HIGH_LEVEL 4 + +/** + * Sol defines + */ +///How long Sol will last until it's night again. +#define TIME_BLOODSUCKER_DAY 60 +///Base time nighttime should be in for, until Sol rises. +// Can't put defines in defines, so we have to use deciseconds. +#define TIME_BLOODSUCKER_NIGHT_MAX 1320 // 22 minutes +#define TIME_BLOODSUCKER_NIGHT_MIN 1020 // 17 minutes + +///Time left to send an alert to Bloodsuckers about an incoming Sol. +#define TIME_BLOODSUCKER_DAY_WARN 90 +///Time left to send an urgent alert to Bloodsuckers about an incoming Sol. +#define TIME_BLOODSUCKER_DAY_FINAL_WARN 30 +///Time left to alert that Sol is rising. +#define TIME_BLOODSUCKER_BURN_INTERVAL 5 + +///How much time Sol can be 'off' by, keeping the time inconsistent. +#define TIME_BLOODSUCKER_SOL_DELAY 90 + +/** + * Ghoul defines + */ +///If someone passes all checks and can be ghouled +#define GHOULING_ALLOWED 0 +///If someone has to accept ghouling +#define GHOULING_DISLOYAL 1 +///If someone is not allowed under any circimstances to become a Ghoul +#define GHOULING_BANNED 2 + +/** + * Cooldown defines + * Used in Cooldowns Bloodsuckers use to prevent spamming + */ +///Spam prevention for healing messages. +#define BLOODSUCKER_SPAM_HEALING (15 SECONDS) +///Span prevention for Sol Masquerade messages. +#define BLOODSUCKER_SPAM_MASQUERADE (60 SECONDS) + +///Span prevention for Sol messages. +#define BLOODSUCKER_SPAM_SOL (30 SECONDS) + + +/** + * Clan defines + */ +#define CLAN_NONE "Caitiff" +#define CLAN_BRUJAH "Brujah Clan" +#define CLAN_TOREADOR "Toreador Clan" +#define CLAN_NOSFERATU "Nosferatu Clan" +#define CLAN_TREMERE "Tremere Clan" +#define CLAN_GANGREL "Gangrel Clan" +#define CLAN_VENTRUE "Ventrue Clan" +#define CLAN_MALKAVIAN "Malkavian Clan" +#define CLAN_TZIMISCE "Tzimisce Clan" + +#define TREMERE_GHOUL "tremere_ghoul" +#define FAVORITE_GHOUL "favorite_ghoul" +#define REVENGE_GHOUL "revenge_ghoul" + +/** + * Power defines + */ +/// This Power can't be used in Torpor +#define BP_CANT_USE_IN_TORPOR (1<<0) +/// This Power can't be used in Frenzy. +#define BP_CANT_USE_IN_FRENZY (1<<1) +/// This Power can be used while transformed, for example by the shapeshift spell +#define BP_CAN_USE_TRANSFORMED (1<<2) +/// This Power can be used with a stake in you +#define BP_CAN_USE_WHILE_STAKED (1<<4) +/// This Power can be used while heartless +#define BP_CAN_USE_HEARTLESS (1<<5) + +/// This Power can be purchased by Bloodsuckers +#define BLOODSUCKER_CAN_BUY (1<<0) +/// This is a Default Power that all Bloodsuckers get. +#define BLOODSUCKER_DEFAULT_POWER (1<<1) +/// This Power can be purchased by Tremere Bloodsuckers +#define TREMERE_CAN_BUY (1<<2) + +/// This Power can be purchased by Ghouls +#define GHOUL_CAN_BUY (1<<3) + +/// If this Power can be bought if you already own it +#define CAN_BUY_OWNED (1<<4) + + +/// This Power is a Continuous Effect, processing every tick +#define BP_CONTINUOUS_EFFECT (1<<0) +/// This Power is a Single-Use Power +#define BP_AM_SINGLEUSE (1<<1) +/// This Power has a Static cooldown +#define BP_AM_STATIC_COOLDOWN (1<<2) +/// This Power doesn't cost bloot to run while unconscious +#define BP_AM_COSTLESS_UNCONSCIOUS (1<<3) + +#define DEACTIVATE_POWER_DO_NOT_REMOVE (1<<0) +#define DEACTIVATE_POWER_NO_COOLDOWN (1<<1) + +// ability levels that are used cross-file +#define DOMINATE_GHOULIZE_LEVEL 2 +#define TREMERE_OBJECTIVE_POWER_LEVEL 4 + +#define COFFIN_HEAL_COST_MULT 0.5 + + +/** + * Torpor check bitflags + */ +#define TORPOR_SKIP_CHECK_ALL (1<<0) +#define TORPOR_SKIP_CHECK_FRENZY (1<<1) +#define TORPOR_SKIP_CHECK_DAMAGE (1<<2) + +/** + * Bloodsucker Signals + */ +///Called when a Bloodsucker ranks up: (datum/bloodsucker_datum, mob/owner, mob/target) +#define COMSIG_BLOODSUCKER_RANK_UP "bloodsucker_rank_up" +///Called when a Bloodsucker interacts with a Ghoul on their persuasion rack. +#define COMSIG_BLOODSUCKER_INTERACT_WITH_GHOUL "bloodsucker_interact_with_ghoul" +///Called when a Bloodsucker makes a Ghoul into their Favorite Ghoul: (datum/ghoul_datum, mob/master) +#define COMSIG_BLOODSUCKER_MAKE_FAVORITE "bloodsucker_make_favorite" +// called when a bloodsucker looses their favorite ghoul, cleaning up whatever they gained +#define COMSIG_BLOODSUCKER_LOOSE_FAVORITE "bloodsucker_loose_favorite" +///Called when a new Ghoul is successfully made: (datum/bloodsucker_datum) +#define COMSIG_BLOODSUCKER_MADE_GHOUL "bloodsucker_made_ghoul" +///Called when a Bloodsucker exits Torpor. +#define COMSIG_BLOODSUCKER_EXIT_TORPOR "bloodsucker_exit_torpor" +///Called when a Bloodsucker reaches Final Death. +#define COMSIG_BLOODSUCKER_FINAL_DEATH "bloodsucker_final_death" + ///Whether the Bloodsucker should not be dusted when arriving Final Death + #define DONT_DUST (1<<0) +///Called when a Bloodsucker breaks the Masquerade +#define COMSIG_BLOODSUCKER_BROKE_MASQUERADE "comsig_bloodsucker_broke_masquerade" +///Called when a Bloodsucker enters Frenzy +#define COMSIG_BLOODSUCKER_ENTERS_FRENZY "bloodsucker_enters_frenzy" +///Called when a Bloodsucker exits Frenzy +#define COMSIG_BLOODSUCKER_EXITS_FRENZY "bloodsucker_exits_frenzy" +/// COMSIG_ATOM_EXAMINE that correctly updates when the bloodsucker datum is moved +#define COMSIG_BLOODSUCKER_EXAMINE "bloodsucker_examine" +/// from /obj/item/organ/proc/on_bodypart_remove(obj/item/bodypart/limb, movement_flags) +#define COMSIG_ORGAN_BODYPART_REMOVED "organ_bodypart_removed" +// Called when anyone enters the coffin +#define COMSIG_ENTER_COFFIN "enter_coffin" +#define COMSIG_MOB_STAKED "staked" +#define COMSIG_BODYPART_STAKED "staked" +// called when a targeted ability is cast +#define COMSIG_FIRE_TARGETED_POWER "comsig_fire_targeted_power" + +/// drink blood via the feed action +#define COMSIG_MOB_FEED_DRINK "mob_feed_drink" +#define FEED_CANCEL_BLOOD_TRANSFER (1 << 0) + +/// returns the bitflag if it indeed reached max blood, otherwise NONE +#define COMSIG_MOB_REACHED_MAX_BLOOD "mob_reached_max_blood" +#define REACHED_MAX_BLOOD (1 << 0) + +/** + * Sol signals & Defines + */ +#define COMSIG_SOL_RANKUP_BLOODSUCKERS "comsig_sol_rankup_bloodsuckers" +#define COMSIG_SOL_RISE_TICK "comsig_sol_rise_tick" +#define COMSIG_SOL_NEAR_START "comsig_sol_near_start" +#define COMSIG_SOL_END "comsig_sol_end" +///Sent when a warning for Sol is meant to go out: (danger_level, vampire_warning_message, ghoul_warning_message) +#define COMSIG_SOL_WARNING_GIVEN "comsig_sol_warning_given" +///Called on a Bloodsucker's Lifetick. +#define COMSIG_BLOODSUCKER_ON_LIFETICK "comsig_bloodsucker_on_lifetick" +/// Called when a Bloodsucker's blood is updated +#define BLOODSUCKER_UPDATE_BLOOD "bloodsucker_update_blood" + #define BLOODSUCKER_UPDATE_BLOOD_DISABLED (1<<0) + +#define DANGER_LEVEL_FIRST_WARNING 1 +#define DANGER_LEVEL_SECOND_WARNING 2 +#define DANGER_LEVEL_THIRD_WARNING 3 +#define DANGER_LEVEL_SOL_ROSE 4 +#define DANGER_LEVEL_SOL_ENDED 5 + +/** + * Clan defines + * + * This is stuff that is used solely by Clans for clan-related activity. + */ +///Drinks blood the normal Bloodsucker way. +#define BLOODSUCKER_DRINK_NORMAL "bloodsucker_drink_normal" +///Drinks blood but is snobby, refusing to drink from mindless +#define BLOODSUCKER_DRINK_SNOBBY "bloodsucker_drink_snobby" +///Drinks blood from disgusting creatures without Humanity consequences. +#define BLOODSUCKER_DRINK_INHUMANELY "bloodsucker_drink_inhumanely" + +/** + * Traits + */ +/// Falsifies Health analyzer blood levels +#define TRAIT_MASQUERADE "masquerade" +/// Your body is literal room temperature. Does not make you immune to the temp +#define TRAIT_COLDBLOODED "coldblooded" + +#define TRAIT_COFFIN_ENLARGED "coffin_enlarged" + +/** + * Sources + */ +/// Source trait for Bloodsuckers-related traits +#define BLOODSUCKER_TRAIT "bloodsucker_trait" + +#define GHOUL_TRAIT "ghoul_trait" + +#define TORPOR_TRAIT "torpor" + +/// Source trait for dominate related traits +#define MESMERIZE_TRAIT "meserize_trait" +#define DOMINATE_TRAIT "dominate_trait" + +/// Source trait for Monster Hunter-related traits +#define HUNTER_TRAIT "monsterhunter_trait" +/// Source trait while Feeding +#define FEED_TRAIT "feed_trait" +/// Source trait during a Frenzy +#define FRENZY_TRAIT "frenzy_trait" + +///Whether a mob is a Bloodsucker +#define IS_BLOODSUCKER(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/bloodsucker)) +///Whether a mob is a Ghoul +#define IS_GHOUL(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/ghoul)) +///Whether a mob is a Favorite Ghoul +#define IS_FAVORITE_GHOUL(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/ghoul/favorite)) +///Whether a mob is a Revenge Ghoul +#define IS_REVENGE_GHOUL(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/ghoul/revenge)) +#define IS_EX_GHOUL(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/ex_ghoul)) + +///Whether a mob is a Monster Hunter-NOT NEEDED RIGHT NOW +// #define IS_MONSTERHUNTER(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/monsterhunter)) +///For future use +#define IS_MONSTERHUNTER(mob) (FALSE) + +#define BLOODSUCKER_SIGHT_COLOR_CUTOFF list(25, 8, 5) +#define POLL_IGNORE_GHOUL "ghoul" + +// Why waste memory on a dynamic global list if we can just bake it in on compile time? +#define BLOODSUCKER_BLACKLISTED_ROLES list( \ + JOB_CAPTAIN, \ + JOB_HEAD_OF_PERSONNEL, \ + JOB_HEAD_OF_SECURITY, \ + JOB_WARDEN, \ + JOB_SECURITY_OFFICER, \ + JOB_DETECTIVE, \ +) + +#define BLOODSUCKER_RESTRICTED_SPECIES list( \ + /datum/species/synthetic, \ + /datum/species/plasmaman, \ + /datum/species/shadow/nightmare, \ + /datum/species/abductor, \ + /datum/species/android, \ + /datum/species/golem, \ + /datum/species/shadow, \ + /datum/species/skeleton, \ + /datum/species/zombie, \ + /datum/species/mutant, \ + /datum/species/dullahan \ +) diff --git a/code/modules/surgery/organs/organ_movement.dm b/code/modules/surgery/organs/organ_movement.dm index 2fa5b1f103e..07bcf4baecb 100644 --- a/code/modules/surgery/organs/organ_movement.dm +++ b/code/modules/surgery/organs/organ_movement.dm @@ -244,7 +244,7 @@ item_flags &= ~ABSTRACT REMOVE_TRAIT(src, TRAIT_NODROP, ORGAN_INSIDE_BODY_TRAIT) - + SEND_SIGNAL(src, COMSIG_ORGAN_BODYPART_REMOVED, limb, movement_flags) // TFF ADDITION, added COMSIG_ORGAN_BODYPART_REMOVED to on_bodypart_remove limb.owner?.synchronize_bodytypes() limb.owner?.synchronize_bodyshapes() diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/assets.dm b/tff_modular/modules/bloodsucker/bloodsuckers/assets.dm new file mode 100644 index 00000000000..916f7b579e8 --- /dev/null +++ b/tff_modular/modules/bloodsucker/bloodsuckers/assets.dm @@ -0,0 +1,15 @@ +/datum/asset/simple/bloodsucker_icons + +/datum/asset/simple/bloodsucker_icons/register() + for(var/datum/bloodsucker_clan/clans as anything in typesof(/datum/bloodsucker_clan)) + if(!initial(clans.joinable_clan)) + continue + add_bloodsucker_icon(initial(clans.join_icon), initial(clans.join_icon_state)) + + for(var/datum/action/cooldown/bloodsucker/power as anything in subtypesof(/datum/action/cooldown/bloodsucker)) + add_bloodsucker_icon(initial(power.button_icon), initial(power.button_icon_state)) + + return ..() + +/datum/asset/simple/bloodsucker_icons/proc/add_bloodsucker_icon(bloodsucker_icon, bloodsucker_icon_state) + assets[SANITIZE_FILENAME("bloodsucker.[bloodsucker_icon_state].png")] = icon(bloodsucker_icon, bloodsucker_icon_state) diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm b/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm new file mode 100644 index 00000000000..f4b6d2c1ee2 --- /dev/null +++ b/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm @@ -0,0 +1,607 @@ +/datum/antagonist/bloodsucker + name = "\improper Bloodsucker" + show_in_antagpanel = TRUE + roundend_category = "bloodsuckers" + antagpanel_category = "Bloodsucker" + pref_flag = ROLE_BLOODSUCKER + antag_hud_name = "bloodsucker" + show_name_in_check_antagonists = TRUE + hijack_speed = 0.5 + hud_icon = 'tff_modular/modules/bloodsucker/icons/bloodsucker.dmi' + ui_name = "AntagInfoBloodsucker" + preview_outfit = /datum/outfit/bloodsucker_outfit + + /// How much blood we have, starting off at default blood levels. Do not adjust this directly, use adjustBloodVolume(), and use getBloodVolume() to get the current value. + VAR_PRIVATE/bloodsucker_blood_volume = BLOOD_VOLUME_NORMAL + /// How much blood we can have without it deckaying quickly, increases per level. + var/max_blood_volume = 600 + + var/datum/bloodsucker_clan/my_clan + + // TIMERS // + ///Timer between alerts for Burn messages + COOLDOWN_DECLARE(bloodsucker_spam_sol_burn) + ///Timer between alerts for Healing messages + COOLDOWN_DECLARE(bloodsucker_spam_healing) + /// Timer between exiting torpor + COOLDOWN_DECLARE(bloodsucker_spam_torpor) + + COOLDOWN_DECLARE(bloodsucker_torpor_max_time) + ///Used for assigning your name + var/bloodsucker_name + ///Used for assigning your title + var/bloodsucker_title + ///Used for assigning your reputation + var/bloodsucker_reputation + + ///Amount of Humanity lost, don't modify this directly, use AddHumanityLost(), and use GetHumanityLost() to get the current value. + VAR_PRIVATE/humanity_lost = 0 + ///Have we been broken the Masquerade? + var/broke_masquerade = FALSE + ///How many Masquerade Infractions do we have? + var/masquerade_infractions = 0 + ///If we are currently in a Frenzy + var/frenzied = FALSE + /// sired by a ventrue + var/ventrue_sired + + ///ALL Powers currently owned + var/list/datum/action/cooldown/bloodsucker/powers = list() + + ///Ghouls under my control. Periodically remove the dead ones. + var/list/datum/antagonist/ghoul/ghouls = list() + ///Special ghouls I own, to not have double of the same type. + var/list/datum/antagonist/ghoul/special_ghouls = list() + + ///How many ranks we have, don't modify this directly, use AdjustRank() and use GetRank() to get the current value. + VAR_PRIVATE/bloodsucker_level = 0 + /// Unspent ranks, don't modify this directly, use AdjustUnspentRank() and use GetUnspentRank() to get the current value. + VAR_PRIVATE/bloodsucker_level_unspent = 1 + var/additional_regen + var/blood_over_cap = 0 + var/bloodsucker_regen_rate = 0.3 + + // Used for Bloodsucker Objectives + var/area/bloodsucker_haven_area + var/obj/structure/closet/crate/coffin + var/total_blood_drank = 0 + + /// Used for Bloodsuckers gaining levels from drinking blood + var/blood_level_gain = 0 + /// How many levels you can get from Sol + var/sol_levels_remaining = 6 + + ///Blood display HUD + var/atom/movable/screen/bloodsucker/blood_counter/blood_display + ///Vampire level display HUD + var/atom/movable/screen/bloodsucker/rank_counter/vamprank_display + + /// Static typecache of all bloodsucker powers. + var/static/list/all_bloodsucker_powers = typecacheof(/datum/action/cooldown/bloodsucker, ignore_root_path = TRUE) + /// Antagonists that cannot be Ghouled no matter what + var/static/list/ghoul_banned_antags = list( + /datum/antagonist/bloodsucker, + // /datum/antagonist/monsterhunter, + /datum/antagonist/changeling, + /datum/antagonist/cult, + // /datum/antagonist/ert/safety_moth, + ) + ///Default Bloodsucker traits + var/static/list/bloodsucker_traits = list( + TRAIT_NOBREATH, + TRAIT_SLEEPIMMUNE, + TRAIT_NOCRITDAMAGE, + TRAIT_RESISTCOLD, + TRAIT_RADIMMUNE, + TRAIT_STABLEHEART, + TRAIT_NOSOFTCRIT, + TRAIT_NOHARDCRIT, + TRAIT_AGEUSIA, + TRAIT_COLDBLOODED, + TRAIT_VIRUSIMMUNE, + TRAIT_NO_MIRROR_REFLECTION, + TRAIT_DRINKS_BLOOD, + TRAIT_TOXIMMUNE, + // Fun fact, toxins can still be applied to you if you loose your liver even with TOXIMMUNE + TRAIT_STABLELIVER + ) + var/static/biotype = MOB_VAMPIRIC + + var/static/list/torpor_traits = list( + TRAIT_DEATHCOMA, + TRAIT_FAKEDEATH, + TRAIT_NODEATH, + TRAIT_RESISTHIGHPRESSURE, + TRAIT_RESISTLOWPRESSURE, + ) + + var/list/body_signals = list( + COMSIG_ATOM_EXAMINE = PROC_REF(on_examine), + COMSIG_LIVING_LIFE = PROC_REF(LifeTick), + COMSIG_LIVING_DEATH = PROC_REF(on_death), + COMSIG_SPECIES_GAIN = PROC_REF(on_species_gain), + COMSIG_QDELETING = PROC_REF(on_owner_deletion), + COMSIG_ENTER_COFFIN = PROC_REF(on_enter_coffin), + COMSIG_MOB_STAKED = PROC_REF(on_staked), + COMSIG_CARBON_LOSE_ORGAN = PROC_REF(on_organ_removal), + COMSIG_HUMAN_ON_HANDLE_BLOOD = PROC_REF(HandleBlood), + ) + +/** + * Apply innate effects is everything given to the mob + * When a body is tranferred, this is called on the new mob + * while on_gain is called ONCE per ANTAG, this is called ONCE per BODY. + */ +/datum/antagonist/bloodsucker/apply_innate_effects(mob/living/mob_override) + . = ..() + var/mob/living/carbon/current_mob = mob_override || owner.current + register_body_signals(current_mob) + talking_head(current_mob) + handle_clown_mutation(current_mob, mob_override ? null : "As a vampiric clown, you are no longer a danger to yourself. Your clownish nature has been subdued by your thirst for blood.") + add_team_hud(current_mob) + + if(current_mob.hud_used) + on_hud_created() + else + RegisterSignal(current_mob, COMSIG_MOB_HUD_CREATED, PROC_REF(on_hud_created)) + if(ishuman(current_mob)) + current_mob?.dna?.species.on_bloodsucker_gain(current_mob) +#ifdef BLOODSUCKER_TESTING + var/turf/user_loc = get_turf(current_mob) + new /obj/structure/closet/crate/coffin(user_loc) + new /obj/structure/bloodsucker/ghoulrack(user_loc) +#endif + +/** + * Remove innate effects is everything given to the mob + * When a body is transferred, this is called on the old mob. + * while on_removal is called ONCE per ANTAG, this is called ONCE per BODY. + */ +/datum/antagonist/bloodsucker/remove_innate_effects(mob/living/mob_override) + . = ..() + var/mob/living/carbon/current_mob = mob_override || owner.current + unregister_body_signals(current_mob) + handle_clown_mutation(current_mob, removing = FALSE) + if(current_mob.hud_used) + var/datum/hud/hud_used = current_mob.hud_used + hud_used.infodisplay -= blood_display + hud_used.infodisplay -= vamprank_display + QDEL_NULL(blood_display) + QDEL_NULL(vamprank_display) + + if(iscarbon(current_mob)) + current_mob?.dna.species.on_bloodsucker_loss(current_mob) + +/datum/antagonist/bloodsucker/proc/on_hud_created(datum/source) + SIGNAL_HANDLER + var/datum/hud/bloodsucker_hud = owner.current.hud_used + + blood_display = new(null, bloodsucker_hud) + bloodsucker_hud.infodisplay += blood_display + + vamprank_display = new(null, bloodsucker_hud) + bloodsucker_hud.infodisplay += vamprank_display + + bloodsucker_hud.show_hud(bloodsucker_hud.hud_version) + UnregisterSignal(owner.current, COMSIG_MOB_HUD_CREATED) + update_blood_hud() + update_rank_hud() + +/// Override some properties of incompatible species +/datum/antagonist/bloodsucker/proc/on_species_gain(mob/living/carbon/human/target, datum/species/current_species, datum/species/old_species) + SIGNAL_HANDLER + if(!ishuman(owner.current)) + return + var/mob/living/carbon/human/user = owner.current + user?.dna?.species.on_bloodsucker_gain(target) + +/datum/antagonist/bloodsucker/get_admin_commands() + . = ..() + .["Set blood level"] = CALLBACK(src, PROC_REF(admin_set_blood)) + .["Give Level"] = CALLBACK(src, PROC_REF(admin_rankup)) + // I know admins can technically do it via VV's dropdown, but it's super inconvenient. + .["Give Power"] = CALLBACK(src, PROC_REF(admin_give_power)) + .["Remove Power"] = CALLBACK(src, PROC_REF(admin_remove_power)) + .["Set Power Level"] = CALLBACK(src, PROC_REF(admin_set_power_level)) + if(bloodsucker_level_unspent >= 1) + .["Remove Level"] = CALLBACK(src, PROC_REF(RankDown)) + + if(broke_masquerade) + .["Fix Masquerade"] = CALLBACK(src, PROC_REF(fix_masquerade)) + else + .["Break Masquerade"] = CALLBACK(src, PROC_REF(break_masquerade)) + + if(my_clan) + .["Remove Clan"] = CALLBACK(src, PROC_REF(remove_clan)) + else + .["Add Clan"] = CALLBACK(src, PROC_REF(admin_set_clan)) + +///Called when you get the antag datum, called only ONCE per antagonist. +/datum/antagonist/bloodsucker/on_gain() + if(!owner?.current) + return ..() + if(ventrue_sired) // sired bloodsuckers shouldnt be getting the same benefits as roundstart Bloodsuckers. + bloodsucker_level_unspent = 1 + else + // Start Sunlight if first Bloodsucker + // Name and Titles + SelectFirstName() + SelectTitle(am_fledgling = TRUE) + SelectReputation(am_fledgling = TRUE) + // Objectives + forge_bloodsucker_objectives() + + . = ..() + // Assign Powers + give_starting_powers() + assign_starting_stats() + +/// Called by the remove_antag_datum() and remove_all_antag_datums() mind procs for the antag datum to handle its own removal and deletion. +/datum/antagonist/bloodsucker/on_removal() + free_all_ghouls() + if(!owner?.current) + return + if(is_head(owner.current)) + cleanup_talking_head() + if(ishuman(owner.current)) + var/mob/living/carbon/human/user = owner.current + user?.dna?.species.regenerate_organs(user, null, TRUE) + clear_powers_and_stats() + ventrue_sired = null + coffin?.unclaim_coffin(FALSE, TRUE) + return ..() + +/datum/antagonist/bloodsucker/on_body_transfer(mob/living/old_body, mob/living/new_body) + . = ..() + if(!old_body || !new_body) + CRASH("Bloodsucker on_body_transfer called with null bodies!") + for(var/datum/action/cooldown/bloodsucker/all_powers as anything in powers) + if(old_body) + all_powers.Remove(old_body) + all_powers.Grant(new_body) + var/obj/item/bodypart/old_left_arm = old_body?.get_bodypart(BODY_ZONE_L_ARM) + var/obj/item/bodypart/old_right_arm = old_body?.get_bodypart(BODY_ZONE_R_ARM) + var/old_left_arm_unarmed_damage_low + var/old_left_arm_unarmed_damage_high + var/old_right_arm_unarmed_damage_low + var/old_right_arm_unarmed_damage_high + if(old_body && ishuman(old_body)) + var/mob/living/carbon/human/old_user = old_body + old_user.mob_biotypes &= ~biotype + //Keep track of what they were + old_left_arm_unarmed_damage_low = old_left_arm?.unarmed_damage_low + old_left_arm_unarmed_damage_high = old_left_arm?.unarmed_damage_high + old_right_arm_unarmed_damage_low = old_right_arm?.unarmed_damage_low + old_right_arm_unarmed_damage_high = old_right_arm?.unarmed_damage_high + //Then reset them + if(old_left_arm) + old_left_arm.unarmed_damage_low = initial(old_left_arm.unarmed_damage_low) + old_left_arm.unarmed_damage_high = initial(old_left_arm.unarmed_damage_high) + if(old_right_arm) + old_right_arm.unarmed_damage_low = initial(old_right_arm.unarmed_damage_low) + old_right_arm.unarmed_damage_high = initial(old_right_arm.unarmed_damage_high) + if(ishuman(new_body)) + var/mob/living/carbon/human/new_user = new_body + new_user.mob_biotypes |= biotype + var/obj/item/bodypart/new_left_arm + var/obj/item/bodypart/new_right_arm + //Give old punch damage values + new_left_arm = new_body?.get_bodypart(BODY_ZONE_L_ARM) + new_right_arm = new_body?.get_bodypart(BODY_ZONE_R_ARM) + if(old_left_arm) + new_left_arm.unarmed_damage_low = old_left_arm_unarmed_damage_low + new_left_arm.unarmed_damage_high = old_left_arm_unarmed_damage_high + if(old_right_arm) + new_right_arm.unarmed_damage_low = old_right_arm_unarmed_damage_low + new_right_arm.unarmed_damage_high = old_right_arm_unarmed_damage_high + + //Give Bloodsucker Traits + if(old_body) + old_body.remove_traits(bloodsucker_traits, BLOODSUCKER_TRAIT) + new_body.add_traits(bloodsucker_traits, BLOODSUCKER_TRAIT) + +/datum/antagonist/bloodsucker/greet() + . = ..() + var/fullname = return_full_name() + to_chat(owner, span_userdanger("You are [fullname], a strain of vampire known as a Bloodsucker!")) + owner.announce_objectives() + if(bloodsucker_level_unspent >= 2) + to_chat(owner, span_announce("As a latejoiner, you have [bloodsucker_level_unspent] bonus Ranks, entering your claimed coffin allows you to spend a Rank.")) + owner.current.playsound_local(null, 'tff_modular/modules/bloodsucker/sound/BloodsuckerAlert.ogg', 100, FALSE, pressure_affected = FALSE) + antag_memory += "Although you were born a mortal, in undeath you earned the name [fullname].
" + +/datum/antagonist/bloodsucker/farewell() + to_chat(owner.current, span_userdanger("With a snap, your curse has ended. You are no longer a Bloodsucker. You live once more!")) + // Refill with Blood so they don't instantly die. + if(!HAS_TRAIT(owner.current, TRAIT_NOBLOOD)) + owner.current.blood_volume = max(owner.current.blood_volume, BLOOD_VOLUME_NORMAL) + +// Called when using admin tools to give antag status +/datum/antagonist/bloodsucker/admin_add(datum/mind/new_owner, mob/admin) + var/levels = tgui_input_number(admin, "How many unspent Ranks would you like [new_owner] to have?","Bloodsucker Rank", GetUnspentRank(), 100, 0) + var/msg = " made [key_name_admin(new_owner)] into \a [name]" + if(levels > 1) + bloodsucker_level_unspent = levels + msg += " with [levels] extra unspent Ranks." + message_admins("[key_name_admin(usr)][msg]") + log_admin("[key_name(usr)][msg]") + new_owner.add_antag_datum(src) + +/datum/antagonist/bloodsucker/get_preview_icon() + + var/icon/outfit_icon = render_preview_outfit(preview_outfit) + var/icon/blood_icon = icon('icons/effects/blood.dmi', "uniformblood") + blood_icon.Blend(BLOOD_COLOR_RED, ICON_MULTIPLY) + outfit_icon.Blend(blood_icon, ICON_OVERLAY) + + return finish_preview_icon(outfit_icon) + +/datum/antagonist/bloodsucker/ui_static_data(mob/user) + var/list/data = ability_ui_data(powers) + //we don't need to update this that much. + data["in_clan"] = !!my_clan + var/list/clan_data = list() + if(my_clan) + clan_data["clan_name"] = my_clan.name + clan_data["clan_description"] = my_clan.description + clan_data["clan_icon"] = my_clan.join_icon_state + + data["clan"] += list(clan_data) + + return data + ..() + +/datum/antagonist/bloodsucker/ui_assets(mob/user) + return list( + get_asset_datum(/datum/asset/simple/bloodsucker_icons), + ) + +/datum/antagonist/bloodsucker/ui_act(action, params, datum/tgui/ui) + . = ..() + if(.) + return + + switch(action) + if("join_clan") + if(my_clan) + return + assign_clan_and_bane() + if(ui.closing) + return + ui.send_full_update(force = TRUE) + +/datum/antagonist/bloodsucker/roundend_report() + var/list/report = list() + + // Vamp name + report += "
\[[return_full_name()]\]" + report += printplayer(owner) + if(my_clan) + report += "They were part of the [my_clan.name]!" + + // Default Report + var/objectives_complete = TRUE + if(objectives.len) + report += printobjectives(objectives) + for(var/datum/objective/objective in objectives) + if(objective.objective_name == "Optional Objective") + continue + if(!objective.check_completion()) + objectives_complete = FALSE + break + + // Now list their ghouls + if(ghouls.len) + report += "Their Ghouls were..." + for(var/datum/antagonist/ghoul/all_ghouls as anything in ghouls) + if(!all_ghouls.owner) + continue + var/list/ghoul_report = list() + ghoul_report += "[all_ghouls.owner.name]" + + if(all_ghouls.owner.assigned_role) + ghoul_report += " the [all_ghouls.owner.assigned_role.title]" + if(IS_FAVORITE_GHOUL(all_ghouls.owner.current)) + ghoul_report += " and was the Favorite Ghoul" + else if(IS_REVENGE_GHOUL(all_ghouls.owner.current)) + ghoul_report += " and was the Revenge Ghoul" + report += ghoul_report.Join() + + if(objectives.len == 0 || objectives_complete) + report += "The [name] was successful!" + else + report += "The [name] has failed!" + + return report.Join("
") + +/datum/antagonist/bloodsucker/proc/give_starting_powers() + for(var/datum/action/cooldown/bloodsucker/all_powers as anything in all_bloodsucker_powers) + if(!(initial(all_powers.purchase_flags) & BLOODSUCKER_DEFAULT_POWER)) + continue + BuyPower(all_powers) + +/datum/antagonist/bloodsucker/proc/assign_starting_stats() + //Traits: Species + if(ishuman(owner.current)) + var/mob/living/carbon/human/user = owner.current + var/obj/item/bodypart/user_left_arm = user.get_bodypart(BODY_ZONE_L_ARM) + var/obj/item/bodypart/user_right_arm = user.get_bodypart(BODY_ZONE_R_ARM) + user.dna?.remove_all_mutations() + user_left_arm.unarmed_damage_low += 1 //lowest possible punch damage - 6 now + user_left_arm.unarmed_damage_high += 1 //highest possible punch damage - 11 + user_right_arm.unarmed_damage_low += 1 //lowest possible punch damage - 6 + user_right_arm.unarmed_damage_high += 1 //highest possible punch damage - 11 + user.mob_biotypes |= biotype + //Give Bloodsucker Traits + owner.current.add_traits(bloodsucker_traits, BLOODSUCKER_TRAIT) + //Clear Addictions + for(var/addiction_type in subtypesof(/datum/addiction)) + owner.current.mind.remove_addiction_points(addiction_type, MAX_ADDICTION_POINTS) + //No Skittish "People" allowed + if(HAS_TRAIT(owner.current, TRAIT_SKITTISH)) + REMOVE_TRAIT(owner.current, TRAIT_SKITTISH, ROUNDSTART_TRAIT) + // Tongue & Language + owner.current.grant_language(/datum/language/vampiric, ALL, LANGUAGE_MIND) + /// Clear Disabilities & Organs + heal_vampire_organs() + +/** + * ##clear_power_and_stats() + * + * Removes all Bloodsucker related Powers/Stats changes, setting them back to pre-Bloodsucker + * Order of steps and reason why: + * Remove clan - Clans like Nosferatu give Powers on removal, we have to make sure this is given before removing Powers. + * Powers - Remove all Powers, so things like Masquerade are off. + * Species traits, Traits, Language - Misc stuff, has no priority. + * Organs - At the bottom to ensure everything that changes them has reverted themselves already. + * Update Sight - Done after Eyes are regenerated. + */ +/datum/antagonist/bloodsucker/proc/clear_powers_and_stats() + // Remove clan first + // if(my_clan) + // QDEL_NULL(my_clan) + // Powers + for(var/datum/action/cooldown/bloodsucker/all_powers as anything in powers) + RemovePower(all_powers) + if(QDELETED(owner.current)) + return + /// Stats + if(ishuman(owner.current)) + var/mob/living/carbon/human/user = owner.current + user.mob_biotypes &= ~biotype + var/obj/item/bodypart/left_arm = user.get_bodypart(BODY_ZONE_L_ARM) + var/obj/item/bodypart/right_arm = user.get_bodypart(BODY_ZONE_R_ARM) + if(left_arm) + left_arm.unarmed_damage_low = initial(left_arm.unarmed_damage_low) + left_arm.unarmed_damage_high = initial(left_arm.unarmed_damage_high) + if(right_arm) + right_arm.unarmed_damage_low = initial(right_arm.unarmed_damage_low) + right_arm.unarmed_damage_high = initial(right_arm.unarmed_damage_high) + var/obj/item/bodypart/chest/target_chest = owner.current.get_bodypart(BODY_ZONE_CHEST) + if(target_chest && target_chest.bodypart_flags & BODYPART_UNREMOVABLE) + target_chest.bodypart_flags &= ~BODYPART_UNREMOVABLE + // Remove all bloodsucker traits + owner.current.remove_traits(bloodsucker_traits, BLOODSUCKER_TRAIT) + // Language + owner.current.remove_language(/datum/language/vampiric, ALL, LANGUAGE_MIND) + // Heart & Eyes + var/mob/living/carbon/user = owner.current + var/obj/item/organ/heart/newheart = owner.current.get_organ_slot(ORGAN_SLOT_HEART) + if(newheart) + newheart.Restart() + var/obj/item/organ/eyes/user_eyes = user.get_organ_slot(ORGAN_SLOT_EYES) + if(user_eyes) + user_eyes.flash_protect = initial(user_eyes.flash_protect) + user_eyes.color_cutoffs = initial(user_eyes.color_cutoffs) + user_eyes.sight_flags = initial(user_eyes.sight_flags) + user.update_sight() + +/// Name shown on antag list +/datum/antagonist/bloodsucker/antag_listing_name() + return ..() + "([return_full_name()])" + +/// Whatever interesting things happened to the antag admins should know about +/// Include additional information about antag in this part +/datum/antagonist/bloodsucker/antag_listing_status() + if(owner && !considered_alive(owner)) + return "Final Death" + return ..() + +/datum/antagonist/bloodsucker/proc/considered_alive(datum/mind/player_mind, enforce_human) + if(!player_mind?.current) // no owner.current means there is no body, thus we final-death'd + return FALSE + if(is_head(player_mind.current)) + return FALSE + if(am_staked()) + return FALSE + return TRUE + +/datum/antagonist/bloodsucker/proc/forge_bloodsucker_objectives() + // Claim a haven Objective + var/datum/objective/bloodsucker/haven/haven_objective = new + haven_objective.owner = owner + objectives += haven_objective + // Survive Objective + var/datum/objective/survive/bloodsucker/survive_objective = new + survive_objective.owner = owner + objectives += survive_objective + + // Objective 1: Ghoulize a Head/Command, or a specific target + switch(rand(1, 3)) + if(1) // Conversion Objective + var/datum/objective/bloodsucker/conversion/chosen_subtype = pick(subtypesof(/datum/objective/bloodsucker/conversion)) + var/datum/objective/bloodsucker/conversion/conversion_objective = new chosen_subtype + conversion_objective.owner = owner + conversion_objective.objective_name = "Optional Objective" + objectives += conversion_objective + if(2) // Heart Thief Objective + var/datum/objective/steal_n_of_type/hearts/heartthief_objective = new + heartthief_objective.owner = owner + heartthief_objective.objective_name = "Optional Objective" + objectives += heartthief_objective + if(3) // Drink Blood Objective + var/datum/objective/bloodsucker/gourmand/gourmand_objective = new + gourmand_objective.owner = owner + gourmand_objective.objective_name = "Optional Objective" + objectives += gourmand_objective + +/datum/mood_event/drankblood + description = "I have fed greedily from that which nourishes me.\n" + mood_change = 10 + timeout = 8 MINUTES + +/datum/mood_event/drankblood_bad + description = "I drank the blood of a lesser creature. Disgusting.\n" + mood_change = -4 + timeout = 3 MINUTES + +/datum/mood_event/drankblood_dead + description = "I drank dead blood. I am better than this.\n" + mood_change = -7 + timeout = 8 MINUTES + +/datum/mood_event/drankblood_synth + description = "I drank synthetic blood. What is wrong with me?\n" + mood_change = -7 + timeout = 8 MINUTES + +/datum/mood_event/drankkilled + description = "I fed off of a dead person. I feel... less human.\n" + mood_change = -15 + timeout = 10 MINUTES + +/datum/mood_event/madevamp + description = "A mortal has reached an apotheosis- undeath- by my own hand.\n" + mood_change = 15 + timeout = 20 MINUTES + +/datum/mood_event/coffinsleep + description = "I slept in a coffin during the day. I feel whole again.\n" + mood_change = 10 + timeout = 6 MINUTES + +/datum/mood_event/coffinsleep/quirk + mood_change = 4 + +/datum/mood_event/daylight_bad_sleep + description = "I slept poorly in a makeshift coffin during the day.\n" + mood_change = -3 + timeout = 6 MINUTES + +/datum/mood_event/daylight_sun_scorched + description = "I have been scorched by the unforgiving rays of the sun.\n" + mood_change = -6 + timeout = 6 MINUTES + +///Candelabrum's mood event to non Bloodsucker/Ghouls +/datum/mood_event/vampcandle + description = "Something is making your mind feel... loose.\n" + mood_change = -15 + timeout = 5 MINUTES + +/datum/mood_event/nosferatu_examined + mood_change = -10 + timeout = 5 MINUTES + +/datum/mood_event/nosferatu_examined/add_effects(target, level = 0) + description = span_danger("You feel a deep sense of revulsion at the sight of [target].") + mood_change = level * -5 diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/clans.dm b/tff_modular/modules/bloodsucker/bloodsuckers/clans.dm new file mode 100644 index 00000000000..c0ec95caf4e --- /dev/null +++ b/tff_modular/modules/bloodsucker/bloodsuckers/clans.dm @@ -0,0 +1,48 @@ +/** + * Gives Bloodsuckers the ability to choose a Clan. + * If they are already in a Clan, or is in a Frenzy, they will not be able to do so. + * The arg is optional and should really only be an Admin setting a Clan for a player. + * If set however, it will give them the control of their Clan instead of the Bloodsucker. + * This is selected through a radial menu over the player's body, even when an Admin is setting it. + * Args: + * person_selecting - Mob override for stuff like Admins selecting someone's clan. + */ +/datum/antagonist/bloodsucker/proc/assign_clan_and_bane(mob/person_selecting) + if(my_clan) + return + if(owner.current.has_status_effect(/datum/status_effect/frenzy)) + return + if(!person_selecting) + person_selecting = owner.current + + var/list/options = list() + var/list/radial_display = list() + for(var/datum/bloodsucker_clan/all_clans as anything in typesof(/datum/bloodsucker_clan)) + if(!initial(all_clans.joinable_clan)) //flavortext only + continue + options[initial(all_clans.name)] = all_clans + + var/datum/radial_menu_choice/option = new + option.image = image(icon = initial(all_clans.join_icon), icon_state = initial(all_clans.join_icon_state)) + option.info = "[initial(all_clans.name)] - [span_boldnotice(initial(all_clans.join_description))]" + radial_display[initial(all_clans.name)] = option + var/anchor = get_turf(owner.current) == owner.current.loc ? owner.current : get_turf(owner.current) + var/require_near = person_selecting == owner.current ? TRUE : FALSE + var/chosen_clan = show_radial_menu(person_selecting, anchor, radial_display, require_near = require_near) + chosen_clan = options[chosen_clan] + if(QDELETED(src) || QDELETED(owner.current)) + return FALSE + if(!chosen_clan) + to_chat(person_selecting, span_announce("You choose to remain ignorant, for now.")) + return + my_clan = new chosen_clan(src) + +/datum/antagonist/bloodsucker/proc/remove_clan(mob/admin) + if(owner.current.has_status_effect(/datum/status_effect/frenzy)) + to_chat(admin, span_announce("Removing a Bloodsucker from a Clan while they are in a Frenzy will break stuff, this action has been blocked.")) + return + QDEL_NULL(my_clan) + to_chat(owner.current, span_announce("You have been forced out of your clan! You can re-enter one by regular means.")) + +/datum/antagonist/bloodsucker/proc/admin_set_clan(mob/admin) + assign_clan_and_bane(admin) diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/conversion.dm b/tff_modular/modules/bloodsucker/bloodsuckers/conversion.dm new file mode 100644 index 00000000000..ea896e695c4 --- /dev/null +++ b/tff_modular/modules/bloodsucker/bloodsuckers/conversion.dm @@ -0,0 +1,97 @@ +/** + * Checks if the target has antag datums and, if so, + * are they allowed to be Ghouled, or not, or banned. + * Args: + * target - The person we check for antag datums. + */ +/datum/antagonist/bloodsucker/proc/AmValidAntag(mob/target) + if(HAS_TRAIT(target, TRAIT_UNCONVERTABLE)) + return GHOULING_BANNED + + var/ghouling_status = GHOULING_ALLOWED + for(var/datum/antagonist/antag_datum as anything in target.mind.antag_datums) + if(antag_datum.type in ghoul_banned_antags) + return GHOULING_BANNED + ghouling_status = GHOULING_DISLOYAL + return ghouling_status + +/** + * # can_make_ghoul + * Checks if the person is allowed to turn into the Bloodsucker's + * Ghoul, ensuring they are a player and valid. + * If they are a Ghoul themselves, will check if their master + * has broken the Masquerade, to steal them. + * Args: + * conversion_target - Person being ghouled + */ +/datum/antagonist/bloodsucker/proc/can_make_ghoul(mob/living/conversion_target) + if(!iscarbon(conversion_target) || (conversion_target.stat < CONSCIOUS)) + return FALSE + // No Mind! + if(!conversion_target.mind) + to_chat(owner.current, span_danger("[conversion_target] isn't self-aware enough to be made into a Ghoul.")) + return FALSE + if(AmValidAntag(conversion_target) == GHOULING_BANNED) + to_chat(owner.current, span_danger("[conversion_target] resists the power of your blood to dominate their mind!")) + return FALSE + var/mob/living/master = conversion_target.mind.enslaved_to?.resolve() + if(!master || (master == owner.current)) + return TRUE + var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(master) + if(bloodsuckerdatum && bloodsuckerdatum.broke_masquerade) + //ghoul stealing + return TRUE + to_chat(owner.current, span_danger("[conversion_target]'s mind is overwhelmed with too much external force to put your own!")) + return FALSE + +/** + * First will check if the target can be turned into a Ghoul, if so then it will + * turn them into one, log it, sync their minds, then updates the Rank + * Args: + * conversion_target - The person converted. + */ +/datum/antagonist/bloodsucker/proc/make_ghoul(mob/living/conversion_target) +#ifndef BLOODSUCKER_TESTING + if(!can_make_ghoul(conversion_target)) + return FALSE +#endif + //Check if they used to be a Ghoul and was stolen. + var/datum/antagonist/ghoul/old_ghoul = IS_GHOUL(conversion_target) + if(old_ghoul) + conversion_target.mind.remove_antag_datum(/datum/antagonist/ghoul) + + var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(owner.current) + bloodsuckerdatum.SelectTitle(am_fledgling = FALSE) + + //set the master, then give the datum. + var/datum/antagonist/ghoul/ghouldatum = new(conversion_target.mind) + ghouldatum.master = bloodsuckerdatum + conversion_target.mind.add_antag_datum(ghouldatum) + + message_admins("[conversion_target] has become a Ghoul, and is enslaved to [owner.current].") + log_admin("[conversion_target] has become a Ghoul, and is enslaved to [owner.current].") + return TRUE + +/* + * # can_make_special + * + * MIND Helper proc that ensures the person can be a Special Ghoul, + * without actually giving the antag datum to them. + * This is because Special Ghouls get special abilities, without the unique Bloodsucker blood tracking, + * and we don't want this to be infinite. + * Args: + * creator - Person attempting to convert them. + */ +/datum/mind/proc/can_make_special(datum/mind/creator) + return TRUE + +/// Check if this is a valid person to actually be a bloodsucker +/datum/mind/proc/valid_bloodsucker_candidate() + if(has_antag_datum(/datum/antagonist/bloodsucker)) + return FALSE + if(!(current.mob_biotypes & MOB_ORGANIC)) + return FALSE + // While the antag can function without the mob itself having no blood, it doesn't make sense. + if(HAS_TRAIT(src, TRAIT_NOBLOOD)) + return FALSE + return TRUE diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/crafts.dm b/tff_modular/modules/bloodsucker/bloodsuckers/crafts.dm new file mode 100644 index 00000000000..d69c19d79b2 --- /dev/null +++ b/tff_modular/modules/bloodsucker/bloodsuckers/crafts.dm @@ -0,0 +1,87 @@ +/datum/crafting_recipe/blackcoffin + name = "Black Coffin" + result = /obj/structure/closet/crate/coffin/blackcoffin + tool_behaviors = list(TOOL_WELDER, TOOL_SCREWDRIVER) + reqs = list( + /obj/item/stack/sheet/cloth = 1, + /obj/item/stack/sheet/mineral/wood = 5, + /obj/item/stack/sheet/iron = 1, + ) + time = 15 SECONDS + category = CAT_FURNITURE + +//VAMPIRE STUFF + +/datum/crafting_recipe/securecoffin + name = "Secure Coffin" + result = /obj/structure/closet/crate/coffin/securecoffin + tool_behaviors = list(TOOL_WELDER, TOOL_SCREWDRIVER) + reqs = list( + /obj/item/stack/rods = 1, + /obj/item/stack/sheet/plasteel = 5, + /obj/item/stack/sheet/iron = 5, + ) + time = 15 SECONDS + category = CAT_FURNITURE + +/datum/crafting_recipe/meatcoffin + name = "Meat Coffin" + result = /obj/structure/closet/crate/coffin/meatcoffin + tool_behaviors = list(TOOL_KNIFE, TOOL_ROLLINGPIN) + reqs = list( + /obj/item/food/meat/slab = 5, + /obj/item/restraints/handcuffs/cable = 1, + ) + time = 15 SECONDS + category = CAT_FURNITURE + crafting_flags = parent_type::crafting_flags | CRAFT_MUST_BE_LEARNED + +/datum/crafting_recipe/metalcoffin + name = "Metal Coffin" + result = /obj/structure/closet/crate/coffin/metalcoffin + reqs = list( + /obj/item/stack/sheet/iron = 6, + /obj/item/stack/rods = 2, + ) + time = 10 SECONDS + category = CAT_FURNITURE + +/datum/crafting_recipe/ghoulrack + name = "Persuasion Rack" + result = /obj/structure/bloodsucker/ghoulrack + tool_behaviors = list(TOOL_WELDER, TOOL_WRENCH) + reqs = list( + /obj/item/stack/sheet/mineral/wood = 3, + /obj/item/stack/sheet/iron = 2, + /obj/item/restraints/handcuffs/cable = 2, + ) + time = 15 SECONDS + category = CAT_FURNITURE + crafting_flags = parent_type::crafting_flags | CRAFT_MUST_BE_LEARNED + +/datum/crafting_recipe/candelabrum + name = "Candelabrum" + result = /obj/structure/bloodsucker/candelabrum + tool_behaviors = list(TOOL_WELDER, TOOL_WRENCH) + reqs = list( + /obj/item/stack/sheet/iron = 3, + /obj/item/stack/rods = 1, + /obj/item/flashlight/flare/candle = 1, + ) + time = 10 SECONDS + category = CAT_FURNITURE + crafting_flags = parent_type::crafting_flags | CRAFT_MUST_BE_LEARNED + +/datum/crafting_recipe/bloodthrone + name = "Blood Throne" + result = /obj/structure/bloodsucker/bloodthrone + tool_behaviors = list(TOOL_WRENCH) + reqs = list( + /obj/item/stack/sheet/cloth = 3, + /obj/item/stack/sheet/iron = 5, + /obj/item/stack/sheet/mineral/wood = 1, + ) + time = 5 SECONDS + category = CAT_FURNITURE + crafting_flags = parent_type::crafting_flags | CRAFT_MUST_BE_LEARNED + diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/hud.dm b/tff_modular/modules/bloodsucker/bloodsuckers/hud.dm new file mode 100644 index 00000000000..f3c3038089e --- /dev/null +++ b/tff_modular/modules/bloodsucker/bloodsuckers/hud.dm @@ -0,0 +1,101 @@ +/// 1 tile down +#define UI_BLOOD_DISPLAY "WEST:6,CENTER-1:0" +/// 2 tiles down +#define UI_VAMPRANK_DISPLAY "WEST:6,CENTER-2:-5" +/// 6 pixels to the right, zero tiles & 5 pixels DOWN. +#define UI_SUNLIGHT_DISPLAY "WEST:6,CENTER-0:0" + +///Maptext define for Bloodsucker HUDs +#define FORMAT_BLOODSUCKER_HUD_TEXT(valuecolor, value) MAPTEXT("
[round(value,1)]
") +///Maptext define for Bloodsucker Sunlight HUDs +#define FORMAT_BLOODSUCKER_SUNLIGHT_TEXT(valuecolor, value) MAPTEXT("
[value]
") + +/atom/movable/screen/bloodsucker + icon = 'tff_modular/modules/bloodsucker/icons/bloodsucker.dmi' + +/atom/movable/screen/bloodsucker/blood_counter + name = "Blood Consumed" + icon_state = "blood_display" + screen_loc = UI_BLOOD_DISPLAY + +/atom/movable/screen/bloodsucker/blood_counter/proc/update_blood_hud(blood_volume) + maptext = FORMAT_BLOODSUCKER_HUD_TEXT(hud_text_color(), blood_volume) + +/atom/movable/screen/bloodsucker/rank_counter + name = "Bloodsucker Rank" + icon_state = "rank" + screen_loc = UI_VAMPRANK_DISPLAY + +/atom/movable/screen/bloodsucker/rank_counter/proc/update_rank_hud(level = 0, unspent_level = 0, blood_volume = 0) + if(unspent_level > 0) + icon_state = "[initial(icon_state)]_up" + else + icon_state = initial(icon_state) + maptext = FORMAT_BLOODSUCKER_HUD_TEXT(hud_text_color(), level) + +/* +/atom/movable/screen/bloodsucker/sunlight_counter + name = "Solar Flare Timer" + icon_state = "sunlight" + screen_loc = UI_SUNLIGHT_DISPLAY + +/atom/movable/screen/bloodsucker/sunlight_counter/Initialize(mapload, datum/hud/hud_owner) + . = ..() + update_sol_hud() + START_PROCESSING(SSsunlight, src) + +/atom/movable/screen/bloodsucker/sunlight_counter/Destroy() + STOP_PROCESSING(SSsunlight, src) + . = ..() + +/atom/movable/screen/bloodsucker/sunlight_counter/proc/update_sol_hud() + var/valuecolor = hud_text_color() + if(!SSsunlight) + return + if(SSsunlight.sunlight_active) + valuecolor = "#FF5555" + icon_state = "[initial(icon_state)]_day" + else + switch(round(SSsunlight.time_til_cycle, 1)) + if(0 to 30) + icon_state = "[initial(icon_state)]_30" + valuecolor = "#FFCCCC" + if(31 to 60) + icon_state = "[initial(icon_state)]_60" + valuecolor = "#FFE6CC" + if(61 to 90) + icon_state = "[initial(icon_state)]_90" + valuecolor = "#FFFFCC" + else + icon_state = "[initial(icon_state)]_night" + valuecolor = "#FFFFFF" + maptext = FORMAT_BLOODSUCKER_SUNLIGHT_TEXT( \ + valuecolor, \ + (SSsunlight.time_til_cycle >= 60) ? "[round(SSsunlight.time_til_cycle / 60, 1)] m" : "[round(SSsunlight.time_til_cycle, 1)] s" \ + ) + +/atom/movable/screen/bloodsucker/sunlight_counter/process(seconds_per_tick) + update_sol_hud() +*/ + +/atom/movable/screen/bloodsucker/proc/hud_text_color(blood_volume) + return blood_volume > BLOOD_VOLUME_SAFE ? "#FFDDDD" : "#FFAAAA" + +/// Updated every time blood is changed by either +/datum/antagonist/bloodsucker/proc/update_blood_hud() + blood_display?.update_blood_hud(bloodsucker_blood_volume) + +/datum/antagonist/bloodsucker/proc/update_rank_hud() + vamprank_display?.update_rank_hud(bloodsucker_level, bloodsucker_level_unspent, bloodsucker_blood_volume) + +/// 1 tile down +#undef UI_BLOOD_DISPLAY +/// 2 tiles down +#undef UI_VAMPRANK_DISPLAY +/// 6 pixels to the right, zero tiles & 5 pixels DOWN. +#undef UI_SUNLIGHT_DISPLAY + +///Maptext define for Bloodsucker HUDs +#undef FORMAT_BLOODSUCKER_HUD_TEXT +///Maptext define for Bloodsucker Sunlight HUDs +#undef FORMAT_BLOODSUCKER_SUNLIGHT_TEXT diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/integration.dm b/tff_modular/modules/bloodsucker/bloodsuckers/integration.dm new file mode 100644 index 00000000000..eca36eb435f --- /dev/null +++ b/tff_modular/modules/bloodsucker/bloodsuckers/integration.dm @@ -0,0 +1,118 @@ + +// this suggests that your heart is beating, when it is not +/mob/living/carbon/bleed_warn(bleed_amt = 0, forced = FALSE) + if(mind && IS_BLOODSUCKER(src) && !HAS_TRAIT(src, TRAIT_MASQUERADE)) + return + . = ..() + +/datum/reagent/blood/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message=TRUE, touch_protection=0) + var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(exposed_mob) + if(!bloodsuckerdatum) + return ..() + if(!(methods & (INJECT|INGEST))) + return ..() + + if(bloodsuckerdatum.my_clan && istype(bloodsuckerdatum.my_clan, /datum/bloodsucker_clan/ventrue) && bloodsuckerdatum.GetBloodVolume() >= BLOOD_VOLUME_SAFE) + return ..() + if(bloodsuckerdatum.GetBloodVolume() >= BLOOD_VOLUME_NORMAL) + return ..() + bloodsuckerdatum.AdjustBloodVolume(round(reac_volume, 0.1)) + +/mob/living/carbon/transfer_blood_to(atom/movable/receiver, amount, ignore_low_blood = FALSE, ignore_incompatibility = FALSE, transfer_viruses = TRUE) + . = ..() + if(!mind) + return + var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(src) + if(!bloodsuckerdatum) + return + bloodsuckerdatum.AdjustBloodVolume(-amount) + +// Prevents using a Memento Mori +// todo move this to it's own trait +/obj/item/clothing/neck/necklace/memento_mori/memento(mob/living/carbon/human/user) + if(IS_BLOODSUCKER(user)) + to_chat(user, span_warning("The Memento notices your undead soul, and refuses to react..")) + return + return ..() + +/mob/living/carbon/human/natural_bodytemperature_stabilization(datum/gas_mixture/environment, seconds_per_tick, times_fired) + // Return 0 as your natural temperature. Species proc handle_environment() will adjust your temperature based on this. + if(HAS_TRAIT(src, TRAIT_COLDBLOODED)) + return 0 + return ..() + +// Used when analyzing a Bloodsucker, Masquerade will hide brain traumas +/// todo move this to it's own trait or something +/mob/living/carbon/get_traumas() + if(!mind) + return ..() + var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(src) + if(bloodsuckerdatum && HAS_TRAIT(src, TRAIT_MASQUERADE)) + return + return ..() + +// Used to keep track of how much Blood we've drank so far +/mob/living/get_status_tab_items() + . = ..() + if(!mind) + return ..() + var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(src) + if(bloodsuckerdatum) + . += "" + . += "Blood Drank: [bloodsuckerdatum.total_blood_drank]" + . += "Maximum blood: [bloodsuckerdatum.max_blood_volume]" + . += "Blood Thickening: [bloodsuckerdatum.blood_level_gain] / [bloodsuckerdatum.get_level_cost()]" + if(bloodsuckerdatum.frenzied) + . += "Frenzy exit blood threshold: [bloodsuckerdatum.frenzy_exit_threshold()]" + else + . += "Frenzy blood threshold: [bloodsuckerdatum.frenzy_enter_threshold()]" + +/datum/outfit/bloodsucker_outfit + name = "Bloodsucker outfit (Preview only)" + suit = /obj/item/clothing/suit/costume/dracula + +/datum/outfit/bloodsucker_outfit/post_equip(mob/living/carbon/human/enrico, visualsOnly=FALSE) + enrico.hairstyle = "Undercut" + enrico.hair_color = "FFF" + enrico.skin_tone = "african2" + enrico.eye_color_left = "#663300" + enrico.eye_color_right = "#663300" + + enrico.update_body(is_creating = TRUE) + + +/** + * CARBON INTEGRATION +* +* All overrides of mob/living and mob/living/carbon +*/ +/// Brute +/mob/living/proc/get_brute_loss_nonProsthetic() + return get_brute_loss() + +/mob/living/carbon/get_brute_loss_nonProsthetic() + var/amount = 0 + for(var/obj/item/bodypart/chosen_bodypart as anything in bodyparts) + if(!IS_ORGANIC_LIMB(chosen_bodypart)) + continue + amount += chosen_bodypart.brute_dam + return amount + +/// Burn +/mob/living/proc/get_fire_loss_nonProsthetic() + return get_fire_loss() + +/mob/living/carbon/get_fire_loss_nonProsthetic() + var/amount = 0 + for(var/obj/item/bodypart/chosen_bodypart as anything in bodyparts) + if(!IS_ORGANIC_LIMB(chosen_bodypart)) + continue + amount += chosen_bodypart.burn_dam + return amount + +/mob/living/brain/can_be_revived() + if(health <= HEALTH_THRESHOLD_DEAD) + return FALSE + if(IS_BLOODSUCKER(src)) + return TRUE + . =..() diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/life.dm b/tff_modular/modules/bloodsucker/bloodsuckers/life.dm new file mode 100644 index 00000000000..7e14a4ceb1f --- /dev/null +++ b/tff_modular/modules/bloodsucker/bloodsuckers/life.dm @@ -0,0 +1,495 @@ +///How much Blood it costs to live. +#define BLOODSUCKER_PASSIVE_BLOOD_DRAIN 0.1 + +/// Runs from COMSIG_LIVING_LIFE, handles Bloodsucker constant proccesses. +/datum/antagonist/bloodsucker/proc/LifeTick(mob/living/source, seconds_per_tick, times_fired) + SIGNAL_HANDLER + if(QDELETED(owner) || QDELETED(owner.current)) + INVOKE_ASYNC(src, PROC_REF(HandleDeath)) + return + life_always() + var/is_head = is_head(owner.current) + if(!is_head && owner.current.get_organ_slot(ORGAN_SLOT_HEART) && !am_staked()) + INVOKE_ASYNC(src, PROC_REF(life_active), is_head) + + SEND_SIGNAL(src, COMSIG_BLOODSUCKER_ON_LIFETICK, seconds_per_tick, times_fired) + +/datum/antagonist/bloodsucker/proc/life_always(is_head = FALSE) + if(is_in_torpor()) + check_end_torpor() + if(is_head) + return + if(owner.current.stat == CONSCIOUS && !HAS_TRAIT(owner.current, TRAIT_IMMOBILIZED) && !is_in_torpor()) + INVOKE_ASYNC(src, PROC_REF(AdjustBloodVolume), -BLOODSUCKER_PASSIVE_BLOOD_DRAIN) // -.1 currently + +/datum/antagonist/bloodsucker/proc/life_active() + if(HandleHealing()) + if((COOLDOWN_FINISHED(src, bloodsucker_spam_healing)) && bloodsucker_blood_volume > 0) + to_chat(owner.current, span_notice("The power of your blood begins knitting your wounds...")) + COOLDOWN_START(src, bloodsucker_spam_healing, BLOODSUCKER_SPAM_HEALING) + +/datum/antagonist/bloodsucker/proc/on_death(mob/living/source, gibbed) + SIGNAL_HANDLER + RegisterSignal(owner.current, COMSIG_LIVING_REVIVE, PROC_REF(on_revive)) + RegisterSignal(src, COMSIG_BLOODSUCKER_ON_LIFETICK, PROC_REF(HandleDeath)) + +/datum/antagonist/bloodsucker/proc/on_revive(mob/living/source) + SIGNAL_HANDLER + UnregisterSignal(owner.current, COMSIG_LIVING_REVIVE) + UnregisterSignal(src, COMSIG_BLOODSUCKER_ON_LIFETICK) + +/** + * ## BLOOD STUFF + */ + +/datum/antagonist/bloodsucker/proc/GetBloodVolume() + return bloodsucker_blood_volume + +/datum/antagonist/bloodsucker/proc/AdjustBloodVolume(value) + bloodsucker_blood_volume = clamp(bloodsucker_blood_volume + value, 0, max_blood_volume * 2) + blood_over_cap = max(bloodsucker_blood_volume - max_blood_volume, 0) // Gets how much blood we have over the cap. + update_blood_hud() + +/datum/antagonist/bloodsucker/proc/SetBloodVolume(value) + bloodsucker_blood_volume = clamp(value, 0, max_blood_volume) + update_blood_hud() + +#define MASQUERADE /datum/action/cooldown/bloodsucker/masquerade + +/datum/antagonist/bloodsucker/proc/GetHumanityLost() + return humanity_lost + +/datum/antagonist/bloodsucker/proc/AddHumanityLost(value) + if(value == 0) + return + var/has_masq = is_path_in_list(MASQUERADE, powers) + if(value + humanity_lost >= HUMANITY_LOST_MAXIMUM) + if(has_masq) + RemovePowerByPath(MASQUERADE) + to_chat(owner.current, span_warning("You hit the maximum amount of lost Humanty, you are far from Human. You've forgotten how to pretend to be like your prey...")) + else + to_chat(owner.current, span_hypnophrase("The Beast, it yearns for Blood...")) + else if(!has_masq) + BuyPower(MASQUERADE) + to_chat(owner.current, span_hypnophrase("You've remembered, yet again, how it feels to live again.")) + humanity_lost = clamp(value, 0, HUMANITY_LOST_MAXIMUM) + to_chat(owner.current, span_warning("You feel as if you [value < 0 ? "gained" : "lost" ] some of your humanity, you will now enter Frenzy at [FRENZY_THRESHOLD_ENTER + (humanity_lost * 10)] Blood.")) + +#undef MASQUERADE + +/// mult: SILENT feed is 1/3 the amount +/datum/antagonist/bloodsucker/proc/handle_feeding(mob/living/carbon/target, blood_taken, already_drunk = 0) + // Apply to Volume + AdjustBloodVolume(blood_taken) + total_blood_drank += blood_taken + OverfeedHealing(blood_taken) + // Reagents (NOT Blood!) + if(target.mind) // Checks if the target has a mind + // closer it is to max, the less level up blood you get + var/blood_for_leveling = blood_taken + if(already_drunk > BLOOD_VOLUME_NORMAL) + var/max_threshold = BLOOD_VOLUME_NORMAL * 2 + var/modify_blood_gain = 1 - (already_drunk / max_threshold) + blood_for_leveling = max(blood_taken * modify_blood_gain, 0) + blood_level_gain += blood_for_leveling + return blood_taken + +/** + * ## HEALING + */ + +/// Constantly runs on Bloodsucker's LifeTick, and is increased by being in Torpor/Coffins +/datum/antagonist/bloodsucker/proc/HandleHealing(mult = 1) + // Don't heal if I'm staked or on Masquerade. + var/actual_regen = bloodsucker_regen_rate + additional_regen + if(owner.current.am_staked() || (HAS_TRAIT(owner.current, TRAIT_MASQUERADE))) + return FALSE + owner.current.adjust_organ_loss(ORGAN_SLOT_BRAIN, -1 * actual_regen * mult) //adjustBrainLoss(-1 * (actual_regen * 4) * mult, 0) + if(!iscarbon(owner.current)) // Damage Heal: Do I have damage to ANY bodypart? + return FALSE + var/mob/living/carbon/user = owner.current + var/costMult = 1 // Coffin makes it cheaper + // If you're a synth, you heal prosthetic damage. + var/bruteLoss = get_brute_loss() + var/bruteheal = min(bruteLoss, actual_regen) // BRUTE: Always Heal + var/fireheal = 0 // BURN: Heal in Coffin while Fakedeath, or when damage above maxhealth (you can never fully heal fire) + // Checks if you're in a coffin here, additionally checks for Torpor right below it. + var/amInCoffin = is_valid_coffin() + if (blood_over_cap > 0) + costMult += round(blood_over_cap / 1000, 0.1) // effectively 1 (normal) + 0.1 for every 100 blood you are over cap + if(amInCoffin && is_in_torpor()) + if(HAS_TRAIT(owner.current, TRAIT_MASQUERADE) && (COOLDOWN_FINISHED(src, bloodsucker_spam_healing))) + to_chat(user, span_alert("You do not heal while your Masquerade ability is active.")) + COOLDOWN_START(src, bloodsucker_spam_healing, BLOODSUCKER_SPAM_MASQUERADE) + return FALSE + fireheal = min(get_fire_loss(), actual_regen) + mult *= 5 // Increase multiplier if we're sleeping in a coffin. + costMult *= COFFIN_HEAL_COST_MULT // Decrease cost if we're sleeping in a coffin. + user.extinguish_mob() + user.bodytemperature = user.get_body_temp_normal() + if(ishuman(user)) + var/mob/living/carbon/human/humie = user + humie.set_coretemperature(humie.get_body_temp_normal(apply_change = FALSE)) + user.remove_all_embedded_objects() // Remove Embedded! + if(check_limbs(costMult)) + return TRUE + // In Torpor, but not in a Coffin? Heal faster anyways. + else if(is_in_torpor()) + var/fireloss = get_fire_loss() + fireheal = min(fireloss, actual_regen) / 1.2 // 20% slower than being in a coffin + mult *= 3 + // Heal if Damaged + if((bruteheal + fireheal) && mult != 0) // Just a check? Don't heal/spend, and return. + // We have damage. Let's heal (one time), and don't cost any blood if we cannot + if(!user.adjust_brute_loss(-bruteheal * mult, updating_health = FALSE) && !user.adjust_fire_loss(-fireheal * mult, updating_health = FALSE)) // Heal BRUTE / BURN in random portions throughout the body. + return FALSE + user.updatehealth() + AdjustBloodVolume(((bruteheal * -0.5) + (fireheal * -1)) * costMult * mult) // Costs blood to heal + return TRUE + +/datum/antagonist/bloodsucker/proc/OverfeedHealing(drunk) + var/mob/living/carbon/user = owner.current + if(blood_over_cap > 0) //Checks if you are over your blood cap + var/overbruteheal = user.get_brute_loss_nonProsthetic() + var/overfireheal = user.get_fire_loss_nonProsthetic() + var/heal_amount = drunk / 3 + if(overbruteheal > 0 && heal_amount > 0) + user.adjust_brute_loss(-heal_amount, updating_health = FALSE, forced = TRUE) // Heal BRUTE / BURN in random portions throughout the body; prioritising BRUTE. + heal_amount = (heal_amount - overbruteheal) // Removes the amount of BRUTE we've healed from the heal amount + else if(overfireheal > 0 && heal_amount > 0) + heal_amount /= 1.5 // Burn should be more difficult to heal + user.adjust_fire_loss(-heal_amount, updating_health = FALSE, forced = TRUE) + user.updatehealth() + +/datum/antagonist/bloodsucker/proc/check_limbs(costMult = 1) + var/limb_regen_cost = 50 * -costMult + var/mob/living/carbon/user = owner.current + var/list/missing = user.get_missing_limbs() + if(missing.len && (bloodsucker_blood_volume < limb_regen_cost + 5)) + return FALSE + for(var/missing_limb in missing) //Find ONE Limb and regenerate it. + user.regenerate_limb(missing_limb, FALSE) + AdjustBloodVolume(-limb_regen_cost) + var/obj/item/bodypart/missing_bodypart = user.get_bodypart(missing_limb) // 2) Limb returns Damaged + missing_bodypart.brute_dam = missing_bodypart.max_damage + to_chat(user, span_notice("Your flesh knits as it regrows your [missing_bodypart]!")) + playsound(user, 'sound/effects/magic/demon_consume.ogg', 50, TRUE) + return TRUE + +/* + * # Heal Vampire Organs + * + * This is used by Bloodsuckers, these are the steps of this proc: + * Step 1 - Cure husking and Regenerate organs. regenerate_organs() removes their Vampire Heart & Eye augments, which leads us to... + * Step 2 - Repair any (shouldn't be possible) Organ damage, then return their Vampiric Heart & Eye benefits. + * Step 3 - Revive them, clear all wounds, remove any Tumors (If any). + * + * This is called on Bloodsucker's Assign, and when they end Torpor. + */ +// TODO: Separate this into smaller functions +/datum/antagonist/bloodsucker/proc/heal_vampire_organs() + var/mob/living/carbon/bloodsuckeruser = owner.current + // please don't poison or asphyxiate the immune + bloodsuckeruser.set_tox_loss(0, forced = TRUE) + bloodsuckeruser.set_oxy_loss(0, forced = TRUE) + + if(QDELETED(bloodsuckeruser)) + return + + if(HAS_TRAIT_FROM_ONLY(bloodsuckeruser, TRAIT_HUSK, CHANGELING_DRAIN) || bloodsuckeruser.has_status_effect(/datum/status_effect/gutted)) + to_chat(bloodsuckeruser, span_danger("Your immortal blood has healed your body from near-irrecoverable damage, but has used nearly all of your blood in doing so!")) + AddHumanityLost(2) + SetBloodVolume(min(bloodsucker_blood_volume, frenzy_enter_threshold() * 2)) + bloodsuckeruser.cure_husk(CHANGELING_DRAIN) + + bloodsuckeruser.cure_husk(BURN) + + if(bloodsuckeruser.get_organ_slot(ORGAN_SLOT_HEART)) + bloodsuckeruser.regenerate_organs(remove_hazardous = FALSE) + + if(!HAS_TRAIT(bloodsuckeruser, TRAIT_MASQUERADE)) + var/obj/item/organ/heart/current_heart = bloodsuckeruser.get_organ_slot(ORGAN_SLOT_HEART) + current_heart?.Stop() + + var/obj/item/organ/eyes/current_eyes = bloodsuckeruser.get_organ_slot(ORGAN_SLOT_EYES) + if(current_eyes && !(current_eyes.organ_flags & ORGAN_ROBOTIC)) + current_eyes.flash_protect = max(initial(current_eyes.flash_protect) - 1, FLASH_PROTECTION_SENSITIVE) + current_eyes.color_cutoffs = BLOODSUCKER_SIGHT_COLOR_CUTOFF + current_eyes.sight_flags = SEE_MOBS + + bloodsuckeruser.update_sight() + /// Disable gutting for the chest + var/obj/item/bodypart/chest/target_chest = bloodsuckeruser.get_bodypart(BODY_ZONE_CHEST) + if(target_chest && !(target_chest.bodypart_flags & BODYPART_UNREMOVABLE)) + target_chest.bodypart_flags |= BODYPART_UNREMOVABLE + + // Sometimes bloodsuckers can get into a loop of reviving and dying, if they somehow get a new body without being revived. + if(bloodsuckeruser.stat == DEAD) + . = bloodsuckeruser.revive() + + for(var/datum/wound/iter_wound in bloodsuckeruser.all_wounds) + iter_wound.remove_wound() + + // From [powers/panacea.dm] + var/list/bad_organs = list( + bloodsuckeruser.get_organ_by_type(/obj/item/organ/body_egg), + bloodsuckeruser.get_organ_by_type(/obj/item/organ/zombie_infection) + ) + for(var/tumors in bad_organs) + var/obj/item/organ/yucky_organs = tumors + if(!istype(yucky_organs)) + continue + to_chat(bloodsuckeruser, span_warning("You feel a little ill for a moment, but it passes. Did you just cough up a tumor?")) + yucky_organs.Remove(bloodsuckeruser) + yucky_organs.forceMove(get_turf(bloodsuckeruser)) + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// DEATH + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/// FINAL DEATH +/datum/antagonist/bloodsucker/proc/HandleDeath() + if(QDELETED(owner.current)) + if(length(ghouls)) + free_all_ghouls() + ghouls = list() + return + // Fire Damage? (above double health) + if(owner.current.get_fire_loss() >= owner.current.maxHealth * FINAL_DEATH_HEALTH_TO_BURN) // 337.5 burn with 135 maxHealth + FinalDeath() + return + // Temporary Death? Convert to Torpor. + if(is_in_torpor() || isbrain(owner.current)) + return + check_begin_torpor(TORPOR_SKIP_CHECK_ALL) + +/datum/antagonist/bloodsucker/proc/HandleBlood() + INVOKE_ASYNC(src, PROC_REF(update_blood)) + INVOKE_ASYNC(src, PROC_REF(HandleStarving)) + return HANDLE_BLOOD_NO_OXYLOSS | HANDLE_BLOOD_NO_NUTRITION_DRAIN + +/datum/antagonist/bloodsucker/proc/HandleStarving() // I am thirsty for blood! + // Nutrition - The amount of blood is how full we are. + owner.current.set_nutrition(min(bloodsucker_blood_volume, NUTRITION_LEVEL_FED)) + + // BLOOD_VOLUME_GOOD: [336] - Pale +// handled in bloodsucker_integration.dm + // BLOOD_VOLUME_EXIT: [250] - Exit Frenzy (If in one) This is high because we want enough to kill the poor soul they feed off of. + var/datum/status_effect/frenzy/status_effect = owner.current.has_status_effect(/datum/status_effect/frenzy) + if(bloodsucker_blood_volume >= frenzy_exit_threshold() && frenzied) + owner.current.remove_status_effect(status_effect) + owner.current.balloon_alert(owner.current, "frenzy ends in 10 seconds!") + // BLOOD_VOLUME_BAD: [224] - Jitter + if(bloodsucker_blood_volume < BLOOD_VOLUME_BAD && prob(0.5) && !is_in_torpor() && !HAS_TRAIT(owner.current, TRAIT_MASQUERADE)) + owner.current.set_timed_status_effect(3 SECONDS, /datum/status_effect/jitter, only_if_higher = TRUE) + // BLOOD_VOLUME_SURVIVE: [122] - Blur Vision + if(bloodsucker_blood_volume < BLOOD_VOLUME_SURVIVE) + owner.current.set_eye_blur_if_lower((8 - 8 * (bloodsucker_blood_volume / BLOOD_VOLUME_BAD))*2 SECONDS) + + // The more blood, the better the Regeneration, get too low blood, and you enter Frenzy. + if(bloodsucker_blood_volume < frenzy_enter_threshold() && !frenzied) + owner.current.apply_status_effect(/datum/status_effect/frenzy) + else if(bloodsucker_blood_volume < BLOOD_VOLUME_BAD) + additional_regen = 0.1 + else if(bloodsucker_blood_volume < BLOOD_VOLUME_OKAY) + additional_regen = 0.2 + else if(bloodsucker_blood_volume < BLOOD_VOLUME_NORMAL) + additional_regen = 0.3 + else if(bloodsucker_blood_volume < BS_BLOOD_VOLUME_MAX_REGEN) + additional_regen = 0.4 + else if(bloodsucker_blood_volume < max_blood_volume) + additional_regen = 0.5 + else if(bloodsucker_blood_volume > max_blood_volume) + additional_regen = 1 + round((blood_over_cap / 1000) * 2, 0.1) + AdjustBloodVolume(-1 - blood_over_cap / 100) + +/// Makes your blood_volume look like your bloodsucker blood, unless you're Masquerading. +/datum/antagonist/bloodsucker/proc/update_blood() + if(SEND_SIGNAL(src, BLOODSUCKER_UPDATE_BLOOD) & BLOODSUCKER_UPDATE_BLOOD_DISABLED) + return + if(HAS_TRAIT(owner.current, TRAIT_NOBLOOD)) + return + //If we're on Masquerade, we appear to have full blood, unless we are REALLY low, in which case we don't look as bad. + if(HAS_TRAIT(owner.current, TRAIT_MASQUERADE)) + switch(bloodsucker_blood_volume) + if(BLOOD_VOLUME_OKAY to INFINITY) // 336 and up, we are perfectly fine. + owner.current.blood_volume = initial(bloodsucker_blood_volume) + if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY) // 224 to 336 + owner.current.blood_volume = BLOOD_VOLUME_SAFE + else // 224 and below + owner.current.blood_volume = BLOOD_VOLUME_OKAY + return + + owner.current.blood_volume = bloodsucker_blood_volume + +/// Turns the bloodsucker into a wacky talking head. +/datum/antagonist/bloodsucker/proc/talking_head(mob/target) + var/mob/living/poor_fucker = target + if(QDELETED(poor_fucker)) + return + // Don't do anything if we're not actually inside a brain and a head + var/obj/item/bodypart/head/head = is_head(poor_fucker) + if(!head || poor_fucker.stat != DEAD || !poor_fucker.can_be_revived()) + return + if(istype(poor_fucker.loc, /obj/item/organ/brain)) + RegisterSignal(poor_fucker.loc, COMSIG_QDELETING, PROC_REF(on_brain_remove)) + RegisterSignal(poor_fucker.loc, COMSIG_ORGAN_BODYPART_REMOVED, PROC_REF(on_brain_remove)) + + RegisterSignal(poor_fucker, COMSIG_MOB_TRY_SPEECH, PROC_REF(allow_head_to_talk)) + RegisterSignal(poor_fucker, COMSIG_MOB_SAY, PROC_REF(shake_head_on_talk)) + poor_fucker.revive() + poor_fucker.stat = CONSCIOUS + to_chat(poor_fucker, span_warning("Your immortal [pick(list("blood", "curse"))] keeps your head alive! Though... what will you do now?")) + // No lungs to speak, let's make it spooky + poor_fucker.speech_span = SPAN_PAPYRUS + +/datum/antagonist/bloodsucker/proc/cleanup_talking_head(obj/item/organ/brain) + var/mob/living/poor_fucker = owner.current + if(brain) + UnregisterSignal(brain, list(COMSIG_QDELETING, COMSIG_ORGAN_BODYPART_REMOVED)) + // fucked up if this happens, but we're probably final deathed at this point + if(QDELETED(poor_fucker)) + return + UnregisterSignal(poor_fucker, list(COMSIG_MOB_TRY_SPEECH, COMSIG_MOB_SAY, COMSIG_QDELETING)) + poor_fucker.death() + poor_fucker.speech_span = initial(poor_fucker.speech_span) + +/datum/antagonist/bloodsucker/proc/on_brain_remove(obj/item/organ/brain) + SIGNAL_HANDLER + cleanup_talking_head(brain) + +/datum/antagonist/bloodsucker/proc/on_brainmob_qdel() + SIGNAL_HANDLER + if(istype(owner.current.loc, /obj/item/organ/brain)) + cleanup_talking_head(owner.current.loc) + else + cleanup_talking_head() + +/// Gibs the Bloodsucker, roundremoving them. +/datum/antagonist/bloodsucker/proc/FinalDeath(check_organs = FALSE) + SIGNAL_HANDLER + // If we have no body, end here. + if(QDELETED(owner.current) || isbrain(owner.current)) + return + unregister_body_signals() + free_all_ghouls() + DisableAllPowers(forced = TRUE) + if(!iscarbon(owner.current)) + owner.current.gib(DROP_ITEMS) + return + // Drop anything in us and play a tune + var/mob/living/carbon/user = owner.current + owner.current.drop_all_held_items() + owner.current.unequip_everything() + INVOKE_ASYNC(user, TYPE_PROC_REF(/mob/living/carbon, remove_all_embedded_objects)) + playsound(owner.current, 'sound/effects/tendril_destroyed.ogg', 40, TRUE) + + var/unique_death = SEND_SIGNAL(src, COMSIG_BLOODSUCKER_FINAL_DEATH) + if(unique_death & DONT_DUST) + return + + // Elders get dusted, Fledglings get gibbed. + if(bloodsucker_level >= 4) + user.visible_message( + span_warning("[user]'s skin crackles and dries, their skin and bones withering to dust. A hollow cry whips from what is now a sandy pile of remains."), + span_userdanger("Your soul escapes your withering body as the abyss welcomes you to your Final Death."), + span_hear("You hear a dry, crackling sound.")) + addtimer(CALLBACK(user, TYPE_PROC_REF(/atom/movable, dust)), 5 SECONDS, TIMER_UNIQUE|TIMER_STOPPABLE) + return + user.visible_message( + span_warning("[user]'s skin bursts forth in a spray of gore and detritus. A horrible cry echoes from what is now a wet pile of decaying meat."), + span_userdanger("Your soul escapes your withering body as the abyss welcomes you to your Final Death."), + span_hear("You hear a wet, bursting sound.")) + addtimer(CALLBACK(user, TYPE_PROC_REF(/mob/living, gib), DROP_ITEMS), 2 SECONDS, TIMER_UNIQUE|TIMER_STOPPABLE) + user.investigate_log("Died as a bloodsucker from Final Death.", INVESTIGATE_DEATHS) + +#undef BLOODSUCKER_PASSIVE_BLOOD_DRAIN + + +/** + * # Status effect + * + * This is the status effect given to Bloodsuckers in a Frenzy + * This deals with everything entering/exiting Frenzy is meant to deal with. + */ + +/atom/movable/screen/alert/status_effect/frenzy + name = "Frenzy" + desc = "You are in a Frenzy! You are entirely Feral and, depending on your Clan, fighting for your life! Find and drink blood, or you will suffer a Final Death!" + icon = 'tff_modular/modules/bloodsucker/icons/bloodsucker.dmi' + icon_state = "power_recover" + alerttooltipstyle = "cult" + +/datum/status_effect/frenzy + id = "Frenzy" + status_type = STATUS_EFFECT_UNIQUE + duration = STATUS_EFFECT_PERMANENT + alert_type = /atom/movable/screen/alert/status_effect/frenzy + ///Boolean on whether they were an AdvancedToolUser, to give the trait back upon exiting. + var/was_tooluser = FALSE + /// The stored Bloodsucker antag datum + var/datum/antagonist/bloodsucker/bloodsuckerdatum + var/trait_list = list(TRAIT_MUTE, TRAIT_DEAF, TRAIT_STRONG_GRABBER) + +/datum/status_effect/frenzy/get_examine_text() + return span_notice("They seem... inhumane, and feral!") + +/atom/movable/screen/alert/status_effect/masquerade/MouseEntered(location,control,params) + desc = initial(desc) + return ..() + +/datum/status_effect/frenzy/on_apply() + var/mob/living/carbon/human/user = owner + bloodsuckerdatum = IS_BLOODSUCKER(user) + + // Disable ALL Powers and notify their entry + bloodsuckerdatum.DisableAllPowers(forced = TRUE) + to_chat(owner, span_userdanger("Blood! You need Blood, now! You enter a total Frenzy! You will DIE if you do not get BLOOD.")) + to_chat(owner, span_announce("* Bloodsucker Tip: While in Frenzy, you quickly accrue burn damage, instantly Aggresively grab, have stun resistance, cannot speak, hear, or use any powers outside of Feed and Trespass (If you have it).")) + owner.balloon_alert(owner, "you enter a frenzy! Drink blood, or you will die!") + SEND_SIGNAL(bloodsuckerdatum, COMSIG_BLOODSUCKER_ENTERS_FRENZY) + + // Give the other Frenzy effects + owner.add_traits(trait_list, FRENZY_TRAIT) + if(HAS_TRAIT(owner, TRAIT_ADVANCEDTOOLUSER)) + was_tooluser = TRUE + REMOVE_TRAIT(owner, TRAIT_ADVANCEDTOOLUSER, SPECIES_TRAIT) + owner.add_movespeed_modifier(/datum/movespeed_modifier/frenzy_speedup) + owner.add_client_colour(/datum/client_colour/manual_heart_blood, REF(src)) + var/obj/cuffs = user.get_item_by_slot(ITEM_SLOT_HANDCUFFED) + var/obj/legcuffs = user.get_item_by_slot(ITEM_SLOT_LEGCUFFED) + if((user.handcuffed && cuffs) || (user.legcuffed && legcuffs)) + user.clear_cuffs(cuffs, TRUE) + user.clear_cuffs(legcuffs, TRUE) + bloodsuckerdatum.frenzied = TRUE + return ..() + +/datum/status_effect/frenzy/on_remove() + owner.balloon_alert(owner, "you come back to your senses.") + owner.remove_traits(trait_list, FRENZY_TRAIT) + if(was_tooluser) + ADD_TRAIT(owner, TRAIT_ADVANCEDTOOLUSER, SPECIES_TRAIT) + was_tooluser = FALSE + owner.remove_movespeed_modifier(/datum/movespeed_modifier/frenzy_speedup) + owner.remove_client_colour(REF(src)) + + SEND_SIGNAL(bloodsuckerdatum, COMSIG_BLOODSUCKER_EXITS_FRENZY) + bloodsuckerdatum.frenzied = FALSE + return ..() + +/datum/status_effect/frenzy/tick() + var/mob/living/carbon/human/user = owner + // If duration is not -1, that means we're about to loose frenzy, let's give them some safe time. + if(!bloodsuckerdatum.frenzied || duration > 0 || user.stat != CONSCIOUS ) + return + user.adjust_fire_loss(1 + (bloodsuckerdatum.GetHumanityLost() / 10)) + +/datum/movespeed_modifier/frenzy_speedup + blacklisted_movetypes = (FLYING|FLOATING) + multiplicative_slowdown = -0.4 + +/datum/movespeed_modifier/mesmerize_slowdown + blacklisted_movetypes = (FLYING|FLOATING) + multiplicative_slowdown = 0.5 diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/movable_hud.dm b/tff_modular/modules/bloodsucker/bloodsuckers/movable_hud.dm new file mode 100644 index 00000000000..89729506b57 --- /dev/null +++ b/tff_modular/modules/bloodsucker/bloodsuckers/movable_hud.dm @@ -0,0 +1,207 @@ + +/// UI obj holders for all your maptext needs +/atom/movable/screen/text + name = null + icon = null + icon_state = null + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + screen_loc = "CENTER-7,CENTER-7" + maptext_height = 480 + maptext_width = 480 + +/// A screen object that shows the time left on a timer +/atom/movable/screen/text/screen_timer + screen_loc = "CENTER-7,CENTER-7" + /// The actual displayed content of the maptext, use ${timer}, and it'll be replaced with formatted time left + var/maptext_string + /// Timer ID that we're tracking, the time left of this is displayed as maptext + var/timer_id + /// The list of mobs in whose client.screens we are added to + var/list/timer_mobs = list() + +/atom/movable/screen/text/screen_timer/Initialize( + mapload, + list/mobs, + timer, + text, + offset_x = 150, + offset_y = -70, + ) + . = ..(mapload, null) + + if(!islist(mobs) && mobs) + mobs = list(mobs) + // Copy the list just in case the arguments list is a list we don't want to modify + if(length(mobs)) + mobs = mobs.Copy() + if(!timer) + return INITIALIZE_HINT_QDEL + maptext_string = text + timer_id = timer + maptext_x = offset_x + maptext_y = offset_y + update_maptext() + if(length(mobs)) + apply_to(mobs) + +/atom/movable/screen/text/screen_timer/process() + if(!timeleft(timer_id)) + qdel(src) + return + update_maptext() + +/// Adds the object to the client.screen of all mobs in the list, and registers the needed signals +/atom/movable/screen/text/screen_timer/proc/apply_to(list/mobs) + if(!mobs) + return + if(!islist(mobs)) + mobs = list(mobs) + if(!length(timer_mobs) && length(mobs)) + START_PROCESSING(SSprocessing, src) + for(var/player in mobs) + if(player in timer_mobs) + continue + if(istype(player, /datum/weakref)) + var/datum/weakref/ref = player + player = ref.resolve() + attach(player) + RegisterSignal(player, COMSIG_MOB_LOGIN, PROC_REF(attach)) // doesn't currently cleanup properly + timer_mobs += WEAKREF(player) + +/// Removes the object from the client.screen of all mobs in the list, and unregisters the needed signals, while also stopping processing if there's no more mobs in the screen timers mob list +/atom/movable/screen/text/screen_timer/proc/remove_from(list/mobs) + if(!mobs) + return + if(!islist(mobs)) + mobs = list(mobs) + for(var/player in mobs) + // when the player is a weakref, assume it's the same pointer that we use in the timer_mobs list + var/datum/weakref/found_weakref + if(istype(player, /datum/weakref)) + var/datum/weakref/ref = player + found_weakref = ref + // otherwise we have to search through and resolve each one and compare it + else + for(var/datum/weakref/possible_match as anything in timer_mobs) + if(player == possible_match.resolve()) + found_weakref = possible_match + break + timer_mobs -= found_weakref + var/found_player = found_weakref.resolve() + if(!found_player) + return + UnregisterSignal(found_player, COMSIG_MOB_LOGIN) + de_attach(found_player) + if(!length(timer_mobs)) + STOP_PROCESSING(SSprocessing, src) + +/// Updates the maptext to show the current time left on the timer +/atom/movable/screen/text/screen_timer/proc/update_maptext() + var/time_formatted = time2text(timeleft(timer_id), "mm:ss") + var/timer_text = replacetextEx(maptext_string, "${timer}", time_formatted) + // If we don't find ${timer} in the string, just use the time formatted + var/result_text = MAPTEXT("[timer_text]") + apply_change(result_text) + +/atom/movable/screen/text/screen_timer/proc/apply_change(result_text) + maptext = result_text + +/// Adds the object to the client.screen of the mob, or removes it if add_to_screen is FALSE +/atom/movable/screen/text/screen_timer/proc/attach(mob/source, add_to_screen = TRUE) + SIGNAL_HANDLER + if(!source?.client) + return + var/client/client = source.client + // this checks if the screen is already added or removed + if(!can_attach(client, add_to_screen)) + return + if(!ismob(source)) + CRASH("Invalid source passed to screen_timer/attach()!") + do_attach(client, add_to_screen) + +/atom/movable/screen/text/screen_timer/proc/can_attach(client/client, add_to_screen) + return add_to_screen == (src in client.screen) + +/atom/movable/screen/text/screen_timer/proc/do_attach(client/client, add_to_screen) + if(add_to_screen) + client.screen += src + else + client.screen -= src + +/// Signal handler to run attach with specific args +/atom/movable/screen/text/screen_timer/proc/de_attach(mob/source) + SIGNAL_HANDLER + attach(source, FALSE) + +/atom/movable/screen/text/screen_timer/Destroy() + if(length(timer_mobs)) + remove_from(timer_mobs) + + STOP_PROCESSING(SSprocessing, src) + . = ..() + +/atom/movable/screen/text/screen_timer/attached + maptext_x = 0 + maptext_y = 16 + maptext_height = 32 + maptext_width = 32 + var/following_object + var/image/text_image + +/atom/movable/screen/text/screen_timer/attached/Initialize( + mapload, + list/mobs, + timer, + text, + offset_x, + offset_y, + following_object, + ) + if(following_object && get_turf(following_object)) + attach_self_to(following_object, offset_x, offset_y) + else + return INITIALIZE_HINT_QDEL + . = ..() + +/atom/movable/screen/text/screen_timer/attached/can_attach(client/client) + return !(src in client.images) + +// attached screen timers are a visible timer in the gameworld that are only visible to the mobs listed in the timer_mobs list +/atom/movable/screen/text/screen_timer/attached/do_attach(client/client, add_to_screen) + if(add_to_screen) + client.images += text_image + else + client.images -= text_image + +/atom/movable/screen/text/screen_timer/attached/proc/attach_self_to(atom/movable/target, maptext_x, maptext_y) + text_image = image(src, target) + + text_image.maptext_x = maptext_x + text_image.maptext_y = maptext_y + + text_image.maptext_height = maptext_height + text_image.maptext_width = maptext_width + + SET_PLANE_EXPLICIT(text_image, ABOVE_HUD_PLANE, target) + +/atom/movable/screen/text/screen_timer/attached/apply_change(result_text) + ..() + text_image?.maptext = result_text + +/atom/movable/screen/text/screen_timer/attached/proc/hide_timer(atom/movable/target) + unregister_follower() + +/atom/movable/screen/text/screen_timer/attached/proc/unregister_follower() + following_object = null + text_image = null + +/atom/movable/screen/text/screen_timer/attached/proc/update_glide_speed(atom/movable/tracked) + set_glide_size(tracked.glide_size) + +/atom/movable/screen/text/screen_timer/attached/proc/timer_follow(atom/movable/tracked, atom/mover, atom/oldloc, direction) + abstract_move(get_turf(tracked)) + +/atom/movable/screen/text/screen_timer/attached/Destroy() + if(following_object) + unregister_follower() + . = ..() diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/names.dm b/tff_modular/modules/bloodsucker/bloodsuckers/names.dm new file mode 100644 index 00000000000..60a9c1c1d74 --- /dev/null +++ b/tff_modular/modules/bloodsucker/bloodsuckers/names.dm @@ -0,0 +1,136 @@ + +/datum/antagonist/bloodsucker/proc/return_full_name() + var/fullname = bloodsucker_name ? bloodsucker_name : owner.current.name + if(bloodsucker_title) + fullname = "[bloodsucker_title] [fullname]" + if(bloodsucker_reputation) + fullname += " the [bloodsucker_reputation]" + + return fullname + +///Returns a First name for the Bloodsucker. +/datum/antagonist/bloodsucker/proc/SelectFirstName() + if(owner.current.gender == MALE) + bloodsucker_name = pick( + "Desmond","Rudolph","Dracula","Vlad","Pyotr","Gregor", + "Cristian","Christoff","Marcu","Andrei","Constantin", + "Gheorghe","Grigore","Ilie","Iacob","Luca","Mihail","Pavel", + "Vasile","Octavian","Sorin","Sveyn","Aurel","Alexe","Iustin", + "Theodor","Dimitrie","Octav","Damien","Magnus","Caine","Abel", // Romanian/Ancient + "Lucius","Gaius","Otho","Balbinus","Arcadius","Romanos","Alexios","Vitellius", // Latin + "Melanthus","Teuthras","Orchamus","Amyntor","Axion", // Greek + "Thoth","Thutmose","Osorkon,","Nofret","Minmotu","Khafra", // Egyptian + "Dio", + ) + else + bloodsucker_name = pick( + "Islana","Tyrra","Greganna","Pytra","Hilda", + "Andra","Crina","Viorela","Viorica","Anemona", + "Camelia","Narcisa","Sorina","Alessia","Sophia", + "Gladda","Arcana","Morgan","Lasarra","Ioana","Elena", + "Alina","Rodica","Teodora","Denisa","Mihaela", + "Svetla","Stefania","Diyana","Kelssa","Lilith", // Romanian/Ancient + "Alexia","Athanasia","Callista","Karena","Nephele","Scylla","Ursa", // Latin + "Alcestis","Damaris","Elisavet","Khthonia","Teodora", // Greek + "Nefret","Ankhesenpep", // Egyptian + ) + +///Returns a Title for the Bloodsucker. +/datum/antagonist/bloodsucker/proc/SelectTitle(am_fledgling = FALSE, forced = FALSE) + // Already have Title + if(!forced && bloodsucker_title != null) + return + // Titles [Master] + if(am_fledgling) + bloodsucker_title = null + return + if(owner.current.gender == MALE) + bloodsucker_title = pick( + "Count", + "Baron", + "Viscount", + "Prince", + "Duke", + "Tzar", + "Dreadlord", + "Lord", + "Master", + ) + else + bloodsucker_title = pick( + "Countess", + "Baroness", + "Viscountess", + "Princess", + "Duchess", + "Tzarina", + "Dreadlady", + "Lady", + "Mistress", + ) + to_chat(owner, span_announce("You have earned a title! You are now known as [return_full_name()]!")) + +///Returns a Reputation for the Bloodsucker. +/datum/antagonist/bloodsucker/proc/SelectReputation(am_fledgling = FALSE, forced = FALSE) + // Already have Reputation + if(!forced && bloodsucker_reputation != null) + return + + if(am_fledgling) + bloodsucker_reputation = pick( + "Crude", + "Callow", + "Unlearned", + "Neophyte", + "Novice", + "Unseasoned", + "Fledgling", + "Young", + "Neonate", + "Scrapling", + "Untested", + "Unproven", + "Unknown", + "Newly Risen", + "Born", + "Scavenger", + "Unknowing", + "Unspoiled", + "Disgraced", + "Defrocked", + "Shamed", + "Meek", + "Timid", + "Broken", + "Fresh", + ) + else if(owner.current.gender == MALE && prob(10)) + bloodsucker_reputation = pick( + "King of the Damned", + "Blood King", + "Emperor of Blades", + "Sinlord", + "God-King", + ) + else if(owner.current.gender == FEMALE && prob(10)) + bloodsucker_reputation = pick( + "Queen of the Damned", + "Blood Queen", + "Empress of Blades", + "Sinlady", + "God-Queen", + ) + else + bloodsucker_reputation = pick( + "Butcher","Blood Fiend","Crimson","Red","Black","Terror", + "Nightman","Feared","Ravenous","Fiend","Malevolent","Wicked", + "Ancient","Plaguebringer","Sinister","Forgotten","Wretched","Baleful", + "Inqisitor","Harvester","Reviled","Robust","Betrayer","Destructor", + "Damned","Accursed","Terrible","Vicious","Profane","Vile", + "Depraved","Foul","Slayer","Manslayer","Sovereign","Slaughterer", + "Forsaken","Mad","Dragon","Savage","Villainous","Nefarious", + "Inquisitor","Marauder","Horrible","Immortal","Undying","Overlord", + "Corrupt","Hellspawn","Tyrant","Sanguineous", + ) + + to_chat(owner, span_announce("You have earned a reputation! You are now known as [return_full_name()]!")) diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/objectives.dm b/tff_modular/modules/bloodsucker/bloodsuckers/objectives.dm new file mode 100644 index 00000000000..25c7811bcf8 --- /dev/null +++ b/tff_modular/modules/bloodsucker/bloodsuckers/objectives.dm @@ -0,0 +1,372 @@ +/* + * # Hide a random object somewhere on the station: + * + * var/turf/targetturf = get_random_station_turf() + * var/turf/targetturf = get_safe_random_station_turf() + */ + +/datum/objective/bloodsucker + martyr_compatible = TRUE + +// GENERATE +/datum/objective/bloodsucker/New() + update_explanation_text() + ..() + +////////////////////////////////////////////////////////////////////////////// +// // PROCS // // + +/// Look at all crew members, and for/loop through. +/datum/objective/bloodsucker/proc/return_possible_targets() + var/list/possible_targets = list() + for(var/datum/mind/possible_target in get_crewmember_minds()) + // Check One: Default Valid User + if(possible_target != owner && ishuman(possible_target.current) && possible_target.current.stat != DEAD) + // Check Two: Am Bloodsucker? + if(IS_BLOODSUCKER(possible_target.current)) + continue + possible_targets += possible_target + + return possible_targets + +/// Check Ghouls and get their occupations +/datum/objective/bloodsucker/proc/get_ghoul_occupations() + var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(owner.current) + if(!bloodsuckerdatum || !bloodsuckerdatum.ghouls.len) + return FALSE + var/list/all_ghoul_jobs = list() + var/ghoul_job + for(var/datum/antagonist/ghoul/bloodsucker_ghouls in bloodsuckerdatum.ghouls) + if(!bloodsucker_ghouls || !bloodsucker_ghouls.owner) // Must exist somewhere, and as a ghoul. + continue + // Mind Assigned + if(bloodsucker_ghouls.owner?.assigned_role) + ghoul_job = bloodsucker_ghouls.owner.assigned_role + // Mob Assigned + else if(bloodsucker_ghouls.owner?.current?.job) + ghoul_job = SSjob.get_job(bloodsucker_ghouls.owner.current.job) + // PDA Assigned + else if(bloodsucker_ghouls.owner?.current && ishuman(bloodsucker_ghouls.owner.current)) + var/mob/living/carbon/human/ghoul = bloodsucker_ghouls.owner.current + ghoul_job = SSjob.get_job(ghoul.get_assignment()) + if(ghoul_job) + all_ghoul_jobs += ghoul_job + return all_ghoul_jobs + +////////////////////////////////////////////////////////////////////////////////////// +// // OBJECTIVES // // +////////////////////////////////////////////////////////////////////////////////////// + +////////////////////////////// +// DEFAULT OBJECTIVES // +////////////////////////////// + +/datum/objective/bloodsucker/haven + name = "claimhaven" + +// EXPLANATION +/datum/objective/bloodsucker/haven/update_explanation_text() + explanation_text = "Create a haven by claiming a coffin, and protect it until the end of the shift."// Make sure to keep it safe!" + +// WIN CONDITIONS? +/datum/objective/bloodsucker/haven/check_completion() + var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(owner.current) + if(bloodsuckerdatum && bloodsuckerdatum.coffin && bloodsuckerdatum.bloodsucker_haven_area) + return TRUE + return FALSE + +/// Space_Station_13_areas.dm <--- all the areas + +////////////////////////////////////////////////////////////////////////////////////// + +/datum/objective/survive/bloodsucker + name = "bloodsuckersurvive" + explanation_text = "Survive the entire shift without succumbing to Final Death." + +/datum/objective/survive/bloodsucker/check_completion() + var/list/datum/mind/owners = get_owners() + for(var/datum/mind/mind in owners) + var/datum/antagonist/bloodsucker/vamp = IS_BLOODSUCKER(mind.current) + if(!vamp) + return FALSE + if(!vamp.considered_alive(mind)) + return FALSE + return TRUE + +////////////////////////////////////////////////////////////////////////////////////// + + +/// Ghoulify a certain person / people +/datum/objective/bloodsucker/conversion + name = "ghouling" + +///////////////////////////////// + +// Ghoulify a head of staff +/datum/objective/bloodsucker/conversion/command + name = "ghoulingcommand" + target_amount = 1 + +// EXPLANATION +/datum/objective/bloodsucker/conversion/command/update_explanation_text() + explanation_text = "Guarantee a Ghoul ends up as a Department Head or in a Leadership role." + +// WIN CONDITIONS? +/datum/objective/bloodsucker/conversion/command/check_completion() + var/list/ghoul_jobs = get_ghoul_occupations() + for(var/datum/job/checked_job in ghoul_jobs) + if(checked_job.departments_bitflags & DEPARTMENT_BITFLAG_COMMAND) + return TRUE // We only need one, so we stop as soon as we get a match + return FALSE + +///////////////////////////////// + +// Ghoulify crewmates in a department +/datum/objective/bloodsucker/conversion/department + name = "ghoulify department" + + ///The selected department we have to ghoulify. + var/datum/job_department/target_department + ///List of all departments that can be selected for the objective. + var/static/list/possible_departments = list( + /datum/job_department/security, + /datum/job_department/engineering, + /datum/job_department/medical, + /datum/job_department/science, + /datum/job_department/cargo, + /datum/job_department/service, + ) + + +// GENERATE! +/datum/objective/bloodsucker/conversion/department/New() + target_department = SSjob.get_department_type(pick(possible_departments)) + target_amount = rand(2, 3) + return ..() + +// EXPLANATION +/datum/objective/bloodsucker/conversion/department/update_explanation_text() + explanation_text = "Have [target_amount] Ghoul[target_amount == 1 ? "" : "s"] in the [target_department.department_name] department." + return ..() + +// WIN CONDITIONS? +/datum/objective/bloodsucker/conversion/department/check_completion() + var/list/ghoul_jobs = get_ghoul_occupations() + var/converted_count = 0 + for(var/datum/job/checked_job in ghoul_jobs) + if(checked_job.departments_bitflags & target_department.department_bitflags) + converted_count++ + if(converted_count >= target_amount) + return TRUE + return FALSE + + /** + * # IMPORTANT NOTE!! + * + * Look for Job Values on mobs! This is assigned at the start, but COULD be changed via the HoP + * ALSO - Search through all jobs (look for prefs earlier that look for all jobs, and search through all jobs to see if their head matches the head listed, or it IS the head) + * ALSO - registered_account in _vending.dm for banks, and assigning new ones. + */ + +////////////////////////////////////////////////////////////////////////////////////// + +// NOTE: Look up /steal in objective.dm for inspiration. +/// Steal hearts. You just really wanna have some hearts. +/datum/objective/steal_n_of_type/hearts + martyr_compatible = TRUE + name = "heartthief" + wanted_items = (/obj/item/organ/heart) + +// GENERATE! +/datum/objective/steal_n_of_type/hearts/New() + amount = rand(2, 3) + explanation_text = "Steal and keep [amount] organic hearts. Must be obtained from non-monkeys. Examine hearts thoroughly to see if they are valid." + update_explanation_text() + ..() + +/datum/objective/steal_n_of_type/hearts/check_if_valid_item(obj/item/organ/heart/current_item) + . = ..() + if(current_item.type == /obj/item/organ/heart/monkey || IS_ROBOTIC_ORGAN(current_item)) + return FALSE + +////////////////////////////////////////////////////////////////////////////////////// + +///Eat blood from a lot of people +/datum/objective/bloodsucker/gourmand + name = "gourmand" + +// GENERATE! +/datum/objective/bloodsucker/gourmand/New() + target_amount = rand(800, 3 * BLOOD_VOLUME_NORMAL) + ..() + +// EXPLANATION +/datum/objective/bloodsucker/gourmand/update_explanation_text() + . = ..() + explanation_text = "Using your Feed ability, drink [target_amount] units of Blood." + +// WIN CONDITIONS? +/datum/objective/bloodsucker/gourmand/check_completion() + var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(owner.current) + if(!bloodsuckerdatum) + return FALSE + var/stolen_blood = bloodsuckerdatum.total_blood_drank + if(stolen_blood >= target_amount) + return TRUE + return FALSE + +// HOW: Track each feed (if human). Count victory. + + + +////////////////////////////// +// CLAN OBJECTIVES // +////////////////////////////// + +/// Steal the Book of Nod - Nosferatu Clan objective +/datum/objective/bloodsucker/kindred + name = "steal the Book of Nod" + +// EXPLANATION +/datum/objective/bloodsucker/kindred/update_explanation_text() + . = ..() + explanation_text = "A Noddist Scholar has posted a bounty on SchreckNet for a scrap of the Book of Nod located in your sector. Their advise? Read a book." + +// WIN CONDITIONS? +/datum/objective/bloodsucker/kindred/check_completion() + if(!owner.current) + return FALSE + var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(owner.current) + if(!bloodsuckerdatum) + return FALSE + + for(var/datum/mind/bloodsucker_minds as anything in get_antag_minds(/datum/antagonist/bloodsucker)) + var/obj/item/book/kindred/the_book = locate() in bloodsucker_minds.current.get_all_contents() + if(the_book) + return TRUE + return FALSE + +////////////////////////////////////////////////////////////////////////////////////// + +/// Max out a Tremere Power - Tremere Clan objective +/datum/objective/bloodsucker/tremere_power + name = "tremerepower" + var/power_level = TREMERE_OBJECTIVE_POWER_LEVEL + +// EXPLANATION +/datum/objective/bloodsucker/tremere_power/update_explanation_text() + explanation_text = "Your Regent is doubting your abilities, level some Blood Magic to [power_level] to prove them wrong! Remember that Ghoulifying gives more Ranks!" + +// WIN CONDITIONS? +/datum/objective/bloodsucker/tremere_power/check_completion() + var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(owner.current) + if(!bloodsuckerdatum) + return FALSE + for(var/datum/action/cooldown/bloodsucker/tremere_powers in bloodsuckerdatum.powers) + if(tremere_powers.purchase_flags & TREMERE_CAN_BUY && tremere_powers.level_current >= power_level) + return TRUE + return FALSE + +////////////////////////////////////////////////////////////////////////////////////// + +/// Convert a crewmate - Ventrue Clan objective +/datum/objective/bloodsucker/embrace + name = "embrace" + +// EXPLANATION +/datum/objective/bloodsucker/embrace/update_explanation_text() + . = ..() + explanation_text = "Your Strategoi has granted you permission to embrace your favourite ghoul , use the Rack to 'level' them up." + +// WIN CONDITIONS? +/datum/objective/bloodsucker/embrace/check_completion() + var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(owner.current) + if(!bloodsuckerdatum) + return FALSE + for(var/datum/antagonist/bloodsucker/sired_vamp in GLOB.antagonists) + if(sired_vamp.ventrue_sired == bloodsuckerdatum) + return TRUE + return FALSE + + + +////////////////////////////// +// MONSTERHUNTER OBJECTIVES // +////////////////////////////// + +/datum/objective/bloodsucker/monsterhunter + name = "destroymonsters" + +// EXPLANATION +/datum/objective/bloodsucker/monsterhunter/update_explanation_text() + . = ..() + explanation_text = "Destroy all monsters on [station_name()]." + +// WIN CONDITIONS? +/datum/objective/bloodsucker/monsterhunter/check_completion() + var/list/datum/mind/monsters = list() + for(var/datum/antagonist/monster in GLOB.antagonists) + var/datum/mind/brain = monster.owner + if(!brain || brain == owner) + continue + if(brain.current.stat == DEAD) + continue + if(IS_HERETIC(brain.current) || IS_CULTIST(brain.current) || IS_BLOODSUCKER(brain.current) || IS_WIZARD(brain.current)) + monsters += brain + if(brain.has_antag_datum(/datum/antagonist/changeling)) + monsters += brain + + return completed || !monsters.len + + + +////////////////////////////// +// GHOUL OBJECTIVES // +////////////////////////////// + +/datum/objective/bloodsucker/ghoul + +// EXPLANATION +/datum/objective/bloodsucker/ghoul/update_explanation_text() + . = ..() + explanation_text = "Guarantee the success of your Master's mission!" + +// WIN CONDITIONS? +/datum/objective/bloodsucker/ghoul/check_completion() + var/datum/antagonist/ghoul/antag_datum = owner.has_antag_datum(/datum/antagonist/ghoul) + return antag_datum.master?.owner?.current?.stat != DEAD + + + +////////////////////////////// +// REMOVED OBJECTIVES // +// NOT GUARANTEED FUNCTIONAL// +////////////////////////////// + +// NOTE: Look up /assassinate in objective.dm for inspiration. +/// Ghoulify a target. +/datum/objective/bloodsucker/ghoulhim + name = "ghoulhim" + var/target_department_type = FALSE + +/datum/objective/bloodsucker/ghoulhim/New() + var/list/possible_targets = return_possible_targets() + find_target(possible_targets) + ..() + +// EXPLANATION +/datum/objective/bloodsucker/ghoulhim/update_explanation_text() + . = ..() + if(target?.current) + explanation_text = "Ensure [target.name], the [!target_department_type ? target.assigned_role.title : english_list(target.get_special_roles())], is Ghoulifyd via the Persuasion Rack." + else + explanation_text = "Free Objective" + +/datum/objective/bloodsucker/ghoulhim/admin_edit(mob/admin) + admin_simple_target_pick(admin) + +// WIN CONDITIONS? +/datum/objective/bloodsucker/ghoulhim/check_completion() + if(!target || target.has_antag_datum(/datum/antagonist/ghoul)) + return TRUE + return FALSE diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/procs.dm b/tff_modular/modules/bloodsucker/bloodsuckers/procs.dm new file mode 100644 index 00000000000..e1f986918fe --- /dev/null +++ b/tff_modular/modules/bloodsucker/bloodsuckers/procs.dm @@ -0,0 +1,381 @@ +/datum/antagonist/bloodsucker/proc/on_examine(datum/source, mob/examiner, examine_text) + SIGNAL_HANDLER + + if(!iscarbon(source)) + return + var/vamp_examine = return_vamp_examine(examiner) + if(vamp_examine) + examine_text += vamp_examine + SEND_SIGNAL(src, COMSIG_BLOODSUCKER_EXAMINE, source, examiner, examine_text) + +/datum/antagonist/bloodsucker/proc/BuyPowers(powers = list()) + for(var/datum/action/cooldown/bloodsucker/power as anything in powers) + BuyPower(power) + +///Called when a Bloodsucker buys a power: (power) +/datum/antagonist/bloodsucker/proc/BuyPower(datum/action/cooldown/bloodsucker/power) + for(var/datum/action/cooldown/bloodsucker/current_powers as anything in powers) + if(current_powers.type == power.type) + return null + power = new power() + powers += power + power.Grant(owner.current) + log_uplink("[key_name(owner.current)] purchased [power].") + return power + +///Called when a Bloodsucker loses a power: (power) +/datum/antagonist/bloodsucker/proc/RemovePower(datum/action/cooldown/bloodsucker/power) + if(power.active) + power.DeactivatePower() + powers -= power + power.Remove(owner.current) + +/datum/antagonist/bloodsucker/proc/RemovePowerByPath(datum/action/cooldown/bloodsucker/power_to_remove) + for(var/datum/action/cooldown/bloodsucker/power as anything in powers) + if(power?.type == power_to_remove) + RemovePower(power) + +///When a Bloodsucker breaks the Masquerade, they get their HUD icon changed, and Malkavian Bloodsuckers get alerted. +/datum/antagonist/bloodsucker/proc/break_masquerade(mob/admin) + if(broke_masquerade) + return + owner.current.playsound_local(null, 'tff_modular/modules/bloodsucker/sound/lunge_warn.ogg', 100, FALSE, pressure_affected = FALSE) + to_chat(owner.current, span_cult_bold_italic("You have broken the Masquerade!")) + to_chat(owner.current, span_warning("Bloodsucker Tip: When you break the Masquerade, you become open for termination by fellow Bloodsuckers, and your Ghouls are no longer completely loyal to you, as other Bloodsuckers can steal them for themselves!")) + broke_masquerade = TRUE + antag_hud_name = "masquerade_broken" + add_team_hud(owner.current) + SEND_GLOBAL_SIGNAL(COMSIG_BLOODSUCKER_BROKE_MASQUERADE, src) + +///This is admin-only of reverting a broken masquerade, sadly it doesn't remove the Malkavian objectives yet. +/datum/antagonist/bloodsucker/proc/fix_masquerade(mob/admin) + if(!broke_masquerade) + return + to_chat(owner.current, span_cult_bold_italic("You have re-entered the Masquerade.")) + broke_masquerade = FALSE + antag_hud_name = "bloodsucker" + add_team_hud(owner.current) + +/datum/antagonist/bloodsucker/proc/give_masquerade_infraction() + if(broke_masquerade) + return + masquerade_infractions++ + if(masquerade_infractions >= 3) + break_masquerade() + else + to_chat(owner.current, span_cult_bold("You violated the Masquerade! Break the Masquerade [3 - masquerade_infractions] more times and you will become a criminal to the Bloodsucker's Cause!")) + +/datum/antagonist/bloodsucker/proc/RankUp(force = FALSE) + if(!owner || !owner.current) + return + AdjustUnspentRank(1) + if(!my_clan) + to_chat(owner.current, span_notice("You have gained a rank. Join a Clan to spend it.")) + return + // Spend Rank Immediately? + if(!is_valid_coffin()) + to_chat(owner, span_notice("You have grown more ancient! Sleep in a coffin (or put your Favorite Ghoul on a persuasion rack for Ventrue) that you have claimed to thicken your blood and become more powerful.")) + if(bloodsucker_level_unspent >= 2) + to_chat(owner, span_announce("Bloodsucker Tip: If you cannot find or steal a coffin to use, you can build one from wood or metal.")) + return + SpendRank() + +/datum/antagonist/bloodsucker/proc/RankDown() + AdjustUnspentRank(-1) + +/datum/antagonist/bloodsucker/proc/remove_nondefault_powers(return_levels = FALSE) + for(var/datum/action/cooldown/bloodsucker/power as anything in powers) + if(power.purchase_flags & BLOODSUCKER_DEFAULT_POWER) + continue + RemovePower(power) + if(return_levels) + AdjustUnspentRank(1) + +/datum/antagonist/bloodsucker/proc/LevelUpPowers() + for(var/datum/action/cooldown/bloodsucker/power as anything in powers) + if(power.purchase_flags & TREMERE_CAN_BUY) + continue + power.upgrade_power() + +///Disables all powers, accounting for torpor +/datum/antagonist/bloodsucker/proc/DisableAllPowers(forced = FALSE) + for(var/datum/action/cooldown/bloodsucker/power as anything in powers) + if(forced || ((power.check_flags & BP_CANT_USE_IN_TORPOR) && is_in_torpor())) + if(power.active) + power.DeactivatePower() + +/datum/antagonist/bloodsucker/proc/SpendRank(mob/living/carbon/human/target, cost_rank = TRUE, blood_cost) + if(!owner || !owner.current || !owner.current.client || (cost_rank && bloodsucker_level_unspent <= 0)) + return + SEND_SIGNAL(src, COMSIG_BLOODSUCKER_RANK_UP, target, cost_rank, blood_cost) + +/datum/antagonist/bloodsucker/proc/GetRank() + return bloodsucker_level + +/datum/antagonist/bloodsucker/proc/AdjustRank(amount) + bloodsucker_level = max(bloodsucker_level + amount, 0) + update_rank_hud() + +/datum/antagonist/bloodsucker/proc/GetUnspentRank() + return bloodsucker_level_unspent + +/datum/antagonist/bloodsucker/proc/AdjustUnspentRank(amount) + bloodsucker_level_unspent = max(bloodsucker_level_unspent + amount, 0) + update_rank_hud() +/** + * Called when a Bloodsucker reaches Final Death + * Releases all Ghouls and gives them the ex_ghoul datum. + */ +/datum/antagonist/bloodsucker/proc/free_all_ghouls() + for(var/datum/antagonist/ghoul/all_ghouls in ghouls) + // Skip over any Bloodsucker Ghouls, they're too far gone to have all their stuff taken away from them + if(IS_BLOODSUCKER(all_ghouls.owner.current)) + all_ghouls.owner.current.remove_status_effect(/datum/status_effect/agent_pinpointer/ghoul_edition) + continue + if(all_ghouls.special_type == REVENGE_GHOUL || !all_ghouls.owner) + continue + all_ghouls.owner.add_antag_datum(/datum/antagonist/ex_ghoul) + all_ghouls.owner.remove_antag_datum(/datum/antagonist/ghoul) + +/** + * Returns a Vampire's examine strings. + * Args: + * viewer - The person examining. + */ +/datum/antagonist/bloodsucker/proc/return_vamp_examine(mob/living/viewer) + if(!viewer.mind && !isobserver(viewer)) + return FALSE + // Viewer is Target's Ghoul? + if(!isobserver(viewer) && (viewer.mind.has_antag_datum(/datum/antagonist/ghoul) in ghouls)) + var/returnString = "\[This is your Master!\]" + var/returnIcon = "[icon2html('tff_modular/modules/bloodsucker/icons/language.dmi', world, "bloodsucker")]" + returnString += "\n" + return returnIcon + returnString + // Viewer not a Vamp AND not the target's ghoul? + if(!isobserver(viewer) && !viewer.mind.has_antag_datum((/datum/antagonist/bloodsucker)) && !(viewer in ghouls)) + if(!(HAS_TRAIT(viewer.mind, TRAIT_BLOODSUCKER_HUNTER) && broke_masquerade)) + return FALSE + // Default String + var/returnString = "\[[return_full_name()]\]" + var/returnIcon = "[icon2html('tff_modular/modules/bloodsucker/icons/language.dmi', world, "bloodsucker")]" + + // In Disguise (Veil)? + //if (name_override != null) + // returnString += " ([real_name] in disguise!) " + + //returnString += "\n" Don't need spacers. Using . += "" in examine.dm does this on its own. + return returnIcon + returnString + +/datum/antagonist/bloodsucker/proc/can_gain_blood_rank(silent = TRUE, requires_blood = FALSE) + var/level_cost = get_level_cost() + var/mob/living/carbon/user = owner.current + if(blood_level_gain < level_cost) + if(!silent) + user.balloon_alert(user, "not enough blood thickening points!") + return FALSE + if(requires_blood && bloodsucker_blood_volume < level_cost) + if(!silent) + user.balloon_alert(user, "not enough blood!") + return FALSE + return TRUE + +// Blood level gain is used to give Bloodsuckers more levels if they are being agressive and drinking from real, sentient people. +// The maximum blood that counts towards this +/datum/antagonist/bloodsucker/proc/blood_level_gain(silent = TRUE, requires_blood = FALSE) + var/level_cost = get_level_cost() + if(can_gain_blood_rank(silent, requires_blood)) // Checks if we have drunk enough blood from the living to allow us to gain a level up as well as checking if we have enough blood to actually use on the level up + var/input = tgui_alert(owner.current, "You have drunk enough blood from the living to thicken your blood, this will cost you [level_cost] blood and give you another level", "Thicken your blood?.", list("Yes", "No")) //asks user if they want to spend their blood on a level + if(input == "Yes") + AdjustUnspentRank(1) // gives level + blood_level_gain -= level_cost // Subtracts the cost from the pool of drunk blood + if(requires_blood) + AdjustBloodVolume(-level_cost) // Subtracts the cost from the bloodsucker's actual blood + return TRUE + return FALSE + +/datum/antagonist/bloodsucker/proc/get_level_cost() + var/percentage_needed = my_clan ? my_clan.level_cost : BLOODSUCKER_LEVELUP_PERCENTAGE + return max_blood_volume * percentage_needed + +/datum/antagonist/bloodsucker/proc/max_ghouls() + return round(bloodsucker_level * 0.5) + +/datum/antagonist/bloodsucker/proc/free_ghoul_slots() + return max(max_ghouls() - length(ghouls), 0) + +/datum/antagonist/bloodsucker/proc/frenzy_enter_threshold() + return FRENZY_THRESHOLD_ENTER + (humanity_lost * 10) + +/datum/antagonist/bloodsucker/proc/frenzy_exit_threshold() + return FRENZY_THRESHOLD_EXIT + (humanity_lost * 10) + +/datum/antagonist/bloodsucker/proc/on_organ_removal(mob/living/carbon/old_owner, obj/item/organ/organ, special) + SIGNAL_HANDLER + if(old_owner?.get_organ_slot(ORGAN_SLOT_HEART) || organ?.slot != ORGAN_SLOT_HEART || !old_owner?.dna?.species.mutantheart) + return + DisableAllPowers(TRUE) + if(HAS_TRAIT_FROM_ONLY(old_owner, TRAIT_NODEATH, BLOODSUCKER_TRAIT)) + torpor_end(TRUE) + to_chat(old_owner, span_userdanger("You have lost your [organ.slot]!")) + to_chat(old_owner, span_warning("This means you will no longer enter torpor nor revive from death, and you will no longer heal any damage, nor can you use your abilities.")) + +/// checks if we're a brainmob inside a brain & the brain is inside a head +/datum/antagonist/bloodsucker/proc/is_head(mob/living/poor_fucker) + if(!istype(poor_fucker?.loc, /obj/item/organ/brain)) + return + var/obj/brain = poor_fucker.loc + if(!istype(brain?.loc, /obj/item/bodypart/head)) + return + return brain.loc + +// helper procs for damage checking, just in case a synth becomes one, let's them heal thesmelves +/datum/antagonist/bloodsucker/proc/get_brute_loss() + var/mob/living/carbon/human/humie = owner.current + return issynthetic(humie) ? humie.get_brute_loss() : humie.get_brute_loss_nonProsthetic() + +/datum/antagonist/bloodsucker/proc/get_fire_loss() + var/mob/living/carbon/human/humie = owner.current + return issynthetic(humie) ? humie.get_fire_loss() : humie.get_fire_loss_nonProsthetic() + +/datum/antagonist/bloodsucker/proc/admin_set_blood(mob/admin) + var/blood = tgui_input_number(admin, "What blood level to set [owner.current]'s to?", "Blood is life.", floor(bloodsucker_blood_volume), max_blood_volume, 0) + // 0 input is falsey + if(blood == null) + return + SetBloodVolume(blood) + +/datum/antagonist/bloodsucker/proc/admin_rankup(mob/admin) + to_chat(admin, span_notice("[owner.current] has been given a free level")) + RankUp() + +/datum/antagonist/bloodsucker/proc/admin_give_power(mob/admin) + var/power_type = tgui_input_list(admin, "What power to give [owner.current]?", "Might is right.", all_bloodsucker_powers) + if(!power_type) + return + var/datum/action/cooldown/bloodsucker/power = BuyPower(power_type) + power.upgrade_power() + +/datum/antagonist/bloodsucker/proc/admin_remove_power(mob/admin) + var/datum/action/cooldown/bloodsucker/power = tgui_input_list(admin, "What power to remove from [owner.current]?", "Might is right.", powers) + if(!power) + return + RemovePower(power) + +/datum/antagonist/bloodsucker/proc/admin_set_power_level(mob/admin) + var/list/valid_powers = list() + for(var/datum/action/cooldown/bloodsucker/power as anything in powers) + if(power.purchase_flags & BLOODSUCKER_DEFAULT_POWER) + continue + valid_powers += power + var/datum/action/cooldown/bloodsucker/power = tgui_input_list(admin, "What power to set the level of for [owner.current]?", "Might is right.", valid_powers) + if(!power) + return + var/level = tgui_input_number(admin, "What level to set [power] to?", "Might is right.", power.level_current, 30, 0) + if(level == null) + return + power.level_current = level + power.on_power_upgrade() + +/datum/antagonist/bloodsucker/proc/regain_heart(mob/living/carbon/target, obj/structure/closet/crate/coffin/coffin) + var/obj/item/organ/heart = locate(/obj/item/organ/heart) in coffin.contents + if(heart && !target.get_organ_slot(ORGAN_SLOT_HEART) && heart.Insert(target)) + to_chat(target, span_warning("You have regained your heart!")) + +/datum/antagonist/bloodsucker/proc/allow_head_to_talk(mob/speaker, message, ignore_spam, forced) + SIGNAL_HANDLER + if(!is_head(speaker) || speaker.stat >= UNCONSCIOUS) + return + return COMPONENT_IGNORE_CAN_SPEAK + +/datum/antagonist/bloodsucker/proc/shake_head_on_talk(mob/speaker, speech_args) + SIGNAL_HANDLER + var/obj/head = is_head(speaker) + if(!head) + return + var/animation_time = max(2, length_char(speech_args[SPEECH_MESSAGE]) * 0.5) + head.Shake(duration = animation_time) + +/datum/antagonist/bloodsucker/proc/stake_can_kill() + if(owner.current.IsSleeping() || owner.current.stat >= UNCONSCIOUS || is_in_torpor()) + for(var/stake in get_stakes()) + var/obj/item/stake/killin_stake = stake + if(killin_stake?.kills_blodsuckers) + return TRUE + return FALSE + +/datum/antagonist/bloodsucker/proc/am_staked() + var/obj/item/bodypart/chosen_bodypart = owner.current.get_bodypart(BODY_ZONE_CHEST) + if(!chosen_bodypart) + return FALSE + var/obj/item/stake/stake = locate() in chosen_bodypart.embedded_objects + return stake + +/datum/antagonist/bloodsucker/proc/get_stakes() + var/obj/item/bodypart/chosen_bodypart = owner.current.get_bodypart(BODY_ZONE_CHEST) + if(!chosen_bodypart) + return FALSE + var/list/stakes = list() + for(var/obj/item/embedded_stake in chosen_bodypart.embedded_objects) + if(istype(embedded_stake, /obj/item/stake)) + stakes += list(embedded_stake) + return stakes + +/datum/antagonist/bloodsucker/proc/on_staked(atom/target, forced) + SIGNAL_HANDLER + if(stake_can_kill()) + FinalDeath() + else + to_chat(target, span_userdanger("You have been staked! Your powers are useless, your death forever, while it remains in place.")) + target.balloon_alert(target, "you have been staked!") + +/// is it something that is close enough to a coffin to let us heal/level up in it? +/datum/antagonist/bloodsucker/proc/is_valid_coffin() + if(istype(owner.current.loc, /obj/structure/closet/crate/coffin)) + return TRUE + // if(istype(owner.current.loc, /obj/structure/closet/crate/grave)) + // return TRUE + return FALSE + +/datum/antagonist/bloodsucker/proc/on_enter_coffin(mob/living/carbon/target, obj/structure/closet/crate/coffin/coffin, mob/living/carbon/user) + SIGNAL_HANDLER + check_limbs(COFFIN_HEAL_COST_MULT) + regain_heart(target, coffin) + if(!check_begin_torpor()) + heal_vampire_organs() + if(user == owner.current && (user in coffin)) + if(can_claim_coffin(coffin, get_area(coffin))) + INVOKE_ASYNC(src, PROC_REF(try_claim_coffin), coffin) + else + INVOKE_ASYNC(src, PROC_REF(try_coffin_level_up)) + +/datum/antagonist/bloodsucker/proc/try_claim_coffin(obj/structure/closet/crate/coffin/coffin) + if(coffin.prompt_coffin_claim(src)) + try_coffin_level_up() + +/datum/antagonist/bloodsucker/proc/try_coffin_level_up() + var/mob/living/carbon/user = owner.current + //Level up if possible. + if(!my_clan) + user.balloon_alert(user, "enter a clan!") + to_chat(user, span_notice("You must enter a Clan to rank up. Do it in the antag menu, which you can see by pressing the action button in the top left.")) + else if(!frenzied) + if(GetUnspentRank() < 1) + blood_level_gain() + // Level ups cost 30% of your max blood volume, which scales with your rank. + SpendRank() + +/datum/antagonist/bloodsucker/proc/on_owner_deletion(mob/living/deleted_mob) + SIGNAL_HANDLER + free_all_ghouls() + if(deleted_mob != owner.current) + return + if(is_head(deleted_mob)) + on_brainmob_qdel() + +/datum/antagonist/bloodsucker/proc/register_body_signals(mob/target) + for(var/signal in body_signals) + RegisterSignal(target, signal, body_signals[signal]) + +/datum/antagonist/bloodsucker/proc/unregister_body_signals(mob/target) + for(var/signal in body_signals) + UnregisterSignal(target, signal) diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/shaded_bloodsucker.dm b/tff_modular/modules/bloodsucker/bloodsuckers/shaded_bloodsucker.dm new file mode 100644 index 00000000000..4f9d905cafa --- /dev/null +++ b/tff_modular/modules/bloodsucker/bloodsuckers/shaded_bloodsucker.dm @@ -0,0 +1,5 @@ +///a malkavian bloodsucker that has entered final death. does nothing, other than signify they are dead + +/obj/item/soulstone/bloodsucker + theme = THEME_WIZARD + required_role = null diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/sol.dm b/tff_modular/modules/bloodsucker/bloodsuckers/sol.dm new file mode 100644 index 00000000000..9e0b15489be --- /dev/null +++ b/tff_modular/modules/bloodsucker/bloodsuckers/sol.dm @@ -0,0 +1,154 @@ +///Legacy name - now refers to the time between free levels for vampires. +#define TIME_BLOODSUCKER_NIGHT 600 + +SUBSYSTEM_DEF(sol) + name = "Sol" + can_fire = FALSE + wait = 20 // ticks, not seconds (so this runs every second, actually) + flags = SS_NO_INIT | SS_BACKGROUND | SS_TICKER | SS_KEEP_TIMING + + ///The time between the next cycle. + var/time_til_cycle = TIME_BLOODSUCKER_NIGHT + ///If Bloodsucker levels for the night has been given out yet. + var/issued_XP = FALSE + +/datum/controller/subsystem/sol/Recover() + can_fire = SSsol.can_fire + time_til_cycle = SSsol.time_til_cycle + issued_XP = SSsol.issued_XP + +/datum/controller/subsystem/sol/fire(resumed = FALSE) + time_til_cycle-- + + if (time_til_cycle > 0 && time_til_cycle <= 15) + if (!issued_XP) + issued_XP = TRUE + SEND_SIGNAL(src, COMSIG_SOL_RANKUP_BLOODSUCKERS) + + if (time_til_cycle < 1) + issued_XP = FALSE + time_til_cycle = TIME_BLOODSUCKER_NIGHT + +#undef TIME_BLOODSUCKER_NIGHT + +/** + * # Assigning Sol + * + * Sol is a legacy name, now simply referring to the system used to give all vampires free levels at the same time. + */ + +/// Start Sol, called when someone is assigned Bloodsucker +/datum/antagonist/bloodsucker/proc/check_start_sunlight() + var/list/existing_suckers = get_antag_minds(/datum/antagonist/bloodsucker) - owner + if(!length(existing_suckers)) + message_admins("New Sol has been created due to Bloodsucker assignment.") + SSsol.can_fire = TRUE + +/// End Sol, if you're the last Bloodsucker +/datum/antagonist/bloodsucker/proc/check_cancel_sunlight() + var/list/existing_suckers = get_antag_minds(/datum/antagonist/bloodsucker) - owner + if(!length(existing_suckers)) + message_admins("Sol has been deleted due to the lack of Bloodsuckers") + SSsol.can_fire = FALSE + +///Ranks the Bloodsucker up, called by Sol. +/datum/antagonist/bloodsucker/proc/sol_rank_up(atom/source) + SIGNAL_HANDLER + + if(sol_levels_remaining > 0) + sol_levels_remaining-- + INVOKE_ASYNC(src, PROC_REF(RankUp)) + +/** + * # Torpor + * + * Torpor is what deals with the Bloodsucker falling asleep, their healing, the effects, ect. + * This is basically what Sol is meant to do to them, but they can also trigger it manually if they wish to heal, as Burn is only healed through Torpor. + * You cannot manually exit Torpor, it is instead entered/exited by: + * + * Torpor is triggered by: + * - Being in a Coffin while Sol is on, dealt with by Sol + * - Entering a Coffin with more than 10 combined Brute/Burn damage, dealt with by /datum/antagonist/bloodsucker/on_enter_coffin() [procs.dm] + * - Death, dealt with by /HandleDeath() + * Torpor is ended by: + * - Having less than maxHealth * 0.8 damage while OUTSIDE of your Coffin while it isnt Sol. + * - Having less than 10 Damage Combined while INSIDE of your Coffin while it isnt Sol. + * - Sol being over, dealt with by /datum/controller/subsystem/processing/sunlight/process() [sol_subsystem.dm] +*/ +/datum/antagonist/bloodsucker/proc/check_begin_torpor(SkipChecks = FALSE) + var/mob/living/carbon/user = owner.current + if(QDELETED(user)) + return + /// Are we entering Torpor via Sol/Death? Then entering it isnt optional! + if(SkipChecks) + torpor_begin() + return + if(user.has_status_effect(/datum/status_effect/frenzy)) + to_chat(user, span_userdanger("You are restless! Collect enough blood to end your frenzy.")) + return + var/total_brute = user.get_brute_loss_nonProsthetic() + var/total_burn = user.get_fire_loss_nonProsthetic() + var/total_damage = total_brute + total_burn + /// Checks - Not daylight & Has more than 10 Brute/Burn & not already in Torpor + if((total_damage >= 10 || length(user.get_missing_limbs()) > 0) && !is_in_torpor()) + torpor_begin() + +/datum/antagonist/bloodsucker/proc/check_end_torpor() + var/mob/living/carbon/user = owner.current + if(QDELETED(user)) + return + var/total_brute = user.get_brute_loss_nonProsthetic() + var/total_burn = user.get_fire_loss_nonProsthetic() + var/total_damage = total_brute + total_burn + if(total_burn >= 199) + return FALSE + + // You are in a Coffin, so instead we'll check TOTAL damage, here. + if(istype(user.loc, /obj/structure/closet/crate/coffin)) + if(total_damage <= 10 && length(user.get_missing_limbs()) == 0) + torpor_end() + else + if(total_brute <= 10) + torpor_end() + //monkestation edit + if(COOLDOWN_FINISHED(src, bloodsucker_torpor_max_time)) + torpor_end() // YOUR TAKING TOO LONG + //monkestation end +/datum/antagonist/bloodsucker/proc/is_in_torpor() + if(QDELETED(owner.current)) + return FALSE + return HAS_TRAIT_FROM(owner.current, TRAIT_NODEATH, TORPOR_TRAIT) + +/datum/antagonist/bloodsucker/proc/torpor_begin() + var/mob/living/current = owner.current + if(QDELETED(current)) + return + to_chat(current, span_notice("You enter the horrible slumber of deathless Torpor. You will heal until you are renewed.")) + // Force them to go to sleep + REMOVE_TRAIT(current, TRAIT_SLEEPIMMUNE, BLOODSUCKER_TRAIT) + // Without this, you'll just keep dying while you recover. + current.add_traits(torpor_traits, TORPOR_TRAIT) + current.set_timed_status_effect(0 SECONDS, /datum/status_effect/jitter, only_if_higher = TRUE) + //monkestation edit + // Failsafe to prevent players taking too long in torpor + COOLDOWN_START(src, bloodsucker_torpor_max_time, BLOODSUCKER_TORPOR_MAX_TIME) + //monkestation end + // Disable ALL Powers + DisableAllPowers() + +/datum/antagonist/bloodsucker/proc/torpor_end() + var/mob/living/current = owner.current + if(QDELETED(current)) + return + + if(!COOLDOWN_FINISHED(src, bloodsucker_torpor_max_time)) + COOLDOWN_RESET(src, bloodsucker_torpor_max_time) + + current.grab_ghost() + to_chat(current, span_warning("You have recovered from Torpor.")) + current.remove_traits(torpor_traits, TORPOR_TRAIT) + if(!HAS_TRAIT(current, TRAIT_MASQUERADE)) + ADD_TRAIT(current, TRAIT_SLEEPIMMUNE, BLOODSUCKER_TRAIT) + heal_vampire_organs() + current.update_stat() + SEND_SIGNAL(src, COMSIG_BLOODSUCKER_EXIT_TORPOR) diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/species.dm b/tff_modular/modules/bloodsucker/bloodsuckers/species.dm new file mode 100644 index 00000000000..7321cd1f1ef --- /dev/null +++ b/tff_modular/modules/bloodsucker/bloodsuckers/species.dm @@ -0,0 +1,84 @@ +/datum/species + var/sort_bottom = FALSE +//Whether or not a given species is sorted to the bottom of the list. We mainly want to do this for species that are used only for ghostroles, and template species. + +/// Called once the target is made into a bloodsucker. Used for removing conflicting species organs mostly +/datum/species/proc/on_bloodsucker_gain(mob/living/carbon/human/target) + return null + +/datum/species/proc/on_bloodsucker_loss(mob/living/carbon/human/target) + return null + +/// Replaces a couple organs to normal variants to not cause issues. Not super happy with this, alternative is disallowing vampiric races from being bloodsuckers +/datum/species/proc/humanize_organs(mob/living/carbon/human/target, organs = list()) + if(!organs || !length(organs)) + organs = list( + ORGAN_SLOT_HEART = /obj/item/organ/heart, + ORGAN_SLOT_LIVER = /obj/item/organ/liver, + ORGAN_SLOT_STOMACH = /obj/item/organ/stomach, + ORGAN_SLOT_TONGUE = /obj/item/organ/tongue, + ) + mutantheart = organs[ORGAN_SLOT_HEART] + mutantliver = organs[ORGAN_SLOT_LIVER] + mutantstomach = organs[ORGAN_SLOT_STOMACH] + mutanttongue = organs[ORGAN_SLOT_TONGUE] + for(var/organ_slot in organs) + var/obj/item/organ/old_organ = target.get_organ_slot(organ_slot) + var/organ_path = organs[organ_slot] + if(old_organ?.type == organ_path) + continue + var/obj/item/organ/new_organ = SSwardrobe.provide_type(organ_path) + new_organ.Insert(target, FALSE, DELETE_IF_REPLACED) + +/datum/species/proc/normalize_organs(mob/living/carbon/human/target) + mutantheart = initial(mutantheart) + mutantliver = initial(mutantliver) + mutantstomach = initial(mutantstomach) + mutanttongue = initial(mutanttongue) + regenerate_organs(target, replace_current = TRUE) + + +/datum/species/get_species_description() + SHOULD_CALL_PARENT(FALSE) + + //stack_trace("Species [name] ([type]) did not have a description set, and is a selectable roundstart race! Override get_species_description.") + return list("No species description set, file a bug report!",) + +/datum/language/vampiric + name = "Enochian" + desc = "Rumored to be created by the Dark Father, Caine himself as a way to talk to his Childer, the truth, like many things in unlife is uncertain. Spoken by creatures of the night." + key = "L"//Capital L, lowercase l is for ashies. + space_chance = 40 + default_priority = 90 + + flags = TONGUELESS_SPEECH | LANGUAGE_HIDE_ICON_IF_NOT_UNDERSTOOD + syllables = list( + "luk","cha","no","kra","pru","chi","busi","tam","pol","spu","och", + "umf","ora","stu","si","ri","li","ka","red","ani","lup","ala","pro", + "to","siz","nu","pra","ga","ump","ort","a","ya","yach","tu","lit", + "wa","mabo","mati","anta","tat","tana","prol", + "tsa","si","tra","te","ele","fa","inz", + "nza","est","sti","ra","pral","tsu","ago","esch","chi","kys","praz", + "froz","etz","tzil", + "t'","k'","t'","k'","th'","tz'" + ) + + icon_state = "bloodsucker" + icon = 'tff_modular/modules/bloodsucker/icons/language.dmi' + secret = TRUE + +// second fallback just in case the map is missing both the curator display case and codex gigas +/datum/job/curator/after_spawn(mob/living/spawned, client/player_client) + mind_traits += (TRAIT_BLOODSUCKER_HUNTER) + . = ..() + var/list/points_of_interest = SSpoints_of_interest.get_other_pois() + var/obj/item/book/kindred/book_to_spawn + for(var/poi in points_of_interest) + var/thing = points_of_interest[poi] + if(istype(thing, /obj/item/book/kindred)) + return + book_to_spawn = new(get_turf(spawned)) + if(iscarbon(spawned)) + var/mob/living/carbon/carbon_spawned = spawned + // Not suspicious but convenient in this case + carbon_spawned.equip_conspicuous_item(book_to_spawn, FALSE) diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/trauma.dm b/tff_modular/modules/bloodsucker/bloodsuckers/trauma.dm new file mode 100644 index 00000000000..82353a1dd8d --- /dev/null +++ b/tff_modular/modules/bloodsucker/bloodsuckers/trauma.dm @@ -0,0 +1,169 @@ +/** + * # Phobetor Brain Trauma + * + * Beefmen's Brain trauma, causing phobetor tears to traverse through. + */ + +/datum/brain_trauma/special/bluespace_prophet/phobetor + name = "Sleepless Dreamer" + desc = "The patient, after undergoing untold psychological hardship, believes they can travel between the dreamscapes of this dimension." + scan_desc = "awoken sleeper" + gain_text = "Your mind snaps, and you wake up. You really wake up." + lose_text = "You succumb once more to the sleepless dream of the unwoken." + + ///Created tears, only checking the FIRST one, not the one it's created to link to. + var/list/created_firsts = list() + +///When the trauma is removed from a mob. +/datum/brain_trauma/special/bluespace_prophet/phobetor/on_lose(silent) + . = ..() + for(var/obj/effect/client_image_holder/phobetor/phobetor_tears as anything in created_firsts) + qdel(phobetor_tears) + +/datum/brain_trauma/special/bluespace_prophet/phobetor/on_life(seconds_per_tick, times_fired) + if(!COOLDOWN_FINISHED(src, portal_cooldown)) + return + COOLDOWN_START(src, portal_cooldown, 10 SECONDS) + var/list/turf/possible_tears = list() + for(var/turf/nearby_turfs as anything in RANGE_TURFS(8, owner)) + if(nearby_turfs.density) + continue + possible_tears += nearby_turfs + if(!LAZYLEN(possible_tears)) + return + + var/turf/first_tear + var/turf/second_tear + first_tear = return_valid_floor_in_range(owner, 6, 0, TRUE) + if(!first_tear) + return + second_tear = return_valid_floor_in_range(first_tear, 20, 6, TRUE) + if(!second_tear) + return + + var/obj/effect/client_image_holder/phobetor/first = new(first_tear, owner) + var/obj/effect/client_image_holder/phobetor/second = new(second_tear, owner) + + first.linked_to = second + first.seer = owner + first.desc += " This one leads to [get_area(second)]." + first.name += " ([get_area(second)])" + created_firsts += first + + second.linked_to = first + second.seer = owner + second.desc += " This one leads to [get_area(first)]." + second.name += " ([get_area(first)])" + + // Delete Next Portal if it's time (it will remove its partner) + var/obj/effect/client_image_holder/phobetor/first_on_the_stack = created_firsts[1] + if(created_firsts.len && world.time >= first_on_the_stack.created_on + first_on_the_stack.exist_length) + var/targetGate = first_on_the_stack + created_firsts -= targetGate + qdel(targetGate) + +/datum/brain_trauma/special/bluespace_prophet/phobetor/proc/return_valid_floor_in_range(atom/targeted_atom, checkRange = 8, minRange = 0, check_floor = TRUE) + // FAIL: Atom doesn't exist. Aren't you real? + if(!istype(targeted_atom)) + return FALSE + var/delta_x = rand(minRange,checkRange)*pick(-1,1) + var/delta_y = rand(minRange,checkRange)*pick(-1,1) + var/turf/center = get_turf(targeted_atom) + + var/target = locate((center.x + delta_x),(center.y + delta_y), center.z) + if(check_turf_is_valid(target, check_floor)) + return target + return FALSE + +/** + * Used as a helper that checks if you can successfully teleport to a turf. + * Returns a boolean, and checks for if the turf has density, if the turf's area has the NOTELEPORT flag, + * and if the objects in the turf have density. + * If check_floor is TRUE in the argument, it will return FALSE if it's not a type of [/turf/open/floor]. + * Arguments: + * * turf/open_turf - The turf being checked for validity. + * * check_floor - Checks if it's a type of [/turf/open/floor]. If this is FALSE, lava/chasms will be able to be selected. + */ +/datum/brain_trauma/special/bluespace_prophet/phobetor/proc/check_turf_is_valid(turf/open_turf, check_floor = TRUE) + if(check_floor && !istype(open_turf, /turf/open/floor)) + return FALSE + if(open_turf.density) + return FALSE + var/area/turf_area = get_area(open_turf) + if(turf_area.area_flags & NOTELEPORT) + return FALSE + // Checking for Objects... + for(var/obj/object in open_turf) + if(object.density) + return FALSE + return TRUE + +/** + * # Phobetor Tears + * + * The phobetor tears created by the Brain trauma. + */ + +/obj/effect/client_image_holder/phobetor + name = "phobetor tear" + desc = "A subdimensional rip in reality, which gives extra-spacial passage to those who have woken from the sleepless dream." + image_icon = 'tff_modular/modules/bloodsucker/icons/phobetor_tear.dmi' + image_state = "phobetor_tear" + // Place this above shadows so it always glows. + image_layer = ABOVE_MOB_LAYER + + /// How long this will exist for + var/exist_length = 50 SECONDS + /// The time of this tear's creation + var/created_on + /// The phobetor tear this is linked to + var/obj/effect/client_image_holder/phobetor/linked_to + /// The person able to see this tear. + var/mob/living/carbon/seer + +/obj/effect/client_image_holder/phobetor/Initialize(mapload) + . = ..() + created_on = world.time + +/obj/effect/client_image_holder/phobetor/Destroy() + if(linked_to) + linked_to.linked_to = null + QDEL_NULL(linked_to) + return ..() + +/obj/effect/client_image_holder/phobetor/proc/check_location_seen(atom/subject, turf/target_turf) + if(!target_turf) + return FALSE + if(!isturf(target_turf)) + return FALSE + if(!target_turf.lighting_object || !target_turf.get_lumcount() >= 0.1) + return FALSE + for(var/mob/living/nearby_viewers in viewers(target_turf)) + if(nearby_viewers == subject) + continue + if(!isliving(nearby_viewers) || !nearby_viewers.mind) + continue + if(nearby_viewers.is_blind()) + continue + return TRUE + return FALSE + +/obj/effect/client_image_holder/phobetor/attack_hand(mob/living/user, list/modifiers) + if(user != seer || !linked_to) + return + if(user.loc != src.loc) + to_chat(user, "Step into the Tear before using it.") + return + for(var/obj/item/implant/tracking/imp in user.implants) + to_chat(user, span_warning("[imp] gives you the sense that you're being watched.")) + return + // Is this, or linked, stream being watched? + if(check_location_seen(user, get_turf(user))) + to_chat(user, span_warning("Not while you're being watched.")) + return + if(check_location_seen(user, get_turf(linked_to))) + to_chat(user, span_warning("Your destination is being watched.")) + return + to_chat(user, span_notice("You slip unseen through [src].")) + user.playsound_local(null, 'sound/effects/magic/wand_teleport.ogg', 30, FALSE, pressure_affected = FALSE) + user.forceMove(get_turf(linked_to)) diff --git a/tff_modular/modules/bloodsucker/clans/clan.dm b/tff_modular/modules/bloodsucker/clans/clan.dm new file mode 100644 index 00000000000..e7e4ab5aaba --- /dev/null +++ b/tff_modular/modules/bloodsucker/clans/clan.dm @@ -0,0 +1,339 @@ +/** + * Bloodsucker clans + * + * Handles everything related to clans. + * the entire idea of datumizing this came to me in a dream. + */ +/datum/bloodsucker_clan + ///The bloodsucker datum that owns this clan. Use this over 'source', because while it's the same thing, this is more consistent (and used for deletion). + var/datum/antagonist/bloodsucker/bloodsuckerdatum + ///The name of the clan we're in. + var/name = CLAN_NONE + ///Description of what the clan is, given when joining and through your antag UI. + var/description = "The Caitiff is as basic as you can get with Bloodsuckers. \n\ + Entirely without the help of a formal Clan, they are blissfully unaware of who they really are. \n\ + No additional abilities is gained, nothing is lost, if you want a plain Bloodsucker, this is it. \n\ + The Favorite Ghoul will gain the Brawn ability, to help in combat." + ///The clan objective that is required to greentext. + var/datum/objective/bloodsucker/clan_objective + ///The icon of the radial icon to join this clan. + var/join_icon = 'tff_modular/modules/bloodsucker/icons/clan_icons.dmi' + ///Same as join_icon, but the state + var/join_icon_state = "caitiff" + ///Description shown when trying to join the clan. + var/join_description = "The default, Classic Bloodsucker." + ///Whether the clan can be joined by players. FALSE for flavortext-only clans. + var/joinable_clan = TRUE + + ///How we will drink blood using Feed. + var/blood_drink_type = BLOODSUCKER_DRINK_NORMAL + /// How much stamina armor we get in frenzy + var/frenzy_stamina_mod = 0.4 + var/buy_power_flags = BLOODSUCKER_CAN_BUY + // what percentage of blood you need to spend to level up, divided by 100 + var/level_cost = BLOODSUCKER_LEVELUP_PERCENTAGE + +// TODO add handling for body transfers +/datum/bloodsucker_clan/New(datum/antagonist/bloodsucker/owner_datum) + . = ..() + src.bloodsuckerdatum = owner_datum + + RegisterSignal(bloodsuckerdatum, COMSIG_BLOODSUCKER_ON_LIFETICK, PROC_REF(handle_clan_life)) + RegisterSignal(bloodsuckerdatum, COMSIG_BLOODSUCKER_RANK_UP, PROC_REF(on_spend_rank)) + + RegisterSignal(bloodsuckerdatum, COMSIG_BLOODSUCKER_INTERACT_WITH_GHOUL, PROC_REF(on_interact_with_ghoul)) + RegisterSignal(bloodsuckerdatum, COMSIG_BLOODSUCKER_MAKE_FAVORITE, PROC_REF(favorite_ghoul_gain)) + RegisterSignal(bloodsuckerdatum, COMSIG_BLOODSUCKER_LOOSE_FAVORITE, PROC_REF(favorite_ghoul_loss)) + + RegisterSignal(bloodsuckerdatum, COMSIG_BLOODSUCKER_MADE_GHOUL, PROC_REF(on_ghoul_made)) + RegisterSignal(bloodsuckerdatum, COMSIG_BLOODSUCKER_EXIT_TORPOR, PROC_REF(on_exit_torpor)) + RegisterSignal(bloodsuckerdatum, COMSIG_BLOODSUCKER_FINAL_DEATH, PROC_REF(on_final_death)) + + RegisterSignal(bloodsuckerdatum, COMSIG_BLOODSUCKER_ENTERS_FRENZY, PROC_REF(on_enter_frenzy)) + RegisterSignal(bloodsuckerdatum, COMSIG_BLOODSUCKER_EXITS_FRENZY, PROC_REF(on_exit_frenzy)) + + give_clan_objective() + +/datum/bloodsucker_clan/Destroy(force) + UnregisterSignal(bloodsuckerdatum, list( + COMSIG_BLOODSUCKER_ON_LIFETICK, + COMSIG_BLOODSUCKER_RANK_UP, + COMSIG_BLOODSUCKER_INTERACT_WITH_GHOUL, + COMSIG_BLOODSUCKER_MAKE_FAVORITE, + COMSIG_BLOODSUCKER_MADE_GHOUL, + COMSIG_BLOODSUCKER_EXIT_TORPOR, + COMSIG_BLOODSUCKER_FINAL_DEATH, + COMSIG_BLOODSUCKER_ENTERS_FRENZY, + COMSIG_BLOODSUCKER_EXITS_FRENZY, + )) + remove_clan_objective() + bloodsuckerdatum = null + return ..() + +/datum/bloodsucker_clan/proc/on_enter_frenzy(datum/antagonist/bloodsucker/source) + SIGNAL_HANDLER + var/mob/living/carbon/human/human_bloodsucker = bloodsuckerdatum.owner.current + if(!istype(human_bloodsucker)) + return + human_bloodsucker.physiology.stamina_mod *= frenzy_stamina_mod + +/datum/bloodsucker_clan/proc/on_exit_frenzy(datum/antagonist/bloodsucker/source) + SIGNAL_HANDLER + var/mob/living/carbon/human/human_bloodsucker = bloodsuckerdatum.owner.current + if(!istype(human_bloodsucker)) + return + human_bloodsucker.set_timed_status_effect(3 SECONDS, /datum/status_effect/dizziness, only_if_higher = TRUE) + human_bloodsucker.Paralyze(2 SECONDS) + human_bloodsucker.physiology.stamina_mod /= frenzy_stamina_mod + +/datum/bloodsucker_clan/proc/give_clan_objective() + if(isnull(clan_objective)) + return + clan_objective = new clan_objective() + clan_objective.objective_name = "Clan Objective" + clan_objective.owner = bloodsuckerdatum.owner + bloodsuckerdatum.objectives += clan_objective + bloodsuckerdatum.owner.announce_objectives() + +/datum/bloodsucker_clan/proc/remove_clan_objective() + bloodsuckerdatum.objectives -= clan_objective + QDEL_NULL(clan_objective) + bloodsuckerdatum.owner.announce_objectives() + +/** + * Called when a Bloodsucker exits Torpor + * args: + * source - the Bloodsucker exiting Torpor + */ +/datum/bloodsucker_clan/proc/on_exit_torpor(datum/antagonist/bloodsucker/source) + SIGNAL_HANDLER + +/** + * Called when a Bloodsucker enters Final Death + * args: + * source - the Bloodsucker exiting Torpor + */ +/datum/bloodsucker_clan/proc/on_final_death(datum/antagonist/bloodsucker/source) + SIGNAL_HANDLER + return FALSE + +/** + * Called during Bloodsucker's LifeTick + * args: + * bloodsuckerdatum - the antagonist datum of the Bloodsucker running this. + */ +/datum/bloodsucker_clan/proc/handle_clan_life(datum/antagonist/bloodsucker/source, seconds_per_tick, times_fired) + SIGNAL_HANDLER + +/** + * Called when a Bloodsucker successfully Ghoulizes someone. + * args: + * bloodsuckerdatum - the antagonist datum of the Bloodsucker running this. + */ +/datum/bloodsucker_clan/proc/on_ghoul_made(datum/antagonist/bloodsucker/source, mob/living/user, mob/living/target) + SIGNAL_HANDLER + user.playsound_local(null, 'sound/effects/explosion/explosion_distant.ogg', 40, TRUE) + target.playsound_local(null, 'sound/effects/singlebeat.ogg', 40, TRUE) + target.set_timed_status_effect(15 SECONDS, /datum/status_effect/jitter, only_if_higher = TRUE) + INVOKE_ASYNC(target, TYPE_PROC_REF(/mob, emote), "laugh") + +/** + * Called when a Bloodsucker successfully starts spending their Rank + * args: + * bloodsuckerdatum - the antagonist datum of the Bloodsucker running this. + * target - The Ghoul (if any) we are upgrading. + * cost_rank - TRUE/FALSE on whether this will cost us a rank when we go through with it. + * blood_cost - A number saying how much it costs to rank up. + */ +/datum/bloodsucker_clan/proc/on_spend_rank(datum/antagonist/bloodsucker/source, mob/living/carbon/human/target, cost_rank = TRUE, blood_cost, force) + SIGNAL_HANDLER + + INVOKE_ASYNC(src, PROC_REF(spend_rank), bloodsuckerdatum, cost_rank, blood_cost) + +/datum/bloodsucker_clan/proc/spend_rank(datum/antagonist/bloodsucker/source, cost_rank = TRUE, blood_cost, requires_coffin = TRUE) + var/list/options = list_available_powers() + if(length(options)) + var/datum/action/cooldown/bloodsucker/choice = choose_powers( + "You have the opportunity to grow more ancient. [blood_cost > 0 ? " Spend [round(blood_cost, 1)] blood to advance your rank" : ""]", + "Your Blood Thickens...", + options + ) + if(!is_valid_choice(choice, cost_rank, blood_cost, requires_coffin)) + return FALSE + // Good to go - Buy Power! + purchase_choice(source, choice) + level_message(initial(choice.name)) + + return finalize_spend_rank(bloodsuckerdatum, cost_rank, blood_cost) + +/datum/bloodsucker_clan/proc/level_message(power_name) + var/mob/living/carbon/human/human_user = bloodsuckerdatum.owner.current + human_user.balloon_alert(human_user, "learned [power_name]!") + to_chat(human_user, span_notice("You have learned how to use [power_name]!")) + +/datum/bloodsucker_clan/proc/choose_powers(message, title, options = list()) + var/mob/living/carbon/human/human_user = bloodsuckerdatum.owner.current + if(!length(options)) + return FALSE + + var/choice = tgui_input_list(human_user, message, title, options) + return options[choice] + +/datum/bloodsucker_clan/proc/is_valid_choice(datum/action/cooldown/bloodsucker/power, cost_rank, blood_cost, requires_coffin) + var/mob/living/carbon/human/human_user = bloodsuckerdatum.owner.current + if(!power) + return FALSE + if(cost_rank && bloodsuckerdatum.GetUnspentRank() <= 0) + return FALSE + if(blood_cost && bloodsuckerdatum.GetBloodVolume() < blood_cost) + human_user.balloon_alert(human_user, "not enough blood!") + to_chat(human_user, span_notice("You need at the very least [blood_cost] blood to thicken your blood.")) + return FALSE + // Prevent Bloodsuckers from purchasing a power while outside of their Coffin. + if(requires_coffin && !istype(human_user.loc, /obj/structure/closet/crate/coffin)) + to_chat(human_user, span_warning("You must be in your Coffin to purchase Powers.")) + return FALSE + if(!(initial(power.purchase_flags) & buy_power_flags)) + to_chat(human_user, span_notice("[initial(power.name)] is not available for purchase.")) + return FALSE + if(!(buy_power_flags & CAN_BUY_OWNED) && locate(power) in bloodsuckerdatum.powers) + to_chat(human_user, span_notice("You already know [initial(power.name)]!")) + return FALSE + return TRUE + +/datum/bloodsucker_clan/proc/finalize_spend_rank(datum/antagonist/bloodsucker/source, cost_rank = TRUE, blood_cost) + level_up_powers(source) + bloodsuckerdatum.bloodsucker_regen_rate += 0.05 + bloodsuckerdatum.max_blood_volume += 100 + + if(ishuman(bloodsuckerdatum.owner.current)) + var/mob/living/carbon/human/human_user = bloodsuckerdatum.owner.current + var/obj/item/bodypart/user_left_hand = human_user.get_bodypart(BODY_ZONE_L_ARM) + var/obj/item/bodypart/user_right_hand = human_user.get_bodypart(BODY_ZONE_R_ARM) + user_left_hand.unarmed_damage_low += 0.5 + user_right_hand.unarmed_damage_low += 0.5 + // This affects the hitting power of Brawn. + user_left_hand.unarmed_damage_high += 0.5 + user_right_hand.unarmed_damage_high += 0.5 + + // We're almost done - Spend your Rank now. + bloodsuckerdatum.AdjustRank(1) + if(cost_rank) + bloodsuckerdatum.AdjustUnspentRank(-1) + + if(blood_cost) + bloodsuckerdatum.AdjustBloodVolume(-blood_cost) + + // Ranked up enough to get your true Reputation? + if(bloodsuckerdatum.GetRank() == BLOODSUCKER_HIGH_LEVEL) + bloodsuckerdatum.SelectReputation(am_fledgling = FALSE, forced = TRUE) + + + to_chat(bloodsuckerdatum.owner.current, span_notice("You are now a rank [bloodsuckerdatum.GetRank()] Bloodsucker. \ + Your strength, feed rate, regen rate, and maximum blood capacity have all increased! \n\ + * Your existing powers have all ranked up as well!")) + bloodsuckerdatum.owner.current.playsound_local(null, 'sound/effects/pope_entry.ogg', 25, TRUE, pressure_affected = FALSE) + bloodsuckerdatum.update_static_data_for_all_viewers() + + // unlock ghoulizing if we have a ghoul slot + if(bloodsuckerdatum.max_ghouls() >= 1 && !(/datum/crafting_recipe/ghoulrack in bloodsuckerdatum.owner?.learned_recipes)) + bloodsuckerdatum.owner.teach_crafting_recipe(/datum/crafting_recipe/ghoulrack) + bloodsuckerdatum.owner.teach_crafting_recipe(/datum/crafting_recipe/candelabrum) + bloodsuckerdatum.owner.teach_crafting_recipe(/datum/crafting_recipe/bloodthrone) + bloodsuckerdatum.owner.teach_crafting_recipe(/datum/crafting_recipe/meatcoffin) + bloodsuckerdatum.owner.current.balloon_alert(bloodsuckerdatum.owner.current, "new recipes learned! Ghouling unlocked!") + return TRUE + + +/datum/bloodsucker_clan/proc/list_available_powers(already_known = bloodsuckerdatum.powers, powers_list = bloodsuckerdatum.all_bloodsucker_powers) + var/list/options = list() + for(var/datum/action/cooldown/bloodsucker/power as anything in powers_list) + if(initial(power.purchase_flags) & buy_power_flags && !(locate(power) in already_known)) + options[initial(power.name)] = power + return options + +/datum/bloodsucker_clan/proc/purchase_choice(datum/antagonist/bloodsucker/source, datum/action/cooldown/bloodsucker/purchased_power) + return bloodsuckerdatum.BuyPower(purchased_power) + +/datum/bloodsucker_clan/proc/level_up_powers(datum/antagonist/bloodsucker/source) + bloodsuckerdatum.LevelUpPowers() +/** + * Called when we are trying to turn someone into a Favorite Ghoul + * args: + * bloodsuckerdatum - the antagonist datum of the Bloodsucker performing this. + * ghouldatum - the antagonist datum of the Ghoul being offered up. + */ +/datum/bloodsucker_clan/proc/on_interact_with_ghoul(datum/antagonist/bloodsucker/source, datum/antagonist/ghoul/ghouldatum) + SIGNAL_HANDLER + + INVOKE_ASYNC(src, PROC_REF(interact_with_ghoul), bloodsuckerdatum, ghouldatum) + +/datum/bloodsucker_clan/proc/interact_with_ghoul(datum/antagonist/bloodsucker/source, datum/antagonist/ghoul/ghouldatum) + var/mob/living/carbon/human/master = bloodsuckerdatum.owner.current + var/mob/living/carbon/human/servant = ghouldatum.owner.current + if(ghouldatum.special_type || IS_BLOODSUCKER(servant)) + to_chat(master, span_notice("This Ghoul was already assigned a special position.")) + return FALSE + if(!ghouldatum.owner.can_make_special(creator = bloodsuckerdatum.owner)) + to_chat(master, span_notice("This Ghoul is unable to gain a Special rank due to innate features.")) + return FALSE + if(bloodsuckerdatum.GetBloodVolume() < SPECIAL_GHOUL_COST) + to_chat(master, span_notice("You need at least 150 blood to make a Ghoul a Favorite Ghoul.")) + return FALSE + var/list/options = list() + var/list/radial_display = list() + for(var/datum/antagonist/ghoul/ghouldatums as anything in subtypesof(/datum/antagonist/ghoul)) + var/ghoul_type = initial(ghouldatums.special_type) + var/slot = bloodsuckerdatum.special_ghouls[ghoul_type] + if(ghoul_type && slot) + continue + options[initial(ghouldatums.name)] = ghouldatums + + var/datum/radial_menu_choice/option = new + option.image = image(icon = initial(ghouldatums.hud_icon), icon_state = initial(ghouldatums.antag_hud_name), pixel_y = -12, pixel_x = -12) + option.info = "[initial(ghouldatums.name)] - [span_boldnotice(initial(ghouldatums.ghoul_description))]" + radial_display[initial(ghouldatums.name)] = option + if(!length(options)) + master.balloon_alert(master, "out of Special Ghoul slots!") + return FALSE + + to_chat(master, span_notice("You can change who this Ghoul is, who are they to you? This will cost [SPECIAL_GHOUL_COST] blood.")) + var/ghoul_response = show_radial_menu(master, servant, radial_display) + if(!ghoul_response || !is_valid_ghoul(options[ghoul_response])) + return FALSE + var/datum/antagonist/ghoul/ghoul_type = options[ghoul_response] + + // let's ask if the ghoul themselves actually wants to be a favorite +#ifndef BLOODSUCKER_TESTING + servant.balloon_alert(master, "asking...") + var/ghoul_permission = tgui_alert(servant, initial(ghoul_type.ghoul_description), "Become a Special Ghoul?", list("Yes", "No"), 1 MINUTES) == "Yes" + if(!ghoul_permission) + servant.balloon_alert(master, "refused!") + return FALSE +#endif + if(QDELETED(src) || QDELETED(master) || QDELETED(servant) || !ghoul_type) + return FALSE + + if(bloodsuckerdatum.GetBloodVolume() < SPECIAL_GHOUL_COST) + to_chat(master, span_notice("You took too long to make your ghoul, you no longer have enough blood!")) + return FALSE + ghouldatum.make_special(ghoul_type) + bloodsuckerdatum.AdjustBloodVolume(-SPECIAL_GHOUL_COST) + return TRUE + +/datum/bloodsucker_clan/proc/is_valid_ghoul(datum/antagonist/ghoul/ghoul_type) + if(!ghoul_type) + return FALSE + return TRUE +/** + * Called when we are successfully turn a Ghoul into a Favorite Ghoul + * args: + * bloodsuckerdatum - antagonist datum of the Bloodsucker who turned them into a Ghoul. + * ghouldatum - the antagonist datum of the Ghoul being offered up. + */ +/datum/bloodsucker_clan/proc/favorite_ghoul_gain(datum/antagonist/bloodsucker/source, datum/antagonist/ghoul/ghouldatum) + SIGNAL_HANDLER + ghouldatum.BuyPower(/datum/action/cooldown/bloodsucker/targeted/brawn) + +/datum/bloodsucker_clan/proc/favorite_ghoul_loss(datum/antagonist/bloodsucker/source, datum/antagonist/ghoul/ghouldatum) + SIGNAL_HANDLER diff --git a/tff_modular/modules/bloodsucker/clans/clan_flavortext.dm b/tff_modular/modules/bloodsucker/clans/clan_flavortext.dm new file mode 100644 index 00000000000..b55cfce68ce --- /dev/null +++ b/tff_modular/modules/bloodsucker/clans/clan_flavortext.dm @@ -0,0 +1,47 @@ +/datum/bloodsucker_clan/gangrel + name = CLAN_GANGREL + description = "Closer to Animals than Bloodsuckers, known as Werewolves waiting to happen, \n\ + these are the most fearful of True Faith, being the most lethal thing they would ever see the night of. \n\ + Full Moons do not seem to have an effect, despite common-told stories. \n\ + The Favorite Ghoul turns into a Werewolf whenever their Master does." + joinable_clan = FALSE + blood_drink_type = BLOODSUCKER_DRINK_INHUMANELY + +/datum/bloodsucker_clan/gangrel/on_enter_frenzy(datum/antagonist/bloodsucker/source) + ADD_TRAIT(bloodsuckerdatum.owner.current, TRAIT_STUNIMMUNE, FRENZY_TRAIT) + +/datum/bloodsucker_clan/gangrel/on_exit_frenzy(datum/antagonist/bloodsucker/source) + REMOVE_TRAIT(bloodsuckerdatum.owner.current, TRAIT_STUNIMMUNE, FRENZY_TRAIT) + +/datum/bloodsucker_clan/gangrel/handle_clan_life(datum/antagonist/bloodsucker/source, seconds_per_tick, times_fired) + . = ..() + var/area/current_area = get_area(bloodsuckerdatum.owner.current) + if(istype(current_area, /area/station/service/chapel)) + to_chat(bloodsuckerdatum.owner.current, span_warning("You don't belong in holy areas! The Faith burns you to a crisp!")) + bloodsuckerdatum.owner.current.adjust_fire_loss(20) + bloodsuckerdatum.owner.current.adjust_fire_stacks(2) + bloodsuckerdatum.owner.current.ignite_mob() + +/datum/bloodsucker_clan/toreador + name = CLAN_TOREADOR + description = "The most charming Clan of them all, allowing them to very easily disguise among the crew. \n\ + More in touch with their morals, they suffer and benefit more strongly from humanity cost or gain of their actions. \n\ + Known as 'The most humane kind of vampire', they have an obsession with perfectionism and beauty \n\ + The Favorite Ghoul gains the Mesmerize ability." + joinable_clan = FALSE + blood_drink_type = BLOODSUCKER_DRINK_SNOBBY + +/datum/bloodsucker_clan/brujah + name = CLAN_BRUJAH + description = "The Brujah Clan has proven to be the strongest in melee combat, boasting a powerful punch. \n\ + They also appear to be more calm than the others, entering their 'frenzies' whenever they want, but dont seem affected much by them. \n\ + Be wary, as they are fearsome warriors, rebels and anarchists, with an inclination towards Frenzy. \n\ + The Favorite Ghoul gains brawn and a massive increase in brute damage from punching." + joinable_clan = FALSE + +/datum/bloodsucker_clan/tzimisce + name = CLAN_TZIMISCE + description = "The Tzimisce Clan has no knowledge about it. \n\ + If you see one, you should probably run away.\n\ + *the rest of the page is full of undecipherable scribbles...*" + joinable_clan = FALSE diff --git a/tff_modular/modules/bloodsucker/clans/clan_malkavian.dm b/tff_modular/modules/bloodsucker/clans/clan_malkavian.dm new file mode 100644 index 00000000000..ff2f4a0ae22 --- /dev/null +++ b/tff_modular/modules/bloodsucker/clans/clan_malkavian.dm @@ -0,0 +1,100 @@ +/datum/bloodsucker_clan/malkavian + name = CLAN_MALKAVIAN + description = "Little is documented about Malkavians. Complete insanity is the most common theme. \n\ + The Favorite Ghoul will suffer the same fate as the Master, while gaining the ability to tap into the madness when fighting." + join_icon_state = "malkavian" + join_description = "Completely insane. You gain constant hallucinations, become a prophet with unintelligable rambling, \ + and become the enforcer of the Masquerade code." + blood_drink_type = BLOODSUCKER_DRINK_INHUMANELY + /// The prob chance of a malkavian spouting a revelation. + var/max_madness_chance = 10 + var/min_madness_chance = 5 + +/datum/bloodsucker_clan/malkavian/on_enter_frenzy(datum/antagonist/bloodsucker/source) + ADD_TRAIT(bloodsuckerdatum.owner.current, TRAIT_STUNIMMUNE, FRENZY_TRAIT) + +/datum/bloodsucker_clan/malkavian/on_exit_frenzy(datum/antagonist/bloodsucker/source) + REMOVE_TRAIT(bloodsuckerdatum.owner.current, TRAIT_STUNIMMUNE, FRENZY_TRAIT) + +/datum/bloodsucker_clan/malkavian/New(datum/antagonist/bloodsucker/owner_datum) + . = ..() + RegisterSignal(SSdcs, COMSIG_BLOODSUCKER_BROKE_MASQUERADE, PROC_REF(on_bloodsucker_broke_masquerade)) + ADD_TRAIT(bloodsuckerdatum.owner.current, TRAIT_XRAY_VISION, BLOODSUCKER_TRAIT) + var/mob/living/carbon/carbon_owner = bloodsuckerdatum.owner.current + if(istype(carbon_owner)) + carbon_owner.gain_trauma(/datum/brain_trauma/mild/hallucinations, TRAUMA_RESILIENCE_ABSOLUTE) + carbon_owner.gain_trauma(/datum/brain_trauma/special/bluespace_prophet, TRAUMA_RESILIENCE_ABSOLUTE) + owner_datum.owner.current.update_sight() + + bloodsuckerdatum.owner.current.playsound_local(get_turf(bloodsuckerdatum.owner.current), 'sound/music/antag/creepalert.ogg', 80, FALSE, pressure_affected = FALSE, use_reverb = FALSE) + to_chat(bloodsuckerdatum.owner.current, span_hypnophrase("Welcome to the Malkavian...")) + +/datum/bloodsucker_clan/malkavian/Destroy(force) + UnregisterSignal(SSdcs, COMSIG_BLOODSUCKER_BROKE_MASQUERADE) + REMOVE_TRAIT(bloodsuckerdatum.owner.current, TRAIT_XRAY_VISION, BLOODSUCKER_TRAIT) + var/mob/living/carbon/carbon_owner = bloodsuckerdatum.owner.current + if(istype(carbon_owner)) + carbon_owner.cure_trauma_type(/datum/brain_trauma/mild/hallucinations, TRAUMA_RESILIENCE_ABSOLUTE) + carbon_owner.cure_trauma_type(/datum/brain_trauma/special/bluespace_prophet, TRAUMA_RESILIENCE_ABSOLUTE) + bloodsuckerdatum.owner.current.update_sight() + return ..() + +/datum/bloodsucker_clan/malkavian/handle_clan_life(datum/antagonist/bloodsucker/source, seconds_per_tick, times_fired) + . = ..() + // Using linear interpolation to calculate the chance of a revelation. The more humanity lost, the higher the chance. + // This is the reversed version since we want to increase the prob as the number decreases. + // Equation: interpolated value = end + normalized factor * (start - end) + // normalized factor(between 0 and 1, in decimals) + var/humanity_lost_modifier = source.GetHumanityLost() / 50 + if(humanity_lost_modifier == 0) + // 0 * anything = 0, this makes having 0 humanity not max out the chance. + humanity_lost_modifier = 1 + var/interpolated_chance = max_madness_chance + humanity_lost_modifier * (min_madness_chance - max_madness_chance) + var/madness_chance = clamp(interpolated_chance, min_madness_chance, max_madness_chance) + if(!prob(madness_chance) || source.owner.current.stat != CONSCIOUS || HAS_TRAIT(source.owner.current, TRAIT_MASQUERADE)) + return + var/message = pick(strings("malkavian_revelations.json", "revelations", "tff_modular/strings/bloodsuckers")) + INVOKE_ASYNC(source.owner.current, TYPE_PROC_REF(/atom/movable, say), message, forced = CLAN_MALKAVIAN) + +/datum/bloodsucker_clan/malkavian/favorite_ghoul_gain(datum/antagonist/bloodsucker/source, datum/antagonist/ghoul/ghouldatum) + var/mob/living/carbon/carbonowner = ghouldatum.owner.current + if(istype(carbonowner)) + carbonowner.gain_trauma(/datum/brain_trauma/mild/hallucinations, TRAUMA_RESILIENCE_ABSOLUTE) + carbonowner.gain_trauma(/datum/brain_trauma/special/bluespace_prophet/phobetor, TRAUMA_RESILIENCE_ABSOLUTE) + var/datum/martial_art/psychotic_brawling/psychotic_brawling = new(null) + psychotic_brawling.teach(ghouldatum.owner.current, TRUE) + to_chat(ghouldatum.owner.current, span_notice("Additionally, you now suffer the same fate as your Master, while also gaining the ability to tap into the madness when fighting.")) + +/datum/bloodsucker_clan/malkavian/favorite_ghoul_loss(datum/antagonist/bloodsucker/source, datum/antagonist/ghoul/ghouldatum) + var/mob/living/carbon/carbonowner = ghouldatum.owner.current + if(istype(carbonowner)) + carbonowner.cure_trauma_type(/datum/brain_trauma/mild/hallucinations, TRAUMA_RESILIENCE_ABSOLUTE) + carbonowner.cure_trauma_type(/datum/brain_trauma/special/bluespace_prophet/phobetor, TRAUMA_RESILIENCE_ABSOLUTE) + var/datum/martial_art/psychotic_brawling/psychotic_brawling = locate() in ghouldatum.owner.current.martial_arts + if(isnull(psychotic_brawling)) + return + psychotic_brawling.unlearn(ghouldatum.owner.current) + +/datum/bloodsucker_clan/malkavian/on_exit_torpor(datum/antagonist/bloodsucker/source) + var/mob/living/carbon/carbonowner = bloodsuckerdatum.owner.current + if(istype(carbonowner)) + carbonowner.gain_trauma(/datum/brain_trauma/mild/hallucinations, TRAUMA_RESILIENCE_ABSOLUTE) + carbonowner.gain_trauma(/datum/brain_trauma/special/bluespace_prophet, TRAUMA_RESILIENCE_ABSOLUTE) + +/datum/bloodsucker_clan/malkavian/on_final_death(datum/antagonist/bloodsucker/source) + var/obj/item/soulstone/bloodsucker/stone = new /obj/item/soulstone/bloodsucker(get_turf(bloodsuckerdatum.owner.current)) + if(!bloodsuckerdatum.owner.current.ckey) + return + ASYNC + stone.capture_soul(bloodsuckerdatum.owner.current, forced = TRUE) + return DONT_DUST + +/datum/bloodsucker_clan/malkavian/proc/on_bloodsucker_broke_masquerade(datum/source, datum/antagonist/bloodsucker/masquerade_breaker) + SIGNAL_HANDLER + to_chat(bloodsuckerdatum.owner.current, span_userdanger("[masquerade_breaker.owner.current] has broken the Masquerade! Ensure [masquerade_breaker.owner.current.p_they()] [masquerade_breaker.owner.current.p_are()] eliminated at all costs!")) + var/datum/objective/assassinate/masquerade_objective = new() + masquerade_objective.target = masquerade_breaker.owner.current + masquerade_objective.objective_name = "Clan Objective" + masquerade_objective.explanation_text = "Ensure [masquerade_breaker.owner.current], who has broken the Masquerade, succumbs to Final Death." + bloodsuckerdatum.objectives += masquerade_objective + bloodsuckerdatum.owner.announce_objectives() diff --git a/tff_modular/modules/bloodsucker/clans/clan_nosferatu.dm b/tff_modular/modules/bloodsucker/clans/clan_nosferatu.dm new file mode 100644 index 00000000000..05ef28df2b8 --- /dev/null +++ b/tff_modular/modules/bloodsucker/clans/clan_nosferatu.dm @@ -0,0 +1,103 @@ +/* +/datum/bloodsucker_clan/nosferatu + name = CLAN_NOSFERATU + description = "The Nosferatu Clan is unable to blend in with the crew, with no abilities such as Masquerade and Veil. \n\ + Additionally, has a permanent bad back and looks like a Bloodsucker upon a simple examine, and their face is disfigured \n\ + they can fit in the vents. \n\ + The Favorite Ghoul is also permanently disfigured, and can also ventcrawl, but only while entirely nude. \n\ + They also have night vision, know what each wire does, and have silent footsteps." + clan_objective = /datum/objective/bloodsucker/kindred + join_icon_state = "nosferatu" + join_description = "You are permanetly disfigured, look like a Bloodsucker to all who examine you, \ + lose your Masquerade ability, but gain the ability to Ventcrawl even while clothed." + blood_drink_type = BLOODSUCKER_DRINK_INHUMANELY + var/ventcrawl_time = 10 SECONDS + +/datum/bloodsucker_clan/nosferatu/New(datum/antagonist/bloodsucker/owner_datum) + . = ..() + for(var/datum/action/cooldown/bloodsucker/power as anything in bloodsuckerdatum.powers) + if(istype(power, /datum/action/cooldown/bloodsucker/masquerade) || istype(power, /datum/action/cooldown/bloodsucker/veil)) + bloodsuckerdatum.RemovePower(power) + var/mob/living/mob = bloodsuckerdatum.owner.current + if(!mob.has_quirk(/datum/quirk/badback)) + mob.add_quirk(/datum/quirk/badback) + + mob.add_traits(list(TRAIT_DISFIGURED, TRAIT_VENTCRAWLER_NUDE), BLOODSUCKER_TRAIT) + + RegisterSignal(bloodsuckerdatum, COMSIG_BLOODSUCKER_EXAMINE, PROC_REF(on_mob_examine)) + RegisterSignal(mob, COMSIG_CAN_VENTCRAWL, PROC_REF(can_ventcrawl)) + RegisterSignal(mob, COMISG_VENTCRAWL_PRE_ENTER, PROC_REF(on_ventcrawl_enter)) + RegisterSignal(mob, COMSIG_VENTCRAWL_PRE_EXIT, PROC_REF(on_ventcrawl_pre_exit)) + RegisterSignal(mob, COMSIG_VENTCRAWL_EXIT, PROC_REF(on_ventcrawl_exit)) + RegisterSignal(mob, COMSIG_VENTCRAWL_PRE_CANCEL, PROC_REF(on_ventcrawl_cancel)) + +/datum/bloodsucker_clan/nosferatu/proc/get_ventcrawl_time() + return max(ventcrawl_time - bloodsuckerdatum.GetRank() SECONDS, 2 SECONDS) + +/datum/bloodsucker_clan/nosferatu/proc/can_ventcrawl(mob/living/carbon/human/owner_mob, atom/vent, provide_feedback) + SIGNAL_HANDLER + for(var/item in owner_mob.held_items) + if(isnull(item)) + continue + if(provide_feedback) + to_chat(owner_mob, span_warning("You cannot ventcrawl while holding items!")) + return FALSE + return TRUE + +/datum/bloodsucker_clan/nosferatu/proc/on_ventcrawl_cancel(mob/living/carbon/human/owner_mob, obj/machinery/atmospherics/components/ventcrawl_target) + SIGNAL_HANDLER + animate(ventcrawl_target) + +/datum/bloodsucker_clan/nosferatu/proc/on_ventcrawl_enter(mob/living/carbon/human/owner_mob, obj/machinery/atmospherics/components/ventcrawl_target) + SIGNAL_HANDLER + var/crawl_time = get_ventcrawl_time() + ventcrawl_target.Shake(pixelshiftx = 1, pixelshifty = 1, duration = crawl_time, shake_interval = 0.3 SECONDS) + return crawl_time + +/datum/bloodsucker_clan/nosferatu/proc/on_ventcrawl_pre_exit(mob/living/carbon/human/owner_mob, obj/machinery/atmospherics/components/ventcrawl_target) + SIGNAL_HANDLER + var/crawl_time = get_ventcrawl_time() + playsound(ventcrawl_target, 'sound/effects/bang.ogg', 25) + addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(playsound), crawl_time, 'sound/effects/bang.ogg', 25), ventcrawl_time * 0.6) + ventcrawl_target.Shake(pixelshiftx = 1, pixelshifty = 1, duration = crawl_time, shake_interval = 0.3 SECONDS) + return crawl_time + +/datum/bloodsucker_clan/nosferatu/proc/on_ventcrawl_exit(mob/living/carbon/human/owner_mob, obj/machinery/atmospherics/components/ventcrawl_target) + SIGNAL_HANDLER + // cooldown all non-inherent abilities on exit to prevent instant ambushes + for(var/datum/action/cooldown/bloodsucker/power as anything in bloodsuckerdatum.powers) + if(power.purchase_flags & BLOODSUCKER_DEFAULT_POWER) + continue + power.StartCooldown() + +/datum/bloodsucker_clan/nosferatu/proc/on_mob_examine(datum/antagonist/bloodsucker/owner_datum, datum/source, mob/examiner, examine_text) + SIGNAL_HANDLER + var/mob/living/carbon/human/ogled = owner_datum.owner.current + var/mob/living/ogler = examiner + if(isliving(examiner) && examiner != ogled && !ogler.mob_mood.has_mood_of_category("nosferatu_examine")) + ogler.add_mood_event("nosferatu_examine", /datum/mood_event/nosferatu_examined, ogled, owner_datum.GetRank()) + ogler.adjust_disgust(owner_datum.GetRank() * 10) + // show that they are dangerous nosferatu, as if you're gazing upon them with fear, without mentioning the clan name/antagonist name, describe their appearance + examine_text += span_danger("[ogled.p_They()] look[ogled.p_s()] like a pale, grotesque hunchback, with a mouth full of jagged yellowy teeth, and breath that reeks of fresh blood. You feel both afraid and disgusted as you gaze upon [ogled.p_them()].") + examine_text += span_userdanger("[ogled.p_They()] [ogled.p_are()] clearly a BLOODSUCKER!") + +/datum/bloodsucker_clan/nosferatu/Destroy(force) + var/datum/action/cooldown/bloodsucker/feed/suck = locate() in bloodsuckerdatum.powers + if(suck) + bloodsuckerdatum.RemovePower(suck) + bloodsuckerdatum.give_starting_powers() + bloodsuckerdatum.owner.current.remove_quirk(/datum/quirk/badback) + bloodsuckerdatum.owner.current.remove_traits(list(TRAIT_VENTCRAWLER_NUDE, TRAIT_DISFIGURED), BLOODSUCKER_TRAIT) + UnregisterSignal(bloodsuckerdatum, list(COMSIG_BLOODSUCKER_EXAMINE, COMSIG_CAN_VENTCRAWL, COMISG_VENTCRAWL_PRE_ENTER, COMSIG_VENTCRAWL_PRE_EXIT, COMSIG_VENTCRAWL_EXIT)) + return ..() + +/datum/bloodsucker_clan/nosferatu/favorite_ghoul_gain(datum/antagonist/bloodsucker/source, datum/antagonist/ghoul/ghouldatum) + var/list/traits_to_add = list(TRAIT_VENTCRAWLER_NUDE, TRAIT_DISFIGURED, TRAIT_TRUE_NIGHT_VISION, TRAIT_KNOW_ENGI_WIRES, TRAIT_SILENT_FOOTSTEPS) + ghouldatum.owner.current.add_traits(traits_to_add, GHOUL_TRAIT) + ghouldatum.traits += traits_to_add + ghouldatum.owner.current.update_sight() + to_chat(ghouldatum.owner.current, span_notice("Additionally, you can now ventcrawl while naked, and are permanently disfigured. You also have night vision, know how which wires to cut, and have silent footsteps.")) + +/datum/bloodsucker_clan/nosferatu/favorite_ghoul_loss(datum/antagonist/bloodsucker/source, datum/antagonist/ghoul/ghouldatum) + ghouldatum.owner.current.update_sight() +*/ diff --git a/tff_modular/modules/bloodsucker/clans/clan_tremere.dm b/tff_modular/modules/bloodsucker/clans/clan_tremere.dm new file mode 100644 index 00000000000..d85d902d22d --- /dev/null +++ b/tff_modular/modules/bloodsucker/clans/clan_tremere.dm @@ -0,0 +1,63 @@ +/datum/bloodsucker_clan/tremere + name = CLAN_TREMERE + description = "The Tremere Clan is extremely weak to True Faith, and will burn when entering areas considered such, like the Chapel. \n\ + Additionally, a whole new moveset is learned, built on Blood magic rather than Blood abilities, which are upgraded overtime. \n\ + More ranks can be gained by Ghoulizing crewmembers. \n\ + The Favorite Ghoul gains the Batform spell, being able to morph themselves at will." + clan_objective = /datum/objective/bloodsucker/tremere_power + join_icon_state = "tremere" + join_description = "You will burn if you enter the Chapel, lose all default powers, \ + but gain Blood Magic instead, stronger powers you level up overtime." + buy_power_flags = TREMERE_CAN_BUY|CAN_BUY_OWNED + +/datum/bloodsucker_clan/tremere/New(mob/living/carbon/user) + . = ..() + bloodsuckerdatum.remove_nondefault_powers(return_levels = TRUE) + for(var/datum/action/cooldown/bloodsucker/power as anything in bloodsuckerdatum.all_bloodsucker_powers) + if((initial(power.purchase_flags) & buy_power_flags) && initial(power.level_current) == 1) + bloodsuckerdatum.BuyPower(power) + +/datum/bloodsucker_clan/tremere/Destroy(force) + for(var/datum/action/cooldown/bloodsucker/power in bloodsuckerdatum.powers) + if(power.purchase_flags & buy_power_flags) + bloodsuckerdatum.RemovePower(power) + return ..() + +/datum/bloodsucker_clan/tremere/handle_clan_life(datum/antagonist/bloodsucker/source, seconds_per_tick, times_fired) + . = ..() + var/area/current_area = get_area(bloodsuckerdatum.owner.current) + if(istype(current_area, /area/station/service/chapel)) + to_chat(bloodsuckerdatum.owner.current, span_warning("You don't belong in holy areas! The Faith burns you!")) + bloodsuckerdatum.owner.current.adjust_fire_loss(10) + bloodsuckerdatum.owner.current.adjust_fire_stacks(2) + bloodsuckerdatum.owner.current.ignite_mob() + +/datum/bloodsucker_clan/tremere/level_up_powers(datum/antagonist/bloodsucker/source) + return + +/datum/bloodsucker_clan/tremere/level_message(power_name) + var/mob/living/carbon/human/human_user = bloodsuckerdatum.owner.current + human_user.balloon_alert(human_user, "upgraded [power_name]!") + to_chat(human_user, span_notice("You have upgraded [power_name]!")) + +// redefine the default args +/datum/bloodsucker_clan/tremere/list_available_powers(already_known, powers_list) + already_known = list() + powers_list = bloodsuckerdatum.powers + return ..() + +/datum/bloodsucker_clan/tremere/purchase_choice(datum/antagonist/bloodsucker/source, datum/action/cooldown/bloodsucker/purchased_power) + return purchased_power.upgrade_power() + +/datum/bloodsucker_clan/tremere/favorite_ghoul_gain(datum/antagonist/bloodsucker/source, datum/antagonist/ghoul/ghouldatum) + var/datum/action/cooldown/spell/shapeshift/bat/batform = new(ghouldatum.owner || ghouldatum.owner.current) + batform.Grant(ghouldatum.owner.current) + +/datum/bloodsucker_clan/tremere/favorite_ghoul_loss(datum/antagonist/bloodsucker/source, datum/antagonist/ghoul/ghouldatum) + var/datum/action/cooldown/spell/shapeshift/bat/batform = locate() in ghouldatum.owner.current.actions + batform.Remove(ghouldatum.owner.current) + +/datum/bloodsucker_clan/tremere/on_ghoul_made(datum/antagonist/bloodsucker/source, mob/living/user, mob/living/target) + . = ..() + to_chat(bloodsuckerdatum.owner.current, span_danger("You have now gained an additional Rank to spend!")) + bloodsuckerdatum.AdjustUnspentRank(1) diff --git a/tff_modular/modules/bloodsucker/clans/clan_ventrue.dm b/tff_modular/modules/bloodsucker/clans/clan_ventrue.dm new file mode 100644 index 00000000000..713fec66fe8 --- /dev/null +++ b/tff_modular/modules/bloodsucker/clans/clan_ventrue.dm @@ -0,0 +1,153 @@ +///The maximum level a Ventrue Bloodsucker can be, before they have to level up their ghoul instead. +#define VENTRUE_MAX_POWERS 3 + +/datum/bloodsucker_clan/ventrue + name = CLAN_VENTRUE + description = "The Ventrue Clan is extremely snobby with their meals, and refuse to drink blood from people without a mind. \n\ + You may have up to %MAX_POWERS% powers, anything further will be ranks to spend on their Favorite Ghoul through a Persuasion Rack. \n\ + The Favorite Ghoul will slowly turn more Vampiric this way, until they finally lose their last bits of Humanity. \n\ + Once you finish your embracing, the newly sired vampire will become just a ghoul, and you'll be able to sire another bloodsucker." + clan_objective = /datum/objective/bloodsucker/embrace + join_icon_state = "ventrue" + join_description = "Lose the ability to drink from mindless mobs, can't level up or gain new powers, \ + instead you raise a ghoul into a Bloodsucker." + blood_drink_type = BLOODSUCKER_DRINK_SNOBBY + level_cost = BLOODSUCKER_LEVELUP_PERCENTAGE_VENTRUE + +/datum/bloodsucker_clan/ventrue/New(datum/antagonist/bloodsucker/owner_datum) + . = ..() + description = replacetext(description, "%MAX_POWERS%", VENTRUE_MAX_POWERS) + +/datum/bloodsucker_clan/ventrue/proc/has_enough_abilities() + var/power_count = 0 + for(var/datum/action/cooldown/bloodsucker/power in bloodsuckerdatum.powers) + if(!(power.purchase_flags & BLOODSUCKER_DEFAULT_POWER)) + power_count++ + if(power_count >= VENTRUE_MAX_POWERS) + return TRUE + return FALSE + +/datum/bloodsucker_clan/ventrue/spend_rank(datum/antagonist/bloodsucker/source, cost_rank = TRUE, blood_cost) + if(has_enough_abilities()) + to_chat(bloodsuckerdatum.owner.current, span_danger("You can only have up to [VENTRUE_MAX_POWERS] powers, anything further must be ranks to spend on your Favorite Ghoul through a Persuasion Rack.")) + return FALSE + . = ..() + +/datum/bloodsucker_clan/ventrue/proc/finish_spend_rank(datum/antagonist/ghoul/ghouldatum, cost_rank, blood_cost) + finalize_spend_rank(bloodsuckerdatum, cost_rank, blood_cost) + ghouldatum.LevelUpPowers() + +/datum/bloodsucker_clan/ventrue/interact_with_ghoul(datum/antagonist/bloodsucker/source, datum/antagonist/ghoul/favorite/ghouldatum) + . = ..() + if(.) + return TRUE + if(!istype(ghouldatum)) + return FALSE + to_chat(bloodsuckerdatum.owner.current, span_warning("Do you wish to Rank [ghouldatum.owner.current] up?")) + to_chat(bloodsuckerdatum.owner.current, span_warning("This will use [bloodsuckerdatum.GetUnspentRank() >= 1 ? "a unspent Rank" : "[bloodsuckerdatum.get_level_cost()] Blood Thickening Points"]!")) + + var/static/list/rank_options = list( + "Yes" = image(icon = 'icons/hud/radial.dmi', icon_state = "radial_yes"), + "No" = image(icon = 'icons/hud/radial.dmi', icon_state = "radial_no"), + ) + var/rank_response = show_radial_menu(bloodsuckerdatum.owner.current, ghouldatum.owner.current, rank_options, radius = 36, require_near = TRUE) + if(rank_response == "Yes") + if(!bloodsuckerdatum.GetUnspentRank() >= 1 && !source.blood_level_gain(FALSE)) + to_chat(bloodsuckerdatum.owner.current, span_danger("You don't have any levels or enough blood thickening points to Rank [ghouldatum.owner.current] up with.")) + return FALSE + return ghoul_level(ghouldatum) + return FALSE + +/datum/bloodsucker_clan/ventrue/proc/ghoul_level(datum/antagonist/ghoul/favorite/ghouldatum) + var/list/options = list_available_powers(ghouldatum.bloodsucker_powers) + var/mob/living/carbon/human/target = ghouldatum.owner.current + var/datum/action/cooldown/bloodsucker/choice = choose_powers( + "You have the opportunity to level up your Favorite Ghoul. Select a power you wish them to receive.", + "A wise master's hand is neccesary", + options + ) + if(!choice) + return FALSE + var/power_name = initial(choice.name) + if(!ghouldatum.BuyPower(choice, ghouldatum.bloodsucker_powers)) + bloodsuckerdatum.owner.current.balloon_alert(bloodsuckerdatum.owner.current, "[target] already knows [power_name]!") + return FALSE + bloodsuckerdatum.owner.current.balloon_alert(bloodsuckerdatum.owner.current, "taught [power_name]!") + to_chat(bloodsuckerdatum.owner.current, span_notice("You taught [target] how to use [power_name]!")) + + target.balloon_alert(target, "learned [power_name]!") + to_chat(target, span_notice("Your master taught you how to use [power_name]!")) + + ghouldatum.ghoul_level++ + finish_spend_rank(ghouldatum, TRUE, FALSE) + bloodsuckerify(ghouldatum) + return TRUE + +/datum/bloodsucker_clan/ventrue/proc/bloodsuckerify(datum/antagonist/ghoul/favorite/ghouldatum) + var/mob/living/carbon/human/target = ghouldatum.owner.current + var/stage = ghouldatum.ghoul_level + var/list/traits_possible = list( + list(TRAIT_COLDBLOODED, TRAIT_NOBREATH, TRAIT_AGEUSIA), + list(TRAIT_NOCRITDAMAGE, TRAIT_NOSOFTCRIT, TRAIT_SLEEPIMMUNE, TRAIT_VIRUSIMMUNE), + list(TRAIT_NOHARDCRIT, TRAIT_HARDLY_WOUNDED) + ) + var/traits_to_add = length(traits_possible) >= stage ? traits_possible[stage] : list() + switch(stage) + + if(1) + to_chat(target, span_notice("Your blood begins to feel cold, and as a mote of ash lands upon your tongue, you stop breathing...")) + + if(2) + to_chat(target, span_notice("You feel your Master's blood reinforce you, strengthening you up.")) + if(ishuman(target)) + var/mob/living/carbon/human/human_target = target + human_target.skin_tone = "albino" + + if(3) + to_chat(target, span_notice("You feel yourself able to take cuts and stabbings like it's nothing.")) + + if(4 to INFINITY) + var/datum/antagonist/bloodsucker/bloodsucker_target = IS_BLOODSUCKER(target) + if(!bloodsucker_target) + to_chat(target, span_notice("You feel your heart stop pumping for the last time as you begin to thirst for blood, you feel... dead.")) + // Unfavorites you, so the ventrue isn't stuck with you forever + var/powers_to_transfer = list() + // Get rid of the favorite datum and replace with a normal ghoul datum + if(ghouldatum) + ghouldatum.silent = TRUE + for(var/datum/power as anything in ghouldatum.bloodsucker_powers) + powers_to_transfer += power.type + target.mind.remove_antag_datum(/datum/antagonist/ghoul/favorite) + else + target.remove_traits(assoc_to_values(traits_to_add), GHOUL_TRAIT) + + + var/datum/antagonist/bloodsucker/vamp = new() + vamp.ventrue_sired = bloodsuckerdatum + bloodsucker_target = target.mind.add_antag_datum(vamp) + bloodsucker_target.BuyPowers(powers_to_transfer) + // Check for the recuperate power and remove it if they have it + bloodsuckerdatum.owner.current.add_mood_event("madevamp", /datum/mood_event/madevamp) + + + if(ghouldatum && QDELETED(ghouldatum) && length(traits_to_add)) + target.add_traits(traits_to_add, GHOUL_TRAIT) + ghouldatum.traits += traits_to_add + +/datum/bloodsucker_clan/ventrue/favorite_ghoul_gain(datum/antagonist/bloodsucker/source, datum/antagonist/ghoul/ghouldatum) + to_chat(source.owner.current, span_announce("* Bloodsucker Tip: You can now upgrade your Favorite Ghoul by buckling them onto a persuasion rack!")) + ghouldatum.BuyPower(/datum/action/cooldown/bloodsucker/distress) + +/datum/bloodsucker_clan/ventrue/is_valid_ghoul(datum/antagonist/ghoul/ghoul_type) + . = ..() + if(!.) + return FALSE + var/datum/antagonist/ghoul/favorite = /datum/antagonist/ghoul/favorite + if(ghoul_type != favorite) + // no ghoul slots and trying to make a non-favorite ghoul, don't softlock yourself + if(bloodsuckerdatum.free_ghoul_slots() < 1 && !bloodsuckerdatum.special_ghouls[initial(favorite.special_type)]) + to_chat(bloodsuckerdatum.owner.current, span_danger("Making a non-favorite Ghoul will prevent you from leveling up, as you have no slots left!")) + return FALSE + return TRUE + +#undef VENTRUE_MAX_POWERS diff --git a/tff_modular/modules/bloodsucker/credit_file.md b/tff_modular/modules/bloodsucker/credit_file.md new file mode 100644 index 00000000000..427f3f28ef4 --- /dev/null +++ b/tff_modular/modules/bloodsucker/credit_file.md @@ -0,0 +1,32 @@ +## File containing credit for all sprites in this folder.area and related files moved out of it +Sheits (Throne, vamp_obj_64.dmi) https://github.com/fulpstation/fulpstation/pull/393 +modular_zubbers/icons/obj/structures/vamp_obj_64.dmi + +ReinaCoder (Book, vamp_obj.dmi) https://github.com/fulpstation/fulpstation/pull/649 +modular_zubbers/icons/obj/structures/vamp_obj.dmi + +A majority of credit goes to JohnFulpWillard for coding and spriting Bloodsuckers. +Code paths: +This folder, +modular_zubbers/code/datums/components/crafting/crafting/furniture.dm +modular_zubbers/code/datums/components/crafting/crafting/melee_weapon.dm +modular_zubbers/code/controllers/subsystem/sol_subsystem.dm +modular_zubbers/code/modules/languages/vampiric.dm +modular_zubbers/code/__DEFINES/bloodsucker.dm + + +Sprite paths: +modular_zubbers/icons/obj/equipment/stakes.dmi +modular_zubbers/icons/mob/inhands/weapons/bloodsucker_lefthand.dmi +modular_zubbers/icons/mob/inhands/weapons/bloodsucker_righthand.dmi +modular_zubbers/icons/mob/actions/bloodsucker.dmi +modular_zubbers/icons/mob/actions/tremere_bloodsucker.dmi +modular_zubbers/icons/effects/radials/clan_icons.dmi +modular_zubbers/icons/misc/language.dmi +modular_zubbers/icons/huds/bloodsucker.dmi +modular_zubbers/icons/effects/phobetor_tear.dmi + +Sound paths: +everything in modular_zubbers/sound/bloodsucker +modular_zubbers/sound/machines/coffin_close.ogg +modular_zubbers/sound/machines/coffin_open.ogg diff --git a/tff_modular/modules/bloodsucker/icons/bloodsucker.dmi b/tff_modular/modules/bloodsucker/icons/bloodsucker.dmi new file mode 100644 index 0000000000000000000000000000000000000000..901589214ea27d40a9cf85be020b3aa2eb79f734 GIT binary patch literal 20484 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 V=o{ZQTfzVU002ovPDHLkV1o8DS*QR2 literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/icons/bloodsucker_lefthand.dmi b/tff_modular/modules/bloodsucker/icons/bloodsucker_lefthand.dmi new file mode 100644 index 0000000000000000000000000000000000000000..7e69d1073dfe311516172dbbca2cab38cf12dba0 GIT binary patch literal 6531 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 literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/icons/bloodsucker_righthand.dmi b/tff_modular/modules/bloodsucker/icons/bloodsucker_righthand.dmi new file mode 100644 index 0000000000000000000000000000000000000000..14069ad34f0de0cc6e4375dd14a53ab84c67640d GIT binary patch literal 6751 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 literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/icons/clan_icons.dmi b/tff_modular/modules/bloodsucker/icons/clan_icons.dmi new file mode 100644 index 0000000000000000000000000000000000000000..f6242a2143db59626279769bb56470be464b99b4 GIT binary patch literal 16483 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 W|4@H#NBq|SfSk0FRMkh5p#KFV!0PJ& literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/icons/hud.dmi b/tff_modular/modules/bloodsucker/icons/hud.dmi new file mode 100644 index 0000000000000000000000000000000000000000..9cd9b225d72261ad3b8a77f3f7eb6af8940e2fcb GIT binary patch literal 1342 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGoi>pE+N?cNllZ!G7N;32F7#J$% z^q$_!b;v-Z?V;t)F6Z6de=q8GZ}DjVCgzpZ=lR0_gG%6@>h`ADGu~D|{8_YP%k{j5 zW$%9opN!t#*zl|1$(z(r1BC@zmc|)dIjestFgG>iM9m4dyO*}4$2j$5b3@Z+>yx72 z|88CVrN2W(v`=`a`knd-TceKNUatP9rs~iSo4(I?_F5X&TmAoh zS=a9Vzaw94dQ?B%KXgs~#xE9zAJIw%Jm)1F@+w#ux{vM``uIX%0xN??TQ}zmfejHl zE}w+Uw%PqG`^|M}CS8+;A zSDMJDp>yG2!v4EV<@_6tDKRrFWZJTgd6(@5_6v-u;tauEPnpkGJ6;Vr_LOg%U8RGE z!?wHMgzLUDFk~<$>^|BraPQ}8dk;gK^2e;Af3xq`op|#7O-}8n75e5$f{f4JF&Z*G zTQ|Q^!dT)n!%Ed1+NbUAFZn5OT3+J%zq=8C8yXsRt@EAtT=4$3^Rw5zG*9T<-k7|P zS68fCpMfF!dxXxuj=j8W4NG3t-ePonRLsEeq*Ctj26l;(j9G4P=F5NHT+7X};Psk_ zeW&l*Gt_*#r1v+{hv9-h6T`=o|22N*D{47Z_MUjo@brHmV@e2vq^N@%>jYAmGyf)B ztJ>Qa8k)E>W>(>xO)+}uwn~qR#J}qn*oCLbET41!>YJar7a#7(JY(Uvu%w}w@0_KZ z3B!Udf16u*C38+NoZ!A;`TWBsZk5m8+DV%lQfJ-RxzdnL=s)Dutj?%jEAI5ojpt=OhE;rX1;3~{+ff_^S- zW!E!*^f^-Re%l%4n7kvCyeG)3)vc;~*n5Lt*gkas2e&uvo%2`4Z(*La>U$5L$EthA zRthVt=9e9KvwZRO*I#!(f6U*0_|E&o_s_1Mb<>``X3lTsDc4_w3z8K|;1Hd8lRs_e zoug&*A6D!&1g7eWy)*y+Yglx&ve*R3+hcidUi=o_b?0mAF2+3zwmL9PHs|Kwf8yzj zc*Ig4+*J@*vY0LP@pw$_1NtYa-hUywo0PaEWb$x&z1`vVcBu# z=-|kb@%?zm=VwRTCiZF;QXiS62#Yh zWl+lI{B-z;|5g1xg1-|VEq^6`uj8-5$KbEsWe!1K=Ursrf4Zs4C!PC{xWt~$(69CO6W0?Q| literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/icons/language.dmi b/tff_modular/modules/bloodsucker/icons/language.dmi new file mode 100644 index 0000000000000000000000000000000000000000..1cf92d5c97a7cf5a75ba5f09bd19af492f7f90fe GIT binary patch literal 722 zcmV;@0xkWCP)V=-0C=2JR&a84_w-Y6@%7{?OD!tS%+FJ>RWQ*r;NmRLOex7wuvIWLl;joY$>g`NEMAD=Lm};D^-fPO@UI*0ajvr`vzNDpzSgzm@UGv0~i9> zuuXo+;x`uazIp!VA*RzQr<977t>lnjx3|K1UtgS&Qd+IGaK3FZ|GD$WDAEl8l^k-h z{xFV}9T~$Bv0N5!+;sSaIfQr=*Aoso+`}bmf5J@TR$QYh&$mQjG!MC@orSEe7+q5wU zmSm#F7=tkeA!^uGI60AJ$a0pXqfQ)nXtPA&^@ zy4~*ta1hXc@b(5chgv70uOvxqQ4|aY1L3@{G)+5oXJ-hvNhyU=s!QFY0me!x*1K>v zfXQTX-#5hG07;VA*=%Ngh(2D!havPdR!Zf-N)XdDJsUt?6a`8t2hxl72Jm*B_t}9D z2T_tFJO9t;^LeK^(0LNZaop+mM-8Gr^$G9^@ZSOc0`403H@7u0Z~y=R07*qoM6N<$ Eg1`SsmjD0& literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/icons/phobetor_tear.dmi b/tff_modular/modules/bloodsucker/icons/phobetor_tear.dmi new file mode 100644 index 0000000000000000000000000000000000000000..4ae3e95fe248fdd6e861382c9c8fb7be96f49c7e GIT binary patch literal 1927 zcmV;22YC32P)V=-0C=1w$FT~+Fc1ddIrkJl?HWX5*IOh-GPJKCk(?%=jUX5%cQdmq0&js3B+fVfLf|00zHFL_t(|ob8%VXxwHR#(&zj7gJ^k zDZy;f)EC7RHraZ0^fGD=o}tB*E|l6CNC@2_4s4)dR2J&Ehfq7E5E&PINR7P(2ZlK0 zuuxw{KE#?Ohoz`a|FLz3LTte%6hg2lrJ)7&F#e{pMl;sT*iqZebCK{!-}}DL`+k3{ z_mNgtSBV0xsAmAIoMA?K;WvUmM0rRn>KX0~mAsyONh|6ZK}LG}`Y7PHyO*dVK-2Zx z8!ygye#2hEdwJ3PnkzFUu$i@ThM6wvnKN^gnvsxRE{wF}ln8Xk)t7+u9wtBvn*!{5>=koCVd={V_GCk7Eg^}{`^iuFX z4C$htk$g7GIm6sez=125Qda>^s!j!!vmS6}j?(4RWW($R$8GdXLjuaf(@W{=g(>N) z)HsThwW`j%jm-rT@>63s90rlOiNl8~6=2>|xkbV|&@9L(5DDrgUFnj znMbmjm26%}7xhfgmWV}+9kdr(0d-C-7e=NoC9kGPvdI<>ZY}$R$ZWC&fcX9VTU(<$ zh-{-GMA_D=ak(%vbt(DgmslhjKqgVMH=(+fNjsr@iN#fQpyD0#-ocd~>^3!aB|ux( zj{@I%|MN8IKhnFCc0%!!0M!Z*glw|KdCgs5z*~`?mn^H_xYugnp=1OSkRr)VoEi!K zdy#nr!U0kGDU!9|QzT&^|M&8%zhu1CoxoqF z+PdDWt?Rw~1b*A1@*G??+1eSr<}UD4_1!2H@WiQ8ryBmaaX9%}_wij0`lkU@9Xxv2{WteMU3>1X`9t}b@tGK-6#_PnWWTB1Ka>5g@4oqT`LEOe z?YnP2o#tWcKSZa zShVH${cAyud4PVd)dshjwG88MD+JUW4p}=iUH>PLpR^N-gIlXYfC<(8(L3ZV^1TH8 zT#J%@hCQ}I{8#Ia=cfqt&hlP_JFlS=@LwybEne!CSL0(HT!>%FMl z0_MdO6zdRxKX|BSJc{j>2!I+1XD^@2SI+>MAyAxb`GS#`Y-W$o`~#?F|HNr0D=MH} zB5HQ~jeB7UaB!;$5W)B4OULKd>JrfC)Y#G#@S}D-?OWM#5)+1^mSDTKy`FsO%*;F= zW`^+kR>sRY<2_B+Z!g-i0@V|vr*c-j(`Y)jO+YgQx1T86QLET30kAU(jS{mj1UxD< zI%Ks%c*|=*6g;YblY_yxGyQ(k6|fiBmkNjr?Nr|HihyA0M$xfZgdHV+kv>z zB_M7G;zpN%xE+WaT>|2EAZ~OCh}(g<5t)GfYEQ?Fu0Ej7P`EzeKs)+?cCnj2Ks*$0Ly=YGdA-?QBw|Y*3UlP!cJ|K$i=FQQfp4sln3w=Nan^_XF(uzKyoer_E zwP?#qKp#-OkC=enuQeG*)b@0zA_>^L1T;g_MKBnAiX?wRV-OjDn>eIM zGG?QsNb)kTFli^0;22@|QDEf^(^EG`w*?v_lXHpEsJ*5{6=+1kZu)>;fS^7=w5LU1 z9@yEQegygepw5plfyQoQH?05>Ku{kbjEe@P=+g^*08e%vFjNH^jr0McJzf|5wmv{o zBr9yp$ONRX7pAnLo)IKiIpaNGenNFC{;Wf_3@23g#}hAYF0eMgfGa)dB>Q68S^dW6 zR=;sCm;f;a0S1xTQ5k^*h`{|?AwQ(m)m5~jo)L>oBPFP|uJ>Yd)UOZl~@BDq5!Ae`ysB70@)ci9|$Y!o7m>^}At z&zB_M7G;zpN%xE+WaT>|2EAZ~OCh}(g<@iToZ-|{LrMI!(J N002ovPDHLkV1lKZtMC8- literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/icons/stakes.dmi b/tff_modular/modules/bloodsucker/icons/stakes.dmi new file mode 100644 index 0000000000000000000000000000000000000000..dfc1dc08bf4334835cf6f2ab74919b1eda6c7679 GIT binary patch literal 866 zcmV-o1D*VdP))f<<+_Q;ID;0vEzf@py*Qj}hK_JcZ{C9+zt!5wa(5CV=- z0C=2JR&a84_w-Y6@%7{?OD!tS%+FJ>RWQ*r;NmRLOex6#a*U0*I5Sc+(=$pSoZ^zi zl2jm5sXRYFMTv_uC9|j)$Tj5ROe;#vO@*-GiZT+5Qd09$2`enl%mF%ppfZr9PL9sr zp#el&O{8*&1Mn+WR&e!m0S6WU%*t0)k-GxD0005~Nkl7ykSg=2IIlO_Ra|ZH# zq#6te=>ouj(p@gjeMkJdw(AxXWJs*G%L=J z_=<0u9rGXM{ZD*C#8-UNTowMu1^l&dniKP%ML#3Y7XUs`&3B0}f1eDfYqVeW-Sq|X zv#bN(-x~jR!~9K~Hf{QXBE?t3Db}FyQL^}>lZYP(4&danV!-hzEEi~s2l)ISf%^-kE5Q6K;@{nGrh*3e s_x2m7^6ykCXrIYX1#S8NZPS0CcX7iktM*kz?EnA(07*qoM6N<$g3fKDng9R* literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/icons/tremere_bloodsucker.dmi b/tff_modular/modules/bloodsucker/icons/tremere_bloodsucker.dmi new file mode 100644 index 0000000000000000000000000000000000000000..057b17bbe103d2053b2fdf2a701ec73818365061 GIT binary patch literal 5371 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 literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/icons/vamp_obj.dmi b/tff_modular/modules/bloodsucker/icons/vamp_obj.dmi new file mode 100644 index 0000000000000000000000000000000000000000..fa6228f45e056049e62d5e47d78f2139e5380f13 GIT binary patch literal 10653 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 literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/icons/vamp_obj_64.dmi b/tff_modular/modules/bloodsucker/icons/vamp_obj_64.dmi new file mode 100644 index 0000000000000000000000000000000000000000..4367da28b32b8e74f93adcfea4d20a6b7c7cca37 GIT binary patch literal 1109 zcmV-b1giUqP)bB>(^b0d!JM zQvg8b*k%9#0Caj(Sad{Xb7OL8aCB*JZU6vyoKseCa&`CgQ*iP1i4QC_gV%iHkEOv#1!Pi;FX@ zC^0t`#5P1%mROXFOQo`ctDg(l1poprClvZq%31&b16D~yK~!jg?U=uAA~6ugja`F+ z(xqD2cM3re5sxkqM7BsC;U3}MAQVdt1y?5(NfoG)JV8PS^_?Qpo)F5m2hVU`7XMjx zb4J%(;}42__Ri1tjM+$okdu>>lao_gxxJ*vo?$$cDQp^2OHL;Ir)hCryvP zWCOk$JM&I26B|nU(`>*uV-0kAX`Xb;x3d9tGeDf#`^e)SWW__nh$!x#6cdw_>Y&5! zm4{Nohovj|w})~;u&2x7Arb^N>2dHqxJm;K#jxb&_8URaJ5g5wvqrzu2)-^-;w0?zx#)!BO}w@8Q&%Q=L#nmhu8;aeDnB=$Am_s@MF^btT1M7+*& zfrNf-VPrj=uih3iiv$YitEF$g_)&hfdPSxd1(fuQg=q_gt$CDxMNUpmPEJlvPEJlv zPEP+MOaH(sTmQfgu=EeCvh@$_vh@#k1bo~-u*lv&u*up#u*%Xuu*u#(uxW?>fmPQ2 b!T-}AaD_*nX)b$H00000NkvXXu0mjf=H29G literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/powers/_powers.dm b/tff_modular/modules/bloodsucker/powers/_powers.dm new file mode 100644 index 00000000000..82295560ef1 --- /dev/null +++ b/tff_modular/modules/bloodsucker/powers/_powers.dm @@ -0,0 +1,319 @@ +/datum/action + /// Extended description of the action, usually shown in an antag UI. + var/power_explanation = "" + +/datum/antagonist + var/antag_panel_title = "Antagonist Panel" + var/antag_panel_description = "This is the antagonist panel. It contains all the abilities you have access to as an antagonist. Use them wisely." + +/datum/antagonist/proc/ability_ui_data(actions = list()) + var/list/data = list() + data["title"] = "[antag_panel_title]\n[antag_panel_data()]" + data["description"] = antag_panel_description + for(var/datum/action/cooldown/power as anything in actions) + var/list/power_data = list() + + power_data["power_name"] = power.name + power_data["power_icon"] = power.button_icon_state + if(istype(power, /datum/action/cooldown/bloodsucker)) + var/datum/action/cooldown/bloodsucker/bloodsucker_power = power + power_data["power_explanation"] = bloodsucker_power.get_power_explanation() + + data["powers"] += list(power_data) + return data + +/datum/action/cooldown/bloodsucker + name = "Vampiric Gift" + background_icon = 'tff_modular/modules/bloodsucker/icons/bloodsucker.dmi' + background_icon_state = "vamp_power_off" + button_icon = 'tff_modular/modules/bloodsucker/icons/bloodsucker.dmi' + button_icon_state = "power_feed" + buttontooltipstyle = "cult" + transparent_when_unavailable = TRUE + + /// Cooldown you'll have to wait between each use, decreases depending on level. + cooldown_time = 2 SECONDS + + ///Background icon when the Power is active. + active_background_icon_state = "vamp_power_on" + ///Background icon when the Power is NOT active. + base_background_icon_state = "vamp_power_off" + + /// The text that appears when using the help verb, meant to explain how the Power changes when ranking up. + ///The owner's stored Bloodsucker datum + var/datum/antagonist/bloodsucker/bloodsuckerdatum_power + + // FLAGS // + /// The effects on this Power (Toggled/Single Use/Static Cooldown) + var/power_flags = BP_AM_SINGLEUSE|BP_AM_STATIC_COOLDOWN|BP_AM_COSTLESS_UNCONSCIOUS + /// Requirement flags for checks + check_flags = AB_CHECK_INCAPACITATED|AB_CHECK_CONSCIOUS|AB_CHECK_PHASED + var/bloodsucker_check_flags = BP_CANT_USE_IN_TORPOR|BP_CANT_USE_IN_FRENZY + /// Who can purchase the Power + var/purchase_flags = NONE // BLOODSUCKER_CAN_BUY|BLOODSUCKER_DEFAULT_POWER|TREMERE_CAN_BUY|GHOUL_CAN_BUY + + // VARS // + /// If the Power is currently active, differs from action cooldown because of how powers are handled. + var/active = FALSE + ///Can increase to yield new capabilities - Each Power ranks up each Rank, with the oldest power being the highest rank. + var/level_current = 0 + ///The cost to ACTIVATE this Power + var/bloodcost = 0 + ///The cost to MAINTAIN this Power - Only used for Constant Cost Powers + var/constant_bloodcost = 0 + ///Most powers happen the moment you click. Some, like Mesmerize, require time and shouldn't cost you if they fail. + var/power_activates_immediately = TRUE + +// Modify description to add cost. +/datum/action/cooldown/bloodsucker/New(Target) + SHOULD_CALL_PARENT(TRUE) + . = ..() + desc = get_power_desc() + +/datum/action/cooldown/bloodsucker/Destroy() + SHOULD_CALL_PARENT(TRUE) + if(active) + DeactivatePower() + bloodsuckerdatum_power = null + return ..() + +/datum/action/cooldown/bloodsucker/IsAvailable(feedback = FALSE) + return next_use_time <= world.time + +/datum/action/cooldown/bloodsucker/Grant(mob/user) + . = ..() + var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(owner) + if(bloodsuckerdatum) + bloodsuckerdatum_power = bloodsuckerdatum + +/datum/action/cooldown/bloodsucker/Trigger(trigger_flags, atom/target) + if(trigger_flags & TRIGGER_SECONDARY_ACTION) + RightClickActivate(trigger_flags) + return + . = ..() + +//This is when we CLICK on the ability Icon, not USING. +/datum/action/cooldown/bloodsucker/PreActivate(atom/target) + if(QDELETED(owner)) + return FALSE + if(SEND_SIGNAL(src, COMSIG_ACTION_TRIGGER) & COMPONENT_ACTION_BLOCK_TRIGGER) + return FALSE + if(active && can_deactivate()) // Active? DEACTIVATE AND END! + DeactivatePower() + return FALSE + if(!can_pay_cost() || !can_use(owner)) + return FALSE + . = ..() + // base type returns true? Pay costs + if(!click_to_activate && power_activates_immediately) + pay_cost() + +/datum/action/cooldown/bloodsucker/proc/can_pay_cost() + if(QDELETED(owner) || !owner.mind) + return FALSE + // Cooldown? + if(!COOLDOWN_FINISHED(src, next_use_time)) + owner.balloon_alert(owner, "power unavailable!") + return FALSE + if(!bloodsuckerdatum_power) + var/mob/living/living_owner = owner + if(!HAS_TRAIT(living_owner, TRAIT_NOBLOOD) && living_owner.blood_volume <= bloodcost) + to_chat(owner, span_warning("You need at least [bloodcost] blood to activate [name]")) + return FALSE + return TRUE + + // Have enough blood? Bloodsuckers in a Frenzy don't need to pay them + if(bloodsuckerdatum_power.frenzied) + return TRUE + if(bloodsuckerdatum_power.GetBloodVolume() < bloodcost) + to_chat(owner, span_warning("You need at least [bloodcost] blood to activate [name]")) + return FALSE + return TRUE + +///Called when the Power is upgraded. +/datum/action/cooldown/bloodsucker/proc/upgrade_power() + SHOULD_CALL_PARENT(TRUE) + DeactivatePower() + if(level_current == -1) // -1 means it doesn't rank up ever + return FALSE + level_current++ + on_power_upgrade() + return TRUE + +/datum/action/cooldown/bloodsucker/proc/on_power_upgrade() + SHOULD_CALL_PARENT(TRUE) + desc = get_power_desc() + if(purchase_flags & TREMERE_CAN_BUY && level_current >= TREMERE_OBJECTIVE_POWER_LEVEL) + background_icon_state = "tremere_power_gold_off" + active_background_icon_state = "tremere_power_gold_on" + base_background_icon_state = "tremere_power_gold_off" + build_all_button_icons(ALL) + +///Checks if the Power is available to use. +/datum/action/cooldown/bloodsucker/proc/can_use(mob/living/carbon/user) + if(QDELETED(owner)) + return FALSE + if(!isliving(user)) + return FALSE + if(!(bloodsucker_check_flags & BP_CAN_USE_HEARTLESS) && bloodsuckerdatum_power && !owner.get_organ_slot(ORGAN_SLOT_HEART)) + to_chat(user, span_warning("To channel your powers you need a heart!")) + return FALSE + if(isbrain(user)) + to_chat(user, span_warning("What are you going to do, jump on someone and suck their blood? You're just a head.")) + return FALSE + // Torpor? + if((bloodsucker_check_flags & BP_CANT_USE_IN_TORPOR) && bloodsuckerdatum_power?.is_in_torpor()) + to_chat(user, span_warning("Not while you're in Torpor.")) + return FALSE + if(!(bloodsucker_check_flags & BP_CAN_USE_TRANSFORMED) && (user.has_status_effect(/datum/status_effect/shapechange_mob/from_spell) || user.has_status_effect(/datum/status_effect/shapechange_mob))) + to_chat(user, span_warning("You can't do this while transformed!")) + return FALSE + // Frenzy? + if((bloodsucker_check_flags & BP_CANT_USE_IN_FRENZY) && (bloodsuckerdatum_power?.frenzied)) + to_chat(user, span_warning("You cannot use powers while in a Frenzy!")) + return FALSE + // Stake? + if(!(bloodsucker_check_flags & BP_CAN_USE_WHILE_STAKED) && user.am_staked()) + to_chat(user, span_warning("You have a stake in your chest! Your powers are useless.")) + return FALSE + // Constant Cost (out of blood) + if(constant_bloodcost > 0 && !can_pay_blood(user)) + to_chat(user, span_warning("You don't have the blood to upkeep [src].")) + return FALSE + return TRUE + +/// NOTE: With this formula, you'll hit half cooldown at level 8 for that power. +/datum/action/cooldown/bloodsucker/StartCooldown(override_cooldown_time, override_melee_cooldown_time) + // Calculate Cooldown (by power's level) + if(!(power_flags & BP_AM_STATIC_COOLDOWN)) + var/custom_cooldown = max(initial(cooldown_time) / 2, initial(cooldown_time) - (initial(cooldown_time) / 16 * (level_current-1))) + // calling parent proc with custom args + return ..(custom_cooldown, override_melee_cooldown_time) + return ..() + +/datum/action/cooldown/bloodsucker/proc/can_pay_blood(mob/living/carbon/user) + return bloodsuckerdatum_power ? bloodsuckerdatum_power?.GetBloodVolume() >= 0 : user.blood_volume >= 0 + +/datum/action/cooldown/bloodsucker/proc/can_deactivate() + return TRUE + +/datum/action/cooldown/bloodsucker/is_action_active() + return active + +/datum/action/cooldown/bloodsucker/proc/pay_cost(cost_override) + // Non-bloodsuckers will pay in other ways. + if(!bloodsuckerdatum_power) + var/mob/living/living_owner = owner + var/blood_cost = cost_override ? cost_override : bloodcost + if(HAS_TRAIT(living_owner, TRAIT_NOBLOOD)) + living_owner.adjust_brute_loss(blood_cost * 0.1) + else + living_owner.blood_volume = max(0, living_owner.blood_volume - blood_cost) + return + // Bloodsuckers in a Frenzy don't have enough Blood to pay it, so just don't. + if(bloodsuckerdatum_power.frenzied) + return + bloodsuckerdatum_power.AdjustBloodVolume(cost_override ? -cost_override : -bloodcost) + +// TODO refactor the Trigger -> PreActivate -> Activate -> ActivatePower / set_click_ability -> Activate -> ActivatePower chain +/datum/action/cooldown/bloodsucker/Activate(atom/target) + if(active) + return FALSE + active = TRUE + . = ActivatePower(target) + if(!.) + DeactivatePower(DEACTIVATE_POWER_NO_COOLDOWN) + return FALSE + if(power_flags & BP_CONTINUOUS_EFFECT || constant_bloodcost) + START_PROCESSING(SSprocessing, src) + + owner.log_message("used [src][bloodcost != 0 ? " at the cost of [bloodcost]" : ""].", LOG_ATTACK, color="red") + build_all_button_icons(UPDATE_BUTTON_BACKGROUND) + +/datum/action/cooldown/bloodsucker/proc/RightClickActivate(trigger_flags) + if(!owner) + return FALSE + +/// return TRUE if you want the ability to be considered activated, put your ability activate logic here +/datum/action/cooldown/bloodsucker/proc/ActivatePower(atom/target) + return TRUE + +/datum/action/cooldown/bloodsucker/proc/DeactivatePower(deactivate_flags) + SHOULD_CALL_PARENT(TRUE) + if(!active) //Already inactive? Return + return FALSE + if(power_flags & BP_CONTINUOUS_EFFECT || constant_bloodcost) + STOP_PROCESSING(SSprocessing, src) + if(power_flags & BP_AM_SINGLEUSE && !(deactivate_flags & DEACTIVATE_POWER_DO_NOT_REMOVE)) + remove_after_use() + return FALSE + active = FALSE + if(!click_to_activate && !(deactivate_flags & DEACTIVATE_POWER_NO_COOLDOWN)) + StartCooldown() + build_all_button_icons(UPDATE_BUTTON_BACKGROUND) + return TRUE + +///Used by powers that are scontinuously active (That have BP_CONTINUOUS_EFFECT flag) +/datum/action/cooldown/bloodsucker/process(seconds_per_tick) + SHOULD_CALL_PARENT(TRUE) //Need this to call parent so the cooldown system works + . = ..() + if(!active || !(power_flags & BP_CONTINUOUS_EFFECT)) + return FALSE + if(!ContinueActive(owner)) // We can't afford the Power? Deactivate it. + DeactivatePower() + return FALSE + // We can keep this up (For now), so Pay Cost! + if(power_flags & BP_AM_COSTLESS_UNCONSCIOUS && owner.stat != CONSCIOUS) + return TRUE + if(constant_bloodcost < 0) + return TRUE + if(bloodsuckerdatum_power) + bloodsuckerdatum_power.AdjustBloodVolume(-constant_bloodcost * seconds_per_tick) + else + pay_cost(constant_bloodcost * seconds_per_tick) + return TRUE + +/// Checks to make sure this power can stay active +/datum/action/cooldown/bloodsucker/proc/ContinueActive(mob/living/user, mob/living/target) + if(QDELETED(user)) + return FALSE + if(!constant_bloodcost > 0 || can_pay_blood(user)) + return TRUE + +/// Used to unlearn Single-Use Powers +/datum/action/cooldown/bloodsucker/proc/remove_after_use() + bloodsuckerdatum_power?.powers -= src + Remove(owner) + +/datum/action/cooldown/bloodsucker/proc/get_power_explanation() + SHOULD_CALL_PARENT(TRUE) + . = list() + if(level_current != -1) + . += "LEVEL: [level_current] [name]:" + else + . += "(Inherent Power) [name]:" + + . += get_power_explanation_extended() + +/datum/action/cooldown/bloodsucker/proc/get_power_explanation_extended() + return list() + +/datum/action/cooldown/bloodsucker/proc/get_power_desc() + SHOULD_CALL_PARENT(TRUE) + var/new_desc = "" + if(level_current != -1) + new_desc += "
LEVEL: [level_current]" + else + new_desc += "
(Inherent Power)" + if(bloodcost > 0) + new_desc += "

COST: [bloodcost] Blood" + if(constant_bloodcost > 0) + new_desc += "

CONSTANT COST: [name] costs [constant_bloodcost] blood per second to keep it active." + if(power_flags & BP_AM_SINGLEUSE) + new_desc += "


SINGLE USE:
[name] can only be used once per night." + new_desc += "

DESCRIPTION: [get_power_desc_extended()]" + new_desc += "
" + return new_desc + +/datum/action/cooldown/bloodsucker/proc/get_power_desc_extended() + return initial(desc) diff --git a/tff_modular/modules/bloodsucker/powers/cloak.dm b/tff_modular/modules/bloodsucker/powers/cloak.dm new file mode 100644 index 00000000000..3165734f67f --- /dev/null +++ b/tff_modular/modules/bloodsucker/powers/cloak.dm @@ -0,0 +1,86 @@ +#define USE_SEEN_CLOAK_LEVEL 2 +#define USE_RUN_CLOAK_LEVEL 4 + +/datum/action/cooldown/bloodsucker/cloak + name = "Cloak of Darkness" + desc = "Blend into the shadows and become invisible to the untrained and Artificial eye." + button_icon_state = "power_cloak" + power_explanation = "Cloak of Darkness:\n\ + Activate this Power in the shadows and you will slowly turn nearly invisible.\n\ + While using Cloak of Darkness, attempting to run will crush you.\n\ + Additionally, while Cloak is active, you are completely invisible to the AI.\n\ + Higher levels will increase how invisible you are.\n\ + At level 2, you will no longer need to be unseen to activate this power.\n\ + At level 4, you will be able to run while cloaked." + power_flags = BP_CONTINUOUS_EFFECT + check_flags = AB_CHECK_CONSCIOUS + purchase_flags = BLOODSUCKER_CAN_BUY|GHOUL_CAN_BUY + bloodcost = 5 + constant_bloodcost = 0.2 + cooldown_time = 5 SECONDS + var/was_running + +/// Must have nobody around to see the cloak +/datum/action/cooldown/bloodsucker/cloak/can_use(mob/living/carbon/user, trigger_flags) + . = ..() + if(!.) + return FALSE + if(level_current < USE_SEEN_CLOAK_LEVEL) + for(var/mob/living/watcher in oviewers(9, owner)) + if(!watcher.mind) + continue + if(!can_see(watcher, owner)) + continue + if(IS_BLOODSUCKER(watcher) || IS_GHOUL(watcher)) + continue + owner.balloon_alert(owner, "you can only vanish unseen.") + return FALSE + return TRUE + +/datum/action/cooldown/bloodsucker/cloak/ActivatePower(atom/target) + var/mob/living/user = owner + was_running = (user.move_intent == MOVE_INTENT_RUN) + if(level_current < USE_RUN_CLOAK_LEVEL && was_running) + user.toggle_move_intent() + user.AddElement(/datum/element/digitalcamo) + user.balloon_alert(user, "cloak turned on.") + return TRUE + +/datum/action/cooldown/bloodsucker/cloak/process(seconds_per_tick) + // Checks that we can keep using this. + . = ..() + if(!.) + return + if(!active) + return + var/mob/living/user = owner + animate(user, alpha = max(25, owner.alpha - min(75, 10 + 5 * level_current)), time = 1.5 SECONDS) + // Prevents running while on Cloak of Darkness + if(level_current < USE_RUN_CLOAK_LEVEL && user.move_intent != MOVE_INTENT_WALK) + owner.balloon_alert(owner, "you attempt to run, crushing yourself.") + user.toggle_move_intent() + user.adjust_brute_loss(rand(5, 15)) + +/datum/action/cooldown/bloodsucker/cloak/ContinueActive(mob/living/user, mob/living/target) + . = ..() + if(!.) + return FALSE + /// Must be CONSCIOUS + if(user.stat != CONSCIOUS) + to_chat(owner, span_warning("Your cloak failed due to you falling unconcious!")) + return FALSE + return TRUE + +/datum/action/cooldown/bloodsucker/cloak/DeactivatePower(deactivate_flags) + . = ..() + if(!.) + return + var/mob/living/user = owner + animate(user, alpha = 255, time = 1 SECONDS) + user.RemoveElement(/datum/element/digitalcamo) + if(level_current < USE_RUN_CLOAK_LEVEL && was_running && user.move_intent == MOVE_INTENT_WALK) + user.toggle_move_intent() + user.balloon_alert(user, "cloak turned off.") + +#undef USE_SEEN_CLOAK_LEVEL +#undef USE_RUN_CLOAK_LEVEL diff --git a/tff_modular/modules/bloodsucker/powers/feed.dm b/tff_modular/modules/bloodsucker/powers/feed.dm new file mode 100644 index 00000000000..6f4e308a72b --- /dev/null +++ b/tff_modular/modules/bloodsucker/powers/feed.dm @@ -0,0 +1,458 @@ +#define FEED_NOTICE_RANGE 2 +#define FEED_DEFAULT_TIMER (10 SECONDS) +#define FEED_MIN_TIMER (1 SECONDS) + +/datum/action/cooldown/bloodsucker/feed + name = "Feed" + desc = "Feed blood off of a living creature. Feeding while aggressively grabbing them will put them to sleep for a short moment." + button_icon_state = "power_feed" + power_explanation = list( + "Activate Feed while next to someone and you will begin to feed blood off of them.", + "The time needed before you start feeding speeds up the higher level you are.", + "Feeding off of someone next to you will not be noticed by the victim, but it will by nearby onlookers", + "Feeding off of someone while you have them aggressively grabbed will put them to sleep.", + "While feeding, you can't speak, as your mouth is covered.", + "Feeding while nearby (2 tiles away from) a mortal who is unaware of Bloodsuckers' existence, will cause a Masquerade Infraction", + "If you get too many Masquerade Infractions, you will break the Masquerade.", + "If you are in desperate need of blood, mice can be fed off of, at a cost.", + "You must use the ability again to stop sucking blood.", + ) + level_current = -1 // scales itself based on your actual level, since you always have it + power_flags = BP_CONTINUOUS_EFFECT|BP_AM_STATIC_COOLDOWN + bloodsucker_check_flags = BP_CANT_USE_IN_TORPOR|BP_CAN_USE_WHILE_STAKED|BP_CAN_USE_HEARTLESS + purchase_flags = BLOODSUCKER_DEFAULT_POWER + bloodcost = 0 + cooldown_time = 15 SECONDS + + COOLDOWN_DECLARE(feed_movement_notify_cooldown) + ///Amount of blood taken, reset after each Feed. Used for logging. + var/blood_taken = 0 + ///The amount of Blood a target has since our last feed, this loops and lets us not spam alerts of low blood. + var/warning_target_bloodvol = BLOOD_VOLUME_MAX_LETHAL + ///Reference to the target we've fed off of + var/datum/weakref/target_ref + ///Have we notified you already that you are at maximum blood? + var/notified_overfeeding = FALSE + ///assoc list of weakrefs to targets and how much blood we've taken from them. + var/list/targets_and_blood = list() + /// What level of protection you need to prevent feeding + var/penetration = NONE + ///Did we start feeding with aggressive grab or not, or grabbed by someone else? + var/aggressive_feed = TRUE + +/datum/action/cooldown/bloodsucker/feed/get_power_explanation_extended() + . = list() + . += "Activate Feed while next to someone and you will begin to feed blood off of them." + . += "The time needed before you start feeding is [DisplayTimeText(get_feed_start_time())]." + . += "Feeding off of someone while you have them aggressively grabbed will put them to sleep for [DisplayTimeText(get_sleep_time())]." + . += "While feeding, you can't speak, as you are using your mouth to drink blood." + . += "Feeding while nearby ([FEED_NOTICE_RANGE] tiles away from) a mortal who is unaware of Bloodsuckers' existence, will cause a Masquerade Infraction" + . += "If you get too many Masquerade Infractions, you will break the Masquerade." + . += "If you are in desperate need of blood, mice can be fed off of, at a cost to your humanity." + . += "If you are handcuffed, you can use feed to feed off whoever is grabbing you, however this is slower, and very obvious." + . += "You must use the ability again to stop sucking blood." + +/datum/action/cooldown/bloodsucker/feed/can_use(mob/living/carbon/user, trigger_flags) + . = ..() + if(!.) + return FALSE + var/mob/target = target_ref?.resolve() + if(target) //already sucking blood. + var/aggro_feed = check_aggro_feed(target) + if(!ContinueActive(user, target, aggro_feed)) + target_ref = null + else + owner.balloon_alert(owner, "already feeding!") + return FALSE + if(user.is_mouth_covered() && !isplasmaman(user)) + owner.balloon_alert(owner, "mouth covered!") + return FALSE + //Find target, it will alert what the problem is, if any. + if(!find_target()) + return FALSE + return TRUE + +/datum/action/cooldown/bloodsucker/feed/ContinueActive(mob/living/user, mob/living/target, check_aggresive_grab) + if(!target) + return FALSE + if(!user.Adjacent(target)) + return FALSE + if(check_aggresive_grab && !check_aggro_feed(target)) + return FALSE + return TRUE + +/datum/action/cooldown/bloodsucker/feed/DeactivatePower(deactivate_flags) + // run before parent checks just to ensure that this always gets cleaned up + UnregisterSignal(owner, COMSIG_MOB_CLIENT_PRE_LIVING_MOVE) + REMOVE_TRAIT(owner, TRAIT_IMMOBILIZED, FEED_TRAIT) + REMOVE_TRAIT(owner, TRAIT_MUTE, FEED_TRAIT) + . = ..() + if(!.) + return + var/mob/living/user = owner + var/mob/living/feed_target = target_ref?.resolve() + + if(!blood_taken) + return + if(isnull(feed_target) && blood_taken) + log_combat(user, user, "fed on blood (target not found)", addition="(and took [blood_taken] blood)") + else + log_combat(user, feed_target, "fed on blood", addition="(and took [blood_taken] blood)") + to_chat(user, span_notice("You slowly release [feed_target].")) + if(feed_target.client && feed_target.stat == DEAD) + user.add_mood_event("drankkilled", /datum/mood_event/drankkilled) + bloodsuckerdatum_power?.AddHumanityLost(5) + + target_ref = null + warning_target_bloodvol = initial(warning_target_bloodvol) + blood_taken = initial(blood_taken) + notified_overfeeding = initial(notified_overfeeding) + +/datum/action/cooldown/bloodsucker/feed/ActivatePower(atom/target) + // if this happens this means that we didn't properly deactivate the power + if(HAS_TRAIT_FROM(owner, TRAIT_IMMOBILIZED, FEED_TRAIT) || HAS_TRAIT_FROM(owner, TRAIT_MUTE, FEED_TRAIT)) + DeactivatePower() + var/mob/living/feed_target = target_ref?.resolve() + if(!feed_target) + DeactivatePower() + return FALSE + if(istype(feed_target, /mob/living/basic/mouse)) + to_chat(owner, span_notice("You recoil at the taste of a lesser lifeform.")) + if(snobby_drinking_check()) + var/mob/living/user = owner + user.add_mood_event("drankblood", /datum/mood_event/drankblood_bad) + bloodsuckerdatum_power?.AddHumanityLost(1) + bloodsuckerdatum_power?.AdjustBloodVolume(25) + feed_target.death() + StartCooldown() + return FALSE + + owner.balloon_alert(owner, "feeding off [feed_target]...") + owner.face_atom(feed_target) + if(!do_after(owner, get_feed_start_time(), feed_target, hidden = TRUE)) + owner.balloon_alert(owner, "feed stopped") + target_ref = null + return FALSE + if(check_aggro_feed(feed_target)) + aggressive_feed = TRUE + if(!IS_BLOODSUCKER(feed_target) && !IS_GHOUL(feed_target) && !IS_MONSTERHUNTER(feed_target)) + feed_target.Unconscious(get_sleep_time()) + if(!feed_target.density) + feed_target.Move(owner.loc) + owner.visible_message( + span_warning("[owner] closes [owner.p_their()] mouth around [feed_target]'s neck!"), + span_warning("You sink your fangs into [feed_target]'s neck.")) + else + aggressive_feed = FALSE + // Only people who AREN'T the target will notice this action. + var/dead_message = feed_target.stat != DEAD ? " [feed_target.p_they(TRUE)] looks dazed, and will not notice this." : "" + owner.visible_message( + span_warning("[owner] puts [feed_target]'s wrist up to [owner.p_their()] mouth."), + span_notice("You slip your fangs into [feed_target]'s wrist.[dead_message]"), + vision_distance = FEED_NOTICE_RANGE, ignored_mobs = feed_target + ) + + check_if_seen(feed_target) + + ADD_TRAIT(owner, TRAIT_MUTE, FEED_TRAIT) + ADD_TRAIT(owner, TRAIT_IMMOBILIZED, FEED_TRAIT) + RegisterSignal(owner, COMSIG_MOB_CLIENT_PRE_LIVING_MOVE, PROC_REF(notify_move_block)) + return TRUE + +/datum/action/cooldown/bloodsucker/feed/proc/check_if_seen(mob/living/feed_target) + for(var/mob/living/watchers in oviewers(FEED_NOTICE_RANGE) - feed_target) + if(!watchers.client) + continue + if(watchers.stat >= DEAD) + continue + if(watchers.is_blind() || watchers.is_nearsighted_currently()) + continue + if(IS_BLOODSUCKER(watchers) || IS_GHOUL(watchers) || HAS_TRAIT(watchers.mind, TRAIT_BLOODSUCKER_HUNTER)) + continue + owner.balloon_alert(owner, "feed noticed!") + bloodsuckerdatum_power?.give_masquerade_infraction() + break + +/datum/action/cooldown/bloodsucker/feed/process(seconds_per_tick) + if(!active) //If we aren't active (running on SSfastprocess) + return ..() //Manage our cooldown timers + var/mob/living/user = owner + var/mob/living/feed_target = target_ref?.resolve() + if(!feed_target) + DeactivatePower() + return + if(!ContinueActive(user, feed_target, aggressive_feed)) + if(aggressive_feed) + user.visible_message( + span_warning("[user] is ripped from [feed_target]'s throat. [feed_target.p_Their(TRUE)] blood sprays everywhere!"), + span_warning("Your teeth are ripped from [feed_target]'s throat. [feed_target.p_Their(TRUE)] blood sprays everywhere!") + ) + // Deal Damage to Target (should have been more careful!) + if(iscarbon(feed_target)) + var/mob/living/carbon/carbon_target = feed_target + carbon_target.bleed(15) + playsound(get_turf(feed_target), 'sound/effects/splat.ogg', 40, TRUE) + if(ishuman(feed_target)) + var/mob/living/carbon/human/target_user = feed_target + var/obj/item/bodypart/head_part = target_user.get_bodypart(BODY_ZONE_HEAD) + if(head_part) + head_part.generic_bleedstacks += 5 + feed_target.add_splatter_floor(get_turf(feed_target)) + user.add_mob_blood(feed_target) // Put target's blood on us. The donor goes in the ( ) + feed_target.add_mob_blood(feed_target) + feed_target.apply_damage(10, BRUTE, BODY_ZONE_HEAD, wound_bonus = CANT_WOUND) + INVOKE_ASYNC(feed_target, TYPE_PROC_REF(/mob, emote), "scream") + DeactivatePower() + return + + var/feed_strength_mult = 0.3 + if(aggressive_feed) + feed_strength_mult = 1 + if(bloodsuckerdatum_power?.frenzied) + feed_strength_mult *= 2 + + var/already_drunk = targets_and_blood[target_ref] || 0 + var/blood_eaten = drink_blood(feed_target, feed_strength_mult, level_current, already_drunk) + blood_taken += blood_eaten + targets_and_blood[target_ref] += blood_eaten + modify_blood_drunk(blood_eaten * 0.5) + + if(feed_target.mind) + user.add_mood_event("drankblood", /datum/mood_event/drankblood) + // Drank mindless as Ventrue? - BAD + else if(snobby_drinking_check()) + user.add_mood_event("drankblood", /datum/mood_event/drankblood_bad) + if(feed_target.stat >= DEAD) + user.add_mood_event("drankblood", /datum/mood_event/drankblood_dead) + + if(!IS_BLOODSUCKER(feed_target)) + if(feed_target.blood_volume <= BLOOD_VOLUME_BAD && warning_target_bloodvol > BLOOD_VOLUME_BAD) + owner.balloon_alert(owner, "your victim's blood is fatally low!") + else if(feed_target.blood_volume <= BLOOD_VOLUME_OKAY && warning_target_bloodvol > BLOOD_VOLUME_OKAY) + owner.balloon_alert(owner, "your victim's blood is dangerously low.") + else if(feed_target.blood_volume <= BLOOD_VOLUME_SAFE && warning_target_bloodvol > BLOOD_VOLUME_SAFE) + owner.balloon_alert(owner, "your victim's blood is at an unsafe level.") + else if(feed_target.blood_volume <= BLOOD_VOLUME_SAFE && owner.pulling != feed_target) + owner.balloon_alert(owner, "you cannot drink more without first getting a better grip!.") + DeactivatePower() + return + warning_target_bloodvol = feed_target.blood_volume + + if(max_blood_reached(feed_target)) + var/message = "full on blood!" + var/can_overfeed = can_overfeed() + if(can_overfeed) + message += " Anything more we drink now will be burnt on quicker healing" + user.balloon_alert(owner, message) + if(!can_overfeed) + DeactivatePower() + return + notified_overfeeding = TRUE + if(feed_target.blood_volume <= 0) + user.balloon_alert(owner, "no blood left!") + DeactivatePower() + return + owner.playsound_local(get_turf(owner), 'sound/effects/singlebeat.ogg', 40, TRUE) + //play sound to target to show they're dying. + if(aggressive_feed) + feed_target.playsound_local(get_turf(src), 'sound/effects/singlebeat.ogg', 40, TRUE) + +/datum/action/cooldown/bloodsucker/feed/proc/drink_blood(mob/living/feed_target, feed_strength_mult, level_current, already_drunk) + // overridden in bloodsucker power.dm + var/feed_amount = 15 + (level_current * 2) + var/max_drink = feed_amount * feed_strength_mult + var/blood_eatable = min(max_drink, feed_target.blood_volume) + var/owner_blood_volume = 0 + + blood_eatable = apply_drink_modifiers(feed_target, blood_eatable) + + var/sigval = SEND_SIGNAL(owner, COMSIG_MOB_FEED_DRINK, feed_target, blood_eatable, already_drunk) + + if(!(sigval & FEED_CANCEL_BLOOD_TRANSFER)) + if(IS_BLOODSUCKER(owner)) + bloodsuckerdatum_power.handle_feeding(feed_target, blood_eatable, already_drunk) + owner_blood_volume = bloodsuckerdatum_power.GetBloodVolume() + + else if(isliving(owner) && !HAS_TRAIT(owner, TRAIT_NOBLOOD)) + var/mob/living/living_owner = owner + living_owner.blood_volume += blood_eatable + owner_blood_volume = living_owner.blood_volume + + if(feed_target.reagents && feed_target.reagents.total_volume) + feed_target.reagents.trans_to(owner, INGEST, 1) // Run transfer of 1 unit of reagent from them to me. + feed_target.blood_volume = max(0, feed_target.blood_volume - blood_eatable) + + if(owner_blood_volume > 0) + owner.bodytemperature = ((owner_blood_volume * owner.bodytemperature) + (blood_eatable * feed_target.bodytemperature)) / (owner_blood_volume + blood_eatable) + return blood_eatable + +/datum/action/cooldown/bloodsucker/feed/proc/apply_drink_modifiers(mob/living/feed_target, blood_eatable) + if(feed_target.stat == DEAD) // Penalty for Dead Blood + blood_eatable /= 3 + if(!ishuman(feed_target)) // Penalty for Non-Human Blood + blood_eatable /= 2 + else if(!feed_target?.mind) // Penalty for Mindless Blood + blood_taken /= 2 + return blood_eatable + +/datum/action/cooldown/bloodsucker/feed/proc/check_aggro_feed(mob/living/feed_target) + var/mob/living/carbon/carbon = owner + if(owner.pulling != feed_target && owner.pulledby != feed_target \ + || (feed_target.pulledby != owner && iscarbon(carbon) && carbon.handcuffed)) + return FALSE + return TRUE + +/datum/action/cooldown/bloodsucker/feed/proc/max_blood_reached(mob/living/feed_target) + if(bloodsuckerdatum_power && bloodsuckerdatum_power.GetBloodVolume() >= bloodsuckerdatum_power.max_blood_volume && !notified_overfeeding) + return TRUE + if(HAS_TRAIT(owner, TRAIT_NOBLOOD)) + return FALSE + var/sigval = SEND_SIGNAL(owner, COMSIG_MOB_REACHED_MAX_BLOOD, feed_target) + if(sigval & REACHED_MAX_BLOOD) + return TRUE + if(astype(owner, /mob/living).blood_volume >= BLOOD_VOLUME_MAXIMUM) + return TRUE + return FALSE + +/datum/action/cooldown/bloodsucker/proc/snobby_drinking_check() + if(bloodsuckerdatum_power?.my_clan && bloodsuckerdatum_power.my_clan.blood_drink_type != BLOODSUCKER_DRINK_INHUMANELY) + return TRUE + return TRUE + +/datum/action/cooldown/bloodsucker/feed/proc/find_target() + // grabbing or grabbed, you're close enough to bite. + if(safe_set_target(owner.pulling)) + return TRUE + if(safe_set_target(owner.pulledby)) + return TRUE + if(bloodsuckerdatum_power?.frenzied) + owner.balloon_alert(owner, "beast active! must grab someone to feed!") + return FALSE + var/mob/living/carbon/carbon = owner + if(iscarbon(carbon) && carbon.handcuffed) + owner.balloon_alert(owner, "you cannot stealthily feed while handcuffed!") + return FALSE + var/list/close_living_mobs = list() + var/list/close_dead_mobs = list() + for(var/mob/living/near_targets in oview(1, owner)) + if(!owner.Adjacent(near_targets)) + continue + if(near_targets.stat) + close_living_mobs |= near_targets + else + close_dead_mobs |= near_targets + //Check living first + for(var/mob/living/suckers in close_living_mobs) + if(can_feed_from(suckers)) + set_target(suckers) + return TRUE + //If not, check dead + for(var/mob/living/suckers in close_dead_mobs) + if(can_feed_from(suckers)) + set_target(suckers) + return TRUE + //No one to suck blood from. + return FALSE + +/datum/action/cooldown/bloodsucker/feed/proc/safe_set_target(mob/living/target, give_warnings = TRUE) + if(!can_feed_from(target, give_warnings)) + return FALSE + set_target(target) + return TRUE + +// this lets us compare and access things by weakrefs, if we use the actual same weakref instance in the assoc list +/datum/action/cooldown/bloodsucker/feed/proc/set_target(mob/living/target) + if(!length(targets_and_blood)) + target_ref = WEAKREF(target) + return + + for(var/datum/weakref/weakref as anything in targets_and_blood) + var/mob/living/old_target = weakref.resolve() + if(old_target == target) + target_ref = weakref + break + if(!target_ref) + target_ref = WEAKREF(target) + +/datum/action/cooldown/bloodsucker/feed/proc/can_feed_from(mob/living/target, give_warnings = FALSE) + if(istype(target, /mob/living/basic/mouse)) + if(snobby_drinking_check()) + if(give_warnings) + owner.balloon_alert(owner, "too disgusting!") + return FALSE + return TRUE + //Mice check done, only humans are otherwise allowed + if(!ishuman(target)) + return FALSE + + var/mob/living/carbon/human/target_user = target + if(!(target_user.dna?.species) || !(target_user.mob_biotypes & MOB_ORGANIC) || HAS_TRAIT(target_user, TRAIT_NOBLOOD)) + if(give_warnings) + owner.balloon_alert(owner, "no blood!") + return FALSE + if(!target_user.can_inject(owner, BODY_ZONE_HEAD, penetration)) + if(give_warnings) + owner.balloon_alert(owner, "headgear too thick!") + return FALSE + if(!can_overfeed() && max_blood_reached(target_user)) + if(give_warnings) + owner.balloon_alert(owner, "too full to drink more!") + return FALSE + if(!target.mind && !can_drink_from_mindless(target_user)) + if(give_warnings) + owner.balloon_alert(owner, "cant drink from mindless!") + return FALSE + if(target_user.has_reagent(/datum/reagent/consumable/garlic, 5)) + if(give_warnings) + owner.balloon_alert(owner, "too much garlic!") + return FALSE + return TRUE + +/datum/action/cooldown/bloodsucker/feed/proc/can_drink_from_mindless(mob/living/target) + if(!bloodsuckerdatum_power?.my_clan) + return TRUE + if(snobby_drinking_check() && !bloodsuckerdatum_power.frenzied) + return FALSE + return TRUE + +/datum/action/cooldown/bloodsucker/feed/proc/get_sleep_time() + return (5 + bloodsuckerdatum_power?.GetRank() || 1) SECONDS + +/datum/action/cooldown/bloodsucker/feed/proc/get_feed_start_time() + var/bloodsucker_level_divider = 1.25 * (bloodsuckerdatum_power?.GetRank() || 1) + var/feed_time = FEED_DEFAULT_TIMER / bloodsucker_level_divider + if(bloodsuckerdatum_power?.frenzied) + feed_time *= 0.5 + var/mob/living/carbon/carbon = owner + if(iscarbon(carbon) && carbon.handcuffed) + feed_time *= 2 + return clamp(round(feed_time), FEED_MIN_TIMER, FEED_DEFAULT_TIMER) + +/datum/action/cooldown/bloodsucker/feed/proc/notify_move_block() + SIGNAL_HANDLER + if(!active) + DeactivatePower() + return + if (!COOLDOWN_FINISHED(src, feed_movement_notify_cooldown)) + return + COOLDOWN_START(src, feed_movement_notify_cooldown, 3 SECONDS) + owner.balloon_alert(owner, "you cannot move while feeding! Click the power to stop.") + +/datum/action/cooldown/bloodsucker/feed/proc/modify_blood_drunk(amount = 0) + for(var/datum/weakref/weakref as anything in targets_and_blood) + if(weakref == target_ref) + continue + targets_and_blood[weakref] = max(0, targets_and_blood[weakref] - amount) + if(targets_and_blood[weakref] <= 0) + targets_and_blood -= weakref + +/datum/action/cooldown/bloodsucker/feed/proc/can_overfeed() + return IS_BLOODSUCKER(owner) + + +#undef FEED_NOTICE_RANGE +#undef FEED_DEFAULT_TIMER +#undef FEED_MIN_TIMER + + + diff --git a/tff_modular/modules/bloodsucker/powers/fortitude.dm b/tff_modular/modules/bloodsucker/powers/fortitude.dm new file mode 100644 index 00000000000..a306c7d113a --- /dev/null +++ b/tff_modular/modules/bloodsucker/powers/fortitude.dm @@ -0,0 +1,112 @@ +#define FORTITUDE_STUN_IMMUNITY_LEVEL 4 +/datum/action/cooldown/bloodsucker/fortitude + name = "Fortitude" + desc = "Withstand egregious physical wounds and walk away from attacks that would stun, pierce, and dismember lesser beings, but will render you unable to heal." + button_icon_state = "power_fortitude" + power_flags = BP_CONTINUOUS_EFFECT|BP_AM_COSTLESS_UNCONSCIOUS + check_flags = BP_CANT_USE_IN_TORPOR|BP_CANT_USE_IN_FRENZY + purchase_flags = BLOODSUCKER_CAN_BUY|GHOUL_CAN_BUY + cooldown_time = 20 SECONDS + bloodcost = 30 + constant_bloodcost = 0.2 + var/was_running + var/fortitude_resist // So we can raise and lower your brute resist based on what your level_current WAS. + var/list/trigger_listening = list() + var/traits_to_add = list(TRAIT_PIERCEIMMUNE, TRAIT_NODISMEMBER, TRAIT_PUSHIMMUNE) + +/datum/action/cooldown/bloodsucker/fortitude/get_power_explanation_extended() + . = list() + . += "Fortitude will provide pierce, stun and dismember immunity." + . += "You will additionally gain resistance to both brute, burn and stamina damage, scaling with level." + . += "Fortitude will make you receive [GetFortitudeResist() * 10]% less brute and and stamina and [GetBurnResist() * 10]% less burn damage." + . += "While using Fortitude, attempting to run will crush you." + . += "At level [FORTITUDE_STUN_IMMUNITY_LEVEL], you gain complete stun immunity while [src] is active." + . += "Higher levels will increase Brute and Stamina resistance." + +/datum/action/cooldown/bloodsucker/fortitude/upgrade_power() + . = ..() + if(level_current >= FORTITUDE_STUN_IMMUNITY_LEVEL) + traits_to_add |= TRAIT_STUNIMMUNE + +/datum/action/cooldown/bloodsucker/fortitude/ActivatePower(atom/target) + owner.balloon_alert(owner, "fortitude turned on.") + to_chat(owner, span_notice("Your flesh, skin, and muscles become as steel.")) + // Traits & Effects + owner.add_traits(traits_to_add, BLOODSUCKER_TRAIT) + + var/mob/living/carbon/human/bloodsucker_user = owner + if(IS_BLOODSUCKER(owner) || IS_GHOUL(owner)) + fortitude_resist = GetFortitudeResist() + bloodsucker_user.physiology.brute_mod *= fortitude_resist + bloodsucker_user.physiology.burn_mod *= GetBurnResist() + bloodsucker_user.physiology.stamina_mod *= fortitude_resist + + was_running = (bloodsucker_user.move_intent == MOVE_INTENT_RUN) + if(was_running) + bloodsucker_user.toggle_move_intent() + for(var/power in bloodsuckerdatum_power.powers) + if(!istype(power, /datum/action/cooldown/bloodsucker/targeted/haste)) + continue + RegisterSignal(power, COMSIG_FIRE_TARGETED_POWER, PROC_REF(on_action_trigger)) + trigger_listening += power + RegisterSignal(owner, COMSIG_LIVING_ADJUST_BRUTE_DAMAGE, PROC_REF(on_heal)) + RegisterSignal(owner, COMSIG_LIVING_ADJUST_BURN_DAMAGE, PROC_REF(on_heal)) + return TRUE + +/datum/action/cooldown/bloodsucker/fortitude/proc/on_heal(mob/current_mob, type, amount, forced) + if(!forced && active && amount < 0) + return COMPONENT_IGNORE_CHANGE + return NONE + +/datum/action/cooldown/bloodsucker/fortitude/proc/on_action_trigger(datum/action, mob/target) + SIGNAL_HANDLER + addtimer(CALLBACK(src, PROC_REF(DeactivatePower)), 1 SECONDS) + return TRUE + +/datum/action/cooldown/bloodsucker/fortitude/proc/GetFortitudeResist() + return max(0.3, 0.7 - level_current * 0.05) + +/datum/action/cooldown/bloodsucker/fortitude/proc/GetBurnResist() + return GetFortitudeResist() + 0.2 + +/datum/action/cooldown/bloodsucker/fortitude/process(seconds_per_tick) + // Checks that we can keep using this. + . = ..() + if(!.) + return + if(!active) + return + var/mob/living/carbon/user = owner + /// Prevents running while on Fortitude + if(user.move_intent != MOVE_INTENT_WALK) + user.toggle_move_intent() + user.balloon_alert(user, "you attempt to run, crushing yourself.") + user.adjust_brute_loss(rand(5,15)) + /// We don't want people using fortitude being able to use vehicles + if(user.buckled && istype(user.buckled, /obj/vehicle)) + user.buckled.unbuckle_mob(src, force=TRUE) + +/datum/action/cooldown/bloodsucker/fortitude/DeactivatePower(deactivate_flags) + if(length(trigger_listening)) + for(var/power in trigger_listening) + UnregisterSignal(power, COMSIG_FIRE_TARGETED_POWER) + trigger_listening -= power + . = ..() + if(!. || !ishuman(owner)) + return + var/mob/living/carbon/human/bloodsucker_user = owner + if(IS_BLOODSUCKER(owner) || IS_GHOUL(owner) && fortitude_resist) + bloodsucker_user.physiology.brute_mod /= fortitude_resist + bloodsucker_user.physiology.burn_mod /= fortitude_resist + 0.2 + bloodsucker_user.physiology.stamina_mod /= fortitude_resist + // Remove Traits & Effects + owner.remove_traits(traits_to_add, BLOODSUCKER_TRAIT) + + if(was_running && bloodsucker_user.move_intent == MOVE_INTENT_WALK) + bloodsucker_user.toggle_move_intent() + owner.balloon_alert(owner, "fortitude turned off.") + fortitude_resist = 1 + UnregisterSignal(owner, list(COMSIG_LIVING_ADJUST_BRUTE_DAMAGE, COMSIG_LIVING_ADJUST_BURN_DAMAGE)) + return ..() + +#undef FORTITUDE_STUN_IMMUNITY_LEVEL diff --git a/tff_modular/modules/bloodsucker/powers/gohome.dm b/tff_modular/modules/bloodsucker/powers/gohome.dm new file mode 100644 index 00000000000..33854eff513 --- /dev/null +++ b/tff_modular/modules/bloodsucker/powers/gohome.dm @@ -0,0 +1,138 @@ +#define GOHOME_START 0 +#define GOHOME_FLICKER_ONE 2 +#define GOHOME_FLICKER_TWO 4 +#define GOHOME_TELEPORT 6 + +/** + * Given to Bloodsuckers near Sol if they have a Coffin claimed. + * Teleports them to their Coffin after a delay. + * Makes them drop everything if someone witnesses the act. + */ +/datum/action/cooldown/bloodsucker/gohome + name = "Vanishing Act" + desc = "As dawn aproaches, disperse into mist and return directly to your Haven.
WARNING: You will drop ALL of your possessions if observed by mortals." + button_icon_state = "power_gohome" + active_background_icon_state = "vamp_power_off_oneshot" + base_background_icon_state = "vamp_power_off_oneshot" + power_flags = BP_CONTINUOUS_EFFECT | BP_AM_SINGLEUSE | BP_AM_STATIC_COOLDOWN + bloodsucker_check_flags = BP_CANT_USE_IN_FRENZY + check_flags = NONE + purchase_flags = NONE + bloodcost = 100 + cooldown_time = 10 SECONDS + power_activates_immediately = FALSE + level_current = -1 + + ///What stage of the teleportation are we in + var/teleporting_stage = GOHOME_START + ///The types of mobs that will drop post-teleportation. + var/static/list/spawning_mobs = list( + /mob/living/basic/mouse = 3, + /mob/living/basic/bat = 1, + ) + +/datum/action/cooldown/bloodsucker/gohome/get_power_explanation_extended() + . = list() + . += "Vanishing Act will, after a short delay, teleport the user to their Claimed Coffin." + . += "The user will drop all belongings if seen by a mortal." + . += "The power will cancel out if the Claimed Coffin is somehow destroyed." + . += "Immediately after activating, lights around the user will begin to flicker." + . += "Once the user teleports to their coffin, in their place will be a Rat or Bat." + +/datum/action/cooldown/bloodsucker/gohome/can_use(mob/living/carbon/user, trigger_flags) + . = ..() + if(!.) + return FALSE + /// Have No Haven (NOTE: You only got this power if you had a haven, so this means it's destroyed) + if(!istype(bloodsuckerdatum_power) || !bloodsuckerdatum_power.coffin) + owner.balloon_alert(owner, "coffin was destroyed!") + return FALSE + return TRUE + +/datum/action/cooldown/bloodsucker/gohome/ActivatePower(atom/target) + owner.balloon_alert(owner, "preparing to teleport...") + return TRUE + +/datum/action/cooldown/bloodsucker/gohome/DeactivatePower(deactivate_flags) + if(active && teleporting_stage != GOHOME_TELEPORT) + owner.balloon_alert(owner, "teleportation cancelled.") + teleporting_stage = GOHOME_START + return . = ..(DEACTIVATE_POWER_DO_NOT_REMOVE) + . = ..() + +/datum/action/cooldown/bloodsucker/gohome/process(seconds_per_tick) + . = ..() + if(!.) + return FALSE + + switch(teleporting_stage) + if(GOHOME_START) + INVOKE_ASYNC(src, PROC_REF(flicker_lights), 3, 20) + if(GOHOME_FLICKER_ONE) + INVOKE_ASYNC(src, PROC_REF(flicker_lights), 4, 40) + if(GOHOME_FLICKER_TWO) + INVOKE_ASYNC(src, PROC_REF(flicker_lights), 4, 60) + if(GOHOME_TELEPORT) + INVOKE_ASYNC(src, PROC_REF(teleport_to_coffin), owner) + teleporting_stage++ + +/datum/action/cooldown/bloodsucker/gohome/ContinueActive(mob/living/user, mob/living/target) + . = ..() + if(!.) + return FALSE + if(!isturf(owner.loc)) + return FALSE + if(!bloodsuckerdatum_power.coffin) + user.balloon_alert(user, "coffin destroyed!") + to_chat(owner, span_warning("Your coffin has been destroyed! You no longer have a destination.")) + return FALSE + return TRUE + +/datum/action/cooldown/bloodsucker/gohome/proc/flicker_lights(flicker_range, beat_volume) + for(var/obj/machinery/light/nearby_lights in view(flicker_range, get_turf(owner))) + nearby_lights.flicker(5) + playsound(get_turf(owner), 'sound/effects/singlebeat.ogg', beat_volume, 1) + +/datum/action/cooldown/bloodsucker/gohome/proc/teleport_to_coffin(mob/living/carbon/user) + var/drop_item = FALSE + var/turf/current_turf = get_turf(user) + // If we aren't in the dark, anyone watching us will cause us to drop out stuff + if(current_turf && current_turf.lighting_object && current_turf.get_lumcount() >= 0.2) + for(var/mob/living/watchers in viewers(world.view, get_turf(user)) - user) + if(QDELETED(watchers.client) || watchers.stat != CONSCIOUS) + continue + if(watchers.is_blind()) + continue + if(!IS_BLOODSUCKER(watchers) && !IS_GHOUL(watchers)) + drop_item = TRUE + break + // Drop all necessary items (handcuffs, legcuffs, items if seen) + user.uncuff() + if(drop_item) + for(var/obj/item/literally_everything in owner) + owner.dropItemToGround(literally_everything) + + playsound(current_turf, 'sound/effects/magic/summon_karp.ogg', 60, 1) + + var/datum/effect_system/steam_spread/bloodsucker/puff = new /datum/effect_system/steam_spread/bloodsucker() + puff.set_up(3, 0, current_turf) + puff.start() + + /// STEP FIVE: Create animal at prev location + var/mob/living/simple_animal/new_mob = pick_weight(spawning_mobs) + new new_mob(current_turf) + /// TELEPORT: Move to Coffin & Close it! + user.set_resting(TRUE, TRUE, FALSE) + do_teleport(user, bloodsuckerdatum_power.coffin, no_effects = TRUE, forced = TRUE, channel = TELEPORT_CHANNEL_QUANTUM) + bloodsuckerdatum_power.coffin.force_enter(user) + + DeactivatePower() + pay_cost() + +/datum/effect_system/steam_spread/bloodsucker + effect_type = /obj/effect/particle_effect/fluid/smoke/vampsmoke + +#undef GOHOME_START +#undef GOHOME_FLICKER_ONE +#undef GOHOME_FLICKER_TWO +#undef GOHOME_TELEPORT diff --git a/tff_modular/modules/bloodsucker/powers/masquerade.dm b/tff_modular/modules/bloodsucker/powers/masquerade.dm new file mode 100644 index 00000000000..a7e4af8d3d2 --- /dev/null +++ b/tff_modular/modules/bloodsucker/powers/masquerade.dm @@ -0,0 +1,115 @@ +/** + * # WITHOUT THIS POWER: + * + * - Mid-Blood: SHOW AS PALE + * - Low-Blood: SHOW AS DEAD + * - No Heartbeat + * - Examine shows actual blood + * - Thermal homeostasis (ColdBlooded) + * WITH THIS POWER: + * - Normal body temp -- remove Cold Blooded (return on deactivate) + */ + +/datum/action/cooldown/bloodsucker/masquerade + name = "Masquerade" + desc = "Feign the vital signs of a mortal, and escape both casual and medical notice as the monster you truly are." + button_icon_state = "power_human" + power_flags = BP_CONTINUOUS_EFFECT|BP_AM_STATIC_COOLDOWN|BP_AM_COSTLESS_UNCONSCIOUS + check_flags = NONE + bloodsucker_check_flags = BP_CANT_USE_IN_FRENZY + purchase_flags = BLOODSUCKER_DEFAULT_POWER + bloodcost = 10 + level_current = -1 + cooldown_time = 5 SECONDS + constant_bloodcost = 0.1 + +/datum/action/cooldown/bloodsucker/masquerade/get_power_explanation_extended() + . = list() + . += "Masquerade will forge your identity to be practically identical to that of a human." + . += "- You lose nearly all Bloodsucker benefits, including healing, sleep, radiation, crit, virus, gutting and cold immunity." + . += "- Your eyes turn to that of a regular human as your heart begins to beat." + . += "- You gain a Genetic sequence, and appear to have 100% blood when scanned by a Health Analyzer." + . += "- You will not appear as Pale when examined. Anything further than Pale, however, will not be hidden." + . += "At the end of a Masquerade, you will re-gain your Vampiric abilities, as well as lose any diseases you might have." + +/datum/action/cooldown/bloodsucker/masquerade/ActivatePower(atom/target) + var/mob/living/carbon/user = owner + owner.balloon_alert(owner, "masquerade turned on.") + to_chat(user, span_notice("Your heart beats falsely within your lifeless chest, and your eyes are no longer sensitive to the light. You may yet pass for a mortal.")) + to_chat(user, span_warning("Your vampiric healing is halted while imitating life.")) + + // Give status effect + user.apply_status_effect(/datum/status_effect/masquerade) + + // Handle Traits + user.remove_traits(bloodsuckerdatum_power.bloodsucker_traits, BLOODSUCKER_TRAIT) + + ADD_TRAIT(user, TRAIT_MASQUERADE, BLOODSUCKER_TRAIT) + var/obj/item/bodypart/chest/target_chest = user.get_bodypart(BODY_ZONE_CHEST) + if(target_chest) + target_chest.bodypart_flags &= ~BODYPART_UNREMOVABLE + // Handle organs + var/obj/item/organ/heart/vampheart = user.get_organ_slot(ORGAN_SLOT_HEART) + if(vampheart) + vampheart.Restart() + var/obj/item/organ/eyes/eyes = user.get_organ_slot(ORGAN_SLOT_EYES) + if(eyes) + eyes.flash_protect = initial(eyes.flash_protect) + eyes.color_cutoffs = initial(eyes.color_cutoffs) + eyes.sight_flags = initial(eyes.sight_flags) + user.update_sight() + return TRUE + +/// todo, make bloodsuckerification into it's own proc, ie, eyes, traits, and such +/datum/action/cooldown/bloodsucker/masquerade/DeactivatePower(deactivate_flags) + . = ..() // activate = FALSE + if(!.) + return + var/mob/living/carbon/user = owner + owner.balloon_alert(owner, "masquerade turned off.") + + // Remove status effect, mutations & diseases that you got while on masq. + user.remove_status_effect(/datum/status_effect/masquerade) + for(var/datum/disease/diseases as anything in user.diseases) + diseases.cure() + + // Handle Traits + user.add_traits(bloodsuckerdatum_power.bloodsucker_traits, BLOODSUCKER_TRAIT) + REMOVE_TRAIT(user, TRAIT_MASQUERADE, BLOODSUCKER_TRAIT) + var/obj/item/bodypart/chest/target_chest = user.get_bodypart(BODY_ZONE_CHEST) + if(target_chest) + target_chest.bodypart_flags |= BODYPART_UNREMOVABLE + // Handle organs + var/obj/item/organ/heart/vampheart = user.get_organ_slot(ORGAN_SLOT_HEART) + if(vampheart) + vampheart.Stop() + var/obj/item/organ/eyes/eyes = user.get_organ_slot(ORGAN_SLOT_EYES) + if(eyes) + eyes.flash_protect = max(initial(eyes.flash_protect) - 1, FLASH_PROTECTION_SENSITIVE) + eyes.color_cutoffs = BLOODSUCKER_SIGHT_COLOR_CUTOFF + eyes.sight_flags = SEE_MOBS + user.update_sight() + to_chat(user, span_notice("Your heart beats one final time, while your skin dries out and your icy pallor returns.")) + +/** + * # Status effect + * + * This is what the Masquerade power gives, handles their bonuses and gives them a neat icon to tell them they're on Masquerade. + */ + +/datum/status_effect/masquerade + id = "masquerade" + duration = STATUS_EFFECT_PERMANENT + duration = STATUS_EFFECT_NO_TICK + alert_type = /atom/movable/screen/alert/status_effect/masquerade + +/atom/movable/screen/alert/status_effect/masquerade + name = "Masquerade" + desc = "You are currently hiding your identity using the Masquerade power. This halts Vampiric healing." + icon = 'tff_modular/modules/bloodsucker/icons/bloodsucker.dmi' + icon_state = "power_human" + alerttooltipstyle = "cult" + +/atom/movable/screen/alert/status_effect/masquerade/MouseEntered(location,control,params) + desc = initial(desc) + return ..() diff --git a/tff_modular/modules/bloodsucker/powers/targeted/_powers_targeted.dm b/tff_modular/modules/bloodsucker/powers/targeted/_powers_targeted.dm new file mode 100644 index 00000000000..e41ecc0fc65 --- /dev/null +++ b/tff_modular/modules/bloodsucker/powers/targeted/_powers_targeted.dm @@ -0,0 +1,119 @@ +// NOTE: All Targeted spells are Toggles! We just don't bother checking here. +/datum/action/cooldown/bloodsucker/targeted + power_flags = NONE + click_to_activate = TRUE + ///If set, how far the target has to be for the power to work. + var/target_range + ///Message sent to chat when clicking on the power, before you use it. + var/prefire_message + ///Is this power LOCKED due to being used? + var/power_in_use = FALSE + +/// Modify description to add notice that this is aimed. +/datum/action/cooldown/bloodsucker/targeted/get_power_desc() + . = ..() + var/current_desc = "
\[Targeted Power\]" + if(target_range) + current_desc += "
Cast Range: [target_range]
" + current_desc += . + return current_desc + + +// *Don't read this if you don't care about how actions work.* +// Actions are a wee complicated, but for anyone else who's going to take a look at this, let me explain. +// Actions start at Trigger, which is/ called by the client clicking the action button, +// if it's a targeted power, like this one here, it will call set_click_ability, +// which will set up the click interception. Thus clicking will call Trigger again, but with a target this time. +// Otherwise, if click_to_activate is false, it will simply always call Trigger without a target, +// and call PreActivate, which then calls Activate. +// For this ability, we call InterceptClickOn to trigger the ability with a target, as we want +// to be able to use trigger_flags, which Activate doesn't have. + + +// If click_to_activate is true, only these two procs are called when the ability is clicked on +/datum/action/cooldown/bloodsucker/targeted/set_click_ability(mob/on_who) + // activate runs before + if(!PreActivate()) + return + . = ..() + if(prefire_message) + to_chat(owner, span_announce("[prefire_message]")) + +/datum/action/cooldown/bloodsucker/targeted/unset_click_ability(mob/on_who, refund_cooldown) + . = ..() + if(active) //todo refactor active into is_action_active() + DeactivatePower() + +/// Check if target is VALID (wall, turf, or character?) +/datum/action/cooldown/bloodsucker/targeted/proc/CheckValidTarget(atom/target_atom) + if(target_atom == owner) + return FALSE + if(!target_atom) + return FALSE + return TRUE + +/// Check if valid target meets conditions +/datum/action/cooldown/bloodsucker/targeted/proc/CheckCanTarget(atom/target_atom) + if(target_range) + // Out of Range + if(!(target_atom in view(target_range, owner))) + if(target_range > 1) // Only warn for range if it's greater than 1 + owner.balloon_alert(owner, "out of range.") + return FALSE + return istype(target_atom) + +/// Click Target +/datum/action/cooldown/bloodsucker/targeted/PreActivate(atom/target) + if(!target) + return ..() + // CANCEL RANGED TARGET check + if(power_in_use || !CheckValidTarget(target)) + return FALSE + // Valid? (return true means DON'T cancel power!) + if(!can_pay_cost() || !can_use(owner) || !CheckCanTarget(target)) + return FALSE + if(power_activates_immediately) + PowerActivatedSuccesfully() // Mesmerize pays only after success. + power_in_use = FALSE + return TRUE + +/datum/action/cooldown/bloodsucker/targeted/proc/FireTargetedPower(atom/target, params) + return FALSE + +/// Called on right click +/datum/action/cooldown/bloodsucker/targeted/proc/FireSecondaryTargetedPower(atom/target, params) + return FireTargetedPower(target, params) + +/datum/action/cooldown/bloodsucker/targeted/ActivatePower(atom/target) + . = ..() + if(!target) + return . + log_combat(owner, target, "used [name] on [target].") + return TRUE + +/datum/action/cooldown/bloodsucker/targeted/DeactivatePower(deactivate_flags) + . = ..() + if(!.) + return + // sometimes things will call DeactivatePower, but not unset_click_ability, so we have to unset the click interception here. + if(owner.click_intercept == src) // TODO test if this is no longer needed + owner.click_intercept = null + +/// The power went off! We now pay the cost of the power. +/datum/action/cooldown/bloodsucker/targeted/proc/PowerActivatedSuccesfully(cooldown_override, cost_override) + StartCooldown(cooldown_override) + unset_click_ability(owner) + pay_cost(cost_override) + // if(active) + // DeactivatePower() + +/datum/action/cooldown/bloodsucker/targeted/InterceptClickOn(mob/living/clicker, params, atom/target) + . = ..() + if(!.) + return FALSE + var/list/modifiers = params2list(params) + SEND_SIGNAL(src, COMSIG_FIRE_TARGETED_POWER, target) + if(LAZYACCESS(modifiers, RIGHT_CLICK)) + return FireSecondaryTargetedPower(target, modifiers) + else + return FireTargetedPower(target, modifiers) diff --git a/tff_modular/modules/bloodsucker/powers/targeted/brawn.dm b/tff_modular/modules/bloodsucker/powers/targeted/brawn.dm new file mode 100644 index 00000000000..fbcf1362629 --- /dev/null +++ b/tff_modular/modules/bloodsucker/powers/targeted/brawn.dm @@ -0,0 +1,229 @@ + +#define BRAWN_BREAKOUT_LEVEL 3 +#define BRAWN_AIRLOCK_LEVEL 4 +/datum/action/cooldown/bloodsucker/targeted/brawn + name = "Brawn" + desc = "Snap restraints, break lockers and doors at higher levels, or deal terrible damage with your bare hands." + button_icon_state = "power_strength" + purchase_flags = BLOODSUCKER_CAN_BUY|GHOUL_CAN_BUY + bloodcost = 10 + cooldown_time = 12 SECONDS + target_range = 1 + prefire_message = "Select a target." + +/datum/action/cooldown/bloodsucker/targeted/brawn/get_power_explanation_extended() + . = list() + . += "Click any person to bash into them, break restraints you have or knocking a grabber down. Only one of these can be done per use." + . += "Brawn will do [GetDamage()] brute damage to the target and knockdown them for [DisplayTimeText(GetKnockdown())]." + . += "Punching a Cyborg will heavily EMP them in addition to deal damage." + . += "At level [BRAWN_BREAKOUT_LEVEL], you get the ability to break closets open, additionally can both break restraints AND knock a grabber down in the same use." + . += "At level [BRAWN_AIRLOCK_LEVEL], you get the ability to bash airlocks open, as long as they aren't bolted." + . += "Higher levels will increase the damage and knockdown when punching someone." + +/datum/action/cooldown/bloodsucker/targeted/brawn/ActivatePower(atom/target) + // Did we break out of our handcuffs? + if(break_restraints()) + playsound(get_turf(owner), 'sound/effects/grillehit.ogg', 80, 1, -1) + PowerActivatedSuccesfully() + return FALSE + // Did we knock a grabber down? We can only do this while not also breaking restraints if strong enough. + if(owner.pulledby) + if(level_current >= BRAWN_BREAKOUT_LEVEL && escape_puller()) + PowerActivatedSuccesfully() + return FALSE + owner.balloon_alert(owner, "ability level too low to break free!") + // Did neither, now we can PUNCH. + if(HAS_TRAIT(owner, TRAIT_HANDS_BLOCKED)) + owner.balloon_alert(owner, "your hands are blocked!") + return FALSE + // check if we have atleast one arm + if(!owner.get_active_hand()) + owner.balloon_alert(owner, "you need a usable arm!") + return FALSE + return TRUE + +// Look at 'biodegrade.dm' for reference +/datum/action/cooldown/bloodsucker/targeted/brawn/proc/break_restraints() + var/mob/living/carbon/human/user = owner + ///Only one form of shackles removed per use + var/obj/handcuffed = user.get_item_by_slot(ITEM_SLOT_HANDCUFFED) + if(user.buckled && handcuffed && user.buckled.unbuckle_mob(user)) + user.visible_message( + span_warning("[user] breaks free of [user.buckled]!"), + span_warning("We break free of [user.buckled]!"), + ) + user.buckled = null + return TRUE + + // Breaks out of lockers + if(istype(user.loc, /obj/structure/closet)) + var/obj/structure/closet/closet = user.loc + if(!istype(closet)) + return FALSE + closet.visible_message( + span_warning("[closet] tears apart as [user] bashes it open from within!"), + span_warning("[closet] tears apart as you bash it open from within!"), + ) + to_chat(user, span_warning("We bash [closet] wide open!")) + addtimer(CALLBACK(src, PROC_REF(break_closet), user, closet), 1) + return TRUE + + // Remove both Handcuffs & Legcuffs in one step + var/legcuffed = user.get_item_by_slot(ITEM_SLOT_LEGCUFFED) + if(handcuffed || legcuffed) + var/hand_cuffs = user.clear_cuffs(handcuffed, TRUE) + var/leg_cuffs = user.clear_cuffs(legcuffed, TRUE) + if(hand_cuffs || leg_cuffs) + user.visible_message( + span_warning("[user] discards their restraints like it's nothing!"), + span_warning("We break through our restraints!"), + ) + return TRUE + + // Remove Straightjackets + if(user.wear_suit?.breakouttime) + var/obj/item/clothing/suit/straightjacket = user.get_item_by_slot(ITEM_SLOT_OCLOTHING) + user.visible_message( + span_warning("[user] rips straight through the [user.p_their()] [straightjacket]!"), + span_warning("We tear through our [straightjacket]!"), + ) + if(straightjacket && user.wear_suit == straightjacket) + qdel(straightjacket) + return TRUE + return FALSE + +// This is its own proc because its done twice, to repeat code copypaste. +/datum/action/cooldown/bloodsucker/targeted/brawn/proc/break_closet(mob/living/carbon/human/user, obj/structure/closet/closet) + if(closet) + closet.welded = FALSE + closet.locked = FALSE + closet.broken = TRUE + closet.open() + +/datum/action/cooldown/bloodsucker/targeted/brawn/proc/escape_puller() + var/mob/pulled_mob = owner.pulledby + var/pull_power = pulled_mob.grab_state + playsound(get_turf(pulled_mob), 'sound/effects/woodhit.ogg', 75, 1, -1) + // Knock Down (if Living) + if(isliving(pulled_mob)) + var/mob/living/hit_target = pulled_mob + hit_target.Knockdown(pull_power * 10 + 20) + // Knock Back (before Knockdown, which probably cancels pull) + var/send_dir = get_dir(owner, pulled_mob) + var/turf/turf_thrown_at = get_ranged_target_turf(pulled_mob, send_dir, pull_power) + owner.newtonian_move(send_dir) // Bounce back in 0 G + pulled_mob.throw_at(turf_thrown_at, pull_power, TRUE, owner, FALSE) // Throw distance based on grab state! Harder grabs punished more aggressively. + // /proc/log_combat(atom/user, atom/target, what_done, atom/object=null, addition=null) + log_combat(owner, pulled_mob, "used Brawn power") + owner.visible_message( + span_warning("[owner] tears free of [pulled_mob]'s grasp!"), + span_warning("You shrug off [pulled_mob]'s grasp!"), + ) + owner.pulledby = null // It's already done, but JUST IN CASE. + return TRUE + +/datum/action/cooldown/bloodsucker/targeted/brawn/FireTargetedPower(atom/target, params) + . = ..() + var/mob/living/user = owner + // Target Type: Mob + if(isliving(target)) + var/mob/living/target_atom = target + //You know what I'm just going to take the average of the user's limbs max damage instead of dealing with 2 hands + var/hitStrength = GetDamage() + // Knockdown! + var/powerlevel = GetPowerLevel() + if(rand(5 + powerlevel) >= 5) + target_atom.visible_message( + span_danger("[user] lands a vicious punch, sending [target_atom] away!"), \ + span_userdanger("[user] has landed a horrifying punch on you, sending you flying!"), + ) + target_atom.Knockdown(GetKnockdown()) + // Attack! + owner.balloon_alert(owner, "you punch [target_atom]!") + playsound(get_turf(target_atom), 'sound/items/weapons/punch4.ogg', 60, 1, -1) + user.do_attack_animation(target_atom, ATTACK_EFFECT_SMASH) + var/obj/item/bodypart/affecting = target_atom.get_bodypart(ran_zone(target_atom.zone_selected)) + target_atom.apply_damage(hitStrength, BRUTE, affecting) + // Knockback + var/send_dir = get_dir(owner, target_atom) + var/turf/turf_thrown_at = get_ranged_target_turf(target_atom, send_dir, powerlevel) + owner.newtonian_move(send_dir) // Bounce back in 0 G + target_atom.throw_at(turf_thrown_at, powerlevel, TRUE, owner) //new /datum/forced_movement(target_atom, get_ranged_target_turf(target_atom, send_dir, (hitStrength / 4)), 1, FALSE) + // Target Type: Cyborg (Also gets the effects above) + if(issilicon(target_atom)) + target_atom.emp_act(EMP_HEAVY) + // Target Type: Locker + else if(istype(target, /obj/structure/closet)) + if(level_current <= BRAWN_BREAKOUT_LEVEL) + target.balloon_alert(user, "ability level too low to break open!") + return FALSE + var/obj/structure/closet/target_closet = target + user.balloon_alert(user, "you prepare to bash [target_closet] open...") + if(!do_after(user, 2.5 SECONDS, target_closet)) + user.balloon_alert(user, "interrupted!") + return FALSE + target_closet.visible_message(span_danger("[target_closet] breaks open as [user] bashes it!")) + addtimer(CALLBACK(src, PROC_REF(break_closet), user, target_closet), 1) + playsound(get_turf(user), 'sound/effects/grillehit.ogg', 80, TRUE, -1) + // Target Type: Door + else if(istype(target, /obj/machinery/door)) + if(level_current <= BRAWN_AIRLOCK_LEVEL) + target.balloon_alert(user, "ability level too low to break open!") + return FALSE + var/obj/machinery/door/target_airlock = target + playsound(get_turf(user), 'sound/machines/airlock/airlock_alien_prying.ogg', 40, TRUE, -1) + owner.balloon_alert(owner, "you prepare to tear open [target_airlock]...") + if(!do_after(user, 2.5 SECONDS, target_airlock)) + user.balloon_alert(user, "interrupted!") + return FALSE + if(target_airlock.Adjacent(user)) + target_airlock.visible_message(span_danger("[target_airlock] breaks open as [user] bashes it!")) + user.Stun(10) + user.do_attack_animation(target_airlock, ATTACK_EFFECT_SMASH) + playsound(get_turf(target_airlock), 'sound/effects/bang.ogg', 30, 1, -1) + target_airlock.open(2) // open(2) is like a crowbar or jaws of life. + +/datum/action/cooldown/bloodsucker/targeted/brawn/proc/GetPowerLevel() + return min(5, 1 + level_current) + +/datum/action/cooldown/bloodsucker/targeted/brawn/proc/GetKnockdown() + return min(5, rand(10, 10 * GetPowerLevel())) + +/datum/action/cooldown/bloodsucker/targeted/brawn/proc/GetDamage() + var/mob/living/carbon/human/user = owner + var/obj/item/bodypart/user_active_arm + user_active_arm = user.get_active_hand() + if(!user || !user_active_arm) + return GetPunchDamage(initial(user_active_arm.unarmed_damage_high)) + return GetPunchDamage(user_active_arm.unarmed_damage_high) + +/datum/action/cooldown/bloodsucker/targeted/brawn/proc/GetPunchDamage(punch_damage) + return punch_damage * 1.25 + 2 + +/datum/action/cooldown/bloodsucker/targeted/brawn/CheckValidTarget(atom/target_atom) + . = ..() + if(!.) + return FALSE + return isliving(target_atom) || istype(target_atom, /obj/machinery/door) || istype(target_atom, /obj/structure/closet) + +/datum/action/cooldown/bloodsucker/targeted/brawn/CheckCanTarget(atom/target_atom) + // DEFAULT CHECKS (Distance) + . = ..() + if(!.) // Disable range notice for Brawn. + return FALSE + // Must outside Closet to target anyone! + if(!isturf(owner.loc)) + return FALSE + // Target Type: Living + if(isliving(target_atom)) + return TRUE + // Target Type: Door + else if(istype(target_atom, /obj/machinery/door)) + return TRUE + // Target Type: Locker + else if(istype(target_atom, /obj/structure/closet)) + return TRUE + return FALSE + +#undef BRAWN_BREAKOUT_LEVEL +#undef BRAWN_AIRLOCK_LEVEL diff --git a/tff_modular/modules/bloodsucker/powers/targeted/haste.dm b/tff_modular/modules/bloodsucker/powers/targeted/haste.dm new file mode 100644 index 00000000000..ce1a39b3b3b --- /dev/null +++ b/tff_modular/modules/bloodsucker/powers/targeted/haste.dm @@ -0,0 +1,120 @@ +/* Level 1: Speed to location + * Level 2: Dodge Bullets + * Level 3: Stun People Passed + */ + +#define HASTE_GETUP_LEVEL 3 +/datum/action/cooldown/bloodsucker/targeted/haste + name = "Immortal Haste" + desc = "Force yourself to stand up if you're down and dash somewhere with supernatural speed. Those nearby may be knocked away, stunned, or left empty-handed." + button_icon_state = "power_speed" + prefire_message = "You prepare to dash!" + purchase_flags = BLOODSUCKER_CAN_BUY|GHOUL_CAN_BUY + bloodcost = 6 + cooldown_time = 12 SECONDS + target_range = 5 + power_activates_immediately = FALSE + ///List of all people hit by our power, so we don't hit them again. + var/list/hit = list() + +/datum/action/cooldown/bloodsucker/targeted/haste/get_power_desc_extended() + . = "Dash to a location, knocking down anyone in your way, and refilling your stamina. Those nearby may be knocked away, stunned, or left empty-handed.\n" + if(level_current >= HASTE_GETUP_LEVEL) + . += "Dashing from lying down will get you up, but won't affect your foes." + else + . += "You cannot dash while knocked down." + +/datum/action/cooldown/bloodsucker/targeted/haste/get_power_explanation_extended() + . = list() + . += "Click anywhere to immediately dash towards that location." + . += "At level [HASTE_GETUP_LEVEL], if you are lying down, you will get up and regain your stamina, but the resulting dash will not knock down those nearby." + . += "Haste will knockdown your enemies for [DisplayTimeText(GetKnockdown())] and refill your stamina, but using haste while knocked down will make it go on cooldown for [DisplayTimeText(cooldown_time * 3)]" + . += "The Power will not work if you are lying down, in no gravity, or are aggressively grabbed." + . += "Anyone in your way during your Haste will be knocked down." + . += "Higher levels will increase the knockdown dealt to enemies." + . += "It will also refill your stamina so you can keep moving." + . += "If Fortitude is active, using haste will disable it." + +/datum/action/cooldown/bloodsucker/targeted/haste/can_use(mob/living/carbon/user, trigger_flags) + . = ..() + if(!.) + return FALSE + // Being Grabbed + if(user.pulledby && user.pulledby.grab_state >= GRAB_AGGRESSIVE) + user.balloon_alert(user, "you're being grabbed!") + return FALSE + if(!user.has_gravity(user.loc)) //We dont want people to be able to use this to fly around in space + user.balloon_alert(user, "you cannot dash while floating!") + return FALSE + if(level_current < HASTE_GETUP_LEVEL && user.body_position == LYING_DOWN) + user.balloon_alert(user, "you must be standing to dash!") + return FALSE + return TRUE + +/// Anything will do, if it's not mea or my square +/datum/action/cooldown/bloodsucker/targeted/haste/CheckValidTarget(atom/target_atom) + . = ..() + if(!.) + return FALSE + return target_atom.loc != owner.loc + +/// This is a non-async proc to make sure the power is "locked" until this finishes. +/datum/action/cooldown/bloodsucker/targeted/haste/FireTargetedPower(atom/target, params) + . = ..() + var/mob/living/user = owner + var/stuns_mobs = TRUE + var/temp_cooldown = cooldown_time + if(level_current >= HASTE_GETUP_LEVEL && user.body_position == LYING_DOWN) + to_chat(user, span_danger("Your heart takes a beat, and you force yourself to stand up!")) + user.SetKnockdown(0) + user.set_stamina_loss(0) + user.set_resting(FALSE, FALSE, TRUE) + stuns_mobs = FALSE + temp_cooldown = GetGetupCooldown() + if(stuns_mobs) + RegisterSignal(owner, COMSIG_MOVABLE_MOVED, PROC_REF(on_move)) + var/turf/targeted_turf = isturf(target) ? target : get_turf(target) + // Pulled? Not anymore. + user.pulledby?.stop_pulling() + // Go to target turf + // DO NOT USE WALK TO. + owner.balloon_alert(owner, "you dash into the air!") + playsound(get_turf(owner), 'sound/items/weapons/punchmiss.ogg', 25, 1, -1) + var/safety = get_dist(user, targeted_turf) * 3 + 1 + var/consequetive_failures = 0 + active = TRUE + while(--safety && (get_turf(user) != targeted_turf)) + var/success = step_towards(user, targeted_turf) //This does not try to go around obstacles. + if(!success) + success = step_to(user, targeted_turf) //this does + if(!success) + consequetive_failures++ + if(consequetive_failures >= 3) //if 3 steps don't work + break //just stop + else + consequetive_failures = 0 //reset so we can keep moving + if(user.resting || INCAPACITATED_IGNORING(user, INCAPABLE_GRAB|INCAPABLE_RESTRAINTS)) //actually down? stop. + break + if(success) //don't sleep if we failed to move. + sleep(world.tick_lag) + UnregisterSignal(owner, COMSIG_MOVABLE_MOVED) + hit.Cut() + user.adjust_stamina_loss(-user.staminaloss) + PowerActivatedSuccesfully(temp_cooldown) + +/datum/action/cooldown/bloodsucker/targeted/haste/proc/GetKnockdown() + return 10 + level_current * 4 + +/datum/action/cooldown/bloodsucker/targeted/haste/proc/GetGetupCooldown() + return cooldown_time * 3 + +/datum/action/cooldown/bloodsucker/targeted/haste/proc/on_move() + for(var/mob/living/hit_living in dview(1, get_turf(owner)) - owner) + if(hit.Find(hit_living)) + continue + hit += hit_living + playsound(hit_living, "sound/weapons/punch[rand(1,4)].ogg", 15, 1, -1) + hit_living.Knockdown(GetKnockdown()) + hit_living.spin(10, 1) + +#undef HASTE_GETUP_LEVEL diff --git a/tff_modular/modules/bloodsucker/powers/targeted/lunge.dm b/tff_modular/modules/bloodsucker/powers/targeted/lunge.dm new file mode 100644 index 00000000000..e519c3724d8 --- /dev/null +++ b/tff_modular/modules/bloodsucker/powers/targeted/lunge.dm @@ -0,0 +1,191 @@ + +#define LUNGE_INSTANT_LEVEL 4 +#define LUNGE_INSTANT_RANGE 6 +/datum/action/cooldown/bloodsucker/targeted/lunge + name = "Predatory Lunge" + desc = "Spring at your target to grapple them without warning, or tear the dead's heart out. Attacks from concealment or the rear may even knock them down if strong enough." + button_icon_state = "power_lunge" + check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_INCAPACITATED|AB_CHECK_LYING|AB_CHECK_PHASED|AB_CHECK_LYING + purchase_flags = BLOODSUCKER_CAN_BUY|GHOUL_CAN_BUY + bloodcost = 10 + cooldown_time = 10 SECONDS + power_activates_immediately = FALSE + unset_after_click = FALSE + +/datum/action/cooldown/bloodsucker/targeted/lunge/get_power_explanation_extended() + . = list() + . += "Click any player to start spinning wildly and, after a short delay, dash at them." + . += "When lunging at someone, you will grab them, immediately starting off at aggressive." + . += "Riot gear and Monster Hunters are protected and will only be passively grabbed." + . += "You cannot use the Power if you are already grabbing someone, or are being grabbed." + . += "If you grab from behind, or while using cloak of darkness, you will knock the target down." + . += "If used on a dead body, will tear out a random organ from the zone you are targeting." + . += "Higher levels increase how long enemies are knocked down." + . += "At level [LUNGE_INSTANT_LEVEL], you will no longer spin, but you will be limited to tackling from only [LUNGE_INSTANT_RANGE] tiles away." + +/datum/action/cooldown/bloodsucker/targeted/lunge/on_power_upgrade() + . = ..() + //range is lowered when you get stronger, since it's instant now. + if(level_current > LUNGE_INSTANT_LEVEL) + target_range = LUNGE_INSTANT_RANGE + +/datum/action/cooldown/bloodsucker/targeted/lunge/can_use(mob/living/carbon/user, trigger_flags) + . = ..() + if(!.) + return FALSE + // Are we being grabbed? + if(user.pulledby && user.pulledby.grab_state >= GRAB_AGGRESSIVE) + owner.balloon_alert(user, "grabbed!") + return FALSE + if(user.pulling) + owner.balloon_alert(user, "grabbing someone!") + return FALSE + return TRUE + +/// Check: Are we lunging at a person? +/datum/action/cooldown/bloodsucker/targeted/lunge/CheckValidTarget(atom/target_atom) + . = ..() + if(!.) + return FALSE + return isliving(target_atom) + +/datum/action/cooldown/bloodsucker/targeted/lunge/CheckCanTarget(atom/target_atom) + // Default Checks + . = ..() + if(!.) + return FALSE + // Check: Turf + var/mob/living/turf_target = target_atom + if(!isturf(turf_target.loc)) + return FALSE + return TRUE + +/datum/action/cooldown/bloodsucker/targeted/lunge/can_deactivate() + return !(datum_flags & DF_ISPROCESSING) //only if you aren't lunging + +/datum/action/cooldown/bloodsucker/targeted/lunge/FireTargetedPower(atom/target, params) + . = ..() + owner.face_atom(target) + if(level_current >= LUNGE_INSTANT_LEVEL) + do_lunge(target) + return + + prepare_target_lunge(target) + return TRUE + +///Starts processing the power and prepares the lunge by spinning, calls lunge at the end of it. +/datum/action/cooldown/bloodsucker/targeted/lunge/proc/prepare_target_lunge(atom/target_atom) + START_PROCESSING(SSprocessing, src) + owner.balloon_alert(owner, "lunge started!") + //animate them shake + var/base_x = owner.base_pixel_x + var/base_y = owner.base_pixel_y + animate(owner, pixel_x = base_x, pixel_y = base_y, time = 1, loop = -1) + for(var/i in 1 to 25) + var/x_offset = base_x + rand(-3, 3) + var/y_offset = base_y + rand(-3, 3) + animate(pixel_x = x_offset, pixel_y = y_offset, time = 1) + + if(!do_after(owner, 2 SECONDS, timed_action_flags = (IGNORE_USER_LOC_CHANGE|IGNORE_TARGET_LOC_CHANGE|IGNORE_SLOWDOWNS), extra_checks = CALLBACK(src, PROC_REF(CheckCanTarget), target_atom))) + end_target_lunge(base_x, base_y) + + return FALSE + + end_target_lunge() + do_lunge(target_atom) + return TRUE + +///When preparing to lunge ends, this clears it up. +/datum/action/cooldown/bloodsucker/targeted/lunge/proc/end_target_lunge(base_x, base_y) + animate(owner, pixel_x = base_x, pixel_y = base_y, time = 1) + STOP_PROCESSING(SSprocessing, src) + +/datum/action/cooldown/bloodsucker/targeted/lunge/process() + if(!active) //If running SSfasprocess (on cooldown) + return ..() //Manage our cooldown timers + if(prob(75)) + owner.spin(8, 1) + owner.balloon_alert_to_viewers("spins wildly!", "you spin!") + return + do_smoke(0, owner.loc, smoke_type = /obj/effect/particle_effect/fluid/smoke/transparent) + +///Actually lunges the target, then calls lunge end. +/datum/action/cooldown/bloodsucker/targeted/lunge/proc/do_lunge(atom/hit_atom) + var/turf/targeted_turf = get_turf(hit_atom) + + var/safety = get_dist(owner, targeted_turf) * 3 + 1 + var/consequetive_failures = 0 + while(--safety && !hit_atom.Adjacent(owner)) + if(!step_to(owner, targeted_turf)) + consequetive_failures++ + if(consequetive_failures >= 3) // If 3 steps don't work, just stop. + break + + lunge_end(hit_atom, targeted_turf) + +/datum/action/cooldown/bloodsucker/targeted/lunge/proc/lunge_end(atom/hit_atom, turf/target_turf) + PowerActivatedSuccesfully() + // Am I next to my target to start giving the effects? + if(!owner.Adjacent(hit_atom)) + return + + var/mob/living/user = owner + var/mob/living/carbon/target = hit_atom + + // Did I slip or get knocked unconscious? + if(user.body_position != STANDING_UP || user.incapacitated) + user.throw_at(target_turf, 12, 0.8) + user.spin(10) + return + // Is my target a Monster hunter? + if(HAS_TRAIT(target, TRAIT_BRAWLING_KNOCKDOWN_BLOCKED)) + user.balloon_alert(user, "pushed away!") + target.grabbedby(user) + return + + user.balloon_alert(user, "you lunge at [target]!") + user.changeNext_move(CLICK_CD_MELEE) + if(target.stat == DEAD) + var/obj/item/bodypart/bodypart = target.get_bodypart(check_zone(user.zone_selected)) + if(!bodypart) + target.balloon_alert(user, "bodypart missing!") + return + var/datum/wound/slash/flesh/moderate/crit_wound = new + crit_wound.sound_effect = null + crit_wound.apply_wound(bodypart) + user.visible_message( + span_warning("[user] tears into [target]'s [bodypart]!"), + span_warning("You tear into [target]'s [bodypart]!")) + playsound(target, 'sound/effects/wounds/crackandbleed.ogg', 100, TRUE, 5) + var/obj/item/organ/myheart_now + if(bodypart.body_zone == BODY_ZONE_CHEST) + myheart_now = target.get_organ_slot(ORGAN_SLOT_HEART) + if(!myheart_now) + var/list/organs = target.get_organs_for_zone(bodypart.body_zone) + if(!length(organs)) + to_chat(user, span_warning("[target] has no organs in [bodypart]!")) + target.balloon_alert(user, "no organs!") + return + myheart_now = pick(organs) + + if(myheart_now) + myheart_now.Remove(target) + user.put_in_hands(myheart_now) + + else + if(!is_source_facing_target(target, user) || user.alpha <= 40) + target.Knockdown(10 + level_current * 5) + target.Paralyze(0.1) + target.grabbedby(user) + target.grippedby(user, instant = TRUE) + // Did we knock them down? + + +/datum/action/cooldown/bloodsucker/targeted/lunge/DeactivatePower(deactivate_flags) + . = ..() + if(!.) + return + REMOVE_TRAIT(owner, TRAIT_IMMOBILIZED, BLOODSUCKER_TRAIT) + +#undef LUNGE_INSTANT_LEVEL +#undef LUNGE_INSTANT_RANGE diff --git a/tff_modular/modules/bloodsucker/powers/targeted/mesmerize.dm b/tff_modular/modules/bloodsucker/powers/targeted/mesmerize.dm new file mode 100644 index 00000000000..0bf234dd852 --- /dev/null +++ b/tff_modular/modules/bloodsucker/powers/targeted/mesmerize.dm @@ -0,0 +1,243 @@ +/** + * MEZMERIZE + * Locks a target in place for a certain amount of time. + * + * Level 2: Additionally mutes + * Level 3: Can be used through face protection + * Level 5: Doesn't need to be facing you anymore + */ + +#define MESMERIZE_MUTE_LEVEL 2 +#define MESMERIZE_GLASSES_LEVEL 3 +#define MESMERIZE_FACING_LEVEL 5 +/datum/action/cooldown/bloodsucker/targeted/mesmerize + name = "Mesmerize" + button_icon_state = "power_mez" + power_flags = NONE + purchase_flags = BLOODSUCKER_CAN_BUY|GHOUL_CAN_BUY + bloodcost = 30 + cooldown_time = 30 SECONDS + target_range = 4 + power_activates_immediately = FALSE + unset_after_click = FALSE + prefire_message = "Whom will you subvert to your will?" + ///Our mesmerized target - Prevents several mesmerizes. + var/datum/weakref/target_ref + /// How long it takes us to mesmerize our target. + var/mesmerize_delay = 5 SECONDS + /// At what level this ability will blind the target at. Level 0 = never. + var/blind_at_level = 0 + /// if the ability requires you to be physically facing the target + var/requires_facing_target = FALSE + /// if the ability requires you to not have your eyes covered + var/blocked_by_glasses = TRUE + /// if the ability will knockdown on secondary click + var/knockdown_on_secondary = FALSE + // string id timer of the current cast, used for combat glare + var/timer + // a cooldown to ensure you can't spam both the primary and secondary mesmerizes + COOLDOWN_DECLARE(mesmerize_cooldown) + +/datum/action/cooldown/bloodsucker/targeted/mesmerize/get_power_desc_extended() + . += "[src] a target, locking them in place for a short time[level_current >= MESMERIZE_MUTE_LEVEL ? " and muting them" : ""].
" + if(knockdown_on_secondary) + . += "Right clicking on your victim will apply a knockdown for [DisplayTimeText(combat_mesmerize_time())].
" + else + . += "Right clicking on your victim will confuse them for [DisplayTimeText(combat_mesmerize_time())]." + +/datum/action/cooldown/bloodsucker/targeted/mesmerize/get_power_explanation_extended() + . = list() + . += "Click any player to attempt to mesmerize them. This will stun the victim." + . += "The victim will realize they are being mesmerized, but will be unable to talk, but at level [MESMERIZE_MUTE_LEVEL] they will be also muted." + if(blocked_by_glasses && requires_facing_target) + . += "[src] requires you to not be wearing glasses and to be facing your target." + else if(blocked_by_glasses) + . += "[src] requires you to not be wearing glasses." + else if(requires_facing_target) + . += "[src] requires you to be facing your target." + . += "You cannot wear anything covering your face, and both parties must be facing eachother." + . += "Obviously, both parties need to not be blind." + . += "Right clicking with the ability will apply a knockdown for [DisplayTimeText(combat_mesmerize_time())], but will also confuse your victim for [DisplayTimeText(get_power_time())]." + . += "If your target is already mesmerized or a bloodsucker, the Power will fail." + . += "Once mesmerized, the target will be unable to move for [DisplayTimeText(get_power_time())] and muted for [DisplayTimeText(get_mute_time())], scaling with level." + . += "At level [MESMERIZE_GLASSES_LEVEL], you will be able to use the power through items covering your face." + . += "At level [MESMERIZE_FACING_LEVEL], you will be able to mesmerize regardless of your target's direction." + . += "Additionally it works on silicon lifeforms, causing a EMP effect instead of a freeze." + +/datum/action/cooldown/bloodsucker/targeted/mesmerize/can_use(mob/living/carbon/user, trigger_flags) + . = ..() + if(!.) // Default checks + return FALSE + if(!user.get_organ_slot(ORGAN_SLOT_EYES)) + // Cant use balloon alert, they've got no eyes! + to_chat(user, span_warning("You have no eyes with which to mesmerize.")) + return FALSE + // Check: Eyes covered? + if(blocked_by_glasses && istype(user) && (user.is_eyes_covered() && level_current <= 2) || !isturf(user.loc)) + user.balloon_alert(user, "your eyes are concealed from sight.") + return FALSE + return TRUE + +/datum/action/cooldown/bloodsucker/targeted/mesmerize/CheckValidTarget(atom/target_atom) + . = ..() + if(!.) + return FALSE + return isliving(target_atom) + +/datum/action/cooldown/bloodsucker/targeted/mesmerize/CheckCanTarget(atom/target_atom) + . = ..() + if(!.) + return FALSE + var/mob/living/current_target = target_atom // We already know it's carbon due to CheckValidTarget() + // No mind +#ifndef BLOODSUCKER_TESTING + if(!current_target.mind) + owner.balloon_alert(owner, "[current_target] is mindless.") + return FALSE +#endif + // Bloodsucker + if(IS_BLOODSUCKER(current_target)) + owner.balloon_alert(owner, "bloodsuckers are immune to [src].") + return FALSE + // Dead/Unconscious + if(current_target.stat > CONSCIOUS) + owner.balloon_alert(owner, "[current_target] is not [(current_target.stat == DEAD || HAS_TRAIT(current_target, TRAIT_FAKEDEATH)) ? "alive" : "conscious"].") + return FALSE + // Target has eyes? + if(!current_target.get_organ_slot(ORGAN_SLOT_EYES) && !issilicon(current_target)) + owner.balloon_alert(owner, "[current_target] has no eyes.") + return FALSE + // Target blind? + if(current_target.is_blind() && !issilicon(current_target)) + owner.balloon_alert(owner, "[current_target] is blind.") + return FALSE + // Facing target? + if(requires_facing_target && !is_source_facing_target(owner, current_target)) // in unsorted.dm + owner.balloon_alert(owner, "you must be facing [current_target].") + return FALSE + // Target facing me? (On the floor, they're facing everyone) + if(((current_target.mobility_flags & MOBILITY_STAND) && requires_facing_target && !is_source_facing_target(current_target, owner) && level_current <= MESMERIZE_FACING_LEVEL)) + owner.balloon_alert(owner, "[current_target] must be facing you.") + return FALSE + + // Gone through our checks, let's mark our guy. + target_ref = WEAKREF(current_target) + return TRUE + +/datum/action/cooldown/bloodsucker/targeted/mesmerize/FireTargetedPower(atom/target, params) + var/mob/living/user = owner + var/mob/living/carbon/mesmerized_target = target_ref?.resolve() + if(!COOLDOWN_FINISHED(src, mesmerize_cooldown)) + return + if(!mesmerized_target) + CRASH("mesmerized_target is null") + + perform_indicators(mesmerized_target, mesmerize_delay) + + if(issilicon(mesmerized_target)) + var/mob/living/silicon/mesmerized = mesmerized_target + mesmerized.emp_act(EMP_HEAVY) + owner.balloon_alert(owner, "temporarily shut [mesmerized] down.") + PowerActivatedSuccesfully() // PAY COST! BEGIN COOLDOWN! + return + // slow them down during the mesmerize + mute_target(mesmerized_target) + + COOLDOWN_START(src, mesmerize_cooldown, mesmerize_delay) + if(!do_after(user, mesmerize_delay, mesmerized_target, IGNORE_USER_LOC_CHANGE | IGNORE_TARGET_LOC_CHANGE, TRUE, extra_checks = CALLBACK(src, PROC_REF(ContinueActive), user, mesmerized_target))) + StartCooldown(cooldown_time * 0.5) + return + // Can't quite time it here, but oh well + to_chat(mesmerized_target, "[user]'s eyes look into yours, and [span_hypnophrase("you feel your mind slipping away")]...") + /*if(IS_MONSTERHUNTER(mesmerized_target)) + to_chat(mesmerized_target, span_notice("You feel your eyes burn for a while, but it passes.")) + return*/ + if(HAS_TRAIT_FROM_ONLY(mesmerized_target, TRAIT_NO_TRANSFORM, MESMERIZE_TRAIT)) + owner.balloon_alert(owner, "[mesmerized_target] is already in a hypnotic gaze.") + return + owner.balloon_alert(owner, "successfully mesmerized [mesmerized_target].") + mesmerize_effects(user, mesmerized_target) + PowerActivatedSuccesfully() // PAY COST! BEGIN COOLDOWN! + +/datum/action/cooldown/bloodsucker/targeted/mesmerize/FireSecondaryTargetedPower(atom/target, params) + if(!isliving(target)) + CRASH("[src] somehow casted on a non-living target, should have been stopped by CheckCanTarget.") + if(timer || !COOLDOWN_FINISHED(src, mesmerize_cooldown)) + return + COOLDOWN_START(src, mesmerize_cooldown, 2 SECONDS) + var/mob/living/mesmerized_target = target + owner.balloon_alert(owner, "gazing [mesmerized_target]...") + perform_indicators(mesmerized_target, 3 SECONDS) + timer = addtimer(CALLBACK(src, PROC_REF(combat_mesmerize_effects), owner, mesmerized_target), 2 SECONDS) + +/datum/action/cooldown/bloodsucker/targeted/mesmerize/proc/mesmerize_effects(mob/living/user, mob/living/mesmerized_target) + var/power_time = get_power_time() + mute_target(mesmerized_target) + mesmerized_target.Immobilize(power_time) + mesmerized_target.next_move = world.time + power_time // <--- Use direct change instead. We want an unmodified delay to their next move // mesmerized_target.changeNext_move(power_time) // check click.dm + ADD_TRAIT(mesmerized_target, TRAIT_NO_TRANSFORM, MESMERIZE_TRAIT) // <--- Fuck it. We tried using next_move, but they could STILL resist. We're just doing a hard freeze. + addtimer(CALLBACK(src, PROC_REF(end_mesmerize), user, mesmerized_target), power_time) + +/datum/action/cooldown/bloodsucker/targeted/mesmerize/proc/combat_mesmerize_effects(mob/living/user, mob/living/mesmerized_target) + if(!ContinueActive(user, mesmerized_target)) + StartCooldown(cooldown_time * 0.5) + owner.balloon_alert(owner, "failed!") + return + to_chat(mesmerized_target, "[src]'s eyes look into yours, and [span_hypnophrase("your head becomes fuzzy for a moment")]...") + var/effect_time = combat_mesmerize_time() + mute_target(mesmerized_target) + if(knockdown_on_secondary) + mesmerized_target.Knockdown(effect_time) + else + mesmerized_target.adjust_confusion(effect_time) + PowerActivatedSuccesfully(cost_override = bloodcost * 0.5) + +/datum/action/cooldown/bloodsucker/targeted/mesmerize/proc/get_power_time() + return 9 SECONDS + level_current * 1 SECONDS + +/datum/action/cooldown/bloodsucker/targeted/mesmerize/proc/get_mute_time() + return get_power_time() + +/datum/action/cooldown/bloodsucker/targeted/mesmerize/proc/combat_mesmerize_time() + return get_power_time() * 0.3 + +/datum/action/cooldown/bloodsucker/targeted/mesmerize/proc/blind_target(mob/living/mesmerized_target) + if(!blind_at_level && level_current < blind_at_level) + return + mesmerized_target.become_blind(MESMERIZE_TRAIT) + +/datum/action/cooldown/bloodsucker/targeted/mesmerize/proc/mute_target(mob/living/mesmerized_target) + if(level_current >= MESMERIZE_MUTE_LEVEL) + mesmerized_target.set_silence_if_lower(get_mute_time()) + +/datum/action/cooldown/bloodsucker/targeted/mesmerize/DeactivatePower(deactivate_flags) + . = ..() + target_ref = null + timer = null + +/datum/action/cooldown/bloodsucker/targeted/mesmerize/proc/end_mesmerize(mob/living/user, mob/living/target) + REMOVE_TRAIT(target, TRAIT_NO_TRANSFORM, MESMERIZE_TRAIT) + target.cure_blind(MESMERIZE_TRAIT) + // They Woke Up! (Notice if within view) + if(istype(user) && target.stat == CONSCIOUS && (target in view(target_range, get_turf(user)))) + target.balloon_alert(owner, "[target] snapped out of their trance.") + +/datum/action/cooldown/bloodsucker/targeted/mesmerize/ContinueActive(mob/living/user, mob/living/target) + return ..() && can_use(user) && CheckCanTarget(target) + +/datum/action/cooldown/bloodsucker/targeted/mesmerize/proc/perform_indicators(mob/target, duration) + // Display an animated overlay over our head to indicate what's going on + eldritch_eye(target, "eye_open", 1 SECONDS) + var/main_duration = max(duration - 2 SECONDS, 1 SECONDS) + addtimer(CALLBACK(src, PROC_REF(eldritch_eye), target, "eye_flash", main_duration), 1 SECONDS) + addtimer(CALLBACK(src, PROC_REF(eldritch_eye), target, "eye_close", 1 SECONDS), main_duration + 1 SECONDS) + +/// Display an animated overlay over our head to indicate what's going on +/datum/action/cooldown/bloodsucker/targeted/mesmerize/proc/eldritch_eye(mob/target, icon_state = "eye_open", duration = 1 SECONDS) + var/image/image = image('icons/effects/eldritch.dmi', owner, icon_state, ABOVE_ALL_MOB_LAYER, pixel_x = -owner.pixel_x, pixel_y = 28) /// TODO make this disable cloak + SET_PLANE_EXPLICIT(image, ABOVE_LIGHTING_PLANE, owner) + flick_overlay_global(image, list(owner?.client, target?.client), duration) + +#undef MESMERIZE_GLASSES_LEVEL +#undef MESMERIZE_FACING_LEVEL +#undef MESMERIZE_MUTE_LEVEL diff --git a/tff_modular/modules/bloodsucker/powers/targeted/trespass.dm b/tff_modular/modules/bloodsucker/powers/targeted/trespass.dm new file mode 100644 index 00000000000..22f423b1cb5 --- /dev/null +++ b/tff_modular/modules/bloodsucker/powers/targeted/trespass.dm @@ -0,0 +1,109 @@ +/datum/action/cooldown/bloodsucker/targeted/trespass + name = "Trespass" + desc = "Become mist and advance two tiles in one direction. Useful for skipping past doors and barricades." + button_icon_state = "power_tres" + bloodsucker_check_flags = BP_CANT_USE_IN_TORPOR + purchase_flags = BLOODSUCKER_CAN_BUY|GHOUL_CAN_BUY + bloodcost = 10 + cooldown_time = 8 SECONDS + prefire_message = "Select a destination." + target_range = 2 + var/turf/target_turf // We need to decide where we're going based on where we clicked. It's not actually the tile we clicked. + +/datum/action/cooldown/bloodsucker/targeted/trespass/get_power_explanation_extended() + . = list() + . += "Click anywhere [target_range] tiles away from you to teleport." + . += "This power goes through all obstacles except Walls." + . += "Higher levels decrease the sound played from using the Power, and increase the speed of the transition." + . += "It takes [DisplayTimeText(GetTeleportDelay())] to teleport." + +/datum/action/cooldown/bloodsucker/targeted/trespass/can_use(mob/living/carbon/user, trigger_flags) + . = ..() + if(!.) + return FALSE + if(HAS_TRAIT(user, TRAIT_NO_TRANSFORM) || !get_turf(user)) + return FALSE + return TRUE + +/datum/action/cooldown/bloodsucker/targeted/trespass/CheckValidTarget(atom/target_atom) + . = ..() + if(!.) + return FALSE + // Can't target my tile + if(target_atom == get_turf(owner) || get_turf(target_atom) == get_turf(owner)) + return FALSE + return TRUE // All we care about is destination. Anything you click is fine. + +/datum/action/cooldown/bloodsucker/targeted/trespass/CheckCanTarget(atom/target_atom) + // NOTE: Do NOT use ..()! We don't want to check distance or anything. + + // Get clicked tile + var/final_turf = isturf(target_atom) ? target_atom : get_turf(target_atom) + + // Are either tiles WALLS? + var/turf/from_turf = get_turf(owner) + var/this_dir // = get_dir(from_turf, target_turf) + for(var/i = 1 to 2) + // Keep Prev Direction if we've reached final turf + if(from_turf != final_turf) + this_dir = get_dir(from_turf, final_turf) // Recalculate dir so we don't overshoot on a diagonal. + from_turf = get_step(from_turf, this_dir) + // ERROR! Wall! + if(iswallturf(from_turf)) + var/wallwarning = (i == 1) ? "in the way" : "at your destination" + owner.balloon_alert(owner, "there is a wall [wallwarning].") + return FALSE + // Done + target_turf = from_turf + + return TRUE + +/datum/action/cooldown/bloodsucker/targeted/trespass/FireTargetedPower(atom/target, params) + . = ..() + + // Find target turf, at or below Atom + var/mob/living/carbon/user = owner + var/turf/my_turf = get_turf(owner) + + user.visible_message( + span_warning("[user]'s form dissipates into a cloud of mist!"), + span_notice("You disspiate into formless mist."), + ) + // Effect Origin + var/sound_strength = max(60, 70 - level_current * 10) + playsound(get_turf(owner), 'sound/effects/magic/summon_karp.ogg', sound_strength, 1) + var/datum/effect_system/steam_spread/bloodsucker/puff = new /datum/effect_system/steam_spread() + puff.set_up(3, 0, my_turf) + puff.start() + + var/mist_delay = GetTeleportDelay() // Level up and do this faster. + + // Freeze Me + user.Stun(mist_delay, ignore_canstun = TRUE) + user.density = FALSE + var/invis_was = user.invisibility + user.invisibility = INVISIBILITY_MAXIMUM + + // Wait... + sleep(mist_delay / 2) + // Move & Freeze + if(isturf(target_turf)) + do_teleport(owner, target_turf, no_effects=TRUE, channel = TELEPORT_CHANNEL_QUANTUM) // in teleport.dm? + user.Stun(mist_delay / 2, ignore_canstun = TRUE) + + // Wait... + sleep(mist_delay / 2) + // Un-Hide & Freeze + user.dir = get_dir(my_turf, target_turf) + user.Stun(mist_delay / 2, ignore_canstun = TRUE) + user.density = 1 + user.invisibility = invis_was + // Effect Destination + playsound(get_turf(owner), 'sound/effects/magic/summon_karp.ogg', 60, 1) + puff = new /datum/effect_system/steam_spread/() + puff.effect_type = /obj/effect/particle_effect/fluid/smoke/vampsmoke + puff.set_up(3, 0, target_turf) + puff.start() + +/datum/action/cooldown/bloodsucker/targeted/trespass/proc/GetTeleportDelay() + return max(5, 20 - level_current * 2.5) diff --git a/tff_modular/modules/bloodsucker/powers/tremere/_powers_tremere.dm b/tff_modular/modules/bloodsucker/powers/tremere/_powers_tremere.dm new file mode 100644 index 00000000000..60b8fe125cb --- /dev/null +++ b/tff_modular/modules/bloodsucker/powers/tremere/_powers_tremere.dm @@ -0,0 +1,22 @@ +/** + * # Tremere Powers + * + * This file is for Tremere power procs and Bloodsucker procs that deals exclusively with Tremere. + * Tremere has quite a bit of unique things to it, so I thought it's own subtype would be nice + */ + +/datum/action/cooldown/bloodsucker/targeted/tremere + name = "Tremere Gift" + desc = "" + power_explanation = "" + active_background_icon_state = "tremere_power_on" + base_background_icon_state = "tremere_power_off" + button_icon = 'tff_modular/modules/bloodsucker/icons/tremere_bloodsucker.dmi' + background_icon = 'tff_modular/modules/bloodsucker/icons/tremere_bloodsucker.dmi' + + level_current = 0 + // Re-defining these as we want total control over them + power_flags = BP_AM_STATIC_COOLDOWN + // Targeted stuff + unset_after_click = FALSE + diff --git a/tff_modular/modules/bloodsucker/powers/tremere/auspex.dm b/tff_modular/modules/bloodsucker/powers/tremere/auspex.dm new file mode 100644 index 00000000000..4acab01649f --- /dev/null +++ b/tff_modular/modules/bloodsucker/powers/tremere/auspex.dm @@ -0,0 +1,120 @@ +/** + * # Auspex + * + * Level 1 - Cloak of Darkness until clicking an area, teleports the user to the selected area (max 2 tile) + * Level 2 - Cloak of Darkness until clicking an area, teleports the user to the selected area (max 3 tiles) + * Level 3 - Cloak of Darkness until clicking an area, teleports the user to the selected area + * Level 4 - Cloak of Darkness until clicking an area, teleports the user to the selected area, causes nearby people to bleed. + * Level 5 - Cloak of Darkness until clicking an area, teleports the user to the selected area, causes nearby people to fall asleep. + */ + +#define AUSPEX_BLOOD_COST_PER_TILE 5 +#define AUSPEX_BLEED_LEVEL 4 +#define AUSPEX_KNOCKDOWN_LEVEL 5 +#define AUSPEX_ANYWHERE_LEVEL 6 +/datum/action/cooldown/bloodsucker/targeted/tremere/auspex + name = "Auspex" + level_current = 1 + button_icon_state = "power_auspex" + bloodsucker_check_flags = BP_CANT_USE_IN_TORPOR + purchase_flags = TREMERE_CAN_BUY + bloodcost = 10 + constant_bloodcost = 1 + cooldown_time = 12 SECONDS + target_range = 2 + power_activates_immediately = FALSE + prefire_message = "Right click to teleport" + +/datum/action/cooldown/bloodsucker/targeted/tremere/auspex/on_power_upgrade() + // 1 + for default, the other + is for the upgrade that hasn't been added yet. + if(level_current >= AUSPEX_ANYWHERE_LEVEL) + target_range = 0 + else + target_range = min(level_current + 2, 10) + . = ..() + +/datum/action/cooldown/bloodsucker/targeted/tremere/auspex/get_power_desc_extended() + . = "Hide yourself within a Cloak of Darkness, click on a tile to teleport" + . = "Costs [AUSPEX_BLOOD_COST_PER_TILE] blood per tile teleported." + if(target_range) + . += " up to [target_range] tiles away." + else + . += " anywhere you can see." + if(level_current >= AUSPEX_BLEED_LEVEL) + if(level_current >= AUSPEX_KNOCKDOWN_LEVEL) + . += " This will cause people at your destination to start bleeding and fall asleep." + else + . += " This will cause people at your destination to start bleeding." + +/datum/action/cooldown/bloodsucker/targeted/tremere/auspex/get_power_explanation_extended() + . = list() + . += "When Activated, you will be hidden in a Cloak of Darkness." + . += "[target_range ? "Click to teleport up to [target_range] tiles away, as long as you can see it" : "You can teleport anywhere you can see"]." + . += "Teleporting will refill your stamina to full." + . += "At level [AUSPEX_BLEED_LEVEL] you will cause people at your end location to start bleeding." + . += "At level [AUSPEX_KNOCKDOWN_LEVEL] you will cause people at your end location to be knocked down." + . += "At level [AUSPEX_ANYWHERE_LEVEL] you will be able to teleport anywhere, even if you cannot properly see the tile." + . += "The power will cost [AUSPEX_BLOOD_COST_PER_TILE] blood per tile that you teleport." + +/datum/action/cooldown/bloodsucker/targeted/tremere/auspex/CheckValidTarget(atom/target_atom) + . = ..() + if(!.) + return FALSE + if(!isturf(target_atom)) + return FALSE + var/turf/target_turf = target_atom + if(target_turf.is_blocked_turf_ignore_climbable()) + return FALSE + if(level_current < AUSPEX_ANYWHERE_LEVEL && !(target_turf in view(owner.client.view, owner.client))) + owner.balloon_alert(owner, "out of view!") + return FALSE + return TRUE + +/datum/action/cooldown/bloodsucker/targeted/tremere/auspex/ActivatePower(trigger_flags) + . = ..() + owner.AddElement(/datum/element/digitalcamo) + animate(owner, alpha = 15, time = 2 SECONDS) + return TRUE + +/datum/action/cooldown/bloodsucker/targeted/tremere/auspex/DeactivatePower(deactivate_flags) + . = ..() + if(!.) + return FALSE + animate(owner, alpha = 255, time = 2 SECONDS) + owner.RemoveElement(/datum/element/digitalcamo) + +/datum/action/cooldown/bloodsucker/targeted/tremere/auspex/FireSecondaryTargetedPower(atom/target, params) + . = ..() + var/mob/living/user = owner + var/turf/targeted_turf = get_turf(target) + auspex_blink(user, targeted_turf) + +/datum/action/cooldown/bloodsucker/targeted/tremere/auspex/proc/auspex_blink(mob/living/user, turf/targeted_turf) + var/blood_cost = AUSPEX_BLOOD_COST_PER_TILE * get_dist(user, targeted_turf) + if(!can_pay_blood(blood_cost)) + owner.balloon_alert(owner, "not enough blood!") + return + playsound(user, 'sound/effects/magic/summon_karp.ogg', 60) + playsound(targeted_turf, 'sound/effects/magic/summon_karp.ogg', 60) + + new /obj/effect/particle_effect/fluid/smoke/vampsmoke(user.drop_location()) + new /obj/effect/particle_effect/fluid/smoke/vampsmoke(targeted_turf) + + for(var/mob/living/carbon/living_mob in range(1, targeted_turf)-user) + if(IS_BLOODSUCKER(living_mob) || IS_GHOUL(living_mob)) + continue + if(level_current >= AUSPEX_BLEED_LEVEL) + var/obj/item/bodypart/bodypart = pick(living_mob.bodyparts) + bodypart.force_wound_upwards(/datum/wound/slash/flesh/critical) + living_mob.adjust_brute_loss(15) + if(level_current >= AUSPEX_KNOCKDOWN_LEVEL) + living_mob.Knockdown(10 SECONDS, ignore_canstun = TRUE) + + do_teleport(owner, targeted_turf, no_effects = TRUE, channel = TELEPORT_CHANNEL_QUANTUM) + user.adjust_stamina_loss(-user.staminaloss) + PowerActivatedSuccesfully(cost_override = blood_cost) + +#undef AUSPEX_BLOOD_COST_PER_TILE +#undef AUSPEX_BLEED_LEVEL +#undef AUSPEX_KNOCKDOWN_LEVEL +#undef AUSPEX_ANYWHERE_LEVEL diff --git a/tff_modular/modules/bloodsucker/powers/tremere/dominate.dm b/tff_modular/modules/bloodsucker/powers/tremere/dominate.dm new file mode 100644 index 00000000000..dca84b9a606 --- /dev/null +++ b/tff_modular/modules/bloodsucker/powers/tremere/dominate.dm @@ -0,0 +1,217 @@ +/** + * # Dominate; + * + * Level 1 - Mesmerizes target + * Level 2 - Mesmerizes and mutes target + * Level 3 - Mesmerizes, blinds and mutes target + * Level 4 - Target (if at least in crit & has a mind) will revive as a Mute/Deaf Ghoul for 5 minutes before dying. + * Level 5 - Target (if at least in crit & has a mind) will revive as a Ghoul for 8 minutes before dying. + */ + +#define TEMP_GHOULIZE_COST 150 +#define DOMINATE_XRAY_LEVEL 3 +#define DOMINATE_NON_MUTE_GHOULIZE_LEVEL 4 +/datum/action/cooldown/bloodsucker/targeted/mesmerize/dominate + name = "Dominate" + button_icon_state = "power_auspex" + background_icon_state = "tremere_power_off" + active_background_icon_state = "tremere_power_on" + base_background_icon_state = "tremere_power_off" + button_icon = 'tff_modular/modules/bloodsucker/icons/tremere_bloodsucker.dmi' + background_icon = 'tff_modular/modules/bloodsucker/icons/tremere_bloodsucker.dmi' + level_current = 1 + button_icon_state = "power_dominate" + purchase_flags = TREMERE_CAN_BUY + bloodcost = 15 + constant_bloodcost = 0.1 + target_range = 6 + mesmerize_delay = 4 SECONDS + blind_at_level = 3 + requires_facing_target = FALSE + blocked_by_glasses = FALSE + knockdown_on_secondary = TRUE + /// Data huds to show while the power is active + var/list/datahuds = list(DATA_HUD_SECURITY_ADVANCED, DATA_HUD_MEDICAL_ADVANCED, DATA_HUD_DIAGNOSTIC, DATA_HUD_BOT_PATH) + var/list/thralls = list() + +/datum/action/cooldown/bloodsucker/targeted/mesmerize/dominate/Remove(mob/removed_from) + . = ..() + for(var/thrall in thralls) + if(!thrall) + continue + end_possession(thrall) + +/datum/action/cooldown/bloodsucker/targeted/mesmerize/dominate/get_power_desc_extended() + . = ..() + if(level_current >= DOMINATE_GHOULIZE_LEVEL) + . += "If your target is in critical condition or dead, they will instead be turned into a temporary Ghoul. This will cost [TEMP_GHOULIZE_COST] blood. Pre-existing dead ghouls will simply be revived." + +/datum/action/cooldown/bloodsucker/targeted/mesmerize/dominate/get_power_explanation_extended() + . = list() + . += "Click any person to, after [DisplayTimeText(mesmerize_delay)], stun them for [DisplayTimeText(get_power_time())]." + . += "Right clicking on your victim however will apply a knockdown will confuse and slow them down for [DisplayTimeText(get_power_time())]." + . += "A left click will completely immobilize, and blind them for the next [DisplayTimeText(get_power_time())] seconds, and will also mute them for [DisplayTimeText(get_power_time())] seconds." + . += "While this ability is active, you will be able to see additional information about everyone in the room." + . += "At level [DOMINATE_XRAY_LEVEL], you will gain X-Ray vision while this ability is active." + . += "At level [DOMINATE_GHOULIZE_LEVEL], while adjacent to the target, if your target is in critical condition or dead, they will instead be turned into a temporary Ghoul. This will cost [TEMP_GHOULIZE_COST] blood." + . += "The victim must have atleast [BLOOD_VOLUME_BAD] blood to be ghouled." + . += "The ghoul will be mute and deaf if the level of [src] is not at least [DOMINATE_NON_MUTE_GHOULIZE_LEVEL]" + . += "If you use this on a currently dead normal Ghoul, they will will not suddenly cease to live as if a temporary Ghoul." + . += "They will have complete loyalty to you, until their death in [DisplayTimeText(get_ghoul_duration())] upon use." + . += "Ghoulizing or reviving a ghoul will make this ability go on cooldown for [DisplayTimeText(get_ghoulize_cooldown())]." + +/datum/action/cooldown/bloodsucker/targeted/mesmerize/dominate/CheckCanTarget(atom/target_atom) + var/mob/living/selected_target = target_atom + if(level_current >= DOMINATE_GHOULIZE_LEVEL && (IS_GHOUL(selected_target) || selected_target.stat >= SOFT_CRIT)) + if(selected_target?.mind && owner.Adjacent(selected_target)) + return TRUE + . = ..() + if(!.) + return FALSE + return TRUE + +/datum/action/cooldown/bloodsucker/targeted/mesmerize/dominate/ContinueActive(mob/living/user, mob/living/target) + if(!target) + return can_use(user) + . = ..() + +/datum/action/cooldown/bloodsucker/targeted/mesmerize/dominate/ActivatePower(atom/target) + . = ..() + if(level_current >= DOMINATE_XRAY_LEVEL) + ADD_TRAIT(owner, TRAIT_XRAY_VISION, DOMINATE_TRAIT) + for(var/hudtype in datahuds) + var/datum/atom_hud/data_hud = GLOB.huds[hudtype] + data_hud.show_to(owner) + owner.update_sight() + return TRUE + +/datum/action/cooldown/bloodsucker/targeted/mesmerize/dominate/DeactivatePower(deactivate_flags) + . = ..() + if(!.) + return + if(level_current >= DOMINATE_XRAY_LEVEL) + REMOVE_TRAIT(owner, TRAIT_XRAY_VISION, DOMINATE_TRAIT) + for(var/hudtype in datahuds) + var/datum/atom_hud/data_hud = GLOB.huds[hudtype] + data_hud.hide_from(owner) + owner.update_sight() + +/datum/action/cooldown/bloodsucker/targeted/mesmerize/dominate/FireTargetedPower(atom/target, params) + var/mob/living/target_mob = target + var/mob/living/user = owner + if(target_mob.stat != CONSCIOUS && level_current >= DOMINATE_GHOULIZE_LEVEL) + if(user.Adjacent(target)) + attempt_ghoulize(target, user) + else + if(IS_GHOUL(target_mob)) + owner.balloon_alert(owner, "too far to revive!") + else + owner.balloon_alert(owner, "too far to ghoul!") + return TRUE + return ..() + +/datum/action/cooldown/bloodsucker/targeted/mesmerize/dominate/proc/attempt_ghoulize(mob/living/target, mob/living/user) + owner.face_atom(target) + var/datum/antagonist/ghoul/ghoul = IS_GHOUL(target) + if(!victim_has_blood(target)) + return FALSE + if(ghoul) + owner.balloon_alert(owner, "attempting to revive.") + else + owner.balloon_alert(owner, "attempting to ghoul.") + if(!do_after(user, 6 SECONDS, target, NONE, TRUE)) + return FALSE + if(!victim_has_blood(target)) + return FALSE + if(ghoul?.master == bloodsuckerdatum_power) + if(target.stat != DEAD) + owner.balloon_alert(owner, "not dead!") + return FALSE + PowerActivatedSuccesfully(get_ghoulize_cooldown()) + to_chat(user, span_warning("We revive [target]!")) + owner.balloon_alert(owner, "successfully revived!") + target.mind?.grab_ghost() + target.revive(ADMIN_HEAL_ALL) + pay_cost(TEMP_GHOULIZE_COST - bloodcost) + log_combat(owner, target, "tremere revived", addition="Revived their ghoul using dominate") + return FALSE + if(!bloodsuckerdatum_power.make_ghoul(target)) + owner.balloon_alert(owner, "not a valid target for ghouling!.") + return + + /*if(IS_MONSTERHUNTER(target)) + to_chat(target, span_notice("Their body refuses to react...")) + return*/ + PowerActivatedSuccesfully(get_ghoulize_cooldown()) + to_chat(user, span_warning("We revive [target]!")) + // no escaping at this point + target.mind?.grab_ghost(TRUE) + target.revive(ADMIN_HEAL_ALL) + var/datum/antagonist/ghoul/ghouldatum = target.mind.has_antag_datum(/datum/antagonist/ghoul) + ghouldatum.special_type = TREMERE_GHOUL //don't turn them into a favorite please + var/living_time = get_ghoul_duration() + log_combat(owner, target, "tremere mindslaved", addition="Revived and converted [target] into a temporary tremere ghoul for [DisplayTimeText(living_time)].") + if(level_current <= DOMINATE_NON_MUTE_GHOULIZE_LEVEL) + target.add_traits(list(TRAIT_MUTE, TRAIT_DEAF), DOMINATE_TRAIT) + user.balloon_alert(target, "only [DisplayTimeText(living_time)] left to live!") + to_chat(target, span_warning("You will only live for [DisplayTimeText(living_time)]! Obey your master and go out in a blaze of glory!")) + var/timer_id = addtimer(CALLBACK(src, PROC_REF(end_possession), target), living_time, TIMER_STOPPABLE) + // timer that only the master and thrall can see + setup_timer(user, target, living_time, timer_id) + thralls += target + RegisterSignals(target, list(COMSIG_LIVING_DEATH, COMSIG_QDELETING), PROC_REF(end_possession), timer_id) + RegisterSignal(ghouldatum, COMSIG_ANTAGONIST_REMOVED, PROC_REF(on_antag_datum_removal), target, timer_id) + pay_cost(TEMP_GHOULIZE_COST - bloodcost) + return TRUE + +/datum/action/cooldown/bloodsucker/targeted/mesmerize/dominate/proc/victim_has_blood(mob/living/target) + // you can always revive non-temporary ghouls + if(IS_GHOUL(target)) + return TRUE + if(target.blood_volume < BLOOD_VOLUME_BAD) + owner.balloon_alert(owner, "not enough blood in victim!") + return FALSE + return TRUE + +/datum/action/cooldown/bloodsucker/targeted/mesmerize/dominate/proc/setup_timer(mob/living/user, mob/living/target, living_time, timer_id) + var/list/show_to = list(user, target) + if(bloodsuckerdatum_power && length(bloodsuckerdatum_power.ghouls)) + for(var/datum/antagonist/ghoul in bloodsuckerdatum_power.ghouls) + if(!ghoul?.owner?.current) + continue + show_to += ghoul.owner.current + new /atom/movable/screen/text/screen_timer/attached(null, show_to, timer_id, "Dies in ${timer}", null, null, target) + new /atom/movable/screen/text/screen_timer(null, target, timer_id, "You die in ${timer}") + +/datum/action/cooldown/bloodsucker/targeted/mesmerize/dominate/proc/on_antag_datum_removal(datum/antagonist/ghoul, mob/living/thrall, timer_id) + end_possession(thrall, timer_id) + +/datum/action/cooldown/bloodsucker/targeted/mesmerize/dominate/proc/end_possession(mob/living/user, timer_id) + if(timer_id) + deltimer(timer_id) + if(!user) + CRASH("[src] end_possession called with no user!") + if(!(user in thralls)) + return + thralls -= user + user.remove_traits(list(TRAIT_MUTE, TRAIT_DEAF), DOMINATE_TRAIT) + if(!HAS_TRAIT(user, TRAIT_NOBLOOD)) + user.blood_volume = 0 + if(!IS_GHOUL(user)) + to_chat(user, span_warning("You feel the blood keeping you alive run out!")) + return + to_chat(user, span_warning("You feel the Blood of your Master run out!")) + user.mind?.remove_antag_datum(/datum/antagonist/ghoul) + if(user.stat == DEAD) + return + user.death() + +/datum/action/cooldown/bloodsucker/targeted/mesmerize/dominate/proc/get_ghoul_duration() + return 4 MINUTES * max(level_current, 1) + +/datum/action/cooldown/bloodsucker/targeted/mesmerize/dominate/proc/get_ghoulize_cooldown() + return cooldown_time * 3 + +#undef TEMP_GHOULIZE_COST +#undef DOMINATE_XRAY_LEVEL +#undef DOMINATE_NON_MUTE_GHOULIZE_LEVEL diff --git a/tff_modular/modules/bloodsucker/powers/tremere/thaumaturgy.dm b/tff_modular/modules/bloodsucker/powers/tremere/thaumaturgy.dm new file mode 100644 index 00000000000..6adf88b10a2 --- /dev/null +++ b/tff_modular/modules/bloodsucker/powers/tremere/thaumaturgy.dm @@ -0,0 +1,288 @@ +/** + * # Thaumaturgy + * + * Level 1 - One shot bloodbeam spell + * Level 2 - Bloodbeam spell - Gives them a Blood shield until they use Bloodbeam + * Level 3 - Bloodbeam spell that breaks open lockers/doors - Gives them a Blood shield until they use Bloodbeam + * Level 4 - Bloodbeam spell that breaks open lockers/doors + double damage to victims - Gives them a Blood shield until they use Bloodbeam + * Level 5 - Bloodbeam spell that breaks open lockers/doors + double damage & steals blood - Gives them a Blood shield until they use Bloodbeam + */ + +#define BLOOD_SHIELD_BLOCK_CHANCE 75 +#define BLOOD_SHIELD_BLOOD_COST 15 +#define THAUMATURGY_BLOOD_COST_PER_CHARGE 5 +#define THAUMATURGY_COOLDOWN_PER_CHARGE 5 SECONDS + +#define THAUMATURGY_SHIELD_LEVEL 2 +#define THAUMATURGY_DOOR_BREAK_LEVEL 3 +#define THAUMATURGY_EXTRA_DAMAGE_LEVEL 4 +#define THAUMATURGY_BLOOD_STEAL_LEVEL 5 +/datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy + name = "Thaumaturgy" + level_current = 1 + button_icon_state = "power_thaumaturgy" + check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_HANDS_BLOCKED + purchase_flags = TREMERE_CAN_BUY + // custom cooldown handling based on charges + power_flags = BP_AM_STATIC_COOLDOWN + bloodcost = 5 + constant_bloodcost = 0 + // 5 seconds per charge + cooldown_time = 10 SECONDS + prefire_message = "Right click where you wish to fire." + click_to_activate = TRUE // you pay to replenish charges + power_activates_immediately = FALSE + unset_after_click = FALSE // Lets us cast multiple times + /// How many times you can shoot before you need to recast + var/charges = 0 + /// How long it takes before you can shoot again + var/shot_cooldown = 0 + var/datum/weakref/blood_shield + var/obj/projectile/magic/arcane_barrage/bloodsucker/magic_9ball + +/datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy/Grant() + charges = get_max_charges() + . = ..() + +/datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy/Remove() + . = ..() + var/shield = blood_shield?.resolve() + if(shield) + QDEL_NULL(shield) + +/datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy/on_power_upgrade() + cooldown_time = get_max_charges() * THAUMATURGY_COOLDOWN_PER_CHARGE + bloodcost = get_max_charges() * THAUMATURGY_BLOOD_COST_PER_CHARGE + // just in case you somehow level up while the power is active + charges = get_max_charges() + . = ..() + +/datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy/get_power_desc_extended() + . = "
Projectile can seek for [get_shot_range()] tiles.
" + . += "Fire a slow seeking blood bolt at your enemy.
" + if(level_current >= THAUMATURGY_SHIELD_LEVEL) + . += "Right click the button to create a blood shield
" + if(level_current >= THAUMATURGY_DOOR_BREAK_LEVEL) + . += "The projectile will open doors/lockers" + if(level_current >= THAUMATURGY_BLOOD_STEAL_LEVEL) + . += " and steal blood from the target" + +/datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy/get_power_explanation_extended() + . = list() + . += "Thaumaturgy grants you the ability to cast and shoot a slow moving target seeking blood projectile." + . += "The projectile will auto aim to a nearby mob if you aim at the ground." + . += "If the Blood blast hits a person, it will deal [get_blood_bolt_damage()] [initial(magic_9ball.damage_type)] damage, and is blocked by [initial(magic_9ball.armor_flag)] armor." + . += "You can use Blood blast [get_max_charges()] times before needing to recast Thaumaturgy. After each shot you will have to wait [DisplayTimeText(get_shot_cooldown())]." + . += "At level [THAUMATURGY_SHIELD_LEVEL] it will grant you a shield that will block [BLOOD_SHIELD_BLOCK_CHANCE]% of incoming damage, costing you [THAUMATURGY_BLOOD_COST_PER_CHARGE] blood each time." + . += "To activate the shield, right click the action button." + . += "At level [THAUMATURGY_DOOR_BREAK_LEVEL], it will also break open lockers and doors." + . += "At level [THAUMATURGY_BLOOD_STEAL_LEVEL], it will also steal blood to feed yourself, just as much as each charge costs." + . += "The cooldown increases by [DisplayTimeText(THAUMATURGY_COOLDOWN_PER_CHARGE)] per charge used, and each blast costs [THAUMATURGY_BLOOD_COST_PER_CHARGE] blood." + +/datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy/ActivatePower(mob/target) + . = ..() + charges = get_max_charges() + toggle_blood_shield(TRUE) + return TRUE + +/datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy/proc/toggle_blood_shield(toggle) + if(level_current < THAUMATURGY_SHIELD_LEVEL) + return + // don't toggle if we're already in the state we want to be in + if(toggle == !!blood_shield) + return + + if(blood_shield) + var/shield = blood_shield?.resolve() + owner.visible_message( + span_warning("[owner]\'s [blood_shield] loses its form and disappears into [owner.p_their()] hands "), + span_warning("We unform our Blood shield!"), + span_hear("You hear liquids sloshing around."), + ) + owner.balloon_alert(owner, "you unform the [shield]") + qdel(shield) + blood_shield = null + else + var/obj/item/shield/bloodsucker/new_shield = new + blood_shield = WEAKREF(new_shield) + if(!owner.put_in_inactive_hand(new_shield)) + QDEL_NULL(new_shield) + owner.balloon_alert(owner, "off hand is full!") + to_chat(owner, span_notice("[capitalize(src)] couldn't be activated as your off hand is full.")) + return FALSE + owner.balloon_alert(owner, "you form the [src]") + owner.visible_message( + span_warning("[owner]\'s hands begins to bleed and forms into a [src]!"), + span_warning("We form our [src]!"), + span_hear("You hear liquids forming together."), + ) + +/datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy/DeactivatePower(deactivate_flags) + . = ..() + if(!.) + return + var/used_charges = get_max_charges() - charges + toggle_blood_shield(FALSE) + if(used_charges > 0) + StartCooldown() + +/datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy/StartCooldown(override_cooldown_time, override_melee_cooldown_time) + var/used_charges = get_max_charges() - charges + // no cooldown if we didn't use any charges + if(used_charges <= 0) + return + charges = get_max_charges() + return ..(used_charges * THAUMATURGY_COOLDOWN_PER_CHARGE, override_melee_cooldown_time) + +/datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy/proc/get_blood_bolt_damage() + if(level_current >= THAUMATURGY_EXTRA_DAMAGE_LEVEL) + return 40 + return 20 + +/datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy/proc/get_max_charges() + return level_current * 2 + +/datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy/proc/get_shot_cooldown() + return max(1.5 - (level_current * 0.1), 0) SECONDS + +/datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy/proc/get_shot_range() + return initial(magic_9ball.range) + level_current * 10 + +/datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy/update_button_status(atom/movable/screen/movable/action_button/button, force) + . = ..() + if(next_use_time - world.time <= 0) + button.maptext = MAPTEXT_TINY_UNICODE(span_italics("[charges]/[get_max_charges()]")) + +/datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy/FireSecondaryTargetedPower(atom/target, params) + if(shot_cooldown > world.time) + return + if(!can_pay_blood(THAUMATURGY_BLOOD_COST_PER_CHARGE)) + owner.balloon_alert(owner, "not enough blood!") + DeactivatePower() + return + shot_cooldown = world.time + get_shot_cooldown() + var/mob/living/user = owner + owner.balloon_alert(owner, "you fire a blood bolt!") + owner.visible_message( + span_warning("[owner] fires a blood bolt at [target]!"), + span_warning("You fire a blood bolt at [target]!"), + span_hear("You hear a loud crackling sound."), + ) + user.changeNext_move(CLICK_CD_RANGE) + user.newtonian_move(get_dir(target, user)) + user.face_atom(target) + handle_shot(user, target) + + pay_cost(THAUMATURGY_BLOOD_COST_PER_CHARGE) + playsound(user, 'sound/effects/magic/wand_teleport.ogg', 60, TRUE) + charges -= 1 + build_all_button_icons(UPDATE_BUTTON_STATUS) + if(charges <= 0) + // delay the message so it doesn't overlap with the cooldown message + addtimer(CALLBACK(owner, TYPE_PROC_REF(/atom, balloon_alert), owner, "no charges left!"), 0.5 SECONDS) + PowerActivatedSuccesfully(cost_override = 0) + +/datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy/proc/handle_shot(mob/user, atom/target) + magic_9ball = new(get_turf(user)) + magic_9ball.firer = user + magic_9ball.power_ref = WEAKREF(src) + magic_9ball.damage = get_blood_bolt_damage() + magic_9ball.def_zone = ran_zone(user.zone_selected, min(level_current * 10, 90)) + magic_9ball.aim_projectile(target, user) + // autotarget if we aim at a turf + if(isturf(target)) + var/list/targets = list() + for(var/mob/living/possible_target in orange(1, target)) + if(!ismob(possible_target)) + continue + var/datum/antagonist/ghoul/ghoul = IS_GHOUL(possible_target) + if(length(bloodsuckerdatum_power?.ghouls) && ghoul && (ghoul in bloodsuckerdatum_power?.ghouls)) + continue + targets += possible_target + if(length(targets)) + magic_9ball.set_homing_target(pick(targets)) + else if(ismob(target)) + magic_9ball.homing_target = target + magic_9ball.homing_turn_speed = min(10 * level_current, 90) + magic_9ball.range = initial(magic_9ball.range) + level_current * 10 + INVOKE_ASYNC(magic_9ball, TYPE_PROC_REF(/obj/projectile, fire)) + // ditch the pointer to reduce harddels + magic_9ball = null +/** + * # Blood Bolt + * + * This is the projectile this Power will fire. + */ +/obj/projectile/magic/arcane_barrage/bloodsucker + name = "blood bolt" + icon_state = "mini_leaper" + damage = 1 + wound_bonus = 20 + armour_penetration = 30 + speed = 0.6 + impact_effect_type = /obj/effect/temp_visual/impact_effect/red_laser + range = 30 + armor_flag = LASER + var/datum/weakref/power_ref + +/obj/projectile/magic/arcane_barrage/bloodsucker/on_hit(target, blocked = 0, pierce_hit) + var/datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy/bloodsucker_power = power_ref?.resolve() + if(!bloodsucker_power) + return ..() + if(istype(target, /obj/structure/closet) && bloodsucker_power.level_current >= THAUMATURGY_DOOR_BREAK_LEVEL) + var/obj/structure/closet/hit_closet = target + if(hit_closet) + hit_closet.welded = FALSE + hit_closet.locked = FALSE + hit_closet.broken = TRUE + hit_closet.update_appearance() + return ..() + if(istype(target, /obj/machinery/door) && bloodsucker_power.level_current >= THAUMATURGY_DOOR_BREAK_LEVEL) + var/obj/machinery/door/hit_airlock = target + hit_airlock.open(2) + qdel(src) + return ..() + if(ismob(target)) + if(bloodsucker_power.level_current >= THAUMATURGY_BLOOD_STEAL_LEVEL) + var/mob/living/person_hit = target + person_hit.blood_volume -= THAUMATURGY_BLOOD_COST_PER_CHARGE + bloodsucker_power.bloodsuckerdatum_power.AdjustBloodVolume(THAUMATURGY_BLOOD_COST_PER_CHARGE) + return ..() + . = ..() + +/** + * # Blood Shield + * + * The shield spawned when using Thaumaturgy when strong enough. + * Copied mostly from '/obj/item/shield/changeling' + */ + +/obj/item/shield/bloodsucker + name = "blood shield" + desc = "A shield made out of blood, requiring blood to sustain hits." + item_flags = ABSTRACT | DROPDEL + icon = 'tff_modular/modules/bloodsucker/icons/vamp_obj.dmi' + icon_state = "blood_shield" + lefthand_file = 'tff_modular/modules/bloodsucker/icons/bloodsucker_lefthand.dmi' + righthand_file = 'tff_modular/modules/bloodsucker/icons/bloodsucker_righthand.dmi' + block_chance = BLOOD_SHIELD_BLOCK_CHANCE + +/obj/item/shield/bloodsucker/Initialize(mapload) + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, BLOODSUCKER_TRAIT) + +/obj/item/shield/bloodsucker/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) + var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(owner) + if(bloodsuckerdatum) + bloodsuckerdatum.AdjustBloodVolume(-BLOOD_SHIELD_BLOOD_COST) + return ..() + +#undef BLOOD_SHIELD_BLOCK_CHANCE +#undef BLOOD_SHIELD_BLOOD_COST +#undef THAUMATURGY_BLOOD_COST_PER_CHARGE +#undef THAUMATURGY_COOLDOWN_PER_CHARGE + +#undef THAUMATURGY_SHIELD_LEVEL +#undef THAUMATURGY_DOOR_BREAK_LEVEL +#undef THAUMATURGY_BLOOD_STEAL_LEVEL +#undef THAUMATURGY_EXTRA_DAMAGE_LEVEL diff --git a/tff_modular/modules/bloodsucker/powers/vassal/distress.dm b/tff_modular/modules/bloodsucker/powers/vassal/distress.dm new file mode 100644 index 00000000000..788f80feb8f --- /dev/null +++ b/tff_modular/modules/bloodsucker/powers/vassal/distress.dm @@ -0,0 +1,24 @@ +/datum/action/cooldown/bloodsucker/distress + name = "Distress" + desc = "Injure yourself, allowing you to make a desperate call for help to your Master." + button_icon_state = "power_distress" + power_explanation = "Distress:\n\ + Use this Power from anywhere and your Master Bloodsucker will instantly be alerted of your location." + power_flags = NONE + check_flags = NONE + purchase_flags = NONE + bloodcost = 10 + cooldown_time = 10 SECONDS + level_current = -1 + +/datum/action/cooldown/bloodsucker/distress/ActivatePower(trigger_flags) + . = ..() + var/turf/open/floor/target_area = get_area(owner) + var/datum/antagonist/ghoul/ghouldatum = owner.mind.has_antag_datum(/datum/antagonist/ghoul) + + owner.balloon_alert(owner, "you call out for your master!") + to_chat(ghouldatum.master.owner, "[owner], your loyal Ghoul, is desperately calling for aid at [target_area]!") + + var/mob/living/user = owner + user.adjust_brute_loss(10) + return TRUE diff --git a/tff_modular/modules/bloodsucker/powers/vassal/recuperate.dm b/tff_modular/modules/bloodsucker/powers/vassal/recuperate.dm new file mode 100644 index 00000000000..108dd5a7c92 --- /dev/null +++ b/tff_modular/modules/bloodsucker/powers/vassal/recuperate.dm @@ -0,0 +1,75 @@ +/// Used by Ghouls +/datum/action/cooldown/bloodsucker/recuperate + name = "Sanguine Recuperation" + desc = "Slowly heals you overtime using your master's blood, in exchange for some of your own blood and effort." + button_icon_state = "power_recup" + power_explanation = "Recuperate:\n\ + Activating this Power will begin to heal your wounds.\n\ + You will heal Brute and Toxin damage, at the cost of Stamina damage, and blood from both you and your Master.\n\ + If you aren't a bloodless race, you will additionally heal Burn damage.\n\ + The power will cancel out if you are dead or unconcious." + power_flags = BP_CONTINUOUS_EFFECT + check_flags = AB_CHECK_CONSCIOUS + bloodsucker_check_flags = NONE + purchase_flags = NONE + bloodcost = 1.5 + cooldown_time = 10 SECONDS + level_current = -1 + +/datum/action/cooldown/bloodsucker/recuperate/can_use(mob/living/carbon/user, trigger_flags) + . = ..() + if(!.) + return + if(user.stat >= DEAD || user.incapacitated) + user.balloon_alert(user, "you are incapacitated...") + return FALSE + return TRUE + +/datum/action/cooldown/bloodsucker/recuperate/ActivatePower(trigger_flags) + . = ..() + to_chat(owner, span_notice("Your muscles clench as your master's immortal blood mixes with your own, knitting your wounds.")) + owner.balloon_alert(owner, "recuperate turned on.") + return TRUE + +/datum/action/cooldown/bloodsucker/recuperate/process(seconds_per_tick) + . = ..() + if(!.) + return + + if(!active) + return + var/mob/living/carbon/user = owner + var/datum/antagonist/ghoul/ghouldatum = IS_GHOUL(user) + if(!ghouldatum || QDELETED(ghouldatum.master)) + to_chat(owner, span_warning("No master to draw blood from!")) + DeactivatePower() + return + ghouldatum.master.AdjustBloodVolume(-1) + user.set_timed_status_effect(5 SECONDS, /datum/status_effect/jitter, only_if_higher = TRUE) + user.adjust_stamina_loss(bloodcost * 1.1) + user.adjust_brute_loss(-2.5, updating_health = FALSE) + user.adjust_tox_loss(-2, forced = TRUE, updating_health = FALSE) + // Plasmamen won't lose blood, they don't have any, so they don't heal from Burn. + if(!HAS_TRAIT(user, TRAIT_NOBLOOD)) + user.blood_volume -= bloodcost + user.adjust_fire_loss(-1.5, updating_health = FALSE) + user.updatehealth() + // Stop Bleeding + if(istype(user) && user.is_bleeding()) + for(var/obj/item/bodypart/part in user.bodyparts) + part.generic_bleedstacks-- + +/datum/action/cooldown/bloodsucker/recuperate/ContinueActive(mob/living/user, mob/living/target) + if(user.stat >= DEAD) + return FALSE + if(INCAPACITATED_IGNORING(user, INCAPABLE_GRAB|INCAPABLE_RESTRAINTS)) + owner?.balloon_alert(owner, "too exhausted...") + return FALSE + return TRUE + +/datum/action/cooldown/bloodsucker/recuperate/DeactivatePower(deactivate_flags) + . = ..() + if(!.) + return + owner.balloon_alert(owner, "recuperate turned off.") + return ..() diff --git a/tff_modular/modules/bloodsucker/powers/vassal/vassal_fold.dm b/tff_modular/modules/bloodsucker/powers/vassal/vassal_fold.dm new file mode 100644 index 00000000000..8e6a942debf --- /dev/null +++ b/tff_modular/modules/bloodsucker/powers/vassal/vassal_fold.dm @@ -0,0 +1,90 @@ +/datum/action/cooldown/bloodsucker/ghoul_blood + name = "Help Ghoul" + desc = "Bring an ex-Ghoul back into the fold, or create blood using a bag. RMB: Check Ghoul status." + button_icon_state = "power_torpor" + power_explanation = "Help Ghoul:\n\ + Use this power while you have an ex-Ghoul grabbed to bring them back into the fold. \ + Use this power with a bloodbag in your hand to instead fill it with Vampiric Blood which \ + can be used to reset ex-ghoul deconversion timers. \ + Right-Click will show the status of all Ghouls." + check_flags = NONE + purchase_flags = NONE + bloodcost = 10 + cooldown_time = 10 SECONDS + level_current = -1 + ///Bloodbag we have in our hands. + var/obj/item/reagent_containers/blood/bloodbag + ///Weakref to a target we're bringing into the fold. + var/datum/weakref/target_ref + +/datum/action/cooldown/bloodsucker/ghoul_blood/can_use(mob/living/carbon/user, trigger_flags) + . = ..() + if(!.) + return FALSE + var/datum/antagonist/ghoul/revenge/revenge_ghoul = IS_REVENGE_GHOUL(owner) + if(revenge_ghoul) + return FALSE + + if(trigger_flags & TRIGGER_SECONDARY_ACTION) + if(!revenge_ghoul.ex_ghouls.len) + owner.balloon_alert(owner, "no ghouls!") + return FALSE + return TRUE + + if(owner.pulling && isliving(owner.pulling)) + var/mob/living/pulled_target = owner.pulling + var/datum/antagonist/ex_ghoul/former_ghoul = IS_EX_GHOUL(pulled_target) + if(!former_ghoul) + owner.balloon_alert(owner, "not a former ghoul!") + return FALSE + target_ref = WEAKREF(owner.pulling) + return TRUE + + var/blood_bag = locate(/obj/item/reagent_containers/blood) in user.held_items + if(!blood_bag) + owner.balloon_alert(owner, "blood bag needed!") + return FALSE + if(istype(blood_bag, /obj/item/reagent_containers/blood/o_minus/bloodsucker)) + owner.balloon_alert(owner, "already bloodsucker blood!") + + bloodbag = blood_bag + return TRUE + +/datum/action/cooldown/bloodsucker/ghoul_blood/ActivatePower(trigger_flags) + . = ..() + var/datum/antagonist/ghoul/revenge/revenge_ghoul = IS_REVENGE_GHOUL(owner) + if(trigger_flags & TRIGGER_SECONDARY_ACTION) + for(var/datum/antagonist/ex_ghoul/former_ghouls as anything in revenge_ghoul.ex_ghouls) + var/information = "[former_ghouls.owner.current]" + information += " - has [round(COOLDOWN_TIMELEFT(former_ghouls, blood_timer) / 600)] minutes left of Blood" + var/turf/open/floor/target_area = get_area(owner) + if(target_area) + information += " - currently at [target_area]." + if(former_ghouls.owner.current.stat >= DEAD) + information += " - DEAD." + + to_chat(owner, "[information]") + + DeactivatePower() + return FALSE + + if(target_ref) + var/mob/living/target = target_ref.resolve() + var/datum/antagonist/ex_ghoul/former_ghoul = IS_EX_GHOUL(target) + if(!former_ghoul || former_ghoul.revenge_ghoul) + target_ref = null + return + if(do_after(owner, 5 SECONDS, target)) + former_ghoul.return_to_fold(revenge_ghoul) + target_ref = null + DeactivatePower() + return FALSE + + if(bloodbag) + var/mob/living/living_owner = owner + living_owner.blood_volume -= 150 + QDEL_NULL(bloodbag) + var/obj/item/reagent_containers/blood/o_minus/bloodsucker/new_bag = new(owner.loc) + owner.put_in_active_hand(new_bag) + DeactivatePower() + return TRUE diff --git a/tff_modular/modules/bloodsucker/powers/veil.dm b/tff_modular/modules/bloodsucker/powers/veil.dm new file mode 100644 index 00000000000..9d5d69b0262 --- /dev/null +++ b/tff_modular/modules/bloodsucker/powers/veil.dm @@ -0,0 +1,162 @@ +/datum/action/cooldown/bloodsucker/veil + name = "Veil of Many Faces" + desc = "Disguise yourself in the illusion of another identity." + button_icon_state = "power_veil" + power_flags = NONE + check_flags = AB_CHECK_CONSCIOUS + bloodsucker_check_flags = BP_CANT_USE_IN_FRENZY|BP_CANT_USE_IN_TORPOR + purchase_flags = BLOODSUCKER_DEFAULT_POWER + bloodcost = 15 + level_current = -1 + constant_bloodcost = 0.1 + cooldown_time = 10 SECONDS + // Outfit Vars +// var/list/original_items = list() + // Identity Vars + var/prev_gender + var/prev_skin_tone + var/prev_hair_style + var/prev_facial_hair_style + var/prev_hair_color + var/prev_facial_hair_color + var/prev_underwear + var/prev_undershirt + var/prev_socks + var/prev_disfigured + var/prev_mutant_bodyparts + var/prev_markings + var/list/prev_features // For lizards and such + var/disguise_name + +/datum/action/cooldown/bloodsucker/veil/get_power_explanation_extended() + . = list() + . += "Activating Veil of Many Faces will shroud you in smoke and forge you a new identity." + . += "Your name and appearance will be completely randomized, and turning the ability off again will undo it all." + . += "Clothes, gear, and Security/Medical HUD status is kept the same while this power is active." + +/datum/action/cooldown/bloodsucker/veil/ActivatePower(atom/target) + . = ..() + cast_effect() // POOF +// if(blahblahblah) +// Disguise_Outfit() + veil_user() + owner.balloon_alert(owner, "veil turned on.") + return TRUE + +/* // Meant to disguise your character's clothing into fake ones. +/datum/action/cooldown/bloodsucker/veil/proc/Disguise_Outfit() + return + // Step One: Back up original items +*/ + +/datum/action/cooldown/bloodsucker/veil/proc/veil_user() + // Change Name/Voice + var/mob/living/carbon/human/user = owner + to_chat(owner, span_warning("You mystify the air around your person. Your identity is now altered.")) + + // Store Prev Appearance + disguise_name = generate_random_name(user.gender, TRUE) + prev_gender = user.gender + prev_skin_tone = user.skin_tone + prev_hair_style = user.hairstyle + prev_facial_hair_style = user.facial_hairstyle + prev_hair_color = user.hair_color + prev_facial_hair_color = user.facial_hair_color + prev_underwear = user.underwear + prev_undershirt = user.undershirt + prev_socks = user.socks +// prev_eye_color + prev_disfigured = HAS_TRAIT(user, TRAIT_DISFIGURED) // I was disfigured! //prev_disabilities = user.disabilities + prev_features = user.dna.features + prev_mutant_bodyparts = user.dna.mutant_bodyparts + prev_markings = user.dna.body_markings + + // Change Appearance + user.gender = pick(MALE, FEMALE, PLURAL, NEUTER) + user.skin_tone = pick(GLOB.skin_tones) + user.hairstyle = random_hairstyle(user.gender) + user.facial_hairstyle = pick(random_facial_hairstyle(user.gender), "Shaved") + user.hair_color = "#[random_short_color()]" + user.facial_hair_color = user.hair_color + user.underwear = random_underwear(user.gender) + user.undershirt = random_undershirt(user.gender) + user.socks = random_socks(user.gender) + + //user.eye_color = random_eye_color() + if(prev_disfigured) + REMOVE_TRAIT(user, TRAIT_DISFIGURED, null) + var/datum/dna/dna = user.dna + // + // dna.features = dna.species.randomize_features() + dna.features = dna.species.randomize_features(user) + // dna.body_markings = dna.species.get_random_body_markings(dna.features) + dna.body_markings = list() + dna.mutant_bodyparts = dna.species.get_mutant_bodyparts(dna.features) + + // Apply Appearance + user.regenerate_organs() // Actually regenerates the mutant_bodyparts. + user.update_body(TRUE) // Outfit and underware, also body. + user.update_body_parts(TRUE) // Lizard tails etc + + RegisterSignal(user, COMSIG_HUMAN_GET_VISIBLE_NAME, PROC_REF(return_disguise_name)) + +/datum/action/cooldown/bloodsucker/veil/proc/return_disguise_name(mob/living/carbon/human/user, list/identity) + SIGNAL_HANDLER + + identity[VISIBLE_NAME_FACE] = disguise_name + user.get_message_voice(disguise_name) + +/datum/action/cooldown/bloodsucker/veil/DeactivatePower(deactivate_flags) + . = ..() + if(!. || !ishuman(owner)) + return + var/mob/living/carbon/human/user = owner + // Revert Identity + user.get_message_voice() + + // Revert Appearance + user.gender = prev_gender + user.skin_tone = prev_skin_tone + user.hairstyle = prev_hair_style + user.facial_hairstyle = prev_facial_hair_style + user.hair_color = prev_hair_color + user.facial_hair_color = prev_facial_hair_color + user.underwear = prev_underwear + user.undershirt = prev_undershirt + user.socks = prev_socks + user.dna.mutant_bodyparts = prev_mutant_bodyparts + user.dna.body_markings = prev_markings + + //user.disabilities = prev_disabilities // Restore HUSK, CLUMSY, etc. + if(prev_disfigured) + //We are ASSUMING husk. // user.status_flags |= DISFIGURED // Restore "Unknown" disfigurement + ADD_TRAIT(user, TRAIT_DISFIGURED, TRAIT_HUSK) + user.dna.features = prev_features + + // Apply Appearance + user.regenerate_organs() + user.update_body(is_creating = TRUE) // Outfit and underware, also body. + user.update_body_parts(update_limb_data = TRUE) // Body itself, maybe skin color? + + cast_effect() // POOF + owner.balloon_alert(owner, "veil turned off.") + + UnregisterSignal(user, COMSIG_HUMAN_GET_VISIBLE_NAME) + + +// CAST EFFECT // General effect (poof, splat, etc) when you cast. Doesn't happen automatically! +/datum/action/cooldown/bloodsucker/veil/proc/cast_effect() + // Effect + playsound(get_turf(owner), 'sound/effects/magic/smoke.ogg', 20, 1) + var/datum/effect_system/steam_spread/bloodsucker/puff = new /datum/effect_system/steam_spread/() + puff.set_up(3, 0, get_turf(owner)) + puff.attach(owner) //OPTIONAL + puff.start() + owner.spin(8, 1) //Spin around like a loon. + +/obj/effect/particle_effect/fluid/smoke/vampsmoke + opacity = FALSE + lifetime = 0 + +/obj/effect/particle_effect/fluid/smoke/vampsmoke/fade_out(frames = 0.8 SECONDS) + ..(frames) diff --git a/tff_modular/modules/bloodsucker/sound/BloodsuckerAlert.ogg b/tff_modular/modules/bloodsucker/sound/BloodsuckerAlert.ogg new file mode 100644 index 0000000000000000000000000000000000000000..686f15bb711eae7f062f530453bf9ff42abfc0cc GIT binary patch literal 218645 zcmeFZcUV+Ew?CShp-TtpAV{y$5u^-FdIymvAiZ~_GjyaV(m_B_dXpkesiG9=Rf-g) z_byGCJNSLidEayY`Q7I^_pkfhy|c5Em6c@YvyzpSy)&a>W1|D0;9tjiUT06^41{@xoQ8aFxr`?$$@lY;xgQHMwq`9BX#*gqxVp%_%n zy{&~rc<%G_@bU8BR7{V$teh=eEUnxnP>B|(L_S_&)FnvoX!rD=jJHrcHdfB=RuVFf zURE9u^nb|AGO~{#01g0?2L;E&0uQoqLMjkbG7^?&-6fKIP+1=0xW&X>P7qvyDN@LN6FY(^T z4O_W?MiVYC`j`+!Tc-~vkZH^eD;GsEGYKhbhGB@V(}aKKVv7m=!rMp|jwZww7rM;b zGahzJCOR`rN$89!+(z1m?4LTAq!kmwFr<4Z!XHYbo&ZC%kufsCL~ z#(#@lA-a&Ylxu*Wsa!2eo26LioA^4WNpvmCW3YEMi*FDWdYff{n~CCE%leXQfb&m? zwc2+$ljDZwHn?GyMbw1~u~hgbWX9K_Lg*ECFEUlCQ6a@9U+vc_H#Co%qW*fDUpHv7 zNN%FVElsJfhrgmi8eJRnS%m-1@|W)~$f)+h2_xgpf3RbXuG!K*Bzj84zaf3P&WlYI zmL;<}vTmE7EQZCL;-;<4`VZhx0LNm8Ak|j=`{xO`s-WjQOpXzMr$O+I$m66^eF6QFeoh( zv~Eg%8qHpm<&MKq{12S;H=+SRAi1y#^fM$q@S&JCuxX1W~#&qQMysW;bdKokX z8cju*oCeOJ+?kj8<5Vky|Ka{=I%@dQqdNOP4Po!1@aPv^XG$jguV$hI3S3DQ{`NPe z8YY!drh!o|jUzz~5(zC*`7uGgk=rI(B2HSuR%1dYI>IJ;kDT;Vos8Q&4`To#r9(9ej<}nBC}nhjc;mkM&?FF z4oB%<7C?Bza&yEK`oxs@#1#9ySdUJ$%}6aS$>jW2xc#wm>;L3#{q5jP0C+MfxHBne zGs$bC0)Np(;NGB1)5*sq@6OdXD)>(uM@S@4fa-hxqcr{{0F;L7ts?Ckp;04dp3vsj z)8U@bmY>kk`#&9OV}fcVC}6Qc0t6%w>Tq*+Wn#xNJsq_#%eBDO-Y%$C_oHym|`lrT3BI+ASBUBdMwwDSMA?eFrgBp$LM2#5-MR>F#7JllM+!0xpsu| zh6#9?K0PVbL>7JiQhE) zt!*Zuyq2I^dZAq@2d|pmZIr#TcmsP_;g??^BC;F}$Up&2%u|ERRo@)en8K3Ge@c-b z5meLBQ%WrK%|RJUcA15xHC$>(;x|*2uAW}RzsRMfo2ZI3NKxE+6J9@WNM zrDM8kdR`{5qwb^fn>nd|Fzf0D(XV)XtW-m#`k>OxY(FR~D z1ctgIG;Mp70X+dg@IJhmwAJtClUfXlvJz>>@U3MfDf6wO%pfIpO4Mw=mY@9BRU+Zw#tQxDCofg%JIJqyP4_Z&Lpq{eKkVMj2;+Ewume z(7}b?eQ+ijPN}>=1s=K#S6i|5J%CHycVxc79scRTpEfdYR#*{y9==jxR zP@0V)W%4Okjt9OBJNws17Fz7#+S_?gZl%8Mch{`Q%gtg!WnzKE-XePF763K2i`7(MZ3!rLCi@r%wPPJUT7` zr65rUB?v&RT$$l=a)KTdlvLC-v~+jq8SXMNq15<4OLBSyKtub-qPo%GXlVbex#5+6 z^Mji;_YJ*>PZeoEy^h5CeQQ&=BCqx7NPGvB&BrQ)N#HQJ`XAY@^Y~i@t z+%qp(YwM=g&0K3m#V&Nq5004<o4BkPh^z5nyPDV5>r}S% zTm!tk0v2PIzZo|~|4fvoXR~H^zKNRt?)KfhGMq`EcIeBL+RQ{`OT+J@mYH^S*h{oZ z+A@MKEm1RVhToSe@`K$LM0kQEoRKE}PFIpDCs~~r!Dr-wx^debjfPo!q+d=p4}-aO z58cCikdFs)UwpOtj)P~31v+ujz*GW+E|v7^QtbWD4J7UhvhTH)?0X);alQIDEnU8Y zEDKZ9>(lSBDv3)=u|i}9t+}ViKWpp!V)~%#C-~v=L*4AN)(@+?rLqnJR21jG`j$OB zR##5@mX;h6tTZ6Q@pvHlI|OvO%d?nGqLUQ;vE-k2`xGBk*wW+&-6Mw17o z8R~VojPN0yueRUO$-P#`7*Z2Xqder3IxtB-XL>HXAHv5NRxXUy7jx_T2TRY|$u7yxb~7YW>F_c+ zLiF@*W3Sd%cN^|Cjt%WE4>eb+n)$6BG-wZ>x(sg3m_E6Xe*L6@QDfze)K2e{EKI}% zwq|f375r$U44ppKI{^xZ!{pkZ5X^S8Di^Ps(O5&x%$YY74_XAUM1dd#w5E>l61&8j z&AXhKbFm*w^h3Ym1&~?6whk_RYaidv-k#F-)7E*Nr>Mt3w6AljZ)$WjD`C((k(Y5l z20pyDD^4(Bj+012@GQt$^)jIU@Ym;4eT&XdLBt5Hhj{Um1_9{+krNX{281Ijpua&A9T^<@1-t#)=CR|0rlM!>Cip&L zXtW53^3J~u@r4uD7>LFfycZ%!wKqib=eA?=O=L>BYW{@vk+%lI+vGgEce~W-2Y^;l zW;fXr^+jE>v{`}5t##KNd9G3x55?-g0ZoEp5U$mjAW2})%m(I#IsM9G}ZI1@$~lN>V{KLy_9uJ47PXJPLjkgHB%v`b?Ex-?SM2=7~T))2smRbgr1Huc**urTD#`sYJmxyZV%tZ`E*P6!hFqtKA0>QHrn9lridQts10 z3H#nN#hIGrW;pw0{9C&diLpK*)r9^w7x+X5Fk74k?P5DoUm*J*SC*-Wh0N&N@C7H^ z6kt% zc#mp^lN+sG-fMI559fF{|I>w{qSMzNJhw|)gk^|-VC1g)RH=mGmH8~jhHD0M-tT=h zFm}sW_B{rWu0Kn7$)eb2X^Kf3eaj3N4}BWm8G=KP!XSA&vp%zfMk7o#v64BXk!6P8 z?&!JhhW&x)@b+8GW*zrbFKn*(;vx=VT|J_y_gfwl#H`s!(*P?Me=5Nb>9c8zTcjo@ zg>v9CMW)Up(*f>hEZ>m2sxGS1@6tI;_nYM(3|XpG0C=kgI)J;-0^4*n4719&BU`*} z5FdK%cw&|xI=JYI_ifsmxje@By$Yqh^kmBT`t{~;cvT&i(g&T4nN3;E;U@cJO2=pB z_;Y%5O1M~*eG`L9Sr^(Zt_mj!C8zJ4{V8};N+sr>rF8EN0{CmrRT{4`0)BWjQEUEc zo4Patudwa=40&M&Uh4OJ1egBl-G61GAicfjPS^Vm>$C zPA)$Pp8$uKCwK&YnwvDn6G)bljGJ<+gag{?=m>*g&*-y+AC&}(RJ`gOEl(MEp-T51 zC*XX*m-P*0@ymel1#zeV^ZPZ7o`wcV#FO`jos68aj#J z>wUHD)K4O^;37k ze>?8KEPbG(#}q{4o!jChAT|1+YQ76Jx7b1xW|po|<{t8zfzr%ESgEF@5VB64oA7f; z0yYt*Ycs-o@H#TyBHiqp!YM?blT8SMegCeIH&((UeC(va3QO4Z+_I;L2X(sY+t+!6 zyMsnNFy>8|+e=p5dX*Vv^dZ{*EA5mE>_ZL%Ec02s614TAj|JPbFVmlyJNAB&Q6$Fz zgcMbdjaC*6jHWe?kUWSWsm&nHgfA;Ke>Y6csemf~Y8L&GE&Xs04wz5NzfSeW&)oAB zOOT`L^;cSJ$h*Vaos?g`zx-<{bIEk9_c{0Ux+ke}c+4x5DKt4?Ov&tx3fXccSx zr@YPZ%MMA^SAT8u9<&0<+n)=hUI$IDO9aOtYtU&oL`|tdz_(%egubr<04H;Fnm|mQ z8Bz-A*!YxdcZN>QMr#S?)fK=vWV>`em^mLix6AKD3pom)Q950qce@7Kw1=}Zy84jzGc5%Ny z{J`>y|9PPv@}q^Uktd@w-iL`Ro|4wD|TUAcIy<*m*;6HeG;@}EkJnn(q@fZgjIn4y^}5w%>SP05duPf9vcA<-Gf&J0 z=#Rc zqn0!NNm$KvYvJ=`EQB7hYyFuwD%9N6T52AR;7pen=Kne_(G7t?Z-yEf`M)x2@tGgI z6ZnZt8$V2}#ZMA^%Usv>hjbCPE48uw#oI-YpE(ruQXH*y)wo-l@p5y=Z6JI6nc1Ir zYxYZf2`(1mpc7^-vZ zN@fdC_8U~lci~gjePT)Fe=S@u&po=&MKjDMa^8h^@r5zB`Z(tmze+Ib*cNEG!oZQo8S$NK~hOYPS~wA2W~9(`pB-QD&wg9wEukbj?-v~BO33Xgd2*IhAi zkf)fv;`!Y9;iN@^6*zV(Abd_*>Z8Vs0m4ad8xzf2I<{5w=k(4>k~UCkP5BE|eXX^_ zal`_Sm{kzT^yAh3O!DNpFl6qlbA?r{Z{9K=mPM)QoIGDuw!KZF_GF^NJGPqKU>i^1 z)rFvSK!Fs%k~=-ZhH*MYt4bM`ERZP+ZuXV72Fhc{FEBqAxj1wEz8a7|?(L~dS;zF{ z+0D{dr38KSLBhR;i{L-^*v{%tZ4hIy+F8t{C^x?jN61{lLCFt~utONUM8RGbLg)>_ z&J`P`%Eo-4fQO*8%qr(G>&KPLLrdV~@Dvg1WRETTNFQPx$=Cn3Wckh;PU)#v+KUnK z@LVIT(IDS!`=5V)OYjEljvNe4CsCM3GehicFlqdlEvFyj)cFu^P++5MDstZF;0hV8 z`8(dqzrC0+TF+nbP2t4jErQnc;}gYM1w(#oVREYzDZxx16;*R4f16rC5>rukc<0pB z(X);yWL6OV|9BLisrSYMNguj{rQG(f{JP#@mDKf8_wxPUG_+eQAN8TTUxU^ut>`t|-V@gG1Sy)=8-c>7atL6fM(ZeU!` zM+w0SQcZ!fwDhZB>Xhan@gd0}%pQNC#=9x}6j~Yj`Jwrx6$EW`h16Nb#nXf;J$ewp8-|0H z|7)a5*7ik@*PRb*RZUgCF{47QkCnN0#*)0>bN^o55ufKwPIEUbeaKG=GK?InFabJv zcQ0*JAKiG@1{efqxSuoOtyhsrW3JPdcrNNK28yPb!1|$3+f+6v;)yaz3*3d=?lc@% zbcd4wd9%K}~xzjW*}C>b6%c(|YtF4kKKX=X!fJeX6l! z)}u`=TLBY4d}XoVAJOT@M%ETDBsBv`#u()S(@gs}3e1e}l$0qWm&?dXVeE0ehi0x| zKK=NjfBR)ut>xingRSR9reuaR=Scq_M7Zx^W*Af&W&_JrsExC>k1T}(GYn=hMI-!> zr?S?rUZjak#poAR#neUhsWy6`OG3#Cy=3y()SQ zB^?tEsal?bf+`5%qCS1b_)f!13>7YKa*N2xYBMi2qusMtY>{dHw9}T5p!9L)2X)>f zS)X*6$Gd3hN_?&6zhS+wy;G^xSZp45Fg>(*NaCSMGUScrw*+k#=u_lbdy03{7pTz^ z>0ZPgAQ7t_Bk?Wl0%V(ZNnyx4NJm@mB?xeS`wsx>&hgcP;Xt~wpu>v=gzm+RD?;MGwsFok+kku`Qks(Jf} z#EjY^u2Z5QnM!lqpNDOjds7S-tx`Y`C?j@POWcp{&%DREKP|X=?=$N@hJ&mwvG|z& zKF9a2(q_KqLOstpCO)ewjPA}7UM;|Qm(S6cw5GaHLR=L z=>3s#uQRmygT}yv7{frW-$PQ+hP2aT_{p==?d(*QH&^GEtTt48j3IQc&6xMm{n#5n z2%D(jKQygz>u=$U6YY+Xh@Z-WUJj2h`A23%mHv#LXDg)1a?H3V(Lc4;laUX>c06OH zdJbd5xg4&`JVq~OJ4vqn(`!d*l;&%n(p?{JHOrC;LU^H@c}+cETYqHbHSCHkOOD0I zxbIWKC~%tt5()u6c+wPikXS2)=HXdS@!gioZ?^nlZp@(4n`$XbBjP6yN1MW2#La-v zLBDi5w@O$}WV+@AApinDn8CRJw$jCjz41<-RTYQUOl;}!BBO+@2b(=r#)^jDa(2B3 zd*R2A1`IxkAG@OZHy_sNR~NoHAWYVFh^7YIozFgiDm#u?s$~|~A4!*Sv2!a0?!QCm3MkAFjckYVz9+9l z%Vb^TP4=Y$Sp3eDw2_v5A9gqU&l53$dWbok=ybj3>67Q9mHAy_V!AcZw5Yb;q@UaG z0)-6`6z2R+_9k5vgo^J!JC@Ej3c5X*@Uz`b$c7s1q}d8?b7_S2Gwu9Rov2wCK&J`E zlXMGXR;*(E4vuZ@mQ^dlIZ*2?Y{b;c`&Txlb`y)9>OI&BU$;gl=ld8EAF}#sNm<)# z?yT*$SA37fT%Q-SfV6+KY>?bM{Dc(YvHWl<4A@!|mmFXZbtGMsCXyPXvSLd_IC`2O zzu%_T*Zc4b_Vhkkom_v@N+HG01E>(;SGslgd94P8Rww%;ly$h&u*GGiAu!635^u?i zjnGj6I7V67vjW#=lIk-`Wo~$vFJh^goU76i9300iy1FZ8Z0^r=UJ}uVp-EFKCo&-( zn9AW|lpVw`G;Mq{!DERUucSAJU_3!7H_jy_E@&-rbb4(|-dSt;HQ+j>i}Za)JW>A_ z_SdUdh{39kwJ)8tUyj~DM%*EEnmxsNlZ7{EQ0mez&Rp%g)qt)J@EIp5VzkBB=mQMMV4-ohhV%RG1V4kwY3`huGFH`FHM8y1trS@F z{c(qJ`9)PaAY{5u$G9#Ceaz1r~SE43{=FvoSe{l+dg7T&M$o{!mRgn zuSQ!>FXfv;Ni$A*4_6o4BZpd=TZ)pH1Ft_RJAS35oJ6x`Q1386?-#yL~NG3f6@OCdL!nhD#F%;Z%ne1{3Ws!wKpkU8XJmzZrf<` z+yKL>gk|Sk(J*O_aL!YiG-k;oh^k%jLd6+E5Av|0hmxY2Dj{ZdNNXI<_vlzkKgX@+ z4Q96oj?c~cPX`mUuTT60#ioOJK-CNLBTdbv)DI%SWCcNRn!xa=eY?eyfm;@(-5XK&o|X1IeMhD$-Y4~4dt zs9L=iQV=ZCD;giBdSIt|=%^mm?^tM=!@p~hsv#{eq5&cE;Uh90obrHkeFR>kT47Af zd5TH^^e+Ywx^iDK&Q)m?Fo`#OxZ9cfroUjB z@rjnN38COO4?ciH#6XoWt_F;vjH73PB4T&E4+8{dJvuw41caBtW76-I6Ct}DDSPd@ zGHQHX_zY#uX&a81F~H42qg7(a+%Z6ci%KF<4~V>VB<0jPI9OL94SVW4#1QwV z(YDQ1fh{?#{PL6);~Cr95fd4K1%;4>_ina8LAVc?e(XJL0Vf(I@HS$ zgZ^@N90PwfOY=4a+{zsbY=J=^28x^wj6Z$2BiZ3qQCU#E{bO8hyqkvh6E5Yu?C+eP!+lzY5*G=iyV z7Q5ZpSEmDG;&X+ys6D@k5~u5}nRx#*Uh|putOt7@Sr)qzn^hq>SCg;rN|VjZg~8AW zbDUjH)`so{Uy1RC=t(lLD-A^4U&v^{{ei({*s(rIhMd1D&7D&}@9Let3a7l*X@)!dVk=>vP@>)Lh z9+JKtDOcP;*G2Q z4vJxAETz=Dq-C>JV}a+q4Y?pa=Xwlh$cT;7om?+1+V+}fX3##AK)$~hVKSV~tTFVv z>*LnoN`U#M?9#IB+MUjEwRC!jsfSYZxo+)Lkk+@Y^hNIr++u(lE1nywJ@%U?X6VYwT?bn!N49N@)uWjLsbB?|*;S8K&{K9l(}>uA+! zMctC8>0?~)<50!zLVWtQtFo&M00%La{3}R{3AUzS$%SAJXfkR~5%%hesq|uDOziiQ zN>hC|6;)}wx}327`FjkzPW#=E=9aVKd14?cZ^fbRZ-_4cEaizZr%o_-Bl;HI1^TaA z$k{t?3a^tv(lxvz9*x~iKm~VRREDo66+-DyHch!uS5A<&{3?>FvUlTiX|(2f>Dw5x zP|`fbs~l}h^WMiHd^Kv3;@qCMHnpClwukH}KqT4if=!ZsL3mQQMQw<(E{6a@7$t%VBJFApfBo%l? z|50@o=XBOqTP-a)`NWhGq!;1xr-`GaY0azVCn2Xayz`l%5F`=WHZ9@@!JggC*OdO`ks%AFzI-_&d!8y0NV(p*Tm` zl#SZ#B{@TLnNu2N_rcbUn!Ge?lUXnPZSo?g`Xra>giR$9H$sE4ayu_$_u==M(l*ux)<1{-JUW8X>}HRZn24*Y z3}pb><0j=!nTR%BoeuhHwu@TH-Z2GQ$xgFNNkcXc`H7s}TG@*}|BIHCtjoR#AM)pv zNtNlx;{1**L}x${<0bOwjt~MuH&ecpVNWoiIwHMgZ(LlH#yCM3F-mi-BXmoOiyI;E zW06&{=eLU~Y`F$M;NCl-uZ4igE?N&Y;nIYNRvW#GFRh$Z`mAkV&vJ5@d|X4Xs_eRVIX&>BHqqX zWyD5|d}88_^YcW;9Bk@#P=9d#!`3Fb!qtuq6TsNOG6h{#>V+*T5w`{Yr{K8EOZNwPq;XX>e0>A~FCg z>fx-3lOaV$lPSS348BBvhG0E*>)#f=sVl5MpoFitcu=Y(Iq_hJm|UNEP5XTv10Dlv zkN<7CKbZ6>>rCCE%fY7E8v_qKFs6K2HXA^s*XsEFZk=p5*S3MCg&^*=;~|KRn{IcB zy&Aa)EMXJPEQs>KZ}YuC50*UhH-6*@)^UFt2}>tL2?@$R66@Dz*488rHrvt|^^l8Y zU_^&$jeD@A+t1%kl-o2^rH24*p(TC=EwAnl^D53)GC45E`fj^2K3t1iQFs(g67_0rR%T6NcA@>8KA}0dcH4AZ8H*tH*;S7TZ(=v*&K9i-hJydAOsWzJ9o>=DDrOb+ z5k#5uSvHR$8hY14i)SvNhd+Ahb5Y|ee7JZuy+y8W4~0YE272RI!Ef1I^q}C9baeWg z1g=|r({R5^66fW~hBwLIg z`61E?DHD-L{%ScZbbqT3rxYLrfFzFERbmiNJ#8rgiG`%s?~NSE+h3Kwc1K6CdTiie zuLTgd|8aq65-}||GD57*L3^ye2{zlfo+&x61+y+XXvgItoJuP>^LwgichO+-Vw7jC z>*t%5D6UthDisSRPih`sWZEd6k*H|~NDlpe2qDF)j=vhjfwN$0U}zrw7+(&I#6?H+ zk6Hxox@j8WSOP-5Gu{}4-QgC18}ZJ-ELT4-k2cOZJ1_CJ{&0SMJ+mV&ohKbeIXWk# zad&-F6{AWykdl9Uc5c%WHW4RA3}B57F#4hI!dP%XQH;+KY=AYFK-p(~+8m>T^Hh)0 z%Qm_SVz~!hw}$AvgRCaK*)c9ow31MTR!)sRi`t`z|6IjT z_Mx`&VSHFxwd5j&CbDX&XXW7K$QBYM*?HN}7F`xG5>=)$E^ijON9R!X@=-_U(=jXvlt-BMfm=zvm z3ITHdrK3w4a>pz!&n>(-t|jpq$+Wv^jKhNJs!H)tbaJzAzXc0 z^o}mzoYhCr^^C~BaJ&9D#aEikV0{ld8fCk;LKd(TQ*a%LXw@Ciqi}X@)UT5&lMA7z zhAtGOJ!0{Ao&1rwr6$73lE?w0+WyBZM(FtayM4uCzcV{?_G>bLuhqwh7tkP_?9EJj zMyGU!`?|F=`kP!kR8o=F9Ia1{2ep<7_smq%k;z!Z$Fb9prU0<`(<qycEuRM+k)w`hDgoE8`$6dBRTB)=+?Nc(=_j^YOPW;uI~(-$ik@f=DXcneO9H zSwz6dn5(z=B4=J#X*C~H1>of(9MTXQL)L!oieP^Z4ttx{u;i?6c-eZpSDw-|FFyt8 z0%Ov1jmQM_n``#kQYxB2f#T!$jW$t1!q1BQ1UQh{7$)rJt2IQsvI9RlG6n@kYlAa~ zs5(>DLOVJP>xClC*obo3i=o%pv`bl|VJyt}?hKrHgN8#s0=N%^)`T5QBs2Oj&p!O5 z7CCDqW@@}%szC2qfq^#-b)0}1-64}Ix`<&?GYkt((+FQoD3{fd3^_g<``$V6O?S7q z`+UPnuHaqe7g^cc&son(xw6JTZbLpx^aP-`DGOM}Z0~FY&*0&pjIMZL$9H(%(=e1B zv?{lv=MiNlu01op8Ks6iNV0sF%Y=!jJmo31Bg`)~J<&PLmW8l+1UekyWMn-UwmwW4 z>;1U}S_rMhOzwd%v)4~uKP9EuOrQ&c;!Jp=1y}R9INcp*ATytGhY1(a4zyrUM}t=8 z+oU26bJz9Ca?vin&Sx&7n4~lqdEa{;#w0{E#_l`nFkC=L7a>3ei}8p8fJhuVoE5lnDLy)2H|qWRl;cq=Z(FS8ZQk20aF~C;Dk}(NwQzdO zc`%FkeZD^{fZJnYTl3_j`EJf`#JmwCx6?88&0y3AKzg0{l1@YB4e=zMt!^Ahwu|BZ zp*wmu>L9t6;{=0NNn+?C3+Ocqq%qqcKa9cUE?4`oIft{Xf`J|4?~ME6b|MhDJErzQ zy0}3H`*cPRPVGJR3AKVmBPfJ{$+Pevf}O?m2$#|-j(FAFh7xCr`bAD22a_Pv$>nK- zKDLX2yrvj~>F|o+L~8IvPNAWc>CSP!j(3jW6}iSWK8 zjg9fp^SqBM$z!uWuY(kSw$yymgXb6Oec11pK7jAK*LY~>oRQ`3JI0hUf1lqwD@GUh z0fcr7)-4`*XgKJI_^;P)v2)&r-@f( zKu+#*YF@0y8@UI_a1IRlekOwg$*Q5#6Dg#rjU=6w!_te?ukCMtzJVuz;)$nBz)>2f z7@@rK9;rO-U+a7U>8YYfSRUav8_yXW(w_UxQmMd1*cu-)5t5cRMl)Zv(mvn?9~6&V`h`3sT-@;7fX z`p|648J1X2>J z(!jW34Y8NiP_SHe$-7na<|!Yc&zhuCr9g{#V)C04AFql@s~y9tKli{fJeb4dt6!u56F)$R+x1U*X4#9 zO_6KJ`fo$Zk#2_#tz!H@P;cp*pPJzFngRPELmMaRAZJ+@eGAQ7hyi`e$c%S$6Jegx z@)M*pEQTsbqy&k=rFw*2vzyQHp-!FLM2&XJ+gC5&+$rHuyd-LWh6^sv!u^!DNM>II zbpJRyo65IVGmWH=SpAgKPS-YJAyMG#L~0TEpon0{=c3y|qq}-Z&EKb87_O8sye&lr znts3)1ie^z`MusZRu0U+oOEzXWAL<9ZKVy0i_ve zhnv4+Euu0Wi49x&{Gcnm;K^P1PMy03O~`w-Wm+8>Qr@%t{qWD1xG}#3UR=9kSJ&BB zr`L7$gx~N!b}Swoza`OEd;HkZ>2AH9egOXrZd2r@C+rTkSjnN%-xN*%(f zADIlY+neguYLcsgOt~0XL%NB|zUoxWl(zUfGX=yR#~R|`367eT#(#1U()I%)0$A?DO%a36`*w`Bt|v>u1n@zgcJrvW`IYCdajG1iJ*v!E8q8Z?63moSBDXYnMsvZy+=4X$f;H+c-Fnya_?M=x!R1L4Kd1H zT0N6x^^gfz=T0#z7Kg5e#6?w6!HaBGfm+7>E#wn;Uquvesz`R| zz}q9_;rEDrQO+mDB=u^^vtS65(pD1uYs>$Wf41M>Z27xdR^EfigI{G%D&S>#M{BN;0%!>J5#*&kh6g?2q{6F>!CUOE*)KfBA^k}?>(kFiTDtej9 z%%j2De`4dE$||mKp$6|Cw0V5+_G4(lvwx{i`;i{~-h%QcC}mRKT>#lHW}pR6I4bOh zHb@i{kMqRbsAy*?PvJ@0uHVQi#B$R41AiMt@>Dj37!I2Si@M?UtU$9SlUp~@6}6*E zIUHTX;IsZi*Z6i!QAws3<*AXYlH>mO{8)f!c@1-{6cNU=Iv7=dv~bAqWE00-uqKsfMt*& zA{fVDD5QVQ9HChKJ488eG~gomu$Dt}PuHfQ+n9EIG;I7qpRry5XO>VDy>a?AsIp8^-YOcNEh0{Ydie&5+7^4>A0)d zj{B$CU=Pe8$Pibge4$O9j?I^itTa{ghuiy6`vi5sbu9N7|TO3zN+#e|T1-ou4cUJY`k0QMv0JCK?QFl}FdMM-ZB*nU< zfxc~}7I!iu7-xS#LxAFW%ErU~ zRyKRJlOjf`XOcw@N14F}mh$IhAQyMT8dr(iQn*Fi)Ie6|8Q(C0x+fc@ZT2q#A>C_< z_WjZ9Z7Q0u1A&$KOAr5|XTq_yr(VvQRIJJ=3SmhQTq;0J49w29cF@>R-?OJR1<0j( z5(&`~&#&h8whm*up^lW{#%(z{Z-^IkZkN=VkV`t?Umtu<=%J(JEWlSG-{<*QFLWnV ztG$}wnvkEj>9#5^Mh?#N84$#gJxX&LHn7Z@%ATTb7a#RbD{~Y`TFn!Dq4o9_kuSJ#A~3 zx|3vCG;1Ul7F<>@oB@}tlfW>HTYU6|8t+~p93a$P7-+GfGyof?VTgp(qTRTl2;=vyRco; z-v`evtU(oSb(sxj9z(9hDG|q?`N6)~jxjZ;A}U2f>{qqW;CO;Sj zOQ2QEq>nT&$*t`9k$sgx_KS_gOm%8Qj#dU9R*VDJ^M;US!DkQ~k_b%DV?|s1rTAVi z?PV=K{m;n$QYtw#2hiGrhUWOqd(v0xi%8C#*ZGI>LrvOW^=9>y%T@p}gtnhEX6@nn za=P{sHZ2PX=(|JbS8v%r{LuV4N5|ZAad53irQ+e6jJeCUws~lTF$RK(0@U=C2N-am zUaI_p6ffwhDZG;Y6e8zVdL8TU5rR7`y<%rZYYGXo@uE1+ysCQZ-9;30wQ--WT~=iJZD#S{{H zGSVxyVI@*_qJ~_2SXML^e*ahVbx2`Iq&q41(=*f-H3Hx`{*!*@*7b&}^NYz*=K|MV zOjyw%J5LFZ;#1q8Tb%>iE+H@Xg`=1z`{affFQ5x)z^@GhvDfOA-*3Qcoa8Y<7%BwX z6ku5SLPfH{jD@#$0zX*VRi4*6YLK6MgdTu&-XD14KpxA7UHmft7NH!G@6Ihl4Gno0 zDc?G&WL=6suG*C=+TsOtzYiDhv<%Ng-@~Ln5=up~1tsUo9;fl2^+dF1o|AOErs z0AN7^2nzs#R{~9CSfU9I0K7i4KD7voV4y&21Ko#lDPjXg=F7|N*Ir}-*;tS7VnmRF zT>MhqNXlZlY~uYwX$~L9<|$WgX}|bgud6vj8zN7@pDEZOeRf}Qw=ZovJ*j8O(KS&{*kKEmFWHT_mfUv*%UzCbVr7aGf7D3O7;K% zAOH}5p?lT<002M+1eN3}6)#2z008BX+33IQkP8!JY5I=puUB0Wln4O-T&_f$N377v zv7Z5FZ~SUr+ye{)Ang!_;L#c&I2ad?4aibxQ~};P-RqQyN!tWYi8HIysch3*V#xT0 zQs(@)+~CYw(BSR=`A-Xw>l)w!^sYjk1(WiwstRkMGu~bT0wgCSt-p3Yu!Lg!np1s5 zV`d%0#H@NgqyW`dyJrCq`o|z7N-c3R_&(1{D&#?~z0Pb#F@YJq8 z+c18<{kT26;t51Ee3n`I??4OJCbL`>f;AX4zS|H)U~^8c8HvA|qpDtS4t-uAm-7vM<{3P2 zy*GfIkp--L)xop;_TOKTdgUPm3II*@$?Awo7$it<_X#{O@OkG4E0%3GC8@mLJ`X=u zOfmP&a1AwpE*F5Ee@lDfYc8~LAYTAr_@b05zs7Jd_hJaXq<5eJU^-p1p|A9{ITQdO z1{we#DD;y1`@uJ_yw8*gy7ta&bs+*MiUD{4;DMmI*wqc;;?n{@W`csNseyt632D0 zh_YOO@0K!J^FIUzT**|4P+^1f2?|7=TMZ<-)|#BSef-pPYZ}Q%wyCX|8iVuk){A%_ zuc;gDkK7H80bo%*zo;ZA0OSnWlkHXdcYGOF+4-+KpHU$A42r0tXU0oal|`x?C0m(Y z|JO6fhzd3dpx&ms0D!)#Sl?=#ZG)<(5vIO>3m`+GcQ8q@iwLsw>NW>3CQj9nN^1vn zN_kWJ<642z!OcJfB`5=0L$wHyAQV*Ob9$RE3IHs~7{F$sKYl3HdJ@Rs@~E}XvR?kw z%H+R!ziJzyl++~wvW>8ik&v(@Rw}V>03NE<@1E7c+s`_fDFM>vf2mPkgHwb7FL0yH++a!8ZDm zHe`Lei-|7aFmM3|fXpeDn&Y@051Sr{N~!aYg4PNJDD9sG;V%DQ)c`bfLlu-~eY-_< zW9)tA$B%a$2?Drt05A*2E?KqHnfF54(tq`jLP-g*3t$XL!e7R&VTYq`0E42?5(c>s z^`F73YAV0|KPf`7Qs_A3FXo()-J7V&gw$QkN0js5`PNbZv)*@~AP@x?q2;Y^i}k1Y z0-hR;V@aHcp~yZ|I*+T-QpU6uXc|5qYLawzkYHEd1b|-Ff#&m>vx>E-ss;%f_y!;V zAmN#g2SoxWYw#cU5C3O>4)P!T zobGx{s+P81ilz>}_1Qw$o;}@f^W)FXF|dd>4Pa-oAE@;ry>)a^1)XGa`;jWnIsh38 zy^~~YZVcknh90uXLY0Cnr(?2e=pu)n<4aI5j*Ei(9?H8Rn|)n5NzUNekM7!0O3JB{ zCiWAPB!N$!l6?8mB1)$wP^9nfX;qev3CP>tevb*Xwc5r85NHWf&s7BpRNq>aAY;GB zEH+Ns=hNzJ!jwIwusarTsQt!>4aHH-R<34<5!FyzH~TX-AnB2?iv|FG`s_ud=E0_0 zY=ck^a0+cvr_H7nWvM=9rbnU%6`kxL!8@)0yc&@7Y}2!uq-0lBg$)h^fu@0;b3FLe zLC(i#v!Q?OHU{nw9^3W4qdGM0gc8c%hxdUT9;%=sg5?N7O9l1xAe?Fg>wo|3Qg=TO zXB(Gs|Hs+pbgWt&8%N83gP@vHpv^wEXySpgO1sc74eB$35 z5Bz5guuWsoXSa?=(~=Bi|EsIQQCphEDjvOif1-3)##qgT-urrXnD0M`!Nw$H60Giy zoC_ap{`wsyqJRR0JmqW|K56nKl+u)Syi=-85&`4b1~Ag!&nv&J)P;8G+~s$?^j3&9 zgGSUfPl?a$T>CXCTFoYpiErMNmggY;vaN)&XI|}M0Dju+38s317JIAG9Gv>BNuo(Aijsd>l}Bn!M*7L+MA)%(Fa>nm%Vzf1hOhM z)-)f^H>0Z8Db=`w&*TTz>1H-$CEcXEYNlswuTj{{Irpsc2%n#_$VbK3luA*l@{}S1 zE(cqb-NiV9f{-KT*`f4fHJ5}oRQqzRCO<3fr>AccnLy?;GT`;kDk_D*7&i!g%a?58 zTHJ@4A@T1cB*zDJI|@LnguuqpUnzK@NgdY@m#>Wt7-UI+OlS+NMIaUqeWZUg;wL0* z003V4Y#yYy##G|v!<7s=j2ssX(DZJ6vg7qkBS_4&eYuA zBS7->kKHf<002f`2MTp&54pssTvg#g1i>A51IOOryD>xdV|-}85p!sg`qt+IaG3yI zTS|sda@HmpIjx)?o7hxMl}26uv2HQH=p_XQJ=an%4_Y00X*AR1U=$f*+sSEuHFN+% zL0zWmk7Ijvat{W^S?z6>_S_iau9(RdO+ycJcS8b2W_MN9a}F{tU}(Vb?QKe3^(iL) z?9VgqnanNpWkF8YHH}}~=k4KMX7x9$001&Vl0X3F(cBs8ZkIB`OK&-vKS*+jbt1$7 z05CCDaM31Gx%Sw!QI)c&uc<(#qGBnEF zM*HOBly4SQogQYoTh@j9;Ky4CA@qlLu!VHXfeZiue%ka!B#z_QUFRLlq>$52qcQ37 zJ_ih)uaxHT5qLq(1HA?!#QHlh0p6Tl1rXWSfp0`h55>&QP_D}12qc>Qw7G61yV~`K zeA3dK?@!iV-OUDSQR2t7HMVIUO(_H?e~MBF_s%x}xdS<)P{R4lVPM%F<2iZzy#LJW zTvlgCN3O3d2|!X!P3kk(d35&B06aD?tsEGzFFQR=7LVCOxg&aLq-G8c?u^K$VW2@;M#US4qyJF^jTdvwtb zZRh-mWp6xG+HL=o}naZ0S)3}`m z>PK45Sbls+H-Dxx@lhs;R4Iw)XAtQQ$)Ofo3lb>*O?)L}$yyB{gz2ua004M!q<(Nm zz=kpBflX7{_QG^n=4_gr57k-#5D_4WQ}3%eMDX?O$Fi{Bnu~9vYR# zWbYTpwE8Zhz$jHFlejOojSrQMXU6~v^C=hbO(jUMrvA_YV|fh#%{TFoJus-hexsuTTntNxru|DkU*tI?l=0U(p=fC0`lYL>6B<83haUGcMveK7#nO%wNkAgI_D;c4WzeCDdFDe{QEJf(qx@vb)jTC z3=Fc6mwTihm)v^B$UM;VcGSOM`~fU1NkplZ$ekEqrq4t7Tqw?3Z;#d!cjaxet4sT5 z+3~Lr%SlhdlI_J7Xmt$$e(H4IlTw|*!(e)1Q~Pa>RIcw|m)0wsxzG03=ht&m?OR`Q zElQw{lcLE3#`0NNJ~sydhH~Xe!MNKE3S`cigrd5cJ`YVQ8B}QJ-+JVz7Te3%(_}D$ zqmS9NX8NCv@vF{dEQYAPWZYF$MoZ$+_>mt^c(gtG)m4n0<;LkKomOF{uB(75xR5d+jrenUrUIjsLJH1G_}*p zxB{n5XJ6Xi2c$1cOv`Dor@QCcNDoSX_?g{_ld7uvpaP= zLb27>Tzp+j10OCabGT}D93BO^2VEjViI5CcF@_CJ4+4fx(w)R^$8>z|a^=HZE_k}l z$))%V!_Mmb!6{)a}@2UMVct!Q??e^+jLyNR}GR~#U+oFH^ z3lDoO#FPwuZb3JcVLk${`JMuXqO;uQA*ZKUyukY`B zo-sIk&oQg^g=^oR6OClh3NIeKWazso6Kp6CPfzyu0}%fZ3)%%53fS zkO88REF>c^VvNzk*K<&3ZsWYY!2&>7_zGkYpapC@J2x_tN<~36S1WoWKr#SeA~G>{ zJgQ=t=(oqQC`><2iVQ?`n9Ogl6MhvBauxdn#=`agdzOY`)XTAA{mlk`TJi&1 zapH5P8&LHz0zh>B3KO*g$be*Q>!DKX>U-Ec7Z=Rf{pfG?Dq9kAXc^f6fG8Wf85qx@3JLw}652=-BJ@}ji}Ptb z%Y_pIehM|-rRK#j^geEx)v1ni&I;!A%+Xgi*$g~K91qV0{KRs$WN#R(!mBDFY;Yn7 z?DR`w7;JF0$@*J=$F0icrG(Zs^RSWB_b7lVh&ekF6zXYJ?>`?b?Md+HNv$6HaP_-S z>eHTeUhPHyqN=wVwV#G8QAUsLNiRTN9mI44;4V1IFQ4~Ykz|2b&qEiq-U{TNY-NP~ zZa3*Sdg~2ZX|1q+|8kH~O+*99!0f)sui8X|DWIY7bCSk&JI{5_{N&FehC~1rb!RWl zdd_q9fBOMH=6UPqO^OrlB5QsmttTYL7#kZ{v(s-te`339dvCQjp zbF2?Stc~@kgDd}2mAt1)rBaYweWj{9>fLthT+vTRaPb`xkjIL`a9!GN%MkQ`ru zd`q+cZkZMUemXTirrL;U>V3THd7YNh(`O=Rs*jhP5I%vq7w}Oiq7B(tGG{6# zI965I;06JIRNSM-piTZGc8_x|xu2Bq{rQ9a_dF&iksr4vL)X%qGA>4$bx|hcL%hB2 zL-AP?0Z@e{sR`))(|mn+-ixR6Smwt=b6?hB*J(9CLsT<#^3)SI%K*kx5kh{C5olbGnq* zY<(P$>~!jd{L|C~DNd@q`fmHo+y2YBFaB4&>l4s0A-+*Xr9W>uIAXBHf>@FDx!Y_N zD_6g3T{8f;+pl61k`>q~yMU4vL+dGXFb*ct2%&qVFH^#4AzBpS)ui(D0RDQ7twsC8 zZQ^57Wft3NPoD?V#>WaCEu2d{n+q3~F10v(!DKGkiz->Vs=@{p2xw8q)p~P$rjLiy z*!QM#SmQE{FZbt%y3lHgkn%WGMZ}KQR|opz($VW%hVK9fn*f?BO1pw$KBkjfe>0nA zS2ORz$79+hs=We0)x?)`Z<+$SxKcT zr3^N5h>b5DCI)YPG$F~wXfn1BRafW~N8;TgJb*9Wmvkwa zRYa6C=&d^OrXn)N*WUYlF!$SSJ2~-?kj$EC&PN@N!+qY)NnMLw4ca6wuKkKi>6ub; zo_fY#?Ov$q_J3*-Byh-rZt|JVqAugdIkNY3zR&qSY8wRqKUq=q;$|3Xu5>YQ%CaBN zS)Q3W!Jqyi0q)-hO9%n4egYT0LkGQse<5nIZs>kx3`R&M7RE+k+q$s=BWsb2{YSnf z%NCN1WU!6&KDL^ACQ+p-N$uJ9EF@X7ZB{v(ftb&nJI7|i*2N2s*=sx`G8m2i(%3`n zo8sbNJf5;%2qWv!$^`{`AP3Q)A#4maci zC7^HWl+KTL?%MU0`RXt>eDA-fCi?WI~MqY`sC$*CKSCT@ zurziQMXDsJs=@|`fdFn#2HxFzDap2^Cx@vdXT4yp)V`h(C}clS;(-a!^-&QbLDl_3 zXui_wKAK1O@RvPKITyHF%o_Ez#(AuDP83Pe#uV)=UR>mfPU|#sVJcrqt<&8X#j&aJZF=ZR8PDai9j zxt7SIBGHig>&LSC0eYt^Rdepd%tQ}%$ydYHU^$*cMSem6H~rn>+@1!^TVV2Q_r5Hb z0N#rAe#)E|LBm%9VzaUD>2onme6Ndn^luhC58&o5Dr<3AXv~%+YD|^Iq^b&Q(7+pj zfHsKR|2ZgLtH;JNbQjNV)>r;&X|c{VO&_9@^MRl8F>cL+?@Nk+f@SG>)eO)FkbV%| zMpd}=ih*4A_Ex;r&@@#hW&iW=jUSKL>KxgNN$%aA)G2-7hhCtODO26evD#{L8zU$k zfL36C_rPxnrQ3dh3NI4;E7gUS>6R?HaTFI(i<=|NVTVZyJ0I zAQ8NQYzqLaK0Hd8@31Qqp81MSI9yWWxz@^pgG$*gu%c8G_v+R~MR`yqPflNT?`BcM%5~yv}f`G}(gb_%zK^=PWk>o_ck1%rhU7GkDVktYTeR z(|RNMPS)_m3?uO2VOTc}7jdYdv5Z1TTuw+3stOyN9t0Np@%HXv+mp~=p60o*I*w>= zzPkMU@=nTn5o2Wk>1whK8e2YQy6SJ~yy)b{>2)$t`T!Uzdht+GRr7nF-cxJ6-y`Xz zE|NJA9MjBdJ-#Yz+x=}!b?;j4e~hnuTF9j_=ad=`j;E@JZm2rL*_?+M|9yH~FK%Vt z4G6!kCv7t@Qv>tCLH%BsL}0DaKU!JY#P9*$cV-A^#7C#HF#k+ zM?E@HHOJ@%^*j`Ew9&1>L{oJ$qI%cTC zD&hh9!<`3$4mszR+j@zbO2HHjE<>JFGGuaTl-4}`=s1Bw;H=kryRn);T~+RA8t%%=`a7P5TUn3;9pA!t72bVvs^f1j zfRTk{w&FY0<4?f(bJo=DubxGc# zdpiqO*TtcP*~4ygAxRyqo>BzriqVy)VLod?~2CVQ1aq8gu^?xc&zp` zeBZu==kPPMVX1ag{RaR-0SZOi+?HNry#+u8;W!l$EnACJ>$ogn`}qLA68f#GYbKc= z7D0waq0s2J^lUaN2U_@8P$m@>D5Y@r*N5|J&S}dTje!dQ;5_S85NAO_vTuiN&VT>h z+qqSEDz& z+mQ{%7T{=a*D--eKNs(Z!^N=Ubj%)eE49A6I|`xu@Na3}mPWo=iY{EH*1MUI6f+si z5cMT@;U0C3(4kp>*@yt%nvH%+Zx2bEe7r;K*41s=T5PBBG+fP#Ofa9fUf%2l7tkjT z3Cq$ObYCP2=WXx0bkaqyd511R&-P>6tFxtOtQWDdQ_RD$S6{jg z?XGUv>j2;s6j4-V>RT0gq1kg{;%d{-n!u? z_gvMUI5%f}{VNv8!kH8lU%%e!_VWM7*%^+lQCacRbicj^l+yF; z61{A)hbhLqaO=k8f)az*mf4=@&nF8~10 zi;*l)PnU!U)WR_D{>=aMbSl)=NBepNYOf_k*tZ=gWs25_VGcfKH?>>eF6n2Y8H1NhDH9WVz8wDy>^QWc(U(DO zOi5L_s&E7hme9*74VLT`$eQr{dIo^y!MIf?z9U&&`V;QVJBOb3IN$JBy?;H|bKKx5 zdf$93_MUlobUS19he?qx)^9@z@pVPN-5mS2o%`MHx(?l7&G(;w?%CcPbDS}9C0+mk z5ELks^!*gH>GvM*D)Jr@0M`G$KfK+3y`8}}u`zu9?cogeT#rY(bUAO1R@)BUeawGv zFWk(>!_3DI9&lesAQ=PL7Ygh3q#sa8{Zf&MS5sGcSNm<`ReBSP1(C_a_~hH;cB)3z zmD+X?j3Jr{&Ym^py2XX+4;{Bh&YeE==fl=NXpbUxoWseiv|urz#)AG#XS{h{%Pc{Cu!gfpiXU;0bc3u*2v#J<9dLzYGc-^Sl&LIDUUqM`_W6VT3O z*k_!5a(l8hw>jrIbL8iGVrl;dTmWdbnU(_Ar5}=;{p`fZDQeKs_p#jIQrnVkxkMr99xW$~q1|VY) zfWP`&zuLI^<5N&X76t$zk#u6UJ+`&z>w*83rK%uG#Ot?tLux%`&hG$V5raY1RfQNP z?~4OB`B4-L5JD{2ZDMSakhq_>!J*wk#eH=D5=e9zOl*4KfH?+>meozuVA)^$YM{TO%a=1O{1!LZz-yn`F&yb za6Mq9v+{c6U^sED4aCX59_5J_SIIpold64#$dP!h=%_e9)!*!-b!FVS{UKOCm_ zaU`JjA0A7oYHD6 z+&m*zt`e6)=zhNZTP(QPk}Jg_U|E)vu_+-Z!Z1`7HaIj0SRF@SD-AU>hUuutQ%o^s zt47C5qHEDi}9 zfwX{ZTcCj-CMRi_qHS@7n%y1(wplC;KF$nXqU0{XiTkI<*LF46$s2@(d6EoX%XY(aW1j#wq~_A zP1K3kQpxtm-H>PL_xQW3QU!!QBBP(HBHi(Y%$YI2|7YtDW1MlWet&@3rn2#P`mTBg zxVir6#itp7oC|p?d&b07Hn{5iZ}w}!eajlV?bf=eLlpd7Q}Ie3D5MQ z3S2iXjx{gws9;SAWOh0$w@DgeRpAKWxO9>&uEdD;8l98I2_-kjqJh!=j;$(nRkLi5 zRxhOH@?AgeN+FLQlek^-6cnR->+J63$rv_x|S?1MLI9JQZ?w zfS!@+b0wMCpX_V~1~5&T`t~yX{eGQ6yi{fK$)-Qf_qqBp^mBJ^Ac1))?*&8uC$vn% zWmNQroGUST{9IqW)Kt%u05C|vUw<~sHs7gAMalyyEPmTr=igZhC*RfoIaNuiq)OGZ zi5%e&5lfs zy_)Vm^mm5$T>ub=f`g~O1?bcPK8rPNPPL0>e)({~?AG*cT1_PT=Hnq|1pvV9nEae2 z`x2cg4kie(s=^Tf^v3|m+H}@#XjPt)jiO;NVfqc`V}Yyp3d#RdPYnyRQrgy@XZ7WB zd65aJ*VMpcO)Udp^NG!HXHvR<7T~AE+?I>?^nf^gfF%h8LMDC&1`F~1wT&^i zY=a!CCLl1vaDl^4YMoSe&Yv_Rgc$4bN8XZECSoRZh+V{7*waaW8r=3e*>%WKX+P1p zlNK4AJvG#ee6nTB)+={m_8$X2tJQT*TMxm#c@k>7x?R%R#PIy`;t7v{fVal&PKw0# z=?k5eU=E9_62b-*2-H|g8lJ^vimJ@n9k$6{+yUp=F`rzTsrZoncb+yLE`b;_# z0qF~>BB1ibTXXI}PWAH#>bVTnvBFPN08q{=d>t$3Kypz=J|+tEo<&{8nB4cA&l6hz zd7RJtc&1JC2K(n97r6uU(qM2q#$N0>Km9sis+vh!x0BSTM3N0vfB_Ub^|LSe)daO#@xbU{e=Ql1fJLAXGhdlo zU}GBtHj4n;5?0gkc!MR$1bP5Kq)IKn7aw)2v7L#w$UCVEp)YeGxTVQc4(pwd??1|J z{qoKbYwgOS699v~8Y7wDh^OG?Ld#VFp1bw)60L`6K6zHy>e=@%KG^=q{hQvo(xFCK3IUFs#(+Ha-L482#M zMtjEX)WNB*dZWw< z6m(Qg`X=eM%hv#z*2muEsoO;t=gdQa|5875l}IIu2=E79OX7bew&mBKd3}Q=OGpOd z(p9DllFBN%fWUx_(5kx!b~3g!l+nLqtlP(5pU7~`YQ;#=Dhe5lS+I-{e9C#}xM;CM zSUP$-*NB=|rN&i9r zME^klL;pwrNB=heO8-IsQvW>vLjOVkLH|SlHUB;TOP-pgaZ0a;sl9noI5WGAeNDu~ zFrPdL&$hr|ig;tsZyi=)KFD80%frUGn~8KSbA^CJ=@+x=j`_K z)MxLJnM^E~7^gYLF8mH{?v4j?ETuP2JBq3;(__)X(_whG#$}?(2Sc8 z*T4z@fZIPDIm?nuMpF%zhY}hJ8&n{WfTs=!=8C<)D(K_yQV0WpY7gDzSXIzARda-x z%Bii=!^GZ6?&0APj&~&D(H861Zj~5f_lmU!bnHHl8vvPkw2Dmzpm)}N^vT2hM(>F6 z&aZDm2XZTv_AoG)*>#d4*GEgIVJ3S15c*{&m2`DYX&SW^dP?uVDSGb&n4;?LttEeP z|8t-N6tWWd>fNY;YjdUmFwkoPRU;sw38T2Xo1EFXA1}yKay@qCvzOxOmIQ%w5$k-s zZh5ij9@*|Eue^*HurGw<$VeitZ>RsNyIfUJp915N|6RZai|b3WU^uy(wjY<=a#C=6 z66p~F1IBT~xwIfuExq_6IyBM(Sh5f!1>GSXqM^08s8R(0zPhDxPU(o?{$t}HP4_8bA>^tG8yp%0%8p#UUiPjhnKhQF z?XMnFUO{)(k|$qoze0XQ(WPw(}O($c3G zAq0u!%YbBr;E{o}y2vS$mW*s;L1bGg1%&6qV>o#$G#VuF|Pqra-7XZ4L?|tBU@-H44fvzRGkc6xBs1n+#V* zzI43-P`viacPan?=RHt!XHD;>@k$@n*VFRw{QmL%$KQuy+_w|a$u#zPpDw0(!`L+* zeSu?7`TW|B`}Ynsd(#_+T371uWQ|&Z-dhYb=Bk<}8Gh5-15@1%x12l#XcI{C+bw{z zBSB@iuKlS{2C?_t#T8_P1TU5lRY@V0`s-_!;0e{$cfFXkT2e}ts=yqZtK04^ED8-8#P~bV2#@+~8_&5Tx|szdHn2r{boa?XpGik!oA=i@K%?Kx!%qUB&C~NIgDN>wY9&u+Ww7nkpI6$6yzWzq21uLI`=#9nwymED z3=|j7vpudk+^hhcGvM6$xG+7C3CjQ!mfdqQ^v!9`@-}K7)j#gz00=}?=S#)E|Nlct zs>-ZX2lHRAhr|OG_`=q`n`B7rwC4U9_*KyG#re=%FeMN zp1gufP?Z!|_C3%6K}A$#)h?x#^FSFZpB_w&0AOT39i`sLhfqJhsZ~yy-%^tSTe*gu@T9l`4 zJ*gCD_r+^+10ZAg<)_|2BdZh)rDs3qnKcyKCqQbWLWY*o%=zET5A$v8ea^fClLG)K zkSlHbCF{~w%3C^nB_JuSgcK@ON&PCggSx9_VckJIo>>_eXA-+0*O#@qXYOB$S7Hf3 z@Ccax8$JKMoh*3LTR6TsE+Qs6WqtO4GI8xRU$20?$5cKu5oVv}Qspnm5eJ@%#bRon zdXk|0@VPW%w>lo_;(+^yr(OA4mC#A6UyO(Z?tk{-qr;p1-<~hRK(2Ts?2;E=5RIvv zRj#V=AOen=&+)UdV(uxMlvB{fJNe^-`f$$}yaZ{Oun&Yu=x+~01}JoZvB+btkT6CV zE`_0!f{PtnVovsWY=5no6KA?la`)a_1GhZ4ei+>UwqqkhC+h5;$bF)xU%$R(oJsaR z3z}iz9_OJ7aO_*E26ApY1CKvP9``h1lgj|P0$lN6L5Jg~@qNCXA7jKE=k9i|Qj~u= z@YTaVh2QM!4nhkjdz+@l>Rstxa0AKgyjLc2S6kSY9j;F)v`FNgw3N1qkuparA9u@6 z2YTFqduNuNyT8QlT=)FMIeu#=(=*tod$ADNRY~G%??Efi58s5yEP#Dm_U$|07WQ9Y z0001~9TOf>fo&w#7`&59qF6l ze(I)bDnl=*4-|m?=-tc|0GOwPDh?X}tv*=pzFKb$XqgUxS)%v!*8uG7`Oo?32V=vo z!}>^30GL!3<+!WK!j5HuB_ZKGeRdLm+B4l;%?{ZzLSVB91eM}2M9%wgpXSwN zjeVR?q^EzHXkjt7F0@M<-|?YX{QE0NzAOOVs+Dd|*$eg$Pe)B{*T*AATqNVo=bCu5 zF@?a};7zX2FB?L_neAMt%c`IOVQ83DRoI{efskbs%WgE+(Rcjq8bX-HG@2JKK3!ic zG)D+#{r$S0XQuaE%@H+qPlgQ;5miNa7eUPvQS?tw=l})v(bpTab1r1qe3EeifCFA> zujc}g`^~@X-0rM_+)F7LW{1w2MVpGA56?OUipsVAy1=1!rC@;1c0R=vFeqBH0Eiu& z*LPek5*>1HbOSWLYWl^RPv5{OKBv@aR{>vVVYj}>DF7%N00>FnF})MIwgrdLB`?%-kN1@N!N$u{P47nRIZV8jy&j< zA3k0qKJ)nnxkhl)9tjO@$B%ja@u*-KeWCX>*iggJP=zCK_KCSyem3^ux~_Rijnp|L z{`X2O6%FXc{D~7Qc`(H65$y%VPvv$oBLaY(S9W$X0DZ1_0S8&X|Krkc-{AbGU$(3U zr4*MkPd6mB+?54wJ#YV={;xW7&hKY@&DVPzoBP@r;GFS#{#~52H&i|oX1*{}vtSy3 zX0Q~1?%Xodz|^Wv63|?0M$72O0mzAN^1<7Fqm|a1dMRuZQ01ptfwrIiRw;oO4pjpH z0EWlHz|-Be)ibB+ny_Rb3b9b9`e<@x)rso4-hT?${kXr50SgK26~C4^hcE!E!J@FG zYRpJlPHSo-;E^q3UVfz8pU{4rIOKh@5L>@@330Rqag!I)X%=u`2>h?ueq{ijYGtOU z>jU%fB2Lt5P2VPb5zLzpHdn3^Z-)iM`sve%9D~PolH~A!cAqh$j;X3)B?uKZs6jxN zZXQ@&h}Cy}G_o4CC9|!GKbKdF6c5!9aQZ@q@qs zQ2J6S!v^E$DSO|}-8{YS!^EC_|8Ls$yV6=FcZ4$&`{f>=v_5LwRAVVPUO!uKQF5V5DM86alg_{ldX@kiFeI-J*_tQ z911!9>gfX>o7HJfiHjtBd4@(U*VHpj9I(GUofWtmn3SaXk1tceYhvQpTN};B*vse* zYBa^n6&r?1h~qd?fu=h;Fu-k`hfmjmxj6s6zp6fI258#QNyzN$YYS@dbe{b< zitY5@9`Z0Yn}_lE_4__>PK}2jt9Nf2Ci4qH0(bs@u0FkVe|gL~$~aZu)Nxv--&(r~ z7rkbAM%X9k&F39z$_J{IBDvm62PfTBsIkt0P?q+cOLL|by4H=^GeE*10Q-VU+A1X# ze}(7t<1`oPqWO1s&u&GYlNe(V{%%62A9uPJBrIECQ7zk?EDozp-t4%v;-n#j^xINn z+X65z8l$>qS9PQYnt&+9F~}ec;4lL|i`8|>Nqhz)2x z)ncVa);&<|RnZu-7Vy7wCu2`0!`46Rk7{xT$mfgcdut5_e?c0 z^3qgGvp)Bam~hS?{(PLU>7U=mq8OTfKkm8`4r7jcy$*x%b+PI5FE;aI%zdFo*(PTF z{hAGvgYy`eQeV1`1--oNGrc#!GswCPkpD`z^<6!B`%elbOScFCoHe-1w6~wbSj7M9 zjJ_7K5Vj@i{nhO{m{pJ4@5kp}S*c2hq!M|VC?!d~6Wa)*3kg{DNCA9AvowdpX&uebpHNH^jIpPYGdz3k2Bd-CNdaf!bUe zSLEe(-JH`pZtrR+{*zFA3HMzw%g~%?paR(D^B%Hd{l7(caZLzKqX%Pu3T;Hxm{J zEZ`@==be+i=BHc=asR0|b${0(?Hnv#-B>Zq?R;BJ_?0wp@FtR_`0<4K%+t1kAx#pb$K6^D~ zPWeQVo~%ObR>vdd6Um-DoojA`cfHAzAAU+iAoo)GphnX$)FhNtVS^F`BpQB3vpGHN zmpE007`?k@O<)Yp zU)*)fsfED% z%h5lj2fz7?(=Fk59pQ`tc(5ffQf$CwOJGSbc^<^o{Hn%VX(Pdl9;+du$P2Qu41f(_ z%!TCl3YTHaEO>xlvz79Yy7EmRieBXX+^R*E&g7SrsK?4HRe#AIv~V| zv#DqS06vS=X-WN;ssamFC+ILWe`=v;z zEY$ZRElkl#qYVbIutJw?GG)q}n!e3^7}HA^;(Jf`(>pJSci*_veG%FeJ=FYq@Kck& zrdX_u#6c0~Ce}u0JGjMMj-6bLnCqfg#ts1M!q{?k@#Svrzn9Hz7cu`40O7Hb{&Rrj zRXzY-dyRdJbHRAC@5<~}kK0yb3a0j!{NfHTB;)`9`~m=!fW7`7fi`#4nCgO62^Ee& z6@S6jWU9qAzgKSOJL$FoVLy)kxqqHxSt&B4{ycCV{8#vs4G1Sl-V$r^xjJ!qkI4(pHt#aVYg;mri~&Fx zc1Q|`RMmFfqQm<1OOj;~3rL?wmZm$B4-? z)k#vh>3ICi=I{?Ntf(kzq9_unDmD|D$SJoV=XF5z@)vwGh07y#ST{-~M z?bCY>ALMZX$f+biQZ>Egp#WEJf1QWNeM5Qv>umF_834+$-Wd-z`g?BA_lFyqldBF5 zBr^VRxtUsqei2fd0a|)YO`pDJE%R>C2?|$tTMi(9m>oLPhbf@hj0091a)n?A(fcwoBcDH3b zqhg{MPo8vUViIyc{A!Da+mDAa)}jHH?DUu_*P@tI*q|baK*gWEvtbRar)TV*-}Di- zMa%G}pH$|<>!k@x1VC~wpeV0YL{Gj1U1|e)gzF+f^jJdn2p$wxQ4>%fw2iNAFv+hi{X**O<;@7Pm|84#8-vDEw zGiAtb%y+Tr_m|UZSV)_RuC!p$?}@+NRrtDI>e-=qm52M8E-;qm1<8JHQ&g2ym6*4- zFY`aCp}d4Cy6|g$*s*G?2(+=K3RP9*BSF-=XWuy|D`}zj+M-6Acq{<`03LgFeo7M) zMS1cJxYfpXq{M=Dv+v48(CmNwZ_|+c1OPbeX99K(I$G5L@~&J76*l-mfOwKN6UW!I zZwYv~4$#8up*}lHP<-h;3X$`v8r(ALfrtr+h>Cp4v?4kfyQ;Y1mK+RMuiYe!?jTC~ zwxUgn9g0ymWJufZ*Kr4uaK3OcK-ct1*=jihklV7CVQv7FGXVPEF$ok5)YtP<1km(W z|FT%G4|v*6B>{RiZ~mrgkUGQPK{*iN7y;)T@@CRaNTQWx&Kp22+YZx=<)w3}slb zDXdI)wbpYw7W%y`?kRFA!__tNv_rU_{ypHp)`}4bAodrthOg_ru`&kz!(Vv)(294M zU}p;P03M4Keo6C#>AZP%XKJ^mY}3R<(cbL4xe7cB0<1rL{*>U&x_sw-cx)}!zG#3p zI@D+-TihBnSyNSEgNH!CZFXvIPrI5U=H;X5yzXlBA>#diEfFN4dvGg|hj4b%rNiiw zb^=fZLc4wajy_IQ4FTOj5S0}bmeP5d?CMD=fR^dg==?B*0_5!vN=t2Oltuww zc&t)dr^9;R+JHM0U`UqO8`)H0hdV2eh{Xc{L4L;Leyy{Ahu`yVA~bSHV01|U3MJr1 zFaULL;O)7?^Xyhyk5+5}<}WNsvVc24$UxA%?Z?5rQ!GBWVOA&3JbG9czmmgfnKb=3 z-fnkt*nVstTOs;j901-LrEbaY3-+6}dzi&Kf2Qk#a(IR-kA9+ofmeuMzsosSpLguF z8ZdfGT~;-KGFP^eN*KZ#VCAg{0X)eRZh?kgm&KE*(UylBxhYHX@*ZYkKY%(BMM?Y5WhD=>jl4czFIpp8@dy z)86mE2(*6rkudAN|K1}MZ}s`(_RniK8+)I#?r$(z%)e$EFq2wmplFi$@pSe6%Gs#M8nGF+X+E7IHc zwW%go7IDH@zAeCZ95!BVM0Vrz~g<08=&Z{6$j{9=v-A$17X#!s<6Q$2qH*F{x&!IRZfzA;wN46 zwl5)`Y>ZRgTh&SUICED|LRO=l1;4$!YX$%n9kyz@+}nIEyGuYOM}3v^uf5qwgY^Uy z*@_^rF0wM7jfjW>z^yya<2nFP+I;k!1c06|^!8E=^UIHKo?kZ?jJMC>hyivJ&v_DH zI(2{Mfjw0Y$kdFONtWtwNiS2ii`RWN=fB0+oT>Bc8gtD}k_!N+Ns@R6shp;#lBI~0 z0)zSE6v9P1Hh@5aNIvs$p15K=Nz3I&B$d^=K0hd_@KA{LxliOG4A<47Qu0|d;>C5@R?n$2Y=K>=KHK&G^JGd$V zM_>~BjV7m4{e}ro&B=)?fOr7x_f|fyx*7B4$K>JD4H>r(3MDAoYGhr=50sNrWz-f$ z&W)ecz=hKM;Y;fRfc&C-VgR6T*0pa50E+uSN*RtBVEX5L8$ZmN4nLcp?+;+?=04p3 zp!)Q$V9G>mH%*e%?eU{t`t<*Bv3Xpd`xs_EKKp*0J=E-0v_&_^Ryq{W_tM?DQbm+6 zK!HFY3Ra4u1wlj`??$C*X~z z@4@Qk?4{&FmsQ290&Z7kRSDRj0)f7dMGfz!b>_R?qh)h5w|e`XogFDq6FWLYFQV4X zCm!_OI9O=Dyx;p5L8e4X5!O8@>D0E(L1CpiT@kOLG~wto43 zRzG#Cm6Tc7&o=8Lyz&l4mCk{nv*9ju*I901-*6{$zLNcIn{zK>R`DQi?LC~vm#VgmpG zxD|hxIVxCsZaP}UVJHxG?P@^b2v{~IFFz7u>`8rZwyaBlJ_nTO+DKZYj{4u}9Q+65 zUOv4^0Pqax*-5|lo8HU)9_TM7c4!ZTXRVx5TSV6FcHd`NvwAOuHvR40WB~AEe!}~d zfjj@KeVV*j1Gp_3-OzQ2^qd(Or}y(e$HByIqbtp>pBb@&RL;qHq<2d@?qkEn7R1?32;EDGmIHyu)+l!?be4; zT2V>;DvBf&_(rzDz*l~5vPgnP5ADAtDwSGS%5q_mgh3!1$Yy>V(eSFC+Rk-b7&PnJ z$#%PXLUfXfs;K%m75w$AZ}S{0-!EPwm$zKOm_ex<1>qn3RcL=zJOKWh6?IQA!TjNA zXJ)m&?gArQb_yuD^Ti9GJ0kS{k`du`R5G0c z{l+_wj0*<$$7b>01`4o#%{c%WXK}K9O*=vKpN^J+E3?TzkF0*j<|zxd#t{+& z6>&<_1I~BxB*a>ESrfk4#*;5o%vBD8Ipm+p!yNnq03@JYtG@xp=+wqEST0MdO28T< z@}~|6)F;EW-f?lir1toCNlKij2pV?_o7%y^I{Ho=7ty zqFcpm?<%5pUG-}Q-xQFn_%}&gbqx6Gf9JNDfV|%O=eqzv?OE$byV#lheCvIDnFaT08*cM%@0%&F=lpN+c~8fl(HVtlUjBE_>g$l0%sv1tpEm-aq?J+&OrfdzFRZn#WYP*&yQxQG-AA>+)Of*2 z*fJQF6A4BV03It9si$JG&1bKr8cfqG)x|NB1@rJ^@VE*=*pkdIpBmtCp9u!gu7CCd zqa13TYBfVujRW6+KswN$+fLS77u&%1hB2@(Ud8F-4_-1^!&~xPKZef_yQ$ko_nkC@ z;BxAV1U62mMtc1%;Cvy8HZF?~LA{ktc3Lkj@ygfuEs*T}U1;Zw3*VZ$aikq{Kc^yoy?(Esy{hl9 zhi}HCJxB(S7C8iDh)^gn2tWc$x>1Ngg`hEI*Zo|~7u}srh8?_CG}H@wPYipM0l9o7 zwCQ#`?FP z17dyCeaa1a9jXc&oFgazIQM{^g{x8}cK$hppZ4pS{=h(ioU@lKi1sd2RW_XER7ABW z8&S-?gWF=q;{NiBnli(k&(CS*dZW^j;8Y%>6aejkZ04tr zy>EM(&~{YK44AyC7|>2mEVpCKz4zN5X`*Za0HDBzF9S;1G7e#=1aqWBRn3m}V2^SHhwpd^z*)aP1qOZb762VBVrH%?#=-`N2Lb2q+RazDjlcGB@uXg(lk2ZVZYx*L zUcF}@Zj9jpLTRTu$==~)?wCm!0Mg=hT%x_R{%^G>3c2{ui6ET0Vi>bOHB<(7T&y~7 zm8C-S>Bu9!!YRl!c>DR0^HBg`9%l`u13(6VyzXLvo|oTluj7_&8^-e&&G20)RY_M@0hDMS<7q#T`ziUtJ=lu*pthuMtFGNo0 z>5Rt_8r6PJ@=y5QBirAD>xCY;vH|D_IbhEP(Dr!zZ#aH2-T#jO{yNo3$18Cw@5Pfr zlv7)$#+!H*n9s$N-kg2a6PVD+$ER-_;EgZ8>#*OTY1dRhFNZEQB#01ORf$*-0qJt` z{nAjCLw)3xS*>5;YnbQm-P3yZHT@RVFOWs&+tfYOkoE(aY=o%t@FkV}mVZ<0iX;>L z;R65|SORReuNk6UKr%*-V@HY`Wd&@7atOf+Hed_s2FcP>WRJ%H0N(Lu?T!kMt4fJ# zr9Q&2!#<$l?BhB`tS^0K3*Tg+FHGh}=*P4xAlV9J$Dj}-Nd{v*mN=AsU;i**BgvH zRfWWXpnxzLnR~{LavHys+9kj%fd6x_GRchYr5V@wogX+05He{Sz+I$7ou|G`_2Ht> zU9;uL&&(MpWY!OgJ7=5zzC8obJ$pV4K<*42w$E6v{5)j8;gHjB58TrmKxuO;WxzT6 z!5Q@>uL;w{t_Gky{O{|fefw>X?I^-ja{tD4`e-+9-La_BrACkdV{NZ(uM*eW=o3PE z5mZ(EOsQ&8zW%2oRn&7mr7B6OQYov6Q~@OFUm2ZXH_e++B}S@rQ`+$H!&QD?8@LNo z^DVF()bnwm0sByrO`p0=#J%9$FE~5_sDwh<9PIqk)BlW6sq{WQD)r)LN>fcOO922L zYc-{$`+{fdZN0-RHl>#EiJ=u<%+N70q5JHoOLKVRH=@HAaMr3e(B`@Zpc|7_f*@E` zqQC|<2-FOnJNPE%RP$nmOIm-WJ53+qGXOel1dfGA>$7>q1eZ7rqM1OaUmJ%k$$G831zq!u%-Q@m!A{ z_uK7E)O|~rl@6fyo-ZaH;%tzF z9f16B>*xjt28?cei%%{$pO*+y8R=Lr2(7qP2+9Ww%IjaIc$~d{*0dMjmjT%#4vfIE zF-X{tsx9?VL@KIQ!|1yKeoDo@rd4Cwv-2c5(5uyzmZ%F_={>{i;jwtj#T$6*>*vUh z+#!{he7~mwplz(H0cu|Of!Zxqm5c)=L4i3|rf%P2vzZQTtt&N)V`#QeE0!ywWlxrO zFB`0d=4aTGw#+1X!G|EBk=vxzQfdU~jgc&f$l%zNGXcafRTV+hu+P+B_5DG~WOu{X zd7eoFuvC=Y0BXMeoPgC@SCLZQ2NfF(OGyk@r{WxCincEQpw0obqRWy(O3D z?qF3Z;%lU;%EpQ@LdaMlC8@*8Q20TX7Xgq;6$C%qs!A!5$kzhYyGT1Y<#q}+x?&4o zK!sE=*okLWA4T31N+5(KN!B8Pz7Poj-a4fz<*Y@qL-i86W=XA7nOyq5*jnp6gDmN) zeWRR38qHzyd4r4N2hNh~?*O~8?gi**8WI6gRVCuVlb}FX`y4;#2=*05}Of2A!Epr~1=+U(ld;fW87t{*|+74SXgfN5S~RC%1)VY`qj8 z`I2m7Js4s8#_>56yfy@Y0eYjf=;+tCm8j%V@?7J)mMT)DF8?JJcXKY=u%1thoY(H~ zV})Ls(Ng*{KB5qD7#Fq+x7%mfsUcyT5LwwnTSi6;ArhXd`bo8^S~N|mdibgU03KU) z-sEl<>=dnfUCvfr^6BefII1TZ=9o54Y+VJMzU~JYIhEsTsH!aj`%$yOcsb$VKc1IK zBlFeheP7bRPVgo7%JO8wSbfm!yGYA6ZO9&nKR&ut-w;;lbEI;qUaJ4sH;E%Mfeo&bCP22fOsz+Bt-~$NTl4 zf9kctGICGYg^2qLW*!c#5W!oP)vxqp%N|=Cd=*ja-XtoINqsL%L#y{^`RzcK4Tf0O z=$SEzig?icT-@Po_MaNyv&e+Xgs`7M+zbX+ec@Snl~UrVvRX+Kwrn#h`Scg#J9P^H zembR6X0C^07WT;!VyDi#>}SE0JcBIxndU+c9K=lna!qYu%oZxOYTH#+VS|RCK(+8} zm9W>_sbqI$BR)$y4XSF3_MHc(n?pz?*0c6UIam%pdVlikW%rF2*46J_?+}&J_o&M5 zL{$u9YF$O;=zDx25B`tEZ6a^9{G8|$pI$gC@rXiip zDKi2-AoBr`_`Rg4RGz7cdYM|--Om1r{*3&|9X);S$I3#Aq%g*S4`jWlS0(i-N@e+& zTaf?@uuOLCRjq-AAl>fN)#;)CUVCasSZ~wSHqzXKgnlL*iYo&9N(=+8Wg>QGF62A) z+9c-hG~V+Q0NyIq(WJGBVJFtUEGhP?OUYT6#%w$T9&@8w-1WmaW9@i4;N-fmKvWjZ z%2m}kP{AZnUvSrIilQa(4fQQc4rJl?GV=GnmhLHZ^2lH3h&hZ<25wCr|*>K(k_~ z@w2(j&Bdt+VLFBO#kqg2X;f8PK+;Bk0UIK(9G2|Ou_Ys;xvy;J3r)wA{^M0KeO>2E zyPCt0I zu*Zlj{AJ4ra;$zqzfub=G=C;v;@W&P<{a4~MQ zT!4D|#Oa2N{@i2K@HXPzUbB|}FqO+uX>M$1?;+=(b2U3V*0e=g{VPu|#xpH%sI^Df zmtRHTB@i>n8lt^jl(pc5`9-!`X!3-4T zU$$%S>qo=x2A!ffiw$))dvEL-_r-B)nyIJ?GJa+=904ZC9T_D z%J1*p<)H2~nX$;0gk>brJ)_Lj=T(JX9G|>ecPBho_YBt&^W{N%lU`^vo6)^TPibyB z9J;fs?}HhO*pbk#jazQYQOih5s#3o~N@@%2*Fyl_T4iR;S`$n>sStfn#fH^&h!>@pLhL`*Zu9T7G@MJT5-fZR|58r8NQU2Anfw$_vP)0L=ZrA03!? zo_=*}L+JpJ6g6xW9|xo6IP6=e17();*{Qe6j1v{C*|$%ltkex6sppucIT9T z`uyEq{aW$n_tfM5c{&+*NlH{y$k){GXSZ;2t(~53EFrGRPobxUfhzKzM2eIzIw=c1 zJ;rNdjk1F|?4HQHT<=G?htw!?>a~1Mv$Li7s35mr zCpzUkmApFA`p~fQ)0PnM9#IiPL|!iXq0H!^j(^r)KDpiVpXxcUQ|0_Gx9i(|)IH;a zF>Dg>oF~|$8k$etJn90V=q@N=eE;X2Q`yr{Ra;v%K-AIFY#JFGG z_IUmBV;X1we9iprbui`pe?Az_p8V4%Y~O^xv^(kLR933e5Gs~1fgXA z?*lLpLPb^k-b6@&YOoAKLhwU{zx*d#7Loz+RO*eUDk}a;JVJJs98X`LBk47_cvhvz zb&xy_&7K;2{5fyHaJpg@f_7o0`Fx0*J5I(Y4puA9nZ7?X3hC-*zNSN%ze|(4F%|#- z08eLUQvd)!z5)OM0002_eZdw50002W*^YTw|1|$a|3&{f|3v>k|2_Xg|49Eo|3Uv! z|5N`-|408)|3?2(|4sim|6cz`|3&{!|4aWt|408m|33ds|5E=)|4;u`|3v>s|408v z|3Lpj|3d#j|4RQuzG|g@PG1x3!q$mbtf@;l3mR785mkYIam+95v34uo&~sB8TSJvl z6*j0~5->$=JNmO+%l+Pc?{sa3JKzqC939&}3`cI~yZNW7*E_rW3IHI2DyY7+APPn6 z&-?5C+3nikJkO0YbA9_|GWJ}5Kl=#w6!6fE&1Wd&rA2)rS+9TTPjj0;=6!4<@2|IU^@omrTaSHO zvQFJDuiLqCpViABmAQBXJaWxgvgLsMB2+}FE#%6_eSt1fE9`;}b=@M7q_ zu*iCTBm@AyYL&hx`bE(Otru#su`ba*(TqV$4Oe?36Lh2RFB2{t4?w&2QiL9DI#XPR=PJ z*`uN&b_5kfq4#^5%i^|o)ZVw{m)Geq+~%Kic~0)oc+qpY0N`3JDr|qOzx|%^${DYC zkfyS@n0rq`1Hiq<@NWs#0Z%fVW!I)chT_X>&0lWT_5Ja7pX`y>>Q3dsGR|T$pE^l) zy8GX*jBof|nbC(^mcf9w-%S`>>!S^EB;3`rr2pE+G64$$S+*=A0IXHq>yYL!r7!|@Ohh_cUB#boDbqe+a~9NZG!s56-i7*tp$cTLxI zyVo5Nl=tsk>B7Xw839BD?TgCK--4n#3Xgy6rle>rQak3~k8IOcub&pLK*L>7&ZH~c z$>6Z zgf;WPYnJCr@Rg zePc<&GKeU3QYHK??6|?S*e?9-p>FC`wr>xA{rCW$dZlhk)dllrH3+!P`hLXQg0b1c ztxn9`u8)GoGNOf!R>BV?s$wju!Uh!xh2~Ap;_=%Aahq4yk5jC#D&pU;Mx%yi9S3aodjSBxI%RImoD-bM+F=xXHGL1g!P#u# zld1HsM9Kxu$IbC$=xd7p20dD$#+D$NHRPmK*q{V~o1SaMxJzbkD>X#spg&)qn%|ip zw{8~k*_ZEu_urge7GEeAudAK$Yo|`w3m&LYQRyR7qZ%lyee>YI$Qc>vsmCp{ftmlm z*VhJ;E15$9s9^?`%8ToB?Bi2*_1k;_u-~haZlH^%h?B{$*?Ss3pq+)S<5Py5TkfBG zyf*iWi#gS&AhTHU&=?qgYJW6GZ|vm9*Lu61I;O{UqjvHM0DS9@H!`xolpimwR$7u| z-bN){jwxva!UDxeV346P6{@JpcdMy(p%sAuBw>M;=Yazbz_C7$+eVg*VG+i1Z&BfC zlYKN+p$)&LB0Q_2Nx93%T3s+dg~U}Pl|(O%;jgpD#yZL5l=o}18UUVZ1!l=S2fR0{ zP>c0_4Q+zwW(&70lYiEkgRrbU9XrF)SOF#?#DJ{!Ryp}|hI@a&gwrjuGx-nTqKg-v1 zpn#lSMXfY|#s^!A0y5uN)BubbRNlK@zMZ>ThCVXM!BO^{f*IyLRbZN57h}|Uyq|La z+;nD35XE#CpXxKyz)x;5s)4TeS^fIBrOsX#^V?nX#CC^j5s3uwe{}|+`UNOixAmcl z1bZ@8Y=y_m5W@(h2xBYqaKuAz6;&!;#Wdre2WGp}I#+Jx*l1`^Dy4!-+ufa{hj(^S+($cSU)UO0o48Wb_1h^1)k%)C25L&d(FuCHjSIx zS0=+$rGc8}%-2}LKakrtW~t4k=S|JpJ;(bwlJNdgAQu{btepuSvwE?$Ri zjxi?_Qie>as`~%`BcyQQc=%B>Zl2odwD}_uRaNDSN=PaEO8T)Xo38rS@A+$C-iLN1 zsp3Vmd3IXlUbdq1c4TlS}eU-GT>=5YtCxc{ms4V@@iB8 z9(&bo3jKh+SvzryjpG_(!Fe;oV{g=0o80K=rmW#K7`f2>5C*s^X$l*ZAfWZ8#{1ez zJuTMeYol7*b=R!vT9LP#8YQQJBJA`V8h*PlIqU+Vdsvd~?6VVN4gnBQ&IOU#Z>l0a z`I)qbIYWVxivmKR0IGK!0Z&Jb1Ao5ZVQcd3W43dWIp^E^d;h-AIW@+u`TFlopc*>I z*?+!vbwgYXO=6l-DSD1P5#ke@}P*CHySDB68+^-6c{;{IN}`nxww#a`4~ zEiHW!yq)q5q~}uVNzMOn3_S~IXL^1=KyHiuP>+V{oRtR071U?#{Kvf3ciR-_wd#JH zo0R_LMPC5yRhKcwr)`+3Al)-GD&_uQ0dx!5~`{qFO@3GR7K_qv5k%F zV;O(kbjl<1$;o;Ak+5vrhw=ZE9F#r)ew+1aN^2L%e$u)fv8%0pO~eHEVRmND_-ODN z_Wmilp<}P3N{n2njiVW=$`v*^JP7oos_;={}y`EXJ%kyq~!%OhN~9WzoxnJTcEd z$6EhDS0w-d(Twx{EO+IU#izG1%<;W;o#!mam?WGjPiB8jLT8}}JOJ*Ln@yU=6w1@T zBs*U?^X&TGKz>)&`*8s_tY?Ef{y68$U>@gux~Yqo_!zMM@$&@$!m_^F@%8F80zkfz zzsVP~9;==?6(&K^EejBmEJI)$2Urm@7^BF>)DCo5S3_qhz(}?Y|F0N&v0d!fJ`B^7 zdew;L?fT2VDe0coNKK%bwM%zJ437=r!OinzT zMI2aMZ}9Mc)Q!&rV;un}H?WGI`q_Rwik zBZsN&%_?5f43-OU{Pe!OjuKifB-fT75aNzRsy zdT!Xf4L#3`OzuE;`MZaIubo}suJ&==C8N6LU>RLg|Ssbn0Ttax1RT_Noa&nWC5!|_g_W^VM}t+Ne}{Y8^9c| z=2XVfwwIqPHKsl~Wm2VE9d9y%-Aw z$hiZtzv1;q3Kal8n>A$&b-{izJFvTr;}LBW$vm{Q@Qfph8)#}S+#kbPLq`~WL_OZr zfIE_qhh$S>gNq;nzmr^d{_E0O739h%BsLiq@taorM&&rp!9}Ag`~6QbH6e06keWNa z@#K@2@~a9UdOfuI_=t*vprV4RivG=sAaizZH`5$*IH&)YWyMe^bnY78J_jh%J#)c@ z2CHs0;K!f0{vOQ!J*Bf)JA2#8$Ln8vGf|gWS8vXEMGtwksRlfI&ij~W8hflS&6i*6 z*RAStKMaofk_^%SOy#(Yu0pBb_u_5d_uVkhWT23BgF&cjtt;>GuKZvGG3Tg-J5rwO zO{upeNpGoC6_wPNB!Ml201GY?OJD$FVI&lget-lv$OeP#b2#=5EQs?ZAwaf?jguj6 z{Ua%Y6rSlFbxex~?wbW}x3R7% zpWuGeQs63~;{=4}@V76(F93iS*t0P@-D657wrUN94N4GjT(Bko^mgW(@$KARZ0^d- z=e1rQOjzK72LQ1W?)$2q074%{5LHnlz6=76?1)B=*SCe$ttDBmd(j0z-oCR4HXL|d zFCV`bAkVdnt=Id`VotAhAe{g{HuLuQ%-(OituycK+qvPk`LkBon?3e0zgZvq$BuE% zTz*U#%y^h{4|e!%@jL@FIeXs8f+~5I)PiB?gyJ%Z@&0;Z+QvXRleS`k0a@4}ym%Fc zSGNDUT|EFB7}g~(n1`Z7qH!NT>xs>G9xABhS5hG)Tj0mG1%ZqN{(vNfi1I-&5=@Kx zWN?_IBJU!^$~{YG8_!}H!&Y6pN7cLod0e^R;J9tD_F};!eVtz)$e?%#Uh%SWJ8}3+Hr~bnPaLx9odYko z?!QkN_}(YXi`<)e4*2@>>hWIybhrCKZUCczg{S@W__3aN9gXo)8vzYHtn2RkG6op- ztar{d`KdYL*MFcl6P|9r%If5Xfk~)_UaZ6Kq@MD=XzH$L=f+#OGzD3Bb7okQbXfhM|*h@T*&E*8vBojJMu@ z*wAyPuxN)>1QU>HEvITF>>EaJo!8tz;V&fp=2SgHGmE@Qy0K@@Sy?B>%{?o9CmLw_ zZ4Poccj!~*eE;e}@WO6-C)3${q0v{2DrM+Lk5Xg4U;dcR!|S*kOnur)fe;8;7=r?q z#1JV9A@0Px`ZTP4>3v43g+j&uRaW>#2!t`l_lIWG#TMR^F51AD+u5rMX?|T473aO5 zcD0S1h=P%_DBbSWqO~RKMt~$Cj79J>l5FbsInhd$vU99{EroFaKC5-9r~HEXWev65 zSe9rU1m{glao}nUAz`ro{I`JDu=lP1!3|sh%}bEG`K}$n9F&ZO+Tn7}Rf%9iSOf40 zAYiYLnB$c)GE-gs-`sS(s%vb4F^8GQVO$GD2<(uGeD>z`zy_bKs|nX-)8^{ z8EA>>m%ZhHsDc$lE){{>!>{I^Gfs_NUvCD~VtF5XLc8Up;AN)p8XYK1qocRq&cV*x zGdug-$K2kZevAS8Ob!+pN}+h(?fjYO4 za|M!(1?Smxv4i*9w=3+BK;UWjncwUxgg?oS|0F`>lj3W>JpZ%aE4(v9+Cs`NLrrPm z%Cra4r;Ej_39i^C?hGSBMum`Y3}DN#Z5bOIEOKqiN;N&MRtCf$Y-1hYoi|3y-dg(` z0KST4eopu?Fn^d1+-hT85_%BrAKD16y#OpBtoZTc=nZd(`8WTX(L0=VEVN@C@MeRl zmabL9Dr|5V2;A*1TG6*y4z%rGH2V2=_DBjzlIH*MvA>*mjbplh1tYLLdNoxz<1a z%K?wQ-|wG4cc5i9<<{>;rztZq-gdra-{!nIr~k(@2eS9Crh%uY0J`bM6xS|*EQWe1 zsQGi9-P?Z6K0Y=#Lo*WI3t9&LkOC>ZHDrYifN{;v{#Sg9_Wt6*TnQT-*jkOHA_?-V zJo;aPN+SpZNJPefCaipMSY53r_C8L&jc}<_ey<35wW>ZWh7+?5Vb~kF;@I0!Y|CI| z5Wl>RRH%0<6;X%EtKs#3>$_H!Sbw^{mh4#zGC1AcPGr5b#bdvfEnY7iJg6f6;o}IrN93p4;89H5$mF zfc9wsjBF_yk2&_n>*@Lc z1I@?zzPNAfv+w<%<<~ixE}a~b$2;h1i#Gu+rFrJD{d;}(+3UF-E;<7QF@UiE$>8;m zl^*hO6bo##(f8A0=j?4mh@lG`NeDYKA#%VWe%uy+gFqMn{Fe3=Tr^_pT`z(tq3Zz2 zwtoUkJy^Xju5VePxVe`+TXu_`JqZN+U?ZMXeu(a(uM{G`a{~UFrD;ji z3(gNCnAIA;q{RXI$u=T$%@%YVKtA947YP@xfxV7%HJ09~u~uUtR;~&g92x}n7Y<5x z88%Z=Yf@|u^#&`kxtD*&(~0zM7e)@|1V{A%ni}w87K<6zO{BV3IOeLdR~nD7t_!LOH@fuVB9}y?>d;= z`(pvj;MCMNaX(+1KmL8MVRE{LOcKa-YkiKoA9Y9Kgmcohsjn_*I;C`ugKZg66(App zjQ%$DlVAVL0svGmez)9eweIj`A!NxA*#LoM?4LKtS^!xH1RNfc^jPI8_p;wcoTafD zT4ROPQE&Ixcb632l(uu|rcotx3!QW25W!`z<2-h zy5~L|)BWMxiiB(%S>QLF3V!(b4FisC1AuSBsQHLR4^vuld_L6ALh652)u_bRs`@ig z?H?7tS3yCfy6ekxD~KcHed1K#a|UEAZUM$@R5M1pYT3q95%TO^p5}_{`3oVfnPca@ zB+FDq;w@TCOv0=FzDZv0suaX)vd?H1Lw=ymE3JDQ;G}r4A~Bq5szF z?QH->{cC;Z3FEugB?Ei-zBgd{digegZE&97dr#9{0M;e_?(OlSmo@|a58J-#x#L2< zb<8e+&RNu_)==r>DfQM5|5BTwpo73}z;J5maRP!jRsYs)_vl>c5te5C%!uARA;J996q^E4gCrSJ)6e6c@rfLc|BBd}X7 zHlXVIO^))nbz?txbL{u$9Pvn1h|=oZW4mXsPyoGj*LHH#?7Wl!?B`^e>9s_ov*Nuc2nM*hSxSGfY@e1&s8QYMQ`mVro#Fmj zn%3QdwX^HeQ%a`aY?qnlY=3DieR0ndzSe5ZpLb~~XCB_@=}f^tP~T~KIQZ%JV{Om> z$&M0NxR)oJtwjT*@8ecN^G7nigK_kab;H_Js-Zt$^=MmlEYva!0~~V^mpe9t{FHnc z%x6kxf>Et8VhigE=*ybvny~h^Q{Ij1!*uPyLo&v6rdGa|A<#BN!1q^ARj6lt2rnLF zm!&U8dAGtwW6na_S#umEhbO^ISER?$tkY0-WGB7Y{K_CwnxIa8r+uU0aw<7aS1yt@ zx0IT~K&me-UtI+9g{=|0x%*yJ#EU*!esgo#)vU(z$Bi(jcEDyPs+V`K-r(&Gc&P8^ z^EroPD2wVxL@4^dJ$n5UyxPD&JPR|b{fT2DE2@^e4nB6AIqRVA!f-vFoUHF*^?tRY z7!*Fic!0>uy9)}LHD~qPRSp_+_SZPv@U)$dHJfs&xp^smkAg_W{~plSbdY9WxKS@v zrPGL$np|TT+!(7W>XV3*#O@cb?ZRz?seabf&_|Vm;@{oeP`taJ*~RQ;|8hk~So&Ih zXbzVqvQ}dB`sC~3g|dZwOX%9OFC@pCgwkN`h~M+Rnlfh9^d{lG)k!1@+H_Gvv$d}!{`0cggZp0^t z8LmEK^R{OklPMuU`iKfqFMO>Gior>^i zWq#&o9SU9&$9)h8T1_v2;L?mMuZH5$F$dxTmkdw%6%KF^7go>i~ zZlXkVVQbv@c6a@nn#~Hq7#160DUYx~Tfx^$mYe2RlmF;lqFQ>%p(a~E(K%X! zWKmZZAs}7)LKFm`z-+ujficGj1~PtbqlPb-D}0>?MDPj<7@Tz^1MBZTSzAc&F!&!eOjhUs%h zoAv~vnlAm%t^$Z|V~v-`2M-M97d`mKg)I9iqT>LFnq&&ff8zrwBFvI5`pXv9{?04V z!eJAvzVNT;6qnJ`e+w@zm6=SXwLQ^oPBW@aN<%no=#BB9DG-lXvh%S&b@}4YE&-E6 zROqd94UbWSU?JpF0(W%bPAms4}`}^ z6rwpq{NGO7;x@0PkpLVPc`zyj@nvGHZ1ZWUcM`0n!4U+bPaWI^)3wWoxKKYa_v`1} zuYY>=iJ~|JranduIdA)#i^^vVH6f9f)T@>xNv(1v&WW_-=yof}yHW2~=j^Z=XZD<) zd|b1B!Ljvm^tY2(Bjf%2d$?DXv{iC<`5mF5gv?8K>O z95a_Xu3@tD^^aJSDC+uX zBmrP(K~+>@CK`p-=3V1&+xM?SP`J~R4dLRh=ke+HQl!(FjS$yc~8$Z%{+-6j^buo1b07ThFYl1e&~3b6PQSk6I^nd(Md?N zZ{Ae&!Z|ITioh3O@0T&ZUmYoQ<5%Lv`G?N}Sr>jXn|RfmVl~}(j`*t8;pEExO+DLk%m>u$Bmz;Rxv zG)dWewaQjyBH=srEcc^1ch8Sby??n9R5rv(2d7PJ=HsikDJcj*g1q6QgU37qFxYic zhFL2<(MX$TjGssECz(hjqXRXw4?Mo=S-`OSv_RdVK)oX%vHOfQzY^2;)GT-x@^muR z)bvy&6u&&9ga^V+C6ug6|5VP&fLq z+r5)_gf}tVnwXDTB4WtL_3a^sF;|+x_F$`gKCbf+0Gi#HRXWl!2jeQwq@rvnF25AEhyuJE;L1>C*^|DsvQ^nZRkSk=eIsyp>2|Pn{E1FKen#fB{hG}r zX!hmaFyKAYfo{L+Z7eZc?<{-&erza}fbMSKVRmV2ZgPWb1-VIm;+tNdRS1dBs|Kh4 zEVll>TMcq?0U*m2%T&v^TzH}wLL8E8bEh~$9;T*b+L*Rh!Ul*@w&V9d-&WONl`Nyo zozBRxitf%7SlC^&DRTBux{jTg8vViqaWflb+iO>a+xI(X&fOVepnW*uo#(BSS4R$C zvbz9XP8nd?pXja~42{O!>@9<3uLBftu)B`S&;ar_rG4Z&1F0@l!mPx=i2k{NepZRF zB#qTpFSMIG7Sv75PbLc!wLWkLSa5KqanC`)awX55c@(%G0aGIYyf1|b_r2FPh93@B zo1BW0Of3TO@qBJZzMVF`{OF2Spw{rR^J6~3KNJA*8irj;ChnEJFX)c={ZSkDf5VK% zjB>gv%B%IJyoqugQvFin9lFNOgjtqarx3-sYyhxmOpX(xMl;_H9kdDIx`yxopuT-8 zA^wCi-P=Q9C(7n!8m_7bJBR&tBU~2P^%;24gickpEQ05j=xi)Tpn;b@+|4^cv7n0W#Rb$ja$mU(Q$s<*fj_{jTq* zB^U1Ys~0+T-(3ZF^HT(s9A9@xz5~U`Efo8IKD?LQUA&Sk;z~4*5_!3IVmBPyZE9OJ zd~s|b1@F)PaaM8i3;;Sj*7SWloJF6!ZUrOx?0o!%vh_}f=674Xm-dAU;91h z@a+BeAO5ut=eZ9s`sTV^HR4;cp< zLY4{QSyo#?MJ0lFC|!$hPn{*&=g6w{@v|ICyAQKwvZMisQp`tneRBxxYcE(SvbA}N zU**ZtQmbwgK7;sQ_LkG1n(mtTqQA@jz@<895IyiCL2X5f4POvNJ{ zpQ_-7>=PzMRNHVVJ`pn)V$Ff7L?Iws*!8~oeoT!>!i$bdZlb^lIBI7uCF6^S^goZe zWzmh%o25z_yt;T9JMqZnlQ4vjmAQK1C;nsC1spdF1V*TLE+G4du5m396jPa~3I?-#!f`105B zzHL?5jrtUJb2iN0DX^QdVI#+_O%kq|C@c$-=yTv=(+L^5HFZ8n0u8iyE7CopEobop zbGgj8=6~UH`<)KY-YrLg(ON|c*6vclmVJULq2dmH@QHla;ZqZfSDERqxUVndqK&{- z_}|6HE=&N5SGD^7J<`(O$|yIHeh}03+a9`&Y-L^Wsaf98@|ytnazCL5c$VLKe_^r? zAI%G&ur#+CzPeMdi_(z#nPmiOCP=vGLJh-8)?KQYeP)Hf(V8K0ZI%!B4#I+qs*B@T z7rRn)MYx{|lw9r(0F*Yu4<}O2g5$m`jWgbj@{bqh|eRHIe7dcS45QTI_=5ThjSH%s#5D*M)m| z#8nKa%Q_4SG3rDA%sdUBq0?gx)o(fmcAaw!shHuq;LQ}g9=}jdY}PGPZKMhcaIOt& zpJtjnTl~=w)qJ$odeT7#FkYW&s`_X`HpNsm&1F>Gc?R{r}>yv#TJbnRAjZ@rf@CuDK6QyV=hHF#$ALzD6Y}(vc$ZP- zS}=Bbm0s$uFdL?;2EX*fXGCfYx0D5#KlG#0BuZ7ZobH3#}^WcwLA zd^aUR==sU#<$8PvQWuIo?(>YA!)=U7xmz0iFAxhN%F$;#Ar#<4vHF>rD)qyFIy$iU z*n9C@h6M5zAc4{98+zf!gMI(rFNmc1Kn8`cqO^(>GanUxh=jP}(ZD1@?(mA+1x#2k zAk=@_3~KHyU-SRm0xr3+akK)Cvn(5baJ<4dJzTuaIXGAuwhjM5uJ1O?dLi$h(>r7F zFn7DzPOp3Nu?M@no%ud5SfkDUtv`c&OTvVQQPKoBtu3%O*vYVYi)hD7?izav{gV{2Fpm z?GEQJG(U}#3Z1ben6B@p7}Vtz%TvBWaxV(p0aA@1$U7(y&!?gRp*?(ZgwVJ|nE9u9 zo|VJsXZ7`(&@+bL=$D~KFV~7T*O0nv;%P1sfaW+iw3L@rm7LWueaVpFV+}@f{O(fo z196PaZM-mgkU6;}=SJ3R%-LNvokKYqi(9)gIUYz=O%+b)DKMpRyJqgqDl?EmPQS*A zgdGSH(f2tcA%EC5(jl7!3<;ZB$+k}{5y%s7P=M{HZD%qU-n;9!r>mu-H8|0cQ_Dd} zO4VjA=)^(r?{)*U&U<71$_&o|K)q~tzEN+*U| zlcL}cqtQ7^_=r?%ac_#zRz59>f`94|9YHeO{Yh*+9kFJff<`@CGUZNK-$Fm-Bof84 z#+ZS1`ka|kxLU1rg^l(UYBbdg1^;+deeYEJrPQY3Q*&%YZ6KqjM)?Q+e}Gj5R_OFe zTfSUs>eeOXDh7!f6GQRM#kN}!fN&h~?Jtl!%9MV`nKd-LR)j!;>pXM}vR=L+{N{fr ziv2#w-lWPwl3v~K?dGIJ-6&xzJ>}4&4@tw);UM?+p?QVv)BFdl^v>68c`MN|reeD| zRPx^XhriJ=wN_pGep4KNFga`^;HB(0)e?A7Z#vJAyE+b<(;FLIq9br7UwJ0~+<0D{ zqbu`$^}UtQH4KWy?%78bBjIVgWrMe`(hqE-q~n!|JM-zQ$$!SdTAU~y$~0Wbl2+s4 z>cOJk5)t%=7F3bcJC{2Ab`Wz6Zuq6;58Y!mY~Z3x{IL1W#u|aXnyXSL2WziVZ)VE4 z?_bg`ZD#xgJ8~)`bu>Nnq8t6Dk6k?$m~6QYc}9P5$YJE+Eur`D8r>W^-6uu<+(B4P z6vL(9w?6$~@dHb&}$*+`U15F{+A_`g}(nY3#vgsKS9%m zD*wwXNkBRmHcuBFHiLR+mvjneC=?gUgz3ydeIoB%++*1cwLwu=x9rA6cew&**Y=ax(1J zGOE4KV%Uqnqh$0~wt0V$m8`dpcaggc(eyv)Z5Ll0OXlcajXZ02r~+rT%=Hb>s!G$r z=9j-M;SwlSk-YeDvwCEXE)P{1;Xm245YrrW@)^Xz814TEY zEsIX3^rzJ`1OK)TLX!^mm(|MKJ3(y9;cd>h$R@9{Q-V&iz42s$)w>wKSHFyZHJWWK zua>h!gu8_JQB;=xCr4pxQO8ekpB$RmL;;9IjlV-u*X5i~m^Nlk{MV@|lK{oj_W*`e zo2X~P7)8F%8hb`JzHI<&qeAGYL_y44uRN*U1y=cF8;uk$qkRkVJJ3FX)8q-|<7dkS z$5)x&?SoH3FXMx_=)yj3r!rIEN%L>&#p4!*tmpngZg4;s(d-qO#4t}rfxJ|uS71^- zrG}ajD&e-G-vl{O?MsOvTa;I)!aor(c*LFSWp0`?1P3d|-~VIutGDw*V*lZ~ry}P< zvJl~_iffIGlVsLxCYf(x?~iTOH^rFMG8Dtdpi_q*BTN<$;m*TVfo9U$u$=YwC#KEthYHW0uls|X#Uijhc7yD?Q z%(~{CAOmTpSJNFILGSP5CNr+0)+ZE{@rhW`?}MnEf}Q}fvf{tZ5~~zCa>1g+0_+!XEqTI9c%)mRqLi2o^A3 z1ogvH?;W^&D81BA8 zKsJAN8p8?lHyl&AEq?#ev@8_rm!?8YnZ@fHILb9@%A5N=z66?Q2_$ij70M_KkY^FT z*{Bo1f+2u`lQ1iv)NwyFkf1t~(ZW|k=VWWgjquHyc0VBoG9EW3x|O>xH(GXe(I8$T zMVUhG)P&o;XUL2$bp?g1IWl$&a|L(m=IqT?SXY_wUNR}ZwM!2#*+|oZNW+znrB03A z^Y&-z4r=TaEZHgu0M8h?cUti1eD99WtdEtOpgQZ`JRd9oXabWODWSv?<1c0)3H04? zmY^=gz>OJg)I%IE!xocFA6Ht;0_afulu=e&@1EQAP92?j3rzhYW)DSJLa~qdfw2JO zKH;TA#fLv+p5=3*!tBVBm=)%xZGIsvX{6gh_>%-X_pjI#wXz=;Io-Z>?wj=Blt{|W z&U#K)gPB^Kz% zK8`GXoGKxEDa#~ECV;4~WmmnLIF7Eq@lu=U61RH2`QsyXJ#+QG21EbaUu_?(Y`#!i zjJ21m#H_fStl%ZK*JfOZeyZ}W3e0T?y#5$aL^|8I&|A{|@qtIjWhXEee|RPy=CnZ<-O}5 zX#?>fxb{T6MJDiW#akPqCS&$72cQ81e5ubk(yPNHAF!!>+O^%|WO>`_8?Z{rpf*x~ zR*+0alx{Zu%r`A%td5>syhORM`{_Bj41;Ei1ZHKxE)9MwWfph1Vckj?Yykd;k5F{{ zS2Yp(hsMYE9(rWO;W7^fs=o&;YSCd?Yh(QuLY3+060-+rKZwx5fOIldN0hzOR5;9& zG!QPG^-K+Jj%adSnREc9!@Gxu#TSO`R_(5$otobM3vw3sxi|tKOU`Up<__+}{7BR~ zp~g-f)-vqAhI;vU-m+1ZOdkhTWg-q`X zgAZQwFYy>jHFGe z^B{{7l4=$E?`2DiJ+9PK?wtH%IkvZ*coYk;FF7G2_1U*WPfy+3PrbT$)4ZB((*n5` z=46=91p!82i$*`R%krZwW(;cwC`o5 z7r;ORa+vpvR!9!|oNYyfK+wZN*N=TkRkh19@xu?xi3o}72R};_WZpL-hr?peIQ`?Lq3Ct=%lMBKi5awV`U8?Zvq4!fY zyGEpdMcpRDLz;6|>_B(S-Kp>);O{d(r3!-C{0bsa+BvaM_~+L!vC9?Uo!@70{KVHny)PEu!nt)ysxKeEVy7&pBwLy??{6q^wav0 zONCxR&X!Y-T){tE#W=&xq{$s#gXanLHETJ{!8&G1Wl$h1^mYigePn1kCu=^~_Ad5* zl||kt;$3CBQt+kPJU+jr*W+k7#LLe8!u>>%;Wr4@7CH{$yYZ%6^E}vc$2Gp!ZjaQ$zgl`2%~f1-lP9Z3*RF$ zGPN+miZa2k-FWw#T!vQmGrzKXw$4V~vHc~t^9LyLa>jeC9Q;K+9`l!KXwy_Fyj3l- zi)`}F@YfzV@K98ob77l?tQsmN!~q^2#>F7!g`G7k%irEjIBpU?yPe0Gk`Dn92&vV{ z^Y09SL8d4Fji)KLAFXwCf_B7TSJKSZyf)z?BsIU_hJHRwH7?S0`WA;>!g7LvZ) z&X+CNR;Fon)wt&*TBGW6O?b-S@3iAbG3ftJD^9mED9T`E=p8!6ou)H|Co`mwtmG*g zRnYy~-7EIAYN5o zJ(UFvEV`$yy;?}f?T8&bt&-?_9I=M>#Znp1>xIaWP<_eA!lCqn{RbQFlc?q?nO#2r zv6jyen!>_tk3rR&&k*?a{5S8!zP%+9pEIj}q!xw)$`39kpa`6>h>P0*n7mEvAm_H8OGPA)D-dh7U|DFb_OR%p*obzms{!x8#PbiqQ){fh4t&TWdPkc!p4?nZ@zG3xSQaGLo?J4r@^lk;RuHy+L$ zph8pYkn+^Gw`Si&c&Giq&biUBb@Ag zv8@N3n?f*K0+tYRoCy!MZEaTRlwXRBXaw&jI7V^lcDOJ7Z+jw*-ud}o5e@}S-#nVFVU?&}6?xNAde^ssP+L^m)`s1k%F7WrC zh5x1Rb`Y|jXyT?(tan8b73Zo$v093vT{4#6)0b+Gk0phFMA>uDMfI8){(j>vY!0{< z@t;vxG}n0cm_Ol(f$rHM+Hd;6do@0SXVIBwHJYSLsBBEOF^1F2xHZO4zepGIGUrv8 zh_*7gobBJyFq+D{;F7_{w!9m;6?EsWLIQ#L2HKBz<@~iQXJHOsgO6x1yWM-e^a+n{ zZ$vTc>F+7L`K;rLfnR_B7PDr|+-%cUk?vVN3;|&@DE5oa{aWvIOXgYH&FHIuYdvB9 zcUa|4931F2tp&SblEf#%3<(ACSfi}-GVfjM4+5~=XpC6tU~6ewWDSwhybgXSSl_z^NUU}Pl-V9b{ zbP7NC%scQkzbLQyId&Rdt~np9p7!m|RE<@6(IZ5$r!Fh6b@;4k+hE0Vn9OG9lO*Z@ z98b2lAMdZ<`emJlw7~$ODeOY523bp8Q}fR~b~oP6vUW{*i}+}FvesUnGR&6G8Ok}i zcN6RC4C5d7^8@`Z*A!=yapa0j`SCskDy=!;LZU9HWK`A5D3u_wrFUme({YLL(!(?zl`Ft`w9}z<&?&_H7;EiVT}>PN zVo!Hf4^ojzGf@N`f6A>p3{ba(1InOs4j@A=qY~bxH7lsowRss z%~fsg<*Qn|C{O<(rM81d&mWtEUhbl1)2=h-+i@6Ca?djmg`K|1r&UX^Oq z9RK;(ha9};7n``PRUMOBWe!QP+eH17fuE6dD(uaWdo7EzW&07L$NGZ>+e5F*rlPRC z<*(-GJA%4PMn-X3*R{)N8OU$(DF(H-}Kehl;`5VpCP+W zzDd1&!rs`PamckP_Hs(x6l_qIq)=1U51`}wOPI9VnBSjd$_T0g3H#Vp!aH>-d$!n0 z+co|ZQcnIh!at+y(G_sHEcS-GYx9Z=;bw91G$gVSj94D97B zk%tz2@-9~FLLCbhklIJxcXv|5k&$^Q4j{B5QA%9Zu+ z1P4P6>sy@;0AQ%%_>;zcP4v=wt_W!KBW^{u^zS??0?k|e2>Rw1V96O?4*ZqQW-3>Tk z5`tn_W9?V7f?X9ba^GCo*_m)#bqX#Ti_I^viK{NtRQto0!1$zzMU!I~HwnAJ2vbq3 zu7f|Frxm_S?6%@;C!LSnF#$trt1T{mrJW(U@~$xT+`{YT2kI(+MGLHhBU~2aA!^P1 z?konXvvI{`fAHJ6(zeUX+8{1Q+*k0XlK5y+eumnx?o4T6^@b-5M)5R~)-m}>vs8eg z6%()5R_`!pum9QROgj2kZ}L_+<2T9MxvaUZ#fDZ71SMx3e;N~{?z^&Np`3bsAQv+UgeXB&SVo%`tabZzvIaCIC-jy zsaK0DJiNcv*N&Re+19fc#& z`u;v%R)crdn51rgLNS-RKf>+O=^g9X2hfiqlE6ki6`0RPK{K?F0vZ)$Y<&>g`aKD-?iGSGEF49G3|cq`B-dx*7_a> z8nl?=e{mXo5m6^PK{&~|{EzGN;(yR2w;VX)8Y4T`_Az6MPH4& z<5NfJv^!o6ssEMb1ORd_GMTi>J@eJOv9{EITUU2ye)CtR_RuG8Owj`�l8GPyI#u zoAxh}K|e4Kv={w;7mNTveXgYjG(bFMXMl(Ahhlr{lMQj*MiG-T++htYs7)`pKi8}n$ zaPJ~0%i66TE;ENnP|ti9XXys}_#3Yl-qJFA&Dm8htOo*w_m=W{mB%CzK6s||H)d|G zBXuCWlTD-*vtRUV&-3z<-PSN}%S=|$G*mJ4q8Q&NgqWo?9rL-LR^ua2%!dS&q25k} zY~4FRx97v5pW5ck4r5Q#iLWPU*+hM@seHtR6RrGhBPR{$CTe0o`R*QGU2e|K zuu>G*vhGR2+g{$aV{KRtH}~gw3tEiufjYx;w=}R_(_MDi5Bv^SQ-@2!O$U%{S2*e~ zX#e(DV*dhw;nT0x1Gb{l!yQa{Ra;q7Zv!%|Fb~=9XKEt>G1;ZcWz525(5A-<^8xYI zR}$tR)j;a6$|b7GC677cPAEc2HW(06*dAv_#;|#yT7dn}V5=q`Ipu;sCCQ_}G2I>P zi_OE%P8CBeIwRTZVU^4VM<3J|nQ2BJBA8}vNBm}-u4U_?GH#~K^AwRPjV{O_$oFFL zGG*faj{nFRaM~BE>@)}@PN>tafKJ7fgQ8+c-ht-WhB+(>e{OKeBlfBU)PW*~ONp8p z2+@c`eRkT=l*neDeCq#wCWmEbWLb+FU~l)0cX$UdZVKvYLrwNV^x?FRr*GtbI^upH zQE)jFOJzVB*UE1I0y6eF%u*vk>>t*SXx~*2ei7-@>lm6a-U1P-$nJ68M>z#hpnbc})KGThokQNr-kSZ&92~ z9KgBLn6zX^D%dtI6u$0V*)kvia29DSrmrfy@p6E0+B8xRrqaiov6nU=M7&!RSHG}u z;NaPpR1riPaC-IHcBxa#1wG4~&H`}PtOR0o34&%9D22UR} zjf>SOQS?AHLZK+DN+6u&L(hDUkkSEKw;p@X_~TbVaBbWA%zR3q8wLa=sl4B62kO}V z>P3$+JEP~IVx}U&DBDG$rD?UsZ`UNb6eTxdQ+1pN*0*LNhZE>#Uudyvr{;j8?ho5b zs$ZtwIKCPHcl(&ni3%k7Iah$!{2)N%K!dUTe-O@ZF!>+f-NhI+>l<66tr7^g7^RHk zifi@k9p01;W$%1Jf>TqxxhdIm{#BD(u=X=oe4In_j3>>UJo{m0z=U*R$aPPr-s|Y< z%plvrB8+1`Bx?x!DJN|kKDuo;Wlgm}q|u4&sMpSU_~K zvs>F<1#$Yfq+T7Zj0Li#rZ2L%Pv^K{+g$XWO6ek;*Qh0jz0S{2YeQC~ zP#*d&MB0SwA*EfRgr+Gncg=S>V&oUXDz1IjTKrna0uX)jcuWa0%;Wn)DXPW(T|Hvd z(5;l0Qq?GkLlkmfGU6rXJaJ#zpfMYt=B(&kH)LT?JCroH;cUkMqy50;kVX_%0PP*} zTw@#S+o}OJb4DTyP9HYXSm6ORHMQ~kAll1QC8ke>;rSqK(Ky=`8veXJVw649@L#@v{^XWhcAsdDdztU>;0Et>?^=|JqP{c~0f>}kutRiq- zfr2bmn;hF_$~fUOjJkK;?U-oE8=RO??Ov^P1YaBwnR#P_8iEl1HQX3R&*Q3Dnl4o{ zOCe{ziOY~y;D{P3+2-s@yR5f4AWJf~QT07|_vtPwFZ{`LQLMeS1B7)>sNtCRxyNL< z>t-gJ3<+J+U-EY*5Mn+XcAz(D0EDxTZvo55z%^gXC#?V?Lzbw9$3!JQJ~f71xeef4 zKJR0!&lFK~G?n(Ca>ex677tZ)P%wn71bM?z7%drfA{o7ghA-&ufr^ZL9c+2AaI_vd z;)+c^^iBh>K>z^4YjwO^I#=c8FwW^qjo-gtpm?l0eQQ`HX94)(65n}rBAMz%JBdIZ z?j8dheJ}ydtT=RsotSYVu4IkTv9`>$G2*2YR&;;Qw`O4c15X?y=Y=yFdG0Yompfpw z>Te9lh+-eMFIxV>ld?aq!&|UP6+=o?ZW|(32Hi=)7GrYKkpz3Yr)cUeuMP$%w%qtj ztErYElWC3U`8}&O#oDcZBq(X$`=-u3n8PHZzb2606BEob`M$U>DU*RdIW3+S@b`w6 zs9d^!U6fCz&01p#SrbmMd#ZmGuG|f|ErN9x%kuZPCj;`t)Icuvxw^LCf97AR?~#i? zWR(*B=Xw?Eit6McAX7Qevo&4}ZTz^^(B^%ybPEWSyZ4BL)&krN$W+F@OAwIlr?qdF ze`F}QkD|e1F8r}X3kRS-xao?xSxOV3*8`B^@5R+FQz6Ht*VcXU0zjf-*u(voQYo8%B@ zt$439H?>6AYPPOk<)8$MHM6ITw)gv}kFez1FiyM{8TK5y=r-9&jlJSd3Wx$bOn(+7 z38C9(JLZN|LCeZ+1m>|XcJ*^f5+91g6q)~UjxcT z(UBtCM+QV?d3jTt^ybjy)X_=R4E!r5Z)~RiHM9?rJssTqcsXcvhIcHS(#B_JM)vG4 zFad1q=Lin}jRTdBm-pFweENJ(!)wA13}JN0hK{9n^Dk9c#U5X}o4;Hq7*sYOeo#4i zM+*@7blSXw{HeC4<_u$`OS>zk0PX!lPcnLs*o7Y(W!w9W3R}iITB%sdA%`qSw?Dqi ztejQLa6S4Vu}wB^FknW)`@+L;`HbbCajBleS@x~X8UE1$;lnuQ5 zAd#mqvf*RbyiaaM&QlbgGltquDL%Kf90sl1k!!EijLnv$^3XTRY?<-?3e&dS?YUn< zZa{UL;O>k8yfe>8h4LDQB$qeZpnwmIEqIfE-@^3(h~jWzvEoUJ1dGK9x`{whyr!>kN-#0 zRR*=yb?Xy?dnxV?#oZ-PptuJuu0@MG1Su4!6e;emMT=9zt+>0pyL@@?%*{-aIcJhT zd(K{a$s@y-s%xifit5#{`T%e`jA$k3q4_sL_gdQmFy<|Rl#7KAy5d3JN^jN@OHBT zn+d&A4Qq2`{5Gh@e)Hj&B*1zV+q)^-e*@D)b6{DdS4J97lsJ)xsA|qLl^56S25Xz} zH3X`;$HvmvuXprDSBFOL?w_vj-S09ngu2)7Z+vZFCuBB5;(*-&VaV5+RSjR)q}!qmmm=sG!!=g_0pr`c*L^ zxj@MMm+`n8r?yK_TbO&k?u7Y-GCkaFWw64!XSz_V<6w2wh}IY$)0K_(SXf79(AB|bniCF{*C?%k@{d3nBP00$h6N9fuP=7LO5W~! z1s$#a3d4c1y}ZUR-9$`qjnobZ3#t5@eqWQAn6JIr@YX=Fs551yO#=z8_DubYWxhy> zARK?OCuwH@MdOX;C$1((CApt=VQG3{_y_CWw{i>>;vc0<;yytr~&Xt~1q<_t1G zLt+WQXR?2H_1-mg_k0IR2tdzvRop$UKkIx9KF``lGxYF<9B-F?6*U@uMV1p^c;I(q z8F)YhthOP1tN``gue_R7x*X5s_dV&-hpgurKz~z%ZW;ekn~F0Fjsy++(#@Yt*TgZx zb*?&}^_}Prg-rwiV%L)gN-7>8OK#XjuL^{l+nBhw7jXM|tPQV=(~?X>NJmmYrW~ zXeLw4c3N&B#<|kHE*V5jlC!&dSwqMb1i;MqJL(hdks!QcGk~k=9W~7`VZ^NoV#t7w#b70ELo{}DL*xCI5y#UCLPHETga^(kw9jcoa__f*vLOb?clk)6>Vvk8YJ z`z}o?GT2U9!;vJpVgek^WWelux1FwgJpgFP}O z%}!&iBGvr_Om$>`EIx<7nnkcMFf%t(1Ww@wtNH4K<=UES^NpH$xlf4ZsRbw?!aRs^ z!mR-ddaadZS})PMuyYtJYAW=gLF@S?V##uoa>P0=VE@F?#KiA-xqr7?si9rJYQZ!N zUZTR)@7cRi{JK57RR!zEw+&=iR=4{@R7)Nl@4vk~oLGTj{`+1c0H0d}brYL-dTzSfzhHP$c6A?7z9teolYnzKS*8z|Fs5nKYp< zdf6R~VpzwbG(`~5SY&CY0MqAEZ8~xBPl<3Rs>06l6R#s02r>`c>k5My&${lRo$t5> zL&WFlY#aZgZ9cXi69PKDJLG`b-HJCUEbEIgeK56i)RA*l0|5c$bDZKF*xwdBJv=WC zz1_4%on|9>XoAsw#cN*j5Va*j@X>0~!digYugyPiU4cYg%uY%nR5~YryFoxR-*Zqi zR>)imx`%*ZUNvl{de#1T@TvzH5Khk=_+1^BJQ3mDZkmt)`XwwFl|gKAyU^QNJ}G_<%1|a*;FldL%h0-OgjqaV!*(m3Nvlj zzs9T3Z1X1s0YFetAQ%vQEv1bD5zFm7L7b)n^hoX9FDQO-MUawK{%6sUITs~=kn-$` z3Kh=0mj_lIts-hcs1C-XzMafrEeu@)bE0>5 zS92pwEkG%1WjXq2arwEOY1jmu8L6iKL(>6TLi_+ez>eHNP4gn(R|$N&P@@3)5|;e@ zwj8drw{Khu%iMw5JrmCns5XxJWqtduXtPkCIC!(^tI*n0=OKxxu5boc4{tnaahOo)M6q*iQPzRi*Yxjt{yeAvZhX&Y7{FK&;MQDxPw_{5bHS&4MqWTJz1RW)eDuD}xp+hz@y5On2s_*Vd%8#r@NCkq4bkLL z2*$am0RSzjnOMx{H~CsME8%`n4E;ebxf@HFjG*S$a@v?e%;q|Z6%!Y=b`4$#^5LGv ziK7LNzlcOBuN69gQ%vP{90BT9c?r6pYEZaV3Fq0V&o``qgPT(=eC~1TcQCP-19GUm z9u`MyTx@**DNxtHGSUua&Xt$u00P0LD?|mq>J81fLs-^-+=bISZv!`rD#I z5GMwa*W#1KmCk=Nz3(#LLd(1E?1(PPtIXN@i$h#lPj=EPKsTJhh^HrA03c{eyR8lU z0i`d!yVTUXX#Qg&NSz9`hC1OwzzA1TD7{(5og@W?Mw?>uwyBp!dH#Klf@u`MYNay= zdo!XdvOnjYxVYTVH6_m6^|&|yQ)e7*D;a-t^noxNK`NIdD{~76T=;V}*}&4~l{Dk| zvD87A&WkcSkV}2PA1q**y%{9&WQf~<3@P5cvkpXR;oe>-A&6&vdHfkj+#HZGGt}|N zB0W6qDueUDtQKd$XEDBGosQ zRZ_V3L`qjE^)a2RD!rZMo?$ow@HRyihip3dKEnpTTr=9SI^r?pe0wjX<~@l}vnN3P za+>7?Cf?l4QUkg(^*@6r2ao?LV!aADIYWb0@MEHFh5sUjIp@*glJ{bq9guKGCRR0K zm1I>I*35V2tu5U>4VW+Ft6^vN9uPW|mjocyhZ`v)M<@{) z=p^d68hKYr+M8Y3x(+-*OM;T$^Ar*}weXxX@nf$6{8W$f-A3Lm%k12xdRU{_!tCf= zy*lW8`lkJ};=`g&b0YWk(Ea;i)1@?`8}}p43&;fDZO0;nkg>mSa{o&opw6Q77s43p-FTBH>G69*3gi#Kn!x*S?HxHF#5Ep+-c`{*0K$qH zjmf5RNZKKpg3~my+#c8Ldk!EeOaEJ$;usy}jvHKKG$0_<%?Q|aygZ>8O02W~srB6$ zkVfslY*goepw+oC9IcR^3XeM)B&OGg(GNt=Yoqt%l39YXU&^!W5Qm!KP7#~_R=y+u zpdYHj53g0palf+14n^?2JlR|+5TYY5nwHofsVa@Uk$-3Gg@Tin+;Vb*3TGl4C8~9b zoBGu4TTIVe#P;Ll-)`>`m9{VuUi13gl2FeI+TaK8)RRIm)`8*l*9aOV)f%>x*l#QH zplF}4oW3EFCR%TVHcGTa;Rw0n7Yo%9FfT03A0LD&p^qU@rYZTGC1rvDSVF-xlb+Kx zBJ6#NS`-U_ALK@L5VRzM48WkF{@Q-e&j(*XLImI~D7ntBu#S9LV9=)*Az(-s**I2{#+fsk0q6iDZ=1=FZ9= zwxsA7fS6?~S=qcmWs@VxH|=<3%ivjE=M&nX>WswZ&2-9}F-9YSXX-kv+bYZ6xc#;kULb9Ob>-H7EJB#ri%Kwu41b07l`%wjd65>7`hooSO>k>J6Ul=g{9K{J97+#Q}4Z zPCt70YaSo;Io($kzrb=Do|iinXk`u9QF?U`2K&FYYP2F5$WFeT-}1_Oq|6`@Vooz~ zSsU{4)f3M_&YpximW{{(>y}uyqStHYg>Ft-s4o9TRKwJnv~HsI`&SC5-giMmzKsWq~K%SC#w%lArfe1y69f?5ljE`kCkyBh)q6wdbs4*FZ$JQ7WHo=VmB8O*FL<$wXBfrA7O`~oF0sKZ{oKB+$}WF2U%R`h##f$EBNn*DHNwE>`#tTWc4)=;mvXi8E`hwND`F3xm z5qR_rMdtFKebO2CyPQ%2J7eozkRIXyTw_%Oy4s0_rBO+fc+&lU=j!0K4l!A=G8Srs zQ8Y`w*p7`%B1@6Kev%C2Ah~{?uJ%=sbfcnc;A>(9f7%$^*Qgh)hAM`isZhbT|48LZ zf2#=m`w$70gP+$qqPi$kpOg+S)6a+Z5&qxp500+;@AV%G4<5k*+6;^?JvfI>3hwVG z5C2q$JNrq&uN7XD;4C{KIJ538oP#F<=h`X2d3e%rPM#?ITLFGY3x4(A9i`jl(Uu^dg&~^RJUaiqGG&KA!gLMY&G;rb-@cax< zs<1z17F^LbJ$##V>8}3R}(%1nF*H@uV{U+ia74cKx^`oDgKvyA#0U zBO{G-SRV2H+{gUT^`l!x%V_WYx84myvf_L;m?{hm7ytlNLt9hLpo*R1&U$u&R>Z%d zu^kUjHn8!o?=5wng2C1MkDpSk00p74K}s?`CP~V_WGjg@vIfcRO!?A?ysQ12lMQl< z`|>=2Ml0&K&3AHFmJ$Qxxke-y2>d|KDzwz zRO8LZqadWtwh&;G6P{OLY?7Z5!Vz}|=?}d(@vTdQT5t*3EM9z%6~@-ySy%#~)MXHopjQYkwP};gzGQY9G&CR{ zPHNWLTU3l6#5`XM@9y2-+zWT2duY_jWCGWl`1Op5ebZod3yP>hYY-%)CZc zjV1&2abu3*M|iM47GC#C*NwBW0Py4SOji)#*m2u@og|9kK}g!f-%w6UPkd?(Mo_so zm7!aXVf`M=xFg%cDb3eoZ<{IDp6y%q4&lp(92GeLVYRERXadi7Qmv*90beRv32OD3 zMcx&MC>|1?2y(p*CN6kp7w4bh0X`o1NRq2uz7qt1AMq|3enX;Nl;UPt%L!cGWO9J}>1K|9Uz(4{#Y(f;7;hh{Mv#I1%AH`AQm?;VJzI$&1i;6~(4Vrit89i7 zUpi?<)F28a*O2-3b-*udiiMQ8Hul0G?28&?Q&|7tOrXcO4+_8>^W^o?bYr^UCD<0= z?VH;6;GNZIrW)v8K(vch{&=0dici<@-wFqhBz~pN#X<9j!crGcL*Ga=L z1*m^qbX+!-QZJu-q1|sU8kGf5)f!Xdn|4cUu4rq~s*GfAq$^3I(u7Jut_LfM^NcAh znc5~GDfIfCKlfx8;vDT??k;qNPJD;-=WAEvE^fLd?rwOE;-d%UIe$dIaS`B;WtY5? zbX+6=0yB=vdMt^g0xmSRc^5ZErs(xtzJuU~`Qj+5X+)Q?*G|MIROgKMzfKTCB#A& zb?}0&R$P~Kx#1~&tS{!ZDTbPaSjQjZ=$w$W+)f`=Z_v;yVD&=wK*ChQ=BODE69mw# zPEuNX$b(nCc_!7TgicXIP{|K<`}aP6_vK!1m3Ie#%WbY%AY}A`xt}j30u?QRpDQKn z*>=zf1B3$#iP=-+jr*sE+WkYO!sl{{bC0F&L|qDsL_Dt!4RC8|CQIGNE-39A@kciB zd`l8_Y1aN^k8rzEB4*sVF>MNl#q|D;-?bDyTsn>fw5vYQ(kuW7xSD9Wc9n0L-VET33)9wq zypQN^Dip`Z(aJl*z@^sD*~|*l#W|c+uVn(1@HR`5IsTvIjNS31Bl=^Hg0*FxDA(NDgR_RldoZAElNOuEF z%NTxSZ9_n_abJnx`rW(`fVw#mZKClt6(aQ~mmi%*kFJgLO#nIzOa2d*+|kc!^Jcbi zIcyG+MW=-ny7RnRw70taWRwrd#>@b~V?gg#|KIavkeEjv;3 zKSp0_b||fb0-r}8tmgqpR((m=^R0gqFAmC(cyEw#%c%P%HVS6G4Rvr@h_cwv=p?N_ z94HY}2NVqSMCR|t%XuuNV86YNZL<;?oEKkcM}^RuxOL**qj#ewM7qSkc=06Kvm_UO z(CpIuHSQ)keprxam;dQ4Qo{u2X83mi5tZxofc1;u#1hZ$uY(H{3HU_3!bmxi7^fi0 zWd6>{uAY7Pr)t8o*xN4^^s_{CU-}B4)N+QHfJ-lI?cBjexUsF9IN&3!1L2&6riYb7 z;S@+LReEN1uNakZrO!2Vr1h!+wARQ}0&ixv!!j!7212}7(6{@y))4`mq|L1t8!tZ+ zDgbyjg{$S|OZ|5Be5L=P1C0S(bZ9xRPp}|YW^qm7E|gA{Jw%qH`lZ0)kBct!;lg1u#htJ-)9qLL{wO*R<}>9bR# zYl%+JL?mV&#KZ!os{N}ULh(VboA#OoieOociwoo!KizT~r~!TU0Bna2*rxfMwNzHmSl>aa z16@NEQa!)Ry*tWZ*pi&WXh6*tH%02Iwtzg^CwPlf&+E_nf4PLGK+x+Oqwh-N1mJmyMkpa;{G1ql;E?sHaQk z2a3`l9bRpF)A>IM5cI#$6Eu6g#EnoGu7r00%n1PDfv7R}9y?^2Rki3obU$evOf$H}5eHuM^yWTmq&{1cdI+6vqG$A^_-) zl214J^&SW-GdS0WOWD~X&A+}}e2)0#yzr(^*(^G@*IK^i?>$sJj~bu$GG)9)-=2i~ zD&XJ-9!p@?U#!K24?na^3i(PjWh?yDU)anj4|~!aL)x6tc6=dbDX?K{;!?{`KbHM#!AJKOmwLN^mIOC|Ow>X;3S%QVLagIBV;X}y%=3X+~Urcf& z77Vdj1OeVnsI~0OL|9xR9dc_0!4C74c>LP``H7(dt2|gi1Bh1-*zHaGK=! zD&fnT-JC6mkFz)B&>0EH^)@`M>0FV(qZC0%(2((!_HfSmJVvH0RHzyAixAUbjok1| z&K_4fl~jiyzH*C)W7VZu1i<|=di@R67WmjQ5+n%+kB`)M)>!ch6_37HdEDJyd<%YP zuQ`D$p1bsrUoX>Ltewp~{Q_xAAK4IM2YtD=lKk|y7DNi1L*cMfOhCTk6bardNLnQ^ z4R+g7vvrQDfGpdmMM!=nO;j&boOFAo-qAa0^IYvm73I{(XkizopYX-9OOxR|y|m`) z!7_?-gGgbumv#;x{I|K5Hu`(&iV6aZy}{p<+OfAT!``8ahyuQ|DFV>uWSJy=+=LCw zrc~kE93oL^T#c}ZMBm-|gaLds2ES(oJ};oDUytvR*hH3Js}sb*tg2U38qK3+3(cn$&b^xqbA~ zC#jsYR_m!`+O%bxejmdO-h2%f*= zC>i}8GR#g=YpEcQ2YrERSMav59Y34Bp1hfMHIUbsF?#D!3tzIcm)jbaU`PEv#>7{t zKn(B-M`6|sB|H?#P0;nn$dO@1bA}<2!I4wVxGu#3HER;;@jaEoHHfm}=sW!u4)pF^ zqor&~)dk-8sC(Rci!@5VN!HyW3BWR_yZ|9pMD8r0C6%&DI2+N@77ktbM2GA2aUj!} z=uc^7QD-F#f4#@z(_gEEAP+d$&eR2W}47Z#IV8^TQ0`BR~ZX+e&?fb*#Bf}3t z?yr6T_|7vE`2}z_8k~o5qX?`Xkf!odhID8f-&aDKW5$1FS;*K;0V`;xG#4W-2{okJw#Yt^>Xw>u_cGF)kWCTb}(9 zyk_mqPHgg}MFc?58Lr%VWbBH53alTwJIjGk0p$>DVlh(j2y9r<4B8PKg_-pIK9jP5 zN-b2FH4nyOUP?VtVIK7yJ?E1~)MODM?P=s$mNc7)y8t>=53hHkq5;q`-Cph( zrMy5;<`@vBuD#nF1|R~u2c-5oef_mClw72@PmrT0%{4jGxX|Xi)T>rZ ze|Q=gm_cEoq)1fw`(0!IFo#D>KcjE97<)eyb~CetNj!G=atj7-&*8&mmm_S`xH3#& zs|rD`WJXyFb#lbM^e4QRPJlW~n3&&g&Asn3)A`R?B<;+I#(zzl?Y6bgd6FIy9pSUjK#S7gwq zT3KcR7*?(_=R=R_@f^vo%$cHEDxzO_AB`o6I1TU_ z#vX)zknxRxq}5@8{dv26HHHQ_aG>!iXI8;YH{z==_0~kSXBtCOY=J746)s2fOK4Bk2HIGH8`>c?_$Y$9uZiENVCF3wW_Ko+W#Lbbs4E^+8U zkqa0Fa}n{tRGyu;*F_tHk(L+pj-P-y@cne1W?kv*->lvX8r`EH0R(E;0BPN&qn51J6BByW2BX%zjMj_a-$DRLB<`%yS8^xAjo%^NLJjl{Ib^RZl$7&B7dDRmQSlW4T{!R!+w0ary8)_Q zna_iBt<(dFzTZdU15xrONctYeQrbHKOUpFm%^y)QggOg?=12`w?;b9%Z#I?}Ko-2d z=Os2}*qcA4%~qbt)pjK29wvKkp#y(?&Fwz!+L%iYgP7%eT2fli*mqkz0C{B5qZcNd zm>f<@NJXKZyg#vcfcL>lYFAe3G?@pkAMW7B$&TbR2&$m}NQKwa^L6dJj;j5rsU?XK zAq|M#0)qOk=d*FLQwR-1QD~Lub1*g9LZW5b%~FpvvBk$0E3taC?C4JxfkD_!$O~}k zR-`Ct)C0ITN>>!tAgD9LNE4n*KM(VodbJe_Gv>sw1m4N$Qlc%t0|kPB&LdKC$pg5q zml$G;U!?WVpF-OCii)Uk`}YKa9=5m8GVQ-uXdZsQ{m_cN*v<3TBb-dGkpMQ$5uA<) z$Ta!D=(8{z(Eav9g64Gm64-=UN*(GBm0|SCKfP<~^2qOd73P^yAby%Y1TsB5Br;JG z1R#Wasa;}w-*W%aCe&Zd1iK+yWIhCOK3@6yQ2325T=+cYjgp0$ zj{X~Y4P%ttuwQ2e@-++&4sTM4E}z<|s+KeH|9cQSKOMquH|H*3^GA9+35=&(EmjPj zqO5sX9||R3uI1i_T+Q8hIR_$}F5h?s#ABPr+jk*QU+AEGP6;UG&EHUujDr_?kDp zx`wir%||7v9KMyC?DN-H20`?|tl!t}fen$iMxvVb!kcPUrK8acPv@I`#M$ZM3p97d z6UbgY(WmEq>j~L@`)k+cMh zzyJ*ZbM?d*-V1d>l=gR_DR%1kvTU)RL5ZQkmT=YmFNk1w2}Qz>LIvv@A)=%n-Z1Qs z|EWCYm_1@w?P=N-g9R(TN;?w(ZQpJO#{<<7)c{5T9&qXEf{riX5#FZ7Rt-OXZD24L zbu7-TY8|I^H!&5FYtp9Jcg6WqAJ))7?0;@vdv?Zml`iv8=Bkr(T|1|9kcivOzAfuKA`uEOxEqBCDb4 z-fmkQjzy!}D9t6Ar*}vI@rGWA@L>C+@O)1nc1&TswQlT2mr(;ba^6*;cos%pgf6wf z4!dR|otA_=v8~laS@Z)^j(17+`FFAR_7zTNL;QNFG1-eYhH)j6cvA zSTubCfRt{8j2sh5f!5U*{7})EFz?|Jrpzo2g`)ZQg@H)FttAw@7LU9dQ*SnuYnxk^opPkNt0U zm%HpAseaL_;)3HUB_<|`cdEj#j9h#1R~G2IjW+>c^#rG4w}=U2HXX6k;-g@GK5e)Z zB;4NSUg;TgQ1Ic`;&D;u6&IZ|N@QwFH75v`Akmfa(=TLwYioOa{M{)CV7{fC#Hoaz zD2k~ojDkmOB}N?5C@j0>QMM<5d*g+4U2+TgtFX|<_t!)#Cbt*DJ>=V^3xR52dVVfoYn=T7*H+hy>C564|+$6sQh{lYmyd0hE zJr|lko{z4m%8~&^{UiPZ(I>>5dF;6_Ze{qlF}U8I4iHKo0T2#Sp9$v=&VaP3?u{=A zO2&sz0#e$p>YVxc=QOmbL@KoKD2NqJu@dyj;2R3v-fy*^BV`IRDXFD)X?A*a zF$%!D2S$oGbD){8J4r2nRh`(8D*983?^|?dx46M3pqz*2=-*(N@WWaOB4pzZx!XPT zeNXN&<)O9~T;AmZV#+eNKl{;fRyuA`FKFNg>0YnjAc-UcgYpZL(df-0X=zx;_H25A zXc1kkTnVAXWL8VmCt`bSklD)p z;~5oTup9JWD@I)fX0=2!NgV1+!eH+3sDOZ>728TBpM%j4#xxU0th&x`h zlhjdDm;bV5$(Po>qZM(li(Qd5f)ibsFcR&e^lcuVuR5KZ#ZM?Ra#q@xByw_4da^?U za<1-AB`0tN>m`XF7GHjSyKfS(8MF;H;I*H6c_H1n%utjsQyBp}p={h75CcB4O~7m0 zK|x~hc?vk^xlIZU7;Fv;yY=;bay8Ae79FluqIlaTJwD@d5qNRUsnTl&`T1|24jcP- z+GEpp!zwyCI+)0gU8SWu2jSUHm`798!OKg8 zE&nkUrWjricGVRn3Z^MpD58+u-0HFs*iM-I6(RKkPG5>+upT|Qi31bvM+|Sx^ge|Y zo$^hZ_covqx_`CtGB-vXd4>xrsjbcfur_3fzHbaA%?GP3cqCk;{+Jv^*2v0Wd=O(N zkje@7FXR|7#6>4zXbYTsAE4rkT!fLWY-f3PeJ6VgWmeXfEn?~~cdc`?EpxZ}bFhi7 zG+2x{ij#fxc}`khcM}@jQU~_=R`w~Z45WrJA@FTGo8jsD`7dqI?X$^Gr&D}C|UJ=ZZ4$!d_rU~j!NGjrie11nRHNQEZQjy zkBM2D@vB@Sji;IVX@-ZHDMHbzActB$JU&5)53WYsIU_ z9W`%BR}8ozBtYqVm5Z3OiY|s>Ubd8M%U>tKU{coW6?A9bZ^0PTNso(okoE9(wU6Af z&*S#H(s41K&RdSWvs}dB4-@(=;vWdSR}MKQUYAUH+U@(ixbvbr_5Jix)89lm3!|4L zvVuh28e0h;ZM9DamF_d3KrFqYclR<%_Xkbvg3v{Q+!?XD2=uB{ZY)H;?p>91N&JyV z01F6}2Z*~e%3ZQo#4>oKSSKzn{JpCzCeOIT(_rYfQSw>B&5lMVPH<5d&Fgm2JynLW z!W=F7Z|$Q{M)aXmpX*2Qf^*q2=G@W*FPnc5YqZeszfOinx1_B~TrVHZ0SEfL8TDpm zLDzr0t@DNDxGd{k25VD>%C3^>45t=mbel#GsE2q2K}+Ryd0)AwzE1m_(LK^STrjtq z$DL*#x6L?zSQyd$piRIsIgPOF>sT!C5m788--Z*qbv6HpR}Sf!_!tpfb7B$|f$g9N zhtCrLE!BN|Yz$FfzEy^i!mE&-P)Mlbz~^oHPL7yLdO;lDnG!~+`ajx@BR2O!ey85B zm@a0+kbkk5J>l(~z`WMK)C&P!{lGKu2KpLpvCLqduTS#b%Sp%eZj>A5lA~Y4%hBJt z^^sUU*TIC6`5{JDGm+y21i&BSco4rO{h_|8v zUsqU78WJAv&uen995hJoB{?1LHrAHae6u{K(Udn4kkkgj_1F9{&$>fwAncy!?6-&% z+4#I_t55!IIPbcP^{K$wD+t@jJq{$3f4=ErVL=fDen4`+n^jp<%b@Xcn!i_mdGOSh z(p$Kn$@ZL|%5vHcsDa?_3C}^zhI!uPL3&c(^KiCzFt65+=H{~I``$NV=YOBliRx(L z>&=#;j4gx8KmJQe@!9R@LJ)c`jgC#or{GdF~=YAjg3B{hX#2$)8i{_^hRFdGVU!Pn6-Wq2pNdMe@9NCbydVv zQa|Qx_$JP-+y+6jf87SEsA$TF)atsUEw~qMMbS$eYQahnbG+pZH;gxO?oqbhL#~z&#jvA?PR$5$roZ=7G#%gdQ=4qU8^{Z=O~!fgx?*TOp_eG@(37)LKgO!o)N zD^{J;PGl8Azn#bdfu-M8Pp)QWt6!)}(BTwcqsU~GsVFrXD}DphLA<~3iU0LRnJpt9 zw>iLsRS|us-{E6G#iXIi|26B|9lU)uOZHJF(vOjKO6D6LvZ9H26kdlexk>+Yj(f*l z7>dBml3H#q5ya{>UO`ze@_22*srp_m`pj2P`DyBPP|_7$qiSCByoUF-oFB)hZEURL z%N;$f_`ufsQbgjhKJ1ps`Hza9Jxtt`J? zG(S*YarI=ny&QZ5(B>wR>6?)QTdt(yS%pe+VTG5|JsWL~mhf~Lwpl~_&hV+ccEV4t z16tD8))~0VcH;)E5qI2A`8e}MV|1@Xlc0P!Ra=ut3JGubJA421%87jWZByqw)0r9c zsG!%cP>mo-A?NDOyl$oWYhbO3%;#OhKsI)AYZ_c!pyvaISuv4k=n%s8O=!)$Vp8ikRXLKW+>f$ZW<4318Y5%omT z(|rMjdwz1_2h=Djxq3#5)Zh6u4}eO&ErC+WMW^4ntPGK3KL5s5;H5{`*WhXUtxFt~ zhp{wz_eH?H`Y@lc{CEY~?Q|w1)ZW{nt1^Il2-cPOp=bC2qm8?l#9K>J=kdpkRtQV+ zk;ybVYO99S8S6Nwd)k8#q|bzq2lr2rCc##hc8B|`<1C&kCw^QhT+EYNclg%Q>{Y-Uxs z0CMQTXR*k}VRnwml4LZrtE3lr0RD}*pr zx_xbK=3}QL6Y{V2;j|x1v`jbUEvu5r@yYJ8XmE+nNJj0PN@mkYtHJ_7ABacqj9sH; zY&CjMPW?EmtCuc#{CljVkMAHY_37{2eX*~GC?Z&3Er4UYtBXH&&sub-c+$G6>2-6- zn{97m=i%q&Vaw5ATU_X+V5nB}!CjInK}TS~Ut-v*sY>r>By7y^Gpo*JmZpcfoW0$e znaV~e&nJk2kIk};;h&NRBiVQJZ0Fi#wptv2yxhvU zo+`ps!zet^wnIdGMt)UJ8Zb$swB-t9cVwnSJ}h+rAMY|>n8jQOztvOF%;ffrm%U@- zO*MpDOo;fyfn@wLZgu_hzNd2eRJW~*y2Itq!-L*8T!*nd=b_`QBpz5ied!abmbt(X z?avA9jv12a4(`wUMB3HWA%~TL0*515I5TL{UkpA}tPjf;OLAIS%_GK=`*vdxYjXE@ zBXd!g#ctEj47678q3*pimSpb>-^Y$tz7;#3wRmqFbR8%(ggEWI;)$K~x7@~Y>ECR1 zAO&B$G5tXYKJ40~BbhZwE5(@PJCexjL&4~cO#$Cy`uqkT=AL(Ef8;!0QXq9d@q$=S zD|irO>_;9`xCi{GShYCbBUXmezmD<p4*6G5$js-8UuKuhdNXD?)_hyIZHcuTPHEYmySqcN;#OROwYUe0LxJK_+zD1%N{bbDDDD&~ZY}Qa?(PnG^L%H1 z^X8vqH#@_y+1+!_eP5sJN*%4d3C?KEp1yK?ZNALUS!kzWFnU?ZeKhG4^7dlGSu3p}VRD>c94s^cc;{7-LT1M89isOuyQ}NWz zii}7Lz84&Q7T(b3Jql7;+b@BW*dZvq5(Id|iP9NaTlhjkgz?vvk4&g z8HFv6Pdrt<(3fvH<-{e=^8C8Ffi?{)@GXt zkt1?(gyhd3{cZ)8HeM#|pBYciNJT`n-e?h+!UKpV;3GA@p-MCBH%2@tCwcaxeN2vg zP$j4fjS)aI?G69pkR_q85#g)0#!$P2l}+@!ez(HOVc+ER^+?L;S|v`#OKF()ycP(a zE^*xSE>%93aIZkd>%YLfso3+mgAv>c%K5u3yj&^e}d=Fe5jPr82b-64^4&*lTbVO0B9fvH~(?HxdDZfU-4x*%ChE=3MgtU~mQ+~;i7OCJ{Ro*?!QPz@= zFN%megjp~KFf)}OX)@YI#1HBidlzT8@}oj_J8=z(x1=PDJ{*zf78~4=XgTGY)mLbD z6qbLx{^y;nX3eV=*g=r_fw5b#pzN+2nuFNtEgmZxAueQCfGR!c+iJ>D3$2%4?m`Aa z5ds}sL@Tnn%U*XQtaodKK2#NPnp9Izr0#ln3BYh?wP4Cjp3BUrbglZ-sy`G=!RkAgBKBA)jj7ME^*bsm1H12~{sJLM=b-yS4;nw^b2WY7{_R2XRvf21kE105C6}KjFB-2@81ZTIwwVPwzcmt6WHTG_7*-zoPPFI!LL3c_=D6 z!`QJl?Bk`*PIuWqhRbJs;0sk|C5(I=;ifsucrj zY4ndFPG|1ARwQC+uXVXt_E2e8BM-cvlKw(KSx?D{|Bi>@b zXdB@Rs;gcIi4ss$k#2&NV~Jct8YA+q&3L{P_U7{8({L^WD?(pK%9jDFyzGxwkLOR2 zPi9y|cl!9nzsEeb#{d8;Ujvy$If{L+Y<_e=aBQd<$ZH@jWfA1NmS6N0f zh+dRly={dCkYo9^`P1-!-+#H!K^ujvAFB8?^nC8fSrq9X@B5Ndv)U{ZTR$!yRPtby ziXXhJ#%l(zw@@lav?0ZT$+A@&R|$nZ#`#Sfp5G@jnH!E+9MN0-%^~Q|Ig|gO#6I)h zj1sEs9dc`TU8%!Xg7EcrK&+%FuG0%xVKZ)VMr~fpJLCA%dXmqQ^o`D0a>aV&c6N8> z66KY2MT2uH3Vi;^1vH}2mfJcUEU^Vg@Rhs%cSRB~2jjt7tuJ#HZs?Kb1#yn8@Lfl? zQt5lIEv~@K5gQ*Xhns1|Mw@7nu;rSMJ7)9&c_O)OEy$KIgm}MjrA0L8(R-fIQS}>s zW|cVc?SVC}c!g=oTrBB5`3%J!ZvY!GX3c6eATcE2JDtu2{q@>RJR-QY@N(keVePPz ze`b2sBkIoRC-(Pr{z*!^ED^U+shcH`$U~WZJ*g`NbeJTMypP(%AbU*#Gg1XDlCvY` zgv*ZnD`9bpb0M4#ms8(0^-T`l{bf5_*0rvm?RHld`Tx;>BmbZNLxUH@!o9`U z-@^$%X*jV5ffIWQFe5m>rwPx}(}qdHw`5>C@NX61-~LAjD#3Zbw{R*@7M{~51yAD> zg&!vg-xh)ImxXVO!?@u46=Cc!PIyWmw}~HINa5QFf10E$AI%s1s_olYvsfN{dXJDb z8W<2EB7i9w#QDYg0o=~8<_nwDHZf;>vtkevqf-udi!fO`sFvho#1x9HkC? zg^|nE)4!#PCq;1)@yuF>dBg&bla_1c>(5dIuD>EU!uON~7j%7?0|!vLOi($2vjVFN zMSJV!%iPK@6QSgljV&YVntB0}g{^EZww<4? zrj5BvUu?rE-H#R6DZ^d)4O{R19}c6>2N~_;SO`d*Lq(@UQg5x8!Y; zc8Q8^J+9e zX;}bC+QT`QVchT6{roa1dJbN0c*qa^zs1gqM!Ed8LG1vbj@p^NFI|gb-JXYQC%%G# zq=?0Z+o04%LDz~bjdcFddn7@_Z#( zbKsS<5!4g_CZS(DqL6ILq}xCK&GjBFz$Fm3CqpTrfMTmD;7L24{BBrp2rN$Fvt|@& zayviOZ&NEw$xUVNw5Lr4%$8ngPJbSKVL=KxWrJE>)k6__bfNx7Gw$V$qyw5km#RzO z-9S2EXU+d+GFkiO4 z5OTh7Hsz#~C4C3xrMBQICA{foi_ZvHapRbDx_R7{aq>^$K+zQMSkxbY(fk$14HG>f zIl#MRtM$?|9vK(ntrli?Souo}QX4}gxb_Eps$whtna2U(q`y#m*2*u@ifd6i;pBmn z;qbW94DA%`8|cZ|FT#cirW-TrWO4T9OMb+Qc!slmnD4nGK)uqt+mS#Coj?M+2mi)a z&guCYiq1!9`31dHsS8C2Eev_Lz^Y-s)+WIKh2&C*F`&=9BF#cYPDRhCSDo*m(H|Kl zJ&+<_C_x!FJHm7OL*o~G87Ke*=lr7!8xVPPO3bl5EJP&p_ezS zn;)L<0)E+H`r7{PMBwfdYRWzMP{I=I=Demxrc=#>#?gzhoi)aV4FENyhkj4)5KY>A zt>UQ<^JW01XqoLgBOaV&p^QJs|vU((s}vVi)?OFy}4_*sil-evxo{$Fc^WSfZOe&7sEvX(TjwI;~;O=i2~%D6ZI z9ta;|FCp0+6vGEgv_^vn1Py!V2xCQHS0?)IBIJk9J=orX-l~ zSr-hCjOAR*uv_^mFH`4TY(5S?FWwoE_7m7}2G*8$eE9JaecLQN(oMZxtVaMKWCxNm zkRkT?hV%NY+^kiQXqj?BiWQ0@eWP1SA7Ih2*E+0S#kJzzHVW-K*QM>&`3F@d-~5P0 zb{lmjbuZ{owMvfe(SkE@-|6nut((vN_BcJGtO}|G-k<$*)ob~H-XVhrNd4CYx6g3L z*nz@1Euqp`w!&XiNAxr+Uy|7MX2CnFKR|#f?EX|eFBlk&@WP?Zg2(o5JQL7ypP6-+ zY3vqd$JHCbr$*9>c)@e9cy38gzXRp68WHgp$zSOLtcp{Gzqt#0V6pxVbcCmZ?@8o~ z*nSSAx-Th~LZS16Ia^m2us;oYl1!9h-2sb;x;i=_4G~1mpkUTNC;PpG8gSoZU{WZ* ztTfdme#i*`ei)LNJ^%*IWz$aKkK8wU3qySpO=dpUC!r&?{6Mkdk_CeVZDc@ zgE~HZuiqIKmo2!i905VICTu*@e*XkNtF(T^UNcej)hoIcPaycvf5wA85geEp(wR-a zqZ=FaY zbLGTam>?Pa*(qsH?Ezn?T3uK|UHyy)fBL^iy5F%#i}u+?fb(u^yPNwsz|PU@zFFY@ z!pAx4J<+a02px~OfLYOx_juCX#uhw!mtdw7#ycB!S}|a(H*jR|OCcEW4m1jllYnA_ z1C^)F+p_P?R_m{P4}3sGcGEq`?;a;TzoLlvCMSz2s|!iRDuxk_{Ho31*ySt|!1;s% z&=p%1*nUoB!W;`=ih;UqTwLGRCs#R-*l(ZsH80SblM1_4s8Na%e*9SEZ3N71b@z77 zyvD~ul+Q%LF6Ug!(Sc18Sq33R-Lt?u8?_H1AS4-F`b52jQC9uZZ*w$4BPfrAiU^We z{_mi?0Qk|z^l$T6SfBA*qh~$(1U8*&i^(a$hxfWRuLb+kYd6k5VZ7Lkaarc4Et@I{ zS)*qY6m7L{S-%d(m@$RpNQqHQW#G2sSqj2nj{n9Y18R?cGv)#(OWKo>zXmKq%vRV- z{w+q01C$qOh1f_T&ai*gh;C==i*L&30A>U)c!rm=cj)_^9)0ajnV6iMPCGP89l9z! ziJ+Tk1I(qC^#AXYDRs5yR387R4h`@UA{yr)Jqb^v-(&wE1R4*`xY(+Mg|9 ze3(pi{D^)Z;(v)Hl_^1AMzZ$sEQ>BK6(n8<7{NVnm-|s-NcT`Jv^U44!}sYvK)TH8 z&?&_cknFOa0zO~PFpAjE*{HnuPwQXC3H<#F{^e-uU0+N&BZJ1TeDm|FUX_16=L|GT zpf}ihbPhLjNp^q60ou|Lf-Sv>dQTO(T6yEO#2ix5LP8LV7<`vd{l@yQ%G@P*+(%T^ zu8{$t*)FT@Qzq&`RFG+9(Q_m0`iBM9$!0IR5?jNPXd|dyG$^3u*hTlUezZ^3)`L{F z6l7-U-7Y}Gn?4I?CxD=hfOYMuQH0mIk$3Z3A!D$}J~~7*W2n{UTpTG6-AqVo`R$tV zFC^Bj$sBD7viE5Rs0e^aVsO{kF#X}Lx)8=Tp8Dwi1?Xt4su}H=g5=5J^|kEWwL=WS z0Qc*waW1`i)4JmzAke^(VdTOcZV3B1ZO;CiTNUQQj($qY^s7Vm!^-dA|ay3!*8mL*~# zM|McY8K%aJK=P)~_(%W>m^LwLpGQ^2hMzU~(@AjSbX8VfD_ z4L(v$h2mL2as9b_(%MDHwypCm(bJ+Uov1|=er5Ich$dT?EDj*$zZ<&eRCZ_ubI?u| z`&AP7mZ_vD$nSkixD_H?LaD^r)w_TSw~@2@XjlI2w3F*>i=6)JyNWj%kI+*ZT3-jS z`&iVa7?6y15uy(G1Y-t#-7r?_aG}xeu7Jyj@Q^aQKD6TQ>I`n`sAY;d`vzFN0SlBW zEk!KFe|46s<k)O&A< zvzM)sYUDZ^u9DNyZQ6r~-dgs%C##W#IYkvw5upf~qIuIpqVSUmE$&!t7@m3n86uK` zudFB9T@L<_(nFvxFbs?kIw~`C`S7H2v00x(EcA}js#Wa+d)U)!0yA^KNWM)+Yx`QS z1mTRG9uskDX{WqX6mX28W!j$&snDRR#F0=%vH1xfX&j50K2`necH5P6^i;IaYRi5( z%h|Vj`GZg~8w!mWb$anaZM?cTceI0uy!c zziPoF*%Mv7U!e~kjvhNih7!XiWY;E;Y^|UzJpnH1B@wEm2pgQUvZJ|?3h0Ygfs5vn zJ|x6fO=;?!pKC=M)X$tmWvIjaCif)W*sZ#QEfm0{YqLo?_ynKwP^*3`_)kY(<)-at zJVAC8(&Te9H1Nc}Cf4?RDOMUPIJEk*iTa2EWtRdrPjK+cLw}tXWrRiK5rna^gdnXg zjx(Z>2~nxJ|B*}i!Gr&S<)__QK=0B2sv=p_jfOW1ec~Gl$tjY3y84BFb;xg zrF$h2X=*?q{nuGFZ6;!$q=f1%9nCabu?_bRiqhB|b=hV;j;Zv>v$OjT-my1g?i?N+ zXH^G2zVyg5=X1;~HDCV31oXW{{{+vi1qChtkXkYa0VvtM2w?J;M{hp@i^V!+2}kGS z$F~h!)$lN5v<_drx4>R9Ay`I6{T~Vd#RP&&eMBfU>b?wAHs}#68uV`$X5FiYW5j(a z)4xyW27oST=4;!;&b~bm9y8TQou0(N^p)1_0)NGfL&+bT3STJ;k1ApW#%Qyb+I@UM zC|-S-NemPHem)Y7p<@M7Yc{R8)D~OgOrtva@CUcMvp`*|z(gn<4L&~2ixPo~7~mOa zzj_cg%T1(Xg20_7xI)mJ0(S(W=doIg!i*9_0(=0oLyANRJb)P~CN{~lAE4kd(K0*S z8r=%osJ}uCC+P$1g+jY(7%CIX7)q{ny4Et+w{(>U)3vUMx;d0lllh=g4oOL`j^_R( zjIeRR3qwUz=P&iC0o=x|g63AhP{ThX@r-kx&yBY_-y(XYUd{t%P<-EV7>}m&$xhxb zAFqvb2cJ-7QyNfIK}*%0aicA$dZV+N(9|76#q=o2p=s*T_)zQ+R{WAM*ZcW`lJw(* zZ3D5&Q#xJyzWCSi?HQwM@RmyHB+ZZ~f+GK_clUhs6GG06?*E>y4% zEN+4WkpaH4f`-a9b|^#4az8PX_ZbjFozeH1#S-^VJX)mx^#gugeHAtwd|1A_N?Fm8 zVeo6Y^QS`6Ajap#FP4nXPBo=7@8Wi`S z{WxM07E9n+W|ropQLh$`c0%)+XpR6diK)Cf5R``Ja&Z=n@cAWkMC?{1e_c8p@7?PD z5b4~;&OOUZcHUfyh`vb+Kig&uUz+(rP+&(EG$GY;P%m!u3D-@@DQFRq>y!@4W$E=1#kAo>H zeq-qR8sJgQP1-++L{N<0ATo<;+|GeTyU_sCaoXx6N`LOo2PIICtUed>A*W=2Qa3HA zi>e_pc?Lbql>I#aJzZTVhAlsxWiqWyUWzmS@fv+RmOk}+j057#E=Qf*2TW4LJnee@ z*`z|QI9$cQ%}wHS7C2ph>7tzkM~IctMqZV>$TpBQb)!tF{xLb2)1vqh69%tbtVDA9 zVqKUW;EwKhIMnruB%^PvH#Vktjs15irk+YZdID!I2_2rGhd1aCqaWx=?FWxfZ;?6D&3qPwt3_Yi)N$ z4U0S=zKc7l1nbu>e(ag0{%Fk=1*36f?nvHL*`oRY09b&(oxe@02griM{8M`3T7sSo}WGgP!`D;`m7cXd)&>n zohmFS5#75$=i3fmTYgbm4`gCwP><+X+SyE1c1da>(yb16b?Kq#vbMUCN&7|n;-ebK zY|v8dPoaV1h;k+P1o*CId0LcH+BeL-3Ib}s+`Np8cWjJXJ-r$6f7E6^Y8vLf5vP?! zkYG02oYp7yJbd%P7QndcK?O4P84-}%bK!jrvrEw#h2RUX;#IaRk7yF}b3CI;BpI6a z7^=IE;%jvS?Y}f2;llk)Wl~?mvugjXc$zmIDp=p1ti;O7Excz920t5`Tv?#!aFl&# zcxsIcwyauN^ijwX{4Wp0<7+LcBHS>++Ns(tJ(LsADRVi29q~cxtrBo41pvoVPc-dY z01rM@8#l<68V6|;K^Xjium?G&`pUO$#9+rv%Ai3?He-sm{u=l)lk#{>dv! z!m=X^+eD_v4uB4zcK2_!0l-={?rfZdw>dZ9-mMli*Ts=10szH&3)skVI@cHBs*u=) zjF-YZxp#u63gxBkFS#Q>1vt|T*|(^Hl8%@wehu_%lL1fTBwTQ?`O;`~dtyy6(fAOo zeI@-AH8qE_?Fly80iL;q_{^?fx|>SF&4mDPV09jXndfaVz0e=uf7qiO99Uu2VY~oJ zOc1e};##{-e4LIMnesTzOSzDRe}9)0YOrID>LI<#0vRQ!0m*j-550>Qi^C3nwNuvC6^H2*Lo z`j2KP#QSoo=Bp3l-OcO|+Tc&HuNqc`FOFrGw)cp{V#=05cI!?K9lY!-WJX zm4;$gKd$aC$44HfCYH}@-B-?0EAby;PJ!OImIxh!nFcwBz8PfZ$T6%|&F8FJwaX@OwjnlYjZ{&{k{@RU^QLZcs)de~gc`^lztO8iPW z60b(?M4sD$_n&z{^xLO`VNsHUKrGY(+=-PQqp*#b&jZW*Z_dcQmJf;l?9S@Km2YW| zfl3>E%tDpnLe?Luw^sqSS4IF|{C?JAZxYIZZN2sKvWFP8EJ5 ztReKsovmOR0H8W`Gabr)GT6Gb&kKC^Masrq_G$i2LrW6h1oL}5b(qu}(_0Njs)8|OM%YVU2Df+ZoumgU%y(EI4cmeoy(60OGX6TN2lR(0n8z9Hu32U zQ0-dtd*YoG4B$KsWK;Sb-dPGKcTLTS(!vh^S7>GW2!2WWAudM@{KS%IyeX8l{JTp`ozim1$0}0Smi2q~ z1irx6;0SMNE{tOr#0H=jDb5lI3MtX6v`_v|^X=Fg6vnqhDY5U0Z0DRGt@+6>9^_MI z+;4yl zmbC#JH}4WX))O+wF?;`wBn*5u5FCf*(fi)lMrx^Wg}O2$Sm6&6()>i%fnrV$_;V|Z zq=^L{G(5Ps5?+qYFt+9M;ko)At;f7gy!b@rF6}7pr@L*ZhLrGuj$o}BcD?{Q17@CS zo1)B-b`eh~v5>zByJ z)Cx4hSF;CCPM-Ym89n4FM`Pi!=WC%Gu;!NenXj`o=qe&8?NpT+*`~R$*n`W`_q4J4 z{i)PB_k0RtOF~Lk|JeFSu1XF9G1=vAw?#(x79h)kh=Tq;=v{EggMEe$CB8rU3h#K8 zu z*Z|c#n?WUOSf+{oXaLY=$63>x8c{BJe@3EIru$8w!SR*bWi{uNxN=9zn=^gW7Y)>% z9q+)s;IDKA(ZIN9OU6Ftn-#-VI`X&y12{oUfYbw*RtH^T?%3AokEegW-ON%|CCqD7 z=s)S8c4`W_4WVhzVb&uoOm7;~UE!5T_fJYR;~yp~Be^HL^HeDy(h#st z46)pG3Z``6rC=IqaXKlb_X8!g5V3|$z(=ux1tDKXBWSWMGAI|zx@%9JEBbp&!vq_ZWOwK zsfVY7A903JqQyc*7C-wVI<&v@o#w`_( z?LmY}DTPSH78$=E{(%2qviFDR?c6;f+C#M=lfoLL$&R(gq*9~T^f=tK^eEDIH(AaB zNJE`Aum^dBvk(FRkaI>zeZG$t;vfZUYz{9H>u41~w%I_G@G5?IWAS~4xqX9F>4xFy z7ebB~2pKz7`6Si51&l2%!LTyITM=vo8rA{J#+NC0S8)u9E(ft?-Do=?7y*b{oOpB} z@j7jUxlu-i9aei)D?^NQ zm*@BXA33X}otIx8-4M-2+#~khnC-6OFvy&0rc2c$>S*x^2#@PWX^e2Dh+j;HhcAe;Whf7l$7;=i0n7=)1gDwgck~xq1w@iCKvCxGkf}~`3dcVOM6mV_ z@GK@UP+L3_{Uh6udzNuThje?p`CLy*c#ixZ=1|;o*InfxS(_A`T=(M>`bS>(_~=t& zJD;AAQve2kY6FDQGxb1jk{p<@oxD+S5ZML6u7wj>X5v53jv_Gl2M$V5*7abW0XHAY z1dr0h&``p-vtI??yQ4HD;H@7nKv%e)ZlWM<9!+v_bhoh>ev1rE|9!i>XWF;_N3cCU_|83Ed?gFNgXwa0zm#paz2gjFQ8YE_t<} z&FNDXAbQLzp9TE7HOXk;@%th9_>i5!LE(%jVfSFPvqgbYyVm0-7x4bu`jcQ;gJUuR zJQYs-ujbwGhhg0CzrFT9A6y|bF`YFQ794;jIgb?jDV|Xr2}L43l_J6NiqOy~reVg) z59dPON-vF1*kRct|7bQIDhu&**M5;5cAPnfk0t;scAQR8#Hgwb_jB%(29B;cxtd%3 zLj0w!#7uvlQmeBO+wN~%ctLbrFGl_F1@P7}0yHomar5$`b7u)E6j`W~Lr`D`_g@^- zk@U*+*l|*6zR$R4P7+hlEnO}BFuy6j$rL> zi=fd*e)E8s(i>{QUagu2u$Ci5KiOjd0CG-%KsH5WD16xmO%eI|3I({xwS1_3NwQT^ z15`3h+SEp@j4-w)ZfH--JzQg@+#+*x3SihA{c6t7S(n!vE;Jye?7(rn+_KAjJis*W zeDH8=e~B#N>iyduG-WgNCqK?SE64M5y9de$vk8odQ7KqppN43sCVjCfdeJ`HkFX5s zG2;xm&f_o8tVzoDQArEJ7vQhtMd`H^pn3J*fU!jO7qq-ijx(gy`v(PMtKY4Oull)R z=5s|TtyAFBF}z{ek?w<+i|KzETwUylRw*G+%f?{#pU|#yJc#?g!f;&R`Fa@=W{`_2 zo(b>JmXQh-f^a*sQDXYB^KguH<7wC;OXxPX+DpE8sz3YmDmK!>f% zVM6Ey^%?b?wEUjJ)BtS2to{+{pRgu+q{AIYFGXNw=vd;@htDO6Lbr$`y;RoGyE8zx zG}rYa?C|5r$V9u->WQ>S$n`ppY4G0f$KhIHgsl&yPjN=X=21mTLZ;Q^= zj4?aav>mL9WrGw3k8F$_tPzW ztrkabAB>O<&N-P%wrhveaRaI7R4#>4SNH>zyN1Nf_Pb8Tn_m zY5R|c%RrYwB6i;S7ydWp%s%OYCx5=Zn|r6Nke|gv$I5hnZwfK4y(AGQAw#TTO_rDn zGYbqeMju16!19J}qZ6t9u!Y#Y8;Ah5w2?*3Ezg^-5fI@uw3F`ml&!@Vgb83(xy3 zt4*AetRy3UB>uR^APHr;_npZqNi9bbJK(aQ2N#p1aMT#T4zJJ0D?y|4EgGds(kz-N zzWiZQg#kdbnVWa{2(zymI|?3`2;|D9f27;&rPX1koSP0ED^NjYG#(S=8NIT>x?d4Q zIKS&(KD5mWGXqdbW945eYr;;Y>^%*SWIK|#n{Q!*0T~pefK9ohI(Itw&8oi;o2Tb8 zGt`?M`SIhuX z(U~%puzr4$#q)E2*L_I)Mnk^1g;bgfggi$+CPh1xLJmqEorxCtTd5*Y1`0GZ){6d# z+JCX-sM9IO;U1+N13K8UwcaT#4LeI{K%a#)K z1jDU%ey8I`%ZkyAaeZ!Hph@sGtn;>Km)yCGcxpW{AOfy_SY!_)NbAVQCQa9t*pTbq zSF)%b*is%S*ZtOZ$WFg_x;ViB$e}b9#Ye%PXQELH*0HX1tI>oP4W#Zn>+pc06z9^F zVh%t<(vVS1DsBh?J^@hoDE9*PI*w;ydI~ov#~)x$yEBHZlAWCNzd5u21YFu?erp{i zH}c%UZ|IX^U(L3nqkzhuYm8!-#>v@gwQOy$#4sG#q*+*x>Av$UXFZUMw8aTO8vBfd z&nE~R{+KCLVm+7BihBqO{#(^tZ3w2@#atuy5QOpoZ5q=aj=O|8QS?D18DV*gTyfZ649h<+<$k9F@&yI5A9Ce2Ab9x18X_6R zUroOIc(+_sFLe0)$v5+{6rnNV^_}&?Q_%q4h;ZnySvr|KS*2!yln=4&16mm__#CLA zMoOgH>;|asmpEs#+66b=P?Vev4%{U-Rsf9x4H}=v_A>pBcu2xki@U5KplX)~682AR zqAVE!tyB)txCFC6w+v^#%}iICVnZ|;QV!2AKEBDKg$a2cvUPC!U`J@yG>n!`cuyVt zOSC%c{2-Vt`gs}si*$d7K?r6*yxO(-j80*^Zo$dd|Jb5IqEb|j@6VP@kkloD*BBXr zXJxsTCTPM4z+IxxjW$5Z`r=K9z82mNzg@`&^@~24ki?lon&FbScX(An#~kkC;7gN~ z@$cD_(2GB?$NObjz7sFJhQGQ;!^EECNz zxB4e5RGwb;KS7aR;Q#W|;jI|R$W{p|ydnww{Rmfbu&RXH(x)on!9#%lESt+cMu{c) zhNL$DRZG$p4hxKa{%F*RNuh4PwZ!j^q;s0{9^{dsYrD4+vkAqlW3-h|`(Em<3)xDH zrxf}Dw`CTS+rKrp81%@ukMP)h(!y3KS#8|Xjdb!r_aBHbn2uqqjrC-5Q2+K5?^WeREe2fKjUwaIQ}YT?v>h zcd3B8VRgQe?s%>5^B@LGi2qdD8XLY(n!4dc(L*3FnsYVb#PuaJ z$?~ekm}}?YI`YG6G#c<|=RB^mcW;|V&U`GcUb8h-8Jx_}kK=vz zqn=Y`{FLE&ocbpyR4*OKw?|k6&+>JC5+Jid`7t5TtucZSm}a~{H31qlrxYxoaoQ;| zj$u)*Nb%O5j0Mh7fw8N*Ky*Ow9WqdQLk_Ke#Aeml%tm7VR|2m&F#%!h+?}X~O-k0J z>Xg8Wi(*Whcq3r8ZdNr*=1Y&n2h0gY?ij6wI)nJ`V!AC&lgw zQTv|_+{W@0a>GjQ-lyZdot>0u!tugl{DOu|@I9PgtsSXLy^zP-cDvs1uriVp^R$rE zV?SFTTO{%oD6V5f3xTp}N69EdO_u(r;VTR5$j3; z1?)6Tm_PeCmG5R z0-BHuEZ#A)@<>)oAycMzn`8(+pq97my z2qH{s9|cX;;a56!uNV2QEPU7gwJuyUsrBaSj#+-~Ep!cNoO2 zW?Zg!{%OeHi)yr-rmXyDpyOx}cdvb?wR-?Xfxd)+i~L_hiX($15!Gya z=Hp`({vq+nCZ+Y$i=|stjJ-Fp=!tdnRE83eDRB-(yqf8Kp?qct>+1%q+$^DHelsq3 zJ;NPeSIsC`Ig^>#5wi5&n)-IVKJ z$JatAC{&gdMu|nT)H@_U7=N&YFc&Bu`#W`wmU;dCw3j%`HKgh{Z6xF5UVV|J3p1Xm zB)nSVqJYBi`zS>0n+C20mKEN-87|j9* z#=Jw|^TJ=5bKDBoU^sPCAz~1}rC5at8n; zni*`PzVlb#$5IGaSgVp4lNL;rdsisKK=ixssFf5PSe7=6Pl*G4M~DwaK~H~Na4>XX zYW$Z_i(x{;DSat7^lqs11grc4u7#ic{Um6Tzh1?1$70#J@(AdonhDfwScd$0rKFka z6_4-Lb2=!Py+dm!yWYNB(KX7ouvLZ&;MQerUhS~Sxj&#ZM4A>nJc%~%lRzHNq*cfo zSak~nEl&tqmI_4zb46Q0cwlDp0^M#W|K82ao-q0*P~Eb^t@%vcGXYyP_10hC9ZK)4 z#Kf8RjCJz{7iPmXi=K}3hvOn&Vt_4MXbprJu(-!%1Z5)eoP9?MZuil@9dgaI(_+Og zL>t*esYdE+4TXMcPnt1V!&3OIXq`|lCIo*p!XMb*GX>2Vd0Iq}W>JG#b=r2E9MLz- z_=M>llXX^_*Uh=A4G~{2*XPdZ@c!!^-0z$%fDNlcSq8|Pn|3P!4dj1dKo#PlgWY43 zNm7wK2~8OAr)sI;_Z=6IiS0_44z(cHBGIGYGa>nS@7$5EU-HWS!SQh9{ifE=F^iK$ ztDJv+ASIFq12N?WYhkr}@t<>pN&?T0Mc}jNE;1I=^e7na ziu&v8W+ETaP(tc-nUPDnOi25UpZ|k2_;0%?SH4C3T114J?G;+g761%3wz!lsKNDS4 zRI--{fJ*%tgKbu(z5w!+nSTUx_;imKSDN~lv6#!-6so=9gi3u^H+r(cT`FGP$zy_i z;ddO-lRx(!wMF5bKC%D)U^CPWAtIkN!H@@z!{_cu%?Ts$U|*(ojG~!n-F#EBrL0;o z!G-nVY#?T47{I2P_46hmo>BeX{uIXw=l`V|vg>HyY%TPtbz6+4A#Xu;?^eAidF5j| z1w3nZr#96d5c?Hwlahzkec6yHo+ad)iO`~;a4rq$exvX0Jkb+cGb=P*Ms0oXjGn!* zMeY-zO6UO8zt-#FgXYM)5j%R|6W-$KnrYR6EF}h|7fR5c~%~Q$*St`7XrY9H^eGbO_4s0XrFVYqsp`&yK*7U5=KkiS zetajBc*~=o_BuPiP`d;U%5!)XkJHMt!&dhfng%I-+#KD zn6nCp16|${d_vSYv&l{0F1`Me0vww4`NZ1^zn``?SANU?RP?|p1oJWm&**Kq+upri zc*FFErq|%ltbd^!GK1ki` z?LWWr(sR*!1kZ@{zaNgXxl`rDwb|SXGy2M=s$-#;$^W^Op{ot$&o3Y}sP(5?b1*#r zSAC^QF|Nu^r8l=?2fdW{mu{ky`{n`uh2zIo1eg)W%Z>a%!(c6hNn6Gd78{#(cP4lL z?%{_v>HO0W2{@K$)^(rq)upt8p6=C>d;~$&`%;bxMGQe>oBem?!Hc4=S@vpddA~cZ za~1tH^&oBOC!xiPeun^}?S#ireI>Ad;%O`!7nLMDarAGK!zSJk z@~7>~9~z$1Ng+&2 zZ|7Yc@8mL8EHXm~o-sCcE2(X%+=GmStzdLX5ZYTjSn#@D_l9{X%uZou4(-*3H}`si zxIC_TS5ZKjN0ks5f_$s-x~CWb@nUfFbAF`FwG`jCQ(k~Gh!2bssyO%g}0Hbtg}5TqI->5OvXwqUCSa3Oi7MZqT)Or{A#HS<;l z(D}D%=HULb6k;RuP3tAG2$`komU0|5(;ayKL<&m=^Is*1kO*FGEh@boX#1mm6{=gc$ty|c|E_$D1 z$pgE55FJ|t5`w!29@jbTAZz8)s3DLMY;>B+K_lhK#HZ|(qP~_t49w!(! zc)|rlN?+4)6IN6psooa(iU)HJ5rt(-(LRzogg}f^@Q}?5_DZEt(5Hgl@EBAL7 z5FCMvG2Q;TZR(w$w^VP6_phxLo<;^O&P0Z}BJjH&JDKXjk>08-7ple+@_`N!&~ zga{aZo4brFMJ(j6ZUo_F$0q`Q^}mm9xvlrCehde>-#E{o@b5(*Jc$nu(qQ)TL6@A% zL4bscTuTkPAJ{HCQ)!2?xIkU0-=kQqYF%yCjE;O=e?1BkuhVROKDPe1#8Tg5EvS`0 zimP2peAhqMi)_l~dRR+nWUkZxmipgUrC@n_#;>m-<_IT7Q17d-S^t4B*1ZpXzY$AJ z&^`a-7rt}748P@MlNagzce{8qsZEOqw`HXG&Xdo)_G%d+`^zvIm;tFvM{o zV)XhTTaz5f>yy~R5~4jXei0+PU?MB~Qk+wgMG}8&GzS%A+Z0a=yc;!LoezRUKzKp% z`jm=6(MeYm4e5<|6v<033?%Tdj@ldsh$S|sPzs9AEksg$;(ljw`n2CHRLdiNudeZN>WBzMHx1hEDSzaC+zzLP2%4$3IhgO)B{HWHEw5+};F zVrj-aH^;;!KQM>grTTe_$m|EE&QJ;r@^>vmH^Z$Lu6LUCZrz6QfKnOMxX4|;pfgDDc$QiJ&)`q*ywP} zg7y^6-dpPJzxxY;qfI+w883gL7+;<+e;^w-H5rJ-C35-#1mva)PaFtB7y*>hAX4&g z3D>j@W0Oo2|5=#eR9LC&73u|wgT)1?%yd~NTW$ivz;XD61t+iy%TO7e)}r|>gpeJ< z#h(i7WZ0f*%D;QZWNl9#A|4%cknqj5Ky%cVgg2f<(1!bAjAn#_k;( zgAr9uVQ}V;3iwnHe>(izy)_ZGxPG3N^?h3BPH4Zk{$?Y1edsZTYX!_Tni6rnJ&--nL=sK!cU>&jJcJx9}KrVyIu(mqv(}ovICfN&8 z;hLIxtW2-d?_t>+szB#;a(7}Xq26bZ@5D4DLAB7CJ=NIp@@L@j%;k;O?JCoYI=?)j zAg7T_XCIxOmi4v=C>+oh-3%_+bVEZWnZbrB2mpEP>9fVSUXW+k-Q#yyFJ#*F zny#FD50)ig@X+3z7reghUWqpk#)PYbVn(&;b=I>X&UVTW{=uu9Z?63IAkP1MVNj12 zuHs3SwnBxX27Xy}zNnlyWmASfKq7V~Y^G^w7QcP62QsHkF<+s(Q$SS{$eS9bEK>CY z#anrT@TZg5&vdX9{yBchc+YbGDD!Ut<+|JQ6d@POB&)E86HyVIr2-@Qjl9pq3ubL9 z7f9(|zWwC&)<#Vln4uZF#fV@H2g@t`<#vzo<;QztCRQueL}-ti_MhYU3f@(F4XyW6 zI#xYB{IAyjV?m%$OVN%6Kl*x2s_)<4mk-Z#i}N@)Gi0?pSPR-xE;u%|WY^%0rjY<_ zK%(%cx!=vhAy6Qbi)9+Ussj<-(kdOTfX&LiCk~4JcvX+CRZg1FV_+RRwAp&~QpF z{zq*&`T5R^a>Uq*G0`}RO{pTMV#&?dv-*5IEUynW*E@|D|3x>SpEoueFMeOH4AU1B z(nSVK8N7<_>20f#F^vF}Ai8o2Ypb{3B&%&?qY1mx4Ut;~w3lK(hb8yQ8b27}{tnF+ zJe~TAm44`0sR09Wgflrru0zY#>4GP3cHC0zfZ1->eZ}17B8TIwWCp_DMlUd12FU0a z&;6FIMiL>1UV&nsdZs~4u1+68fM!UZy;j{%B|T}|>tBjcGv)4<4*nMro#7l@aZhHn z?sYze;>*MPd?w8?X>I0(hnyQOHWm`VXr+BW*FAAZ?e$pO7<$+GGrU(X{xrkm=cm_PrPTo~MS zwlTF53fBWnx)EQm#U<_Y0V3e^St7+3dkBe`?^WL|br`%NU6K;(!?EYed*v#h0kI1-eTGrLV7c4FPHk{?hSbKtbPzEZrNXj zum2H=5nX#MT&KUd4VNX$WPO6IUe#G!wxxfSUZPY-GYW(YDRi`D=i^Rv8L!qxWH_x;YRpPDxu%>HHzqsQJ*?) z2W6wQ#PIyxjV>1PW)0Qrr^2y##Wg9S>};SuNhm&-PW5S%j}Abhuj_MUtDQ)xA09Bz zIOh=lb$idpQC07cl;$Z>8#Zp3E>&r_w*2_16ekAeP<(oXW23x#L2dcX?0VPX119-EP|SMirNNUA9XD19Au72yd!6|Pd#tPmX==9|v9NIIb^y;wF@ z)W{-16e|wm5=2p^^(Q};{mtY^$os}1H}dPlewM%CLRc{eTn!pTb;r&p4hsmzA-%0v zf+X#_IEdkJKy`46!GbD3UnvJ$?IqR#U0Bu^UWS9TBHmZ`iHQ@gc`BQKFA?YL(tBo1 z@*4UgNSD(mv5CBX{d-_sTo-(|fq-XC?zxN>sQyPtn&|ogBE7;eZRq+lUDgbVL^r&% zIBhbG)mJ-^3--}>N3MkAmYlEmYjh3H9h9Dp;;=fgD3z0DY9`%zPZezsG&;%IX7(*S zCcHQ&%oaJ5_Dnq{Vq%Ce<%)GTG^KdPtPUezUQ!%uyH>n6#z#R^b%?G|Es!vMWY-{( ztQoKR^e@DILdU&#LA|`W4a5395-yrNc_wTUNkUdl5!6rQ1W6$Q=l_lHzDeA}8Gp2z zP9YrRE2PaPC$MD&xbnw+Ow+I=coWoy5tBpacIFR}Iotfeh^3;ahM}DTkk5%E?{!Md zw(emIFM$FLt?)hveq@xdmOKdeozus6Bg(YhEJF zU$q=d?uj^NPs2;=YAi{)S^QojY3|$p7xq+C83AKbgPKFso>rQIVZ{I^^KG0n2 z1G^vp7@oZKBPihaPOyXl8ag{6c29%}Fm$_nAUkLC0WCd}Tr`GHr++#hU;52M;5o!; zyz94=BUke*8uHmPvyAPp%$$TUht_)e%30SC?T6Hp+#Yw%hC6$u{O*QK$R=9AHB8{v z*Eg+oKzn`fgefqD<;sy7h}F@QLug?E`N!uAzIW;6THR~(4_U}x6ZxfKe3abHcjg%7 zp%@XVb~`~-j}<&BbvE;wZTMKiEmsu@Ej3#)K)#=RK&X?$M}AcS=KJ(>R3jKmr7Vl? zb(iAFnBGE<*M^t&Co2}cnhJ8PqJK8?MtS(Qf{^0~Kl0r)K8Ww`)iL*`#yFQg=srW& z9Nc1YcJ}Vg8*H48FBfwi44*lFBp4fSpEa$g9b9vdKGztEV;8*0zskr;8feh(aWK<^ zkmDgP-rnzw`~s&qN=y~~Qu>~C!5==P7hK)BywbzukbWfx8Bj?qeYiXbGLn65%;m9P zb!1jk@>u5tUFFf&Bm@a4&h7Wjcuym+GKa=b*wbpweQpKxP3JTlMPQkbZFpYlO>m>1lx*NA1dN>IGWDvTGje_SH#r69B9aIX+=Yo&FZ-2pMaAlW1H!j#y z2@0OwXvYgWP}aC<%}Nmfp=MLg{KA$7u_J?%(aZAVIVrbfl-PjFpky1t0T3aFYgM- zy4{Ud`rDnnWq?^smg&6pn}Y6XsH~P*)Xb$v%(N&- zA*OMbd|ZU7~a(fp)I8A9CI1FZF$t_6Oi&}A`Ro#f~~mNVh=62bL) zEShjYZOtU=&d4J^uqkR{Cmhs>UwZKPK1&SQM-Uv;byI{HBAlxicuFyXPY$GW?bTrk z$)!diD<$frOIwgs4B;jG))|Yj%P<+7=)Bhu05M!v$o!-+ENd`y_q~%I*kz<)3%c97 z2=&vBRLd`Gz6wO2zvbL8am+m(jEj+-><*hdHf|W2DEX|)?e@s5^(tu0%kda-geuzx zs)HEku2A^Edo7oX`+PG$S(EN}5CwgV)i8H$@!T(~_hkzd>tBsFpNT1>$DP~gp)ED~ zZMr8!>sZ%H;ua&@!C^ED%7XwP^lo(}v!?rp-B5%WrrSyTFuaAF7PrGTRxUM=Z7a^cbVtaZkJ!N&MGJM60J$E*bW?;wMzsPr$=pg$ z1ba~cyO5r4YCk-DSs~)++6P_EU=5d*Ki6!m?|UPDO`y`HC0V`m{VqU-pXKAeY;#Kp z(P1K)1~y=@N4?c@ZGr^=Uo|QN&$fLnKpW*OBbIzd`8?dlqMP{#(prUPr7Exej1T;M zrS@{Y_uZ3AbCi?&ZZE_ehXIc5osByy3WYt-{aW_ZF}1O`uSwquI;IN?&x8&eaWKXV zUDeI1l{`~j};4FkSf-;|ArM!Tu?OW|zbg6p*p-%c71% z{7vY#^>9KA$oSmxz z6o7zXZqR7bDEs zUL5It9ayemkU`S&!R9P~B#DbU)5*he)ja0!x;Z7X!d6(i`vJ*j6)j&U5ck-p3%FNF zTS-n(epEwm1&bzRmBL)_ zb7|`j99%UI+W9(*g;=Ghnir-EQm0kMBeN-ce^$e+*RzP{O#&$vzT{ZjaWVjmB349; zoYnQ=j6dj~p|DVht<}CAzqmwV@D|GlB80CZcTcD|p z;|tYWcIXE$qQ78m(nw6J>ToCMWUg(^1rj1tEADqh%srP(Z%z_|gE`0leh02Iy$sPi zWS&1BH0Z`7f>)DNf=*uqW&=zu0>oTrz3BYk>U2sE=(SbyvN_H|zX+xlb^6g)WsjzD zMBpcIm(&^f@q2pm&&mB5_KA}S3ZOC0jwCSj3{_V&|4r5`T}X95laS8`Do=vRuMtb` zCn>71u`P}XB;{%wm6XY!BPTwm=joZPmT9y=gvLeiqh6YH%eKO{wO60>1u$-hb=sV0 za&7020t2+aKyJPj?7bRL;GIxpy z%9X>O`wh0$lZATG*zvB140P}0AV2m`wryn}&pzP_#}hUjIFpjQ@^Gph5E4 zRHt~MoW*+(h%%#!zhbv%SX73;JrWhF(Ud)_wuJ!{gfcUN1Ajh^%e)@=$pmNki5nWT zTrL1SAbkKbL`-hUT6SuZKM#|p{_?gek&vVa_8OfFG;?W|xv1^t6ylgxo2B8S+>)F< zY{=}GyQoH#Eo9(@9^ycU{w0y|mO?-oJNvQI`=VyC-(4WLSpqDuqzuX3g$PUjaTb?Z z1$$A26<{eIiYdmnY%COCJ#>O z6F_mCYU|YwlWUnLRHt0I?@tI2&f-#Cp{30Kof5kI9Om)#L4SAthXcoEpf|NCVubA8(){25h?4U zqQV3B$o}mv&rduP*SXGueA8-yy&uiJJsdYB1Njt7VqP+IQ6pq9QI7q&7wx}6%x1T- z=7LPzejtV(Vt_PbMnVaIxW?mQHGt4H!iNYza9+-SDY) z(oU3s-vPNR;M3r-TcM*VFS=>8iW0v_a+M`|o~)$}`1$g6d;dt^+F;8tBFa~RuBy^k zmaNj_znWw)r8p-toTS3T1Na~Kg+vDmt2I618QvVqC%7~G>{~f9A{{NO{V<%xMy;)r z(o|KHqAr0V{J6%a5L{fr2pNIUyx*{K_M7_wdsjlos>m)oHi0+Q=htK=H zXB2+w>Kz^QWAW)fJlV`Y!Q7HHc6Wtfvx>jy!7M$?E%1Q@z=uR)HxB|OTP&iNeCr{( zo&*7NsEa3xSVvWlwH~xM@cK75gxhhb(Vd*TZ`d8A@~#WL?y;AWj4|ha({y?$AQOFZ zk#kNfR&vvEBdiXzb&Q>wx*udv*4pOvp~mNP)J;5Hwi58YXD>;Byq^ISvFPJ$a$H?G z7kMatL&G~xBi0@d0GoD`Hso#+)e#|t(9)2iV0sU>mbh}PW-PKw<9|&+4{xWQ*C*%+ zQfcP%@2AQEJ^()k?IF}(^X{k*1#OZr_Ip=u_ATpnwKPb_*3wl?RQuf%!O zo2Zvd&h1N#{hyeWy3eN+fQa=MrKd(Pf`6Dfu`OIW0^rD?W$1FRYRj|3nF+tR$uniJ z*#AAfkxQ?a$89g)lM+LQE}rlFh9Bn1CD7G+(@v7VmLQ8?n0+-N%%%)S4?covTl>nw zx}!!OIWZ#f8J{CDCfV7*Za|3{Et&&RDioNQZ$ec z(_*)N=fwd&LSv;<89Ky=*3@Z09ntApZ&%FuJ;|hO$BDA!UaFF#E3}jaki>8V(-w5A zB=CyiMEU(0K!6zsQ~#=52?yHnDaMeOb019DBm2Dr$7n$TofUdRjlD z?}q?D-iV{IWtaI~bje6wj~hZO1-i&wkKCpQmoVdhTX~)kV$G?TI8zTDngvdIU6P1t zLDVJ6$4A=Mpuk!Xz^!LTw`FF9XI%AO(Cy?B&X`PJpQ*I+9$zsIynBjnig-@|1X!#{ z1B*y&lN7&yoQhOX7%R{ipZn+5uYN*x@NVh)*Y__Y?CJ@p?gYvq87Gsb|4CKe5FZp8*72WN%%=`Wf{1Ma^SR=}Mr7UjvW7GW< za1*H*J(9iSD?!?iZQ$WxbUwd8<@CRNUmw{la`Tn&t57-?;exP0O)O?i*w;Sb`hG+QS1a^|(0*J%dB%cX(TT{*t zOa)(3@25nE1oo|)?k;OD?$iK0HI6f#9WGZi9-aYY-noirI8YsZR&r(KXl>Cxle!BL zo5+grttDfMd~?EvD4%k^tH;I54D$BDQ}k^dl#Vwm8-yyodheABIsGRBlzt*X-QPm( zZt};2;xOC?TDws-paa2W3}zgp30L|0Ob@3MMKI}ei~TsZWwIcghQ~Ch7>xp8JTEIk z#Ns{78@aWondaX*(ZOw0e!Pt)M8@Ip@rSXkhLWx7f4rHf)1zRhszY$igOZ zy0#y-taB|X3{UO>*ES5Qiy94p%)=Z#1m_oZCnz3#mE(jnqNN8mMIfk`#iaE6v;U^L zq+J&X_jQ7uB5=mmMvfD>X>n9}?moo%?Oqp$&pvr{^HL_o-I zf;;4Qv;-2u5<_O*EtxmmtMOFc4{%P3XNfs$(`2gY2WSx5W>?}1OB6i0Cj=I)Y4NdT zf3gWrE>>b7vDocadOu%pFn1Miyn&xQm^FrbL-AmZX# znn^-W0ax7!;Lq3CoW64yKGSW?$nHNSdkqV@jQr?)>Czx>v z5KmcESEb7%nphiiK%0?z7^#vjQsR3hU!13VxD_t--HEy`EB}Mh`raRFHui)_N zB5`&uYQP2Vvi(i{;S?rdrr>5TBk~bZU+L@q5 zH>&qZteoAvrW1jYOMc7G#;+g#T=ShdsK*f#2RO@$bgJ?;9Sk+WD4K(P#VB>Kz@N+^ zf>K}N%Etnw_uM7{*Gw%>u_1!CUT6ZUEt025dgxA&;^?`+^0exnhx<+HJG%UQ49)MQ z5dLl|DA4co@!1(9V`7E?i@-gu@e2Z5xw$AgJNJ*~<-07-uDIa^ z1qt)vT{Ot0J$9LsMk0dCBhaqd_;gVfocKu|z_i>d5r%(h?A0H>*CaF73k6}yvGEUf zW5`bC^$Qr4u^5?6Tf2y(F;biF1kNOXJEiU%BR&Q;Xet;VUsf+bFO5pdAHfig4MrKw zFF|6K5ILKqpid*Mrwm|_xNu9V8B&gm*Lmf++p}|Uan(g-u)hX$-&HOp7%xkY27e&Y zOt>(lACf(eNqtdnBtua6L*nLc2eNG%v<#VW${rV+t>*bHCZwm!`N{~`^EL5YH z+sg0%^aBnX{#}b`g1tt)-*dr$bd${`x$q)lc%YWZhY26DZ3sy&5wVNrlN}HzlpyCQ zntgFyn^XO++%s^{Jm4|Ig^amXy=*#H?*(3_09&5(na!m6LPumI&Fw|Sd2#JKtle1F zQp;0Zl;d|^4AduxUnk=8^$Mf%%}L<1&$=HT|0bp+5PZb;cxogG@f$)6ZE;MzD)cxP z+;I)>dO-}+r3HK*;RF9ze+LU?&Hz=GOjJl16Ce#gI_mCx`T$Odt7&Zw)|CieFzEsx z|FN;a&L1EcDX0GmWQsX0b&UHr6Z9L#XG%4h*69@~109tOc_`5$R7I_4@54G&_KuEwL6aSFk>5-t> zhAo?FNqx@G&Q_DlN8ZKPmK+Yy4p;nr}BboOfggq1syY}4- zK=_N#?maZLiaH9o@#T9&bjT7L`>9Op%S(=Dj4v00l{SW*g}Iq={~nNOw-W%^tY_wR zbIq0sc-Y^Ol8+4X6sWFoE#ictd1evszI=2a0&Q^+o0#cb@800sl4Q#>b5uU4X4RyW z^8%A{$EdrrUQBZ@ds$;+cmC7c%jScc;QIHUs5CQ3gE1z~7T~C?qLzJ20+VMj8NFgI zQqfDf#VBzltrW^49&_HEm-`)UjnCxw|89?Oq{>?^h_YfK>$<{yf1}k=_yWfId>o6# zz7o|w84y4)z0bn7d-lT;Cs3H@QqLd{*{oJE#RUF20^EH6Ah&JaI{iBp7eVY%OKLriBRzHs>3t_AB~B1%YDJ+=bbueIDE8GO!tMX{7vc=xNiK#Fk(9OVG84 z7#iEFvYvR#Nv%N#jOMw3t+ebRW?k9}FupgsrIg__KahL0Ku8Tg8 zX{DC6eeu`%mzQK2Qf5f3X~`J?R2GliYpR_?_$PIZ4m~}LRvMHh9`R5!rKw5f3YLEH z^%F-aU!JDcEk4zv)*Q{iV*+{;`0`--Cx~-A;83~#tZiR(1>~~m6q$&bg=%5wDrj|* zijzlgtERa7o)Mw1g5dI)V{Q;P7;~r<&)pIWmLvwES@@FkE?$aq6#s7FOYNs9fAr-_ zZ;YmDBWKL_GtQekB#*pa>*0Y-xlcUX+j&v;e{ZS7a8zkgEcHwGU4ti1=joG9J~_am z4vG=0B`D(?zyf{BhM2zX?kb6aks@&nfk&_m5&v&O0x;?9QZ=1yVC`x|q7e5{6tr}e z8>q30?#^hy!k-~uf?@S9i$C_wf5|}w1aQ$S;MoTIO^P|Iq_tBW_vVen7nEl8joBVL zS3E%#bVcg-!-^TbnB<-|-Ao_A_~oQDq@etXM&U6Sy$OXFa=LmLD_&Y5i0GrYnM)3i z)y9LGd}0CZc59{9_Y^&jx4zosJfpvon&}ocpYk?NDRRpF^%BC&`_kaAqoy@hQ780sIwUA9jIa4^c>!div9HdLM7@ke;lOCWA`8tyPW{}BkrG~3h6(B z!pJR2>=vunUDA~%D!To0ek`%nK7_!s{(RP=eu9=i0fWR|7Aq}LmfsVs2%&?ok0XoLQuu=%-C}=oL`{z^wLN`s zr{hQrOjE3EUi{kej_^&Q%8(^$Y5z%Z_N$s;0Zg9(ADgEawP4W)jlGf{s8WEsJd<1f z^G!+2y}}{jUCvB^E0AWl%WtRBMHD73xYH?!0AF6xHIP+b_u2?FHb8XrLP zxL%{^vA+Mz$VaCv{s?-=b4>6OBU3gJlV9Ieb5GNe?Afs=Y5v~*c?~3A2>_6?b?h%9=(@uUm(bI*zo@_npXR2PsE&KZkgm1t zYOqC>B1_}IYm$ufVdsp!%A7LRrunABRSHS8@|2&X^Q`%<1FH3#qWiPm;TxJiUpC)< zU`2+&G2n(X9n)U*ZW;PXVF6Z*=sA^cif!pp1BW{!o1;G#md+b@Mwz0g8pZdf^F`0S zx^+`~%h)jh4fq?p0aF05z;1f)u(dolAG!z`UeimM`Ie^=BITSeJCdV;l^6u^LC<2| zqTUp*e+$}1kDu1aO4Cu*pR4<(EIbLl`h3PI6RY;LH3%+uRw1PuEHKOV7j<79FivQ& zMGrvQi9+Eh)Mq1`A)0bxWb^NVsvM`iwx=R$e~V;+Bkjjaui%fBK9K8~et5)+8tbew zu4HqlM*P$0_<&HAkT--e9pZ_iwDASB0Bqd52{^#o9Bc%N&*8ii6p{aykl9SF&*Cnz zEwCC+ekD4g?!2t{H>1l+qj{Pe0u;aX^I`ecB!IRxmXBTB4sTWl$T$LHTmYLS8-koS ziB4t46r^qNaIB!b9>Q;yWPa(srJ!y`F()wHp?7{t7OoB0}1R}ZW+)hb>k4q3S3$n z-11i-bLmo!Ns)0hp7_>9QsmJ2>=*6ePF*?f4Pl(l-W3A69&VSB<;WoO$zOwxL(xGW zD2BBpt?}h{)%#|X1KllNsdWx>#0yyw*wDY0YWEZf1@ektIV{0K1Kop_M?R=nPD?fG z>Nvch!#^Q-TZ#d??E}q$X%%({Gi`;^>h!OiWTRxaFM`4ZM#%CX?kcob;Nb)hs4n(uqVQ`>I5gE1Tp0^yk;$9yYlDk?NQ zj_W545d#Fuom3Ly{LQ;$`K~!eA>Y6F%@|+h_ufOMz7CbIbp7*o&moxUzJ?M&X+_oT z?T(`k2(2A>%w{fCUf4=)-)5C zR%m)PD-|eXPG^31B|3nQDc&G{FR{(lSx$%(c5{&tX$u{?Y0tHNQOiMnI`o*}ck|ac z$Cal)EXuX9aoQ8-pUqhUk{z#}!gT|ES7(-%G(Q8(Q%t=ljrR@abEvvv$+$Syqil|c zuKpG^Y#hJ)taGYFM5Uum+Qm!2Mp zpbh`xLu{5;Uoy5DyLcaa?xQXCio~P8N2Zq6&Uq1l^dv9Th{itI!2Zp59*6niqmhf- ztt2;~0ou~J%a}fK3;+pH(e(v<3c%{GLJpGU~*@sTU3v{CA{=(J$g-F2dIe!S%Y9BI?YzO%9!Ac zm0Qf<%YaW*SyEVijab*=m!*{~fpXakHd^7Kc68Bm*X3GG3^tqH1vemjgXVD-?vMO@ zBc{GZwP5V!fU7u%K;Qc6t2upjlart)gD$erUssl7L|TXUt|k|l3UKW7LbK&li<@j* zRAyFhqxjgG>$+k1>Tc0qWP7u>4+h=ulgeCKgR6|4qH%tWs5=j|Y1G7%F`aVm6yO%rZD-aD=CaQl z-OXN4V9^!v{Zc!_yvW{Ew)wj%xCK z|9{5l?rudwQo09-C{hYYNvCvo43Ls;kQQkP>1K%1DIn4y-OZ?N-@QNQ{Lb%>=WOR} zJ7?$K?(4pu*Y%3xhMbfg5(OU*=e2!@h{3Gz$SNAs_arQR`F&D1R0)Bb1PbBE08VKr z-gaiS3kAe+h~OcM=&hn|grGL&6HdJW<__uZ_a=rL>4;z(_*@c-Ck7=qjHpaWC`zY!e;EDA|l9wHE7rhqi`m9ep) z7A3#AOAz+(bnL?Dz4Cf7{$>21#|M%%HkEd+dBw3G;wmQu8Su&dDdGwG2dcLjEdi;A zTh3KVIxg2bDLlw|$w@Ir`X(I!5~9Pvi8sGeA_Pst$D8|1^>yn zP{2O=9iN~r3$PLRu!#v)de?L`Rp z&0kNrpBbBGc%QFtA0I6L{7BK%i(JWgshvicYMF1nX`aLBLL2bAEl`yKX5ioFf8>GPK| zR~T5;k=t`~Y1{yf10G=iYbOvd$=>7}fK^C`M_6c9TM!%=aFjsYEGi*_CKTAg3OHq3 z=^(6t$ABmPRiYe5&|D<7l^T#Kl`m9|E+}i3pgtz0NPu;u+0<|DcOW`@RaQ-XL5&_^ z&S+TTVVE*nq-^cs_A$-RaqQ}yS@6V<4;(53+m>ON;sVZK!BC?R0OI07R1?Ydk%;kt z+k-(MoB|8+5=+3Hc;yKQS}1@j+yWOe~a zkYcvje-dB(SPFUY8s8j^ck{VlnBA58zWs0_lXWJr)GQrfS7KxFv10Jq?i zz%16a|M}zuOBoxF2{P9$5lSc19|gZs%}n{p8I?q#xBtj6pm2iBGURSk*az?JL1s=A z_VY1J0O0Z$GrP27s)_7}YAP{ezoEiq=mcEPCj|w?yHL`Hzl~&XJ;N9*Za72k;^wk6 z+vB26|Iz;p!SG*ba=Otsv8Q(cwPH^mxO8?fj7dvs0j#9%G@{+U**IdEkCD6Vo(khaehAk7@vn{{zD5jB?Wl9v}$bKKz4ZaFhEK@E^< zo^D|ds%6=p6556QHJr6_Ksy1acz983`gruw%2R{VWQ++|<@ZOvpa;GZg1`(1O8w?; z)diwIhz%utR)-tz7Q&=X7k2!Hj9p*9IR;dWr3~-_??}lXcGy@kn|lTPUZw>yYksN5 z9ewQgjjFx)80|>PgElrCC5d-#_yVi+bbtLdyOGzqruSuX)jd$Tl3|8sVIEcqz`BF) zWgzwUt2nsyjp#rauFoEYp8Zk}Lvg9;^Jco%#PpbfOQg?TP5m!oS5y|`^E%PqXhLF* zji)vjnLYQGL`?N?`E_F+sHW1>9+5-J0(Ar^l$-Cpq*Yz_(a0V zCmdKXnID|;%~I~ztt9ad@_h-|uNnx42}TmrJ38H7gAe zVS?4(`>dICd&86)loaUeh(0uerShy3hn~bcKVt;qG^BGLO&49sv|&>z*PIv==uXS< zLJ=z=jX5}0M99b(v(eTSU^sZ!>+h%XzN+E>{A@tD-$<5@UpL5fXQp2nhHDp%S>d)V z@`lq)b1zq^oo$@`&UvDOSvvmBDrC9au7eLkRq^f!2kojXxSo3AG{_fL{w=!FFjz+i zG(9ze)eh}2Lc4zV^fIB$HJBk_*Q<*q&L^o|mKjYrq<;ICe*Hv-8)nE-9EU-odh^Qz z?^jQ&8w{E-0J%BoS=eV$b8Sk4$%{)J$`(+4x{!(D+ac2x!=%PUA}G4GvIMhs9G^L( z98tHt6}Y;BVvpnl9d zfH1^rzM=Y6DLuOKEgP#3bGp*%ndwUHi?TfldnbXlnAAT@_ElUk%4Ga<6TiJOnSA3E z&VWn4c?1TO2QDDrrVmc_M)8-RXm*=9CW8!iXePlb0i3u)yY|tAr(cIRO~@6U_q&rL z1V>~=Nhaoxj{|R%2(-WWb&pHGgMmp01Q-Uj((d3$^XvIU5N2TH`zvhcOBN1Hh?ask zb;^4k5OmmfkJ(I~8Z!QuT~p_AanAI8=a9#VY=M_5-33TOnz_gC#z))0j(J0mWr|J- zehKsy?&ZPauoqoLEk_%+J9m~nV#BUfp4f@V4Oqy%)KHqK#q%0j;^?; zo+hAt^fpZ_1^){buA2I##%BCtdt30^;A|Iu<2!F?V0nP+?AqiSnYS-R^o|q(asMGaYJcuaDepuiQB|1+eC0S{>}GA zYkjAOhk+doS1@qo5!Z`72#^{M9<3i#ARy!H_~qsF7L^$BE0Y694KGffe^g`4)e#2) z1S|LuQxrWUiO|1z2O~&M{)A`xqAYPpkdRvbB!GOdD8{}g=QDPB<>z2xwZPlMzc+mJ zDUle>D6bHi2cKu-f=8ABkZw9lo%FnKWn9qG2uMlpmU1>A#||eGd1>Y5dllu7?Opyh zQGzupL;nrCf(X49eql%T$wls6D#(d2`sNE{B7eF6ojxl=8R)Qxz6h^0j8I);i{anN9bj%wxD8cvtGNoNjH?)FDw7wT;GSC{Y=EU5R5&Qk+Po>X6vbI72p%ujSFY?Q%?f#+ zfRg#iPyNGjLhStC?@f8o8}AI=?R-D)@{4Lr_o>hK@GqP1r0^Dw7>G6!QZD+80z^SX zYl!{ZJLT!GSClezfn>>n-ro)jAk=7uih)8+s+~ZNiP5r1T~s^Hwo!_x4%p!6xxA*r zqpA#x)%%JIEV{zU3BM~&>_X4)!?SAFB9|_O*Z}QZ`WnWHn=Qywi2us(({LEZyehzc zd#9l=)>2p;(cD$81_0M2X)<^~C~z{jX3| zs1jZv^EWK=s4bXZ=_63Qtoh{H?e$@}+tl=-ojhlJJJ zd_8f$E_mUZS|Y|csM`|lC9hT}YvPQ~UL(ScC+*k$Pb+|p`Dbj-v`79>auW$h54h?4 z(;Hm+5UJv*0(qqIEiy6CIY=}?RQv@~^dYZbLD>RL6dv%N2)MaG8%x(yVw!Rx4=?+- z{Ih)_Iuj6wvGU=f!!EQacs-h(D>pYJOPa6`7rGz@Y*fjD+sZ+)0r88C1D!$4-Et3C z1Ya>Di>?195a$uOV$I#17C$qWNS~C2Y$Kl*1^jL)_=_JIiG2BZ0s{kE z@zG0iic#bf*-c8=u#umZSx>h4@CepVV1<6!Qq!5UJpQ}NQ_oicF9{f7vqt}J_`nyB znN68JkOTlgte&)XpM#0JJX_#qmjU&>R%kh{XUz}dqL8jpCW>Sr|I{J0i!~QPMO2o zi~F))bG^A6nJxE6vZ#V6^Y$_2VGmWW1OaS`or6U6ZO3AOX!+>Z*%UEk-rlp7B$||yFklLx#m*-nfr+hE~VRq75aba`v zF|a8;6=~*A<;z2Gg&LtN;||78GttV*nuSUpbkAYDv=rU=)`-vOmeutirBn`wn7Zek zl3OdYXo`)oH+5dHcFzD5W-8S|Z-%~!|t9)%PQwH{d z-p^@xS7rtW-P0Fq%t^k z_t#UZbc8vT7O3!(_%f-&486MJ0j0uoOdEU%|6!;F&>A!_iM3ywbKbE*f+raSzq)$l z0lD(%@42^y`7$#@N_Q@<>urHS$nilc%WEgY{yAZ%1oKC>odR=hB<3^S8+d@Xl`J;Q zTZ+qx41=fQTc+Mqu%CM2VGexhRh9hTvW$km0*HCZ=Z21F!qVdrn7+1N`LJ=p=bvK$ z>HRouC_PaBgB%cqIT=*w8*qTS>190yUO8lpYyj`d9NwqS$5yT~{#?7uFy`Zo^Ag1w zoG7yloQIOh%fT2e0=J0-K^F%uApi_>s^?w;xO|)OBJ_eZHi_pGP5}slvSgc(Z;r2; zk7mA8uaaUuVF`|O-t4H^%$AA%?EY?I3z047TH|sU&JN2kZ7+ZS>w#0pzWZ7Bdje9- zHo=xT;Atb$lYZN9eQIu5Gb?kzcP57i7phM45!T#P zl1TH;4*x?(Xz~`+NdNmart#~%lih3bWuNf+S)b22at?D?IJaDogk_`GvpN` zWJ;I!$6)_AGO=p=a+o0Vj3C}&+(UPM&*%A;$ScG%gd_+$Ao1krt6_RI#ZuE#L1&+Z z-`*}nDA|4vZMK)619(J+Mv$?w@hw1vA|Ak+Ybx9rFb{-&avS8mF!ZsqA!;ME%+~W9JDFMYXzOR#}7oHdk>k! zSccibG7lHsT)l`=zL_>SD!9wop0GK|`VvnCvO6bfTri zkuqg?b5GF@X!}17Y>NTRBtol#AY7V1LwIz6RY}2f%Q^ir!8Uv+ONol!=RZU7gnc3sxn^^7UUu`0P@oOO1DbK5U~o76vRAyiCjGpB72`+F z7e!;duiU?q`G_>$nWnE2Si_lOK~so>eU^dm(ChUa;z0iB4S!Ou^Ds1$%T?jKRvC%! z2B?@_)qePJI>yOc2u^hzCF$EY|CWC%+mqey_ea|<+V)U#XDOtKVfc5K_>jqIV?g`O zUcep~@Uf)UZsP|SG6Vqy`sR!T@GuXXxewqxbCU|hBD_Vo?UryFaVJTh#mO2h&(zGF z{Sb`1|GROPD8JI4k_YxQnaa*A%EbJ9hym;)ENF24I=VPzwVWX>0}&e+n5{3|T0gsc zf}s#u<&-3?j|CMyGj6S5T=w-XQ!NF4lBu;n^+(>_KJ-zC3TzEpgJNdy9svfMa-~hg zT{s@kIv(2FrDU0-g`@x$EdnTPqvN_Zf`*(B3q2VEnlheE3t7G?Ijk3kIo?Z_ZeqT{@ihzX_r zz)gt{dJ7rbcm7YlF%P47H>9ZZISVQk_NstaX+h z{VU(WEfCNzz#(g10et!5f89<`I{7*GIK!2S_Q=d(zD($QRvht?)2yF#ZHxjp3@66u)ObDoNIK73vo}_BUps$}I$Y zh*%$a1v^1S@A&}_&DF<0zuRIcYlK3^_=n)^Oj?=1|DhbSynaTGcn6T~+=y z(wttl6}3GcP8k|qJSH8+Nm0|F4kQM&_)Q+ZHUc;QGQUcEe++10FasH!U26?@k&b!SmQ$u)Non@_jrc?D0!40aS^HqbL)1NEF20F!g!{p27u2QP;60l+)s z#KmSNAef%d`NL@y+iF~)r{NXzPiw1XLTuUsfl3QS6#%+pRGz=4`p=a*3zjo*0@C+4 z1#=M98_n`m;1a_&5L?UZ8s%e|b>9~ngD`-ToBeiezC0_GhhfOcPgY*Iboc$yQFGX# z!t#lD6d{CbQzkHZ4ZZt-6#*Z-hWv?35;eE=;dhZ5y=}*BEhe9_Y}z_NH`!u*uw6ZQ zStlSb<->-IwxII)#>(i?7}3V)9BN!04hfU&@b?fON4bpCT7S;L&brMV=FxI8<9ja` zg1WrBa=%^)cM2K?SQN|d8h9w7VdXm*ae`39%hmV${ggZEGZU4GiC^&zp$(TL@%FV( zf~<|37VZSNWGfyj8(*c6;%HSDkuJ$aTF7!$ezb)if}S6|i3Yh4ZXK9~M~Ei|V>e(2 z(^vZ^+$qm!@)L`s(&t?Jo^dfPo69P7O1We=$Xq?vw1w-3zEb&Oc+T0w7 zGr&@Uh|)#}&2`&8MG)DOO8CjThtS=Y?G68xG;NlDa>Q1fJrvx7T0WYTV%vP*eSFe` z(?~hjQpCaei-ZY%I36QgpE0w_H~e0q02GUTA&baktu4HCbh533?(_JS+N=U_bjyl*8SiLLWOuIkzNozg2Xu+ECTwtL)phnaMU=Rq z=RGufz~INV!OvSmX!<5V$7nz{SYVk9{dUm~%bBs0y&AQ*o7xzHz90rdK zVD$eD*wc%DRe8|R;k)?JkV|509w1V?CITi^N1Ps>j%StJ;hP;-^yvKc>ed;+a_>H2 ze)ej~!DPQphl&-8y&?l7*vxx*?(*@uZqf|YkK(t$S${vYdJ%N&}ByT z(F@Yvm-RrW1=jn%H1s`^=+8)E;Ac3d)-8MrjQ*|<01O@H0s~C$)T{}m!jLv5bP?1& z*v#bbx+X(IewD4cT}t9kEXaY3NLr9E!C_kjxgq4!?GgKR`KBjnamZ4Gi^FzIy=*ZL z513DVQY*$6K}d=VKnLMJ-(am9AzeNNRD=4FA8de|v9;cUcAya4T07=(c+`mqI)AhX zl|*$fTRo}RaO-cgE#%|{YXReu%<{|GI6Z13%Fm*;1B7VwnnsVyh>1z!#h# zX5a~tzB?n7%vs(Sq3=je-naF;GbK=6c}DSv^GWlGF+`jrfF>1YWK0D~1lN_o6kQ2p zV~icN)JE~x0XRX6iZ+z6fW(a$Frlw@CRUqV=GBrq@{eC<-}7bzNgAKD|M1!!;0Mli zkKtze`l)lGws#X9U1Eh+26EnApGz+*GXO{GJn zJBh3PJnk;Ne3(*F)j37OIlnajWq5bN%HcmzFrhT1>uMsRby*rcW)VI!%9h<9nkVrg z&bnAUv301V>(FSc5^3u069E%J#43079%J`2uCgrlob<=z2=ZseK93GIZww-f2B68& zj(D4cdh0%mVQt6#}sI5=0dn`I*995Z~r|xnNTvo zCzt6&;gTMdeCv&;Gsvq{(4i8u!)5n1&VH)0I&~c4nOy75m>QKU%K77)=+~36lC3ia zO^puJbcDgUGVzCVP4wtLwFGl+e`%czpqi?d7gDwxYBVXhzo`=l_|cvOFS-a_`URYZ z%%j=Kmoz@)bbgcgkUx#VLRGfH08!I5|L^I0)L}M>GL2^*I^V}e0%v2&cX#E$dHi&8 z29}#EP>aPffR5}kDob4oDxqRvZBjq~?ST^fRtqZP(mGqofv)#$rp^4RbN)5|*Tw8< z8fLhVnC>$5e3uP!a7iRHaSf7a1+dY!CvZO^hyvw;@iC!l+BLGcbp%kNO&SP#H!|OO zT4-E^^D@`4S9{9E(&bpmVJ@dunN@f07FLK1I2!}NG0wUtrurnZ6pM7npY+gR+$Jl# z+`jxJp~~7`pSk4JDg(nIVq!%M30m9#jGXW}jZnL=KB;2)8O7qB)`bN$+6C<*(OAd7 zZpQg)O8aD{nw#G7UXr&xw1dYbt6ryj)7+`3qXNmS#cbFy5?vY&U!s`q(Gsct*14f5 zzy93X3s*rte8>n#t$f^;Q*kNstzSrpp_wZNFgjOT`UzVV`ws4WasubQ@Zl;d{3y&_9ohSR7f^D=&nwW3e ztW4Z&5*zRI5#8YAJN93WpJCL*Eut!vzJXS83OHp150Qp{vFpCw{SkX^t62N3-v@sbZjA?e9l^d-l9SeA`zM#gqDK@@8(x=6G@K;|u@(JSAdT zx76B*Qn+f-2EV$}D)h4}0ChEY;kHg*gzaQt=?9*N#GxzLQ8&k4^w(8Jjhx>f)E!7^ zHf@Dq0elVbv>NXOT^#){QTdsxBPg8cAjz`g(AB;$Umen&8zFuF4(t%YR8gI9-6G#f z0Jc0*Fu!C!*D0VUu<8?>sT6$J(o*CYVPhq51+7_M;`B)UqwTUaUy1i|vFl=eD;c1K z);!4M%z(6Z-C18lsr}H7LBJRAm;=|1)crW8LCEK|n)DB7rt|D}hjKUuq~f=<`aj;} z>V4;DPSf}Q_C*fgph;B0&MgA)xci_iOYmgY;&e6!5xoxW*JimcH?KDoll1M*XOM3; zh=8S$*5dATJ0WBF+LQNH<4!;6ad{sR>wBa*kYw^CGMPUI$=u z>8bSy*}#a}t$nAz6!vW!L>KAF`@?gu1Lw2ifzzf&{QZ}0BTH{6&j z7EHuwydp*0;lv;-m6FbwHrbvHJnbB5-N=7Il5_aVpfoO^#PiwAMA6y-LE(j%l8v*1 zlS%tKJizeH(VQtZ^o^|Vy#G@Gi2CI;>uoB()IZbk0PwK&*pTXmkyqLNrRXYAo|w6O zOt=g~y1xb6`6&pNEz1xbYw%H18lJrPrUq=QZM=pGVibOSy;<@yV&+>SEuo^KY5AwL zwpH|i^2(U}W1fczvw_U$Y`7!fvMf`a@h(GyDj84)sjil&2`s^>!swY>I-!CAW z6L~v%fe}BENl>T4jD1QStpdxXx$MuXegkG~S0&P+BEuEiB~FFxbVr6X(fl*;Yg#R) zI-7D#iM?=ldc-gGE`pHF*YHwgWC$y+xDAPoxT+cG3&K4A^`eubGyIMFoelj%bzj6OeAfQ zh!C2{w^a*X+G+GCMj?-%d7n@Fr{QTX=KTSY5 z)YyIa(SP`kt|1l?npA*pEC~Ni4Z1v`4SFYw!#^lqoL!|tBT(rA2L^9go)%yPazk0% zUPfL0%3%xEZek>MdU%8@mQRda5*;L0HbA{fsCUH>71ZzBNB}?tv3%*gm@gO)PYo;0Zda8g@1jZ;PA%vz%>JB;o3%G_y<;(x zl>??s^$4;9xJrckWRL|j^geZS(K&W&FCO2$4yPq;X2RQ$(aNUAFL4X1BS98e9X2W6 z*Q%O^Hf~BWiW8)T@~9Ih9~N}(6H+Oz2QO00Wn{-vf50Cjiy+1F8~z<6sGeF|s`|q#e*P5X5Qx)S?&9Evn#po>;G)b`oC!(GL`p-E|G?qIXxp0- zlueeNRjI&D9`>kCpvxqrIqL6%cNDU{6&%iK-qr}$Sm{9?zB=s=jL8*OPnfzn9s`dY z{Y%ZrUCdqW=Ci?uE^YPPGh(lDUOOAbs$EhBXiVWlGW*bN^wRCfZ8aE*4Qw#is%z6Y z1X)*PVo1z*>K(X|iK69J|3zI%pv6{_=;vZ+u@xUm5iP?KL_a=53$*@|Td|>^@uB5c0_ab$ zp&p}XP|T=DC{h#;`hBA4*SOFZ8;S|Vj=tDXEZuu*jlTx_*4ibPPNj?w=q-uaj8+*R zb58_G$Un8$>ez_BAoxd0+99IJnkiS6n}wD(Vlo60V{S7Gbe}}+@c&EiHu1kHFfyQ1 zS*~29nuy#wxZiCFx_W(TeziHBL((BQwMhDkc9|7S8rc)I60V1)Our$WLf{a5x-mbf z*4_@NT^^1g?_Plr0V3;YH47AU-33n!IVl7unU7u}HvX2zbQ-WpLcCU`9ZG5Ny`900 z@0k%F6hia4Jr!)n^0Y7_#~4w;UgFSotVlY-OvF9vIC+yP&ONg7+w&yKTk=aps7Xga>4ee6bNs}`I5b*F2ihUKt-Dok#nV`EyIQ$(pjukEoX z(|iKJHjHhP(`{yc2AKWDL+78)F#{`j@$Cb{QRO|7mlR|Llh4a&Z?!xp)>u`)1t(5C z_b+7bB=JMt;IsDQTcE-DJ#+&zQ(5VbD`tluhHHXKa2eK~tF670>Ryq_Y4`igi}>Bt z%^>BCa%kdY2tB;I+rTL&&yz96e#XiNxPNEgH@kfkr}9OcTiv?S`=ft2me60d@1R{A z>$5Q}J+Ksn<;rNgA3OLabNXWJ4+uCfJvk1}9wU@S-FU2^Bkcp}MOVf6URI_NrZItK zHs0fl>=F%)W`YVuq+kW5h(8Qoe=t}zd)j{W!R5B_RM$f@FhYYziKnT|TzVX4Sc?WO z3-*+jHDpqYkxvnoB2-1mf=uh)V~pBSfA|gwlSewNPKF7dju|3x(XhgrJCt+Vcu2|eXB;QF#uwqk*D$=57;~`?znvL7U&!WKp-uUm%Rb$ zd9k{6g&pAG;|$=s$Oen-6GOrS#dfkCQ`8b#B%LjthfS#EWntWAgZ$2~%j8$SXchKJ z+MN0E4oH*|mNa3bF02XThpkRATC-0DKfr5cWWi#)2co#X26+<*YgxHVPN~sbC8GlM z0kK?Zyxhr^fYrx4F*PjgzwOiv_wL{t zR_XyFe=(cbs@C2LdL9OM3E)Bnu~ga&jH9 zrfIof@FP5VOtX%(I;nK&!8BfFGTm&EN+^I}0(pv2N}l)Ly~sH7YrzH(`&*G%IZ`peeg-Y@$Lv1^{CHq>0)F-paa2;37NQJ~}|kCJ@IPezB_=B~d>oV*G^=&Z9W; z={qDi9<8>->2jXUId7&v-nZ#uBsd01+3^HhGax z|5;mSd$x;cGPmZi!o%fvBwOgUj%}CEGc5Y(Mt=uQ;iTBTc(Kwgm*5@&LvtC>ACgzH z>tzEb&22OQ?;xh9G;(qk4bp<2-z?}546W+)W{?U{M^h=%|GrgmyL)@S@Ee3FIyv-Q z>O`7iWb62;w(y5DY;bE%exO!Ss64@BC8<1t)`O}d1{!_?){==#@T=Y8*4Sb-iM27F zh)VTyMC0t|;N?r^Ms7^6Lni_>ei(89NpzU^uFOYRtcQsMpEG({e)(R0Wn?y)(R49rGHsWD zn{qitN=qQk_p#oKaUgwDp&KiXICd(^Hrq~c{l!PrR6umJ#)NI z*C)ka6<#tkNpaD!qHb%aGCiUKcgFW-(*5=Cn*j6`hw<-a}725%0>&1uBI-2I(e>xSQI zsr*A*GsuIkZ?xs4eST2T&x6Xr zW%(DWU#o{*4u+pbSI8)()iXp4`R?fn-I{wfW@J43?o%{1`d)KnHZ2t%VT>6W69pn< z9WjZw{uuA)7;Xs~OaYw|u!7$1tWnj21c7>>RulQO1xs$9x4q0WEKr!^=U1_S&tVd* ztKV#E?s>oP$nml6ved%Q_Ata3y$D6@}@j6$Uw(>Y{D?ODCzG z8Ff6svdF8GC5P04&$_qXuM?3h>$n7SHwNu|6gb_?JXX%(^!uHU^6B7w+93;YHFBOG zjt~NT27R!)|Dw=zsAegQH<_)Q9{x&cUtmDHHSfL6ozeZ3eXtr$E`zX8f!uQZ+?Z3y zvSgF=BQ;l#{XH-FdLaYToIr*V3CqK_+nw2v(X*=oLo9L47O{eg4> zPXSh+XzJpb$Y^=liZJ_eqaEoif9|uKm7Bg&4idIEihtQhOhj&*hTBUq+0Z4nO(@Qv zc0_8}<)yFkwN0fI>wygb!>UA`-UA81pnn{Q{osBd#asl+MJ7-E+e;e?G zQEKw#XPwG(b-OfRgrwqex++#hT{H%A=+cJp9C~B*_Cx%*m+C*IjXcJhgYLv%FRCYH zOc@@7h|bV9+C6}^0T|0hrjeeWCl#H{1_m^HGRMS~&DYXxFHYcxBW(57norWi7yI4u zP#&Bn3RVNRIH#$0?s}to;rKw?s_b|_GwvFQL;*uE2acHtMAHUD9fk8ej6AX|4gZ~S zmGN%2N5=nd{rsMGo7qEcd+~jjgiz>0w$9;dqO=wWN{^&g^9CvZzAW;HXDSk$ zdi(I^sDx+ITB^(E?s}B228KZ*gxIhwzh2|OPn;V>W|!EW$kuMQla=t@S1g0#7ejr(;}=FtIJv8(a}=(~x_hTi+2 zzW|qZnbXRmRo(Y7S(MO-On;0*;5Asu**E`WK=bz@228gEb($YR#5zk0=l z))jnU%B*qZp3Be%3Yw3(@$+W|GH%RXVH{Qd+iuZYEw*z~p4Jl3`}|gBK7fVMFvQYP zmsxD5oS0uN%Y%ydM)z8}m`|)kIMMtkjxd?~{fX z`b4_v!gw%B%9oblvnm0&6XuRRzsqQ(i8v}gr^LQXpo&FB{uUFW*nej~Z)gY%>ubul zawjq=Ycw7?Um(j-EITUNkzeKl1CkW8>wZzD18bqy>Izo+V1U`A^BZVQOa7Qi69DFC z7yXbAzy&0KXK97exAn|?;OEc~&&@>NeQo06lIvIUtcTCWu%wYzh%<{RZebfvD@y}% zbRSXw7e~?P87UNk4RG_XuCn93Lh2@4Tn4)B+Xr;@a_J44)G0lVj;6Q!Y>eZu^T_y- zRf~F8snY#H-mXqq^z&hiytSbvq#FTr2D*9j!Ra=KYQ(tPu1p z?9HxK|2rGaR8P%u*zjx-eL~BvAdc_D!1}f@aw3)l$7;^6$edjzUKlt^k^M}@Ry(XD z%BO&-WC{<-ICv0#AVoQ>gs81hdE+)&Ofqho)@CD~iMaWU_vCf`maX>{Q!%YMy}gn^ zp&c7f4;>3co?YfjC!ub=$FYH7+km@FDIg*a2YK`KSrTXv!BkF z#ej%-OjM&*?-RjV!=GZ2OwfF}d2q*{UGYhAIzV)GwczHKWW_(50U!i$DX#8W30VmQ zsTB!oNnu}O%O*>ucxdEb>m*jH+UNaTNFd4^v(Z0!r!+GW@%gT0CEeL zZg~GNRoMNrFQkBaGYe;|T!%}&<@ONlAYkglw_sz?nS(y9@ zFNi}lDiH^Hy)8#@c(KxKW=z7#0>9JK3witC+p`9>mv{^@_l8F|CmiCoR);E2i>@A4 z5l-WKlz|!srni;PUC<0D{mVI22|mEu<`?i#Re%pjy)Q*gqZh9+gw*vm{)=bwkWh=@qVYb}?q+u| zF*)Y)TxXTSE2Xas!vUuF&3wNF_^)xwwB_FFgKxuWUcOH_y0lAjDOzk@?7hS~H<0=j zT|X&J>UePDrBogJ;a9?9(~@!p3kbpr(hr_-38Y4!>!=c*e+j#740C>MM+WNF=_!|MLq?YE$KHlu=m(}aO_79jdL)mMSH z(nzzaN-HrLfB&hMm07S-+sjOUJoxb);giMuHIm?he8%=9WH4BtW!Q;zizJ+8`+NpmOuqOkO>!H*~6 zPb>Bd(pAEDtHrK5I!9!TCqB0nursoM1tO%Hwv*RWS!ed?RqP37;VR*fw$+dzPu7f) zEzi|+l(UiS($w#ZREntVSvtEuInc8SMHN% zyt!RB%XnJx!SMmPi}Uvq(@2X%`fmBwKJEbr^N==4Z)<{b`B~tfWIM z!HQG_-pt~Gc8XwN7Cj&FrADoPb4ex7{;Dd+t9UB*U!s*G;$4r!$o|N^QxBFY;mZ=_ zy|f}S8db(2vhih@PlnCUB@l!b&nYFer{mExb z3fLwS=z0je>jZsns%4;;_?@r6?P#-8L|;kuGYt3Bvi(7h`DxJaRrzl$n7N46WFGJR zu4)&;f#{h=MH+;^TH3ev$!un@Oa-Lv}{7w}n`0j!xc zt8~lwnRVLlan@9)uV=fvY2!}yO`;BCY2fN9_9&_Y8+BjBiWF7oBD6OJ`j{BFZ301y z&;}ZpEhN^1ixZ|5Xw~*gG^Q`1KUCnJuxNa5uGic*EC(>G((6<6#b2-Mg9_t94}V4V$gxnk zI-<^h(g2s&^EIZN0qBl@j=xowHmrB=-zx{!ScbVw0FswX>P^iI!!n) zH~zbC$U{BOcQbY6vF+$i_cvX*rS%5s>Z77xgc zyb)(O>=0M6Rx46Yvf`q@Sj(6VlO8s`L32&}9~-1=mbtuWTFmIWU+CcB0b#4XyF(aI zmPhD+n&}zQKBYFQ` zkeJ7_Z#;S*$);JuUbRT>5?lG$`OONPsEf-_&s;22L9UEx5;=pt1C`_f&)G5;Ih_<4 z(o5$+QvfQ?|1tH^K>`Wj(k!v9tdQkRn8ca`cYMD**(F>(* zb) zh+uIkD8pxx(!qorL|LPFiRMi%7+?NiH9$=DZ-W>ZMooPblz!h_5jf%RlHn+)^z1Rl zI@CxVT1A=a6nZ(1635A`j7R61Ndk(xqaZ z#F%`z_wiFZ7H*t=kj`-s->ziLAI}{}0h+ zYa#?4u38NoC|+N!5(Os998B#oBwB=W%nt5%=%A(E$O&ofdi3Gs5hDLN-3TO=*2EH0 zT@V_yJ)Ye?Xm0UbbI1_&b(5BBvX!V$Bv^=`C68|$c?QpiMnoJm-zjen4`v8stqqsL z0YsOK9pv%QtR~{|WIapzPx2qox>mwciNxdZ=S|ag0p1jIlE(tTqENmFeYI(VGHWL4 z2NwmoZ9s_6Y8#rLJ+oLl2_1XX5^!2hvy)nQG2|Nm@*kz+3le#L}3l=`~Z|pK?&jF&?AML8=06-W` z6>JB^CNaInjQ}%#%4Qw+k|nhG2o?}cKS_@g95m!CCogTGAM4=cGwW7=^M%boJlswY zdQJ8RXKeVWWNglxv(I;3gTOV4x0KjKAVQ_U5)z5mqE4$dcc2jrbSY0gal_ZZcZrVs z_JUjAueRfgu%3j|om_HE%RBjNh?E$nqBTuKVH``SDyJ#68OckduaW)Ri&iGAzJ8V7 zk~aHF9M$4tzB4M_lW(}pq~7&E_dfxI_f2WNXU>OEAi2IXFwmW1M$UA$z%MUHY&P|8 z8PX3po_hn)V zRvy`eD9_6N@69AL&dy?7th^|xK&w{X8jX?1Swp|f5 zl7q9`oNw_b^ZRJ$OHrU*G62YH*D$Kj$~!3$eQedbW1|79s(dyl|Soll6Bh}BtWgA>sZ5-v8#i1i%0-=qS^4m|z0MD=* zf@ZA|GLYdhdOR|u1~-`~*~Qz=v@25|u~z?GA9ePgo(#C5-+2#*9KfVJfs}5@V-;Nm z`H#DYvTrnNQ{ICmzKJq&B6Mk|K6LtyElGF)Em>xHlC|wQVxyUdug;Hs4GEyn8im=s zf=39>xm~6Z(yh9$`|au@rQAdgtIKrLA!B?GgQl>gjJ!-4dL$fIfdBZF*KhybzdV~V zbUCRvZ-rC-=Cri5O1X2tD{{gA*f_B5wAazt!Nh)}su8Wg@jLXFwY5U@aHdjqR@VhJ#lGD z!lF>k%}ea?cb{Lk+0Qh4SBpnYuA;5CkiLF({ViD72F@BplxS6) zK2nnR;EhjTDv$5sJO4P-=cwIW#_P)3g!ibgczDo#XlFEu$qmSI-YaC7z{FUv2L0>o zt3Jv%ZwkP{jr-I;1`GopXK3sv*_#kslNabnatzThidb!*n7h5hBcm-{G{sWYbw;rq zD%&>hqFc^|-uPwGu!;WE=511mRS#0G-A8nN>|X`TzZFm_fPgYB(apnG`|}lzR{eCv zGhy()p^Su;#i0Y)CfEJM-Cr}3o&Dt=bS|6`YQ<_fhic89MdHROI!J{Y{CV!%#3=`} z^H2Ky02Dd)ZL#_vUV|xYy;(nBew76Q0)5RT@6{k-)s6(u5{i`Xvo3P%^1UdYkFS5^ zsnkK{8b;PfW!q$?A|bv`r)P(9Y^A(a%*(qiCkVLZ`(Y8#PNqVeYqLdUwDVm%sV-6h zW@y^6z}suW^5^V(KfR_{V=JvcLJ(qC-Xv=`O0va}k8mO+1oPPfmUa@e2M4*a_W+g^ za2_5ti<1DOq}bQgXRxI$UcF92jP*SGUo_)TJwCD8IkJ9PHypf6NBTjnichUPKA1gb zwXs@Zr-+p^a6bzWEqtks;UtGXFOh8u8^KTNUaVA?ALsJt*7bP?T7J#{dl<;{URhh0 zfLq_Z%I(#ohoVM;~aPlR~=|C5}f*XQwx(W)rpWS)sZdq z*IJ=bn2D7~6&eE0@|ot{i6tvI$dJD!Ng)!&F`|rGn~X6lk0js?UmVSJx(64oBm-8BH1cBFzhn9^LYlI;;}|9T-~T5MA-1ndjh4B4b|ru)nVnb$F#;K#x6@AOWb{^WM*#YVGO zduDBx>}KWkPQSl2+UY|4ir?xtUV_Gnh|FQ1FBi%5+n3EyRgs97Z6-u(W5W*%#wK z27Qx(Om<)x{vMW)tG4aqMH+|LS3bF^X@8&q9dtg}2NU$i`&TRr?g_Ck?M6aL0F*ct z`5-RHWXd<~?3RVPB*!?yXKgxF+l(5O(?~fysTF>P;Z9DE7e)fk?PyCr4K$S#L;xql zzt6^(SPiuwlia6;O0OHcvWRH#ZvI-zWD>o*a;_;|PLM%W4ErNhowO>k7pYncRbR{i zwpzY{82_fQb+9A9=Sd~td+wm4A`#hUv0!J!Imp)2Liky+1X1$3cNFF*dJW@AL)E(H9 zTU7K!UGI(KiL;r}(!PR$bD98B_N3S>vRw|^+0?@gbghVmbrhP?&y}>Te!5yh>flzh zA!5fZNrdAzbhrIEVzUme>tjYw*Y#MG@mer#hcvpft$8Fhm+vA`PDHkH1x?dILF2oJ zv`FyIBC#*78#>JD4a(+8u4Mu;TYCFR{KRn4fLtX94sI>gtE22iB0{@cUHvhLP-3Xm zmhmzK;}I`)`luf$ppk3@53Z;lkq=GQ)POa%DZ5WtO9AE|$MAf%HHGG^`RCFM1^DaG zZ+}h_^k}J*Z9Mz$@NRp#TqP9yoIN^90Sb~LMdG znZn6S+cT-;nUeeRQL}>=VlyKYPhEKNlZwFX=l(gPQJ;19P-1Of0ZAYyz%Y2G*^0QOSSJ*FqF03kpBzx(O4w=gV7|Fpgs0BRSEX#iGFJng91nI>#- z)U!#l3PlF6al^w6FT^PNTEyh<)oT2PtdY~U(KNhpc?B>*PdRIH-<-0Ns8cqQsxZPH ze!2p2Voe+7K8xjj>CQ%e=iGU``;a3v*VL=S&{~MZ^O=|2KGIai@zM9F zp#WkfH~z(fVxDXWdD>z=l{0k8wFBGD)ldC!&b*$m%G>Zt4!uzb7jdlWpT*U1U}WH^ zkMKS{53>&(QPWXjHrGk+1KsGu^LSI-f>F1#fB2d*bPa*~4i{Hk!kF2OqrcBQy49XG z4+$sV)acy|=?qo~ZKa&7FzTo_iuklP;|@ez;B}Id_{e19_+06O<8*KMJe3HgCq0mwIgYDW@IY&!k z@*j%H5<3EIi}9rgy@G^vT5!Lz`GQV6B-s7NV|XG~(Csa`SXso+_X7~gz&z{lzCUo< zmpfbl+BY_3p9$k$cK|O$6Mc|E@JYq!OC1j%?p>z>JVfyy`^lHr_eLJU)_P;Ei^X;J z1aRzZCPp;+>@4efEwXgL+p1>|R*0oMFWA2&nlgEZJ2_?S8+wIOyZSq^EYj&*F z&N_!F{~q(ed1N@?u1yq78RMSscb5(~d)q=0>P4-05uhUlf|>6Ns}?gz_e-S^5(Y$r zFg+DcuNS`po}cV6grf|`I?Cp1g>GKVZ$+|yk^1*e2cbt+*71=m0wjOgT)d=q?O9`f zdw29}n9w~|wy7%8s_09WD>2Yu_;Do(pk)TYzJ}vJrYrmS&)1Fvx!0P!`%Hv8V_lH= zfa9J&$Ef7xlfS8r5i3!Y02e{oBPh8RspStdXpC0$sB1r1Gwj0&61oCGR>j(-{kDE*Mg0c9Fpsf zb_q1Y!FryET4^f-Bzr#?NW1Vk8I=KI`O5!BCX=ZFpXbHtnvXqL#Wv^Ctkm~eD?sqQ z8f~&XOqh8&ByM-<#GOXng3#!};{?01zZJp35s4AAhjTX1Qwyg-&ITU%sElXH-gn~? za*E>r{V+#Bb|kLr4b!M?=X_A=w-$hj+E7cd=cRop@zeZZ5SiPaRKQ!K>dI(U)b3Zz z!yB=4FXBD^?$w>Q;})G%u|%N#d|M}*d76lF*8cWK%m?nhnT_lHI{ZlSOu_5rWbpV{ zyRYKM(eyc2-}K=At3Ri2rc4We4#{kJDT-AhxeWb#*L&6RWloL@;dF7;+Wt)~$2%)4 zB|ZNMlw10&!OR*o5AAb4#(c}#rHOAz`5v*&p1v_ElzPE+UFz`sp4}M0+#!o3yA3ev zvtQcw4~Sx4@IpqvN!~pX)|I%9-7*UTulWmtisZcj>jLCL+e^|rcGBG(^nomc%<}8=Y@701pTkr z7D5cxjznP7iCTia+;oSVA7C>bKV2yHAn3wOEv5zL7NpkMw?5QalXOYj!s^{%we#+N zrAO`lemedaFFY`pl+ffsUPmEb`X&)}h0lT%@?OSik|>d=*MGJ_S8G^jnKfIK_z?Je zn0u~zI?lx0wr zD+FmRiqQ1*;(tvDAWyj1^(HDiPSF?g?)9buM|s|9eQaZ%l1(l~rdfUBsHO*Ez`Kol z@VuLk(j`KcaXW#c+?}it$!y&4Kw(U+c~)6lRU44Z--l<92I=?h#{_gu299N~)7l4n z=8Vi95? zCt^V}51Sdh)AmLvb?WjwY?tN9aoV@r&Z~r-xiP}o{syE}M|YoDK*tFzvyvpNTwW#i zP&0qMASSp#KwZ#>_67W3{?uS0&x5YF>p{aKc6VNl7Cr54b_n|x1L1hhs3h_6T(XlX zYo|(`fl=yYQ{_=Q2Ml8=+2D6^hZH0D3SEQSawQ@u@-OQ0X=(>~KKT9V8f60Dc>Qp< z=dU|f64$@dB%Kb%Pg87}{*elW)uEb-1^Q*{+_>m(f<&F3jC0P_sqVnB=mF;A`b_s7{?zrA)f6DKhA$JQN})M7w8ud z1>s$*x<|!Jm0ldj^T8h9@wsZcmV|V-yub)D*7h(y;#Wd2D~gE}JOfSnZqAguWb@S% z#cdu^W-{~mfkjKV9E;}*#qHHM+J6w#Ml)NOyNENthVz5MS4ZI%Ihh5l5OOFd$F#9H zN?`M4V{7x|!&@)s7P`^fp33q@(z@MxqSr+GbP5w4j^UnWTWiJeGPCW9PK<#Fd!oW`)BS47bxaX=DuFBRFz~` zhzYfL=^kQ|H*33W$Q`kj;S2G3BiOK(J<}pWw+huxT0ZrU!33@Y9Gb8lwR!l!X%iNqf_cb`3 z9h-?pr8ATK`EC~9FsGRnr1SEdYWj!aQ3XCFRZ)iSh1K~#2Y=rAY z@`9!~2E{*Dri7fdbzLQbW<7lx@57w^Stf7)H9b7^pLl8nM=J36);h&wVPz)o$0ix`q2N>Lc~|qe>E=MF4f*FJsTcEy3q{*ug%s{ z>vG1xH*IYwCy{V=fpSzY$#)i6J7m}!yyYmY#Pv@#F2Pl6dt^=H7KUE2hSGja`YLix zty^E*xAaDsUFU2I1TIJPoM%i=o3vmSCd@)I0&Z-hz9sBeG-ZRRNgr8s(~KB)^Wx;B zCyY6)m#MRRO!YDV-uNn8*?bZZZ(Oa6Hw!}bVP=azS3*Kj`KO~A>pjegZC_TzqnmUT z11{P%CMf`;MH&?wDYA%>CYoZ}{lW8m#fEaL>BD0R6Nyrc_>o6=Q#@KM(~fA`=mh-NMEoOZIo|DDPQBE&ZjLYe z@cYtZzn5X>g(e$X$1E>$>sw|wZvm|JC>msIjrx&rs*GqRT?(cJk+0;xdwMLhEB`5Z zv~cI|+(2&Ay=5Uw-o}b1e&P6DQ}*MDHi@+NNf26iA%v zElCZy^&6*MeUUiko3h)y;+Teqf#d5wf{z1k*;LFvWu^kU<+OCj!}1HL0Ki_mDxS*E zv#WOf55u-S%5_@UFwwuZK>u6rrk7dZ+aim*ES~?S2bfnPU%$$E zfQ-dz&k$o`jNQ0jKYC!0m;-a_@24vzc2@JDn}0Y}lJUsvIE{n9*SQZnlU(vyMo;CH zfFbggz{xta^y-`!iwq!Ubpze@%e0ERM!ZaB+MPH4Z5OCKk)QvV!o-IA^e_HsA=yF! zKU-}J%!PW=VePiE1Nx&IHs3x`<`?)G>J+B{h08!w0rLNOOdp9+9>mvwc}&#AcTW|@ zY+V8efs?>O6zg0iFcC#NOoU6sgN=B`N)+=j5a|DRMo;|AOgtEf2Mh6v|E{@4l>S^N zTp`d9e@jVVBwQw5fh7K(p7<>T;d_1OSUyNzZ#eRR{664qo{(4n%$!F*w7TGbY5CWHW&NR z4Hq)hMwoMgP^SR&Ku<1`Iy03;8$A%E8#wi9QV{UT%)T4joWj{u{}k;JDX3#Xa{G0!m*}k>rF6f7+96R`^O?jTpn+J1%%ltDo#K z(msCOvpTGfK4xbo*^KUQ*X-+~u^D}nph>2Qfgj(^gQ9K*IbK_X8$h5L0Me9y@CI=K zTT3kx^l)8UNScGKvD|w*wk>%PmSI;0wh#S3&j6JDgb*5HmRT(M+ZYpFpmOXFxEx9+~o(tbCfZYgXL z5oOo;iJ`ND4vuD06H|b(g6qU>gd34zMXauacg0e=V(zuQDp|>DV0VKQqC_ut zh&0G1c*HQvU}2PpcCrdN6k`b&TX)=4ygf40a`0_?&v@(kyVNHfsYHoT@bneO3sxv_ zD?bezU%VccN9(Fm=Qt(9kNJhauhMBWEt)jhwpC3yJ24&w5=NpNW|HL36MhY@^A`yN z@U^Mo{75poi{acP^N5tF4|?_mL{8f55YhN?$|o| z`%S!a7!<3m4UE49qDyzXVSc_ z=1DkNLp7m9vY)CS*Ld?)N@x0})FzK*?W3Av`r3x9u@3n;WAs~_e#{1Z)p zXH<;#^KY?$l_O1Djwf_#zjQe44p4A#mCgPLR7`UFSBxVqAOiQt9k&PW9_!v z$Gy3|B!O$5$dm`>G#gpRcsS6YTbSwdA%%Gh7L@;4V@sC7yitosJyxMdSWAX-C#rr} z+JJxU^1V$7qtx6{Eo1KrkL&JC5XtiWe#|b)aJh14CCnzOwXq%o>HEo-YrmqQcVcd8 z8tfen#fDY_NECv2=ZIKS;9)b6h-7t}X2d+K2}{sF=Ktt9;X00qMxOjaS->iM&C^8# zm6WstHOa5-xEtO2YieLDw79;$KHutkba-ZS@nP`o9$x!yW<_oA)>2x{5>D>)4^US!cpt%xn}eFmPiP&mIiJ zu)bp=k>V7Og|~F{WUD2a##) z&Q(Dbxwi5mDsXcW0};S-?+k{gl8yoYB)5xjTKNYjPF`0}-1*d`pvYicsmau#54|SQ zl*;hP@YktQy1T-#_|r+>NQ<7(0=k>eNdnRq@EtLg)6tI^SSYj*o&y8r>1oq@`VNNj zt}Zl1(+R)NjvQ@K4vkhFCBhYp3)XKCQJI6PlD<0!OAQAmUx3t7gI600x{;ci>&QC{ z7|v(Tj`xKxm#)1hgpq)*jX8lU0$<r@f~zEJu)NE9iWl#_H3_esP=sWkvfOSGN?Mr$Hl>Tjbz?%4fd z)EO7q`&3N!%xi{5-*TaNM4bQ50%gYcce|qL^67S%{%Y_j4*4W$+ko{futb|Zu!LKA`+I5b z)m5GCQY&~6Y*RelY2Of8Mm>?|n6zAu7+xT5f}4|RbG z>Xlsa+Z;nln)Lk|*Iuh76XaB*M)KFeH@9V!; z7%*$Da0xA+1rzd`OBwC7p+>)0fU{<7IfM)Y{PPdC!n+4CmW4aa$@vl1EN203?+)#z z4yFFEYNCH zxFP=`bBI43HJ9bMcUmo_73AUMD|3xdP?Sx9f%c$e6V4qAaK9YIOwQ-e_5o+t<$sT0 z0y~lNKBqXAx#gpUM${w~%xQ1jG6B3hi5>|N(FQWv>CVmPupUO-LXYI~eDi15@Mm$i zJv7^%k#Sc)3aW2@bz~3io-)KQ|TVIT~s{F=Ur5XRp z`Odvzn%L)Es>!803|Zr378a2>wjc6md!@rt?@zW!QUCbGIh^`h&V40O@;#OmK4cvg z=$;u_1jgGa`5%ESr}Zp#&JGF^6Xnvw++``?Q>K!h(1E14K7akGH6@jIOsC_%3_|da zzYo-Unt=!MSG2J}0^+mW`Vs%(gI_R)dsO-QW6^cIkxs##A3_#dkpa9Ek1-4@k6n)6 zMAbM>J`-oc+b8?i2h7DzBaRJVhB%IV3~9}BH8KF}1KIZjCK)a8piVa$#1$9~kZYXJW zTaWFNrKeCEPKnIB-+C1D))8U@hcG1xrcP4mgf{NJqF%U zWFj)a2u3WD4VY60bJ7S*20)E!54NaZlWalTEW}VgUw#IMCdXgdO!Zzo~ClG>z2?Q`8*PDY_NMDtwwXp-(>d?;>qg5SuWdc z{iD6RHM!iHUnQCHcUVM?0z^o&3y(U8{_3$ap#-q<4xuDOJaPF{!kBOh5jZ;Yt!!UG zfzwK7sl)4&MM}0i=Uf-JL^My5YWM`vZ$!aC8M{0wrJJg)OSsSI6`0c*%`%`uEUw-2 zF4u@Hg{69GgPoU$qSov3cPe!O1|-3pP2*4411WA?Nw^>Q2BE0PWM^MLMXDz?c{AMp zW|!yH&s0;qe~wr-)`A20^EE>#unnzzbzsMtb$+jl%~ezj5iOMcvBeF808V{=mfYd7r}b;@-i_CM#YS?u5zYpFA;LS#mx01v?}h0;e)oe^K@igG=!o{W z14s6#y><h`vD_k`uJEe5}27Pd)95BKaMqf?qek zoL}XNyyn{QNic-@sPt_(n_xkBLG1BKZK=f;vlG}cGGW!kz@4Za3}=300-Budk*3+i zsn*UJxg6j_b|bEI%5K5)lxf+1wXmBZF=k!-n}A7H5@mKNzow0~!4O9uw#Q9_2x zPDGc@3?)_vjQ?u(WOR4QTIwO&4Ediq`VN2^BYyCXq)tmKMn zXAaC2el!tC4I4Afw8R<4`|L?Kc~6SG`1mJa_I`xi%1ne$-7OG;!~4@D6olCre!5K=~N z_tc4m$z!3Fe6vV1=ugXk48z&X_n3=}w0xOUZanLp^xdx{c`@6unW()+dwt;Mo%>&W z4&#Y&WP*wzRy8fxy@(=h?BDBlF=`7|l4gLKlSKiNmUM7Pmydj07o&Z~pZrvQ*!|M4 z^OZ03+8;|#2i{3I;c-OfGK6u`;v;3eFuhHxjdqA>DRIp%Mb{BLp1*f_Tf%iN+pG4~ za6HCx-5DQ6AQPQXg@7NEmvJn$<$e1XbKkEK1Rb>W!y0ri(z1G6HWO+g2&vkN_#FBE zLns^QQne=^M;E{ZRwI>ungK8Fl=u_yeM+9waR~9iEIx6t9V%Oy6k_HQR`ts)@IT|% z)6~;2;=Yl%LAxrQvi#E3M^>|cC4z`;Fsw2`borrJae#r5lvy)R(bRys4nQ20H99|% zrJJ_b94&@VEI(_|_Q~6hsx-a~xh}Wj6C~++eXAj@m>27#n9{hI@$h|USA===bwESL zVcb~t@U!Ria7aRRuEXQw9}X$yTIt??ZyU~cQ=UFeJ#8J`>{$sz%haa(|2uw3lu~79 z%!t3o5zScDF7Vy|Zo_~;vb?-8Gj)vYk+FX>I|O9Z&X2pkK!Ec@K66KAW@h?(mDd6S zWvWM9>o;XFfBz2l9!0k}T|D`>==s>OUdgGqk=F0m`c>g5@CQa-D13hAaZQ4(`vL}l z$vvvAu}DL$RoTQnN%Dr}Xf9ZVpu3e)^}J2x#wYq4hC^TdNFEZGB$yy4a4ezb1ZgZ_OZ0vsTKicv}< z!n+!Q5s_lGTe{92P#0>adV1LX0PMGd(0iqp0oZ7gSihTr|8(MnX@Qj-F+Plvbr0C_ z!yqQod-0`zAt8+r|D*%|l0N;>uT!hO%iMWC zx-U}rQ~1D&TNu@ousb`m=^VdBz()z$k5>H-g<8=6Rwqf!o#*5MA2j&+y9R%{pZDRb zd}PZSJmuJPXV!nBtdb|&(+G?2k=k{>yO!(2pHN;B+e-sS6Lx=C=3_rb;^d6{~bPJr(1GE%uDN;GP4}<)p{v3XMp`>$?hkydfvoWc~GF z*4>#_r+FI@dA{qbE92(B`(Q&0Kn)kFHvJZwVXU{3#_`Dopns3nl8iMxo0aw_R02OODohCqwl za+`(YW??3>bYB)pU9ELAf@RHc#aexV+wW7{+qQeSe1Gz`Evqdgkry zazbv?`fUh?!0~O+8$(UvasKn|Gsd?9Ro4nO?l}GOm(=K6M?CSg{Qb%J->JpK+j8O*@ZPWyY?RvE@}{A8ak9C$6viY?HvX2XaMyHV2_ZrsxXacKWH(Zs(2VA*<1 zcX#l(9%X76=-g%mx|me6CjS`f$|nO*@K#y_y}dn?plE8)L;~QL_obRn3$BKAR);^i zvk6_;5j!u|$mStW^QucEw4WRT*l3|Fa7e>>K~6N$mcEq4-n8x-<~m?8N{Tq7j=
  • W_eO@b4Zr#4y}T=C86YD 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 w!j0W>hK;{W_P8udf~80e?5c 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 E0I%fCYybcN literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/sound/griffin_2.ogg b/tff_modular/modules/bloodsucker/sound/griffin_2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..4ae4de2595f4bd827acef6194fcb571287f8be5c GIT binary patch literal 4352 zcmd5ogM5sz280Op6`D5pF7`VvS!Vi z-(G9YTC>*xg zz&#)&pwJlO`K>D`TX#Wp48X-Q3EN8;KhRIw3MB5^OJWM?C#y1SDAaQT>#!QKrZlPU zax*>yyEJSk!MKEx&*0g{7N8V1khWTAlybf;(iVvw|)! zZK)t9b-#N8lq(fj9p6uwr^>ER`6VGJuZvuL{Il&iC?{*0@=Np_hCG`l1v%062BcO_ zPSNdh9dd_SyC-X*?}Urc$2c(M!B|%cBn+bd4A9cu%`s$8NQ#Z?XyuZXSw=t-q`-O|twUl2_k6Oea*q zQzq#BCx*vkY8zMJw;e^!c2Jb2_7X0X8|d8$7ty@%=@Iw`2>;%@1wH{1e;VvfL47|4 zg)C+b6>*}5xnnc@=p~27WQYJMd(r;?gK;Z^8}sc@(Tz!r@r=bZCi`4iMaN1C*f zRyN6&?@v_3A3-h{=tX={5wtnW9upLg3G&Be`6{}c8!1;LDxJ@&bZX_l>aO|#F94wb zv|Z0>I~d?JNMQ8dg}Gn=QY^X)V9>*e|6pUt8|YBZfbky>001|~YYbw5fJBop1Dlz_ z&CI~XtPs|}Y8!$FNx{&ut6|oGj+ngfC-DxeS5H2`c4E(zxvz0(-s50&y6}Pfg2l(n zJmeOs4=5AZe8*b1Z}Y(%YDjDkWbc@ z3mGojQsEBzbsU^lmkJo(PDO$pbf*d!AHW3u7FP5ZEXMej0tLvRZ34(T@55Pwi48Wpm}r2NrY zPL$1|P!@lT$r;_q(#&v1X42ThqS)6ytY3l#MVkkO+#wM^O2pyJ28Bt3HAUP(5r4FZ z%lVu;GP_|=$QfjDM}(Y_L)`F79QI7wpeXZU5qEDmmyJ8bnazyS6io^_W8vKJjl1A# zlqPe0SQK626T*VXoVz4WxQMeioTC}uFepKhN0=P;A&ATg9~Rvup~$12oNy_M94-}& z3865T{gxFzBVucc#)tXi8#$U;7JDWWuA<17MI77~)-P#chcd^7+=rUXhwK9!FX@0N zExL$59>Hak|1=&U9h)uULZ}G-2yPeKCTs88bCWY^6JLlpwg<+vx705zx?fbz^$rg4 zV@uM;*!%Z>o$*7Crpi_7<`6h_8SVU5*Y@-KwnpOl z>35xpeVvW>TipNLc7WKPV%L|X>vh+)g|>*k-1~+3wV#C|&f)!>?irDABEaiUz3^x; z=+S=M>s#Tl)JmkQOqnE8)a57$eTu|h6;Gy`R;&0|l*yxVo_?AvQxLDHYDbmRPt}!dMa|(d zUSb)9(hDnV50@n#DN8`goDn1uLFy5N7zI~lPihoSIgq2Mmmw~F3go_uhqNRk2>%K) z{Z7T#si7u(M6vEHl87R!h@kZVap;|YpdeNt< zo6{SJs)4xnsrbt-CeNu8WFNG08C9*DQ$wv@^ePY5B6T`+`uv?TMW=SVs!EfWi> zj;aspJVs~I{9y=&ZQzf>Jb@uN!-cE?5R zN4Idtq3|Vc)Qm_|B-*Pj zwHLg%?v)e1^+KZsBW40{d?Et+Q=WKV6-z6FUadh|o>8URlX4zBsVK-%)F4WoPBzcc zJ%#?!bJS{AnY;!;bZV6n9txsddqp*^g9M`MRTAeq5w&tHbg8bh5pIV^FxqnP&+v9{ zdokB}x?ZPtec$PB5r6@Y%q)Sgv1eU=3WH=5k#Lg^@P-rIVt?r}PI+NnI0jv{r$W}rn`p(tAc>nuA{bvjRa7WGm1oaPh{IB5u9|#xyb65Re z>@x=iIVqsv$nTL!g+Z1ZN+)!c9>=;*;bQw~&V-m-Z6IRb?;&kqTZM`|!7_5mTKLeFndsEifr(CqSjq*Q0L_z( z0{tp1oCKEM`eNH;Ijp#0#-OQ`fu%dc0j_3Xz0pBWp#y`ipPE%jb^@^Pm?7{LFREQt zYMp0ngC-{|LBw{_a>ktuzkI*17y0#uu3tn6A`g_r>_}X{IIMt-JtwrXP4pYt-%Vafnlv^ydo5FM$`e*oqg5q-Ol~%E<;qLw$921Hu z1^ZQmoiE1B%WFK#>A}m4Wu@g|%%^y?vH}+15lpLcuyUoWwz0M2X8*lMPhP?j5jGp} z767j;;_U1x7ow}12g%dR+vjiJX=1ThFXanIu~`2lX0*j#&jRR|7%JG+MF?87(!t&y zevr1iXt!Z&{_toxaE8^e2#4xpa)Gd;TdV`>ii*qi^((lLyj8{D1z8QE= z8Yny+$Mt(`7@)Btt$3Q@7W0;N_vfPr>AO80Ei)Rr+CE}(1FM#Jsq4X}pS-UI{dW9J z59?U@9^LbTlQa#dejB*&^Y9YoCHU#mucO%J{`ACP`O;rgQ*)0>CR>#kgWk4+6mz*z zPrhtV-8HjkM_}YG)lV+6TusTf?F(-gKdX02P*n(fGH1W8eB1H;)uQU_ zZpVrhgW{10w+u^1GvhsWdq45*KURGAt#ji2t?jSB+gkH0{oddmvq$w7Aa`|~@3c!x zr~Tt)57$?3+4RZJCca0VZ+cc+L@wCVc`3O8Ghx)RVr1Flf(Lc`hqFxnk|uS#IF4`s z=qt{f->UMA?zN49Vsns=10DB&^Y8f8H|EtZjipS-WaILO%O6>{?OqYUGs9P0^fXSt z!W^HYKe=}~Y5f;Npz-cAGx<>e+^64cKA5`f(59a@{}qdTzR0YAeCDFZbP(r7p6(-? zx))!Mg>wvA4|fzBma1nqG=6+!Vao0y@jGMR&Lu|TGya(AI2rMkGn~RS>liqb*rzs|Of38@+Hng_6;cDW8Pa78-HrVTK zH0){6o$Zc%l|;YXax}0f@KqGOp?3D>kypC pGLCJ%=l>tRhofFb|9H-X)$f#PWt4uRzua(5Zs%W2j4drK{}W*LbAtc? literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/sound/griffin_3.ogg b/tff_modular/modules/bloodsucker/sound/griffin_3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..28b65b852a675bdf8dcf5882bab6730f5d9f77db GIT binary patch literal 4912 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 literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/sound/griffin_4.ogg b/tff_modular/modules/bloodsucker/sound/griffin_4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..2d6612c7c00eb6efb3a20e66c8698ccab8a551ae GIT binary patch literal 5274 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 literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/sound/griffin_5.ogg b/tff_modular/modules/bloodsucker/sound/griffin_5.ogg new file mode 100644 index 0000000000000000000000000000000000000000..61258463922015119de35a9c517eb62161e8f1fe GIT binary patch literal 5512 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 literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/sound/griffin_6.ogg b/tff_modular/modules/bloodsucker/sound/griffin_6.ogg new file mode 100644 index 0000000000000000000000000000000000000000..43520cddf2a753ada7d4ff6840b7e0d1aa6b28c1 GIT binary patch literal 5895 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 R?MQ;rgBiu~Sao&vzX8*!NFx9M literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/sound/griffin_7.ogg b/tff_modular/modules/bloodsucker/sound/griffin_7.ogg new file mode 100644 index 0000000000000000000000000000000000000000..b3ce436e4e562fb0749990cb585a1eda133fae85 GIT binary patch literal 6307 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 MSB3)kfw1s@04lzr6aWAK literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/sound/griffin_9.ogg b/tff_modular/modules/bloodsucker/sound/griffin_9.ogg new file mode 100644 index 0000000000000000000000000000000000000000..806c67de2f436820b9365322ca066175bd2f4b87 GIT binary patch literal 6913 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

    8|UMo*98JZ(xkh=rgE0w`c$G3q^Zd!JMY)^pKc_ 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 z�{(Zn&cUisXI+<*0|$cCX3Xkr{J0P5yF_1o2dv*xVKG`jPcMFSX$Dlv#?x*DZl? zhwqu4xcnSl+$^0)o7CGXL+JF|kHI~xuet&Jq%(^DyaYZ07U_BS&6uF2eYWP@5*$pF zIyEJEM5ljN;g+vJ0BCW|ulH51>=AC^+#KdM%-V1C6)WbpPg5*23-69FoG9mO zN;jvu-6N_Qdeg{UD4?wK?anh(2s$(l1% ziFAhXiv6WO(8kOy3Cixq=L0qVzP(%5_+wL&Uzcg%ux>nyDm&q?>1Q>yY6873EURAo z zlsV(vguVbJVa@SvgckQ_bB^dclH5e$Z2vS~C{@kTN7dzKH4?t+4>5`808{?iT%%#^3u-9J8g51@Nl&!q-yNO#1zFS z;_MF_L1j9+GUxp};AaG@`$Bzx z!7N0#8z&#QSU~jd{kc+Sl@BAB{3+rCm?Z0?LenvstvGC&tKHo@eH`nfWw)qs5`GAW zd(UT~sbJ&2z6g!ER2Q-u+4Svz+cU_DetLVn%(A+Lfu2;~AhZ%#Itl|lX$#CJU5Rq1 znIJ?=mY1Umgi;Z#`g1)I!zdqu$@jCkY44`NkU6o<%0M1~>agEnhWdr^H6urEM ztL!8sl00_8bjyzaTHqXLu3)4d|7jynKEeUL*L3acu)NsJLt#2fJKg(cN0RXaG~9t# zT|o#GLj9MmJn2pF#1K@*O&Zz|`5gS@+Ns-?JSIR(6OSyNrZ!HP13|1*;Xg(JNVOA} zH^M|yzTU0D4!k{=T9}zjL2)kxd*y3c0RNC55GgFZ`7UWZkbjWrYZg4iAFpHM06??) z-GKSIaAtG@rC+aHa1QyLS#&$G-E*wA&(02cm(*eJahN)8Pu(H};(K<_9m-c*=X}iT zbN2TOOTQ_=NPS?`S#r7cy{v|y*^tnv?!yd0QcZ9=q$TXi4Zv^%VmDR&z0QRQ0II#y z>Hy1SF>1*ZY>un~^KXl6n-9GIE%BN~0kC1*($Tq`Ca0c}sgCZNNk5B<#uTuug1J#(XXvLH9*SL#(YLi{^CVa`e0>k6@c5)eb2oK8>lB zkB-!vEf*U|{FKNk1^Lac2?sj}+YD-)a%3$)O$&?@9tlI}Y+>U&Yl0&JZU)4J|DCpi zoMI+k;c{OE&#jr)cHD{3F+Vu5s%C%;vHAO)!+T(|d&vnC&=lf>X*n-?HdK&8gFJ+i zz8ss@#QY5vVtUy&gU94jugo}zRJLu66R7cW{ADFePqLg!VzdL5;b{G5@IhcbS9zaS z0h6&h##dCtJNSzlrw>IecW!npmac6aJzZ@rMLOcyU`}wWEwfgK%(SzuQcxZlnb5uB zWAR*BEFgQC4ETL+@ZfNCtaQ)FfnBr~-@8&hv~jAB=zZNQXVHVoJG3XTKVzoA*$;0d zl^WdaJ~-4>QQYKR`RG3rQ}LWC&#kt@;TqlC-muqq&!W*~XnCZEh&f?>^u+(3{kxyK%~&xft%12W=0Y3ACdC$VWQcE zT^^_p^+Nl-y}hk}R>~;`YOa-0+e5dBv7BGRSYsL8Mjl> b?;5-d&U@1Az5q(w5Pjm?o(>#CzYO_5@T>9{ literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/sound/owl_1.ogg b/tff_modular/modules/bloodsucker/sound/owl_1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..3d41497d44b43341c3b910f56181c84b16c3217e GIT binary patch literal 4208 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 literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/sound/owl_10.ogg b/tff_modular/modules/bloodsucker/sound/owl_10.ogg new file mode 100644 index 0000000000000000000000000000000000000000..97f45d433788668ddd603260a53c8b054e84aaea GIT binary patch literal 7811 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 literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/sound/owl_3.ogg b/tff_modular/modules/bloodsucker/sound/owl_3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..7c8524e933df8d0cc520d842d4b5f5deb555072b GIT binary patch literal 5030 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 CE3usb literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/sound/owl_5.ogg b/tff_modular/modules/bloodsucker/sound/owl_5.ogg new file mode 100644 index 0000000000000000000000000000000000000000..1210b05ac39a053c7d653d7051964a8a8d959a58 GIT binary patch literal 5796 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 literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/sound/owl_7.ogg b/tff_modular/modules/bloodsucker/sound/owl_7.ogg new file mode 100644 index 0000000000000000000000000000000000000000..fc330687a1104dd83a68729c78bf354741596372 GIT binary patch literal 6591 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 LszUr|XXX7DkK`_B literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/structures/coffin.dm b/tff_modular/modules/bloodsucker/structures/coffin.dm new file mode 100644 index 00000000000..df9b4e01fa6 --- /dev/null +++ b/tff_modular/modules/bloodsucker/structures/coffin.dm @@ -0,0 +1,348 @@ +/datum/antagonist/bloodsucker/proc/can_claim_coffin(obj/structure/closet/crate/claimed, area/current_area) + if(coffin) + return FALSE + // ALREADY CLAIMED + if(claimed.resident) + if(claimed.resident != owner.current) + claimed.balloon_alert(owner.current, "already claimed by another!") + return FALSE + if(!(GLOB.the_station_areas.Find(current_area.type))) + claimed.balloon_alert(owner.current, "not part of station!") + return + return TRUE + +/datum/antagonist/bloodsucker/proc/claim_coffin(obj/structure/closet/crate/claimed, area/current_area) + if(!can_claim_coffin(claimed, current_area)) + return FALSE + // This is my Haven + coffin = claimed + bloodsucker_haven_area = current_area + to_chat(owner, span_userdanger("You have claimed the [claimed] as your place of immortal rest! Your haven is now [bloodsucker_haven_area].")) + to_chat(owner, span_announce("Bloodsucker Tip: Find new haven recipes in the Structures tab of the Crafting Menu, including the Persuasion Rack for converting crew into Ghouls.")) + return TRUE + +/// From crate.dm +/obj/structure/closet/crate + breakout_time = 20 SECONDS + ///The resident (owner) of this crate/coffin. + var/mob/living/resident + ///The time it takes to pry this open with a crowbar. + var/pry_lid_timer = 25 SECONDS + +/obj/structure/closet/crate/coffin/examine(mob/user) + . = ..() + if(user == resident) + . += span_cult("This is your Claimed Coffin.") + . += span_cult("Rest in it while injured to enter Torpor. Entering it with unspent Ranks will allow you to spend one.") + . += span_cult("Going inside while it contains a heart will put it in your chest, letting you regain your might.") + . += span_cult("Alt-Click while inside the Coffin to Lock/Unlock. This also fixes the lock if it's broken.") + . += span_cult("Alt-Click while outside of your Coffin to Unclaim it, unwrenching it and all your other structures as a result.") + +/obj/structure/closet/crate/coffin/blackcoffin + name = "black coffin" + desc = "For those departed who are not so dear." + icon_state = "coffin" + icon = 'tff_modular/modules/bloodsucker/icons/vamp_obj.dmi' + open_sound = 'sound/machines/closet/wooden_closet_open.ogg' + close_sound = 'sound/machines/closet/wooden_closet_close.ogg' + breakout_time = 30 SECONDS + pry_lid_timer = 20 SECONDS + resistance_flags = NONE + material_drop = /obj/item/stack/sheet/iron + material_drop_amount = 2 + armor_type = /datum/armor/blackcoffin + custom_materials = list(/datum/material/wood = SHEET_MATERIAL_AMOUNT * 5, /datum/material/iron = SHEET_MATERIAL_AMOUNT) + +/datum/armor/blackcoffin + melee = 50 + bullet = 20 + laser = 30 + bomb = 50 + fire = 70 + acid = 60 + +/obj/structure/closet/crate/coffin/securecoffin + name = "secure coffin" + desc = "For those too scared of having their place of rest disturbed." + icon_state = "securecoffin" + base_icon_state = "securecoffin" + icon = 'tff_modular/modules/bloodsucker/icons/vamp_obj.dmi' + open_sound = 'sound/machines/closet/wooden_closet_open.ogg' + close_sound = 'sound/machines/closet/wooden_closet_close.ogg' + breakout_time = 35 SECONDS + pry_lid_timer = 35 SECONDS + resistance_flags = FIRE_PROOF | LAVA_PROOF | ACID_PROOF + material_drop = /obj/item/stack/sheet/iron + material_drop_amount = 2 + armor_type = /datum/armor/securecoffin + custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 5.5, /datum/material/alloy/plasteel = SHEET_MATERIAL_AMOUNT * 5) + +/datum/armor/securecoffin + melee = 35 + bullet = 20 + laser = 20 + bomb = 100 + fire = 100 + acid = 100 + +/obj/structure/closet/crate/coffin/meatcoffin + name = "meat coffin" + desc = "When you're ready to meat your maker, the steaks can never be too high." + icon_state = "meatcoffin" + base_icon_state = "meatcoffin" + icon = 'tff_modular/modules/bloodsucker/icons/vamp_obj.dmi' + resistance_flags = FIRE_PROOF + open_sound = 'sound/effects/footstep/slime1.ogg' + close_sound = 'sound/effects/footstep/slime1.ogg' + breakout_time = 25 SECONDS + pry_lid_timer = 20 SECONDS + material_drop = /obj/item/food/meat/slab/human + material_drop_amount = 3 + armor_type = /datum/armor/meatcoffin + custom_materials = list( + /datum/material/meat = SHEET_MATERIAL_AMOUNT * 20, + /datum/material/iron = SMALL_MATERIAL_AMOUNT * 1.5, + /datum/material/glass = SMALL_MATERIAL_AMOUNT * 1.5, + ) + +/datum/armor/meatcoffin + melee = 70 + bullet = 10 + laser = 10 + bomb = 70 + fire = 70 + acid = 60 + +/obj/structure/closet/crate/coffin/metalcoffin + name = "metal coffin" + desc = "A big metal sardine can inside of another big metal sardine can, in space." + icon_state = "metalcoffin" + base_icon_state = "metalcoffin" + icon = 'tff_modular/modules/bloodsucker/icons/vamp_obj.dmi' + resistance_flags = FIRE_PROOF | LAVA_PROOF + open_sound = 'sound/effects/pressureplate.ogg' + close_sound = 'sound/effects/pressureplate.ogg' + breakout_time = 25 SECONDS + pry_lid_timer = 30 SECONDS + material_drop = /obj/item/stack/sheet/iron + material_drop_amount = 5 + armor_type = /datum/armor/metalcoffin + custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 7) + +/datum/armor/metalcoffin + melee = 40 + bullet = 15 + laser = 50 + bomb = 10 + fire = 70 + acid = 60 + +////////////////////////////////////////////// + +/// NOTE: This can be any coffin that you are resting AND inside of. +/obj/structure/closet/crate/coffin/proc/claim_coffin(mob/living/claimant, area/current_area) + var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(claimant) + // Successfully claimed? + if(bloodsuckerdatum.claim_coffin(src, current_area)) + resident = claimant + anchored = TRUE + if(!(interaction_flags_click & ALLOW_RESTING)) + interaction_flags_click = interaction_flags_click | ALLOW_RESTING + START_PROCESSING(SSprocessing, src) + return TRUE + return FALSE + +/obj/structure/closet/crate/coffin/Destroy() + unclaim_coffin() + STOP_PROCESSING(SSprocessing, src) + return ..() + +/obj/structure/closet/crate/coffin/process() + . = ..() + if(!.) + return FALSE + var/list/turf/area_turfs = get_area_turfs(get_area(src)) + // Create Dirt etc. + var/turf/T_Dirty = pick(area_turfs) + if(T_Dirty && !T_Dirty.density) + // Default: Dirt + // STEP ONE: COBWEBS + // CHECK: Wall to North? + var/turf/check_N = get_step(T_Dirty, NORTH) + if(istype(check_N, /turf/closed/wall)) + // CHECK: Wall to West? + var/turf/check_W = get_step(T_Dirty, WEST) + if(istype(check_W, /turf/closed/wall)) + new /obj/effect/decal/cleanable/cobweb(T_Dirty) + // CHECK: Wall to East? + var/turf/check_E = get_step(T_Dirty, EAST) + if(istype(check_E, /turf/closed/wall)) + new /obj/effect/decal/cleanable/cobweb/cobweb2(T_Dirty) + new /obj/effect/decal/cleanable/dirt(T_Dirty) + +/obj/structure/closet/crate/proc/unclaim_coffin(manual = FALSE, silent = FALSE) + // Unanchor it (If it hasn't been broken, anyway) + anchored = FALSE + if(!resident || !resident.mind) + return + un_enlarge(resident) + // Unclaiming + var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(resident) + if(bloodsuckerdatum && bloodsuckerdatum.coffin == src) + bloodsuckerdatum.coffin = null + bloodsuckerdatum.bloodsucker_haven_area = null + for(var/obj/structure/bloodsucker/bloodsucker_structure in get_area(src)) + if(bloodsucker_structure.owner == resident) + bloodsucker_structure.unbolt() + if(!silent) + if(manual) + to_chat(resident, span_cult_italic("You have unclaimed your coffin! This also unclaims all your other Bloodsucker structures!")) + else + to_chat(resident, span_cult_italic("You sense that the link with your coffin and your sacred haven has been broken! You will need to seek another.")) + // Remove resident. Because this object isnt removed from the game immediately (GC?) we need to give them a way to see they don't have a home anymore. + resident = null + if(interaction_flags_click & ALLOW_RESTING) + interaction_flags_click = interaction_flags_click & ~ALLOW_RESTING + +/// You cannot lock in/out a coffin's owner. SORRY. +/obj/structure/closet/crate/coffin/can_open(mob/living/user) + if(!locked) + return ..() + if(user == resident) + if(welded) + welded = FALSE + update_icon() + locked = FALSE + return TRUE + playsound(get_turf(src), 'sound/machines/closet/wooden_closet_close.ogg', 20, 1) + to_chat(user, span_notice("[src] appears to be locked tight from the inside.")) + +/obj/structure/closet/crate/coffin/close(mob/living/user) + var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(user) + if(bloodsuckerdatum && user.mob_size > max_mob_size) + if(!HAS_TRAIT_FROM_ONLY(src, TRAIT_COFFIN_ENLARGED, "bloodsucker_coffin")) + if(prompt_coffin_claim(bloodsuckerdatum)) + enlarge(user) + else + user.balloon_alert(user, "already claimed by another!") + . = ..() + if(!.) + return FALSE + for(var/atom/thing as anything in contents) + SEND_SIGNAL(thing, COMSIG_ENTER_COFFIN, src, user) + return TRUE + +// /obj/structure/closet/crate/coffin/proc/is_claimable_coffin(datum/antagonist/bloodsucker/dracula, area/current_area) +// if(!dracula) +// return FALSE +// if(resident == dracula.owner.current) +// return TRUE +// if(!dracula.can_claim_coffin(src, current_area)) +// return FALSE +// if(!dracula.coffin && resident) +// return FALSE +// return TRUE + +/obj/structure/closet/crate/coffin/proc/prompt_coffin_claim(datum/antagonist/bloodsucker/dracula) + var/area/current_area = get_area(src) + switch(tgui_alert(dracula.owner.current, "Do you wish to claim this as your coffin? [current_area] will be your haven.", "Claim Haven", list("Yes", "No"))) + if("Yes") + return claim_coffin(dracula.owner.current, current_area) + return FALSE + +// some fatass bloodsucker is trying to fit in a too-small coffin, how about we make some room? +/obj/structure/closet/crate/proc/enlarge(mob/living/user) + ADD_TRAIT(src, TRAIT_COFFIN_ENLARGED, "bloodsucker_coffin") + max_mob_size = user.mob_size + to_chat(user, span_warning("The coffin creaks and squeaks as you try to squeeze into it. It's a tight fit but you manage it make it fit you.")) + animate(src, 1 SECONDS, FALSE, BOUNCE_EASING, transform = transform.Scale(user.mob_size * COFFIN_ENLARGE_MULT)) + +/obj/structure/closet/crate/proc/un_enlarge(mob/living/user) + if(!HAS_TRAIT_FROM_ONLY(src, TRAIT_COFFIN_ENLARGED, "bloodsucker_coffin")) + return + REMOVE_TRAIT(src, TRAIT_COFFIN_ENLARGED, "bloodsucker_coffin") + max_mob_size = initial(max_mob_size) + var/matrix/normal + // transform.Scale(user.mob_size * (COFFIN_ENLARGE_MULT + 1) + animate(src, 1 SECONDS, FALSE, transform = normal) + +/// You cannot weld or deconstruct an owned coffin. Only the owner can destroy their own coffin. +/obj/structure/closet/crate/coffin/wrench_act_secondary(mob/living/user, obj/item/tool) + if(resident && anchored) + to_chat(user, span_danger("The coffin won't come unanchored from the floor.[user == resident ? " You can Alt-Click to unclaim and unwrench your Coffin." : ""]")) + return TRUE + . = ..() + +/obj/structure/closet/crate/coffin/tool_interact(obj/item/weapon, mob/living/user) + if(locked && (weapon.tool_behaviour == TOOL_CROWBAR)) + var/pry_time = pry_lid_timer * weapon.toolspeed // Pry speed must be affected by the speed of the tool. + user.visible_message( + span_notice("[user] tries to pry the lid off of [src] with [weapon]."), + span_notice("You begin prying the lid off of [src] with [weapon]. This should take about [DisplayTimeText(pry_time)].") + ) + if(!do_after(user, pry_time, src)) + return TRUE + bust_open() + user.visible_message( + span_notice("[user] snaps the door of [src] wide open."), + span_notice("The door of [src] snaps open.") + ) + return TRUE + if(!resident) + . = ..() + if(user != resident) + if(istype(weapon, cutting_tool)) + to_chat(user, span_notice("This is a much more complex mechanical structure than you thought. You don't know where to begin cutting [src].")) + return TRUE + . = ..() + +/// Forces the coffin to get contents +/obj/structure/closet/proc/force_enter(mob/living/user) + SEND_SIGNAL(src, COMSIG_CLOSET_PRE_CLOSE, user) + take_contents() + var/inserted = insert(user) + playsound(loc, close_sound, close_sound_volume, TRUE, -3) + opened = FALSE + set_density(TRUE) + animate_door(TRUE) + update_appearance() + after_close(user) + SEND_SIGNAL(src, COMSIG_CLOSET_POST_CLOSE, user) + return inserted + +/// Distance Check (Inside Of) +/obj/structure/closet/crate/coffin/click_alt(mob/user) + . = ..() + if(user in src) + LockMe(user, !locked) + return CLICK_ACTION_SUCCESS + + if(user == resident && user.Adjacent(src)) + balloon_alert(user, "unclaim coffin?") + var/static/list/unclaim_options = list( + "Yes" = image(icon = 'icons/hud/radial.dmi', icon_state = "radial_yes"), + "No" = image(icon = 'icons/hud/radial.dmi', icon_state = "radial_no")) + var/unclaim_response = show_radial_menu(user, src, unclaim_options, radius = 36, require_near = TRUE) + switch(unclaim_response) + if("Yes") + unclaim_coffin(TRUE) + return CLICK_ACTION_SUCCESS + +/obj/structure/closet/crate/proc/LockMe(mob/user, inLocked = TRUE) + if(user == resident) + if(!broken) + locked = inLocked + if(locked) + to_chat(user, span_notice("You flip a secret latch and lock yourself inside [src].")) + else + to_chat(user, span_notice("You flip a secret latch and unlock [src].")) + return TRUE + // Broken? Let's fix it. + to_chat(resident, span_notice("The secret latch that would lock [src] from the inside is broken. You set it back into place...")) + if(!do_after(resident, 5 SECONDS, src)) + to_chat(resident, span_notice("You fail to fix [src]'s mechanism.")) + return FALSE + to_chat(resident, span_notice("You fix the mechanism and lock it.")) + broken = FALSE + locked = TRUE + return TRUE diff --git a/tff_modular/modules/bloodsucker/structures/crypt.dm b/tff_modular/modules/bloodsucker/structures/crypt.dm new file mode 100644 index 00000000000..e753d72ca32 --- /dev/null +++ b/tff_modular/modules/bloodsucker/structures/crypt.dm @@ -0,0 +1,642 @@ +/obj/structure/bloodsucker + ///Who owns this structure? + var/mob/living/owner + /* + * We use vars to add descriptions to items. + * This way we don't have to make a new /examine for each structure + * And it's easier to edit. + */ + var/ghost_desc + var/vamp_desc + var/ghoul_desc + var/hunter_desc + +/obj/structure/bloodsucker/examine(mob/user) + . = ..() + if(!user.mind && ghost_desc != "") + . += span_cult(ghost_desc) + if(IS_BLOODSUCKER(user) && vamp_desc) + if(!owner) + . += span_cult("It is unsecured. Click on [src] while in your haven to secure it in place to get its full potential.") + return + . += span_cult(vamp_desc) + if(IS_GHOUL(user) && ghoul_desc != "") + . += span_cult(ghoul_desc) + if(IS_MONSTERHUNTER(user) && hunter_desc != "") + . += span_cult(hunter_desc) + +/// This handles bolting down the structure. +/obj/structure/bloodsucker/proc/bolt(mob/user) + to_chat(user, span_danger("You have secured [src] in place.")) + to_chat(user, span_announce("* Bloodsucker Tip: Examine [src] to understand how it functions!")) + owner = user + +/// This handles unbolting of the structure. +/obj/structure/bloodsucker/proc/unbolt(mob/user) + to_chat(user, span_danger("You have unsecured [src].")) + owner = null + +/obj/structure/bloodsucker/attackby(obj/item/item, mob/living/user, params) + /// If a Bloodsucker tries to wrench it in place, yell at them. + if(item.tool_behaviour == TOOL_WRENCH && !anchored && IS_BLOODSUCKER(user)) + user.playsound_local(null, 'sound/machines/buzz/buzz-sigh.ogg', 40, FALSE, pressure_affected = FALSE) + to_chat(user, span_announce("* Bloodsucker Tip: Examine Bloodsucker structures to understand how they function!")) + return + return ..() + +/obj/structure/bloodsucker/attack_hand(mob/user, list/modifiers) +// . = ..() // Don't call parent, else they will handle unbuckling. + var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(user) + /// Claiming the Rack instead of using it? + if(istype(bloodsuckerdatum) && !owner) + if(!bloodsuckerdatum.bloodsucker_haven_area) + to_chat(user, span_danger("You don't have a haven. Claim a coffin to make that location your haven.")) + return FALSE + if(bloodsuckerdatum.bloodsucker_haven_area != get_area(src)) + to_chat(user, span_danger("You may only activate this structure in your haven: [bloodsuckerdatum.bloodsucker_haven_area].")) + return FALSE + + /// Radial menu for securing your Persuasion rack in place. + to_chat(user, span_notice("Do you wish to secure [src] here?")) + var/static/list/secure_options = list( + "Yes" = image(icon = 'icons/hud/radial.dmi', icon_state = "radial_yes"), + "No" = image(icon = 'icons/hud/radial.dmi', icon_state = "radial_no")) + var/secure_response = show_radial_menu(user, src, secure_options, radius = 36, require_near = TRUE) + if(!secure_response) + return FALSE + switch(secure_response) + if("Yes") + user.playsound_local(null, 'sound/items/tools/ratchet.ogg', 70, FALSE, pressure_affected = FALSE) + bolt(user) + return FALSE + return FALSE + return TRUE + +/obj/structure/bloodsucker/click_alt(mob/user) + . = ..() + if(user == owner && user.Adjacent(src)) + balloon_alert(user, "unbolt [src]?") + var/static/list/unclaim_options = list( + "Yes" = image(icon = 'icons/hud/radial.dmi', icon_state = "radial_yes"), + "No" = image(icon = 'icons/hud/radial.dmi', icon_state = "radial_no"), + ) + var/unclaim_response = show_radial_menu(user, src, unclaim_options, radius = 36, require_near = TRUE) + switch(unclaim_response) + if("Yes") + unbolt(user) + return CLICK_ACTION_SUCCESS +/* +/obj/structure/bloodsucker/bloodaltar + name = "bloody altar" + desc = "It is made of marble, lined with basalt, and radiates an unnerving chill that puts your skin on edge." +/obj/structure/bloodsucker/bloodstatue + name = "bloody countenance" + desc = "It looks upsettingly familiar..." +/obj/structure/bloodsucker/bloodportrait + name = "oil portrait" + desc = "A disturbingly familiar face stares back at you. Those reds don't seem to be painted in oil..." +/obj/structure/bloodsucker/bloodbrazier + name = "lit brazier" + desc = "It burns slowly, but doesn't radiate any heat." +/obj/structure/bloodsucker/bloodmirror + name = "faded mirror" + desc = "You get the sense that the foggy reflection looking back at you has an alien intelligence to it." +/obj/item/restraints/legcuffs/beartrap/bloodsucker +*/ + +/obj/structure/bloodsucker/ghoulrack + name = "persuasion rack" + desc = "If this wasn't meant for torture, then someone has some fairly horrifying hobbies." + icon = 'tff_modular/modules/bloodsucker/icons/vamp_obj.dmi' + icon_state = "ghoulrack" + anchored = FALSE + density = TRUE + can_buckle = TRUE + buckle_lying = 180 + ghost_desc = "This is a Ghoul rack, which allows Bloodsuckers to thrall crewmembers into loyal minions." + vamp_desc = "This is the Ghoul rack, which allows you to thrall crewmembers into loyal minions in your service.\n\ + Simply click and hold on a victim, and then drag their sprite on the ghoul rack. Right-click on the ghoul rack to unbuckle them.\n\ + To convert into a Ghoul, repeatedly click on the persuasion rack. The time required scales with the tool in your off hand. This costs Blood to do.\n\ + Ghouls can be turned into special ones by continuing to torture them once converted." + ghoul_desc = "This is the ghoul rack, which allows your master to thrall crewmembers into their minions.\n\ + Aid your master in bringing their victims here and keeping them secure.\n\ + You can secure victims to the ghoul rack by click dragging the victim onto the rack while it is secured." + hunter_desc = "This is the ghoul rack, which monsters use to brainwash crewmembers into their loyal slaves.\n\ + They usually ensure that victims are handcuffed, to prevent them from running away.\n\ + Their rituals take time, allowing us to disrupt it." + custom_materials = list( + /datum/material/wood = SHEET_MATERIAL_AMOUNT * 3, + /datum/material/iron = SHEET_MATERIAL_AMOUNT * 2.3, + /datum/material/glass = SMALL_MATERIAL_AMOUNT * 3, + ) + + /// Resets on each new character to be added to the chair. Some effects should lower it... + var/convert_progress = 3 + /// Mindshielded and Antagonists willingly have to accept you as their Master. + var/disloyalty_confirm = FALSE + /// Prevents popup spam. + var/disloyalty_offered = FALSE + +/obj/structure/bloodsucker/ghoulrack/examine(mob/user) + . = ..() + var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(user) + if(bloodsuckerdatum) + . += span_cult("You can support a total of [convert_integer_to_words(bloodsuckerdatum.max_ghouls())] [bloodsuckerdatum.max_ghouls() == 1 ? "ghoul" : "ghouls"], \ + with [convert_integer_to_words(bloodsuckerdatum.free_ghoul_slots())] [bloodsuckerdatum.free_ghoul_slots() == 1 ? "slot" : "slots"] remaining.") + +/obj/structure/bloodsucker/ghoulrack/atom_deconstruct(disassembled = TRUE) + . = ..() + new /obj/item/stack/sheet/iron(src.loc, 4) + new /obj/item/stack/rods(loc, 4) + qdel(src) + +/obj/structure/bloodsucker/ghoulrack/bolt() + . = ..() + density = FALSE + anchored = TRUE + +/obj/structure/bloodsucker/ghoulrack/unbolt() + . = ..() + density = TRUE + anchored = FALSE + +/obj/structure/bloodsucker/ghoulrack/mouse_drop_receive(atom/movable/movable_atom, mob/user, params) + var/mob/living/living_target = movable_atom + if(!anchored && IS_BLOODSUCKER(user)) + user.balloon_alert(user, "not secured!") + to_chat(user, span_danger("Until this rack is secured in place, it cannot serve its purpose.")) + to_chat(user, span_announce("* Bloodsucker Tip: Examine the Persuasion Rack to understand how it functions!")) + return + // Default checks + if(!isliving(movable_atom) || !living_target.Adjacent(src) || living_target == user || !isliving(user) || has_buckled_mobs() || user.incapacitated || living_target.buckled) + return + // Don't buckle Silicon to it please. + if(issilicon(living_target)) + to_chat(user, span_danger("You realize that this machine cannot be ghouled, therefore it is useless to buckle them.")) + return + if(do_after(user, 5 SECONDS, living_target)) + attach_victim(living_target, user) + +/// Attempt Release (Owner vs Non Owner) +/obj/structure/bloodsucker/ghoulrack/attack_hand_secondary(mob/user, modifiers) + . = ..() + if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN) + return + if(!user.can_perform_action(src)) + return + if(!has_buckled_mobs() || !isliving(user)) + return + var/mob/living/carbon/buckled_carbons = pick(buckled_mobs) + if(buckled_carbons) + if(user == owner) + unbuckle_mob(buckled_carbons) + else + user_unbuckle_mob(buckled_carbons, user) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + +/** + * Attempts to buckle target into the ghoulrack + */ +/obj/structure/bloodsucker/ghoulrack/proc/attach_victim(mob/living/target, mob/living/user) + if(!buckle_mob(target)) + return + user.visible_message( + span_notice("[user] straps [target] into the rack, immobilizing them."), + span_boldnotice("You secure [target] tightly in place. They won't escape you now."), + ) + + playsound(loc, 'sound/effects/pop_expl.ogg', 25, 1) + update_appearance(UPDATE_ICON) + density = TRUE + + // Set up Torture stuff now + convert_progress = 3 + disloyalty_confirm = FALSE + disloyalty_offered = FALSE + +/// Attempt Unbuckle +/obj/structure/bloodsucker/ghoulrack/user_unbuckle_mob(mob/living/buckled_mob, mob/user) + if(IS_BLOODSUCKER(user) || IS_GHOUL(user)) + return ..() + + if(buckled_mob == user) + buckled_mob.visible_message( + span_danger("[user] tries to release themself from the rack!"), + span_danger("You attempt to release yourself from the rack!"), + span_hear("You hear a squishy wet noise.")) + if(!do_after(user, 20 SECONDS, buckled_mob)) + return + else + buckled_mob.visible_message( + span_danger("[user] tries to pull [buckled_mob] rack!"), + span_danger("[user] tries to pull [buckled_mob] rack!"), + span_hear("You hear a squishy wet noise.")) + if(!do_after(user, 10 SECONDS, buckled_mob)) + return + + return ..() + +/obj/structure/bloodsucker/ghoulrack/unbuckle_mob(mob/living/buckled_mob, force = FALSE, can_fall = TRUE) + . = ..() + if(!.) + return + visible_message(span_danger("[buckled_mob][buckled_mob.stat == DEAD ? "'s corpse" : ""] slides off of the rack.")) + density = FALSE + buckled_mob.Paralyze(2 SECONDS) + update_appearance(UPDATE_ICON) + +/obj/structure/bloodsucker/ghoulrack/attack_hand(mob/user, list/modifiers) + . = ..() + if(!.) + return FALSE + // Is there anyone on the rack & If so, are they being tortured? + if(!has_buckled_mobs()) + return FALSE + + var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(user) + var/mob/living/carbon/buckled_carbons = pick(buckled_mobs) + // If I'm not a Bloodsucker, try to unbuckle them. + if(!istype(bloodsuckerdatum)) + user_unbuckle_mob(buckled_carbons, user) + return + if(!bloodsuckerdatum.my_clan) + to_chat(user, span_warning("You can't ghoul people until you enter a Clan (Through your Antagonist UI button)")) + user.balloon_alert(user, "join a clan first!") + return + var/datum/antagonist/ghoul/ghouldatum = IS_GHOUL(buckled_carbons) + // Are they our Ghoul? + if(ghouldatum && (ghouldatum in bloodsuckerdatum.ghouls)) + SEND_SIGNAL(bloodsuckerdatum, COMSIG_BLOODSUCKER_INTERACT_WITH_GHOUL, ghouldatum) + return + if(bloodsuckerdatum.free_ghoul_slots() < 1) + to_chat(user, span_warning("You can't ghoul more people until you level up more! You are currently at [bloodsuckerdatum.free_ghoul_slots()] active / [bloodsuckerdatum.max_ghouls()] max ghouls.")) + user.balloon_alert(user, "not enough ghoul slots!") + return + + + // Not our Ghoul, but Alive & We're a Bloodsucker, good to torture! + torture_victim(user, buckled_carbons) + +/** + * Torture steps: + * + * * Tick Down Conversion from 3 to 0 + * * Break mindshielding/antag (on approve) + * * Ghoulize target + */ +/obj/structure/bloodsucker/ghoulrack/proc/torture_victim(mob/living/user, mob/living/target) + var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(user) + if(IS_GHOUL(target)) + var/datum/antagonist/ghoul/ghouldatum = IS_GHOUL(target) + if(!ghouldatum.master.broke_masquerade) + balloon_alert(user, "someone else's ghoul!") + return FALSE + + var/disloyalty_requires = RequireDisloyalty(user, target) + if(disloyalty_requires == GHOULING_BANNED) + if(target.ckey) + balloon_alert(user, "can't be ghouled!") + else + balloon_alert(user, "target has no mind!") + return FALSE + + // Conversion Process + if(convert_progress) + balloon_alert(user, "spilling blood...") + bloodsuckerdatum.AdjustBloodVolume(-TORTURE_BLOOD_HALF_COST) + if(!do_torture(user, target)) + return FALSE + bloodsuckerdatum.AdjustBloodVolume(-TORTURE_BLOOD_HALF_COST) + // Prevent them from unbuckling themselves as long as we're torturing. + target.Paralyze(1 SECONDS) + convert_progress-- + + // We're done? Let's see if they can be Ghoul. + if(convert_progress) + balloon_alert(user, "needs more persuasion...") + return + + if(disloyalty_requires) + balloon_alert(user, "has external loyalties! more persuasion required!") + else + balloon_alert(user, "ready for communion!") + return + + if(!disloyalty_confirm && disloyalty_requires) + if(!do_disloyalty(user, target)) + return + if(!disloyalty_confirm) + balloon_alert(user, "refused persuasion!") + else + balloon_alert(user, "ready for communion!") + return + + user.balloon_alert_to_viewers("smears blood...", "painting bloody marks...") + if(!do_after(user, 5 SECONDS, target)) + balloon_alert(user, "interrupted!") + return + // Convert to Ghoul! + bloodsuckerdatum.AdjustBloodVolume(-TORTURE_CONVERSION_COST) + remove_loyalties(target) + if(bloodsuckerdatum.make_ghoul(target)) + SEND_SIGNAL(bloodsuckerdatum, COMSIG_BLOODSUCKER_MADE_GHOUL, user, target) + +/obj/structure/bloodsucker/ghoulrack/proc/do_torture(mob/living/user, mob/living/carbon/target, mult = 1) + // Fifteen seconds if you aren't using anything. Shorter with weapons and such. + var/torture_time = 15 + var/torture_dmg_brute = 2 + var/torture_dmg_burn = 0 + var/obj/item/bodypart/selected_bodypart = pick(target.bodyparts) + // Get Weapon + var/obj/item/held_item = user.get_inactive_held_item() + /// Weapon Bonus + if(held_item) + torture_time -= held_item.force / 4 + if(!held_item.use_tool(src, user, 0, volume = 5)) + return + switch(held_item.damtype) + if(BRUTE) + torture_dmg_brute = held_item.force / 4 + torture_dmg_burn = 0 + if(BURN) + torture_dmg_brute = 0 + torture_dmg_burn = held_item.force / 4 + switch(held_item.sharpness) + if(SHARP_EDGED) + torture_time -= 2 + if(SHARP_POINTY) + torture_time -= 3 + + // Minimum 5 seconds. + torture_time = max(5 SECONDS, torture_time * 10) + // Now run process. + if(!do_after(user, (torture_time * mult), target)) + return FALSE + + if(held_item) + held_item.play_tool_sound(target) + target.visible_message( + span_danger("[user] performs a ritual, spilling some of [target]'s blood from their [selected_bodypart.name] and shaking them up!"), + span_userdanger("[user] performs a ritual, spilling some blood from your [selected_bodypart.name], shaking you up!")) + + INVOKE_ASYNC(target, TYPE_PROC_REF(/mob, emote), "scream") + target.set_timed_status_effect(5 SECONDS, /datum/status_effect/jitter, only_if_higher = TRUE) + target.apply_damages(brute = torture_dmg_brute, burn = torture_dmg_burn, def_zone = selected_bodypart.body_zone) + return TRUE + +/// Offer them the opportunity to join now. +/obj/structure/bloodsucker/ghoulrack/proc/do_disloyalty(mob/living/user, mob/living/target) + if(disloyalty_offered) + return FALSE + // Can't willingly join if you're banned from it. It'll just ghost you anyways. + if(is_banned_from(target.ckey, ROLE_BLOODSUCKER)) + return TRUE + disloyalty_offered = TRUE + to_chat(user, span_notice("[target] has been given the opportunity for servitude. You await their decision...")) + var/alert_response = tgui_alert( + user = target, \ + message = "You are being tortured! Do you want to give in and pledge your undying loyalty to [user]? \n\ + You will not lose your current objectives, but they come second to the will of your new master!", \ + title = "THE HORRIBLE PAIN! WHEN WILL IT END?!", + buttons = list("Accept", "Refuse"), + timeout = 10 SECONDS, \ + autofocus = TRUE, \ + ) + switch(alert_response) + if("Accept") + disloyalty_confirm = TRUE + target.visible_message( + span_notice("[target] gives in to [user]'s offer of servitude!"), + span_userdanger("You give in to [user]'s offer of servitude!")) + else + target.visible_message( + span_danger("[target] stares defiantly at [user], refusing to give in!"), + span_danger("You stare defiantly at [user], refusing to give in!")) + disloyalty_offered = FALSE + return TRUE + +/obj/structure/bloodsucker/ghoulrack/proc/RequireDisloyalty(mob/living/user, mob/living/target) +#ifdef BLOODSUCKER_TESTING + if(!target || !target.mind) +#else + if(!target?.mind || !target?.client) +#endif + return GHOULING_BANNED + + if(HAS_TRAIT(target, TRAIT_MINDSHIELD)) + return GHOULING_DISLOYAL + var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(user) + return bloodsuckerdatum.AmValidAntag(target) + +/obj/structure/bloodsucker/ghoulrack/proc/remove_loyalties(mob/living/target) + // Find Mind Implant & Destroy + for(var/obj/item/implant/all_implants as anything in target.implants) + if(all_implants.type == /obj/item/implant/mindshield) + all_implants.removed(target, silent = TRUE) + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// todo, make this steal blood into a internal reservoir from nearby non-vassals/bloodsuckers +/obj/structure/bloodsucker/candelabrum + name = "candelabrum" + desc = "It burns slowly, but doesn't radiate any heat." + icon = 'tff_modular/modules/bloodsucker/icons/vamp_obj.dmi' + icon_state = "candelabrum" + light_color = "#66FFFF"//LIGHT_COLOR_BLUEGREEN // lighting.dm + light_power = 3 + light_range = 0 // to 2 + max_integrity = 100 + density = FALSE + can_buckle = TRUE + anchored = FALSE + ghost_desc = "This is a magical candle which drains at the sanity of non Bloodsuckers and Ghouls.\n\ + Ghouls can turn the candle on manually, while Bloodsuckers can do it from a distance." + vamp_desc = "This is a magical candle which drains at the sanity of mortals who are not under your command while it is active.\n\ + You can right-click on it from any range to turn it on remotely, or simply be next to it and click on it to turn it on and off normally." + ghoul_desc = "This is a magical candle which drains at the sanity of the fools who havent yet accepted your master, as long as it is active.\n\ + You can turn it on and off by clicking on it while you are next to it.\n\ + If your Master is part of the Ventrue Clan, they utilize this to upgrade their Favorite Ghoul." + hunter_desc = "This is a blue Candelabrum, which causes insanity to those near it while active." + custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 3.5) + var/lit = FALSE + +/obj/structure/bloodsucker/candelabrum/Destroy() + STOP_PROCESSING(SSobj, src) + return ..() + +/obj/structure/bloodsucker/candelabrum/update_icon_state() + icon_state = "candelabrum[lit ? "_lit" : ""]" + return ..() + +/obj/structure/bloodsucker/candelabrum/bolt() + . = ..() + set_anchored(TRUE) + density = TRUE + +/obj/structure/bloodsucker/candelabrum/unbolt() + . = ..() + set_anchored(FALSE) + density = FALSE + if(lit) + toggle() + +/obj/structure/bloodsucker/candelabrum/attack_hand(mob/living/user, list/modifiers) + . = ..() + if(!.) + return + if(IS_GHOUL(user) || IS_BLOODSUCKER(user)) + toggle() + return ..() + +/obj/structure/bloodsucker/candelabrum/Click(location, control, params) + . = ..() + var/mob/user = usr + var/list/modifiers = params2list(params) + if(!LAZYACCESS(modifiers, RIGHT_CLICK) || !IS_BLOODSUCKER(user) || !istype(user)) + return + if(user.stat >= UNCONSCIOUS) + return + user.balloon_alert_to_viewers("motions their hand at [src]") + toggle(user) + +/obj/structure/bloodsucker/candelabrum/proc/toggle(mob/user) + if(!anchored) + to_chat(user, span_danger("You can't turn this on while it is not secured!")) + return + lit = !lit + if(lit) + desc = initial(desc) + set_light(2, 3, "#66FFFF") + START_PROCESSING(SSobj, src) + else + desc = "Despite not being lit, it makes your skin crawl." + set_light(0) + STOP_PROCESSING(SSobj, src) + update_icon() + + +/obj/structure/bloodsucker/candelabrum/process() + if(!lit) + return + for(var/mob/living/carbon/nearly_people in viewers(7, src)) + /// We dont want Bloodsuckers or Ghouls affected by this + if(IS_GHOUL(nearly_people) || IS_BLOODSUCKER(nearly_people)) + continue + nearly_people.adjust_hallucinations(5 SECONDS) + nearly_people.add_mood_event("vampcandle", /datum/mood_event/vampcandle) + +/// Blood Throne - Allows Bloodsuckers to remotely speak with their Ghouls. - Code (Mostly) stolen from comfy chairs (armrests) and chairs (layers) +/obj/structure/bloodsucker/bloodthrone + name = "wicked throne" + desc = "Twisted metal shards jut from the arm rests. Very uncomfortable looking. It would take a masochistic sort to sit on this jagged piece of furniture." + icon = 'tff_modular/modules/bloodsucker/icons/vamp_obj_64.dmi' + icon_state = "throne" + buckle_lying = 0 + anchored = FALSE + density = TRUE + can_buckle = TRUE + ghost_desc = "This is a Bloodsucker throne, any Bloodsucker sitting on it can remotely speak to their Ghouls by attempting to speak aloud." + vamp_desc = "This is a blood throne, sitting on it will allow you to telepathically speak to your ghouls by simply speaking." + ghoul_desc = "This is a blood throne, it allows your Master to telepathically speak to you and others like you." + hunter_desc = "This is a chair that hurts those that try to buckle themselves onto it, though the Undead have no problem latching on.\n\ + While buckled, Monsters can use this to telepathically communicate with eachother." + custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 5, /datum/material/wood = SHEET_MATERIAL_AMOUNT) + var/mutable_appearance/armrest + +// Add rotating and armrest +/obj/structure/bloodsucker/bloodthrone/Initialize(mapload) + AddComponent(/datum/component/simple_rotation) + armrest = GetArmrest() + armrest.layer = ABOVE_MOB_LAYER + return ..() + +/obj/structure/bloodsucker/bloodthrone/Destroy() + QDEL_NULL(armrest) + return ..() + +/obj/structure/bloodsucker/bloodthrone/bolt() + . = ..() + anchored = TRUE + +/obj/structure/bloodsucker/bloodthrone/unbolt() + . = ..() + anchored = FALSE + +// Armrests +/obj/structure/bloodsucker/bloodthrone/proc/GetArmrest() + return mutable_appearance('tff_modular/modules/bloodsucker/icons/vamp_obj_64.dmi', "thronearm") + +/obj/structure/bloodsucker/bloodthrone/proc/update_armrest() + if(has_buckled_mobs()) + add_overlay(armrest) + else + cut_overlay(armrest) + +// Rotating +/obj/structure/bloodsucker/bloodthrone/setDir(newdir) + . = ..() + if(has_buckled_mobs()) + for(var/m in buckled_mobs) + var/mob/living/buckled_mob = m + buckled_mob.setDir(newdir) + + if(has_buckled_mobs() && dir == NORTH) + layer = ABOVE_MOB_LAYER + else + layer = OBJ_LAYER + +// Buckling +/obj/structure/bloodsucker/bloodthrone/buckle_mob(mob/living/user, force = FALSE, check_loc = TRUE) + if(!anchored) + to_chat(user, span_announce("[src] is not bolted to the ground!")) + return + . = ..() + user.visible_message( + span_notice("[user] sits down on [src]."), + span_boldnotice("You sit down onto [src]."), + ) + if(IS_BLOODSUCKER(user)) + RegisterSignal(user, COMSIG_MOB_SAY, PROC_REF(handle_speech)) + else + unbuckle_mob(user) + user.Paralyze(10 SECONDS) + to_chat(user, span_cult("The power of the blood throne overwhelms you!")) + +/obj/structure/bloodsucker/bloodthrone/post_buckle_mob(mob/living/target) + . = ..() + update_armrest() + target.pixel_y += 2 + +// Unbuckling +/obj/structure/bloodsucker/bloodthrone/unbuckle_mob(mob/living/user, force = FALSE, can_fall = TRUE) + src.visible_message(span_danger("[user] unbuckles themselves from [src].")) + if(IS_BLOODSUCKER(user)) + UnregisterSignal(user, COMSIG_MOB_SAY) + . = ..() + +/obj/structure/bloodsucker/bloodthrone/post_unbuckle_mob(mob/living/target) + target.pixel_y -= 2 + +// The speech itself +/obj/structure/bloodsucker/bloodthrone/proc/handle_speech(datum/source, list/speech_args) + SIGNAL_HANDLER + + var/forced_type = speech_args[SPEECH_FORCED] + if(forced_type == CLAN_MALKAVIAN) + return + var/message = speech_args[SPEECH_MESSAGE] + var/mob/living/carbon/human/user = source + var/rendered = span_cult_large("[user.real_name]: [capitalize(message)]") + user.log_talk(message, LOG_SAY, tag = ROLE_BLOODSUCKER) + var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(user) + for(var/datum/antagonist/ghoul/receiver as anything in bloodsuckerdatum.ghouls) + 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]") + + speech_args[SPEECH_MESSAGE] = "" diff --git a/tff_modular/modules/bloodsucker/structures/objects.dm b/tff_modular/modules/bloodsucker/structures/objects.dm new file mode 100644 index 00000000000..09f108767e5 --- /dev/null +++ b/tff_modular/modules/bloodsucker/structures/objects.dm @@ -0,0 +1,358 @@ +////////////////////// +// BLOODBAG // +////////////////////// + +#define BLOODBAG_GULP_SIZE 5 + +/obj/item/reagent_containers/blood + var/being_drunk = FALSE + +/// Taken from drinks.dm +/obj/item/reagent_containers/blood/attack(mob/living/victim, mob/living/attacker, params) + if(!can_drink(victim, attacker) || being_drunk) + return + being_drunk = TRUE + if(victim != attacker) + // show to both victim and attacker + INVOKE_ASYNC(src, GLOBAL_PROC_REF(do_after), victim, 5 SECONDS, attacker) + do_after(victim, 5 SECONDS, attacker) + if(!do_after(attacker, 5 SECONDS, victim)) + being_drunk = FALSE + return + attacker.visible_message( + span_notice("[attacker] forces [victim] to drink from the [src]."), + span_notice("You put the [src] up to [victim]'s mouth.")) + reagents.trans_to(victim, BLOODBAG_GULP_SIZE, transferred_by = attacker, methods = INGEST) + playsound(victim.loc, 'sound/items/drink.ogg', 30, 1) + being_drunk = FALSE + return TRUE + + while(do_after(victim, 1 SECONDS, timed_action_flags = IGNORE_USER_LOC_CHANGE, extra_checks = CALLBACK(src, PROC_REF(can_drink), attacker, victim))) + victim.visible_message( + span_notice("[victim] puts the [src] up to their mouth."), + span_notice("You take a sip from the [src]."), + ) + reagents.trans_to(victim, BLOODBAG_GULP_SIZE, transferred_by = attacker, methods = INGEST) + playsound(victim.loc, 'sound/items/drink.ogg', 30, 1) + being_drunk = FALSE + return TRUE + +#undef BLOODBAG_GULP_SIZE + +/obj/item/reagent_containers/blood/proc/can_drink(mob/living/victim, mob/living/attacker) + if(!canconsume(victim, attacker)) + return FALSE + if(!reagents || !reagents.total_volume) + to_chat(victim, span_warning("[src] is empty!")) + return FALSE + return TRUE + +///Bloodbag of Bloodsucker blood (used by Ghouls only) +/obj/item/reagent_containers/blood/o_minus/bloodsucker + name = "blood pack" + blood_type = null + list_reagents = list(/datum/reagent/blood/bloodsucker = 200) + +/obj/item/reagent_containers/blood/o_minus/bloodsucker/examine(mob/user) + . = ..() + if(user.mind.has_antag_datum(/datum/antagonist/ex_ghoul) || user.mind.has_antag_datum(/datum/antagonist/ghoul/revenge)) + . += span_notice("Seems to be just about the same color as your Master's...") + +////////////////////// +// STAKES // +////////////////////// +/obj/item/stack/sheet/mineral/wood/attackby(obj/item/item, mob/user, params) + if(!item.get_sharpness()) + return ..() + user.visible_message( + span_notice("[user] begins whittling [src] into a pointy object."), + span_notice("You begin whittling [src] into a sharp point at one end."), + span_hear("You hear wood carving."), + ) + // 5 Second Timer + if(!do_after(user, 5 SECONDS, src, NONE, TRUE)) + return + // Make Stake + var/obj/item/stake/new_item = new(user.loc) + user.visible_message( + span_notice("[user] finishes carving a stake out of [src]."), + span_notice("You finish carving a stake out of [src]."), + ) + // Prepare to Put in Hands (if holding wood) + var/obj/item/stack/sheet/mineral/wood/wood_stack = src + var/replace = (user.get_inactive_held_item() == wood_stack) + // Use Wood + wood_stack.use(1) + // If stack depleted, put item in that hand (if it had one) + if(!wood_stack && replace) + user.put_in_hands(new_item) + +// TODO move this into bloodsuckerdatum +/// Do I have a stake in my heart? +/mob/living/proc/am_staked() + var/obj/item/bodypart/chosen_bodypart = get_bodypart(BODY_ZONE_CHEST) + var/obj/item/stake/stake = locate() in chosen_bodypart.embedded_objects + return stake + +/mob/living/proc/get_stakes() + var/obj/item/bodypart/chosen_bodypart = get_bodypart(BODY_ZONE_CHEST) + if(!chosen_bodypart) + return FALSE + var/list/stakes = list() + for(var/obj/item/embedded_stake in chosen_bodypart.embedded_objects) + if(istype(embedded_stake, /obj/item/stake)) + stakes += list(embedded_stake) + return stakes + +/datum/embedding/stake + embed_chance = 20 + +/obj/item/stake + name = "wooden stake" + desc = "A simple wooden stake carved to a sharp point." + icon = 'tff_modular/modules/bloodsucker/icons/stakes.dmi' + icon_state = "wood" + inhand_icon_state = "wood" + lefthand_file = 'tff_modular/modules/bloodsucker/icons/bloodsucker_lefthand.dmi' + righthand_file = 'tff_modular/modules/bloodsucker/icons/bloodsucker_righthand.dmi' + slot_flags = ITEM_SLOT_POCKETS + w_class = WEIGHT_CLASS_SMALL + hitsound = 'sound/items/weapons/bladeslice.ogg' + attack_verb_continuous = list("staked", "stabbed", "tore into") + attack_verb_simple = list("staked", "stabbed", "tore into") + sharpness = SHARP_EDGED + embed_data = /datum/embedding/stake + force = 6 + throwforce = 10 + max_integrity = 30 + custom_materials = list(/datum/material/wood = SHEET_MATERIAL_AMOUNT * 3) + + ///Time it takes to embed the stake into someone's chest. + var/staketime = 5 SECONDS + var/kills_blodsuckers = FALSE + +/obj/item/stake/examine_more(mob/user) + . = ..() + . += span_notice("You can use [src] to stake someone in the chest, if they are laying down or grabbed by the neck.") + if(IS_BLOODSUCKER(user)) + . += span_warning("You feel a sense of dread as you look at the [src]...") + +/obj/item/stake/attack(mob/living/target, mob/living/user, params) + . = ..() + if(.) + return + // Invalid Target, or not targetting the chest? + if(check_zone(user.zone_selected) != BODY_ZONE_CHEST) + return + if(target == user) + return + if(!target.can_be_staked()) // Oops! Can't. + to_chat(user, span_danger("You can't stake [target] when they are moving about! They have to be laying down or grabbed by the neck!")) + return + if(HAS_TRAIT(target, TRAIT_PIERCEIMMUNE)) + to_chat(user, span_danger("[target]'s chest resists the stake. It won't go in.")) + return + + to_chat(user, span_notice("You put all your weight into embedding the stake into [target]'s chest...")) + playsound(user, 'sound/effects/magic/Demon_consume.ogg', 50, 1) + if(!do_after(user, staketime, target, extra_checks = CALLBACK(target, TYPE_PROC_REF(/mob/living/carbon, can_be_staked)))) // user / target / time / uninterruptable / show progress bar / extra checks + return + // Drop & Embed Stake + user.visible_message( + span_danger("[user.name] drives the [src] into [target]'s chest!"), + span_danger("You drive the [src] into [target]'s chest!"), + ) + playsound(get_turf(target), 'sound/effects/splat.ogg', 40, 1) + if(force_embed(target, target.get_bodypart(BODY_ZONE_CHEST))) //and if it embeds successfully in their chest, cause a lot of pain + target.apply_damage(max(10, force * 1.2), BRUTE, BODY_ZONE_CHEST, wound_bonus = 0, sharpness = TRUE) + on_stake_embed(target, user) + +/obj/item/stake/proc/on_stake_embed(mob/living/target, mob/living/user) + return + +/obj/item/stake/hardened/silver/on_stake_embed(mob/living/target, mob/living/user) + var/obj/item/organ/heart/heart = target.get_organ_slot(ORGAN_SLOT_HEART) + if(!heart) + return + target.visible_message( + span_danger("The [src.name] pierces [target]'s chest, destroying their [heart.name]!"), + span_userdanger("You feel a HORRIBLE pain as the [src.name] pierces your chest, destroying your [heart.name]!"), + ) + qdel(heart) + +/obj/item/stake/force_embed(mob/living/carbon/victim, obj/item/bodypart/target_limb) + . = ..() + if(!.) + return . + SEND_SIGNAL(target_limb, COMSIG_BODYPART_STAKED, TRUE) + SEND_SIGNAL(victim, COMSIG_MOB_STAKED, TRUE) + return . + +///Can this target be staked? If someone stands up before this is complete, it fails. Best used on someone stationary. +/mob/living/proc/can_be_staked() + return FALSE + +/mob/living/carbon/can_be_staked() + if(body_position == LYING_DOWN) + return TRUE + return FALSE + +/datum/embedding/stake/hardened + embed_chance = 35 + fall_chance = 0 + +/// Created by welding and acid-treating a simple stake. +/obj/item/stake/hardened + name = "hardened stake" + desc = "A wooden stake carved to a sharp point and hardened by fire." + icon_state = "hardened" + force = 8 + throwforce = 12 + armour_penetration = 10 + embed_data = /datum/embedding/stake/hardened + staketime = 12 SECONDS + custom_materials = list(/datum/material/iron = HALF_SHEET_MATERIAL_AMOUNT) + +/obj/item/stake/hardened/examine_more(mob/user) + . = ..() + . += span_notice("The [src] won't fall out by itself, if embedded in someone.") + +/datum/embedding/stake/silver + embed_chance = 0 // we want it to only be embeddable manually + fall_chance = 0 + +/obj/item/stake/hardened/silver + name = "silver stake" + desc = "Polished and sharp at the end. For when some mofo is always trying to iceskate uphill." + icon_state = "silver" + inhand_icon_state = "silver" + siemens_coefficient = 1 + force = 9 + armour_penetration = 25 + custom_materials = list(/datum/material/iron = HALF_SHEET_MATERIAL_AMOUNT, /datum/material/silver = SHEET_MATERIAL_AMOUNT) + embed_data = /datum/embedding/stake/silver + staketime = 15 SECONDS + +/obj/item/stake/hardened/silver/examine_more(mob/user) + . = ..() + . += span_notice("You think that the [src] could destroy someone's heart if you really slam it in someone's ribs properly.") + +////////////////////// +// ARCHIVES // +////////////////////// + +/** + * # Archives of the Kindred: + *+ + * A book that can only be used by Curators. + * When used on a player, after a short timer, will reveal if the player is a Bloodsucker, including their real name and Clan. + * This book should not work on Bloodsuckers using the Masquerade ability. + * If it reveals a Bloodsucker, the Curator will then be able to tell they are a Bloodsucker on examine (Like a Ghoul). + * Reading it normally will allow Curators to read what each Clan does, with some extra flavor text ones. + * + * Regular Bloodsuckers won't have any negative effects from the book, while everyone else will get burns/eye damage. + */ +/obj/item/book/kindred + name = "\improper Book of Nod" + starting_title = "the Book of Nod" + desc = "Cryptic documents explaining hidden truths behind Undead beings. It is said only Curators can decipher what they really mean." + icon = 'tff_modular/modules/bloodsucker/icons/vamp_obj.dmi' + lefthand_file = 'tff_modular/modules/bloodsucker/icons/bloodsucker_lefthand.dmi' + righthand_file = 'tff_modular/modules/bloodsucker/icons/bloodsucker_righthand.dmi' + icon_state = "kindred_book" + starting_author = "dozens of generations of Curators" + unique = TRUE + throw_speed = 1 + throw_range = 10 + resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF + ///Boolean on whether the book is currently being used, so you can only use it on one person at a time. + COOLDOWN_DECLARE(bloodsucker_check_cooldown) + var/cooldown_time = 1 MINUTES + +/obj/item/book/kindred/Initialize(mapload) + . = ..() + SSpoints_of_interest.make_point_of_interest(src) + +/obj/item/book/kindred/carving_act(mob/living/user, obj/item/tool) + to_chat(user, span_notice("You feel the gentle whispers of a Librarian telling you not to cut [starting_title].")) + return ITEM_INTERACT_BLOCKING + +///Attacking someone with the book. +/obj/item/book/kindred/afterattack(mob/living/target, mob/living/user, flag, params) + . = ..() + if(!user.can_read(src) || (target == user) || !ismob(target)) + return + if(!HAS_TRAIT(user.mind, TRAIT_BLOODSUCKER_HUNTER)) + if(IS_BLOODSUCKER(user)) + to_chat(user, span_notice("[src] seems to be too complicated for you. It would be best to leave this for someone else to take.")) + return + to_chat(user, span_warning("[src] burns your hands as you try to use it!")) + user.apply_damage(3, BURN, pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM)) + return + + if(!COOLDOWN_FINISHED(src, bloodsucker_check_cooldown)) + user.balloon_alert(user, "your head hurts, wait a minute ") + addtimer(CALLBACK(user, TYPE_PROC_REF(/atom, balloon_alert), user, "You feel your head clear up."), cooldown_time) + return + user.balloon_alert_to_viewers(user, "reading book...") + user.balloon_alert(target, "looks at you and checks their [src]...") + if(!do_after(user, 3 SECONDS, target, timed_action_flags = NONE, progress = TRUE)) + to_chat(user, span_notice("You quickly close [src].")) + return + COOLDOWN_START(src, bloodsucker_check_cooldown, cooldown_time) + var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(target) + // Are we a Bloodsucker | Are we on Masquerade. If one is true, they will fail. + if(IS_BLOODSUCKER(target) && !HAS_TRAIT(target, TRAIT_MASQUERADE)) + if(bloodsuckerdatum.broke_masquerade) + to_chat(user, span_warning("[target], also known as '[bloodsuckerdatum.return_full_name()]', is indeed a Bloodsucker, but you already knew this.")) + return + to_chat(user, span_warning("[target], also known as '[bloodsuckerdatum.return_full_name()]', [bloodsuckerdatum.my_clan ? "is part of the [bloodsuckerdatum.my_clan]!" : "is not part of a clan."] You quickly note this information down, memorizing it.")) + bloodsuckerdatum.break_masquerade() + else + to_chat(user, span_notice("You fail to draw any conclusions to [target] being a Bloodsucker.")) + +/obj/item/book/kindred/attack_self(mob/living/user) + if(user.mind && !(HAS_TRAIT(user.mind, TRAIT_BLOODSUCKER_HUNTER) || IS_BLOODSUCKER(user))) + to_chat(user, span_warning("You feel your eyes unable to read the boring texts...")) + user.set_eye_blur_if_lower(10 SECONDS) + return + ui_interact(user) + +/obj/item/book/kindred/ui_interact(mob/living/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "KindredBook", name) + ui.open() + +/obj/item/book/kindred/ui_static_data(mob/user) + var/data = list() + + for(var/datum/bloodsucker_clan/clans as anything in subtypesof(/datum/bloodsucker_clan)) + var/clan_data = list() + clan_data["clan_name"] = initial(clans.name) + clan_data["clan_desc"] = initial(clans.description) + data["clans"] += list(clan_data) + + return data + +/obj/structure/displaycase/curator + desc = "This book was found inside a coffin of a long dead Curator. It is said to be able to reveal the true nature of those who feed upon mankind." + start_showpiece_type = /obj/item/book/kindred + req_access = list(ACCESS_LIBRARY) + + +/// just a typepath to specify that it's monkey-owned, used for the heart thief objective +/obj/item/organ/heart/monkey + +/obj/item/organ/heart/examine_more(mob/user) + . = ..() + var/datum/antagonist/bloodsucker/vampire = IS_BLOODSUCKER(user) + if(!vampire) + return + var/datum/objective/steal_n_of_type/heart_thief = locate() in vampire?.objectives + if(!heart_thief) + return + if(heart_thief.check_if_valid_item(src)) + . += span_notice("This [src.name] will do for your purposes...") + else + . += span_notice("This [src.name] is of lesser quality, it won't do...") diff --git a/tff_modular/modules/bloodsucker/vassal/batform.dm b/tff_modular/modules/bloodsucker/vassal/batform.dm new file mode 100644 index 00000000000..7faeed84388 --- /dev/null +++ b/tff_modular/modules/bloodsucker/vassal/batform.dm @@ -0,0 +1,61 @@ +/** + * # BATFORM + * + * TG removed this, so we're re-adding it + */ +/datum/action/cooldown/spell/shapeshift/bat + name = "Bat Form" + desc = "Take on the shape of a space bat. You can fly and see in the dark, and you heal from doing melee attacks." + background_icon_state = "tremere_power_off" + active_background_icon_state = "tremere_power_on" + base_background_icon_state = "tremere_power_off" + background_icon = 'tff_modular/modules/bloodsucker/icons/tremere_bloodsucker.dmi' + power_explanation = "You can fly and see in the dark, and you heal from doing melee attacks." + invocation = "Master, grant me your might, BAT FORM!!" + invocation_type = INVOCATION_SHOUT + spell_requirements = NONE + convert_damage = TRUE + cooldown_time = 1 MINUTES + possible_shapes = list(/mob/living/basic/bat/bloodsucker) + power_explanation = "This ability turns you into a small bat, which can fly and heals from doing meele damage. \n\ + However, you don't do much meele damage, and are slightly weak to fire damage.\n\ + Using the ability also spawns some normal bats around where you cast it, causing confusion.\n\ + Keep in mind if you die in this form, your real body will also die, and any damage received is transfered as well." + var/bats_to_spawn = 3 + +/datum/action/cooldown/spell/shapeshift/bat/cast(mob/living/cast_on) + . = ..() + // spawn bats around + if(!get_turf(cast_on)) + return + for(var/i in 1 to bats_to_spawn) + var/mob/living/basic/bat/bat = new(get_turf(cast_on)) + QDEL_IN(bat, cooldown_time) + random_step(bat, 2, 50) + +/mob/living/basic/bat/bloodsucker + name ="vampiric bat" + desc = "A bat with a thirst for blood." + maxHealth = 100 + health = 100 + speed = 0 + melee_damage_lower = 10 + melee_damage_upper = 15 + wound_bonus = 10 + obj_damage = 10 + lighting_cutoff_red = 25 + lighting_cutoff_green = 8 + lighting_cutoff_blue = 5 + melee_attack_cooldown = CLICK_CD_MELEE + basic_mob_flags = FLAMMABLE_MOB + lighting_color_cutoffs = BLOODSUCKER_SIGHT_COLOR_CUTOFF + damage_coeff = list(BRUTE = 0.9, BURN = 1.25, TOX = 1, STAMINA = 1, OXY = 1) + attack_verb_simple = "drain blood from" + attack_verb_continuous = "drains blood from" + +/mob/living/basic/bat/bloodsucker/Initialize(mapload) + . = ..() + // Go as fast as people can run + AddElement(/datum/element/lifesteal, melee_damage_lower) + // Too fat to fit through vents + REMOVE_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT) diff --git a/tff_modular/modules/bloodsucker/vassal/vassal_datum.dm b/tff_modular/modules/bloodsucker/vassal/vassal_datum.dm new file mode 100644 index 00000000000..28e93fa38bb --- /dev/null +++ b/tff_modular/modules/bloodsucker/vassal/vassal_datum.dm @@ -0,0 +1,185 @@ +/datum/antagonist/ghoul + name = "\improper Ghoul" + roundend_category = "ghouls" + antagpanel_category = "Bloodsucker" + pref_flag = ROLE_VASSAL + antag_hud_name = "ghoul" + show_in_roundend = FALSE + hud_icon = 'tff_modular/modules/bloodsucker/icons/hud.dmi' + ui_name = "AntagInfoGhoul" + antag_panel_description = "You are a Ghoul, a mortal servant of a Bloodsucker." + + /// The Master Bloodsucker's antag datum. + var/datum/antagonist/bloodsucker/master + /// List of all Purchased Powers, to be cleaned up on antag removal. + var/list/datum/action/powers = list() + ///Whether this ghoul is already a special type of Ghoul. + var/special_type = FALSE + ///Description of what this Ghoul does. + /// It's shown to the bloodsucker in the radial for setting ghoul type + var/ghoul_description + /// inherent traits that are removed and addded on antag datum loss and gain + var/list/traits = list() + +/datum/antagonist/ghoul/antag_panel_data() + return "Master : [master?.owner.name ? master.owner.name : "Gone"]" + +// todo make this into a shared proc that bloodsuckers and ghouls share +/datum/antagonist/ghoul/ui_static_data(mob/user) + return ability_ui_data(powers) + ..() + +/datum/antagonist/ghoul/apply_innate_effects(mob/living/mob_override) + . = ..() + var/mob/living/current_mob = mob_override || owner.current + current_mob.apply_status_effect(/datum/status_effect/agent_pinpointer/ghoul_edition) + add_team_hud(current_mob) + if(length(traits)) + current_mob.add_traits(traits, GHOUL_TRAIT) + +/datum/antagonist/ghoul/add_team_hud(mob/target) + QDEL_NULL(team_hud_ref) + + team_hud_ref = WEAKREF(target.add_alt_appearance( + /datum/atom_hud/alternate_appearance/basic/has_antagonist, + "antag_team_hud_[REF(src)]", + hud_image_on(target), + )) + + var/datum/atom_hud/alternate_appearance/basic/has_antagonist/hud = team_hud_ref.resolve() + + var/list/mob/living/mob_list = list() + mob_list += master.owner.current + for(var/datum/antagonist/ghoul/ghoul as anything in master.ghouls) + mob_list += ghoul.owner.current + + for (var/datum/atom_hud/alternate_appearance/basic/has_antagonist/antag_hud as anything in GLOB.has_antagonist_huds) + if(!(antag_hud.target in mob_list)) + continue + antag_hud.show_to(target) + hud.show_to(antag_hud.target) + +/datum/antagonist/ghoul/remove_innate_effects(mob/living/mob_override) + . = ..() + var/mob/living/current_mob = mob_override || owner.current + current_mob.remove_status_effect(/datum/status_effect/agent_pinpointer/ghoul_edition) + if(length(traits)) + current_mob.remove_traits(traits, GHOUL_TRAIT) + +/datum/antagonist/ghoul/pre_mindshield(mob/implanter, mob/living/mob_override) + return COMPONENT_MINDSHIELD_PASSED + +/// This is called when the antagonist is successfully mindshielded. +/datum/antagonist/ghoul/on_mindshield(mob/implanter, mob/living/mob_override) + owner.remove_antag_datum(/datum/antagonist/ghoul) + owner.current.log_message("has been deconverted from Ghouling by [implanter]!", LOG_ATTACK, color="#960000") + return COMPONENT_MINDSHIELD_DECONVERTED + +/datum/antagonist/ghoul/proc/on_examined(datum/source, mob/examiner, examine_text) + SIGNAL_HANDLER + var/ghoul_examine = return_ghoul_examine(examiner) + if(ghoul_examine) + examine_text += ghoul_examine + + +/datum/antagonist/ghoul/on_gain() + RegisterSignal(owner.current, COMSIG_ATOM_EXAMINE, PROC_REF(on_examined)) + /// Enslave them to their Master + if(!master || !istype(master, master)) + return + if(special_type) + if(!master.special_ghouls[special_type]) + master.special_ghouls[special_type] = list() + master.special_ghouls[special_type] |= src + master.ghouls += src + owner.enslave_mind_to_creator(master.owner.current) + owner.current.log_message("has been ghouled by [master.owner.current]!", LOG_ATTACK, color="#960000") + /// Give Recuperate Power + BuyPower(/datum/action/cooldown/bloodsucker/recuperate) + /// Give Objectives + var/datum/objective/bloodsucker/ghoul/ghoul_objective = new + ghoul_objective.owner = owner + objectives += ghoul_objective + /// Give Vampire Language & Hud + owner.current.grant_all_languages(FALSE, FALSE, TRUE) + owner.current.grant_language(/datum/language/vampiric, ALL, LANGUAGE_MIND) + return ..() + +/datum/antagonist/ghoul/on_removal() + UnregisterSignal(owner.current, COMSIG_ATOM_EXAMINE) + //Free them from their Master + if(master && master.owner) + if(special_type && master.special_ghouls[special_type]) + master.special_ghouls.Remove(special_type) + master.ghouls -= src + owner.enslaved_to = null + //Remove ALL Traits, as long as its from BLOODSUCKER_TRAIT's source. + for(var/all_status_traits in owner.current._status_traits) + REMOVE_TRAIT(owner.current, all_status_traits, GHOUL_TRAIT) + //Remove Recuperate Power + remove_powers(powers) + //Remove Language & Hud + owner.current.remove_language(/datum/language/vampiric, ALL, LANGUAGE_MIND) + return ..() + +/datum/antagonist/ghoul/proc/remove_powers(list/removing_powers) + for(var/datum/action/cooldown/bloodsucker/power as anything in removing_powers) + removing_powers -= power + if(!(power in owner.current.actions)) + continue + power.Remove(owner.current) + +/datum/antagonist/ghoul/on_body_transfer(mob/living/old_body, mob/living/new_body) + . = ..() + for(var/datum/action/cooldown/bloodsucker/all_powers as anything in powers) + all_powers.Remove(old_body) + all_powers.Grant(new_body) + +/datum/antagonist/ghoul/greet() + . = ..() + if(silent) + return + + to_chat(owner, span_userdanger("You are now the mortal servant of [master.owner.current], a Bloodsucker!")) + to_chat(owner, span_boldannounce("The power of [master.owner.current.p_their()] immortal blood compels you to obey [master.owner.current.p_them()] in all things, even offering your own life to prolong theirs.\n\ + You are not required to obey any other Bloodsucker, for only [master.owner.current] is your master. The laws of Nanotrasen do not apply to you now; only your vampiric master's word must be obeyed.")) + owner.current.playsound_local(null, 'sound/effects/magic/mutate.ogg', 100, FALSE, pressure_affected = FALSE) + antag_memory += "You, becoming the mortal servant of [master.owner.current], a bloodsucking vampire!
    " + /// Message told to your Master. + to_chat(master.owner, span_userdanger("[owner.current] has become addicted to your immortal blood. [capitalize(owner.current.p_they(TRUE))] [owner.current.p_are()] now your mortal servant!")) + master.owner.current.playsound_local(null, 'sound/effects/magic/mutate.ogg', 100, FALSE, pressure_affected = FALSE) + +/datum/antagonist/ghoul/farewell() + if(silent) + return + + owner.current.visible_message( + span_deconversion_message("[owner.current]'s eyes dart feverishly from side to side, and then stop. [owner.current.p_They(TRUE)] seem[owner.current.p_s()] to calm, \ + like [owner.current.p_they()] [owner.current.p_have()] regained some lost part of [owner.current.p_them()]self."), \ + span_deconversion_message("With a snap, you are no longer enslaved to [master.owner]! You breathe in heavily, having regained your free will.")) + owner.current.playsound_local(null, 'sound/effects/magic/mutate.ogg', 100, FALSE, pressure_affected = FALSE) + /// Message told to your (former) Master. + if(master && master.owner) + to_chat(master.owner, span_cult_bold("You feel the bond with your ghoul [owner.current] has somehow been broken!")) + +/datum/antagonist/ghoul/admin_add(datum/mind/new_owner, mob/admin) + var/list/datum/mind/possible_vampires = list() + for(var/datum/antagonist/bloodsucker/bloodsuckerdatums in GLOB.antagonists) + var/datum/mind/vamp = bloodsuckerdatums.owner + if(!vamp) + continue + if(!vamp.current) + continue + if(vamp.current.stat == DEAD) + continue + possible_vampires += vamp + if(!length(possible_vampires)) + message_admins("[key_name_admin(admin)] tried ghoulizing [key_name_admin(new_owner)], but there were no bloodsuckers!") + return + var/datum/mind/choice = tgui_input_list(admin, "Which bloodsucker should this ghoul belong to?", "Bloodsucker", possible_vampires) + if(!choice) + return + log_admin("[key_name_admin(admin)] turned [key_name_admin(new_owner)] into a ghoul of [key_name_admin(choice)]!") + var/datum/antagonist/bloodsucker/vampire = IS_BLOODSUCKER(choice.current) + master = vampire + new_owner.add_antag_datum(src) + to_chat(choice, span_notice("Through divine intervention, you've gained a new ghoul!")) diff --git a/tff_modular/modules/bloodsucker/vassal/vassal_pinpointer.dm b/tff_modular/modules/bloodsucker/vassal/vassal_pinpointer.dm new file mode 100644 index 00000000000..82412a34eca --- /dev/null +++ b/tff_modular/modules/bloodsucker/vassal/vassal_pinpointer.dm @@ -0,0 +1,31 @@ +/** + * # Ghoul Pinpointer + * + * Pinpointer that points to their Master's location at all times. + * Unlike the Monster hunter one, this one is permanently active, and has no power needed to activate it. + */ + +/atom/movable/screen/alert/status_effect/agent_pinpointer/ghoul_edition + name = "Blood Bond" + desc = "You always know where your master is." + +/datum/status_effect/agent_pinpointer/ghoul_edition + id = "agent_pinpointer" + alert_type = /atom/movable/screen/alert/status_effect/agent_pinpointer/ghoul_edition + minimum_range = GHOUL_SCAN_MIN_DISTANCE + tick_interval = GHOUL_SCAN_PING_TIME + duration = STATUS_EFFECT_PERMANENT + range_fuzz_factor = 0 + +/datum/status_effect/agent_pinpointer/ghoul_edition/on_creation(mob/living/new_owner, ...) + ..() + var/datum/antagonist/ghoul/antag_datum = new_owner.mind.has_antag_datum(/datum/antagonist/ghoul) + scan_target = antag_datum?.master?.owner?.current + +/datum/status_effect/agent_pinpointer/ghoul_edition/scan_for_target() + return + +/datum/status_effect/agent_pinpointer/ghoul_edition/Destroy() + if(scan_target) + to_chat(owner, span_notice("You've lost your master's trail.")) + return ..() diff --git a/tff_modular/modules/bloodsucker/vassal/vassal_procs.dm b/tff_modular/modules/bloodsucker/vassal/vassal_procs.dm new file mode 100644 index 00000000000..e0d8945f59e --- /dev/null +++ b/tff_modular/modules/bloodsucker/vassal/vassal_procs.dm @@ -0,0 +1,77 @@ +/datum/antagonist/ghoul/proc/give_warning(atom/source, danger_level, vampire_warning_message, ghoul_warning_message) + SIGNAL_HANDLER + if(ghoul_warning_message) + to_chat(owner, ghoul_warning_message) + +/** + * Returns a Ghouls's examine strings. + * Args: + * viewer - The person examining. + */ +/datum/antagonist/ghoul/proc/return_ghoul_examine(mob/living/viewer) + if((!viewer.mind && !isobserver(viewer)) || !iscarbon(owner.current)) + return FALSE + var/mob/living/carbon/carbon_current = owner.current + // Target must be a Ghoul + // Default String + var/returnString = "\[" + var/returnIcon = "" + // Ghouls and Bloodsuckers recognize eachother, while Monster Hunters can see Ghouls. + if(!IS_BLOODSUCKER(viewer) && !IS_GHOUL(viewer) && !IS_MONSTERHUNTER(viewer) && !isobserver(viewer)) + return FALSE + // Am I Viewer's Ghoul? + if(master.owner == viewer.mind) + returnString += "This [carbon_current.dna.species.name] bears YOUR mark!" + returnIcon = "[icon2html('tff_modular/modules/bloodsucker/icons/language.dmi', world, "ghoul")]" + // Am I someone ELSE'S Ghoul? + else if(IS_BLOODSUCKER(viewer) || IS_MONSTERHUNTER(viewer) || isobserver(viewer)) + returnString += "This [carbon_current.dna.species.name] bears the mark of [master.return_full_name()][master.broke_masquerade ? " who has broken the Masquerade" : ""]" + returnIcon = "[icon2html('tff_modular/modules/bloodsucker/icons/language.dmi', world, "ghoul_grey")]" + // Are you serving the same master as I am? + else if(viewer.mind.has_antag_datum(/datum/antagonist/ghoul) in master.ghouls) + returnString += "[p_they(TRUE)] bears the mark of your Master" + returnIcon = "[icon2html('tff_modular/modules/bloodsucker/icons/language.dmi', world, "ghoul")]" + // You serve a different Master than I do. + else + returnString += "[p_they(TRUE)] bears the mark of another Bloodsucker" + returnIcon = "[icon2html('tff_modular/modules/bloodsucker/icons/language.dmi', world, "ghoul_grey")]" + + returnString += "\]" // \n" Don't need spacers. Using . += "" in examine.dm does this on its own. + return returnIcon + returnString + +/// Used when your Master teaches you a new Power. +/datum/antagonist/ghoul/proc/BuyPower(datum/action/cooldown/power, list_to_add_to = powers) + for(var/datum/action/current_powers as anything in list_to_add_to) + if(current_powers.type == power.type) + return FALSE + power = new power() + list_to_add_to += power + power.Grant(owner.current) + log_uplink("[key_name(owner.current)] purchased [power].") + return TRUE + +/datum/antagonist/ghoul/proc/LevelUpPowers() + for(var/datum/action/cooldown/bloodsucker/power in powers) + power.level_current++ + +/// Called when we are made into the Favorite Ghoul +/datum/antagonist/ghoul/proc/make_special(datum/antagonist/ghoul/ghoul_type) + //store what we need + var/datum/mind/ghoul_owner = owner + var/datum/antagonist/bloodsucker/bloodsuckerdatum = master + + //remove our antag datum + silent = TRUE + ghoul_owner.remove_antag_datum(/datum/antagonist/ghoul) + + //give our new one + var/datum/antagonist/ghoul/ghouldatum = new ghoul_type(ghoul_owner) + ghouldatum.master = bloodsuckerdatum + ghouldatum.silent = TRUE + ghoul_owner.add_antag_datum(ghouldatum) + ghouldatum.silent = FALSE + + //send alerts of completion + to_chat(master, span_danger("You have turned [ghoul_owner.current] into your [ghouldatum.name]! They will no longer be deconverted upon Mindshielding!")) + to_chat(ghoul_owner, span_notice("As Blood drips over your body, you feel closer to your Master... You are now the [ghouldatum.name]!")) + ghoul_owner.current.playsound_local(null, 'sound/effects/magic/mutate.ogg', 75, FALSE, pressure_affected = FALSE) diff --git a/tff_modular/modules/bloodsucker/vassal/vassal_types/ex_vassal.dm b/tff_modular/modules/bloodsucker/vassal/vassal_types/ex_vassal.dm new file mode 100644 index 00000000000..42aeaa819db --- /dev/null +++ b/tff_modular/modules/bloodsucker/vassal/vassal_types/ex_vassal.dm @@ -0,0 +1,103 @@ +#define BLOOD_TIMER_REQUIREMENT (10 MINUTES) +#define BLOOD_TIMER_HALWAY (BLOOD_TIMER_REQUIREMENT / 2) + +/datum/antagonist/ex_ghoul + name = "\improper Ex-Ghoul" + roundend_category = "ghouls" + antagpanel_category = "Bloodsucker" + pref_flag = ROLE_VASSAL + antag_hud_name = "ghoul_grey" + show_in_roundend = FALSE + show_in_antagpanel = FALSE + silent = TRUE + ui_name = FALSE + hud_icon = 'tff_modular/modules/bloodsucker/icons/hud.dmi' + + ///The revenge ghoul that brought us into the fold. + var/datum/antagonist/ghoul/revenge/revenge_ghoul + ///Timer we have to live + COOLDOWN_DECLARE(blood_timer) + +/datum/antagonist/ex_ghoul/on_gain() + . = ..() + RegisterSignal(owner.current, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) + +/datum/antagonist/ex_ghoul/on_removal() + if(revenge_ghoul) + revenge_ghoul.ex_ghouls -= src + revenge_ghoul = null + blood_timer = null + return ..() + +/datum/antagonist/ex_ghoul/proc/on_examine(datum/source, mob/examiner, examine_text) + SIGNAL_HANDLER + + var/datum/antagonist/ghoul/revenge/ghouldatum = IS_REVENGE_GHOUL(examiner) + if(ghouldatum && !revenge_ghoul) + examine_text += span_notice("[owner.current] is an ex-ghoul!") + +/datum/antagonist/ex_ghoul/add_team_hud(mob/target) + QDEL_NULL(team_hud_ref) + + team_hud_ref = WEAKREF(target.add_alt_appearance( + /datum/atom_hud/alternate_appearance/basic/has_antagonist, + "antag_team_hud_[REF(src)]", + hud_image_on(target), + )) + + var/datum/atom_hud/alternate_appearance/basic/has_antagonist/hud = team_hud_ref.resolve() + + var/list/mob/living/mob_list = list() + mob_list += revenge_ghoul.owner.current + for(var/datum/antagonist/ex_ghoul/former_ghouls as anything in revenge_ghoul.ex_ghouls) + mob_list += former_ghouls.owner.current + + for (var/datum/atom_hud/alternate_appearance/basic/has_antagonist/antag_hud as anything in GLOB.has_antagonist_huds) + if(!(antag_hud.target in mob_list)) + continue + antag_hud.show_to(target) + hud.show_to(antag_hud.target) + +/** + * Fold return + * + * Called when a Revenge bloodsucker gets a ghoul back into the fold. + */ +/datum/antagonist/ex_ghoul/proc/return_to_fold(datum/antagonist/ghoul/revenge/mike_ehrmantraut) + revenge_ghoul = mike_ehrmantraut + mike_ehrmantraut.ex_ghouls += src + COOLDOWN_START(src, blood_timer, BLOOD_TIMER_REQUIREMENT) + add_team_hud(owner.current) + + RegisterSignal(src, COMSIG_LIVING_LIFE, PROC_REF(on_life)) + +/datum/antagonist/ex_ghoul/proc/on_life(datum/source, seconds_per_tick, times_fired) + SIGNAL_HANDLER + + if(COOLDOWN_TIMELEFT(src, blood_timer) <= BLOOD_TIMER_HALWAY + 2 && COOLDOWN_TIMELEFT(src, blood_timer) >= BLOOD_TIMER_HALWAY - 2) //just about halfway + to_chat(owner.current, span_cult_bold("You need new blood from your Master!")) + if(!COOLDOWN_FINISHED(src, blood_timer)) + return + to_chat(owner.current, span_cult_bold("You are out of blood!")) + to_chat(revenge_ghoul.owner.current, span_cult_bold("[owner.current] has ran out of blood and is no longer in the fold!")) + owner.remove_antag_datum(/datum/antagonist/ex_ghoul) + + +/** + * Bloodsucker Blood + * + * Artificially made, this must be fed to ex-ghouls to keep them on their high. + */ +/datum/reagent/blood/bloodsucker + name = "Blood two" + +/datum/reagent/blood/bloodsucker/expose_mob(mob/living/exposed_mob, methods, reac_volume, show_message, touch_protection) + var/datum/antagonist/ex_ghoul/former_ghoul = exposed_mob.mind.has_antag_datum(/datum/antagonist/ex_ghoul) + if(former_ghoul) + to_chat(exposed_mob, span_cult("You feel the blood restore you... You feel safe.")) + COOLDOWN_RESET(former_ghoul, blood_timer) + COOLDOWN_START(former_ghoul, blood_timer, BLOOD_TIMER_REQUIREMENT) + return ..() + +#undef BLOOD_TIMER_REQUIREMENT +#undef BLOOD_TIMER_HALWAY diff --git a/tff_modular/modules/bloodsucker/vassal/vassal_types/favorite_vassal.dm b/tff_modular/modules/bloodsucker/vassal/vassal_types/favorite_vassal.dm new file mode 100644 index 00000000000..a8375f011d1 --- /dev/null +++ b/tff_modular/modules/bloodsucker/vassal/vassal_types/favorite_vassal.dm @@ -0,0 +1,28 @@ +/** + * Favorite Ghoul + * + * Gets some cool abilities depending on the Clan. + */ +/datum/antagonist/ghoul/favorite + name = "\improper Favorite Ghoul" + antag_hud_name = "ghoul6" + special_type = FAVORITE_GHOUL + ghoul_description = "The Favorite Ghoul gets unique abilities over other Ghouls depending on the Master's Clan \ + and becomes completely immune to Mindshields. If part of Ventrue, this is the Ghoul a Bloodsucker will rank up." + + ///Bloodsucker levels, but for Ghouls, used by Ventrue. Used for ventrue creating a new bloodsucker. + var/ghoul_level + /// Power's we're going to inherit once we turn into a Bloodsucker + var/list/bloodsucker_powers = list() + +/datum/antagonist/ghoul/favorite/on_gain() + . = ..() + SEND_SIGNAL(master, COMSIG_BLOODSUCKER_MAKE_FAVORITE, src) + +/datum/antagonist/ghoul/favorite/on_removal() + SEND_SIGNAL(master, COMSIG_BLOODSUCKER_LOOSE_FAVORITE, src) + remove_powers(bloodsucker_powers) + . = ..() + +/datum/antagonist/ghoul/favorite/pre_mindshield(mob/implanter, mob/living/mob_override) + return COMPONENT_MINDSHIELD_RESISTED diff --git a/tff_modular/modules/bloodsucker/vassal/vassal_types/revenge_vassal.dm b/tff_modular/modules/bloodsucker/vassal/vassal_types/revenge_vassal.dm new file mode 100644 index 00000000000..e1496c54bd7 --- /dev/null +++ b/tff_modular/modules/bloodsucker/vassal/vassal_types/revenge_vassal.dm @@ -0,0 +1,68 @@ +/** + * Revenge Ghoul + * + * Has the goal to 'get revenge' when their Master dies. + */ +/datum/antagonist/ghoul/revenge + name = "\improper Revenge Ghoul" + roundend_category = "abandoned Ghouls" + show_in_roundend = FALSE + show_in_antagpanel = FALSE + antag_hud_name = "ghoul4" + special_type = REVENGE_GHOUL + ghoul_description = "The Revenge Ghoul will not deconvert on a Bloodsucker's Final Death, \ + instead they will gain all your Powers, and the objective to take revenge for your demise. \ + They additionally maintain Ghouls their Master's departure, rather than become aimless." + + ///all ex-ghouls brought back into the fold. + var/list/datum/antagonist/ex_ghoul/ex_ghouls = list() + +/datum/antagonist/ghoul/revenge/roundend_report() + var/list/report = list() + report += printplayer(owner) + if(objectives.len) + report += printobjectives(objectives) + + // Now list their ghouls + if(ex_ghouls.len) + report += "The Ghouls brought back into the fold were..." + for(var/datum/antagonist/ex_ghoul/all_ghouls as anything in ex_ghouls) + if(!all_ghouls.owner) + continue + report += "[all_ghouls.owner.name] the [all_ghouls.owner.assigned_role.title]" + + return report.Join("
    ") + +/datum/antagonist/ghoul/revenge/on_gain() + . = ..() + RegisterSignal(master, COMSIG_BLOODSUCKER_FINAL_DEATH, PROC_REF(on_master_death)) + +/datum/antagonist/ghoul/revenge/on_removal() + UnregisterSignal(master, COMSIG_BLOODSUCKER_FINAL_DEATH) + return ..() + +/datum/antagonist/ghoul/revenge/proc/on_master_death(datum/antagonist/bloodsucker/bloodsuckerdatum, mob/living/carbon/master) + SIGNAL_HANDLER + + show_in_roundend = TRUE + for(var/datum/objective/all_objectives as anything in objectives) + objectives -= all_objectives + BuyPower(/datum/action/cooldown/bloodsucker/ghoul_blood) + for(var/datum/action/cooldown/bloodsucker/master_powers as anything in bloodsuckerdatum.powers) + if(master_powers.purchase_flags & BLOODSUCKER_DEFAULT_POWER) + continue + master_powers.Grant(owner.current) + owner.current.remove_status_effect(/datum/status_effect/agent_pinpointer/ghoul_edition) + + var/datum/objective/survive/new_objective = new + new_objective.name = "Avenge your Master" + new_objective.explanation_text = "Avenge your Master's final death by felling the ones that killed them, recruiting their ex-ghouls and continuing their operations." + new_objective.owner = owner + objectives += new_objective + + antag_panel_title = "You are a Ghoul tasked with taking revenge for the death of your Master!" + antag_panel_description = "You have gained your Master's old Powers, and a brand new \ + power. You will have to survive and maintain your old \ + Master's integrity. Bring their old Ghouls back into the \ + fold using your new Ability." + update_static_data_for_all_viewers() diff --git a/tff_modular/strings/malkavian_revelations.json b/tff_modular/strings/malkavian_revelations.json new file mode 100644 index 00000000000..710e98f149e --- /dev/null +++ b/tff_modular/strings/malkavian_revelations.json @@ -0,0 +1,58 @@ +{ + "revelations": [ + "#Существует целое пространственное измерение, видимое исключительно в крови, но мы никогда его не увидим.", + "#Взрывы происходят так часто, что я боюсь под них попасть.", + "#Капитан однажды падёт, все временно.", + "#Здесь всегда есть чему-то просветиться, у кого-то научиться, что-то прочитать.", + "#Почему мы были брошены в этой вселенной? Когда нас заберут?", + "#Когда сны перестанут преследовать меня? Почему из всех людей они выбрали меня?", + "#Тот кто слышит голоса в голове зовется дураком, но делает ли это его безумным?", + "#Ах милый... Возможно в своей жизни я зашел слишком далеко. Интересно что будет дальше.", + "#Иногда мне кажется, я последний пророк... Возможно так и есть.", + "#Интересно что привело меня к этому пути. Моя кровь? Моя ненависть к тем, кто окружает меня?", + "#Мне стоит понять что приводит меня к моим действиям, или я не должен.", + "#Если я сфокусируюсь на своих целях, а не на моих желаниях, буду ли я счастлив?", + "#Возможно... В другой вселенной, я... Я буду частью семьи, что любит меня.", + "#Страшно представить что люди думают обо мне, скорее всего что-то ужасное.", + "#Я был так близок к какой-то идее, но я потерял ее нить...", + "#Что произойдет когда вся органика умрет? Вся неорганика просто останется?", + "#Что бы случилось, если бы я убил члена командования?", + "#Все думают что я дурак, но по крайней мере я не страшен, тогда бы они извинялись.", + "#Не забудь помолиться, чтобы получить помощь!", + "#Интересно, приняли бы меня таким какой я есть?", + "#Здесь пришельцы, они существуют. Это не заговор. Настоящий вопрос это когда они будут атаковать нас.", + "#Повреждение мозга реально, или это наш мозг адаптируется к новой реальности?", + "#Никогда не заключай сделку с дьяволом... Худшая ошибка в моей жизни.", + "#Генокрады более чистая форма людей... Если бы люди были самыми нечистыми существами.", + "#Как там поживает дьявол? Давно его не видел.", + "#Для меня это ничего не значит, парень.", + "#Я никому не лоялен, я демон.", + "#Я ни к кому не испытываю преданности, никогда не испытывал и не буду испытывать.", + "#Коротышка решила быть с демоном, похоже это ее проблема!", + "#Ты видишь, я действительно сделал это, я действительно он.", + "#Превратил кирпичик в империю, хватит играть со мной.", + "Я это он! Я был им!! Я продолжу быть им!!!", + "#Они думают, что победили демона, но я вернулся!", + "#Ты не можешь верить мне, даже я не верю себе. Я даже не знаю кто я теперь.", + "#У них амнезия, они забыли что я был им.", + "#Я видел Великую хартию вольностей. Я видел Око Горы.", + "#Ты думаешь меня это волнует? Спроси, волнует ли это меня, потому что мне плевать! Если бы я получал 1 кредит каждый раз когда они говорят что мне не плевать, я бы был бедным, потому что мне плевать!", + "#Этот 357-й калибр заставил меня двигаться, как инвазивный вид.", + "#Я делаю плохо прикосновение Мидаса.", + "#Я убью етбя!",, + "#Подожди, дай мне сделать пару глотков.", + "#Маскарад должен соблюдаться также, как хранят ядерный диск, это то что охраняет нас от того, кто снизу...", + "#150, 149, 148... 147, 146, 145, 144... Какое мое число, напомни?", + "#Неважно что мы будем делать, мы все равно будем ощущать боль.", + "Куда я пошел в своей жизни не туда, чтобы оказаться здесь...", + "#Тот, кто знает все уловки монстра, обязательно придет. Только время покажет, когда.", + "#Что мы делаем на этой станции? Разве мы не знаем что это все плохо закончится?", + "#Мне интересно что сказали бы древние греческие философы, оказавшись здесь.", + "#Если бы только все видели мир так, как вижу его я.", + "#Что сделало человечество, чтобы заслужить мое существование?", + "#Если бог существует, как он позволил мне появиться?", + "#...Я, кажется, потерял нить чего-то, не могу понять чего...", + "#Личность которую все пытаются заткнуть, это та личность, которую все будут желать вернуть.", + "#Это твоя вина." + ] +} diff --git a/tgstation.dme b/tgstation.dme index 6984691c622..5832cb86724 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -417,6 +417,7 @@ #include "code\__DEFINES\traits\macros.dm" #include "code\__DEFINES\traits\sources.dm" #include "code\__DEFINES\~ff_defines\barsigns.dm" +#include "code\__DEFINES\~ff_defines\bloodsucker.dm" #include "code\__DEFINES\~ff_defines\DNA.dm" #include "code\__DEFINES\~ff_defines\flavor_misc.dm" #include "code\__DEFINES\~ff_defines\food_defines.dm" @@ -9556,6 +9557,57 @@ #include "tff_modular\modules\autoaccent\code\autoaccent.dm" #include "tff_modular\modules\bar_jukebox\code\jukebox.dm" #include "tff_modular\modules\barsigns\code\barsigns.dm" +#include "tff_modular\modules\bloodsucker\bloodsuckers\assets.dm" +#include "tff_modular\modules\bloodsucker\bloodsuckers\bloodsucker.dm" +#include "tff_modular\modules\bloodsucker\bloodsuckers\clans.dm" +#include "tff_modular\modules\bloodsucker\bloodsuckers\conversion.dm" +#include "tff_modular\modules\bloodsucker\bloodsuckers\crafts.dm" +#include "tff_modular\modules\bloodsucker\bloodsuckers\hud.dm" +#include "tff_modular\modules\bloodsucker\bloodsuckers\integration.dm" +#include "tff_modular\modules\bloodsucker\bloodsuckers\life.dm" +#include "tff_modular\modules\bloodsucker\bloodsuckers\movable_hud.dm" +#include "tff_modular\modules\bloodsucker\bloodsuckers\names.dm" +#include "tff_modular\modules\bloodsucker\bloodsuckers\objectives.dm" +#include "tff_modular\modules\bloodsucker\bloodsuckers\procs.dm" +#include "tff_modular\modules\bloodsucker\bloodsuckers\shaded_bloodsucker.dm" +#include "tff_modular\modules\bloodsucker\bloodsuckers\species.dm" +#include "tff_modular\modules\bloodsucker\bloodsuckers\trauma.dm" +#include "tff_modular\modules\bloodsucker\clans\clan.dm" +#include "tff_modular\modules\bloodsucker\clans\clan_flavortext.dm" +#include "tff_modular\modules\bloodsucker\clans\clan_malkavian.dm" +#include "tff_modular\modules\bloodsucker\clans\clan_nosferatu.dm" +#include "tff_modular\modules\bloodsucker\clans\clan_tremere.dm" +#include "tff_modular\modules\bloodsucker\clans\clan_ventrue.dm" +#include "tff_modular\modules\bloodsucker\powers\_powers.dm" +#include "tff_modular\modules\bloodsucker\powers\cloak.dm" +#include "tff_modular\modules\bloodsucker\powers\feed.dm" +#include "tff_modular\modules\bloodsucker\powers\fortitude.dm" +#include "tff_modular\modules\bloodsucker\powers\gohome.dm" +#include "tff_modular\modules\bloodsucker\powers\masquerade.dm" +#include "tff_modular\modules\bloodsucker\powers\veil.dm" +#include "tff_modular\modules\bloodsucker\powers\targeted\_powers_targeted.dm" +#include "tff_modular\modules\bloodsucker\powers\targeted\brawn.dm" +#include "tff_modular\modules\bloodsucker\powers\targeted\haste.dm" +#include "tff_modular\modules\bloodsucker\powers\targeted\lunge.dm" +#include "tff_modular\modules\bloodsucker\powers\targeted\mesmerize.dm" +#include "tff_modular\modules\bloodsucker\powers\targeted\trespass.dm" +#include "tff_modular\modules\bloodsucker\powers\tremere\_powers_tremere.dm" +#include "tff_modular\modules\bloodsucker\powers\tremere\auspex.dm" +#include "tff_modular\modules\bloodsucker\powers\tremere\dominate.dm" +#include "tff_modular\modules\bloodsucker\powers\tremere\thaumaturgy.dm" +#include "tff_modular\modules\bloodsucker\powers\vassal\distress.dm" +#include "tff_modular\modules\bloodsucker\powers\vassal\recuperate.dm" +#include "tff_modular\modules\bloodsucker\powers\vassal\vassal_fold.dm" +#include "tff_modular\modules\bloodsucker\structures\coffin.dm" +#include "tff_modular\modules\bloodsucker\structures\crypt.dm" +#include "tff_modular\modules\bloodsucker\structures\objects.dm" +#include "tff_modular\modules\bloodsucker\vassal\batform.dm" +#include "tff_modular\modules\bloodsucker\vassal\vassal_datum.dm" +#include "tff_modular\modules\bloodsucker\vassal\vassal_pinpointer.dm" +#include "tff_modular\modules\bloodsucker\vassal\vassal_procs.dm" +#include "tff_modular\modules\bloodsucker\vassal\vassal_types\ex_vassal.dm" +#include "tff_modular\modules\bloodsucker\vassal\vassal_types\favorite_vassal.dm" +#include "tff_modular\modules\bloodsucker\vassal\vassal_types\revenge_vassal.dm" #include "tff_modular\modules\blooper\atoms_movable.dm" #include "tff_modular\modules\blooper\bark.dm" #include "tff_modular\modules\blooper\bark_list.dm" diff --git a/tgui/packages/tgui/interfaces/AntagInfoBloodsucker.tsx b/tgui/packages/tgui/interfaces/AntagInfoBloodsucker.tsx new file mode 100644 index 00000000000..13e5ccee597 --- /dev/null +++ b/tgui/packages/tgui/interfaces/AntagInfoBloodsucker.tsx @@ -0,0 +1,229 @@ +import { useState } from 'react'; +import { Box, Button, Image, Section, Stack, Tabs } from 'tgui-core/components'; +import type { BooleanLike } from 'tgui-core/react'; + +import { resolveAsset } from '../assets'; +import { useBackend } from '../backend'; +import { Window } from '../layouts'; +import type { Objective } from './common/Objectives'; +import { PowerDetails } from './PowerInfo'; + +export type ClanProps = { + clan: ClanInfo[]; + in_clan: BooleanLike; +}; + +export type ClanInfo = { + clan_name: string; + clan_description: string; + clan_icon: string; +}; + +export type PowerInfo = { + power_name: string; + power_explanation: string[]; + power_icon: string; +}; + +export type BloodsuckerProps = { + powers: PowerInfo[]; + objectives: Objective[]; +}; +export type GhoulProps = BloodsuckerProps & { + title: string; + description: string; +}; + +const ObjectivePrintout = (props: any) => { + const { data } = useBackend(); + const { objectives } = data; + return ( + + Your current objectives: + + {(!objectives && 'None!') || + objectives.map((objective) => ( + + #{objective.count}: {objective.explanation} + + ))} + + + ); +}; + +export const AntagInfoBloodsucker = (props: any) => { + const [tab, setTab] = useState(1); + return ( + + + + setTab(1)} + > + Introduction + + setTab(2)} + > + Clan & Powers + + + {tab === 1 && } + {tab === 2 && } + + + ); +}; + +const BloodsuckerIntro = () => { + return ( + + +

    + + + You are a Bloodsucker, an undead blood-seeking monster living + aboard Space Station 13 + + + + + +
    + + +
    + + + + You regenerate your health slowly, you're weak to fire, and + you depend on blood to survive. Don't allow your blood to + run too low, or you'll enter a + + Frenzy!
    + + Beware of your Humanity level! The more Humanity you lose, the + easier it is to fall into a{' '} + Frenzy! + +
    + + Avoid using your Feed ability while near others, or else you + will risk breaking the Masquerade! + + + Loosing your heart will render your powers useless, but going + into a coffin with a heart inside will allow you to regenerate + it. + +
    +
    +
    +
    + +
    + + + Rest in a Coffin to claim it, and that area, as your haven. +
    + Examine your new structures to see how they function! +
    + Medical analyzers and the book of kindred can sell you out, your + Masquerade ability will hide your identity to prevent this. +
    + You will learn how to make persuasion racks once you have enough + levels to support a ghoul, which you will learn during torpor + during daytime. Examine the ghoul rack to see how many ghouls you + can have! +
    + You cannot level up until you select a clan. To select a clan, + click the clan tab on the top right of this window. +
    + Ensure to read the descriptions of each ability in the Clan & + Powers tab, you may learn something new! +
    + After a certain level, Sol will no longer grant you levels, + instead, you will need to feed on the blood of others to gain + levels. +
    + +
    + Other Bloodsuckers are not necessarily your friends, but your + survival may depend on cooperation. Betray them at your own + discretion and peril. +
    +
    +
    +
    +
    + + ); +}; + +const BloodsuckerClan = (props: any) => { + const { act, data } = useBackend(); + const { clan, in_clan, powers } = data; + + if (!in_clan) { + return ( +
    + + You are not in a Clan. + + + + +
    + ); + } + + return ( + + +
    + + + {clan.map((ClanInfo) => ( + <> + + + You are part of the {ClanInfo.clan_name} + + + {ClanInfo.clan_description} + + + ))} + + +
    +
    + +
    + ); +}; diff --git a/tgui/packages/tgui/interfaces/KindredBook.tsx b/tgui/packages/tgui/interfaces/KindredBook.tsx new file mode 100644 index 00000000000..d92ca61680a --- /dev/null +++ b/tgui/packages/tgui/interfaces/KindredBook.tsx @@ -0,0 +1,43 @@ +import { Collapsible, Section, Table } from 'tgui-core/components'; + +import { useBackend } from '../backend'; +import { Window } from '../layouts'; + +type Data = { + clans: ClanInfo[]; +}; + +type ClanInfo = { + clan_name: string; + clan_desc: string; +}; + +export const KindredBook = (props) => { + const { data } = useBackend(); + const { clans } = data; + return ( + + +
    + + + Written by generations of Curators, this holds all information we + the Curators know about the undead threat that looms the + station... + + So, what Clan are you interested in? +
    + + + {clans.map((clan) => ( + + {clan.clan_desc} + + ))} + +
    +
    +
    +
    + ); +}; From 169cf1088b7c6d901630d48813ee6c4514a585b2 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sun, 8 Mar 2026 17:49:06 +0300 Subject: [PATCH 002/149] =?UTF-8?q?=D0=BC=D1=8F=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tgstation.dme | 1 + 1 file changed, 1 insertion(+) diff --git a/tgstation.dme b/tgstation.dme index 5832cb86724..ba4413a8cb6 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -9570,6 +9570,7 @@ #include "tff_modular\modules\bloodsucker\bloodsuckers\objectives.dm" #include "tff_modular\modules\bloodsucker\bloodsuckers\procs.dm" #include "tff_modular\modules\bloodsucker\bloodsuckers\shaded_bloodsucker.dm" +#include "tff_modular\modules\bloodsucker\bloodsuckers\sol.dm" #include "tff_modular\modules\bloodsucker\bloodsuckers\species.dm" #include "tff_modular\modules\bloodsucker\bloodsuckers\trauma.dm" #include "tff_modular\modules\bloodsucker\clans\clan.dm" From 584049e6564b4ca09f629db961c5927ccf78db5f Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sun, 8 Mar 2026 17:51:04 +0300 Subject: [PATCH 003/149] 111 --- tff_modular/modules/bloodsucker/clans/clan_malkavian.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tff_modular/modules/bloodsucker/clans/clan_malkavian.dm b/tff_modular/modules/bloodsucker/clans/clan_malkavian.dm index ff2f4a0ae22..d2ce6e4aee0 100644 --- a/tff_modular/modules/bloodsucker/clans/clan_malkavian.dm +++ b/tff_modular/modules/bloodsucker/clans/clan_malkavian.dm @@ -23,7 +23,7 @@ var/mob/living/carbon/carbon_owner = bloodsuckerdatum.owner.current if(istype(carbon_owner)) carbon_owner.gain_trauma(/datum/brain_trauma/mild/hallucinations, TRAUMA_RESILIENCE_ABSOLUTE) - carbon_owner.gain_trauma(/datum/brain_trauma/special/bluespace_prophet, TRAUMA_RESILIENCE_ABSOLUTE) + carbon_owner.gain_trauma(/datum/brain_trauma/special/bluespace_prophet/phobetor, TRAUMA_RESILIENCE_ABSOLUTE) owner_datum.owner.current.update_sight() bloodsuckerdatum.owner.current.playsound_local(get_turf(bloodsuckerdatum.owner.current), 'sound/music/antag/creepalert.ogg', 80, FALSE, pressure_affected = FALSE, use_reverb = FALSE) @@ -35,7 +35,7 @@ var/mob/living/carbon/carbon_owner = bloodsuckerdatum.owner.current if(istype(carbon_owner)) carbon_owner.cure_trauma_type(/datum/brain_trauma/mild/hallucinations, TRAUMA_RESILIENCE_ABSOLUTE) - carbon_owner.cure_trauma_type(/datum/brain_trauma/special/bluespace_prophet, TRAUMA_RESILIENCE_ABSOLUTE) + carbon_owner.cure_trauma_type(/datum/brain_trauma/special/bluespace_prophet/phobetor, TRAUMA_RESILIENCE_ABSOLUTE) bloodsuckerdatum.owner.current.update_sight() return ..() From f5a414d19c2defc7050ff0c65ed8751e2d251977 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sun, 8 Mar 2026 18:53:03 +0300 Subject: [PATCH 004/149] =?UTF-8?q?=D0=B1=D0=B0=D0=B9=D1=82=20=D0=BD=D0=B0?= =?UTF-8?q?=20=D0=BB=D0=B0=D0=B9=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bloodsucker/bloodsuckers/bloodsucker.dm | 2 +- .../modules/bloodsucker/bloodsuckers/life.dm | 12 +++--- tff_modular/modules/bloodsucker/clans/clan.dm | 2 +- .../bloodsucker/clans/clan_malkavian.dm | 2 +- .../modules/bloodsucker/powers/fortitude.dm | 43 ++----------------- .../bloodsucker/powers/targeted/haste.dm | 2 +- .../bloodsucker/powers/targeted/lunge.dm | 2 +- .../bloodsucker/powers/targeted/mesmerize.dm | 2 +- .../bloodsucker/powers/tremere/thaumaturgy.dm | 4 +- 9 files changed, 17 insertions(+), 54 deletions(-) diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm b/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm index f4b6d2c1ee2..b9d24e8a558 100644 --- a/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm +++ b/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm @@ -59,7 +59,7 @@ VAR_PRIVATE/bloodsucker_level_unspent = 1 var/additional_regen var/blood_over_cap = 0 - var/bloodsucker_regen_rate = 0.3 + var/bloodsucker_regen_rate = 0.4 // Used for Bloodsucker Objectives var/area/bloodsucker_haven_area diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/life.dm b/tff_modular/modules/bloodsucker/bloodsuckers/life.dm index 7e14a4ceb1f..487c68222a5 100644 --- a/tff_modular/modules/bloodsucker/bloodsuckers/life.dm +++ b/tff_modular/modules/bloodsucker/bloodsuckers/life.dm @@ -292,17 +292,17 @@ if(bloodsucker_blood_volume < frenzy_enter_threshold() && !frenzied) owner.current.apply_status_effect(/datum/status_effect/frenzy) else if(bloodsucker_blood_volume < BLOOD_VOLUME_BAD) - additional_regen = 0.1 - else if(bloodsucker_blood_volume < BLOOD_VOLUME_OKAY) additional_regen = 0.2 - else if(bloodsucker_blood_volume < BLOOD_VOLUME_NORMAL) + else if(bloodsucker_blood_volume < BLOOD_VOLUME_OKAY) additional_regen = 0.3 - else if(bloodsucker_blood_volume < BS_BLOOD_VOLUME_MAX_REGEN) + else if(bloodsucker_blood_volume < BLOOD_VOLUME_NORMAL) additional_regen = 0.4 - else if(bloodsucker_blood_volume < max_blood_volume) + else if(bloodsucker_blood_volume < BS_BLOOD_VOLUME_MAX_REGEN) additional_regen = 0.5 + else if(bloodsucker_blood_volume < max_blood_volume) + additional_regen = 0.6 else if(bloodsucker_blood_volume > max_blood_volume) - additional_regen = 1 + round((blood_over_cap / 1000) * 2, 0.1) + additional_regen = 1.35 + round((blood_over_cap / 1000) * 2, 0.1) AdjustBloodVolume(-1 - blood_over_cap / 100) /// Makes your blood_volume look like your bloodsucker blood, unless you're Masquerading. diff --git a/tff_modular/modules/bloodsucker/clans/clan.dm b/tff_modular/modules/bloodsucker/clans/clan.dm index e7e4ab5aaba..c72ec8a3944 100644 --- a/tff_modular/modules/bloodsucker/clans/clan.dm +++ b/tff_modular/modules/bloodsucker/clans/clan.dm @@ -203,7 +203,7 @@ /datum/bloodsucker_clan/proc/finalize_spend_rank(datum/antagonist/bloodsucker/source, cost_rank = TRUE, blood_cost) level_up_powers(source) - bloodsuckerdatum.bloodsucker_regen_rate += 0.05 + bloodsuckerdatum.bloodsucker_regen_rate += 0.1 bloodsuckerdatum.max_blood_volume += 100 if(ishuman(bloodsuckerdatum.owner.current)) diff --git a/tff_modular/modules/bloodsucker/clans/clan_malkavian.dm b/tff_modular/modules/bloodsucker/clans/clan_malkavian.dm index d2ce6e4aee0..b5c97f750b8 100644 --- a/tff_modular/modules/bloodsucker/clans/clan_malkavian.dm +++ b/tff_modular/modules/bloodsucker/clans/clan_malkavian.dm @@ -23,7 +23,7 @@ var/mob/living/carbon/carbon_owner = bloodsuckerdatum.owner.current if(istype(carbon_owner)) carbon_owner.gain_trauma(/datum/brain_trauma/mild/hallucinations, TRAUMA_RESILIENCE_ABSOLUTE) - carbon_owner.gain_trauma(/datum/brain_trauma/special/bluespace_prophet/phobetor, TRAUMA_RESILIENCE_ABSOLUTE) + carbon_owner.gain_trauma(/datum/brain_trauma/special/bluespace_prophet/phobetor , TRAUMA_RESILIENCE_ABSOLUTE) owner_datum.owner.current.update_sight() bloodsuckerdatum.owner.current.playsound_local(get_turf(bloodsuckerdatum.owner.current), 'sound/music/antag/creepalert.ogg', 80, FALSE, pressure_affected = FALSE, use_reverb = FALSE) diff --git a/tff_modular/modules/bloodsucker/powers/fortitude.dm b/tff_modular/modules/bloodsucker/powers/fortitude.dm index a306c7d113a..3d8ab524c68 100644 --- a/tff_modular/modules/bloodsucker/powers/fortitude.dm +++ b/tff_modular/modules/bloodsucker/powers/fortitude.dm @@ -6,10 +6,9 @@ power_flags = BP_CONTINUOUS_EFFECT|BP_AM_COSTLESS_UNCONSCIOUS check_flags = BP_CANT_USE_IN_TORPOR|BP_CANT_USE_IN_FRENZY purchase_flags = BLOODSUCKER_CAN_BUY|GHOUL_CAN_BUY - cooldown_time = 20 SECONDS + cooldown_time = 10 SECONDS bloodcost = 30 constant_bloodcost = 0.2 - var/was_running var/fortitude_resist // So we can raise and lower your brute resist based on what your level_current WAS. var/list/trigger_listening = list() var/traits_to_add = list(TRAIT_PIERCEIMMUNE, TRAIT_NODISMEMBER, TRAIT_PUSHIMMUNE) @@ -18,8 +17,7 @@ . = list() . += "Fortitude will provide pierce, stun and dismember immunity." . += "You will additionally gain resistance to both brute, burn and stamina damage, scaling with level." - . += "Fortitude will make you receive [GetFortitudeResist() * 10]% less brute and and stamina and [GetBurnResist() * 10]% less burn damage." - . += "While using Fortitude, attempting to run will crush you." + . += "Fortitude will make you receive [GetFortitudeResist() * 10]% less brute, stamina and [GetFortitudeResist() * 10]% less burn damage." . += "At level [FORTITUDE_STUN_IMMUNITY_LEVEL], you gain complete stun immunity while [src] is active." . += "Higher levels will increase Brute and Stamina resistance." @@ -38,17 +36,9 @@ if(IS_BLOODSUCKER(owner) || IS_GHOUL(owner)) fortitude_resist = GetFortitudeResist() bloodsucker_user.physiology.brute_mod *= fortitude_resist - bloodsucker_user.physiology.burn_mod *= GetBurnResist() + bloodsucker_user.physiology.burn_mod *= fortitude_resist bloodsucker_user.physiology.stamina_mod *= fortitude_resist - was_running = (bloodsucker_user.move_intent == MOVE_INTENT_RUN) - if(was_running) - bloodsucker_user.toggle_move_intent() - for(var/power in bloodsuckerdatum_power.powers) - if(!istype(power, /datum/action/cooldown/bloodsucker/targeted/haste)) - continue - RegisterSignal(power, COMSIG_FIRE_TARGETED_POWER, PROC_REF(on_action_trigger)) - trigger_listening += power RegisterSignal(owner, COMSIG_LIVING_ADJUST_BRUTE_DAMAGE, PROC_REF(on_heal)) RegisterSignal(owner, COMSIG_LIVING_ADJUST_BURN_DAMAGE, PROC_REF(on_heal)) return TRUE @@ -58,34 +48,9 @@ return COMPONENT_IGNORE_CHANGE return NONE -/datum/action/cooldown/bloodsucker/fortitude/proc/on_action_trigger(datum/action, mob/target) - SIGNAL_HANDLER - addtimer(CALLBACK(src, PROC_REF(DeactivatePower)), 1 SECONDS) - return TRUE - /datum/action/cooldown/bloodsucker/fortitude/proc/GetFortitudeResist() return max(0.3, 0.7 - level_current * 0.05) -/datum/action/cooldown/bloodsucker/fortitude/proc/GetBurnResist() - return GetFortitudeResist() + 0.2 - -/datum/action/cooldown/bloodsucker/fortitude/process(seconds_per_tick) - // Checks that we can keep using this. - . = ..() - if(!.) - return - if(!active) - return - var/mob/living/carbon/user = owner - /// Prevents running while on Fortitude - if(user.move_intent != MOVE_INTENT_WALK) - user.toggle_move_intent() - user.balloon_alert(user, "you attempt to run, crushing yourself.") - user.adjust_brute_loss(rand(5,15)) - /// We don't want people using fortitude being able to use vehicles - if(user.buckled && istype(user.buckled, /obj/vehicle)) - user.buckled.unbuckle_mob(src, force=TRUE) - /datum/action/cooldown/bloodsucker/fortitude/DeactivatePower(deactivate_flags) if(length(trigger_listening)) for(var/power in trigger_listening) @@ -102,8 +67,6 @@ // Remove Traits & Effects owner.remove_traits(traits_to_add, BLOODSUCKER_TRAIT) - if(was_running && bloodsucker_user.move_intent == MOVE_INTENT_WALK) - bloodsucker_user.toggle_move_intent() owner.balloon_alert(owner, "fortitude turned off.") fortitude_resist = 1 UnregisterSignal(owner, list(COMSIG_LIVING_ADJUST_BRUTE_DAMAGE, COMSIG_LIVING_ADJUST_BURN_DAMAGE)) diff --git a/tff_modular/modules/bloodsucker/powers/targeted/haste.dm b/tff_modular/modules/bloodsucker/powers/targeted/haste.dm index ce1a39b3b3b..94b841ed27c 100644 --- a/tff_modular/modules/bloodsucker/powers/targeted/haste.dm +++ b/tff_modular/modules/bloodsucker/powers/targeted/haste.dm @@ -11,7 +11,7 @@ prefire_message = "You prepare to dash!" purchase_flags = BLOODSUCKER_CAN_BUY|GHOUL_CAN_BUY bloodcost = 6 - cooldown_time = 12 SECONDS + cooldown_time = 8 SECONDS target_range = 5 power_activates_immediately = FALSE ///List of all people hit by our power, so we don't hit them again. diff --git a/tff_modular/modules/bloodsucker/powers/targeted/lunge.dm b/tff_modular/modules/bloodsucker/powers/targeted/lunge.dm index e519c3724d8..18985b1ec79 100644 --- a/tff_modular/modules/bloodsucker/powers/targeted/lunge.dm +++ b/tff_modular/modules/bloodsucker/powers/targeted/lunge.dm @@ -8,7 +8,7 @@ check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_INCAPACITATED|AB_CHECK_LYING|AB_CHECK_PHASED|AB_CHECK_LYING purchase_flags = BLOODSUCKER_CAN_BUY|GHOUL_CAN_BUY bloodcost = 10 - cooldown_time = 10 SECONDS + cooldown_time = 9 SECONDS power_activates_immediately = FALSE unset_after_click = FALSE diff --git a/tff_modular/modules/bloodsucker/powers/targeted/mesmerize.dm b/tff_modular/modules/bloodsucker/powers/targeted/mesmerize.dm index 0bf234dd852..b1f3c976729 100644 --- a/tff_modular/modules/bloodsucker/powers/targeted/mesmerize.dm +++ b/tff_modular/modules/bloodsucker/powers/targeted/mesmerize.dm @@ -16,7 +16,7 @@ power_flags = NONE purchase_flags = BLOODSUCKER_CAN_BUY|GHOUL_CAN_BUY bloodcost = 30 - cooldown_time = 30 SECONDS + cooldown_time = 15 SECONDS target_range = 4 power_activates_immediately = FALSE unset_after_click = FALSE diff --git a/tff_modular/modules/bloodsucker/powers/tremere/thaumaturgy.dm b/tff_modular/modules/bloodsucker/powers/tremere/thaumaturgy.dm index 6adf88b10a2..383b7e64e2e 100644 --- a/tff_modular/modules/bloodsucker/powers/tremere/thaumaturgy.dm +++ b/tff_modular/modules/bloodsucker/powers/tremere/thaumaturgy.dm @@ -136,8 +136,8 @@ /datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy/proc/get_blood_bolt_damage() if(level_current >= THAUMATURGY_EXTRA_DAMAGE_LEVEL) - return 40 - return 20 + return 54 + return 27 /datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy/proc/get_max_charges() return level_current * 2 From 33c67483a19e58a63893a3bac6c90ff072364069 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sun, 8 Mar 2026 20:34:35 +0300 Subject: [PATCH 005/149] =?UTF-8?q?=D0=B0=D0=BF=D0=B4=D0=B5=D0=B9=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modules/bloodsucker/bloodsuckers/bloodsucker.dm | 9 +++++---- tff_modular/modules/bloodsucker/bloodsuckers/life.dm | 7 ++----- tff_modular/modules/bloodsucker/bloodsuckers/sol.dm | 3 +-- tff_modular/modules/bloodsucker/powers/fortitude.dm | 2 +- tff_modular/modules/bloodsucker/powers/targeted/brawn.dm | 4 ++-- 5 files changed, 11 insertions(+), 14 deletions(-) diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm b/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm index b9d24e8a558..50f99f91072 100644 --- a/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm +++ b/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm @@ -235,6 +235,7 @@ // Assign Powers give_starting_powers() assign_starting_stats() + RegisterSignal(SSsol, COMSIG_SOL_RANKUP_BLOODSUCKERS, PROC_REF(sol_rank_up)) /// Called by the remove_antag_datum() and remove_all_antag_datums() mind procs for the antag datum to handle its own removal and deletion. /datum/antagonist/bloodsucker/on_removal() @@ -426,10 +427,10 @@ var/obj/item/bodypart/user_left_arm = user.get_bodypart(BODY_ZONE_L_ARM) var/obj/item/bodypart/user_right_arm = user.get_bodypart(BODY_ZONE_R_ARM) user.dna?.remove_all_mutations() - user_left_arm.unarmed_damage_low += 1 //lowest possible punch damage - 6 now - user_left_arm.unarmed_damage_high += 1 //highest possible punch damage - 11 - user_right_arm.unarmed_damage_low += 1 //lowest possible punch damage - 6 - user_right_arm.unarmed_damage_high += 1 //highest possible punch damage - 11 + user_left_arm.unarmed_damage_low += 2 //lowest possible punch damage - 6 now + user_left_arm.unarmed_damage_high += 2 //highest possible punch damage - 11 + user_right_arm.unarmed_damage_low += 2 //lowest possible punch damage - 6 + user_right_arm.unarmed_damage_high += 2 //highest possible punch damage - 11 user.mob_biotypes |= biotype //Give Bloodsucker Traits owner.current.add_traits(bloodsucker_traits, BLOODSUCKER_TRAIT) diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/life.dm b/tff_modular/modules/bloodsucker/bloodsuckers/life.dm index 487c68222a5..8b7f1a52013 100644 --- a/tff_modular/modules/bloodsucker/bloodsuckers/life.dm +++ b/tff_modular/modules/bloodsucker/bloodsuckers/life.dm @@ -112,8 +112,8 @@ // If you're a synth, you heal prosthetic damage. var/bruteLoss = get_brute_loss() var/bruteheal = min(bruteLoss, actual_regen) // BRUTE: Always Heal - var/fireheal = 0 // BURN: Heal in Coffin while Fakedeath, or when damage above maxhealth (you can never fully heal fire) - // Checks if you're in a coffin here, additionally checks for Torpor right below it. + var/fireLoss = get_fire_loss() + var/fireheal = min(brute_loss, actual_regen * 0.75) var/amInCoffin = is_valid_coffin() if (blood_over_cap > 0) costMult += round(blood_over_cap / 1000, 0.1) // effectively 1 (normal) + 0.1 for every 100 blood you are over cap @@ -122,7 +122,6 @@ to_chat(user, span_alert("You do not heal while your Masquerade ability is active.")) COOLDOWN_START(src, bloodsucker_spam_healing, BLOODSUCKER_SPAM_MASQUERADE) return FALSE - fireheal = min(get_fire_loss(), actual_regen) mult *= 5 // Increase multiplier if we're sleeping in a coffin. costMult *= COFFIN_HEAL_COST_MULT // Decrease cost if we're sleeping in a coffin. user.extinguish_mob() @@ -135,8 +134,6 @@ return TRUE // In Torpor, but not in a Coffin? Heal faster anyways. else if(is_in_torpor()) - var/fireloss = get_fire_loss() - fireheal = min(fireloss, actual_regen) / 1.2 // 20% slower than being in a coffin mult *= 3 // Heal if Damaged if((bruteheal + fireheal) && mult != 0) // Just a check? Don't heal/spend, and return. diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/sol.dm b/tff_modular/modules/bloodsucker/bloodsuckers/sol.dm index 9e0b15489be..ea45a92eea4 100644 --- a/tff_modular/modules/bloodsucker/bloodsuckers/sol.dm +++ b/tff_modular/modules/bloodsucker/bloodsuckers/sol.dm @@ -110,10 +110,9 @@ SUBSYSTEM_DEF(sol) else if(total_brute <= 10) torpor_end() - //monkestation edit if(COOLDOWN_FINISHED(src, bloodsucker_torpor_max_time)) torpor_end() // YOUR TAKING TOO LONG - //monkestation end + /datum/antagonist/bloodsucker/proc/is_in_torpor() if(QDELETED(owner.current)) return FALSE diff --git a/tff_modular/modules/bloodsucker/powers/fortitude.dm b/tff_modular/modules/bloodsucker/powers/fortitude.dm index 3d8ab524c68..c7ba5fecb06 100644 --- a/tff_modular/modules/bloodsucker/powers/fortitude.dm +++ b/tff_modular/modules/bloodsucker/powers/fortitude.dm @@ -62,7 +62,7 @@ var/mob/living/carbon/human/bloodsucker_user = owner if(IS_BLOODSUCKER(owner) || IS_GHOUL(owner) && fortitude_resist) bloodsucker_user.physiology.brute_mod /= fortitude_resist - bloodsucker_user.physiology.burn_mod /= fortitude_resist + 0.2 + bloodsucker_user.physiology.burn_mod /= fortitude_resist bloodsucker_user.physiology.stamina_mod /= fortitude_resist // Remove Traits & Effects owner.remove_traits(traits_to_add, BLOODSUCKER_TRAIT) diff --git a/tff_modular/modules/bloodsucker/powers/targeted/brawn.dm b/tff_modular/modules/bloodsucker/powers/targeted/brawn.dm index fbcf1362629..a27bf47362e 100644 --- a/tff_modular/modules/bloodsucker/powers/targeted/brawn.dm +++ b/tff_modular/modules/bloodsucker/powers/targeted/brawn.dm @@ -7,7 +7,7 @@ button_icon_state = "power_strength" purchase_flags = BLOODSUCKER_CAN_BUY|GHOUL_CAN_BUY bloodcost = 10 - cooldown_time = 12 SECONDS + cooldown_time = 8 SECONDS target_range = 1 prefire_message = "Select a target." @@ -198,7 +198,7 @@ return GetPunchDamage(user_active_arm.unarmed_damage_high) /datum/action/cooldown/bloodsucker/targeted/brawn/proc/GetPunchDamage(punch_damage) - return punch_damage * 1.25 + 2 + return punch_damage * 2 + 5 /datum/action/cooldown/bloodsucker/targeted/brawn/CheckValidTarget(atom/target_atom) . = ..() From ef3f48769c1ad57790df5a65cce59da185911834 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sun, 8 Mar 2026 20:41:24 +0300 Subject: [PATCH 006/149] =?UTF-8?q?=D1=84=D0=B8=D0=BA=D1=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tff_modular/modules/bloodsucker/bloodsuckers/life.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/life.dm b/tff_modular/modules/bloodsucker/bloodsuckers/life.dm index 8b7f1a52013..71aa1fd51a6 100644 --- a/tff_modular/modules/bloodsucker/bloodsuckers/life.dm +++ b/tff_modular/modules/bloodsucker/bloodsuckers/life.dm @@ -113,7 +113,7 @@ var/bruteLoss = get_brute_loss() var/bruteheal = min(bruteLoss, actual_regen) // BRUTE: Always Heal var/fireLoss = get_fire_loss() - var/fireheal = min(brute_loss, actual_regen * 0.75) + var/fireheal = min(fireLoss, actual_regen * 0.75) var/amInCoffin = is_valid_coffin() if (blood_over_cap > 0) costMult += round(blood_over_cap / 1000, 0.1) // effectively 1 (normal) + 0.1 for every 100 blood you are over cap From 76e36da2ede5814aad4ccbfa3a32c801f0a02069 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Tue, 10 Mar 2026 10:20:43 +0300 Subject: [PATCH 007/149] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D1=8F=D0=B5=D0=BC=20=D0=BF=D1=80=D0=B8=D0=BD=D1=86=D0=B0,=20?= =?UTF-8?q?=D0=B1=D0=B8=D1=87=D0=B0,=20=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D1=8F=D0=B5=D0=BC=20=D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D1=83?= =?UTF-8?q?=20=D0=B0=D0=B1=D0=B8=D0=BB=D0=BA=D0=B8=20gohome?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/_globalvars/~ff_globalvars/lists/mobs.dm | 2 + .../bloodsucker/bloodsuckers/bloodsucker.dm | 7 +- .../modules/bloodsucker/bloodsuckers/life.dm | 7 +- .../modules/bloodsucker/bloodsuckers/sol.dm | 32 --- tff_modular/modules/bloodsucker/clans/clan.dm | 2 + .../bloodsucker/clans/clan_malkavian.dm | 1 + .../modules/bloodsucker/clans/clan_tremere.dm | 1 + .../modules/bloodsucker/clans/clan_ventrue.dm | 3 +- .../modules/bloodsucker/controllers.dm | 203 ++++++++++++++++++ .../bloodsucker/icons/actions_vampire.dmi | Bin 0 -> 25783 bytes .../modules/bloodsucker/icons/bloodsucker.dmi | Bin 20484 -> 26432 bytes .../modules/bloodsucker/icons/clan_icons.dmi | Bin 16483 -> 13545 bytes .../modules/bloodsucker/icons/disciplines.dmi | Bin 0 -> 1144 bytes .../modules/bloodsucker/icons/vampiric.dmi | Bin 0 -> 668 bytes .../modules/bloodsucker/powers/gohome.dm | 12 +- .../bloodsucker/powers/prince/scourgify.dm | 125 +++++++++++ .../modules/bloodsucker/sound/auspex.ogg | Bin 0 -> 32465 bytes .../modules/bloodsucker/sound/awo1.ogg | Bin 0 -> 36063 bytes .../modules/bloodsucker/sound/bloodbolt.ogg | Bin 0 -> 14083 bytes .../bloodsucker/sound/bloodbolt_fire.ogg | Bin 0 -> 12259 bytes .../bloodsucker/sound/bloodhealing.ogg | Bin 0 -> 18784 bytes .../modules/bloodsucker/sound/bloodneed.ogg | Bin 0 -> 26036 bytes .../bloodsucker/sound/burning_death.ogg | Bin 0 -> 24102 bytes .../bloodsucker/sound/coffin_close.ogg | Bin 0 -> 55584 bytes .../modules/bloodsucker/sound/coffin_open.ogg | Bin 0 -> 66698 bytes .../modules/bloodsucker/sound/drinkblood1.ogg | Bin 0 -> 54662 bytes .../bloodsucker/sound/fortitude_off.ogg | Bin 0 -> 24886 bytes .../bloodsucker/sound/fortitude_on.ogg | Bin 0 -> 14575 bytes .../modules/bloodsucker/sound/griffin_1.ogg | Bin 4117 -> 1964 bytes .../modules/bloodsucker/sound/griffin_10.ogg | Bin 7282 -> 5235 bytes .../modules/bloodsucker/sound/griffin_2.ogg | Bin 4352 -> 2224 bytes .../modules/bloodsucker/sound/griffin_3.ogg | Bin 4912 -> 2828 bytes .../modules/bloodsucker/sound/griffin_4.ogg | Bin 5274 -> 3171 bytes .../modules/bloodsucker/sound/griffin_5.ogg | Bin 5512 -> 3413 bytes .../modules/bloodsucker/sound/griffin_6.ogg | Bin 5895 -> 3830 bytes .../modules/bloodsucker/sound/griffin_7.ogg | Bin 6307 -> 4255 bytes .../modules/bloodsucker/sound/griffin_8.ogg | Bin 6620 -> 4569 bytes .../modules/bloodsucker/sound/griffin_9.ogg | Bin 6913 -> 4881 bytes .../modules/bloodsucker/sound/growl.ogg | Bin 0 -> 31438 bytes .../bloodsucker/sound/humanity_gain.ogg | Bin 0 -> 10036 bytes .../bloodsucker/sound/humanity_loss.ogg | Bin 0 -> 11068 bytes .../modules/bloodsucker/sound/lunge_warn.ogg | Bin 73076 -> 68328 bytes .../sound/masquerade_violation.ogg | Bin 0 -> 23111 bytes .../modules/bloodsucker/sound/mesmerize.ogg | Bin 0 -> 13485 bytes .../modules/bloodsucker/sound/prince.ogg | Bin 0 -> 19756 bytes .../bloodsucker/sound/rage_decrease.ogg | Bin 0 -> 49301 bytes .../bloodsucker/sound/rage_increase.ogg | Bin 0 -> 45155 bytes .../bloodsucker/sound/scourge_offer.ogg | Bin 0 -> 10438 bytes .../bloodsucker/sound/scourge_recruit.ogg | Bin 0 -> 11296 bytes .../modules/bloodsucker/sound/wolf_ask.ogg | Bin 0 -> 15191 bytes .../modules/bloodsucker/sound/wolf_speak.ogg | Bin 0 -> 9414 bytes .../modules/bloodsucker/structures/coffin.dm | 4 + tgstation.dme | 3 + 53 files changed, 360 insertions(+), 42 deletions(-) create mode 100644 code/_globalvars/~ff_globalvars/lists/mobs.dm create mode 100644 tff_modular/modules/bloodsucker/controllers.dm create mode 100644 tff_modular/modules/bloodsucker/icons/actions_vampire.dmi create mode 100644 tff_modular/modules/bloodsucker/icons/disciplines.dmi create mode 100644 tff_modular/modules/bloodsucker/icons/vampiric.dmi create mode 100644 tff_modular/modules/bloodsucker/powers/prince/scourgify.dm create mode 100644 tff_modular/modules/bloodsucker/sound/auspex.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/awo1.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/bloodbolt.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/bloodbolt_fire.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/bloodhealing.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/bloodneed.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/burning_death.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/coffin_close.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/coffin_open.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/drinkblood1.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/fortitude_off.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/fortitude_on.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/growl.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/humanity_gain.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/humanity_loss.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/masquerade_violation.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/mesmerize.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/prince.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/rage_decrease.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/rage_increase.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/scourge_offer.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/scourge_recruit.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/wolf_ask.ogg create mode 100644 tff_modular/modules/bloodsucker/sound/wolf_speak.ogg diff --git a/code/_globalvars/~ff_globalvars/lists/mobs.dm b/code/_globalvars/~ff_globalvars/lists/mobs.dm new file mode 100644 index 00000000000..d9ec248e1d0 --- /dev/null +++ b/code/_globalvars/~ff_globalvars/lists/mobs.dm @@ -0,0 +1,2 @@ +GLOBAL_LIST_EMPTY(all_vampires) +GLOBAL_LIST_EMPTY(masquerade_breakers) diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm b/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm index 50f99f91072..5ea2046d9cc 100644 --- a/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm +++ b/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm @@ -127,6 +127,9 @@ COMSIG_HUMAN_ON_HANDLE_BLOOD = PROC_REF(HandleBlood), ) + var/prince = FALSE + var/scourge = FALSE + /** * Apply innate effects is everything given to the mob * When a body is tranferred, this is called on the new mob @@ -139,7 +142,7 @@ talking_head(current_mob) handle_clown_mutation(current_mob, mob_override ? null : "As a vampiric clown, you are no longer a danger to yourself. Your clownish nature has been subdued by your thirst for blood.") add_team_hud(current_mob) - + RegisterSignal(SSsol, COMSIG_SOL_RANKUP_BLOODSUCKERS, PROC_REF(sol_rank_up)) if(current_mob.hud_used) on_hud_created() else @@ -160,6 +163,7 @@ /datum/antagonist/bloodsucker/remove_innate_effects(mob/living/mob_override) . = ..() var/mob/living/carbon/current_mob = mob_override || owner.current + UnregisterSignal(SSsol, COMSIG_SOL_RANKUP_BLOODSUCKERS) unregister_body_signals(current_mob) handle_clown_mutation(current_mob, removing = FALSE) if(current_mob.hud_used) @@ -235,7 +239,6 @@ // Assign Powers give_starting_powers() assign_starting_stats() - RegisterSignal(SSsol, COMSIG_SOL_RANKUP_BLOODSUCKERS, PROC_REF(sol_rank_up)) /// Called by the remove_antag_datum() and remove_all_antag_datums() mind procs for the antag datum to handle its own removal and deletion. /datum/antagonist/bloodsucker/on_removal() diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/life.dm b/tff_modular/modules/bloodsucker/bloodsuckers/life.dm index 71aa1fd51a6..2dca18af946 100644 --- a/tff_modular/modules/bloodsucker/bloodsuckers/life.dm +++ b/tff_modular/modules/bloodsucker/bloodsuckers/life.dm @@ -122,7 +122,7 @@ to_chat(user, span_alert("You do not heal while your Masquerade ability is active.")) COOLDOWN_START(src, bloodsucker_spam_healing, BLOODSUCKER_SPAM_MASQUERADE) return FALSE - mult *= 5 // Increase multiplier if we're sleeping in a coffin. + mult *= 6 // Increase multiplier if we're sleeping in a coffin. costMult *= COFFIN_HEAL_COST_MULT // Decrease cost if we're sleeping in a coffin. user.extinguish_mob() user.bodytemperature = user.get_body_temp_normal() @@ -134,12 +134,11 @@ return TRUE // In Torpor, but not in a Coffin? Heal faster anyways. else if(is_in_torpor()) - mult *= 3 + mult *= 4 // Heal if Damaged if((bruteheal + fireheal) && mult != 0) // Just a check? Don't heal/spend, and return. // We have damage. Let's heal (one time), and don't cost any blood if we cannot - if(!user.adjust_brute_loss(-bruteheal * mult, updating_health = FALSE) && !user.adjust_fire_loss(-fireheal * mult, updating_health = FALSE)) // Heal BRUTE / BURN in random portions throughout the body. - return FALSE + user.heal_overall_damage(brute = bruteheal * mult, burn = fireheal * mult) user.updatehealth() AdjustBloodVolume(((bruteheal * -0.5) + (fireheal * -1)) * costMult * mult) // Costs blood to heal return TRUE diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/sol.dm b/tff_modular/modules/bloodsucker/bloodsuckers/sol.dm index ea45a92eea4..18f6b488083 100644 --- a/tff_modular/modules/bloodsucker/bloodsuckers/sol.dm +++ b/tff_modular/modules/bloodsucker/bloodsuckers/sol.dm @@ -1,35 +1,3 @@ -///Legacy name - now refers to the time between free levels for vampires. -#define TIME_BLOODSUCKER_NIGHT 600 - -SUBSYSTEM_DEF(sol) - name = "Sol" - can_fire = FALSE - wait = 20 // ticks, not seconds (so this runs every second, actually) - flags = SS_NO_INIT | SS_BACKGROUND | SS_TICKER | SS_KEEP_TIMING - - ///The time between the next cycle. - var/time_til_cycle = TIME_BLOODSUCKER_NIGHT - ///If Bloodsucker levels for the night has been given out yet. - var/issued_XP = FALSE - -/datum/controller/subsystem/sol/Recover() - can_fire = SSsol.can_fire - time_til_cycle = SSsol.time_til_cycle - issued_XP = SSsol.issued_XP - -/datum/controller/subsystem/sol/fire(resumed = FALSE) - time_til_cycle-- - - if (time_til_cycle > 0 && time_til_cycle <= 15) - if (!issued_XP) - issued_XP = TRUE - SEND_SIGNAL(src, COMSIG_SOL_RANKUP_BLOODSUCKERS) - - if (time_til_cycle < 1) - issued_XP = FALSE - time_til_cycle = TIME_BLOODSUCKER_NIGHT - -#undef TIME_BLOODSUCKER_NIGHT /** * # Assigning Sol diff --git a/tff_modular/modules/bloodsucker/clans/clan.dm b/tff_modular/modules/bloodsucker/clans/clan.dm index c72ec8a3944..d72e97b3d05 100644 --- a/tff_modular/modules/bloodsucker/clans/clan.dm +++ b/tff_modular/modules/bloodsucker/clans/clan.dm @@ -32,6 +32,8 @@ var/buy_power_flags = BLOODSUCKER_CAN_BUY // what percentage of blood you need to spend to level up, divided by 100 var/level_cost = BLOODSUCKER_LEVELUP_PERCENTAGE + // what bonus do we get for prince vote + var/princely_score_bonus = -10 // TODO add handling for body transfers /datum/bloodsucker_clan/New(datum/antagonist/bloodsucker/owner_datum) diff --git a/tff_modular/modules/bloodsucker/clans/clan_malkavian.dm b/tff_modular/modules/bloodsucker/clans/clan_malkavian.dm index b5c97f750b8..027a109558e 100644 --- a/tff_modular/modules/bloodsucker/clans/clan_malkavian.dm +++ b/tff_modular/modules/bloodsucker/clans/clan_malkavian.dm @@ -9,6 +9,7 @@ /// The prob chance of a malkavian spouting a revelation. var/max_madness_chance = 10 var/min_madness_chance = 5 + princely_score_bonus = 6 /datum/bloodsucker_clan/malkavian/on_enter_frenzy(datum/antagonist/bloodsucker/source) ADD_TRAIT(bloodsuckerdatum.owner.current, TRAIT_STUNIMMUNE, FRENZY_TRAIT) diff --git a/tff_modular/modules/bloodsucker/clans/clan_tremere.dm b/tff_modular/modules/bloodsucker/clans/clan_tremere.dm index d85d902d22d..6c41f42cc3c 100644 --- a/tff_modular/modules/bloodsucker/clans/clan_tremere.dm +++ b/tff_modular/modules/bloodsucker/clans/clan_tremere.dm @@ -9,6 +9,7 @@ join_description = "You will burn if you enter the Chapel, lose all default powers, \ but gain Blood Magic instead, stronger powers you level up overtime." buy_power_flags = TREMERE_CAN_BUY|CAN_BUY_OWNED + princely_score_bonus = 8 /datum/bloodsucker_clan/tremere/New(mob/living/carbon/user) . = ..() diff --git a/tff_modular/modules/bloodsucker/clans/clan_ventrue.dm b/tff_modular/modules/bloodsucker/clans/clan_ventrue.dm index 713fec66fe8..8c629faf656 100644 --- a/tff_modular/modules/bloodsucker/clans/clan_ventrue.dm +++ b/tff_modular/modules/bloodsucker/clans/clan_ventrue.dm @@ -1,5 +1,5 @@ ///The maximum level a Ventrue Bloodsucker can be, before they have to level up their ghoul instead. -#define VENTRUE_MAX_POWERS 3 +#define VENTRUE_MAX_POWERS 7 /datum/bloodsucker_clan/ventrue name = CLAN_VENTRUE @@ -13,6 +13,7 @@ instead you raise a ghoul into a Bloodsucker." blood_drink_type = BLOODSUCKER_DRINK_SNOBBY level_cost = BLOODSUCKER_LEVELUP_PERCENTAGE_VENTRUE + princely_score_bonus = 15 /datum/bloodsucker_clan/ventrue/New(datum/antagonist/bloodsucker/owner_datum) . = ..() diff --git a/tff_modular/modules/bloodsucker/controllers.dm b/tff_modular/modules/bloodsucker/controllers.dm new file mode 100644 index 00000000000..9c3cdebc3b8 --- /dev/null +++ b/tff_modular/modules/bloodsucker/controllers.dm @@ -0,0 +1,203 @@ +///Legacy name - now refers to the time between free levels for vampires. +#define TIME_BLOODSUCKER_NIGHT 600 + +SUBSYSTEM_DEF(sol) + name = "Sol" + can_fire = FALSE + wait = 20 // ticks, not seconds (so this runs every second, actually) + flags = SS_NO_INIT | SS_BACKGROUND | SS_TICKER | SS_KEEP_TIMING + + ///The time between the next cycle. + var/time_til_cycle = TIME_BLOODSUCKER_NIGHT + ///If Bloodsucker levels for the night has been given out yet. + var/issued_XP = FALSE + +/datum/controller/subsystem/sol/Recover() + can_fire = SSsol.can_fire + time_til_cycle = SSsol.time_til_cycle + issued_XP = SSsol.issued_XP + +/datum/controller/subsystem/sol/fire(resumed = FALSE) + time_til_cycle-- + + if (time_til_cycle > 0 && time_til_cycle <= 15) + if (!issued_XP) + issued_XP = TRUE + SEND_SIGNAL(src, COMSIG_SOL_RANKUP_BLOODSUCKERS) + + if (time_til_cycle < 1) + issued_XP = FALSE + time_til_cycle = TIME_BLOODSUCKER_NIGHT + +#undef TIME_BLOODSUCKER_NIGHT + +SUBSYSTEM_DEF(vsociety) + name = "Vampire Society" + wait = 5 MINUTES + flags = SS_NO_INIT | SS_BACKGROUND + can_fire = FALSE + + var/pooling = FALSE + + var/datum/weakref/princedatum + + var/start_time = 0 + +/datum/controller/subsystem/vsociety/fire(resumed = FALSE) + var/time_elapsed = world.time - start_time + + if(time_elapsed < 9 MINUTES) + return + + if(!princedatum && !pooling) + for(var/datum/antagonist/vampire as anything in GLOB.all_vampires) + to_chat(vampire.owner.current, span_announce("*Vampire Tip: A vote for Prince will occur soon. If you are interested in leading your fellow kindred, press voting button!")) + addtimer(CALLBACK(src, PROC_REF(poll_for_prince)), 2 MINUTES) + message_admins("Vampire Society has fired, and a prince poll will occur in 2 minutes.") + log_game("Vampire society has fired, and a prince poll will occur soon.") + +/datum/controller/subsystem/vsociety/proc/poll_for_prince() + message_admins("Vampire society is now polling for a new prince.") + log_game("Vampire society is now polling for a new prince.") + + var/list/vampire_living_candidates = list() + + for(var/datum/antagonist/vampire as anything in GLOB.all_vampires) + var/currentmob = vampire.owner?.current + + if(!isliving(currentmob)) + continue + + var/mob/living/livingmob = currentmob + if(livingmob.health <= HEALTH_THRESHOLD_DEAD) + continue + + vampire_living_candidates += currentmob + + pooling = TRUE + var/icon/prince_icon = icon('tff_modular/modules/bloodsucker/icons/bloodsucker.dmi', "prince") + prince_icon.Scale(24, 24) + var/list/poolers = SSpolling.poll_candidates( + "You are eligible for princedom.", + poll_time = 3 MINUTES, + flash_window = TRUE, + group = vampire_living_candidates, + alert_pic = prince_icon, + role_name_text = "Prince", + custom_response_messages = list( + POLL_RESPONSE_SIGNUP = "You have made your bid for princedom.
    * Note: Princedom has certain expectations placed upon you. If you are not in a position to enforce a masquerade, consider letting someone else take this burden.", + POLL_RESPONSE_UNREGISTERED = "You have removed your bid to princedom.", + ), + amount_to_pick = length(GLOB.all_vampires), + announce_chosen = FALSE, + ) + pooling = FALSE + + var/datum/antagonist/bloodsucker/chosen_datum + var/mob/living/chosen_candidate + // We have to do this shit because the polling proc doesn't always return a list. Sometimes it just returns a mob. + var/list/candidates = list() + candidates += poolers + + for(var/mob/living/current_candidate in candidates) + var/datum/antagonist/bloodsucker/current_datum = IS_BLOODSUCKER(current_candidate) + if(!chosen_candidate) + chosen_candidate = current_candidate + chosen_datum = IS_BLOODSUCKER(current_candidate) + continue + if(current_datum.get_princely_score() >= chosen_datum.get_princely_score()) + chosen_candidate = current_candidate + chosen_datum = IS_BLOODSUCKER(current_candidate) + + if(chosen_datum) + chosen_datum.princify() + + + + +/datum/antagonist/bloodsucker/proc/check_start_society() + if(SSvsociety.can_fire) + return + if(length(GLOB.all_vampires) >= 3) + SSvsociety.start_time = world.time + SSvsociety.can_fire = TRUE + message_admins("Vampire Society has started, as there are [length(GLOB.all_vampires)] vampires active.") + log_game("Vampire Society has started, as there are [length(GLOB.all_vampires)] vampires active.") + +/datum/antagonist/bloodsucker/proc/check_cancel_society() + if(!SSvsociety.can_fire) + return + if(length(GLOB.all_vampires) < 3) + SSvsociety.can_fire = FALSE + message_admins("Vampire Society has paused, as there are only [length(GLOB.all_vampires)] vampires active.") + log_game("Vampire Society has paused, as there are only [length(GLOB.all_vampires)] vampires active.") + +/datum/antagonist/bloodsucker/proc/princify() + SSvsociety.princedatum = WEAKREF(src) + AdjustUnspentRank(8) + to_chat(owner.current, span_cult_bold("As a true prince, you find some of your old power returning to you!")) + owner.current.playsound_local(null, 'tff_modular/modules/bloodsucker/sound/prince.ogg', 100, FALSE, pressure_affected = FALSE) + prince = TRUE + add_team_hud(owner.current) + + var/full_name = return_full_name() + for(var/datum/antagonist/vampire as anything in GLOB.all_vampires) + to_chat(vampire.owner.current, span_narsiesmall("[full_name], also known as [owner.name || owner.current.real_name || owner.current.name], has claimed the role of Prince!")) + + BuyPower(/datum/action/cooldown/bloodsucker/targeted/scourgify) + + var/datum/objective/bloodsucker/prince/prince_objective = new() + objectives += prince_objective + owner.announce_objectives() + + message_admins("[ADMIN_LOOKUP(owner.current)] has received the role of Vampire Prince. ([get_princely_score()] princely score, with [my_clan?.princely_score_bonus]/[min(50, owner.current?.client?.get_exp_living(TRUE) / 60) / 10] clan/hour bonus.)") + log_game("[key_name(owner.current)] has become the Vampire Prince. ([get_princely_score()] princely score, with [my_clan?.princely_score_bonus]/[min(50, owner.current?.client?.get_exp_living(TRUE) / 60) / 10] clan/hour bonus.)") + + notify_ghosts( + "[owner.name] has become the Bloodsucker Prince!", + source = owner.current, + header = "All hail the Prince!" + ) + + update_static_data_for_all_viewers() + tgui_alert(owner.current, "Congratulations, you have been chosen for Princedom.\nPlease note that this entails a certain responsibility. Your job, now, is to keep order, and to enforce the masquerade.", "Welcome, my Prince.", list("I understand"), 30 SECONDS, TRUE) + +/datum/antagonist/bloodsucker/proc/scourgify() + ASSERT(!prince, "Somehow a prince was going to be turned into a scourge") + AdjustUnspentRank(4) + to_chat(owner.current, span_cult_bold("As a Camarilla scourge, your newfound purpose empowers you!")) + owner.current.playsound_local(null, 'tff_modular/modules/bloodsucker/sound/scourge_recruit.ogg', 100, FALSE, pressure_affected = FALSE) + scourge = TRUE + add_team_hud(owner.current) + var/datum/objective/bloodsucker/scourge/scourge_objectives = new() + objectives += scourge_objectives + owner.announce_objectives() + + for(var/datum/antagonist/bloodsucker as anything in GLOB.all_vampires) + to_chat(bloodsucker.owner.current, span_cult_bold(span_big("Under authority of the Prince, [owner.name || owner.current.real_name || owner.current.name] has been raised to the duty of the Scourge!"))) + message_admins("[ADMIN_LOOKUPFLW(owner.current)] has been made a Scourge of the Bloodsuckers!") + log_game("[key_name(owner.current)] has become a Scourge of the Bloodsuckers.") + + notify_ghosts( + "[owner.name] has been raised to the duty Scourge of the Bloodsuckers!", + source = owner.current, + header = "All hail the Prince!", + ) + + update_static_data_for_all_viewers() + +/datum/antagonist/bloodsucker/proc/get_princely_score() + var/calculated_hour_score = min(50, owner.current?.client?.get_exp_living(TRUE) / 60) / 10 + var/clan_bonus = my_clan?.princely_score_bonus || -10 + + return clan_bonus + calculated_hour_score + +/datum/objective/bloodsucker/scourge + name = "Camarilla Scourge" + explanation_text = "Obey your prince! Ensure order! Safeguard the Masquerade!" + completed = TRUE + +/datum/objective/bloodsucker/prince + name = "Camarilla Prince" + explanation_text = "Rule your fellow kindred with an iron fist! Ensure the sanctity of the Masquerade, at ALL costs!" + completed = TRUE diff --git a/tff_modular/modules/bloodsucker/icons/actions_vampire.dmi b/tff_modular/modules/bloodsucker/icons/actions_vampire.dmi new file mode 100644 index 0000000000000000000000000000000000000000..847f16ba9f62f539913e341c94f4b28f0d85c24b GIT binary patch literal 25783 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 literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/icons/bloodsucker.dmi b/tff_modular/modules/bloodsucker/icons/bloodsucker.dmi index 901589214ea27d40a9cf85be020b3aa2eb79f734..b179e1c27c3dc49530dd7f73804bf68cb1dc9dc9 100644 GIT binary patch literal 26432 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 aMX;*A!|}aVYbL%K2hdd4RjXF9iTEFZk-#bd literal 20484 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 V=o{ZQTfzVU002ovPDHLkV1o8DS*QR2 diff --git a/tff_modular/modules/bloodsucker/icons/clan_icons.dmi b/tff_modular/modules/bloodsucker/icons/clan_icons.dmi index f6242a2143db59626279769bb56470be464b99b4..b9cc68f03402777dfa211eb81051969541a64a2c 100644 GIT binary patch literal 13545 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 W|4@H#NBq|SfSk0FRMkh5p#KFV!0PJ& diff --git a/tff_modular/modules/bloodsucker/icons/disciplines.dmi b/tff_modular/modules/bloodsucker/icons/disciplines.dmi new file mode 100644 index 0000000000000000000000000000000000000000..7becdd41ac2a606bd06cfed18bb27952b197e63e GIT binary patch literal 1144 zcmV-;1c&>HP)V=-0C=2@l1*;HKn#V~nNy5lk4npy4FaJo${pOqAyzX#vOPd=-vJh^kh6Qw z`egfAUi#hP*q;3UyLA_2p%nerZ&n|!xl*rVHD8~u8IjJTK8+|SR=I#k0Va~La7|Av zwYGN6z!31MUu2PtHxs*%bjYCe3nm+I$|+DpG|>(xWYRwq%#4DuvpeRbv$+1gVbwN> z0b@1w{3e@zh9cdZu0vuaE&Yr@ToZvkTSq7XwD8%!rXc4UisT)+^oP^_@p=C)+Pl*~ zcc|e20016POjJbx0095ROZR{f(n$c)GXTvh8J-UhZ3+r00t5g60QPlyPXGV_0d!JM zQvg8b*k%9#11U*FK~#9!?U*rZ8%Z3+U8;!d?l|WncH>|NOAnMem`rS+jOpJpH?l4^#Iy{7<)=lH!3u z?_0Sa@ZuIS>0#fXcV6zo>faQ4wsGH3?_7Ul8^zyu!e>tuT7nn={R6JJxJDRyPYt*w zTSG`<*nZs*>)l;87o^I7BT2w$`|QO~9=jWaTjQMGT_A@Va2JZF`0v&5k9pT@((cZC z!?)}2l}oGsvwKH2fod53cz6E)rybvuTMxpF772)bF{Z2k@`u&=`TD;PJ3}PDzo6dZ z*w7&#Au_b45kvXYtj)*DTwY#WA>8_21JZMVBUVHH?Eb2Tl-*DHSpC^%h&5nSoa?q? z;6@)~`f}ym)!&sjSoB3&#L|Z$J%|A{ETX)b$~&bf@4gxi@5)t+v|h(o0_FZ1tJE-m zPtKY(?}L+A>-=P%?Eh2t!2sI-WREhS{1{+wAM`-19I`LUjH4AUL-C;d00(Hjua-f1 zG^17SeG5qgTKi@|+t?h0v(><}J1`ch_uLxOc;Uv{5-JnGA^QN(fcuvKVQ-DzaZn^6 z0*#mY-uno#gf8oy(T>lo0q(5;h62hoxkL8>5QvpS_C>h>%H%Kv-3LI}M&ayH2KKq! z9M<{CJk|fF?t>|w>wng)S-;6Xpv!3gmlDEFlskueLH7Za-V-bLZPO`(MS1WPbRT$D zS?aua&^o8kfN*aqBnfDtQG;YmF`4nL)P0O#1o;{ysnr~%+J z93OC7@LB7dXC|EzFlHYPe?K@@cO_$e&^=&`XUCJeFBs50z-q|}0kP!Pdg*@{Eu<3y za2^dH`%?na-eXKJ0rB_%eUbF{gDJh<|Hr+`ll?!Xx&LSVGW`J3XW;a-wbiZw0000< KMNUMnLSTZ8f-O)0 literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/icons/vampiric.dmi b/tff_modular/modules/bloodsucker/icons/vampiric.dmi new file mode 100644 index 0000000000000000000000000000000000000000..6b2be9eed78ed40370510a2245e608b49faa9170 GIT binary patch literal 668 zcmV;N0%QG&P)V=-0C=2@%D)Q2Fc5(8IrkJtyNd;J%OWX~p?w7j?U@|dKitKLZ|_iWle&E$ z{A#?kSKp)SJQNb;Wk!pq!x7Aj$DGh&a|V-$W6IlT4w=wmRl>BgPz7dWQMA~Axl5R6 z>#tjd=V71euskL1yAo8x<4<;rLhoO;#o z88ZMg|MA((|NsC0Gu`6r|J|YgzecmY&!(oP|8;d{%m9dzrK6P>w}LAFPfuNDbxc!V z{{S=0005Z)0A>IHCL9PE85uJGGZPgV4-XFj05bpp0GZHTtpET319VbOQvisF>QCK| z0003~Nkl6Rr^0-<8>qDuj@Q zkOXYc0;L9Q&jO=C=f$ooegX`chziHgl9{=1{45n7H@n;(S(qp@gaN|LnIVi>Sl0Em z+agSbi6EGHF3g;SORysADq?YkAX8y-1VKz;_MBgRJVl=I&4{2wnaH`w#was;%qPQs zgn*-j5@m9kjk2y+K@eL7<*5pZXBE`=dg**Nz&c+Hu<=Tzq7lH209K(II$sT)uSPo$ z1M`hBNyEl~dlBg}vVY?sg||-}M5(3~_PrIhtt-64I16tuxe#E0I<}60 z>E_Xx?ms#zO#_r(1GYB}*xqf3+s_SgdusU4U*rejv@isUEdYA}0000ERwohkr$Zu>L)>Dk_#!ZNB>XzhZ2rq$Br2U{t-lr5yY)8M1hUL#>RpGc>i945t?KDwE_kx2aAy`^A9GBvGDX7sq|WI>?CFIKQKi8^&N)n zpCRhM!~Zb;YaR*;pzua~8HNlPaQ>zI|6FDcYM%uSZrl{=LTeF&9~n zoYaN_08|Qdn8D)WTVOyn#{W*4hUz@ExqiCRF1d#9cy>|^C#APa{oZNpvzw5}Xq4rt z@?e$u=_>3t1Q_z-Fy`r6U|@kTP(W0Q|Dcfq0STMI<&MaD9%MdGGHbm{F{W4S>Q;>` zF6L^|Hc>Iw$*V=yHxzNc7f~@1*C}j5o@tZL$EuG&*BUwNn;Z-c6tFbrjc3o5^Ei{6 z+=_X5UF#o{74aI0M@=f%C9%FYHfd@o)+R3`DJnFkW1~&e^rj#SAEtcyCeXbj;uh~Z{sJ=30c64B8H z$hC!v619bd73P!;7UXnlLzogtbhLHEbf!g%${Q78amzW2#b!m3hJ zlq5-+gj9tUVAmp7nLba<=XNMYJ6Tk771NPUu_+F-SBDg1oSri#rc zC|qD33KSOp-IxET$s7O)7GUSYpffLL5WxTDTy9p3QR7T*iri$1TxFIbsd%TTn!Bl< ztGL=N*|nNGxoN+tp0B5=vFC|fa{a!aHD<|R{arE=uA2Nr`mW=e02~iMf0fGL3Mt-G z&#n)lo6TZ)GpDS#@K^XWg}|FRv1v!Q;%#Jk;^QQYu}rfRI`gq(n@Qywme)`o**ntJ4Mmvsm(FET?e?`$IcM~#_Iu@F2SsJFkYL`l{i^Ds zroXh?wmA?CDu?Avo{;in0SF!&6>hh zjm9H1#|1V)01d-fryOZc4YHh5q{=LRn^cEfYeBhiMqBSfnOvD1wNs=FkRrrDcEy}% zC>#KS20_5#|04qq;~6P*e8&<;;Yc8|ovNrQyj|+A$ummhParcwlxMcxgOk85X1T7DWkEM3(4gWYo3PAl6 zasC^^{_hR~$n=hbpl)N*L|fR)DATd2={m^(7!DvLgqf26&G~>x5A6Trm<5ZUbiYDGa2V1Nv>a52H3>_0%% z|1L|PwZA(NTIOVI9-GE#6%732<4h0$Lsgko<57&9Y1^6SbCa=zmhT#TMdmw`+9wyg zHgU>Lov}}!0`CKq0dkB$Ces*i{F@m3 zmGd?}|*WK4W(8bHs6&dW~7ZMoY z9uny0=k4R;=j-O}6X+4(?%@~c=k6I0fOPlu^79RF_jL32^hP>+cz7X^?mkE_PcKg& z4^N~!($mAu(-#?t(ct6l=k4s~;T`1b+S015#a6W;qKz);_2h= zSe=;7ms^z`#`^YZrg2ypZEcJuV`cJ=XaL%MokGbv9GV!M#k83>YjV&U54HER?6`$25|Ng0&;3m4uTX>{@ zyWP?9$s=QjxWeofM@Hs z)Kieb{J8+djGC1h;m^-$qBU`3ENXv=-8pE-?mXF ze+*s1i=Q0AK}3F;7Q4Q|0aTxNpIyHXv$?bNSeGujt9jlX4Kd?sW(`I!HRh~Y);3Wc zyqWj->9HzrJ|%f4DIQ?bT25}v8+sl@#}lCa4MtH z-Qe*j4>wNX=x&_|KjR|{Khm&k_+}GF-M^p5G?Vd`9@I#=y6hSZ^dq|l!KYBI;Mh_^KGW`TV!xSkrySt;X*UyGDbP=F<>9jq}|uYyKnn# zSn8;zb|4MKmBAj{UrLdCt@jE?tE!{tVyW4GncNMhBXcIsonvEGM)*Gv8!eEaSv7}X z1HHiE_QL@Pw$)?sIPXUd=|>dt??=zZU)}Vw@!}2TlTz3`)uLzdOt7&Df!TGc`$Jv7 zjd`W-xLUUh_-hqfvt0U+AC(Q$IG7W=?;US`A&##|_85*|Oe}V0VdGMx2!t%FBB^h6a~o)7;P`48ag{(sd0gsC67g zbChwbqV^ZnprD#WuH!q8W7Ud=9|!0C4#r84+AZs3R~NWt=ZxQJoojhFN{o)t+P_(r zyD?V+J)p9INR0Eug0%5Sp4G|cd6!DNo>uIRRalC|8}$t-#>%*nviE;oaFEzh^sQ=) z)W-i4VbuLKXp-e;O3-;URJ;lnL%Ug*r|nZZsy-_0u) zOFSZ^85(9}9U(KJ0pvAfKoeqeMB8OJs1y&Q%z}rTMsz|i`gR4MWv^TBP{K1!9`01A zgn7R14kM^MPvMzaB;BB7#`~Sef#Z7bN+rdF4mVsUr0__NO`ADfLs#lqtw@YxSu(!| zooBb0XJN-PU7Y(8>Kv4SO(;YgN-fv4hR;SOhPN9?V1%wYH)R zlue0hM$C7v*-l@{m@dfJ>7eC4yUY`~9;r=v{Tv-Le0A3~vf@b_bN>B@#SX~CPDe#N zssW)a!FU?44$l+urI-p3RGm7R0eX`J!QQm;uqnhT;03L5TV$Q{ztx^W(`g(sj zJtW`Mm}ljivE`Ph6U990RGaK)omNl=-+e(RMBLbCJ(s-~*C(3NdDgS`^gci1&KI># z?yPIYv*B%;mlcD0`}U@jALD;0!uTE4pNkAt#9R@UH$i5``2#azc00$|Fbb`nfjl#U z6IHO|2Y#N7&r;UJhj)N0;|AMqV$uP0AJ!4^8GjujvM4k9$$=k($@1Q3eua)&6H`Xr zBvm!aMEdCKwKRM5mfa^2K6z62pRDoJ3{bc*MeQqo{3u{GWJ6VYkPY#3&b?|-fRtTA zyfOk!s0HQT6u+z78a+6tsxBg=#WLN4O-P{4ll5y~;kqgTAHC6P_W>-_H5rpzQxPv} zW2BY6w*37wvw+uf{e_yJPg%ScE8gH?n3~!k@CyW+;l55ponhNpKsd9D32^$lBbe4! zMxw7?a*6V3%fC4DUrcxvv=y>X9IZ%lr_!-s%gXjd)xgmOmQ#iuEGP_F-{P*HFARIR zt=P{GB1{OrvniwRxYasKq~1jC+giUM#biS)UHdhPauzqC7m?S+m^Vze8lsd21oJ4U z-f=^s%u&M&kX`Oq^*H!}>jJASl4mi?zw<<;{^&y_@A51Y(3+7(yO9;oWe#)Bh}v&; z3hk!{HGXBH)O;47Cva>IS(0(8*!3+=3)%j3?@l0FM1jD`{5$m+f)yZ^Ae`Vn^@Jl> zJ~Rd-K-kihoO@UDr!XG->Z1^4C#s*p2Vcro<|0BraKDfT4U{rnKG(8*+&FaI+xQ#{ z*3p(d(vb;EZrkg0jwD27R6||L$voD7=BcHyW9`5_1H{KE6T}vXv`W}Ni;%y*tB#nC znFX(g3?((78?!8JZ7PM2pR;dLUz*c(@CM#KV=1s*#PYj*K+=HLZSu4!Iqktyu_|%| zer#s2k-EybLI2d*%Me>GucwQ1P|_Tpzs|WZySMaAR#Z99-h}T_!=b^(q}_+7_kAW# zYNNk(!G*9QlDbq4Av;yJOcHh{Ml-&G<#;8|CBFqT7K7%V2W6hjP@~qEVS8gR$zS|| zO#GRVcC@^=8W*f7X-{Pw)FgaYRP1!0h+T_;KIW*hbzIm-PRMS`Khv!Kq9~`tuVwA% zqOc7XA=s^y;ssWd<`sB+=rsC4y+_?7?8ld8HGWdglUKLTU%7vX$Obm=7rd|G$cT?# z3&c7(9$sz-zNF$E0Y`iX?W~t3TPke1C0&r8Oz-YD)Qxu^wF<7PW)2nk=@`?p()}J@ zC}u6!=H+LVu-iJ41a6Y%RUq%GjE?Yw9jXbJ{eKtiD~{i6Kdqq+WO26uF85w6*DG1iFxeZffxrQJ zH1e*Hy>D|ab`3{ur7CZ)JxvqgZ2~-ffq~GBR0NFiyOLuQ(ZkG_`Sv6TvyB4sR__o`uYZ|dl}vVA^FL0^C5 zmeLV1ho0uz3+pLrpzX*BF`gU2VqmxzXy^Bd#BDt(UUl+pb8lC?_t1v^Lw$41;%pDNBp`YZ7M>|)>|rnDvdzUxaT z+Cn{_WB5SpAeo%oK~#UT;aWGN8UfNwJxlAi3};9Q`x?T+ojc)E8GoH}yMSFVpQK zZ}QIA70K_iCSsHPF=Wz*73ouyg&q12AK$v^Ajv;Cz5y8D3vj#%w77N`ul7VbSn7K< z=)BXYI$fr1A^<1Z2YO@I-XnQ$&+5Rfw08LwS$31s16I3N3_*!hvASqG-FJi@sA#6*AwpD)R~t~jOcDR; zG6X*-=tpa4=ZxQNo$RfxahkDE6EJ(aCK$+C=UvTg(%8}%qjR3;)&{uthNR5ggSd~E zs?)93RCFqPw2D`4-}p+=+WE!BGKJA)S8CHx;L^`Lj(K_vi%2>Lp>-7btObNbO7QAh zzueD|Y+Y&(ywC815VOl6^>f8#vhaK4JXvP@JhV65_wGYf0+jP=3ffpcA7 zt|98G#Od(GWWdvxzwA}pGDx|&7E;7aaBvUv)p4ut(L{yECM?mNG{=F<8|R^D&y(I0 z94b^4#aYNZ|1TFtKc0W`d)L~rxYA}GRhZ90K12}eO+8qv?`E{pYn=^tNKpKs5R;5_ zOZr4irmBBW^|3kAtwMXT+e_|xW1Pu4|5Id1TQt)6bwk(Ioy@o0Acmn-ko+W{-g}5y zjASK%qQp*JsQlXIvRCrn>s3S9tE1^xJ)ZK+0GyF@<~UO4HXyf=2#Oe33JsyDgFfmz z71muWzhJK*g^dDt<$QM(%KbL9`vN#O}@)S=g(F?|l|a z^=vkO72Z`aj8DJuEE z=Ydh{_t!CSHj1Si8Yf;08ndt~$84c2w>&>;a_gTPbIQ-C%r|<6BkZP(f|8fFZi#Z= z75lhEud?;rb&zBOA}0B!H!DcPj-2T_@Q>Nz#i_KLz~pKj)REChXSyi%GvACQr8xGAzOwHDWYgk-tys zg>!)74r&@j)^5Q!Aywq7MVKcR8%q6DG_@He_Eib?Z@(w-@43S!6fZ-9?{Neje**xc zg}e0?E1pK*^wTNf38!sdZeS)W@SB5_XtcIOQdKn zx;bt(b6)FJtu@c1xRnq>UbeQ94))2`G}^gJ?3h$GH9&2yK9PJYI4&9D0swS3O}PjjK>rQ$5itJgAQ-YK z0+Xd@;X=!;Ex_MaIvC4@!1RZIl}uVDBd6I_KY;{sjI#t7fqvY8SvLY3NE>ml-kKRe z_|`#u4gY0#ZOg1|PJT*-M&FI^BVt6FHeIlp+Lr_U1$RR%gqlQZztoF$G|hOsG@ks_ zBbh-xxlmbI5bERsvB&MbJEShc@jo}tZ8LVnAQXb#G-J}cr`^A^9!Yp`&J z0_C)+AS~7ocHU310Ow?4KnOhCF7k4Lap{?qMnjTtUP_)G7SPUJ3LcgzE>HmU0r;y3 z?>n*90gK464g5rVt+IehB{}^cft@GPjwx%ORL&5`iQHZ@pDc4u1 zJ+B`{N{{mJY-LSGsn6|q_N0EO)$MQ?o|fideX|n~ZcDF#V3+lP-_N(_|0B6bnwkym#{BfDFk>!q>oCF0esLaM7+UGrV{PQ7badW_p18T$KmEKauoFVIj#yc!dutl8U=Uts*PX#tr8gm)q#EDo zritMYnRkq;q@z($*B;X(KRpO=epQ)Nb)z&kKMb7a#e?OSQ`|RjT5!yqL%?`|)CY*G z9T8wb(xnn$bmZq-vVpE1U5^I?4Mt$x=Hr1YC|qGAb>47A*ETnC9`Hde4v{GE8$RlD zuq3H^%a*`XMg7c}jH+JYA#r#zTIC_@i#-**_ww4W$=&LxH#vBOGObA_^rx|ymSb2e zeNVy+T2P+Tz}t1eq=~+n%u$F=R!C%S@k`qBuS-1$YT3;=>SjIr)_@YoSj$Xtv;Zi& z+l~{M#i;QMHN7Byd7I_%N3lPDPp499Jk|Xg^y`!PWmVcJ^+dUHm-uQO)%Q0K#~-A| zM9Y7`Hh4AHKQRObOb6vwRD@C>0AVDy{g@%s={x%_=o8p$Tk#C4yTYz{_zH`@Lc-;`*jEqll)Z#Dirsz~9Qa^b z%U;RsfGaBEF+;?JKQ2wn(Gu0}N1%NIhg`(-`?u0=y@xYT`n1KwBV&vF-vj8QwMtaP zqjHb?fDk=uyf>H!RH^ob+5{+m`^HHgOVq_8-s|flm#a4PRBLzL;U3ekNQ&(X_Okbn z&d`#AtSd?B$r@w=)sk(|+)SDjPOPuzmBRt1<>o~~Z|Ju*%Ihe$Fo41*jT71}d?bxr z)zB-ew05g~!g#$11x&b0yDCNK^4@R&lX|}&`08fw;2!=43em#&%-EqUE($IogyKv9`GDKu|F|l54 z&xu*cZ0PDhaj~WSP?g|XSzM`}Xr_EGikD1B_7p456Erdet57bz!_KtdC1(F1q_-@l zvocC2v3)Iyakw{(y+>Z`x$+RlAJ^%Qz&H?hCD>{G#%&)TATa{;A6jcM0zZGXT~0Ow z%ZX$XnGSQtEoORIn^>ncH9Wn)UXXU)4@ug5$M{%$El}{=y^LQL${^${m1oK27@;yz z`JSkd-3d|UCd}^C6s^a{Uh<(fhnA~ku+6RZi|GA&tFs(zxkSVo+oKQx7JWdCa@Ey= zP_te$_c0Z2?ugi7geNGKqq3Q{*lH8u2 zo#b?QXLrGUjl=f_v7g6J(4~$`B+=CUdwdG7T(=4NGZ>dBgc?}hOcT0Kv5qcW&VRG@ z)_z{PGwctkOe0yCy*_;Qy9Kato@KVu^S0EtpH^$m4&7ZC+y>(i;LYSBpadT2+JGt0QhzbE8w9r8o zO;s?U1&#(t-orza6T=G#Z9Nvh^Z8tkal(L)w>ZFLR{6I87zyt1OX9Co`v5%Y>*Qhv zZs^71KaDBSe4qzB4QAmvBOv7dPOd!64SVvSTfl~1OxlH(L*O%MRt{eIL<%eR)GO7U zM#A)|T9g9MCWQ3iypi_+aqN%hv99$w4`YFA9AH{i>lf4Eut6ii&kM#UbQ7pm)X%Y} zh?T3H7$F{Z;5%OWajdhga})7~h|sITjoN~@QH`RTdqTgJolc3Se(FVjK|xTww~{Do_053>^;%_ChV3Rw z`0Mo}Qdf#Ke=>WLxw(lA9A{xCG@;^GXN0P=dmXSonKk*%*apQt0u`f^MZBY0evJev z3k__=;zayR0cqS(yBDNy?P~)aQ$|Faqm=b4coQj;ZF2_F6F7f=kh(zBp7*c;705P;>LdT?;Ghw{&{N8?9{- zGxE=HaCq~8%4}xl+nc2#DHA|{owQ;o9p=0B?!t3F%6Hs3diaHs01I6apoou^Tf$7tcW5b zP^Q`O*Ajh7v#LS(<5>Dxd2uG!)q5Xam7R4Hyfrf7HwEIyU~3WUw^p|J^p(-;pK5NW z9T0XS*T%c#y2FOkmmk+)C7nt;x|ZCh1&;SS|KLexT2Ep9$>&e%pkN6vK-}f?1(n91 zE3X9-zYNrg{`nfjw4bs;z&sQVgt@Vtf*7O$p+>OaOZ;a)FV^p6Nq_xlkh6h=qMqU+ zBKyNO_WQ%QL9U2COXdPRAgQEc#1|A5N zKXP~T`Mr~0qz9mc0QiVf-?ShJkO%ic+iv6r7!4)?YwtfV)4*p5&xI*oEi9qy&50`m zB#+$UY*$+6V!*`>niBmAUwk!cD3WAvyQ5s6w0lN;^d}X1p@3XKp91JwGZnq> z9KF?5B?m*ytz};w)Ao`q!NKal!trvLW!GEOS1c5izV#~tAD+pTkfDtrBp8{9O0~5c z#@08PxvMwavnET;-G3|uD@#|2C!2imiGYykeJs1b$?Qvt6`f0eMyU&PS|H-(ITRgg zg2n?dpL|f#0Jw?z2?@=|(=+uqZrrbpNwl@tmo~N%fQo3Qrrsk`iuv>=^~L`(K}~OL%-nhZ_Htc_QmoAsKzK5koteU+LmDj(#?^3fG?(+I%> zg2mTrdF~O6VT5AyG8zad2#%;ty|QA$EVCOG=mq)xx8Ki}~bd zGaA&x)^cN}*fvc{hVEh?umB-UT86?kAzedXw=a^hBFgG0E9YN?*ne?lS!*V&T#E$n z6Cu($><$^Yf;>4C?)}+28Q$U#LG^?($+J&=NE;%KECYS;Flc}5RSFG#aevO+94+xJzYIzgKz%bMnS|WkSRHYB>({{q3%Z_mBB5LdFu6 z_r!Mg;6UW;H1+!M`InD0@C%Y>6_x-HfAlzW^LRi(GCGz1V%S=YmuVkz^>P&zgx)5h zv5UhZ;N})67D!rdPWd5(G|+w7u}TK$S2k=4<{Z9_R*#A?{5&TLWWVBRine;GHS8xP ztVUk8UsqM%?Vjp`@2q>CAUpVr`>MF$Io6xZc!R682!9D~QPs`vsJpldTlDh#e2cNf zf^8ta3{XG19>4*P4`ZX_{rApaFn23X$g~1Jmta`F5oeHz5qlzB&i1wdVuE?Ry%D?a zEqi6+n-;P%cnjEl?`!*H&R3Y)I9Dy}r68Sb(hFsmx0d5M2fQT0mee27r5B=SlNnOTvbI+m=RNPYgyZ4Nk%;@fCKEt6fa6IEL({ckIw#biU<Qhp>?n2IGd8gYH90z}O_b+KRE34&xrnO((}quLL+*^-ElkW{zd*d}MXALfvIFSHrR>tW`~}#jBwIq$zqj z{Wf}ST$#-b0kJ7cNdvV6t!ZUr3L^RO)=0s7e_HYv#B=IY)FtS3owvFP0fkOfuAIio zu_u;2S`2j*u87qD`|u?bmuBbPX-=`^#CKVhj7(-OY($aKGe6(gCpaJF$V!Ff{ir@v zf~o`j9uokH$$n#cL=i>jRA&;oa;Q*sFUEFCbOP`-7!nmH{)Tz4=&iM>*GoDE?hN4i zr^jjjD34P&FsAR^*aSLDHNJbR(E_to>*@8Ec_U9UE>e0fp5eyjoXaxd=U>kkE~Ce8 z^qX0|w^dPu=<7O`R8?>isK4?2{YxAh8^9SbM-u`dIeh>;r3iOwoEPlXT%0Fi4=eis zAn+Pw{oS8C7st>QfsV%>;fTbs0<1;0tF+(3$%B4BU?0Y(sMyKjNEV$i)cms1@`|2B zULYets*>C{gdi#d#lh_vR2T6`3LH_Ck^=r@heZp{fy5Pt2Q6`MEQXIQai+=~yq=I3 zgf~ZR_+QH&e=1P0oT75HEntnJp_#i8#WU1Sd~uv9dS?6`EES#1XBnz>miORwG!x|{ zF>DnQTe7$CAU*l@EKW87p_-X#PZ#JWu^9(w10CRw69v-?1CsYx{T+h56Q4{>a-DB) zcNs?=)UcrB=iC`kqmoUuL8A}B!teb}w(2%NarfnNBu~q+Kx}8}2A_OByQ(71r*iqp zNZKWN;V=bw$#9e38JJ-rLCW>M4SqscZqA0u%f*9HMIdb2xGSMa%JP__t+b)d>D9KI zmAx@;z+6OsnfI!Z7eMEH{GpJEoleHFk-f{-Ay>Xv`;!SWqI8Grk1X`<9#OVvsU`M# zC#=Z*ko&%o;eEpeEBcZOpeN))qh`FoR>LN#3k7DV%~r)CD*?BNRpRhIV|aKc!n_x2 ztYqF$cJW3R8-X=Ih?VJeo}bOD=*CS+Z=N@R1i0cU%ZVb>9)pZOM!=01bXGi*GNWv2 zYg^(Kd9S7e#_bl`yAnfBEhmEAH!Df7n0v4QKl`0UXn#@-HhQqS5St3@ldY_MZ-H}j z<(r&s$nT|Dz19*kD$toZF51<8HC{}?AnxomT#`gu?py}wT2+~QrnIOrb3lr<1Q)is z?>n)c#W#{j!%B9W8$c^>_iIf_mewjCf;a13ip@;W1(YY%K+y^kEVqBa{7#@|T;+pz zu!`T2m;9sNC1>xJzex57^DQt`I-T_TKZbGv=l72T51#Ft2H;?NJb`-0FqPc0PF7(E`Qd?Y;v zRNTw@d?hKN?l-|l#ZEUhmb)DS}k!o%Oxs~@}MXSP4bQSKga-}wgW)YSY*0UC!FI~nPN z3{2@T%1qVt&wy@TazQXY?v*>oOtRIS1!9@4Lwuw20glp~EKXbmwoA&xLoNZXkp6+S7Xb}I7k>2h%)y6xirJn!~WaoC8S?y64ZUcc#(K}oh0@~)I^k~2> z7qwPc?FV@;29y`ggV6ZseWMd%Gy|#|!CS2B-mfy2Qg-jl#Ei)4AG4;)T_v9Kob>1B ziXf)wjKFX38u^q+n#_}%&cnLP$2?4z5_6Sw7n=?;xHC5qyGi0^@V(~gY&onrBKa#@ ztU1CkPcO5dxDRM}Ka?kRVWG8vx~^YfXU3s!bu;DIBD}4=n@)o;$KmH&!c`!S`*T%H&e?7M=T9n_~-cZkpio_dC-*n7lwouN;BieuxLUu=PEhQ2Fh=KQD*QHZFZ z%s8D$w%2>3;)x2AlS!sg$HsPY31uo_2>`YTN+-GC}W;aAqD7Y zsSeo=!eR*DL4Q~Ce#c`!Uf7ogr^ddCd%jF&@4HNs5;ek8maG1AFAcRrqUWXG>C--Y zCzQV~<@*j!GQ;h*xyCph_ar?TWNBF^rl9X zynoKQKK3YXwy_n*>2qD*BQnCZhvDD=+6(z7wo%rq!b0u8C1Rp6S@AMC&iva z^-p-=ls^VHhZ8h~!)M7d0P7#>t=;&qb%x{s1*>!2eprd%_dHc85I1sEQqSk`bOZF- zB;pVc7WV^h?RCK=#Z<4)XT&WTFK%z;O~~H@RG?2jGl&HHyb)2#uk}Kx^gzP+;$_v- zr@fi{;04lSF8`gKoyRL|u}hVg?j`vKSikxL-k^A_E-m=Rh2KU$usX>_vUdn(^|aIwZf7>eFJ((zx}6{5l1DJN&W-Ko}M2o0oMS~olNleK72fsqD?o;~=a zDuAbTz&ghKQI179ufrho3RaXdD1v_TIMdh61*J9PA=F=Vt^it%y2HE%>ca6+%6_U0 zm-K^AA2~b@$qVcDp7i7ahz-Y~H|+|KT}e4gW-0gIKf8bOCo6s8S3ITi2NRds-_)Yi zvog$n_|i5@rJ0Wno=j2s8N=!5Qui{iiflnZtmb9{bGw8% zhxTw4;T%G)N)Sx<>(WP87nfAmY)*Lm;m4(~)-9QfrbGv8(+o0AHJ`63hS6VYQf`6e z)(;iK^`h&_l(XBKlt%emylpzjX-K|X*>vg~-#o20Bp+lxUb^Nq^bxyb!Q7EB^niX0 z-iUYj(O4e~qZM;EGj0GcqM6VPB%t*NEQ8^ZtjRjxpY2@^p1oO10&3v;awEGr56beY zorXk#M_f=x!qF*ynpzQ6bSv2(8LCnJYVztfaW3*kR*h7zLF9!P%3dC*7Rbnl zQ`e;ylFEHbrNaa&jIM=(6M{&)nCJ?!!G@TvJntQ^+L;jE8g@b^uhTFRvHqHcboHpVHi_A3(g$D>jWScFB^!= ztJ=zXv!ws@t27NvvfoT>VBE=z<0NGlGi+y4Y3k@RF(0zreAN1N0Z;d{U@J;fLRvy1 zNYfRxwyxDAhPang zL-Aw8s^VJ)^@oXVY~EYZ%9ug1nR@;f=7r*;m#GVB?KA-w<-L!K!v2BfUxaEYUu_+D zn!>wLsxrS&*n8aOG2U#j-A~Wb_kNHSXeji4NV$W2bz&YHZLdRw*RFu(2NRAJNrd-Xzq%G- zxH1S_xpG~^y>gu`;4E*?b?u6aZ62VbYR{_n+_pV5oeKQg-x&|TZ_#@5?(-MjnU!Ge zIvm3WXokhFXTJF!LHMOc1RKv<<*KBZJb+3kUy+WO24CTbiDqixAgZ8@kPQzwk-%Al z?_)DYp9tT?a+Md2ym|h;)q@Z8LJLP&%Lf3BjeHsSbV?4+fHrMv@R<15Y6CdJw-0Z- zJ*K_HDKcieu@Y0TqZVJ}tP{V!?h!<cn9iEwMH(_LEBci}ZI=1Q9)g+l zvp#}uP?vTP#rc}zzH7?^VNQ|Q2>7uiH!A00uygmH^qEO|d+C7tMI}$q`y#8}@Dh?1 z4ZhY1d)K8vYCcu1O8w#FQ*tC!iao#>vGiK^2T{2}cZPTZ_q>&q(Apc!ov>r^%O?TQ z&0Y!wHKef&TD_yVF066_;9_jq6J2Z26wcY8dq@b19$Dy9S_!2Zo0d`Xb_~R`&aU7|ad78rh$OV?mHcwxM$@D#aq1sg z@lwC;^CmL5Pb>3<0@J8~zG4+Nu?O6pTjed$sU}@_-Zq5?GY=ogvKDqjC;W=-%YCZ) z@Bm0TUMv|f=9oz6(e40n*Q|zWr%LS5GymXp3drA0;h{<|Ci?okEsI2L=*`AxSpv7= zY*Eh^m8Q}u{IxjASN~}ZfTe-Ib4UmG^BQSk1xb1tiK1WN#iakU@asdEs_U2_5T_?J zaNQ}Nzx#5MTylg{rdA2t{jg6v#_b^b(>ywT4y zaTwBM5q?yd&Y^?*P_3?Z*oZy|iCZfBCFrQnO|;4OZi+*bjc8zly&M-+l$WUGW`!h6 z9DGyucOgJxO4Ef_n}Oeyf8^`ij()8G$m2Z)p<`H2$v{49AZ)$p%sgo(W7`&q3d!cc zV_mA#8M=p#cy`hvefpZTHy-!ulqswL=z+9zW(Y-%Sw*xRYq)$H z)HzLgCe zKY8)brplkhKdX;Fuj=T4cT3$K8G*3bPTd*a#6_TXnI-W?POPKi;vZP^4(()HK4RoU zMA~ANb(cQ6&BwD-AMRI-FJdZNb9`upnH<@0JEn=)zX(A&RZzDlMLH zZ5gYB#>ytM@xu330BIghwQGON`Ujb7I`!>=Y7^Gcqv_=f608TfohNVD3?x3^r=ce2 zi81t(%g;>p(_C|8W(S;_Mw8pavBWwOa?faU&D>twj58mG6mMM?-74tbxk3bqQ1;Ws zvf7=_fXFz62f_NafVhq`dC5WVu<)Jd=YeKBI9iXc6!>6<@rt>XXTHTWFQ|R>eQqOY zya}?_vpPQ~DmgZoJ`BUnCIg>C4d3%nnI5keLW?IP+B6@eEqvvWVx+f^8Wgz}j=gwB z9dP&gZ&3fQ7_i;R4EQ9<#ZD^x zlSY-8Wzd<{G~_{_Q7Nv%#@lDf8%v`rrZ};aPdpohDxw14s(BpkOliDvihUz+M~dMX z8Xk)pOQ>il^7f%8Z1>qX-p16>vE!OC+W6y)SuAU1Tyq<~s_2jF3aN&<6yOV#yA_q?0i zf8y7AY3wDhd?%7(cRmm@N!1@o;!L@_kUrowS~HP5*nq`^J7RjzyRkPFZer}nUZz<5 zpz!Q{K`wS~&!W$sG3Yg<)YCzkRhaP&&FGa>Uo)enJe`veK-9t2Y{%Gwpm+(&Qkh7-yZ5aCSWGx1_#nlFqVjYpA1 zk0@Mh8Sr1CISg!`>U(&r@~LO?myVJ*dfl3>pryM_Zyc*d9-B|3F) z%Ifh^AFx9AAKg`h(qAupC)c;ApQ5lOe^(*0Sr5T44G$717A#MLnZ|AQke^-kAwP@? z@CQ$FX!&<3M){TDjw>WN74(8ZNB&>tAO*T|Y+qf2*&E*Q3&iD?bf^L6Hf+w*8a9CZ zGUoAgP=}eQ7c8Z}o&s0k8j^hUq*1S}BD`GU$_=}uKmp5>bWAoX(BnpxU!_CtQS(^u zXWDFbnY(w!AX^frY$?Q%HYnq@*JW}dxWkWgn#QfX5PrcE+_wRTSvXkn%nh+?KHNYa z@!uj(Y%~iD8~1+&N<6j0X1D;tdhfxTjg#QU#>9VDb9p+r^u#<2Td1N0niGhi**dE^ zECA1lu0T=iOMA_tibD!fofh2A>QTn@brKK-@#$rmVB{Qm@H2bHc_LbCVUEFhGu(lX zce4FDOSJCraE}K*+S34798k9drqU!>SR`)$R)_V)$=*}8_Q}&8|K1qh)*Cq527Qzv z!rjOoJi>OzT22lVZAlv`2=;+6oD^}B&H05^Ci6>tFeP$!>MjKYqwh~{JN8_(uTF4T za?pKLe%~GfgF=8FYtL)i-~#^HQwdlcu9F&ILxGD*Na(KDlkG2`@?)fXzK(fwUzf7+ zr8ti3<1$dtzPzWRp$!}7OdAUIIGf+~MD97f45i?q-4N$3Sl)I7iUCw%;haJ{IE9h5 z{OK?*DQT_bZW3SV4tGS7Eu14jhQ58(yuurP%EJwSWBfrp*Z_?J^i#W@e6ZY;4_CSV ze9x+U*ih&94m5&s34*i<+epR7GEs;^}T+KAGwHm4w#xKa-m|8t5)4C+Rq#zqIJ*Ht;#956s4 zA$SLoG+Hao(<5L|0SQ2N*q};UshQ(IVga4)XW1t@Tml~Yvj)Jaws`P>S%|Pgfv}Br zH-FZ&cOE1>oU$b{zIN;CA_AgIX*jv$^Y5^4s$>Y*Q&E&^;s3hA)dMHr<1BD_bkLT> zcO@cRYZ#VI!sP5$K;43AMCVH3H_AF<@6P$Lp4|XIo|%p#z6wMMfU^guaKOfch5(W< z{o*wn{r30D-;EvnB5oO;cD9y5gk=^A$GMZhby2}?vRRF*E_9@X)Ow)IcNXy^1Q1C} z{7EBWXn?{J+L@Ci95c1<~yuBh@ZZrBN zB@g8@FGvH^)Px0d7*;fthflx*xtWW(?C}TZ5H)luE?cgQglsto%H8A`Dmw_c+E?o%| z9%L~9TJzef<+LO|%A*FrqYMa$WC~0^2m;+lkx7LmD+}7L`Zu`@X2VSH2m(~UpDC+q zeE%icAcw7BFCwGP%tyX;q`pRm87oGCe&Q>70W9GK!MJV`cs7#;3ECd4iN3=l)W0Op z$P(}~PdQxmP@*i7xd2|e;{m{92P8-uOb!U-T;6p$Wv!u(k925Hzjq?No)fl(Iv$8| z7FFgi>X8W^ZxwRft!fq7x!Y-rqOVQhrEobS#)3rxgn$M{O$ue~Q?>sB=#Xy6IEf<{ zo2LP+K2o4PZwxdFg9!_trSO+;i#R;&rg5hX>>f-}|rxySK*eHMm$kuc!92U;y^oFAwh%hekNwBQt}IcQzbo~%0mNy$1VXid`f_6NCK$*6YQc$ z=&wU3jebf;I=Z=YNiX0*7Og~YeCr1xw)5Kb`Th6CVuIb!r3e5$X~V0uKvU?WWsluqfzJKVr6|C0p<9K$!XPRmnm_Ko_KLbLb9)g^({9sQZC3Baheu?C?1M;Jx zI`#l&rEQ23<+T7NiNHwBP~+sQHwaU>I6>=Qk;Yn}vcL&3>IP;iTf|OI<&jKe5{<+fu zz|(sI0+P1@a{$2zg7w2w0ITdQ`N{Nm!NR(Ivex4!AgbBbOO=53p`2oXCzA-V;*Hk$r3?3Y3g*2y1IslUiO$53E ze(3|fSirlo0+McQz~KSF0$?WryCxMDHKaUS`f1KM3o|`Mrx^x7LEwPbu20JaN-4*5 zHq}Gz^;y>JAPyo#AUTjzmKj(NTN$v&>9V~w_-2G$w|?M}8R8xc!fR4~r zi^B-xrR4CF7+2j0od6!X;{m{98#EUDzrZViK?1I(ab2Q?$;nNWULID{tuD3rLKSd_ zCc&Vjw(1965o%Mve>G64VTltzi1-dM7Je+isZIxpW7xu|chGjWEGXB6lg`kk+NDUB zj)tXZQD4-6&46Bw@|`mGBLaT9qk{&VZ^SUb5dlQBQt|WUD1~VMg}!}$I^KC0Pj20u z76_RcP(ftF)z}Si09kVbyyo#jD1cU_nSY=FEc;(+asf?SQyqKd{Rsw6 zIr~~j%%x@#TZ#lfrY;hd;dluovttNBG7TQO;|0KDNjTP00~^3^rIeO?NljW}ezaUa zy-uvOy^d2Sb`}j{p^D@F<1*w`K;ar0VZD2_k+GrQ3D!)O2GyJ(EC@9_W1mJ4eC(2xp+B8qg%V=o4=&$gH<{14j#!N`xLFGWH)K0^5zz6{pm|vF#0g|&9+p!xpBuiyg@#Il_C&uAk>CA3yDp?rw23%HD_%JP}v0Uoj` z{|H~?>nda#e!2rT0G3@hqY-kHF@Orc@ZU^?qH>Owxm1wQ;oUmtKnsJ!Cl`2D9*FGm)`5)y z-LMEk7Luu4yW(41k?qe zy`tyOmxC`ruLZ4sDdz~W=ynb$Oz`fgzV9=ErYP-R5zq!jgX_Jmq~>a|T!l}Ee7q#A zv;xK?iB4q>OHpecJ%)>$Fuw`#5+16f0lj8@+!FM-y*awl?0;865vS zwGFAe5rV^zCwi-Ry$OxkA{Tt139e?SNyF~G%9U)gSMu1zCk`U%B_CaZ z*_=AzA{uUI3NeH`K0Z4%G!b1EZE0w@MG~<9KFXsDfRoAVhm2sPq)>^^);$>Dx7ESj zFNf!cq0z~@4XP9kS0X9a@5cfG6_3})6%hi!>2+S#?^+8~kJGyU1mX?ex`^-fB;~k4 z(Q(3tAjKGs5jpuZdDI|)euc4}`2#$f=}&$%*PjUI(00 z3qWjYjw|ku&YO$(hDksLs-9{3vyY{Qowojz(<2LI^44}B4Jdwb2T6c2cwHlXWKj)W zfCzqS2UoVnD2uEvTl&x;DQ1Alt{xUpW>^6K=!RB#7CNk#(7I|TYQ7c#UW%guz{%v_ zYZeli>`JJ1?DCw_*3M4sUM~CTN1Oh__k9B@1HOHOQqnrfNyXKF$rctL_{28ovKEQY{5aGOV}PuVUFw!_9oKfD;|`%jI-o z5Q2nuvGfnfkD%be?aiHd7O$K)tn+OWH3|4)mm%sT%pWAsb@#k(U~2x(!xml8aPY1l z06wb2g8+C&U{mxY956EghEt#>7fv)G9ST99CPQPBkq#|!psIq5NOSmJ1TL}ArtoLy zHR4cG3J23CzbO>6L>dKYJ{*&90>a0GgenG~`Y~U^agH-(OdzSKM5+5f zSGx$a2dZ!ZUb>?LfTsq&CDPO)*Z@vIxcRm3qVgX1!JeBQdYyLcO}zmqaMJP>@Wn~5 z0RU8;LG}EvNJab9Z2TQgWk6L7^93fVKRLUgmH^c&#HJMF9PC3&Jj6sZpGD{$+rz-> zRI6w!3;-ZvZ2_LTgA0IX1igV%r2xO<)B;%*m}{w0*0tE)NYyx#<<$L&h=5e}rChD^ z@%bA;Or#BNpHB(!lHC<}K*u${SW3z~d{;J0lSdDXp15pPBaa z1TzF!?HIEL0xX)HlO_Rvy3>aNJPiyQk_1LW3!r2mQ7Zj~|G#LzTKYT%7f(k3fNf~B z95;_@h_olbHX3cL4|@rrOXw8JXtDlXs3e%Fs)<3tX=c4lN0VRp7l(LdwS(k|;grF3 z5l0&ev!wI8VOkmF!K8{#8Ok&M$Pk_ubEFoNbM%67nfe` zjW*h5kTx#eXNrRBed8}c(fM3HkcyTOs!}j_g!DA;{qBQE-*Ow&a3Ju&l<3NSuB@_TAT1Xe$kCp@{`;$~^FG46S45(*=IJ6UC0V4YE}_6mka37#1>Nijy4!B!MBcbWLojX*-z&G$} z5jNu|q>FE_poR}L!Y55R{18DkOb@Y+&p0gLrTvZU`Dk#1+<4gQ0KS>i0l<3|sN+cm zU?d9Un|B2+I9Z{_Xp7vPPSi`SeFFfYap}m5?2&;?t(IbMTYDp+5!nPdDzrv9v!b^d zfdA>p*@NgWgY(!m3m(Ru+5+$`wE^4rk__PNrBpx~OJfiFpZ-5Rj{pF&HAA?F{SKM|9_Ufu z=RscaC2Iy!n4bu+R<^WlXUo7uJr~JeFTrchUgSv_wc&Q@9<_l_&a{w&PnqxHQ*cb_ zsdLuBfbnnJ-_;8-5h{8O_%9$=vfWwEyQXz6>o+ z5EppUCO#`LTtD)a2mYDUMFZ|4#!qFySZ#p6mPHE^H#eLmK6c!=T7QU*j~ybQo^cBs zpxXYmh2QJ~;B((wvKSX4hH8mIGu&~^sL~BWs13o2t({T6e8Q+04w1xpHtT|_m+WB= z9!h3py=M$Sy8`|?fmk+`krM$vilapX4szo+zzn4l?5Z-8r=={<8<6$e!6>ud(gX{Xt@c|Pqrk+nc`gP+C?L;nV3N?E(eYY=C z7I8j;qgS37`d`;h)gS<@m67WMx&a=V(+hwTnP|!Z9!UtEo+M~n`)%*PJ?+EZftw#% z_g`~%07bJ!*zAug1o{K*k`e%ZSXvepxRwq9Gxp-%v;kXn|F3G%9JW3-#0pximc5zU za2}}+koAc4#6ols0lPN*PxN)nUF*N)$B-?r?Q5siS zs`E7l{ihh*nB>)mzQWxBnHv%XPb&>Rih~1ygUi?70|ptb!ow7e?OMC`!sfwUFW)Ug zar#MTdUhNb7EzSdLhQNIk~yedJ9{kzZ?JDRLca8fXOct1!|wg<9!`>|fCwYAZ<@;EI+@I32oMi6c~6ELMS~1>Noc-;x)LoX8vg~@0hMVU zTB>Q9dVL$gf?5T}O2AOTz;PB4%!%I~+%yKZOO^^29q!Qq9;%~<0zANH3;9~!0KSbX z0gOJCti~TK@5tHhSn1!x<&f5lfa} zV2!0Y$(y{uB`zR~?`Y~wQT>*%oy@7(0ojL450pjo_(0iUN$VloRTyCG0nrHwESnHnzDxReukYlf`Z)vTeStJ zp;iJx8!Pbuep&ND3E<%R#{%%J$^(YOCdSfCk5ZFUr04kmbwY0s?nDP1N|(y;G)$FG z48fti3gVcXq5`rfP-(TV!r(T7FT2sws0{KLK!IEa5hBP6Mzw0!6CK%8rYW9Vt$G0U z@U!%jq^WXF9<2rio@wI*apB;p=2`$_sD#>_Q05LZJsCdvzL-ycUw+Wli~vx99+(`X zX-hM1LKSCTvu|**^>x6vs5yKAF%_;}(r%);8)8Z7P=#VMQ>-c}xOq64w&AG!ki3cj z0DLG8Z9-~07(l9Nq|fU+_XAmEFWY2yNZdE=Hl0z80`LBRqTWZFW?*8<#W<7Hd_`#+95 zdfJ|Pi31|cUhIwM%SYrofTQ>jBD;@9ut(wr8|jT=#z;R*rBgqV?N4$;+Iq1-_zTcP zJ7J{m0Ufxj>+6^a(2*Pvq z3doI!HEMjNBT7o+gNhM7hff?>{O9|L9cqhDdC z>)R``RE<|tgaYiG1rkH>Ry3gKJMO(M3^p=uKmr{5Y4(g7kupI~8@_3?!LaZoPiga@EBO{Ayuu3xN&Z!>*UB?wM*I_KyX;MHwcHzY)+i2+oSkynrY>0tc>#fxi0ACPes+3e zH5{;S%qeZx8F>+xh!=nmD2;Lo=D86~t~Hd&ByEkJTJDV2E!ib*;g{utf2g(?Rh@!T zOs*wrJlJvpHPAI@7y|xTqrm_UC?EX?#+Yd6KyQw$6T)9;hclh;d{%J#r5*8l7;KqLdFxasi;rmlZJ(Y1E+r8&< z$g3x0Ib|dcc;t1+abfdqAfM`DO8zE4zCr|2$?1re%OKmiO=wToGgmLwf`|mJWDPXk z5{Fm-&W(}f*1q=+@SF5TLt!9>A7xe)nqJW%f z2yP?!{>L$|4sW}r^B6`2aQa_Wso?QJS}B)(n`18^5nFi`ig49t7`8`Lo%m`GF&6`G zB$ba0W|BiEIK#mowU?A81n-8xAQP+TK91J1{!S36(eUC_?-;~?$Z1=dG6x(= zjS|TTahF2-wUfyo;510+J9e*p)noz*&4QE|!f(+fH6|Ia?QW8v-u{a)te~Ms9g4?_U>6oq+H&Y>F0DW#5EH0plI_6gc-ifn|)!-(w7Ys1T zPKmDTNKy7FJ#*Q0>SEXUnx4*8098xNvRqym>S8z{;|x4X5!*=!m;g8e+L&qbK~s@d zw%I2aTDI+kl&bnJB^<=Ph%Z@dC0SC*=T$@TU4}iv8)m49&+8=OS+tdK0RFkFo(k7o zk~M)YnT^4qrFJ=?tL~g_UnVXlK=oE;>1V zNTd!!03itx;l4AFJ>4{H2BC@J+pIhG|0lyqP)PGrx7lk^6Hp-Il{oS=4K2V5KH95) zCVdYV4n7vj1119C-y4gCh4HPUB%6Ny)cblpPyhgdC2{t+e6*@{>+Subl3TAxmKaO| zU>>ghjT6q*Z|VdO>cMwHwb=n<5x#5Fug4xgNqY?cxS%2q0Z-yYW|9s5fb0NX>Z|{@ zzRQJ!8_5ogNP#wC>rqnD?>tGq+AgNDK1n$M6u#ii&hND_kU_7YUKM)5`s7$PP~Ze3 zxv+;FUv0%Y6RN^Uaz8^IEP@o4qg|baJWw%XC!T;|3bX8gcuD#If>3}(_dg!0i=PzV zfNKmD;R|@Gionj!eaJz(_5Art=s?#-^HeAUPy%~lIqx1$02~mMc>NEVmy-`r4H(bz zpal8H&PZun-%pHwfZAKmON?ics`AE{wEnZ;5mE+5xM7YC>aN8-Ka)i?Gjj~B0b{larkW}6vodR?=k^;N) zn?m36=;wlz##scudGjmzfP459&kigIAUPHcp8_GF)%DfoOSO17vl{CU_Y?q^z{=(d zxyml+gMc>sUvP+}0Dk|>fJWe0{G#(eq96hM0sM`m@+L2ox0E7vrsvT@ip_1uaq&Hv zpy&hL0}leMRO{j6HOU*|X+C-(PL7qB$+fsCt~~~-EtLLa}?X^{HDlsQ$zQ3E|q*Fq>?s} zxBT>FW90^?gC|xVnp%~^@nX?bCT^k!{<*7v*0A+2#TEdlRy4{CUd|0Ig#dq2d?FwOQTSKb5h-fBS^YhntV5}jxvE^k;^ZRotML}@ zG!8}*12PM|?0X?Tz_>aIE<*sr60_)%Z6SWjtA4h>lN7_jv3?I&;egr#7mvd9u-uo8 zo4c<4`_e3y1ptMDK=cO!9IB}taB)E|24;vRpnyv1PO6?^zI8ydh!HszK;{yd)Oos- z1Kbe!1yd219%*k@V@dh%PZJ6o_87aq5c2>^5O!cB0A!OuR+B;aVthL5 z?R^rH&TIidPyyX@hXKflZ2G){5{_z_HieJwTAz|;q1nKwQr$)~kT*C(nC^UG7)dnm zEjj{tw{A-OT!ld@5FLz+909%xtp1+*KFJ|#fJ6@gz#t`%(0rn?ct|1@I{RhcOt0?_ z00002{CyPoSGjm`k*JUW001Pr*dN!T_@AcZGC^-C>0pHq89w_I5R(LMB|fH4Xqa!H z08DU1r(g6C58kP(J{`Wx4F^X`H87}-XeEV4BWuEFJ|13_3dzg7mJv#hJL+OI? z+okmqIRJ+`1#&3&0^W&>Px1!b!=ttXevyK|Z%RU#mhkm@`dYv10E_bg0C&fpX{5Rs z_VlO&DU^haIywh;21w7Rj*j~mC)|O`NRihSGq>#Of7GY$C2|tR10?2IFerT=+KZnvJwC}J2Tkn&3kdRcX)%^z(TNnR7UL^D<8yBW05s6D z$5@gFEk|FHd{PBG_<V@c{7mVwuOV%opMTDR60Ec6yhyhT4 zB$tA`Om-!nnTr=!H{1Y~`hhqo5o*1gp3TU~v-5*{x2@Y4T%4140RVXN`n%ZsxY&%Q zSLAW}ckBzEI|^6@UH!LF=iGv+mn(Q-WRvyQW3=qbbWR()4eEFLgf+Q&?HT3fRzuX- zb0w1{4g#J$4W5}RhwL=q8uVfVe4!0wyTex2=<~Jn)a&K$Ps;-xv)~|PpLaCX9=m%x zluX*4veURC6owKyhMKTQfd)44HePOM$pX!^mbOLOLvnON^;2!>zejxa9+a$ij)*)@;|V^V3_t z3LP|9aU01tfb(rIfCuRw$X5Q4!~IC4ud?nW+U8^mOgRA8@ui=V_gmc6FtvrhC6w6@ z3n@I`jt(K1oK)GO;dlVPnX@P6y?}%6mp>2iz%n(D=Ic+Sh%DB7_l?lb!LeVVn>GLh zAIS=)LuA4Vvd1%!C5cJgq>@mCb?d=oMU?DoaQmrr?``vkY!pIAjldYH2W|Y^zqBUpM-r|qoui!f+pw*6|`c*h7(@+WhCVJL-O~*_intRVtn_u2j zJl&=?^9=>QFEsdk4+;i8q;9%gGY;n6VF2EFqZAJ#47>!Ohm-`2YBxXyf4PO!Lq&}D zl3qLQB>p+i0IsqKl8xH$%z^9!Tk-0Hw!}ff9$(n92*&3~r0#C-`!@#E7k}sz={?Qk zal;xeiEWTT$ed?0=%e75sl7nd+%W^BDgc`zDo;Gg!w> zo{10NVWZ0MMHSYkn@Lin7Yu9{_f{y#>!KLxAumc(=B%A106w}aPo+n%3kT0y5->85 zz#pF|LFC%4rv~%=(@qSz3;;kdGNSLB-|8%|Rjzr#IAwx|FK$*yhtPsrh|@HtR_l8M z(BFopYLFAl2Q`!vTonr0)?8#u@WnEm`+cmy0ZNewWT;2a{<*6@DSibWK#7oQU@S`x zgwm7C446zzmtU-2t16Gl003pVl;9dKhgd4&8}Q=bb=>&? z#$Xl5*eMtL6SrNdsLRDs1rn}!K9es{7L^2^V-YrhHLQQ3yv2=~i-$X-BH;p~+vG52RcC~{Xs@id5y z9DC$%47Z{83&F=+s7#{!i)b8<9-nY8s4vHYem*M(Yj8L=XTj?STPPs?5O58?ne)X7 z+;gC$^R-oVz@j9eI1XwY_O0MSOa*VmS#5Q_-KWkSfNH+ohKR45ze5cLf>H*j@7VjE z+OQSGn#+}PNYK^HkK{{)MRh!&r7^I-2d_$Bv^zXKjlz%oo;Cz!yN^Q%iMdW2ouJVA zE-s122wtkQCuNU#;b4*L{s0EagupL35S=D(H?HSr>En87_qPK84)>uw_uo8MBt|QI zeV6Tl&fxx6f$ezl;m_!83*~}rCF4Owu4n0CWVbdhVK(v(a;BuTkqQ*6;i!O3eh<;J z;$0Eu0jV_pspBIYmVui<@z;P^01_bDuFZIP?^J-A0R)$!R_x8eY-q@w5VuoaYo zsML8?xM@IlDQ_%skV;qa4dgN-m?;BpF?S&RN`BV&D4JKqDI68{x58k8*$pNnqDELY zMJi|{z!ko!^M?oUIsts%tRk38fRcvkrwyW@K2LIO0#SdjxBqX40ss-6qPhY8iNlKvcmg0)R%I2zTmYO}0=ZTJ3uv4^b(^d`(cd;s`X}}Q3JUkf z?eYCcT&dVZ(Wq3BPEkwYbxlAACh?9Ug9PV0?=1^Wt}{HhN6{Mwl9FqnLUi_bKSJoM zdhL|b+C1!xbSvix)1-b9Aw znm#HtiM?!aS?=(@0XvD<6W9b@ zG=^2a_+un((v{xh{*0f3PQ77LYo&$g?ZQ%@2K+nLYQ@T8joOjsts=jgF}36LYv{A?Te z@^X8EzOeSh?Pv|kOyFGhwzMY|SSZ(xLv-^1K|%{cN$7^(<*onTdE=IjEk5u9cohXT zz;DnBbYj3zN*|6qn{FiSFOv7W!wrC<;^sFCBcp|Lf)r}e;tT4yQtfK0Ou}bk%&$rC zmIE%}Y6F~$2GM4cix&k@{CW$o*B`1yj{=I!{KJ=F2!s?lXr|iL*va7hVE= zRMLL|_(Kb7jpnw3pK>#E$f})_Zscn{4FJf-*`2+!r*v_H{ zh5J7Q0KSRi!P4*mD(D%-%Wp7OCE&IqazU9&QPI!0J&Q5iCp>$58F+#K5ekp}=g(5r zVk}1mcRt!j84|4vw7p>m&Njk%NE%}h@4*N`&#lcTsLuS%D;6ie_yja%!xOy+PO&s;NVR>w-C3^Vxt6ol5!6kM@XkA+dJB>7SmbW{cL6 zKdS21^dVQdlIBttaef5=RA5Gv2Pz4S2Tx~bQvd`oAp!sZ0000?b*&@=0002!@mkCk zYiwz3YHw&}ZfSLIad2#IadBB#9lnXvK^gD>64~V+Fe?GbPC^9BsuYCu`AkPX7Tl$i z4da{A2b>J}>hkx+Q-ic>h^ouE^-2I5F1#?G?#aY#Fj%u;Y&!}n&+6pfX-nrw&6$c(b@bTrY!Q22O4KhZoq>iY5L-C)F zkM+Wq+3INlP*8cIN$Gw#B~l`#&L7;V=W@AQi46KZCV2T52%!=WiO*||q6tcs<}Z%% zP*bV1TGE3LC`~*>mUlp4j=~XBn!5#`Y(cUCzKOFHj|(LS;|yS|G^losd{;dJLKVy}gUBGn%D{{`Zl`s}W_D96BUV#$O-iQ`>zM((5wQ61lJjW_lQoZgV;7BFz`2fmq$D;*!hZI=lox)OqwhKkDK`2nL$bC2Xn2M^=8Ix35ctNd_U_FnqAsIgP^z z7Sa}zLAF7(E$;b^O%Yv^V&$HVz+?qRo*JB8J?L|nzOE1cdE>z zmSF0rcWDN<@16YZI{z@70f4%Waq?(swNFbG;vjmLZ^b!m0{sl08|GCT`N14C=^uT9es*rQ%6rENKo|94fsqr z*d7_sdwAL8R?F$5^CdJ%=mqSzB|x#54wHiCcFz+Zsg4J*mM6;_5J-O7i_aXs9`*>`Avyx zpM*(u3~&kFs(w+b-==Pl;QPu@6t`+k1~V$003W@?dXFWjF_L>W{>dv(IzF0)gEoEu zlTrzvo{B3uh{3scrwy~~`(V3@X#fDF^7^uc-9SXzH`m*-i#1on;jjk4H}cbtxo+bZ zr`f6g6;yY4XSj<7fP*eyc=7T&EUgaBdE-+;fcoFzQUztm zXIe1dWAHmjImG<|vx6FwYo@1s2OkTxOt#N}Di_)ydj&7LCF2$-54SL2c?|)6i7N*W z-~qm1=02+dRsiJDNL18`F;SEESH2+HN{;U&e6BSPfC{O&DZDYlwkm%;vKZTm!t%X z&F^K0deJy4qu$O}iH_b5li~i`zcv3GzC5)kW99pmgKE9!OX|Mpl{DvY4zKOFDUWTjl02Yn`3`$$Ds#n6` zl#MvL-pbD0@^HV5PyilSi?{CnsMRbd!c^lJ6Rv}aZlG?xyEV_TO1Gl+iG5_;1b!$&LX(0d(%VD%!&hr!&u0Si)o*jzI1dJX4kd4f+Xi~4#9k!sg z;$L%4oTSsH5NC?EDC;~EC8eIU@o1k=`J5j*mXH64HBK5F$BQ=rm;hdh^OYSh;D9aF zfNcfHX+k`-dTj2)zw=ZU|NPA9q}5Z|0iZ-hzRR1Z} z&5dhxSq)D_Z;*%o{%^A*dwv~Efzf_GLdPW$up?c5LS7Q4PP4(}n0V*(g6oBdbwdL7 zi9;hhUMM;E_e=teX&c&JM-*L^(e5v?7PlTRb{?{#Ak}EQvvpbdvvF*)vQRDf@(XS$ zn6aHk_*l6aKbd{3H2O5PA&7d(!x%r-W@aG2)788cS$A31 z&|3S*$V1{}w!5BY&W<^+CML=?As3d)eDzzGxUu~5EtC}(w3$$h8BTJ+03@-TJkv_%#)V52bH+b$sD)Psc#aA6~3+2!~18l zzS+j=HV>nvLK}}k;!F4JM)^52JNPKlkXy^m0sNeeivbV-RR1&Um;YKs(DKCl(}?Ao JT{8**3INooZF&Fz literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/sound/awo1.ogg b/tff_modular/modules/bloodsucker/sound/awo1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..211358019b99b4b1cfe4213caa24d8beb5d25d70 GIT binary patch literal 36063 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 z z6AP@Wr^i67BEmp zC#)tPzgAi{6l{*FojS6RmqLGg#c;E%7c?-6g)=3WSy1TBzGyjqcfe*u4olVt*0GLxayK!Vkik{Uy$2%nvsDx*Dk-u z^e-FsrUK>#y2$a(aL@~fsO1WO{(})jK)F%iiU8ugTm?$|n$%#`+Gh?t2%?>Ad1;i_ zZ>Wk2y{oc5unE51-(8K{VYi~O^}|WAS~U$AxqztG=J(q3l1J=43zW6^QU!>Co~DHI zxZU+BhFhXF_^IQ~pVIf;Z#1k9$T2WGJV2j6bG~ko z^G*isvd^p|-K;Ml@u!2M<>BDl74Rpi^T<{|<;{KwYT4$ksG0vn2a7s*pMj@{TGRwA zqGeen9OF~3UZq{5)(01uyBi<=_??{FLE68>W|liusI`@0p455nI2k~U%l=bimgRW= z*B|FRokU;$4B4O!p=?5hl9Aj{%R*9UxBil|vtp-HUaeWSVhY&}!woO^8(kO}x(-`R z0zL(lRh{selr@0uCO5xxZP38+)sN;YXw_%~+)$r{5*jtEToPK28pohVsxxxid#+>0 zkF~W1S8BGUFTBNi^9~Zc)ngvG+RrhP2i3@>M=~(nyqLbv+;Ed`(eKLf>!Tco%TTn< zz-KnZz9Jx&_wbDt?OF}^O>yoNvC(GHr>xq$GQ1+QNC5Ej#st2qBxtxqE)aoPlO5d2 zw+GE~2!rnVj?n!O&bgok?AFcQ`XXw9kf;I$HmH`I9x|5*;s7r1}qtIli$4z08!B#*Bl zzvQ)F8iUE-(v*hg^x|mj0tsZw0a53XO)rr!((o-#+}aqVE+(YFKxsvrHq}Cyu-yI6S1TKaZA; z)I2Uuf5MaLBjM;8o>=E+m|RFgZE)T2_&bkWlIb?7g4MK+-SdMtML1Hr$Nb1ivy;Rn zkpk7SR4AJnCryA4V8$||WWgItK#PZ$NBsB+sb^aF@&4l%J7Sh0iv1WAu?5`g)FF=& zB#g|BlGa|i9wb*@6dK=1;jBNj`+&a%b3Z~(t=RL!hj2~oWTJ!Z*T=;0->s7%`3YHD>XXGXI9I-PVbChsTclX`+0TlltDhhAAS zd$@n4eFt#tBkO6u<+4Vn{5In;{Bq1yM#U;*Y8AQgG)mkih@^V7QR5+~dg#)~Rp{pdP$(*laGlI+mh~{XeZw&b^o=Hm1JuDWy*g#43 zSVQW;3pdDoj96qD`DZYPWLkvItkuxJAs#PEPD6mU^^!*Wou#d6{j*%tPl^9R>bK$m zCNu-=Ax;tqS#Lx6kb*=Y1K&MC;s6izs9kg>fa4uu&ePJNeC)A5KQz&3VYfCrg{z5n zzNhh|?Rh!*b=J$mc5h?nS3ga+D|efXGOqpnUY7+O#D)Yd%EpDi{e4p`&SO)R+d8Q= zNaG^8myrkJ^LCbki^SLWnYv8(jpn&5g%z~QFP^Wfj@UGEGVG{K0}+cK!jKveTS>x2 z=UV{_H6L`ig-ReCN-5YFYKM!u^$O6VtLQO^l&elpQh zMSmaMocUG%2qwoERFe5(*tPxGXZ&L4d{WaroYJ{a?%AVEvFsNj68dE;+}D5q==#}h$b3(H`X+E{2)7P(SS2 z#2(^iaSSouasjAM)?*!g&@a2qP_^$R+!nsJOPu?9*rf<-8%We6)CsFt)WTKIDo0m( zTsohOE~F#yw||m$B#@Ox$GSU=Z`j2=`12sZI+wYfK=KK2E_o|4Obpj!qlq-X;;oti zEY{?yF{Az$D zqggxL9z8e25Et{g0Ky+oi8D|7iMY(kamRiUm%UH_{%s^biNm>!T(^3B$!M7eW+qM# zo{{$K=|^r}h4`9^iF`*x=E}omtO8|#uw2I4&tpOI%cWEM{&JnS4&D+�Um-AVRS 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
    !slJoT^GWJU1TiFzWAc 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 literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/sound/bloodbolt.ogg b/tff_modular/modules/bloodsucker/sound/bloodbolt.ogg new file mode 100644 index 0000000000000000000000000000000000000000..131eb3568f1d87ce3817f5232823db602255d969 GIT binary patch literal 14083 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 z z&~|q%ClX3=P66cz;XOvj;A86Nkp-3w-&H6WvXUcG8C(7atVq(rwId0-zwG5?1sx;_w*-MOgYC_4jnxfDaEc6?22~mAT4J{nu@~DNaw% zam~%QFK{d=pLNe>Y0_f#sbRs2J--L?gf|HOg=qQ;va(buD4>{GJ6YL1Vfrb2lJl^ zbPgD`p^&vY=b6Q+z!1l{-}y83sS{^Gan_S=XE)?!kGS=_7C!V5e}PO(*RTrmP(NPl z_)VhEI*^p^TE&_6Qkhci!3!vSr&5)cp6nDW8|V*Q-2$@_>=W|x1Ua|Rn4P7 zO}kVj5s2C|GHi?Rg`dU~`sbcYz73Y^tL=hNY;PcEzUsc@Jhj}Bp@`lkE-+ED=>c${ zgfPd!NN|QeCImBol$lFO$@a5`4Nb1B((78rZRz&PYM+JKo58Nj54_nIG{{%2zIzW~ zpD}bhA(;<3YSMySf#webl6sU@-y|q`;9bZF2KnXghCfqe1ZK(ocJF+!=}Hc-{2e}X zEznZ|;SgMG0`W_tgja9GwCo^X<0QcyGAd3Ug2>r^gSprDa>5}+s6=IIFK!3_IFmVY z*ZtF%BG}~JPxy*-RU}g)~ff1TE!TnqXKn% zVb!wlw8hhlNk0ZM&F^59Y0FCeN&l>Vv)q7G_k47}_bAUGj=C1z@HFHVn= zJ&Jt9<@FANzd4OYJq2rMt8w$b6aHY{<5q=>+BkFUPniK$d6q3$=k90ETUjmAoy$^F z)!T#}jEG|70PcT`&BlDt_Ai{#QNk6*sM& zYhLSxwP@O-MwbJH*nE~D(G22!9MQFx z?|Oe^O@}WVvsV(|@oOHOW#d0$`Ynh&Ug_;7tRhzA6%g8F4|Bo%ps0ayh)cOrBoMYo z^0vIG-;UPi{9YST)0;%_Gaj3B+~C9l^K|Z@aegH|7Y!FDvncNQY<(CRYqS=eEG9KL z)#J-UHLqW*=e&dh>u;2IBHCMdVOa@;72zWLDsXz%rHw4{r>wwg`1!9C*$Zj#2?fjY z?Ni9MlPZCGd~K!_y&zKYRjSUD+N|1(Gaiq?AI=N?*;4qr=AN?-iFI;3p2`*2M+ef$ zB1s*E#*0mby?AR(np!;N{l5%cwI{bPob?9z`7^~*^6C0XOJ!rk_;zdcpiyDcBa5tN z#(SLy_O@bt~Jy%X}6fU+9JnOsFC^w%(TCJ%#jn5zq+WmgK`(_=L zZ>{!>o<)}kc-E81Mp#_Q|HdF5Bk_}Quc>8lplP<*dC{zi>Au3s-Hz-zrB+`WYo0COh*suqJp~ z6`GmG{|GZu4aK#n(_R{i>&Qoa`}3mY=S}a5Wu4Q|5z9L<1G@eR=kpJ!Cyom!;e8*2 zCMzbof!^~i30XYHg9ZBwP=d1kuLhgx6nJ#44^jIEyrA&w+_CDf$OqqsHUGV@zOz}r z-ee^v^<$Z2>G^KZmw4%4eQ&C+?9JdwIs@4YoA0%A|3^ApQsc50Amh Aq5uE@ literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/sound/bloodbolt_fire.ogg b/tff_modular/modules/bloodsucker/sound/bloodbolt_fire.ogg new file mode 100644 index 0000000000000000000000000000000000000000..ebc943628d49acee489e9e7861adb3ca45f706e3 GIT binary patch literal 12259 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 literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/sound/bloodhealing.ogg b/tff_modular/modules/bloodsucker/sound/bloodhealing.ogg new file mode 100644 index 0000000000000000000000000000000000000000..dae85df54e51de41e7e811c013da30c0ea9700e1 GIT binary patch literal 18784 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 R?MQ;rgBiu~Sao&vzX8*!NFx9M diff --git a/tff_modular/modules/bloodsucker/sound/griffin_7.ogg b/tff_modular/modules/bloodsucker/sound/griffin_7.ogg index b3ce436e4e562fb0749990cb585a1eda133fae85..bda462d1d96cf8aa4fb9b073efa815e600823c42 100644 GIT binary patch literal 4255 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 literal 6620 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 MSB3)kfw1s@04lzr6aWAK diff --git a/tff_modular/modules/bloodsucker/sound/griffin_9.ogg b/tff_modular/modules/bloodsucker/sound/griffin_9.ogg index 806c67de2f436820b9365322ca066175bd2f4b87..4128a66172ed10c80c947c39f7de0f6392034dbc 100644 GIT binary patch literal 4881 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 literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/sound/humanity_gain.ogg b/tff_modular/modules/bloodsucker/sound/humanity_gain.ogg new file mode 100644 index 0000000000000000000000000000000000000000..d929118f9e1237a10f77e6bb6b8ab68db61d064f GIT binary patch literal 10036 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 literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/sound/humanity_loss.ogg b/tff_modular/modules/bloodsucker/sound/humanity_loss.ogg new file mode 100644 index 0000000000000000000000000000000000000000..3870e7369dd879c8c2e2f122006cc30098f8e70c GIT binary patch literal 11068 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 z z$cd6@Uu>doFZSP-o1kJT)b%I+JXES?&u}BTWpXQ=K+|!)3hUmrZNzO3rlZ z`Sow3lTSzaGy5dt*Ck}fUc;SaM6+q)Ey>|(*9iOx!Rz&7MISUOE&{LV$P+KFH zVl$=hJf3#70mH+{R2c|~V)BrN_iHJMmiQgH#gvCLu|@|TVhH_|>6V5I-tbeVlHIsX z_jTuC8CnKF7L||g%zc;ZQKO9V@awUasPUFQlAKv01=|0lAFx$L>t_39M~qu7F>B||ug*jZJg-#^D-bH zMac4u=LrGJ8E99vqhPG99sDP$T;vgfN)vZ}iJCo!ZexSZl{vezxgFyez?`Mb?q z-;MxC9Ce5NKYjxM2B^OeD#tvrI&i$E60Uf8)I2bh?G3#~!dJ4W0D+GY`9!#xL;lMGA#r1Ciw6GL3soZ?ts+GwIz#A~PES+(iU`T|1LSrpC<3F_yFA*}uGx0J-8`aK z>YMY4z0=#C5@hRR0^$w0i0N`%oaSc9W~0Qshzf*Ar}pv0qN)Fv(gSeKjb^EtIpP_5 z9m_PE;SMX}%;|&SQN<6gu2<;+wZj&Ne}VC}et$I1%H8GQvt&%zY$8QsHp!%VJ_r(y zNoN|*;1gHlg40ma8#w9~T)Lz*v94Zw(o zYzv7j1zoS{Inn3?5504DoT9%$c+TejeZg!Ybf-wq#WfcyEC`#bbKeZaV+evkU_g#p zt3fH%lpupoJ{pwzWIQWNr5_;rzTn3@6fFR#ca!Qaq#zH+lIkXvwWcDp{_`Z@j7 z2R+twlSDn?OiRL^0WkFF+0k+%fd5eq$oZ9jFDe@2f!(epbK(2gA1#|u{+V>y>*U~&IW?JT!&16bAJrK)g=)w+pKE2G&DE42e z!Qq90n3*?xFO9V@l#sm;J^-?3ZuT7w{%Q``CVrtwr$#xB zww;Z(L#GUkN+621R1EDn6gh)o9)|+;hVeoA7?29{+QjP>)<%Um8FS$l+A|_-K=Dwn z5BLlh%cqKV=KRJ*=b-;Td?sFE^lIUWBlDwOwjH{wznxbYz1zT0S2n?T6glBg zs0qvobMGW{YhG^=_qQ(?T_q+QIgCa$1mXidoUQ@Q<7!h*0-${Tkl zZw;bZM?0j2qA7>u!*{(fYBe%tK3^_wjro7{JXJJM?AP^#?W^_JN4lv)D{N8x$522I z>6ucq(Mc8$L&Nvj;(jGhaH75d|59AQP#+yYt_{AM6s zCN;-j&<1;dFOe%}vz6hR#m0gcLg}VYe1IGQz+Mt555SUYd{drD;$J1beSK!aJ=)d= zYP3t_g)|RW`IkfDpCGl0!-rOdT7?7RuOVXTT`Y+Kl6Xt>m%;0$AQPU%8xjck=$(EH zF`K(o`2Xls6A09s-zB7^O9FLeV^1MSTm&JhSltd$Fru-sQ>%0M zZr)7DqP%?*eQcB)eCkMx@=P?Q_6#l8-re?}`q9W9FAM_rKuUQ~63E`?M8qBp?wy0Q#)oW)Hd_y%<-sDc#xN1}-^vM#VnfqSc zkjLeg)c>nJK)9Dcr2qiVteX^?0fVFl0On`9z z++`4RXbl&}a7MA9ia&Ne;%MIpPz)J}+7I_J`6Ve9*Y7=n^+V_;?eoI1L2Rs)QyCiS z6@Ug}Ltl^18l#B!pC`{lm(hQQyT1WxvAw<=NQAI$86Z@Mz&?dz$gC2k~o~qu_8bPA2|OxG=7R)WS#UbJHMnl2a4Vxh^Zb!>}F2csU+0Q z?DtS!&sq@OlkwWe?m*nHFD@PO2W?+BINs8qVGgUSzJJZx0}?<%?+|LTEylBuXL=OC zhOXoS#HJ1LrU8!sk?H!tI`IAG?XZc9pFRp=G=Z~hn42w%VrrytQyB zddvVZ2z1`g2=x31=FQ2)ME92#htl{IXd5=@_rXiL4eu|2dy+l0`1Imqs^a%1f*SbZmyI3>bFA` z!r}f$R`tL)_kgK$Y<@Xvw9#wyxK=FoDP#3Ts~A%sja?WW5om0{D_=fPnfrhC1{6VN z?i6C@g`8n_mRMdC@4ALs#? zJwCW>a9oU_baqZ6wv-#S)p6xWFOsF-6l&Ty`ijOiOvk6VuzIL!m~J)Vkh~&5=|O8J zPiV7MnD!MPB5>V3^*QKJacBKYiXRo53sb){lYpgeFx=tr^8cSbNLS^*k-ZKM<)J{g zdFDVhFwbsKqvtyt7T^=)DxK*V8Nt*>y%JkijF&D&?OCvs5@QWJVBy7RWl{?kq}kw8 zLFxZ;q!+rl)`V8)jKRbiX}nidkk>0Ck41W|Y(>xZXqSQzB*PD3nA8I-grE?LE0W|b zJu%^3qw+rBf-Z<#EQ{)Y3<4B>$fm zDy~qN3j~NRLRcfB4w0nCtkq&|6W%iN(Iru}TfnqekJ7)^j0diDQ&4vq`r5F#=J)@1 zV{KVc30{~%v>^!3jcm;lpi4&LuTz8!pJ(1J$vNa>wW zgzQCyFkSj$wFrfyx|D9Y&5ekUT!fWD=^5lc1t9RK<-C$fsN@g0be@|oLAprr}d{!z6 zNMgKV_-=HIkUHmT`si!ilO#VR6>U5aEa)X4-4w;J?_dSB!Tm{|t$F&z!L#++2#}}w zf8iZyA~q2XQ%a&QY`)_a(d4&`fKEVbbJ<)n@Fa%BDI+X|u+tRwVwiKAaP0I320)yB zNPX=qFL35+#3~qfdee$x9_4@#}X95O* zRh}0@U$J?BPIn-Uq5t=Ixr{WwTd4ahzC#f;b>@)ttvrNm9xP-q@BLU9V)=s8vxijS z#S0DSwNl28V=v8lhPD*#qzc(YgzU_MFEOkX`1zOT!*M=rDw8TEmjvE^xrt90pw7@A4!fcl__$nY0wCn<@Mo-U zcyxEpi8t=~RvY4jnVzUZI+zc>Zc}F7YdK+>sY{>cp_6{+CMcZBUZu3EmX%?}mn0MM z1cnSXJpogP(AIMPBZn8WePdg|$;u$IhU3=j=IPS!enfF87_4TnSktD|a2FH+JBu8Y z#ZG;mcU!&4z@ucLO?^Ya%jKCGvJKhscS34q|3)!Bef9mC1GASHBuO^3xF2Kr#_VdI z&cC>8QOx5RA{%aNPiL}cI5AN&hn1x#pqnYc;e39}F^`+4UcVA|WtMt);rc6%Y3z-v zzSncv+y0sLFg$Pu4j256`lc7ccj~SE_Vd#hxZcs&Zr`x}@9qB8EtiC5Zti{@U0J=V z_P~AMl>`F4kU2Ppgb2fr?I9bszLSb})8?^~ja{++`r(5@?=LehI_PC*!P3)ND$1Jl z;qT2!?(a1gaP9f}e21g66}MaS)BgubIx;js-d*%;J-8zIHu+IJaEaVMhJW+^DJw0M zyBT3z{?ziJ8p9SA7iDk-^1vhhgZ6H*16@HU1$4Go=sWjsdavxcXY#%&uN4>)P9MI1 zox!0YVkxVLgS$&Gf7VPnd)ab!2DM#tsuBX{F@o&+DYM~-<3sE1?dR@Ivsm%{Pm}Nb zmeUMI|G6vblOemWy)eyJbC5O9a$+xhKv=aW(<5UnSRU)5?H*1@n7+8KTeTH3+@2z-3qkV z>E|!zAFDdlXP!FtDnM~f@(WjoISqSNpsCp5=d3)3h5TKU)&M8QMJ5ZMogU77@sF0k z-F9KF1ry!|<1)yy}&rMK?&^TY8 zH~Suw;~kC5)e1aJYlI*4%$xtdFsz~af67D!a4;TN7xDLo?WCT5MoGRk(T9@~7GM7s z)y4C8&Wtn`hMGGymH|h-yO}hmELe~v_Ro*IjrE3>V!O7%R^YMZ#nn;YET?Lm`ZoXe zWv>H5)~CM66?AnhUha59{O_6i|6ZD(tq<&70-AOMf-Js0_fJfDe}*Yyd#1V=<1LXL z`n@}^D=pj7&%oH>bn@J6BZl&|;>HXMthgrBfBSSUp7q~(rB*Hp4xnG|zA4|-c&I+F zdeYwsmTnJ)pGFCP4^sc)e{}nddD9bt`=$SbwyJ}`nU7zN392vdihXPl;hL!Re)ZG@ z?)J~AvL-C5kDgx*kf^@KGUIi~_rDL-UcH)niCOKlq;L%=DNKH2&LRSgqri{RNe&Oi zU5@&Mb=Y^TKcl+Hx_PW^%YtArFf+mF<`}9{727hfx%5hY^Sszw?C}U#V zlD6jmuk`X6*c`Z64HyboBLdkOBHS;AFBf)T+E;wL?bKqyR^VXb`tx!e8aAnSUjM%z zzNh~8@9;CrmF~{#p8m>v`OD7pudn|uVh{lN#(j&g>7k2FGguz@Tr@l`cRY6g#g9cS U)fOOsTFgIi(w?39Mn5kD0D=b&b^rhX literal 73076 zcmbTd1yof{`zXEvr3FN!Q(C&a1*IjWySuwoq@_C*1f)T_5u`g0-Ee56n{zk%zTfY= z_rKP?YyIcUnKRGSo_Ts^&rvitR{`LGe}bg_-wZES{ZlwnI5&GIBTMIpBKTLu00096 zZ~*`3w+>G6q33_XLr*vmLisAMffe%5@_&LO!ry@y!Fml#2McCJCv$QeOC$9^!;?#s zv$L{sv9hspk<+cF1^y?}BZBRpf?r7m3B^~E%0g0d;P~@jOp}ze7 zhxnlB|0F1X)=%UDt9;oAfkDOafXM?&$WdZn(8uOT=b2fRTBg-l6xG=F|6uI@f&Qln z$RLj%W&?b&OwIfML^I7q)BkrAwdi>Xh=RE6b|mh0q>@yo>ULs8`h(#f0Hmp?GGnI` z=WA!qZf8L-zIJ)l8!tC_Du?+m5gy160HSQfosPu4AU2el#+|s{ISWCY^0Y-c%^ zic~P80ru4#N!|Qjj|1jHs9}b_YYeX=%o++q?Am-$G6G^w7D)H{;ZrF z00Oc8aPhy%A6EX$#ouDXUiQ&d4zTw#J|x8*L;Snt9as|RY#mX zb#C>P7DH~lvJ8FhUx@;VN^TM@hDh*7NP?1``snjPsrYZg{iYgzN;3LiarlT>37Z;> zqwGv7971ZUYVX`^HIrQDYCq{tyDmX|mmr_@@q+$O#`=%s0HDwW{*lReqX@R{^p6VS zD1Qn3ujDx5bjJ|)#!$)rppqYB96aV!JmDODCaJ_Juku`X^ttOeuBi&Q?l_m}xSHvt zo9RrAsdlZeX3akW^H*$^Ag=!$7e8N_QLnpYcDE^V*3DjG*L5I#K+U;{7)P0H7@zUG|S2QBr1_ROXsgW>QlX`oBvISUbrn zKh6mvHUR(#KvhWJnHu;uR!l)=PtvlB9H|6xgFX;HZaREBS-eN-?MoAMf_2f}3AP}t z6C>k%9Pxqhqg>|*F_x}6WpTQn$e`ML1SkOjqVx-CD(Pd+>^G-WgOp){PXnmD1f!tR znLQ^Sq<}PzC+Tq9s~G5!AZVE2Fu*Ua_*V)B_yArwAe_pRRQgyjcHNUx9)}_?v12f8M%np#atq0PVGgZ=yy0=^g4$g7#ASoN_(5=?u3`~wz% zU^NH=KmZ&P5CA;u69rKS7eEI9!K)gHAlkYs80DYIM;dFUnuSqGj|&cSe$~u0PaWY@ zQdP4^1u^$v`2bX6@W*B(UW53{0~3h80RlQ48D+udC$B(Jid)l2gob9*fo7rbB{<^n z9|0RzRZGmZ%%ly=wn!~3EF9tdTMV)jIPgQ$!omh-kbWR*fn~aQshge;Eq5A9(F7H7 zO6cgS^_m(!yFVm(tv*%Du6A7tut8(Rh*uhQ$`GhIv!Qr zvfx|1^qZ3EDR%k-P+?K$RwZinfB810Wt|cTCM5t+j(`My(Z2p!7byUIh)|B;gA#K| z(RZagM-t}X7!UEiPEhXSgOY!Xf7zMtjG-(;@Sun3a=~`#&hg5B47yA~JXl7Yt11J6 zk;*Tr!EUqw@VyNVAa9e38AOr#fciue1^5OJ;1hTM01+oQ%E=@>#;JrO2_i~1_5l$} zTxtoXmJi4QF$1CnMC}9P?s(=E6oLvu_1!7R(7Nvu{|75@z%mL3Ao`fQIMP9x6Ia8c zM+P7VnTidO!USEs2R{%;9GN~B3mX7fmq9PdK%9V%(}Ws`Mg@&sPCRI`q;thX*r4R` zW6GbfjEBVNa&y14b&xAVD(S?}RV|1I zK{lBJXBiMQj#s{j*9xzgqRVw*2feM5K|ZJn=yz$M0iqTT03c9q=o%Q8UC{=T3m)(U zt-ZL+gI9({k&ACUz!n^>{NSXihOu=K8)JY|2Yogq3UB~u`bVsX@rJ~ZGn^yAxdx8# zbtgMxi9^$k2l$Y`I!CZ=rh`ri`~!m%NpjQTqr7}rBNnJK@H>*7Blr+A0#PZTTwI9F@>YFy)D5DPl81-bavj9vI^-d0Rq z8phz7vb3$}^K{SvR!;{YK&IR=DB)XW`{?o?Jk*1p>;oQ>L4J8)Bw`gY|o8mpk!q4-f>&0ix<}MPR)0zd5iS=n((g zBOV)E$|talIuKh1nfhD2GU`JQ`rJTeanNxFxh6OMtqlFwcyRF`|A^E50jVGCJ@tdl zrv_`mig+2iuMh2V;~xqW{!}Q-pnx!lvxg!u^EdrdM4t;j2rT?lge~*np)1S$8TsFK zGN=zl^tm8CLAeY7C|@%DQs5{Rgny00E+_gasQ3|}408X&e86U05lVj^5k~xX+&^6( zl82f69q2zr|NlU^wgo(l0O4o~YxOfB;Z00C4K%43$+@IduhbO&?Xu<@Cg3#TLVxHVPIi@0|MINCAuA+VnxgL(6Q1HKO2(H ze*%bNz2JED!iepS+;_yVux-G=@jV3@z|P4%#?1VsAHZ{QguKW4fE7rNi}Y3$9z&sS zC6q^S1(9|OCxIW_>wy6o@BmFOcR+}R*(NW)ps=X;E2%d!atd#iRY4m81}s1r0Ain$ zzer8ti^Pb+jK+$28jBtGEFK5+VnqM!b^$C=03QDD_W41l!o&aF6^qjR83B0M6+hJe zmfj_P{v75H%YfCvvS5|49N0K)0k#1<`h{iR`~D|u*WVuyg%0Yoh+bUrRr?NbBz0v$ zT0_`8ErJ+u!hRN+BK{ilch?>znr5Umdyw6$`FE%Nd!n3~#w8&_UCHv}$)o}aW^DcF z56@0#IvkwD&0fH~IM18Drtq3~Oj7yTWHj4)>HqW8$K5&@vHl+WozKO|AO@GampE0n z(Ln=LPZygl3t|xOzIU=Qk({!PeI$58HkwK#6cN1i(b1@^->;eWM^)&Mj*j#3hst8Un5 z+&!@*-})`R;MGv+;(N12aafKJQuleXw``)EOWt7Mn20^Cm*eT zx9u*w7|vM?b0JaB>Som-ynC}>BDGC3^S!bio#ULNoA#3 zwRy8)jmr-2yDK@bcb}C=K8shsCl7JVfg!CHsoL*~zYY<@cG;K^)qm1`F{h2d@T@!P zs^SSCd_j3hxYOD}<=bw#-~HH<8fNdoq2BYtPp@3++&y-kPXt=mTw2!ZB7XvH^=}=? z&7Zs1k?@LqF3RC4(6)XuIpXX&8AC0k1nM>*U{IvWWb0lgbgyB&aOqt#CF+@tpImONp*C$DFlEif3o4Wm1Dn0A=#1Xq7Ekm-9JZ%a>p zlC?L2>0$KU%Rf!`oA5Q%Bg<^jT(skxfK?||MLqt?NK~ReleI_A9$PZ6ZQW6)=>_8} z;#W$us4asEk&I0nzERhm*m!9KBTqN4=U+<^{>^Eok~x|ivap*ne0Fh)Pa=5gw{T4r zr92%9iBaF=l~H+?D&khvTN!V;;Y1u9w`($1jb!~XiF0f$<0iL_DpsZs9$uV!!{88C z@LW)$fhLEx|Er%!uMpES5tLvVYnSZOf}-*)Z7vr(k`fk4$+{|BqJ{RMQzOFeE7zDk z8!L3?R%4VhRZag)n?Qw1!~ik`;GmBS#B|FAf=t+QYe$!Tv;;32qMN)G?5p=$>?_ea zVRX8io4RpDTMY(Qb$yQWvJ&taJo?o%hJH=dMnOuQ{VsXa2uVHXH~ z1mU4uso&_!k&~BjKE;ZCN6QqZJ=IQL^op#i$Va#DMsKhd?H)6yPU(OX#f;{igM)BB z`u!ZcKHPxeiV{mfSu>9i4mT7$U1ep1Yr%V^9(E$pPRkpHcI+nK75ouRP_WfM`e_Nn zZ7tT7KAT3tJZuK`+RiOtp@#!75MF*7(2h7#+I*^-@FI`c5F`vxWvdB14I23EWwHjIWO`|Xf_iR+QF-Cb1exmLGo%}0)wWBMb7T&{c@YIZ%x;$e68qa)i-Rc;Xi zDFN%{8%cd*aJpRcN1vCtPR_VrF|Wz{*qu6^M$z^A_%~4q>B=h{WLn=&6&uhGZ^Y_P zWjPOL_v&ANbnm9=I8NfIb{l?MMZi;F&;ZMT_>R6kL>}LdAD%u-Cx6k%yK$#u&DfuI zEbh!SuC$NWA1VNecW`rcyvJ|nyt!XFIZbt-;+<7Ie*;M*tKL5mP?Q#! zPjZ!m#2J4Nx)F#%+urErzsY5(rjdE4W4>_+ZJ9{AX=vrI)pypT@AD{?XyLKVlk03^ zl`fQQ|8!?YwUeAceL-XM>ae5ZT_f2O8H5VaiS53lx_B#O8iU~wp+vt=nsBieuI|{V z8jiIG0|k9{7;k_s&g7Xe0=lNUM|DcWjheJZ6z~l)2*CWqAvdq_BOnv6su+8xm9pgs z1+Ib#KZt$`CgHONmkI0s&?9UXg~7o7^zK~ec$|fDo`2-m^-I>XNqD(Mj1d)A_wj8T zv#%Tvvc#ma6OxDl(Sux%tW%Bd&mU^9Eq}4N+G*+|z4E#!7T&AV%RQ=;Fbwi`Yqmx~ zh*kL6vlrW=V>SA8t|d!~L-TOAsq1*t^SC$4c?P1d;rT;r_+I3CuqL-|P(~wmEpqpX zaiP_#fUl{Y9$93Cm?%?s9ZDMW-Vrpbd?W&!9!C+Z|=NY1Aj>-0cUSiU> zd##jFSFVb!T)w8CKJq4=UP zHTBxMZ+vZ?Qp#HY;%a9dwj!yLmmp#Wtx$~NjX)ErHz~RETeOAZ4K?q24-DxVg?hWe ziu;>*u($hGo@NzAX4JU#dU%z*-STpn<+CZ-@l<#9S00m`pkn1$cN@3}bW?t6Tl{Q7 zMtb&Oj)-lw!{wV{n}a6pd@gH(FlpK|o;5mNNmk=HIga+m6j6gm^aq3TxpGzW2k1XK zvDdd==mPl8>+}QJMWywnPZ0p6Mb-`fC`Fgr%w(q*yXflRAz1(qpofHBl8giU+=SBl z{$!SwV;S|@KbXneBGlm&hE!g5WQbRhoOTJv-sQowYAo-Fu_d2w!$2sdkFxjsm&+G8 z2V;H%U_`jh1qev(Rf|1+^XEkbbyVwR^<_tkC)#Ys3%a;&{S8M}?FyY&3NK_taUN7Y(i>u($*zX47E*1LbZ;gB$vM4I_ff!h*$hr^N#19;aUmp{! z3~I4zw?-4+#p~fRQ84Qs5=5;-W-q9imL_7<1==6&@H zI{LxF#p$?m+!ES%7w)$Ny663qdb(D$tFPvc#UPliXU124^F;YIj$>DS+QWO@solZI z(_JHr@1Oe7Cswwqaeh>dXxO8;mdZLz&CLsOvnnnXCP3XO|KeX9?hwLRuubzNRmuQG zTJy3(EMNPB^+k99WZ9%OxOEz(4p zVeIaJMzRNqt$CPN2;yUd+6F*U9!hnxts2 zw6i(+bZ~ctQDnmo@0^+WSK$DzW6HeORo*R%4u?*8EAh~&YgT13qrBQ#C==0a&VSAz%RO5S)vF2B#N6mfc%n-;nVtQyDp$DQ=ux#e%KJ}ar}P6(Q@ zp~({NpCI0zo#;WGIINozO9taOiv2fFE?8BGeyBPeB?iCfUv#6sj-VX?|$s7Xoi7w&34t;DsE~@!l{+(R{yX5t`#L z3N3#UzBch3)p7swd8Rr#mP_Bu(%%yTq%m?7OGV`x*~o>0vJtOdOyMyh%&h+nmUS#);7h~XsM19 z9rw^Zz9nyskh#$;eK@n_0Qi8%%Yf=KDr3M6-~$Nw{D$KWAgPltT}Ak2X<^vG+4ex> zdv8&5f9o`rx=NOg1ya-gU_q5bMqf;;8_DD)y_(jvLQw`58X~jN z!jZ(8fs_F-gOIUCYEyI0qQ-jkp8s?L6p={FepI8R$GoMJ0U3FYbepp=c5@PCtK z!I3FM|Bx85126klHwH-eLqUFq=2_u1$j|(V_kwx_Qkk444%d~?g;i&LZV-5wQ;gam zyby8%PbBpoBGVnvAhVq+>xEaQJ&sCjxT^N!5z}N7JTL*C-{|4|a}p!VRzsMh6cNZ!PsFid>D)r2E$pztFpn{7C~P{GlU6d+g?>4!KCgfgdNUq zY%j@%iZZX^p$OUAOA745WzVhUy}P+r=L9qcuBVrQZCP@6Dq>D@gdX8d1mFS%xJDs& zd)_7hI7qm^bUY!j;Kdrj41AcyW${Jrpr{L<>93*=67k~QU0jt;&X!7Cs*i{8#_U8G zyyI$R2lbovM1!-qS*jznZT01wiF#NzcEeHybdkQ=Y&Yo8Bvc;k z4qj5Y#vCsE*00k#o^9H1+SRR~s0}~TuI*U0_=#D>(!TLb4$FLmFrj87=S-kXKdP~g zdY`o6E16%T;MF_nQnt)!$K~`+!xCNC#6DgN2l?H-idyJpppE;Yr7^;e7aOCg$wby5 ztbh!SDH-eKQV~{*!d30kULYP5yeCO#{yM{9Iv@a-}q zwzgAjrr$C9r;_j9z4UWe#=H@CCi=lmOBcG^{D-nXg?)M@t!tqb(??d#a=ssACd0?q zZl+zNadI^CP{sHaq`xl_WUkml>eU+~xrw`C9xJ{;sBnrIXvh4%vW2Ll%U-QL_i%U_ zaajK*nYh<6efDF@K!dPv^d}7Fq?g>|9G%&?kCV$k2s(>Lk_0LS3=LnyhPfZ10KdVb z*=6|5B=jG7(MM!fqu$@Ucq~-e?NY8WJ(uBHU;;fg)@3Z%emBg9dml+|4w23&u-kXf zI}iupc$cH{XuBc_-5v{a2Ygh!w+iUb^r++>eX|IkNP@ZLq+1H@K)Lq?{z(0o$k+Hm zX47Lmap<~$FYJ{92I=1S#F_X<&R+%Rntl28_qYX-CQb{u1=G5#rKNC(`qacxsAA@4 zC}wNUYYvplj*HuVUYfHb#5M9PURmN$kCY8&3s2@gUMF-vHg7g4{NWUNf3gtxUjJBX zwy@|Gye_)MnvpCS=QF&yAN~028KFOI7h9XlAWFAxUNBmQN26zVp6v4WxsfjM)dvJS`-S8aBnyyHk zC3JFB&!m||&*4`;->R~Hl?UBUi#(bShe(>Ai1&;+2|rGNQup4eGB+<;vn<)=4)3jP z@t#*C2`l5yjgKu>Dh|!*Z8X<#B{^4AU+BB9@JRZJbsIdQ;uoR4?Rx2zz#XEMb z{E0Q9v&@pF$Mi|19vKt8OKG6kV>qWlDGgN}6T}_|$7q~S9%bFj*iT1}H7uEPP@WL1 zh$GQ5?f+_1HA#klX@TBuqJVDkGgzQH#jqxX%i|kWiA)in>DI#9l=^tw_^9AvN;Et< z0I87RNV+LB#K0b{%9JM_xDvI^O*lxW7_O z+3X;~zd>tN7N8nNUS@xD3Z5YD+EHDMhK(8<00LhIPMQz~1lm-O>gJm?ML{$I7+Eb= zzP>hrxAA5{)Rs#uI>9SO!e_-v{h^L={EZ!sOHm|f*Z!)DV9 z@@6@O!ScO{!izj9yPDUurXD#&DR*LHn9HT_yq(8>9|ZkS91ee`hIlEv@09?lk3(sx zY_SgBicQi@I71)#Rx5si%x9vRcYEFKqce4<7F3VtkC!>cyK}nnPFrE~2Z}4zaF46M zfbGD|(JS3V#~DGxiIdYfUJt0hNQ9T~{O}XS)g_5vO9xBB?>2|8@+1B3?K7?PvM_p|bbv<>HNApDSy{x~(2Gw4W?YBtChT^!!nBSpCHhA3g`u*+93ADQ ztCkL$5reslK?zr8EqwQ*gSgatB zuFi9(*Rh-IdPPr=yQC8*s-*f9d2Pn{N`lHyO3F}&nIX2{wmRD3c_~9jawN&Cpov|b zpkAf*Xx995UeW>L-!DuGk;6<8Uvu)aWek|SYKRt9UHTg4k-{zIM~ zS<=J^OI!En+i55J#w7}aWW8#fP#t7)GNeeYjL3cfvM$0@bV(uxpZ$SENV&^P~L+Tp_L z_VT`p6HCQicLGc#evmeqWO@zecZ>#!>319`-!a~)7TMQUd04EJ|m zY*x=ajJT(5=Shy|4kU&tC;fO($xZ~litPQZt69k|CgP#KpXKB1t2oX&M6UJ~<@We? z-M<|{nsRFGexG~2DmZ9i63CB4kx{csm#vKa^^$^aCl~6&I5o%49C`4H`^EjQ)fyO; zkQJ>?X5-h|3ntI&(vyj1ZgI2M^{?qRlrt~XJxGLV>;YSbLYUK0v+|Wg6aC0LEdAz((ah> z5mXa}=U85kpGdR}3~tJ^N?4fI0fvtmDyE_=KS7oh1emMDDYHk)a=r=(x&&%{qCk&! z(m~3_jtZY83`oY6a|O5Cjbj-&jqEu3jl734@6j_uRQK^OJK9)&Z!lHzW&MUpwH`U) zubh_gcwsILPI*e*DWPPAofr%FpS^#M_B+N0K;b3ddW_H0pMd2n`mBx|nsZ1R*VFhJ zlNi9_eJlEWx+nnQZH^sb_~Cmagsp>}Oka`*g#oC2Cch%<8@fibbRUuGv;WStO3ps} zYjHSHLy>S^&-#2?BlN=cNG+bxRQd2s)@ols1Bn{>XJU~DOrO4ojZ{a*$5Fs{f+S^w zVml`h*Wlc;Yv{|kyXmynHy)4D=%f{w*Q`mS#15^MA3UymzYbAAJ}XMrO0*Q}=%$qN z6E5IJ^J^a}7qeXX%d2ISm%Q7tVHPN)qr1(@A$@x^KGm=-TbloVmdoU|Q>n2wPMSA6 z-PQolrb`oTrTqG$$A#+HFk4(s_!-nygyyJ*&vGQ%UmK_PiuqDFgK3oertinwz=w;MZ$}U%>-_*L9HI%}HR59bS#+f+C z`PkECVZzJkYW~`+4JvE6DN|>+!XLUmLV}Q~(G6G&4z#OHqE=1lGWNmZkL*R}Li(7nIRG0poae=_@k$E1V6 z;q7V0dBf{RG+xDB@DA@Us)GW?;dvYb5M3$hiLJQmNRtx*MnEOWd7p$h+R4=5&ns%J zR^!Q=#(n0n>i*u!3-*w6xu%reDH8v?ph_2es!R(BS*Lwe$l6!bVOurr@AW%gQbGK= zDy>?Tu0D_j{sK$mqVl%=wr_&NisyS(ny(a})A?|-cM@1Na5mn2_1PdvMiQw#ZOuCI zfxgU-t+jKno@F2pY;lQ7Um%m)i;xvrOZIi9ObUmELL?V(J~?x@A6{HnqEBn9NM^lY zrnQIBL}n!OmIUMDQV+D~6fLW@BtuwQjDhxc?f3wAo!Jud#YK;T6tvrvPIPi?m2{Yb z9=CN?)=p9_O3L(cSEtgz(A=f-mhF_iPmsKa6XQ80Q3ALzZb_!^#H(kbLkI$=_ zDde%=Wml?fYv{bR2%2x3Q8EDDZOtLL%5v$NOs zNI^#eM-i3{^duf_cAQ=R!Yvy(TWgTQ)k}Y|5u=ZfMMf-EvVD341%sKr+&H^)lf)X*MkWt$=WL^;(h;Uf0e9pM?}&^AD%N zkXKf_8b>2y;hiZZam~_^NlzZu>RpjW0d9R$$jF94ox#5%A;N$yzZeDB2D+6JyeE$()l? zsC8z?q&r`aTk$?^fy`q_-tF$)Rr}rw`#aD0JaQf$H*KkKuiv@5Vs};AtSjEL~jZ#m%!cs&4Up=e6iYnssTHr1kITs4p-sK4c{-M9^Ww7yeW4>aM#H|&% zzP#s(b74+WaNy>eN75JAzAQH}+VgU$LDH>2QY8ok;mkdb{+tLm+ivu1*gu=csNy z%lgPWcH9c;Gr?qgfoV3kcjz-`;i<%Bf5jk_K}OBBr(~~sk)Jm2IODaQ?U*2MawA*c z3wuV64h)cUK0aqK!w9PQ=3n=CnQ@?Ojw(XmoPcNXHIr~9lp8YKTRB`Zbiz{Yf#*Iy zyvelY<)J*6f95u2KdI9z{))Yo3d1(v83Y zFkt?+B=8d7L=6c`57Z?E1^hj1(G?Sctndb(A8mhcCY=RN)C~tT3#3rXUVlnfFDkS| zb<0*CS1+&ISyDhGJ7VjMSxZiq;7@l<-8vnA{zWlMk(Np8W&lCRz9+4tcsx7yk3!Nv_o+ez z6HU7v+`}&rVXma^Q1#ktM5edhd?o3Ow0ub$hdLMvjZB-*QOsa7PWg#d^t`PqkK&Fl zO6sC!?^do5i%?##0I@440hi!^`p_ zw@)}Zj44yiF+S?Z5vp1;O2+eFvcbJ5Yu`M-tN;FJ^V8B2^0$PNPn9s3zM2{f97{qL zQm{1=#cjgyW}w6U!rp!{GL`q^Z^~>GAzhofkO04c93<$;r8@znX!P^1*HeO37|q`P^F1_*k^0 z8X4OYc2jjcJDOTjdUevPD_EcVIEW(TF9MuKoPU&=>pa zyXms)pre3}*0QrJ&&tneZ4dd)Rj;<)@yBQ#XWOZK9YD4X@y@EiG9VcyElp`8Fd z_AlOT?YBMbFM52ZVEt6zu1t{$7}sx{Lof_lp1Qfoh$zz|@G?<~sx@blk5~ws`8YGv zxuV$h!RAhL#cqbJ^ma~%P_lKcdTmg}6p7&trx+$B(Y!j3f<6A6xpBv!~=cJ zwYHlJ)%){V#QIo_Q&t_K;@Kjnk-Rx;P#j@>aj1KXy8e}pwVzL24IZ_37Pl%lWZ_KNb#^w3|uNuV^J{(X8jb5(ucTvb*(XM6S8LwhkxGj~K54vYU=k_0}` z7ORX>k5JCFy?XK-lD}K36UU>10O3 z)*$vR&UdR!?#MhX#qLLIF2YWmiQ=7{US36?F|ud79P*wa-%px2rGKziTk?G^zQ(LZ zmWglsgv<6x$Bi` zm{5L?pgc+RX5GbIs<{ip_*h(wH3OQTy_B)I<8}1-a~Vn!T3e+7l7yEt!T9ij@XpI# zh%BGTiSmiu%tk~QWRm+`JYj)tBGLUlbo~hrzj`(Qz+(cnyuw}H$Sc+*rtwFpz<{0- z!UQ%;{TClY^GVA6r-gT;s4ZCsb2k>Sm9CDz0kge(=jtM7tPg9okcCWw z6DYQs-25V;E>Ff;$usVpeb$?UyUPYXUcD$t1-9it$y@xEf>Sk*X2S$#pqN=w;l)-e zCpMq%SH;gWC>?i;uZ!bs+3~FrOQ|vpT5|A`Nd#_B|Uvd(0 zR@+gUutFy@9CT(OdNKJQO<&1n*Ojf$eX*}A z9!E_Gx9m6RU8Nz}Q|jed7=N}Y5@5*ku6By>^kw-)+S!7~_u;c@^9vVRS3Z<4hyEuv zr&y&(vr%gDBnyms)Yqm?B?^kA5~Q_Di?HM8hZ=6fE;IRriJfxkIy)Fuj~?SB>@Zzm zg-BCtC;)pKTLx6l%_ha&M7|sIf~CP%R_WTZ2d{^P zu1)>VAUEUMcgtDody|E`StS_WHu@n#dQaZ89W10@iEo==Yuz$kABqqSk-gJm@^&fk zyRokjZoORE|1N98rj2iY?Ip0j1|KB^QHh${&pRsC5&ktG8Tt;sGS2-_wi`2CtlDZC zxZYeVu{61k+K|_3W3fq6nR1+jbsSSRV7c8RrsJ+|z8<#J3%FP1w(%vpKfA`^Yvzi+ zTf97gJGThvZjLhTzG{WCc|{Bn7Dc^dY&e79HeMxrQZxWoSmjW9VWeV zR`C5|S(D4bGn`X|>yO%|Le}UQS^c3!_uawl)wO0>U2#O+sIS*luwC){_70&RQ8Rpl zl#PzsSnYS;An|Tw!%4gIpJ~)jAzRH^zVZiL%%0pr-8+GgRy@9Zr$=_q;?smt?%l`M z5M?=mXGocK18uwEV9kxIw0D3aTg+0UWzeqfne`w`x?Vw;!~@I9@p>9BFI?>do$7f;DzhAyAOBd z{)A;uBvE(4-XY9YuLHGJIN^)6JyLDh&yw0V_^?JYJO$Yae^!%bs#`y-EYscm1!tCl zrKmQy`%62Y3~Nmy4u`vvvqwKPmmihAx|<$Ge9BoI^NzlFpW6*>2nZ-*t(k88%10ey zh)9YQK!krVR_&BgG{bNfN5mCA_)4NO>jqGI%Y=#)4`0XS{+JhV=ooskndxp<4iNi1 z2Hd{jKU@w!?GnAVO2N=C#y|ZXpqNJ_cJuoAjn?#qKyaD%J0eQu8S0Pj$m`hGgR!+} z^NxPX6cLr5{WoROJuDI?a$UD3@kq0(LuXP@cdTnX=$1S)4{caKlzs_L%)6+}?|#|c zTM$=0@NADBCbRXd8+HkWKsLUOCysV`nUWHkn)EVVAvctIZspnI>2r|o%m1DMd$XI>+?k2;5|2h?VA1WI@yWaG zM6#Va7zxew==W8+&?(qi8JViewti#gmKKfe!7UlImuPcIH0{I<>GgutLdr|ZvR~Gy zV?DGg@tJ!~Lz2In53>Cne|(Q>SUokLt8rIUEdH3m-z_i{Y@};bg#JX2jrr?!f&SY% zzMZhaA?0TbWlI|gnqwsWk}!7_X}bc?Y{uEPvym;YJFgqJBX^lj6YxECGo z%FY^YH{7j{tNDFvr=l`_&zfcig@+7DGS_vdhQrNtKX;$?j{7^t1cU@ls~)bHx8ADq zwTAcE+-xegj&z@o+b1;&YtYr@?UFs zMG`x-3H@lQ0!{QTGa}CTKG*sLXd`-H!#2zkq{XSqO6OO%NQ#Whc+kqrT=V_bQOsi0 zmAjwQcWVV{m@)%?KLm<*@8gAQ$^3S`?52~lnsyXz?gc)e9g?uV7*8ef=+kP43LF`Q zky>*4mK|lFu~jp-rWw2@Lkpq}GR<(qH*ArY%3m{*;VEahF9#HnzJsqQ5!x_Vt1(&0 zxN=9<5zzize|Y=lJL8VYf`Rpt_*vHV{^)n3M5HDH9%tRE=O#UR1%0)=XH61c@tN_S z&g`XWY_jOeK?YNXcuzL4?WA}VBo;Q&SzMLyX41x+p^|JvABu)0R@cM1Bx=t`EAMKA zuLYf0;vmJQ7U#J^FL7_I%=61qq;mNV59V&3uSD9o>O)$VUwj8K zw&t!J&N-aF7!LZxksiU)Kp{9+n`88?mR2_H&4;q$x&q=_$!Od6%h&ycY5dz}F;Jo` zG6lcm8^O0}*QR)}m7Tw2pS@n(XrCMr*c}|x7l;M_wh8DDMFp#pW{BuUh0a82wYN

    8|UMo*98JZ(xkh=rgE0w`c$G3q^Zd!JMY)^pKc_ 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 z�{(Zn&cUisXI+<*0|$cCX3Xkr{J0P5yF_1o2dv*xVKG`jPcMFSX$Dlv#?x*DZl? zhwqu4xcnSl+$^0)o7CGXL+JF|kHI~xuet&Jq%(^DyaYZ07U_BS&6uF2eYWP@5*$pF zIyEJEM5ljN;g+vJ0BCW|ulH51>=AC^+#KdM%-V1C6)WbpPg5*23-69FoG9mO zN;jvu-6N_Qdeg{UD4?wK?anh(2s$(l1% ziFAhXiv6WO(8kOy3Cixq=L0qVzP(%5_+wL&Uzcg%ux>nyDm&q?>1Q>yY6873EURAo z zlsV(vguVbJVa@SvgckQ_bB^dclH5e$Z2vS~C{@kTN7dzKH4?t+4>5`808{?iT%%#^3u-9J8g51@Nl&!q-yNO#1zFS z;_MF_L1j9+GUxp};AaG@`$Bzx z!7N0#8z&#QSU~jd{kc+Sl@BAB{3+rCm?Z0?LenvstvGC&tKHo@eH`nfWw)qs5`GAW zd(UT~sbJ&2z6g!ER2Q-u+4Svz+cU_DetLVn%(A+Lfu2;~AhZ%#Itl|lX$#CJU5Rq1 znIJ?=mY1Umgi;Z#`g1)I!zdqu$@jCkY44`NkU6o<%0M1~>agEnhWdr^H6urEM ztL!8sl00_8bjyzaTHqXLu3)4d|7jynKEeUL*L3acu)NsJLt#2fJKg(cN0RXaG~9t# zT|o#GLj9MmJn2pF#1K@*O&Zz|`5gS@+Ns-?JSIR(6OSyNrZ!HP13|1*;Xg(JNVOA} zH^M|yzTU0D4!k{=T9}zjL2)kxd*y3c0RNC55GgFZ`7UWZkbjWrYZg4iAFpHM06??) z-GKSIaAtG@rC+aHa1QyLS#&$G-E*wA&(02cm(*eJahN)8Pu(H};(K<_9m-c*=X}iT zbN2TOOTQ_=NPS?`S#r7cy{v|y*^tnv?!yd0QcZ9=q$TXi4Zv^%VmDR&z0QRQ0II#y z>Hy1SF>1*ZY>un~^KXl6n-9GIE%BN~0kC1*($Tq`Ca0c}sgCZNNk5B<#uTuug1J#(XXvLH9*SL#(YLi{^CVa`e0>k6@c5)eb2oK8>lB zkB-!vEf*U|{FKNk1^Lac2?sj}+YD-)a%3$)O$&?@9tlI}Y+>U&Yl0&JZU)4J|DCpi zoMI+k;c{OE&#jr)cHD{3F+Vu5s%C%;vHAO)!+T(|d&vnC&=lf>X*n-?HdK&8gFJ+i zz8ss@#QY5vVtUy&gU94jugo}zRJLu66R7cW{ADFePqLg!VzdL5;b{G5@IhcbS9zaS z0h6&h##dCtJNSzlrw>IecW!npmac6aJzZ@rMLOcyU`}wWEwfgK%(SzuQcxZlnb5uB zWAR*BEFgQC4ETL+@ZfNCtaQ)FfnBr~-@8&hv~jAB=zZNQXVHVoJG3XTKVzoA*$;0d zl^WdaJ~-4>QQYKR`RG3rQ}LWC&#kt@;TqlC-muqq&!W*~XnCZEh&f?>^u+(3{kxyK%~&xft%12W=0Y3ACdC$VWQcE zT^^_p^+Nl-y}hk}R>~;`YOa-0+e5dBv7BGRSYsL8Mjl> b?;5-d&U@1Az5q(w5Pjm?o(>#CzYO_5@T>9{ diff --git a/tff_modular/modules/bloodsucker/sound/masquerade_violation.ogg b/tff_modular/modules/bloodsucker/sound/masquerade_violation.ogg new file mode 100644 index 0000000000000000000000000000000000000000..82cc39c2f587f0fca24ba48e66ccac7a468eb615 GIT binary patch literal 23111 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 z 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%0A5SkI&mf;vpwFu;X&NWTKoBlPXG0L)Yg%K?3q|@b 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 WkH@XSaO;e|ox?XrCn+Aj!2bds*w%Xh literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/sound/prince.ogg b/tff_modular/modules/bloodsucker/sound/prince.ogg new file mode 100644 index 0000000000000000000000000000000000000000..39418a7c4750e6ac4f0dc3a870eb7c3c70748b12 GIT binary patch literal 19756 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 literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/sound/rage_decrease.ogg b/tff_modular/modules/bloodsucker/sound/rage_decrease.ogg new file mode 100644 index 0000000000000000000000000000000000000000..ec7fd4466ecf82437cc40cd573a1acdaf59ccc96 GIT binary patch literal 49301 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 literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/sound/rage_increase.ogg b/tff_modular/modules/bloodsucker/sound/rage_increase.ogg new file mode 100644 index 0000000000000000000000000000000000000000..c64bff1e1055ec70cfd51bb33ba8209c6c2ca154 GIT binary patch literal 45155 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 literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/sound/scourge_offer.ogg b/tff_modular/modules/bloodsucker/sound/scourge_offer.ogg new file mode 100644 index 0000000000000000000000000000000000000000..199ca79cab8d53a6f1eea9f8f5558374e1323e10 GIT binary patch literal 10438 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 literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/sound/scourge_recruit.ogg b/tff_modular/modules/bloodsucker/sound/scourge_recruit.ogg new file mode 100644 index 0000000000000000000000000000000000000000..321a2c80048281f474c9ff3e19f9287774712647 GIT binary patch literal 11296 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 K+mcsA@xK6@Q*)*O literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/sound/wolf_ask.ogg b/tff_modular/modules/bloodsucker/sound/wolf_ask.ogg new file mode 100644 index 0000000000000000000000000000000000000000..63870a49176846a4852eb952563827f17bde212f GIT binary patch literal 15191 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 WkDKAV#o&y&^?C()v~6I1QvE;6em|}N literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/structures/coffin.dm b/tff_modular/modules/bloodsucker/structures/coffin.dm index df9b4e01fa6..bc78e9900e3 100644 --- a/tff_modular/modules/bloodsucker/structures/coffin.dm +++ b/tff_modular/modules/bloodsucker/structures/coffin.dm @@ -17,6 +17,8 @@ // This is my Haven coffin = claimed bloodsucker_haven_area = current_area + if(!locate(/datum/action/cooldown/bloodsucker/gohome) in powers) + BuyPower(new /datum/action/cooldown/bloodsucker/gohome) to_chat(owner, span_userdanger("You have claimed the [claimed] as your place of immortal rest! Your haven is now [bloodsucker_haven_area].")) to_chat(owner, span_announce("Bloodsucker Tip: Find new haven recipes in the Structures tab of the Crafting Menu, including the Persuasion Rack for converting crew into Ghouls.")) return TRUE @@ -191,6 +193,8 @@ if(bloodsuckerdatum && bloodsuckerdatum.coffin == src) bloodsuckerdatum.coffin = null bloodsuckerdatum.bloodsucker_haven_area = null + for(var/datum/action/cooldown/bloodsucker/gohome/power in bloodsuckerdatum.powers) + bloodsuckerdatum.RemovePower(power) for(var/obj/structure/bloodsucker/bloodsucker_structure in get_area(src)) if(bloodsucker_structure.owner == resident) bloodsucker_structure.unbolt() diff --git a/tgstation.dme b/tgstation.dme index ba4413a8cb6..5a005f3524e 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -675,6 +675,7 @@ #include "code\_globalvars\silo.dm" #include "code\_globalvars\tgui.dm" #include "code\_globalvars\time_vars.dm" +#include "code\_globalvars\~ff_globalvars\lists\mobs.dm" #include "code\_globalvars\lists\achievements.dm" #include "code\_globalvars\lists\ambience.dm" #include "code\_globalvars\lists\basic_ai.dm" @@ -9557,6 +9558,7 @@ #include "tff_modular\modules\autoaccent\code\autoaccent.dm" #include "tff_modular\modules\bar_jukebox\code\jukebox.dm" #include "tff_modular\modules\barsigns\code\barsigns.dm" +#include "tff_modular\modules\bloodsucker\controllers.dm" #include "tff_modular\modules\bloodsucker\bloodsuckers\assets.dm" #include "tff_modular\modules\bloodsucker\bloodsuckers\bloodsucker.dm" #include "tff_modular\modules\bloodsucker\bloodsuckers\clans.dm" @@ -9586,6 +9588,7 @@ #include "tff_modular\modules\bloodsucker\powers\gohome.dm" #include "tff_modular\modules\bloodsucker\powers\masquerade.dm" #include "tff_modular\modules\bloodsucker\powers\veil.dm" +#include "tff_modular\modules\bloodsucker\powers\prince\scourgify.dm" #include "tff_modular\modules\bloodsucker\powers\targeted\_powers_targeted.dm" #include "tff_modular\modules\bloodsucker\powers\targeted\brawn.dm" #include "tff_modular\modules\bloodsucker\powers\targeted\haste.dm" From 05f079f75349b710860df9ce766fae1069a7b924 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Tue, 10 Mar 2026 11:11:22 +0300 Subject: [PATCH 008/149] =?UTF-8?q?=D0=B0=D0=B1=D0=BE=D0=BD=D0=BE=D0=B2?= =?UTF-8?q?=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bloodsucker/bloodsuckers/bloodsucker.dm | 2 +- .../modules/bloodsucker/icons/antag_hud.dmi | Bin 0 -> 1687 bytes tff_modular/modules/bloodsucker/icons/hud.dmi | Bin 1342 -> 0 bytes .../bloodsucker/powers/prince/scourgify.dm | 2 +- tgstation.dme | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 tff_modular/modules/bloodsucker/icons/antag_hud.dmi delete mode 100644 tff_modular/modules/bloodsucker/icons/hud.dmi diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm b/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm index 5ea2046d9cc..6b36df91c25 100644 --- a/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm +++ b/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm @@ -7,7 +7,7 @@ antag_hud_name = "bloodsucker" show_name_in_check_antagonists = TRUE hijack_speed = 0.5 - hud_icon = 'tff_modular/modules/bloodsucker/icons/bloodsucker.dmi' + hud_icon = 'tff_modular/modules/bloodsucker/icons/antag_hud.dmi' ui_name = "AntagInfoBloodsucker" preview_outfit = /datum/outfit/bloodsucker_outfit diff --git a/tff_modular/modules/bloodsucker/icons/antag_hud.dmi b/tff_modular/modules/bloodsucker/icons/antag_hud.dmi new file mode 100644 index 0000000000000000000000000000000000000000..5b1f91fc771d85fb64a0b811f077423e34312c7c GIT binary patch literal 1687 zcmZuydoXFmQEW%*4TTYaOF-D?ZRp~QYRKzf-q}YrmX}qapixb}9LI^;XWt+w{thlfXEVt8UU)P8ZftK|+C-%Glj5=A@ zxQ32ZrTJv0t#>ckUl3J7C6|BgJOaUsL(-GZpwg52OJ~03nt(x?-&CoL@+Om4Zc{4W z^;_NeQK5^Xa@VG|^M>YK-!^WCAGYWW)xYJH1A@Pvs?oN27!IMe%kE@1%JWbQMuz!vz+M{aO{3pN4?FDj4$+F|D+%FP4p}a71=BB8Z^K}tUL{ink{S9IMdr~ zdJQ7&o9STBJ57h4F9QJ+@Hi?^y^`&YW`^(FnufIW=x75+)*t+KUYzlQ(f?1453nFY z`k4M-9JJwD3`P_VtoqR%xq_S(*-&rYEaefJ<;lX^q;~nW{yI{70)xT4eZ%vhr`(3a zrOWob0VX~!D!#wec1{wDcQKOWO7BB0%6*HJYJeHz9vFTA0jeGv{&E(z)%lVbe6ClF zz1u;(4|}VI=HTz8FF>eSGFL?(bh$x;UF(CwJun-W0+Tz~$gfUVHUI59hd2iF=et)u zt)l`8act!w1Q#~FcdmUW-hUVFMuOzv3tK~-UTD3)d4OdrFYv$XUA&(s9-IGN%ui&4}2R@oLDb!1S z_BEu0U9%Z69eS(aQ?!_U$jY31G%BV*5B#^=<%<+{i4hRL+P|sVg_nvKq(hUNDu(yx z&lQKlGU~P)g{0Ipn$_(I6d~Y?B&7m!D5GP%xWOx8Z$+()PGs1LF!VdC97cgyXOvU9 zPlHcsELBUkR(5UVLF7XYU*0Bqnpa#Ld`h*I(h{Y{b8uIK!Rbq(FIH;D;<_g;W z43=)_9F;~ZW?8LX5g%gZ+m>ZhSlZT(!^=OJEV4j)!jHj>$+gwoh5qYt$;0W(vy&PhX4*vzvtu(nWEIW?2>=UxOsqHLaC4-y zw5HkgK|JcbY)-tl?gH-hJI}tQ;*v>Y=aHAyHRCFe6n^kC;or+{#N%DLP0@mj;I-t} zko#bXWpQeJBKZkw=p>_d!v(l@97``AQjs{J^yON(+>m`Gw%zGrw(Ol$1Td3y2HFHZ zuw+oQiSOxK{lf-s`Jxy9ZnOgChbKp9SrnB-N)!PA`SL}fE%+YX?Xpy+!2BP(vKfXY zxkrBhlskI$P05aIQ0%K5^-3v?#2{Wl0L0TLo`eJDWjMf`w681ylOqtFy~6B#FPec@ z`O=p$n20_#usHP9!cBm(?4-B}R6Ub-&99Huzw^0O(N&vgXL!%TEoDXstj literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/icons/hud.dmi b/tff_modular/modules/bloodsucker/icons/hud.dmi deleted file mode 100644 index 9cd9b225d72261ad3b8a77f3f7eb6af8940e2fcb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1342 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGoi>pE+N?cNllZ!G7N;32F7#J$% z^q$_!b;v-Z?V;t)F6Z6de=q8GZ}DjVCgzpZ=lR0_gG%6@>h`ADGu~D|{8_YP%k{j5 zW$%9opN!t#*zl|1$(z(r1BC@zmc|)dIjestFgG>iM9m4dyO*}4$2j$5b3@Z+>yx72 z|88CVrN2W(v`=`a`knd-TceKNUatP9rs~iSo4(I?_F5X&TmAoh zS=a9Vzaw94dQ?B%KXgs~#xE9zAJIw%Jm)1F@+w#ux{vM``uIX%0xN??TQ}zmfejHl zE}w+Uw%PqG`^|M}CS8+;A zSDMJDp>yG2!v4EV<@_6tDKRrFWZJTgd6(@5_6v-u;tauEPnpkGJ6;Vr_LOg%U8RGE z!?wHMgzLUDFk~<$>^|BraPQ}8dk;gK^2e;Af3xq`op|#7O-}8n75e5$f{f4JF&Z*G zTQ|Q^!dT)n!%Ed1+NbUAFZn5OT3+J%zq=8C8yXsRt@EAtT=4$3^Rw5zG*9T<-k7|P zS68fCpMfF!dxXxuj=j8W4NG3t-ePonRLsEeq*Ctj26l;(j9G4P=F5NHT+7X};Psk_ zeW&l*Gt_*#r1v+{hv9-h6T`=o|22N*D{47Z_MUjo@brHmV@e2vq^N@%>jYAmGyf)B ztJ>Qa8k)E>W>(>xO)+}uwn~qR#J}qn*oCLbET41!>YJar7a#7(JY(Uvu%w}w@0_KZ z3B!Udf16u*C38+NoZ!A;`TWBsZk5m8+DV%lQfJ-RxzdnL=s)Dutj?%jEAI5ojpt=OhE;rX1;3~{+ff_^S- zW!E!*^f^-Re%l%4n7kvCyeG)3)vc;~*n5Lt*gkas2e&uvo%2`4Z(*La>U$5L$EthA zRthVt=9e9KvwZRO*I#!(f6U*0_|E&o_s_1Mb<>``X3lTsDc4_w3z8K|;1Hd8lRs_e zoug&*A6D!&1g7eWy)*y+Yglx&ve*R3+hcidUi=o_b?0mAF2+3zwmL9PHs|Kwf8yzj zc*Ig4+*J@*vY0LP@pw$_1NtYa-hUywo0PaEWb$x&z1`vVcBu# z=-|kb@%?zm=VwRTCiZF;QXiS62#Yh zWl+lI{B-z;|5g1xg1-|VEq^6`uj8-5$KbEsWe!1K=Ursrf4Zs4C!PC{xWt~$(69CO6W0?Q| diff --git a/tff_modular/modules/bloodsucker/powers/prince/scourgify.dm b/tff_modular/modules/bloodsucker/powers/prince/scourgify.dm index a2ad9d625ad..d81b325c59d 100644 --- a/tff_modular/modules/bloodsucker/powers/prince/scourgify.dm +++ b/tff_modular/modules/bloodsucker/powers/prince/scourgify.dm @@ -7,7 +7,6 @@ When used on your ghoul, you will become their sire, embracing them as a full-blooded vampire.\n\ They will be part of your own clan, and of course receive some bonus levels as well.\n\n\ The Scourge is your enforcer, your tool to wield in the name of the Camarilla. Use them to enforce the masquerade, and to keep control over your fellow kindred." - power_flags = BP_AM_SINGLEUSE bloodsucker_check_flags = BP_CANT_USE_IN_TORPOR | BP_CANT_USE_IN_FRENZY bloodcost = 0 cooldown_time = 35 SECONDS @@ -103,6 +102,7 @@ target_datum.scourgify() target_ref = null PowerActivatedSuccesfully() + bloodsuckerdatum_power.RemovePower(src) /datum/action/cooldown/bloodsucker/targeted/scourgify/proc/refused() owner.balloon_alert(owner, "offer refused") diff --git a/tgstation.dme b/tgstation.dme index 5a005f3524e..d76fcddde5e 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -675,7 +675,6 @@ #include "code\_globalvars\silo.dm" #include "code\_globalvars\tgui.dm" #include "code\_globalvars\time_vars.dm" -#include "code\_globalvars\~ff_globalvars\lists\mobs.dm" #include "code\_globalvars\lists\achievements.dm" #include "code\_globalvars\lists\ambience.dm" #include "code\_globalvars\lists\basic_ai.dm" @@ -715,6 +714,7 @@ #include "code\_globalvars\lists\xenobiology.dm" #include "code\_globalvars\traits\_traits.dm" #include "code\_globalvars\traits\admin_tooling.dm" +#include "code\_globalvars\~ff_globalvars\lists\mobs.dm" #include "code\_js\byjax.dm" #include "code\_js\menus.dm" #include "code\_onclick\adjacent.dm" From 0d7600de9192dbf7e9d8e6ca1dff9883280c55e4 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Tue, 10 Mar 2026 11:15:21 +0300 Subject: [PATCH 009/149] =?UTF-8?q?=D1=84=D0=B8=D0=BA=D1=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tff_modular/modules/bloodsucker/vassal/vassal_datum.dm | 2 +- .../modules/bloodsucker/vassal/vassal_types/ex_vassal.dm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tff_modular/modules/bloodsucker/vassal/vassal_datum.dm b/tff_modular/modules/bloodsucker/vassal/vassal_datum.dm index 28e93fa38bb..f8f77e53125 100644 --- a/tff_modular/modules/bloodsucker/vassal/vassal_datum.dm +++ b/tff_modular/modules/bloodsucker/vassal/vassal_datum.dm @@ -5,7 +5,7 @@ pref_flag = ROLE_VASSAL antag_hud_name = "ghoul" show_in_roundend = FALSE - hud_icon = 'tff_modular/modules/bloodsucker/icons/hud.dmi' + hud_icon = 'tff_modular/modules/bloodsucker/icons/antag_hud.dmi' ui_name = "AntagInfoGhoul" antag_panel_description = "You are a Ghoul, a mortal servant of a Bloodsucker." diff --git a/tff_modular/modules/bloodsucker/vassal/vassal_types/ex_vassal.dm b/tff_modular/modules/bloodsucker/vassal/vassal_types/ex_vassal.dm index 42aeaa819db..57988daebde 100644 --- a/tff_modular/modules/bloodsucker/vassal/vassal_types/ex_vassal.dm +++ b/tff_modular/modules/bloodsucker/vassal/vassal_types/ex_vassal.dm @@ -11,7 +11,7 @@ show_in_antagpanel = FALSE silent = TRUE ui_name = FALSE - hud_icon = 'tff_modular/modules/bloodsucker/icons/hud.dmi' + hud_icon = 'tff_modular/modules/bloodsucker/icons/antag_hud.dmi' ///The revenge ghoul that brought us into the fold. var/datum/antagonist/ghoul/revenge/revenge_ghoul From 7390716e707574a59490c2c730490aa971b6ebbb Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Tue, 10 Mar 2026 12:16:49 +0300 Subject: [PATCH 010/149] =?UTF-8?q?=D0=B0=D0=B1=D0=BD=D0=BE=D0=B2=D0=B0=20?= =?UTF-8?q?=D1=85=D1=83=D0=B4=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bloodsucker/bloodsuckers/bloodsucker.dm | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm b/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm index 6b36df91c25..c0d93762ca2 100644 --- a/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm +++ b/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm @@ -239,6 +239,8 @@ // Assign Powers give_starting_powers() assign_starting_stats() + check_start_society() + GLOB.all_vampires += src /// Called by the remove_antag_datum() and remove_all_antag_datums() mind procs for the antag datum to handle its own removal and deletion. /datum/antagonist/bloodsucker/on_removal() @@ -253,8 +255,21 @@ clear_powers_and_stats() ventrue_sired = null coffin?.unclaim_coffin(FALSE, TRUE) + GLOB.all_vampires -= src return ..() +/datum/antagonist/bloodsucker/add_team_hud(mob/target, antag_to_check) + if(broke_masquerade) + antag_hud_name = "masquerade_broken" + else if(scourge) + antag_hud_name = "scourge" + else if(prince) + antag_hud_name = "prince" + else + antag_hud_name = initial(antag_hud_name) + + QDEL_NULL(team_hud_ref) + /datum/antagonist/bloodsucker/on_body_transfer(mob/living/old_body, mob/living/new_body) . = ..() if(!old_body || !new_body) From f1daaa1ccb7c738c1dd2074dadd12f3f79031551 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Tue, 10 Mar 2026 13:32:06 +0300 Subject: [PATCH 011/149] =?UTF-8?q?=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2=D0=BA?= =?UTF-8?q?=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bloodsucker/bloodsuckers/bloodsucker.dm | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm b/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm index c0d93762ca2..0fd9084c4b5 100644 --- a/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm +++ b/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm @@ -266,10 +266,32 @@ else if(prince) antag_hud_name = "prince" else - antag_hud_name = initial(antag_hud_name) + antag_hud_name = "bloodsucker" QDEL_NULL(team_hud_ref) + var/datum/atom_hud/alternate_appearance/basic/has_antagonist/hud = target.add_alt_appearance( + /datum/atom_hud/alternate_appearance/basic/has_antagonist, + "antag_team_hud_[REF(src)]", + hud_image_on(target), + ) + team_hud_ref = WEAKREF(hud) + + var/list/mob/living/mob_list = list() + for(var/datum/antagonist/antag as anything in GLOB.antagonists) + if(!istype(antag, /datum/antagonist/bloodsucker) && !istype(antag, /datum/antagonist/ghoul)) + continue + var/mob/living/current = antag.owner?.current + if(!QDELETED(current)) + mob_list |= current + + for (var/datum/atom_hud/alternate_appearance/basic/has_antagonist/antag_hud as anything in GLOB.has_antagonist_huds) + if(!(antag_hud.target in mob_list)) + continue + antag_hud.show_to(target) + hud.show_to(antag_hud.target) + + /datum/antagonist/bloodsucker/on_body_transfer(mob/living/old_body, mob/living/new_body) . = ..() if(!old_body || !new_body) From 96660565654e06f57ff1cfa8c8048a40bf3082e6 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Tue, 10 Mar 2026 14:01:41 +0300 Subject: [PATCH 012/149] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=81=D0=BE=D0=BB=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modules/bloodsucker/bloodsuckers/bloodsucker.dm | 11 ++--------- .../modules/bloodsucker/bloodsuckers/integration.dm | 1 + 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm b/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm index 0fd9084c4b5..65ba62ff9de 100644 --- a/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm +++ b/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm @@ -140,7 +140,7 @@ var/mob/living/carbon/current_mob = mob_override || owner.current register_body_signals(current_mob) talking_head(current_mob) - handle_clown_mutation(current_mob, mob_override ? null : "As a vampiric clown, you are no longer a danger to yourself. Your clownish nature has been subdued by your thirst for blood.") + handle_clown_mutation(current_mob, mob_override ? null : "As a bloodsucker clown, you are no longer a danger to yourself. Your clownish nature has been subdued by your thirst for blood.") add_team_hud(current_mob) RegisterSignal(SSsol, COMSIG_SOL_RANKUP_BLOODSUCKERS, PROC_REF(sol_rank_up)) if(current_mob.hud_used) @@ -240,6 +240,7 @@ give_starting_powers() assign_starting_stats() check_start_society() + check_start_sunlight() GLOB.all_vampires += src /// Called by the remove_antag_datum() and remove_all_antag_datums() mind procs for the antag datum to handle its own removal and deletion. @@ -638,11 +639,3 @@ description = "Something is making your mind feel... loose.\n" mood_change = -15 timeout = 5 MINUTES - -/datum/mood_event/nosferatu_examined - mood_change = -10 - timeout = 5 MINUTES - -/datum/mood_event/nosferatu_examined/add_effects(target, level = 0) - description = span_danger("You feel a deep sense of revulsion at the sight of [target].") - mood_change = level * -5 diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/integration.dm b/tff_modular/modules/bloodsucker/bloodsuckers/integration.dm index eca36eb435f..ef4d34b8e9c 100644 --- a/tff_modular/modules/bloodsucker/bloodsuckers/integration.dm +++ b/tff_modular/modules/bloodsucker/bloodsuckers/integration.dm @@ -62,6 +62,7 @@ . += "Blood Drank: [bloodsuckerdatum.total_blood_drank]" . += "Maximum blood: [bloodsuckerdatum.max_blood_volume]" . += "Blood Thickening: [bloodsuckerdatum.blood_level_gain] / [bloodsuckerdatum.get_level_cost()]" + . += "Time until rank up: [SSsol.time_til_cycle] seconds" if(bloodsuckerdatum.frenzied) . += "Frenzy exit blood threshold: [bloodsuckerdatum.frenzy_exit_threshold()]" else From c2a39db086786726dce371905a69962e6920d80d Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Tue, 10 Mar 2026 14:31:49 +0300 Subject: [PATCH 013/149] =?UTF-8?q?=D1=85=D1=80=D1=8E=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/__DEFINES/~ff_defines/bloodsucker.dm | 7 +++++ code/modules/mob/living/ventcrawling.dm | 26 +++++++++++++++---- .../bloodsucker/bloodsuckers/bloodsucker.dm | 8 ++++++ .../bloodsucker/clans/clan_nosferatu.dm | 7 +++-- 4 files changed, 39 insertions(+), 9 deletions(-) diff --git a/code/__DEFINES/~ff_defines/bloodsucker.dm b/code/__DEFINES/~ff_defines/bloodsucker.dm index 3230a3372be..3bc69f93438 100644 --- a/code/__DEFINES/~ff_defines/bloodsucker.dm +++ b/code/__DEFINES/~ff_defines/bloodsucker.dm @@ -196,6 +196,13 @@ // called when a targeted ability is cast #define COMSIG_FIRE_TARGETED_POWER "comsig_fire_targeted_power" +#define COMSIG_CAN_VENTCRAWL "can_ventcrawl" +#define COMSIG_VENTCRAWL_PRE_ENTER "ventcrawling_pre_enter" +#define COMSIG_VENTCRAWL_PRE_EXIT "ventcrawling_pre_exit" +#define COMSIG_VENTCRAWL_ENTER "ventcrawling_enter" +#define COMSIG_VENTCRAWL_EXIT "ventcrawling_exit" +#define COMSIG_VENTCRAWL_PRE_CANCEL "ventcrawling_pre_cancel" + /// drink blood via the feed action #define COMSIG_MOB_FEED_DRINK "mob_feed_drink" #define FEED_CANCEL_BLOOD_TRANSFER (1 << 0) diff --git a/code/modules/mob/living/ventcrawling.dm b/code/modules/mob/living/ventcrawling.dm index e53885fe3bd..db2ea5caee0 100644 --- a/code/modules/mob/living/ventcrawling.dm +++ b/code/modules/mob/living/ventcrawling.dm @@ -23,8 +23,11 @@ if(!Adjacent(ventcrawl_target)) return - if(!HAS_TRAIT(src, TRAIT_VENTCRAWLER_NUDE) && !HAS_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS)) + // TFF ADDITION START - VENTCRAWLING SIGNAL + var/signal_result = SEND_SIGNAL(src, COMSIG_CAN_VENTCRAWL, ventcrawl_target, provide_feedback) + if(!HAS_TRAIT(src, TRAIT_VENTCRAWLER_NUDE) && !HAS_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS) && !signal_result) return + // TFF ADDITION END - VENTCRAWLING SIGNAL if(stat) if(provide_feedback) to_chat(src, span_warning("You must be conscious to do this!")) @@ -45,7 +48,7 @@ if(provide_feedback) to_chat(src, span_warning("You can't vent crawl while buckled!")) return - if(iscarbon(src) && required_nudity) + if(iscarbon(src) && required_nudity && !signal_result) // TFF CHANGE - VENTCRAWLING SIGNAL if(length(get_equipped_items(INCLUDE_POCKETS|INCLUDE_HELD))) if(provide_feedback) to_chat(src, span_warning("You can't crawl around in the ventilation ducts with items!")) @@ -74,10 +77,16 @@ //Handle the exit here if(HAS_TRAIT(src, TRAIT_MOVE_VENTCRAWLING) && istype(loc, /obj/machinery/atmospherics) && movement_type & VENTCRAWLING) + // TFF ADDITION START - VENTCRAWLING SIGNAL + var/exit_time = SEND_SIGNAL(src, COMSIG_VENTCRAWL_PRE_EXIT, ventcrawl_target) + if(!exit_time) + exit_time = 1 SECONDS + // TFF ADDITION END - VENTCRAWLING SIGNAL to_chat(src, span_notice("You begin climbing out from the ventilation system...")) if(has_client && isnull(client)) return - if(!do_after(src, 1 SECONDS, target = ventcrawl_target)) + if(!do_after(src, exit_time, target = ventcrawl_target)) // TFF CHANGE - VENTCRAWLING SIGNAL + SEND_SIGNAL(src, COMSIG_VENTCRAWL_PRE_CANCEL, ventcrawl_target) // TFF ADDITION - VENTCRAWLING SIGNAL return if(ventcrawl_target.welded) // in case it got welded during our sleep to_chat(src, span_warning("You can't crawl around a welded vent!")) @@ -86,15 +95,21 @@ forceMove(ventcrawl_target.loc) REMOVE_TRAIT(src, TRAIT_MOVE_VENTCRAWLING, VENTCRAWLING_TRAIT) update_pipe_vision() + SEND_SIGNAL(src, COMSIG_VENTCRAWL_EXIT, ventcrawl_target) // TFF ADDITION - VENTCRAWLING SIGNAL //Entrance here else var/datum/pipeline/vent_parent = ventcrawl_target.parents[1] if(vent_parent && (vent_parent.members.len || vent_parent.other_atmos_machines)) + // TFF ADDITION START - VENTCRAWLING SIGNAL + var/enter_time = SEND_SIGNAL(src, COMSIG_VENTCRAWL_PRE_ENTER, ventcrawl_target) + if(!enter_time) + enter_time = 2.5 SECONDS // Default time if the signal doesn't return anything + // TFF ADDITION END - VENTCRAWLING SIGNAL ventcrawl_target.flick_overlay_static(image('icons/effects/vent_indicator.dmi', "arrow", ABOVE_MOB_LAYER, dir = get_dir(src.loc, ventcrawl_target.loc)), 2 SECONDS) visible_message(span_notice("[src] begins climbing into the ventilation system...") ,span_notice("You begin climbing into the ventilation system...")) - if(!do_after(src, 2.5 SECONDS, target = ventcrawl_target, extra_checks = CALLBACK(src, PROC_REF(can_enter_vent), ventcrawl_target))) - return + if(!do_after(src, enter_time, target = ventcrawl_target, extra_checks = CALLBACK(src, PROC_REF(can_enter_vent), ventcrawl_target))) // TFF CHANGE - VENTCRAWLING SIGNAL + SEND_SIGNAL(src, COMSIG_VENTCRAWL_PRE_CANCEL, ventcrawl_target) // TFF ADDITION - VENTCRAWLING SIGNAL if(has_client && isnull(client)) return if(ventcrawl_target.welded) // in case it got welded during our sleep @@ -103,6 +118,7 @@ ventcrawl_target.flick_overlay_static(image('icons/effects/vent_indicator.dmi', "insert", ABOVE_MOB_LAYER), 1 SECONDS) visible_message(span_notice("[src] scrambles into the ventilation ducts!"), span_notice("You climb into the ventilation ducts.")) move_into_vent(ventcrawl_target) + SEND_SIGNAL(src, COMSIG_VENTCRAWL_ENTER, ventcrawl_target) // TFF ADDITION - VENTCRAWLING SIGNAL else to_chat(src, span_warning("This ventilation duct is not connected to anything!")) diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm b/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm index 65ba62ff9de..af5bd6da428 100644 --- a/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm +++ b/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm @@ -639,3 +639,11 @@ description = "Something is making your mind feel... loose.\n" mood_change = -15 timeout = 5 MINUTES + +/datum/mood_event/nosferatu_examined + mood_change = -10 + timeout = 5 MINUTES + +/datum/mood_event/nosferatu_examined/add_effects(target, level = 0) + description = span_danger("You feel a deep sense of revulsion at the sight of [target].") + mood_change = level * -5 diff --git a/tff_modular/modules/bloodsucker/clans/clan_nosferatu.dm b/tff_modular/modules/bloodsucker/clans/clan_nosferatu.dm index 05ef28df2b8..8ff4918deae 100644 --- a/tff_modular/modules/bloodsucker/clans/clan_nosferatu.dm +++ b/tff_modular/modules/bloodsucker/clans/clan_nosferatu.dm @@ -1,4 +1,3 @@ -/* /datum/bloodsucker_clan/nosferatu name = CLAN_NOSFERATU description = "The Nosferatu Clan is unable to blend in with the crew, with no abilities such as Masquerade and Veil. \n\ @@ -12,6 +11,7 @@ lose your Masquerade ability, but gain the ability to Ventcrawl even while clothed." blood_drink_type = BLOODSUCKER_DRINK_INHUMANELY var/ventcrawl_time = 10 SECONDS + princely_score_bonus = 3 /datum/bloodsucker_clan/nosferatu/New(datum/antagonist/bloodsucker/owner_datum) . = ..() @@ -26,7 +26,7 @@ RegisterSignal(bloodsuckerdatum, COMSIG_BLOODSUCKER_EXAMINE, PROC_REF(on_mob_examine)) RegisterSignal(mob, COMSIG_CAN_VENTCRAWL, PROC_REF(can_ventcrawl)) - RegisterSignal(mob, COMISG_VENTCRAWL_PRE_ENTER, PROC_REF(on_ventcrawl_enter)) + RegisterSignal(mob, COMSIG_VENTCRAWL_PRE_ENTER, PROC_REF(on_ventcrawl_enter)) RegisterSignal(mob, COMSIG_VENTCRAWL_PRE_EXIT, PROC_REF(on_ventcrawl_pre_exit)) RegisterSignal(mob, COMSIG_VENTCRAWL_EXIT, PROC_REF(on_ventcrawl_exit)) RegisterSignal(mob, COMSIG_VENTCRAWL_PRE_CANCEL, PROC_REF(on_ventcrawl_cancel)) @@ -88,7 +88,7 @@ bloodsuckerdatum.give_starting_powers() bloodsuckerdatum.owner.current.remove_quirk(/datum/quirk/badback) bloodsuckerdatum.owner.current.remove_traits(list(TRAIT_VENTCRAWLER_NUDE, TRAIT_DISFIGURED), BLOODSUCKER_TRAIT) - UnregisterSignal(bloodsuckerdatum, list(COMSIG_BLOODSUCKER_EXAMINE, COMSIG_CAN_VENTCRAWL, COMISG_VENTCRAWL_PRE_ENTER, COMSIG_VENTCRAWL_PRE_EXIT, COMSIG_VENTCRAWL_EXIT)) + UnregisterSignal(bloodsuckerdatum, list(COMSIG_BLOODSUCKER_EXAMINE, COMSIG_CAN_VENTCRAWL, COMSIG_VENTCRAWL_PRE_ENTER, COMSIG_VENTCRAWL_PRE_EXIT, COMSIG_VENTCRAWL_EXIT)) return ..() /datum/bloodsucker_clan/nosferatu/favorite_ghoul_gain(datum/antagonist/bloodsucker/source, datum/antagonist/ghoul/ghouldatum) @@ -100,4 +100,3 @@ /datum/bloodsucker_clan/nosferatu/favorite_ghoul_loss(datum/antagonist/bloodsucker/source, datum/antagonist/ghoul/ghouldatum) ghouldatum.owner.current.update_sight() -*/ From 9aea5c02bf5422e3846b4af2ae96968716a0e2d2 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Wed, 11 Mar 2026 08:27:30 +0300 Subject: [PATCH 014/149] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D1=8F=D0=B5=D0=BC=20PowerInfo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tgui/interfaces/common/PowerInfo.tsx | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 tgui/packages/tgui/interfaces/common/PowerInfo.tsx diff --git a/tgui/packages/tgui/interfaces/common/PowerInfo.tsx b/tgui/packages/tgui/interfaces/common/PowerInfo.tsx new file mode 100644 index 00000000000..e18d5bb6708 --- /dev/null +++ b/tgui/packages/tgui/interfaces/common/PowerInfo.tsx @@ -0,0 +1,70 @@ +import { useState } from 'react'; +import { + Button, + Divider, + Dropdown, + Image, + Section, + Stack, +} from 'tgui-core/components'; + +import { resolveAsset } from '../../assets'; +import type { PowerInfo } from './../AntagInfoBloodsucker'; + +type PowerDetailsProps = { + powers: PowerInfo[]; +}; + +export const PowerDetails = (props: PowerDetailsProps) => { + const { powers } = props; + if (!powers?.length) { + return

    ; + } + + const [selectedPower, setSelectedPower] = useState(powers[0]); + + return ( +
    + } + > + + + powers.power_name)} + onSelected={(powerName: string) => + setSelectedPower( + powers.find((p) => p.power_name === powerName) || powers[0], + ) + } + /> + {selectedPower && ( + + )} + + + + + {selectedPower?.power_explanation} + + +
    + ); +}; From 96bcfc2f29a8b96f2d74ef875bea803cd09f4942 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Wed, 11 Mar 2026 08:32:25 +0300 Subject: [PATCH 015/149] Create AntagInfoGhoul.tsx --- .../tgui/interfaces/AntagInfoGhoul.tsx | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 tgui/packages/tgui/interfaces/AntagInfoGhoul.tsx diff --git a/tgui/packages/tgui/interfaces/AntagInfoGhoul.tsx b/tgui/packages/tgui/interfaces/AntagInfoGhoul.tsx new file mode 100644 index 00000000000..f05584a8585 --- /dev/null +++ b/tgui/packages/tgui/interfaces/AntagInfoGhoul.tsx @@ -0,0 +1,57 @@ +import { Section, Stack } from 'tgui-core/components'; + +import { useBackend } from '../backend'; +import { Window } from '../layouts'; +import type { GhoulProps } from './AntagInfoBloodsucker'; +import { ObjectivePrintout } from './common/Objectives'; +import { PowerDetails } from './PowerInfo'; + +export const AntagInfoGhoul = (props: any, context: any) => { + const { data } = useBackend(); + const { powers } = data; + return ( + + + + + + ); +}; + +const GhoulInfo = () => { + const { data } = useBackend(); + const { powers, objectives, title, description } = data; + return ( + + +
    + + + {title} + + + + + +
    +
    + {description ? ( + +
    + + + {description} + + +
    +
    + ) : null} + + +
    + ); +}; From 567f9c6bae74d7c76afc08566e2cca668f08cb73 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Wed, 11 Mar 2026 08:45:22 +0300 Subject: [PATCH 016/149] =?UTF-8?q?=D0=BF=D1=80=D0=BE=D0=B1=D1=83=D0=B5?= =?UTF-8?q?=D0=BC=20=D0=BF=D0=BE=D1=87=D0=B8=D0=BD=D0=B8=D1=82=D1=8C=20?= =?UTF-8?q?=D0=BF=D1=80=D0=BE=D0=B2=D0=B0=D0=BB=D1=8B=20=D1=82=D0=B5=D1=81?= =?UTF-8?q?=D1=82=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tgui/packages/tgui/interfaces/AntagInfoBloodsucker.tsx | 2 +- tgui/packages/tgui/interfaces/AntagInfoGhoul.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tgui/packages/tgui/interfaces/AntagInfoBloodsucker.tsx b/tgui/packages/tgui/interfaces/AntagInfoBloodsucker.tsx index 13e5ccee597..e4cd5d5aee5 100644 --- a/tgui/packages/tgui/interfaces/AntagInfoBloodsucker.tsx +++ b/tgui/packages/tgui/interfaces/AntagInfoBloodsucker.tsx @@ -6,7 +6,7 @@ import { resolveAsset } from '../assets'; import { useBackend } from '../backend'; import { Window } from '../layouts'; import type { Objective } from './common/Objectives'; -import { PowerDetails } from './PowerInfo'; +import { PowerDetails } from './common/PowerInfo'; export type ClanProps = { clan: ClanInfo[]; diff --git a/tgui/packages/tgui/interfaces/AntagInfoGhoul.tsx b/tgui/packages/tgui/interfaces/AntagInfoGhoul.tsx index f05584a8585..c12f1bf3233 100644 --- a/tgui/packages/tgui/interfaces/AntagInfoGhoul.tsx +++ b/tgui/packages/tgui/interfaces/AntagInfoGhoul.tsx @@ -4,7 +4,7 @@ import { useBackend } from '../backend'; import { Window } from '../layouts'; import type { GhoulProps } from './AntagInfoBloodsucker'; import { ObjectivePrintout } from './common/Objectives'; -import { PowerDetails } from './PowerInfo'; +import { PowerDetails } from './common/PowerInfo'; export const AntagInfoGhoul = (props: any, context: any) => { const { data } = useBackend(); From 4974da335317c30af8ddff1a4da568bd4cf2c3b2 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Wed, 11 Mar 2026 09:28:07 +0300 Subject: [PATCH 017/149] =?UTF-8?q?=D0=B4=D0=B8=D0=BD=D0=B0=D0=BC=D0=B8?= =?UTF-8?q?=D0=BA=20=D0=B8=20=D0=BF=D1=80=D0=B5=D1=84=D0=B5=D1=80=D0=B5?= =?UTF-8?q?=D0=BD=D1=81=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/dynamic.toml | 18 ++++++++ .../bloodsucker/bloodsuckers/dynamic.dm | 43 +++++++++++++++++++ tgstation.dme | 1 + .../antagonists/antagonists/bloodsucker.ts | 18 ++++++++ .../antagonists/midroundbloodsucker.ts | 18 ++++++++ 5 files changed, 98 insertions(+) create mode 100644 tff_modular/modules/bloodsucker/bloodsuckers/dynamic.dm create mode 100644 tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/bloodsucker.ts create mode 100644 tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/midroundbloodsucker.ts diff --git a/config/dynamic.toml b/config/dynamic.toml index 85fea1ed341..6e268e0e05f 100644 --- a/config/dynamic.toml +++ b/config/dynamic.toml @@ -679,3 +679,21 @@ min_antag_cap = 0 repeatable_weight_decrease = 2 repeatable = 0 minimum_required_age = 0 + +["Roundstart Bloodsucker"] +weight = 10 +min_pop = 15 +blacklisted_roles = [] +min_antag_cap = 1 +max_antag_cap = 4 +minimum_required_age = 0 + +["Midround Bloodsucker"] +weight = 10 +min_pop = 15 +blacklisted_roles = [] +min_antag_cap = 1 +max_antag_cap = 4 +repeatable_weight_decrease = 2 +repeatable = 1 +minimum_required_age = 0 diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/dynamic.dm b/tff_modular/modules/bloodsucker/bloodsuckers/dynamic.dm new file mode 100644 index 00000000000..5326635824e --- /dev/null +++ b/tff_modular/modules/bloodsucker/bloodsuckers/dynamic.dm @@ -0,0 +1,43 @@ +////////////////////////////////////////////// +// // +// ROUNDSTART BLOODSUCKER // +// // +////////////////////////////////////////////// + +/datum/dynamic_ruleset/roundstart/bloodsucker + name = "bloodsuckers" + config_tag = "Roundstart Bloodsucker" + pref_flag = ROLE_BLOODSUCKER + preview_antag_datum = /datum/antagonist/bloodsucker + jobban_flag = ROLE_BLOODSUCKER + weight = 10 + max_antag_cap = 4 + +/datum/dynamic_ruleset/roundstart/bloodsucker/assign_role(datum/mind/candidate) + var/datum/antagonist/bloodsucker/suck_datum = candidate.add_antag_datum(/datum/antagonist/bloodsucker) + suck_datum.AdjustUnspentRank(rand(1,3)) + +////////////////////////////////////////////// +// // +// MIDROUND BLOODSUCKER // +// // +////////////////////////////////////////////// +/datum/dynamic_ruleset/midround/from_living/bloodsucker + name = "Vampiric Accident" + config_tag = "Midround Bloodsucker" + preview_antag_datum = /datum/antagonist/bloodsucker + pref_flag = ROLE_VAMPIRICACCIDENT + jobban_flag = ROLE_BLOODSUCKER + midround_type = LIGHT_MIDROUND + weight = 10 + repeatable = TRUE + max_antag_cap = 4 + +/datum/dynamic_ruleset/midround/from_living/bloodsucker/is_valid_candidate(mob/candidate, client/candidate_client) + if(!is_station_level(candidate.z)) + return FALSE + return ..() + +/datum/dynamic_ruleset/midround/from_living/bloodsucker/assign_role(datum/mind/candidate) + var/datum/antagonist/bloodsucker/suck_datum = candidate.add_antag_datum(/datum/antagonist/bloodsucker) + suck_datum.AdjustUnspentRank(rand(1,3)) diff --git a/tgstation.dme b/tgstation.dme index d76fcddde5e..e70e42e2d38 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -9564,6 +9564,7 @@ #include "tff_modular\modules\bloodsucker\bloodsuckers\clans.dm" #include "tff_modular\modules\bloodsucker\bloodsuckers\conversion.dm" #include "tff_modular\modules\bloodsucker\bloodsuckers\crafts.dm" +#include "tff_modular\modules\bloodsucker\bloodsuckers\dynamic.dm" #include "tff_modular\modules\bloodsucker\bloodsuckers\hud.dm" #include "tff_modular\modules\bloodsucker\bloodsuckers\integration.dm" #include "tff_modular\modules\bloodsucker\bloodsuckers\life.dm" diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/bloodsucker.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/bloodsucker.ts new file mode 100644 index 00000000000..3a5127ffa1f --- /dev/null +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/bloodsucker.ts @@ -0,0 +1,18 @@ +// THIS IS A TFF UI FILE + +import { type Antagonist, Category } from '../base'; + +export const VAMPIRE_MECHANICAL_DESCRIPTION = ` +After your death, you awaken to see yourself as an undead monster. +Use your Vampiric abilities as best you can. +Scrape by Space Station 13, or take over it, ghoulizing your way. +`; + +const bloodsuckers: Antagonist = { + key: 'bloodsucker', + name: 'Roundstart Bloodsucker', + description: [VAMPIRE_MECHANICAL_DESCRIPTION], + category: Category.Roundstart, +}; + +export default bloodsuckers; diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/midroundbloodsucker.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/midroundbloodsucker.ts new file mode 100644 index 00000000000..d7046699940 --- /dev/null +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/midroundbloodsucker.ts @@ -0,0 +1,18 @@ +// THIS IS A TFF UI FILE + +import { type Antagonist, Category } from '../base'; + +export const VAMPIRE_MECHANICAL_DESCRIPTION = ` +After your death, you awaken to see yourself as an undead monster. +Use your Vampiric abilities as best you can. +Scrape by Space Station 13, or take over it, ghoulizing your way. +`; + +const VampiricAccident: Antagonist = { + key: 'bloodsuckermidround', + name: 'Bloodsucker (Midround)', + description: [VAMPIRE_MECHANICAL_DESCRIPTION], + category: Category.Midround, +}; + +export default VampiricAccident; From 38fba795ae393f30a1307ebbbe4da232c1eaf0bc Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Wed, 11 Mar 2026 13:18:56 +0300 Subject: [PATCH 018/149] =?UTF-8?q?=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D1=8F?= =?UTF-8?q?=D0=B5=D0=BC=20=D0=BD=D0=BE=D1=81=D1=84=D0=B5=D1=80=D0=B0=D1=82?= =?UTF-8?q?=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/modules/mob/living/carbon/examine.dm | 2 ++ tff_modular/modules/bloodsucker/clans/clan_nosferatu.dm | 9 +++------ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/code/modules/mob/living/carbon/examine.dm b/code/modules/mob/living/carbon/examine.dm index e086e7577cc..b7464a63fca 100644 --- a/code/modules/mob/living/carbon/examine.dm +++ b/code/modules/mob/living/carbon/examine.dm @@ -8,6 +8,8 @@ /mob/living/carbon/examine(mob/user) if(HAS_TRAIT(src, TRAIT_UNKNOWN_APPEARANCE)) return list(span_warning("You're struggling to make out any details...")) + if(HAS_TRAIT(src, TRAIT_DISFIGURED) && IS_BLOODSUCKER(src)) + return list(span_warning("[src.p_They()] look[src.p_s()] like a pale, grotesque hunchback, with a mouth full of jagged yellowy teeth, and breath that reeks of fresh blood. You feel both afraid and disgusted as you gaze upon [src.p_them()]. [src.p_They()] [src.p_are()] clearly a MUTANT!")) var/t_He = p_They() var/t_His = p_Their() diff --git a/tff_modular/modules/bloodsucker/clans/clan_nosferatu.dm b/tff_modular/modules/bloodsucker/clans/clan_nosferatu.dm index 8ff4918deae..ae04893301c 100644 --- a/tff_modular/modules/bloodsucker/clans/clan_nosferatu.dm +++ b/tff_modular/modules/bloodsucker/clans/clan_nosferatu.dm @@ -12,6 +12,7 @@ blood_drink_type = BLOODSUCKER_DRINK_INHUMANELY var/ventcrawl_time = 10 SECONDS princely_score_bonus = 3 + var/static/list/traits_to_add = list(TRAIT_DISFIGURED, TRAIT_VENTCRAWLER_NUDE, TRAIT_UNKNOWN_VOICE, TRAIT_TRUE_NIGHT_VISION, TRAIT_KNOW_ENGI_WIRES, TRAIT_SILENT_FOOTSTEPS) /datum/bloodsucker_clan/nosferatu/New(datum/antagonist/bloodsucker/owner_datum) . = ..() @@ -22,7 +23,7 @@ if(!mob.has_quirk(/datum/quirk/badback)) mob.add_quirk(/datum/quirk/badback) - mob.add_traits(list(TRAIT_DISFIGURED, TRAIT_VENTCRAWLER_NUDE), BLOODSUCKER_TRAIT) + mob.add_traits(traits_to_add, BLOODSUCKER_TRAIT) RegisterSignal(bloodsuckerdatum, COMSIG_BLOODSUCKER_EXAMINE, PROC_REF(on_mob_examine)) RegisterSignal(mob, COMSIG_CAN_VENTCRAWL, PROC_REF(can_ventcrawl)) @@ -77,9 +78,6 @@ if(isliving(examiner) && examiner != ogled && !ogler.mob_mood.has_mood_of_category("nosferatu_examine")) ogler.add_mood_event("nosferatu_examine", /datum/mood_event/nosferatu_examined, ogled, owner_datum.GetRank()) ogler.adjust_disgust(owner_datum.GetRank() * 10) - // show that they are dangerous nosferatu, as if you're gazing upon them with fear, without mentioning the clan name/antagonist name, describe their appearance - examine_text += span_danger("[ogled.p_They()] look[ogled.p_s()] like a pale, grotesque hunchback, with a mouth full of jagged yellowy teeth, and breath that reeks of fresh blood. You feel both afraid and disgusted as you gaze upon [ogled.p_them()].") - examine_text += span_userdanger("[ogled.p_They()] [ogled.p_are()] clearly a BLOODSUCKER!") /datum/bloodsucker_clan/nosferatu/Destroy(force) var/datum/action/cooldown/bloodsucker/feed/suck = locate() in bloodsuckerdatum.powers @@ -87,12 +85,11 @@ bloodsuckerdatum.RemovePower(suck) bloodsuckerdatum.give_starting_powers() bloodsuckerdatum.owner.current.remove_quirk(/datum/quirk/badback) - bloodsuckerdatum.owner.current.remove_traits(list(TRAIT_VENTCRAWLER_NUDE, TRAIT_DISFIGURED), BLOODSUCKER_TRAIT) + bloodsuckerdatum.owner.current.remove_traits(traits_to_add, BLOODSUCKER_TRAIT) UnregisterSignal(bloodsuckerdatum, list(COMSIG_BLOODSUCKER_EXAMINE, COMSIG_CAN_VENTCRAWL, COMSIG_VENTCRAWL_PRE_ENTER, COMSIG_VENTCRAWL_PRE_EXIT, COMSIG_VENTCRAWL_EXIT)) return ..() /datum/bloodsucker_clan/nosferatu/favorite_ghoul_gain(datum/antagonist/bloodsucker/source, datum/antagonist/ghoul/ghouldatum) - var/list/traits_to_add = list(TRAIT_VENTCRAWLER_NUDE, TRAIT_DISFIGURED, TRAIT_TRUE_NIGHT_VISION, TRAIT_KNOW_ENGI_WIRES, TRAIT_SILENT_FOOTSTEPS) ghouldatum.owner.current.add_traits(traits_to_add, GHOUL_TRAIT) ghouldatum.traits += traits_to_add ghouldatum.owner.current.update_sight() From 4b3aac18019943141bea8b9f076b27f8df803bd7 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Wed, 11 Mar 2026 22:53:13 +0300 Subject: [PATCH 019/149] =?UTF-8?q?=D0=BF=D0=B0=D1=80=D1=83=20=D1=84=D0=B8?= =?UTF-8?q?=D0=BA=D1=81=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm | 1 + tff_modular/modules/bloodsucker/powers/tremere/auspex.dm | 6 ++++-- .../modules/bloodsucker/powers/tremere/thaumaturgy.dm | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm b/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm index af5bd6da428..f45919c20eb 100644 --- a/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm +++ b/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm @@ -90,6 +90,7 @@ var/static/list/bloodsucker_traits = list( TRAIT_NOBREATH, TRAIT_SLEEPIMMUNE, + TRAIT_GENELESS, TRAIT_NOCRITDAMAGE, TRAIT_RESISTCOLD, TRAIT_RADIMMUNE, diff --git a/tff_modular/modules/bloodsucker/powers/tremere/auspex.dm b/tff_modular/modules/bloodsucker/powers/tremere/auspex.dm index 4acab01649f..90f801aa006 100644 --- a/tff_modular/modules/bloodsucker/powers/tremere/auspex.dm +++ b/tff_modular/modules/bloodsucker/powers/tremere/auspex.dm @@ -19,7 +19,7 @@ bloodsucker_check_flags = BP_CANT_USE_IN_TORPOR purchase_flags = TREMERE_CAN_BUY bloodcost = 10 - constant_bloodcost = 1 + constant_bloodcost = 1.1 cooldown_time = 12 SECONDS target_range = 2 power_activates_immediately = FALSE @@ -72,8 +72,10 @@ /datum/action/cooldown/bloodsucker/targeted/tremere/auspex/ActivatePower(trigger_flags) . = ..() + if(bloodsuckerdatum_power.frenzied) + return TRUE owner.AddElement(/datum/element/digitalcamo) - animate(owner, alpha = 15, time = 2 SECONDS) + animate(owner, alpha = 70, time = 2 SECONDS) return TRUE /datum/action/cooldown/bloodsucker/targeted/tremere/auspex/DeactivatePower(deactivate_flags) diff --git a/tff_modular/modules/bloodsucker/powers/tremere/thaumaturgy.dm b/tff_modular/modules/bloodsucker/powers/tremere/thaumaturgy.dm index 383b7e64e2e..38ab3ca6676 100644 --- a/tff_modular/modules/bloodsucker/powers/tremere/thaumaturgy.dm +++ b/tff_modular/modules/bloodsucker/powers/tremere/thaumaturgy.dm @@ -8,7 +8,7 @@ * Level 5 - Bloodbeam spell that breaks open lockers/doors + double damage & steals blood - Gives them a Blood shield until they use Bloodbeam */ -#define BLOOD_SHIELD_BLOCK_CHANCE 75 +#define BLOOD_SHIELD_BLOCK_CHANCE 50 #define BLOOD_SHIELD_BLOOD_COST 15 #define THAUMATURGY_BLOOD_COST_PER_CHARGE 5 #define THAUMATURGY_COOLDOWN_PER_CHARGE 5 SECONDS From 402a2212785699a49ce98b8c1a852b62c5d82265 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Thu, 12 Mar 2026 19:52:57 +0300 Subject: [PATCH 020/149] =?UTF-8?q?=D1=81=D0=B0=D1=80=D0=B0=20=D0=B0=D0=B2?= =?UTF-8?q?=D0=B0=D0=BC=D0=BF=D0=B8=D1=80=D1=86=D3=99=D0=B0=20=D0=B1=D0=B7?= =?UTF-8?q?=D0=B8=D0=B0=20=D0=B8=D0=B7=D0=B1=D0=B5=D0=B8=D1=82,=20=D0=BD?= =?UTF-8?q?=D0=B0=D1=81=D0=B3=D1=8C=D1=8B=20=D1=83=D0=B0=D0=BC=D0=B0=D1=88?= =?UTF-8?q?=D3=99=D0=B0=20=D0=B8=D1=83=D0=B1=D0=B0=D1=88=D0=B0=20=D0=B0?= =?UTF-8?q?=D1=85=D3=99=D0=BC=D0=B0=D1=80=D1=80=D0=B0=D2=BF=D1=8B=20=D1=83?= =?UTF-8?q?=D1=80=D2=AD=20=D0=B0=D1=83=D1=81=20=D1=80=D1=8B=D0=B4=D1=83?= =?UTF-8?q?=D0=BB=D0=B0=D1=80=D0=B0=20=D1=81=D0=B0=D0=BB=D0=B0=D0=B3=D0=B5?= =?UTF-8?q?=D0=B8=D1=82,=20=D0=B0=D1=85=D0=B0=20=D0=BD=D0=B0=D1=81=20?= =?UTF-8?q?=D1=81=D0=B5=D0=B8=D2=AD=D0=B0=D0=B8=D0=B8=D1=82,=20=D0=B8?= =?UTF-8?q?=D0=B0=D1=80=D0=B0=20=D0=B0=D0=B1=D1=80=D0=B8=20=D0=B0=D1=85?= =?UTF-8?q?=D3=99=D0=BC=D0=B0=D1=80=D1=80=D0=B0=D2=BF=D1=8B=20=D0=B2=D0=B0?= =?UTF-8?q?=D0=BC=D0=BF=D0=B8=D1=80=D1=81=20=D1=81=D2=9F=D0=B0=D0=BB=D0=B5?= =?UTF-8?q?=D0=B8=D1=82,=20=D1=88=D3=99=D1=81=D1=8B=D1=86=D1=85=D1=80?= =?UTF-8?q?=D0=B0=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bloodsucker/bloodsuckers/bloodsucker.dm | 4 +-- .../bloodsucker/bloodsuckers/integration.dm | 3 ++- .../bloodsucker/clans/clan_nosferatu.dm | 26 +++++++++++++++++++ .../modules/bloodsucker/powers/feed.dm | 2 +- .../bloodsucker/powers/tremere/thaumaturgy.dm | 9 +++++-- 5 files changed, 37 insertions(+), 7 deletions(-) diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm b/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm index f45919c20eb..f70f17b1e5f 100644 --- a/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm +++ b/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm @@ -69,7 +69,7 @@ /// Used for Bloodsuckers gaining levels from drinking blood var/blood_level_gain = 0 /// How many levels you can get from Sol - var/sol_levels_remaining = 6 + var/sol_levels_remaining = 4 ///Blood display HUD var/atom/movable/screen/bloodsucker/blood_counter/blood_display @@ -81,10 +81,8 @@ /// Antagonists that cannot be Ghouled no matter what var/static/list/ghoul_banned_antags = list( /datum/antagonist/bloodsucker, - // /datum/antagonist/monsterhunter, /datum/antagonist/changeling, /datum/antagonist/cult, - // /datum/antagonist/ert/safety_moth, ) ///Default Bloodsucker traits var/static/list/bloodsucker_traits = list( diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/integration.dm b/tff_modular/modules/bloodsucker/bloodsuckers/integration.dm index ef4d34b8e9c..f6efc281f77 100644 --- a/tff_modular/modules/bloodsucker/bloodsuckers/integration.dm +++ b/tff_modular/modules/bloodsucker/bloodsuckers/integration.dm @@ -62,7 +62,8 @@ . += "Blood Drank: [bloodsuckerdatum.total_blood_drank]" . += "Maximum blood: [bloodsuckerdatum.max_blood_volume]" . += "Blood Thickening: [bloodsuckerdatum.blood_level_gain] / [bloodsuckerdatum.get_level_cost()]" - . += "Time until rank up: [SSsol.time_til_cycle] seconds" + if(bloodsuckerdatum.sol_levels_remaining > 0) + . += "Time until rank up: [SSsol.time_til_cycle] seconds" if(bloodsuckerdatum.frenzied) . += "Frenzy exit blood threshold: [bloodsuckerdatum.frenzy_exit_threshold()]" else diff --git a/tff_modular/modules/bloodsucker/clans/clan_nosferatu.dm b/tff_modular/modules/bloodsucker/clans/clan_nosferatu.dm index ae04893301c..886396d09b7 100644 --- a/tff_modular/modules/bloodsucker/clans/clan_nosferatu.dm +++ b/tff_modular/modules/bloodsucker/clans/clan_nosferatu.dm @@ -97,3 +97,29 @@ /datum/bloodsucker_clan/nosferatu/favorite_ghoul_loss(datum/antagonist/bloodsucker/source, datum/antagonist/ghoul/ghouldatum) ghouldatum.owner.current.update_sight() + +/datum/bloodsucker_clan/nosferatu/handle_clan_life(datum/antagonist/bloodsucker/source, seconds_per_tick, times_fired) + var/area/nosferatu_loc = get_area(source.owner.current) + if(nosferatu_loc == /area/station/maintenance) + source.owner.current.apply_status_effect(/datum/status_effect/nosferatu_effect) + +/datum/status_effect/nosferatu_effect + id = "nosferatu" + duration = 1.5 SECONDS + status_type = STATUS_EFFECT_REFRESH + alert_type = null + +/datum/status_effect/nosferatu_effect/on_apply() + . = ..() + if(!.) + return FALSE + var/mob/living/carbon/human/nosferatu = owner + nosferatu.add_movespeed_modifier(/datum/movespeed_modifier/nosferatu) + +/datum/status_effect/nosferatu_effect/on_remove() + . = ..() + var/mob/living/carbon/human/nosferatu = owner + nosferatu.remove_movespeed_modifier(/datum/movespeed_modifier/nosferatu) + +/datum/movespeed_modifier/nosferatu + multiplicative_slowdown = -0.1 diff --git a/tff_modular/modules/bloodsucker/powers/feed.dm b/tff_modular/modules/bloodsucker/powers/feed.dm index 6f4e308a72b..d095f130ece 100644 --- a/tff_modular/modules/bloodsucker/powers/feed.dm +++ b/tff_modular/modules/bloodsucker/powers/feed.dm @@ -317,7 +317,7 @@ /datum/action/cooldown/bloodsucker/proc/snobby_drinking_check() if(bloodsuckerdatum_power?.my_clan && bloodsuckerdatum_power.my_clan.blood_drink_type != BLOODSUCKER_DRINK_INHUMANELY) return TRUE - return TRUE + return FALSE /datum/action/cooldown/bloodsucker/feed/proc/find_target() // grabbing or grabbed, you're close enough to bite. diff --git a/tff_modular/modules/bloodsucker/powers/tremere/thaumaturgy.dm b/tff_modular/modules/bloodsucker/powers/tremere/thaumaturgy.dm index 38ab3ca6676..656987b538e 100644 --- a/tff_modular/modules/bloodsucker/powers/tremere/thaumaturgy.dm +++ b/tff_modular/modules/bloodsucker/powers/tremere/thaumaturgy.dm @@ -9,7 +9,8 @@ */ #define BLOOD_SHIELD_BLOCK_CHANCE 50 -#define BLOOD_SHIELD_BLOOD_COST 15 +#define BLOOD_SHIELD_BLOCK_CHANCE_UPGRADED 60 +#define BLOOD_SHIELD_BLOOD_COST 5 #define THAUMATURGY_BLOOD_COST_PER_CHARGE 5 #define THAUMATURGY_COOLDOWN_PER_CHARGE 5 SECONDS @@ -17,6 +18,8 @@ #define THAUMATURGY_DOOR_BREAK_LEVEL 3 #define THAUMATURGY_EXTRA_DAMAGE_LEVEL 4 #define THAUMATURGY_BLOOD_STEAL_LEVEL 5 +#define THAUMATURGY_SHIELD_UPGRADE_LEVEL 6 + /datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy name = "Thaumaturgy" level_current = 1 @@ -28,7 +31,7 @@ bloodcost = 5 constant_bloodcost = 0 // 5 seconds per charge - cooldown_time = 10 SECONDS + cooldown_time = 5 SECONDS prefire_message = "Right click where you wish to fire." click_to_activate = TRUE // you pay to replenish charges power_activates_immediately = FALSE @@ -116,6 +119,8 @@ span_warning("We form our [src]!"), span_hear("You hear liquids forming together."), ) + if(level_current >= THAUMATURGY_SHIELD_UPGRADE_LEVEL) + new_shield.block_chance = BLOOD_SHIELD_BLOCK_CHANCE_UPGRADED /datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy/DeactivatePower(deactivate_flags) . = ..() From da52b341005e303a25c8add0dd061355858ca5e2 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Thu, 12 Mar 2026 20:13:45 +0300 Subject: [PATCH 021/149] =?UTF-8?q?=D0=B8=D0=B7=D0=B2=D0=B8=D0=BD=D0=B8?= =?UTF-8?q?=D1=82=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tff_modular/modules/bloodsucker/clans/clan_nosferatu.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tff_modular/modules/bloodsucker/clans/clan_nosferatu.dm b/tff_modular/modules/bloodsucker/clans/clan_nosferatu.dm index 886396d09b7..7994314beb0 100644 --- a/tff_modular/modules/bloodsucker/clans/clan_nosferatu.dm +++ b/tff_modular/modules/bloodsucker/clans/clan_nosferatu.dm @@ -105,7 +105,7 @@ /datum/status_effect/nosferatu_effect id = "nosferatu" - duration = 1.5 SECONDS + duration = 2 SECONDS status_type = STATUS_EFFECT_REFRESH alert_type = null From 2315b8a4007a028cddcd0c18b33e4052facecd10 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Thu, 12 Mar 2026 20:18:24 +0300 Subject: [PATCH 022/149] =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D1=8F=20=D0=B4=D0=B5?= =?UTF-8?q?=D1=80=D0=B6=D0=B0=D1=82=20=D0=B2=20=D0=B7=D0=B0=D0=BB=D0=BE?= =?UTF-8?q?=D0=B6=D0=BD=D0=B8=D0=BA=D0=B0=D1=85=20=D0=B8=20=D0=B7=D0=B0?= =?UTF-8?q?=D1=81=D1=82=D0=B0=D0=B2=D0=BB=D1=8F=D1=8E=D1=82=20=D0=BA=D0=BE?= =?UTF-8?q?=D0=B4=D0=B8=D1=82=D1=8C=20=D0=BA=D0=B0=D0=BA=D1=83=D1=8E-?= =?UTF-8?q?=D1=82=D0=BE=20=D1=85=D1=83=D0=B9=D0=BD=D1=8E=20=D0=BA=D0=BE?= =?UTF-8?q?=D1=82=D0=BE=D1=80=D0=B0=D1=8F=20=D0=BD=D1=83=D0=B6=D0=BD=D0=B0?= =?UTF-8?q?=20=D0=BF=D0=B0=D1=80=D0=B5=20=D1=87=D0=B5=D0=BB=D0=BE=D0=B2?= =?UTF-8?q?=D0=B5=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tff_modular/modules/bloodsucker/clans/clan_nosferatu.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tff_modular/modules/bloodsucker/clans/clan_nosferatu.dm b/tff_modular/modules/bloodsucker/clans/clan_nosferatu.dm index 7994314beb0..03ed6f8f51b 100644 --- a/tff_modular/modules/bloodsucker/clans/clan_nosferatu.dm +++ b/tff_modular/modules/bloodsucker/clans/clan_nosferatu.dm @@ -99,8 +99,8 @@ ghouldatum.owner.current.update_sight() /datum/bloodsucker_clan/nosferatu/handle_clan_life(datum/antagonist/bloodsucker/source, seconds_per_tick, times_fired) - var/area/nosferatu_loc = get_area(source.owner.current) - if(nosferatu_loc == /area/station/maintenance) + var/area/nosf_area = get_area(source.owner.current) + if(nosf_area && istype(nosf_area, /area/station/maintenance)) source.owner.current.apply_status_effect(/datum/status_effect/nosferatu_effect) /datum/status_effect/nosferatu_effect From e3591bfb8f1d22d4600dc3da17c8a8384e407bb9 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Fri, 13 Mar 2026 10:35:19 +0300 Subject: [PATCH 023/149] =?UTF-8?q?=D0=BE=D1=87=D0=B5=D0=BD=D1=8C=20=D0=B2?= =?UTF-8?q?=D0=B0=D0=B6=D0=BD=D0=BE=D0=B5=20=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B4=D0=BB=D1=8F=20=D0=BF?= =?UTF-8?q?=D0=BE=D0=B4=D0=B4=D0=B5=D1=80=D0=B6=D0=B0=D0=BD=D0=B8=D1=8F=20?= =?UTF-8?q?=D0=BC=D0=BE=D0=B5=D0=B9=20=D0=BF=D1=81=D0=B8=D1=85=D0=B8=D0=BA?= =?UTF-8?q?=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tff_modular/modules/bloodsucker/bloodsuckers/dynamic.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/dynamic.dm b/tff_modular/modules/bloodsucker/bloodsuckers/dynamic.dm index 5326635824e..07df6543303 100644 --- a/tff_modular/modules/bloodsucker/bloodsuckers/dynamic.dm +++ b/tff_modular/modules/bloodsucker/bloodsuckers/dynamic.dm @@ -22,6 +22,7 @@ // MIDROUND BLOODSUCKER // // // ////////////////////////////////////////////// + /datum/dynamic_ruleset/midround/from_living/bloodsucker name = "Vampiric Accident" config_tag = "Midround Bloodsucker" From 07a66fb4ee242b3e001a80d4b45d9a1bd2a3dfcd Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Fri, 13 Mar 2026 16:24:08 +0300 Subject: [PATCH 024/149] =?UTF-8?q?=D0=AF=20=D0=B5=D0=B1=D0=BD=D1=83=D1=82?= =?UTF-8?q?=D1=8B=D0=B9=20=D0=B1=D0=B5=D0=B3=D0=B8=D1=82=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../_globalvars/traits/declarations.dm | 5 - code/__DEFINES/~ff_defines/bloodsucker.dm | 514 ++++---- code/_globalvars/lists/crafting.dm | 1 + code/_onclick/hud/hud.dm | 16 +- code/_onclick/hud/vampire.dm | 196 +++ .../configuration/entries/game_options.dm | 9 + code/controllers/subsystem/polling.dm | 4 +- code/datums/elements/art.dm | 2 + .../greyscale/json_configs/_umbrella.json | 28 + .../json_configs/_umbrella_inhand.json | 31 + code/game/atom/_atom.dm | 3 +- code/game/machinery/computer/crew.dm | 6 + .../devices/scanners/sequence_scanner.dm | 10 +- .../structures/crates_lockers/closets.dm | 12 +- .../antagonists/_common/antag_datum.dm | 21 +- .../antagonists/brainwashing/brainwashing.dm | 37 + code/modules/antagonists/cult/blood_magic.dm | 74 +- .../modules/antagonists/heretic/influences.dm | 6 +- code/modules/client/client_colour.dm | 6 + .../logging/categories/log_category_uplink.dm | 9 + .../modules/mob/living/basic/basic_defense.dm | 2 + .../mob/living/carbon/carbon_defense.dm | 1 + code/modules/mob/living/carbon/examine.dm | 2 - code/modules/mob/living/ventcrawling.dm | 26 +- .../crossbreeding/_status_effects.dm | 4 + code/modules/surgery/organs/organ_movement.dm | 1 - .../bloodsucker/bloodsuckers/assets.dm | 15 - .../bloodsucker/bloodsuckers/bloodsucker.dm | 648 ---------- .../modules/bloodsucker/bloodsuckers/clans.dm | 48 - .../bloodsucker/bloodsuckers/conversion.dm | 97 -- .../bloodsucker/bloodsuckers/crafts.dm | 87 -- .../bloodsucker/bloodsuckers/dynamic.dm | 44 - .../modules/bloodsucker/bloodsuckers/hud.dm | 101 -- .../bloodsucker/bloodsuckers/integration.dm | 120 -- .../modules/bloodsucker/bloodsuckers/life.dm | 491 ------- .../bloodsucker/bloodsuckers/movable_hud.dm | 207 --- .../modules/bloodsucker/bloodsuckers/names.dm | 136 -- .../bloodsucker/bloodsuckers/objectives.dm | 372 ------ .../modules/bloodsucker/bloodsuckers/procs.dm | 381 ------ .../bloodsuckers/shaded_bloodsucker.dm | 5 - .../modules/bloodsucker/bloodsuckers/sol.dm | 121 -- .../bloodsucker/bloodsuckers/species.dm | 84 -- tff_modular/modules/bloodsucker/clans/clan.dm | 341 ----- .../bloodsucker/clans/clan_flavortext.dm | 47 - .../bloodsucker/clans/clan_malkavian.dm | 101 -- .../bloodsucker/clans/clan_nosferatu.dm | 125 -- .../modules/bloodsucker/clans/clan_tremere.dm | 64 - .../modules/bloodsucker/clans/clan_ventrue.dm | 154 --- .../modules/bloodsucker/credit_file.md | 32 - .../modules/bloodsucker/icons/antag_hud.dmi | Bin 1687 -> 0 bytes .../modules/bloodsucker/icons/bloodsucker.dmi | Bin 26432 -> 0 bytes .../icons/bloodsucker_lefthand.dmi | Bin 6531 -> 0 bytes .../icons/bloodsucker_righthand.dmi | Bin 6751 -> 0 bytes .../modules/bloodsucker/icons/language.dmi | Bin 722 -> 0 bytes .../modules/bloodsucker/icons/stakes.dmi | Bin 866 -> 0 bytes .../bloodsucker/icons/tremere_bloodsucker.dmi | Bin 5371 -> 0 bytes .../modules/bloodsucker/icons/vamp_obj.dmi | Bin 10653 -> 0 bytes .../modules/bloodsucker/icons/vamp_obj_64.dmi | Bin 1109 -> 0 bytes .../modules/bloodsucker/powers/_powers.dm | 319 ----- .../modules/bloodsucker/powers/cloak.dm | 86 -- .../modules/bloodsucker/powers/feed.dm | 458 ------- .../modules/bloodsucker/powers/fortitude.dm | 75 -- .../modules/bloodsucker/powers/gohome.dm | 144 --- .../modules/bloodsucker/powers/masquerade.dm | 115 -- .../bloodsucker/powers/prince/scourgify.dm | 125 -- .../powers/targeted/_powers_targeted.dm | 119 -- .../bloodsucker/powers/targeted/brawn.dm | 229 ---- .../bloodsucker/powers/targeted/haste.dm | 120 -- .../bloodsucker/powers/targeted/lunge.dm | 191 --- .../bloodsucker/powers/targeted/mesmerize.dm | 243 ---- .../bloodsucker/powers/targeted/trespass.dm | 109 -- .../powers/tremere/_powers_tremere.dm | 22 - .../bloodsucker/powers/tremere/auspex.dm | 122 -- .../bloodsucker/powers/tremere/dominate.dm | 217 ---- .../bloodsucker/powers/tremere/thaumaturgy.dm | 293 ----- .../bloodsucker/powers/vassal/distress.dm | 24 - .../bloodsucker/powers/vassal/recuperate.dm | 75 -- .../bloodsucker/powers/vassal/vassal_fold.dm | 90 -- .../modules/bloodsucker/powers/veil.dm | 162 --- .../bloodsucker/sound/BloodsuckerAlert.ogg | Bin 218645 -> 0 bytes .../modules/bloodsucker/sound/owl_1.ogg | Bin 4208 -> 0 bytes .../modules/bloodsucker/sound/owl_10.ogg | Bin 7811 -> 0 bytes .../modules/bloodsucker/sound/owl_2.ogg | Bin 4615 -> 0 bytes .../modules/bloodsucker/sound/owl_3.ogg | Bin 5030 -> 0 bytes .../modules/bloodsucker/sound/owl_5.ogg | Bin 5796 -> 0 bytes .../modules/bloodsucker/sound/owl_6.ogg | Bin 6211 -> 0 bytes .../modules/bloodsucker/sound/owl_7.ogg | Bin 6591 -> 0 bytes .../modules/bloodsucker/sound/owl_8.ogg | Bin 7037 -> 0 bytes .../modules/bloodsucker/sound/owl_9.ogg | Bin 7381 -> 0 bytes .../modules/bloodsucker/structures/coffin.dm | 352 ----- .../modules/bloodsucker/structures/crypt.dm | 642 ---------- .../modules/bloodsucker/structures/objects.dm | 358 ------ .../modules/bloodsucker/vassal/batform.dm | 61 - .../bloodsucker/vassal/vassal_datum.dm | 185 --- .../bloodsucker/vassal/vassal_pinpointer.dm | 31 - .../bloodsucker/vassal/vassal_procs.dm | 77 -- .../vassal/vassal_types/ex_vassal.dm | 103 -- .../vassal/vassal_types/favorite_vassal.dm | 28 - .../vassal/vassal_types/revenge_vassal.dm | 68 - tff_modular/modules/vampire/clans/_clan.dm | 234 ++++ .../modules/vampire/clans/assignclan.dm | 43 + tff_modular/modules/vampire/clans/brujah.dm | 16 + tff_modular/modules/vampire/clans/debug.dm | 20 + .../modules/vampire/clans/flavortext_clans.dm | 30 + .../trauma.dm => vampire/clans/malkavian.dm} | 113 +- tff_modular/modules/vampire/clans/toreador.dm | 16 + tff_modular/modules/vampire/clans/tremere.dm | 15 + tff_modular/modules/vampire/clans/ventrue.dm | 17 + tff_modular/modules/vampire/component.dm | 361 ++++++ tff_modular/modules/vampire/config.dm | 5 + .../modules/vampire/conversion_vampire.dm | 63 + tff_modular/modules/vampire/crafts.dm | 153 +++ tff_modular/modules/vampire/datum_vampire.dm | 852 ++++++++++++ tff_modular/modules/vampire/effects.dm | 187 +++ tff_modular/modules/vampire/frenzy_vampire.dm | 115 ++ tff_modular/modules/vampire/icons/64x64.dmi | Bin 0 -> 8774 bytes .../icons/actions_vampire.dmi | Bin .../modules/vampire/icons/antag_hud.dmi | Bin 0 -> 907 bytes .../modules/vampire/icons/bs_leftinhand.dmi | Bin 0 -> 2218 bytes .../modules/vampire/icons/bs_rightinhand.dmi | Bin 0 -> 2188 bytes .../icons/clan_icons.dmi | Bin .../icons/disciplines.dmi | Bin tff_modular/modules/vampire/icons/feed.dmi | Bin 0 -> 1288 bytes tff_modular/modules/vampire/icons/hud.dmi | Bin 0 -> 17150 bytes .../icons/phobetor_tear.dmi | Bin tff_modular/modules/vampire/icons/stakes.dmi | Bin 0 -> 535 bytes .../modules/vampire/icons/umbrellas.dmi | Bin 0 -> 1891 bytes .../vampire/icons/umbrellas_inhand_lh.dmi | Bin 0 -> 4764 bytes .../vampire/icons/umbrellas_inhand_rh.dmi | Bin 0 -> 4836 bytes .../modules/vampire/icons/vamp_obj.dmi | Bin 0 -> 5718 bytes .../modules/vampire/icons/vamp_obj_64.dmi | Bin 0 -> 1077 bytes .../vampire/icons/vampire_bloodboil.dmi | Bin 0 -> 394 bytes .../vampire/icons/vampire_bloodbolt.dmi | Bin 0 -> 363 bytes .../vampire/icons/vampire_blooddrain.dmi | Bin 0 -> 466 bytes .../modules/vampire/icons/vampire_command.dmi | Bin 0 -> 356 bytes .../vampire/icons/vampire_entrance.dmi | Bin 0 -> 542 bytes .../modules/vampire/icons/vampire_feed.dmi | Bin 0 -> 400 bytes .../modules/vampire/icons/vampire_lunge.dmi | Bin 0 -> 363 bytes .../vampire/icons/vampire_mesmerize.dmi | Bin 0 -> 495 bytes .../vampire/icons/vampire_strength.dmi | Bin 0 -> 436 bytes .../modules/vampire/icons/vampire_summon.dmi | Bin 0 -> 336 bytes .../vampire/icons/vampire_trespass.dmi | Bin 0 -> 437 bytes .../icons/vampiric.dmi | Bin tff_modular/modules/vampire/icons/worn.dmi | Bin 0 -> 841 bytes tff_modular/modules/vampire/language.dm | 21 + .../modules/vampire/leveling_vampire.dm | 25 + tff_modular/modules/vampire/life_vampire.dm | 318 +++++ .../modules/vampire/misc_procs_vampire.dm | 571 +++++++++ tff_modular/modules/vampire/monitor.dm | 820 ++++++++++++ .../modules/vampire/moodlets_vampire.dm | 35 + tff_modular/modules/vampire/names_vampire.dm | 42 + .../modules/vampire/objectives_vampire.dm | 182 +++ .../vampire/objects/_vampire_object.dm | 92 ++ .../modules/vampire/objects/blood_drinking.dm | 39 + .../modules/vampire/objects/blood_throne.dm | 112 ++ .../modules/vampire/objects/candelabrum.dm | 159 +++ tff_modular/modules/vampire/objects/coffin.dm | 250 ++++ .../modules/vampire/objects/hunter_gear.dm | 188 +++ .../modules/vampire/objects/kindred.dm | 97 ++ .../modules/vampire/objects/umbrellas.dm | 167 +++ .../modules/vampire/objects/vassal_rack.dm | 271 ++++ .../modules/vampire/oozeling_vampire.dm | 91 ++ tff_modular/modules/vampire/powers/_power.dm | 244 ++++ .../modules/vampire/powers/_targeted.dm | 111 ++ .../vampire/powers/auspex/astral_project.dm | 25 + .../modules/vampire/powers/auspex/auspex.dm | 143 +++ .../vampire/powers/celerity/celerity.dm | 11 + .../modules/vampire/powers/celerity/haste.dm | 102 ++ .../vampire/powers/celerity/quickness.dm | 54 + .../modules/vampire/powers/disciplines.dm | 75 ++ .../vampire/powers/dominate/command.dm | 250 ++++ .../vampire/powers/dominate/dominate.dm | 15 + .../vampire/powers/dominate/mesmerize.dm | 214 ++++ tff_modular/modules/vampire/powers/feed.dm | 617 +++++++++ .../vampire/powers/fortitude/fortitude.dm | 118 ++ tff_modular/modules/vampire/powers/gohome.dm | 101 ++ .../modules/vampire/powers/levelspells.dm | 181 +++ .../modules/vampire/powers/masquerade.dm | 79 ++ .../modules/vampire/powers/obfuscate/cloak.dm | 70 + .../vampire/powers/obfuscate/obfuscate.dm | 11 + .../vampire/powers/obfuscate/trespass.dm | 107 ++ .../modules/vampire/powers/obfuscate/veil.dm | 76 ++ .../modules/vampire/powers/potence/brash.dm | 170 +++ .../modules/vampire/powers/potence/brawn.dm | 235 ++++ .../modules/vampire/powers/potence/lunge.dm | 178 +++ .../modules/vampire/powers/potence/potence.dm | 25 + .../modules/vampire/powers/presence/awe.dm | 118 ++ .../vampire/powers/presence/entrance.dm | 115 ++ .../powers/presence/force_of_personality.dm | 101 ++ .../vampire/powers/presence/presence.dm | 9 + .../modules/vampire/powers/presence/summon.dm | 182 +++ .../vampire/powers/thaumaturgy/bloodboil.dm | 130 ++ .../vampire/powers/thaumaturgy/bloodbolt.dm | 73 ++ .../vampire/powers/thaumaturgy/blooddrain.dm | 147 +++ .../vampire/powers/thaumaturgy/bloodshield.dm | 69 + .../vampire/powers/thaumaturgy/thaumaturgy.dm | 11 + .../controllers.dm => vampire/society.dm} | 165 +-- .../modules/vampire/sound/VampireAlert.ogg | Bin 0 -> 213040 bytes .../{bloodsucker => vampire}/sound/auspex.ogg | Bin .../{bloodsucker => vampire}/sound/awo1.ogg | Bin .../sound/bloodbolt.ogg | Bin .../sound/bloodbolt_fire.ogg | Bin .../sound/bloodhealing.ogg | Bin .../sound/bloodneed.ogg | Bin .../sound/burning_death.ogg | Bin .../sound/coffin_close.ogg | Bin .../sound/coffin_open.ogg | Bin .../modules/vampire/sound/door_locked.ogg | Bin 0 -> 7800 bytes .../sound/drinkblood1.ogg | Bin .../sound/fortitude_off.ogg | Bin .../sound/fortitude_on.ogg | Bin .../sound/griffin_1.ogg | Bin .../sound/griffin_10.ogg | Bin .../sound/griffin_2.ogg | Bin .../sound/griffin_3.ogg | Bin .../sound/griffin_4.ogg | Bin .../sound/griffin_5.ogg | Bin .../sound/griffin_6.ogg | Bin .../sound/griffin_7.ogg | Bin .../sound/griffin_8.ogg | Bin .../sound/griffin_9.ogg | Bin .../{bloodsucker => vampire}/sound/growl.ogg | Bin .../sound/humanity_gain.ogg | Bin .../sound/humanity_loss.ogg | Bin .../sound/lunge_warn.ogg | Bin .../sound/masquerade_violation.ogg | Bin .../sound/mesmerize.ogg | Bin .../{bloodsucker => vampire}/sound/prince.ogg | Bin .../sound/rage_decrease.ogg | Bin .../sound/rage_increase.ogg | Bin .../sound/scourge_offer.ogg | Bin .../sound/scourge_recruit.ogg | Bin .../sound/wolf_ask.ogg | Bin .../sound/wolf_speak.ogg | Bin .../modules/vampire/sound/wooden_drop.ogg | Bin 0 -> 9887 bytes .../modules/vampire/sound/wooden_pickup.ogg | Bin 0 -> 18201 bytes tff_modular/modules/vampire/status_effects.dm | 2 + tff_modular/modules/vampire/torpor_vampire.dm | 103 ++ .../modules/vampire/tracking_vampire.dm | 34 + .../modules/vampire/vassals/datum_vassal.dm | 240 ++++ .../vampire/vassals/powers/distress.dm | 21 + .../vampire/vassals/powers/recuperate.dm | 79 ++ tgstation.dme | 130 +- .../tgui-panel/styles/tgchat/chat-dark.scss | 14 + .../tgui-panel/styles/tgchat/chat-light.scss | 14 + .../tgui/interfaces/AntagInfoBloodsucker.tsx | 229 ---- .../tgui/interfaces/AntagInfoGhoul.tsx | 57 - .../tgui/interfaces/AntagInfoVampire.tsx | 1137 +++++++++++++++++ tgui/packages/tgui/interfaces/KindredBook.tsx | 13 +- .../{bloodsucker.ts => vampire.ts} | 9 +- ...oundbloodsucker.ts => vampiricaccident.ts} | 12 +- 251 files changed, 12387 insertions(+), 9849 deletions(-) create mode 100644 code/_onclick/hud/vampire.dm create mode 100644 code/datums/greyscale/json_configs/_umbrella.json create mode 100644 code/datums/greyscale/json_configs/_umbrella_inhand.json delete mode 100644 tff_modular/modules/bloodsucker/bloodsuckers/assets.dm delete mode 100644 tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm delete mode 100644 tff_modular/modules/bloodsucker/bloodsuckers/clans.dm delete mode 100644 tff_modular/modules/bloodsucker/bloodsuckers/conversion.dm delete mode 100644 tff_modular/modules/bloodsucker/bloodsuckers/crafts.dm delete mode 100644 tff_modular/modules/bloodsucker/bloodsuckers/dynamic.dm delete mode 100644 tff_modular/modules/bloodsucker/bloodsuckers/hud.dm delete mode 100644 tff_modular/modules/bloodsucker/bloodsuckers/integration.dm delete mode 100644 tff_modular/modules/bloodsucker/bloodsuckers/life.dm delete mode 100644 tff_modular/modules/bloodsucker/bloodsuckers/movable_hud.dm delete mode 100644 tff_modular/modules/bloodsucker/bloodsuckers/names.dm delete mode 100644 tff_modular/modules/bloodsucker/bloodsuckers/objectives.dm delete mode 100644 tff_modular/modules/bloodsucker/bloodsuckers/procs.dm delete mode 100644 tff_modular/modules/bloodsucker/bloodsuckers/shaded_bloodsucker.dm delete mode 100644 tff_modular/modules/bloodsucker/bloodsuckers/sol.dm delete mode 100644 tff_modular/modules/bloodsucker/bloodsuckers/species.dm delete mode 100644 tff_modular/modules/bloodsucker/clans/clan.dm delete mode 100644 tff_modular/modules/bloodsucker/clans/clan_flavortext.dm delete mode 100644 tff_modular/modules/bloodsucker/clans/clan_malkavian.dm delete mode 100644 tff_modular/modules/bloodsucker/clans/clan_nosferatu.dm delete mode 100644 tff_modular/modules/bloodsucker/clans/clan_tremere.dm delete mode 100644 tff_modular/modules/bloodsucker/clans/clan_ventrue.dm delete mode 100644 tff_modular/modules/bloodsucker/credit_file.md delete mode 100644 tff_modular/modules/bloodsucker/icons/antag_hud.dmi delete mode 100644 tff_modular/modules/bloodsucker/icons/bloodsucker.dmi delete mode 100644 tff_modular/modules/bloodsucker/icons/bloodsucker_lefthand.dmi delete mode 100644 tff_modular/modules/bloodsucker/icons/bloodsucker_righthand.dmi delete mode 100644 tff_modular/modules/bloodsucker/icons/language.dmi delete mode 100644 tff_modular/modules/bloodsucker/icons/stakes.dmi delete mode 100644 tff_modular/modules/bloodsucker/icons/tremere_bloodsucker.dmi delete mode 100644 tff_modular/modules/bloodsucker/icons/vamp_obj.dmi delete mode 100644 tff_modular/modules/bloodsucker/icons/vamp_obj_64.dmi delete mode 100644 tff_modular/modules/bloodsucker/powers/_powers.dm delete mode 100644 tff_modular/modules/bloodsucker/powers/cloak.dm delete mode 100644 tff_modular/modules/bloodsucker/powers/feed.dm delete mode 100644 tff_modular/modules/bloodsucker/powers/fortitude.dm delete mode 100644 tff_modular/modules/bloodsucker/powers/gohome.dm delete mode 100644 tff_modular/modules/bloodsucker/powers/masquerade.dm delete mode 100644 tff_modular/modules/bloodsucker/powers/prince/scourgify.dm delete mode 100644 tff_modular/modules/bloodsucker/powers/targeted/_powers_targeted.dm delete mode 100644 tff_modular/modules/bloodsucker/powers/targeted/brawn.dm delete mode 100644 tff_modular/modules/bloodsucker/powers/targeted/haste.dm delete mode 100644 tff_modular/modules/bloodsucker/powers/targeted/lunge.dm delete mode 100644 tff_modular/modules/bloodsucker/powers/targeted/mesmerize.dm delete mode 100644 tff_modular/modules/bloodsucker/powers/targeted/trespass.dm delete mode 100644 tff_modular/modules/bloodsucker/powers/tremere/_powers_tremere.dm delete mode 100644 tff_modular/modules/bloodsucker/powers/tremere/auspex.dm delete mode 100644 tff_modular/modules/bloodsucker/powers/tremere/dominate.dm delete mode 100644 tff_modular/modules/bloodsucker/powers/tremere/thaumaturgy.dm delete mode 100644 tff_modular/modules/bloodsucker/powers/vassal/distress.dm delete mode 100644 tff_modular/modules/bloodsucker/powers/vassal/recuperate.dm delete mode 100644 tff_modular/modules/bloodsucker/powers/vassal/vassal_fold.dm delete mode 100644 tff_modular/modules/bloodsucker/powers/veil.dm delete mode 100644 tff_modular/modules/bloodsucker/sound/BloodsuckerAlert.ogg delete mode 100644 tff_modular/modules/bloodsucker/sound/owl_1.ogg delete mode 100644 tff_modular/modules/bloodsucker/sound/owl_10.ogg delete mode 100644 tff_modular/modules/bloodsucker/sound/owl_2.ogg delete mode 100644 tff_modular/modules/bloodsucker/sound/owl_3.ogg delete mode 100644 tff_modular/modules/bloodsucker/sound/owl_5.ogg delete mode 100644 tff_modular/modules/bloodsucker/sound/owl_6.ogg delete mode 100644 tff_modular/modules/bloodsucker/sound/owl_7.ogg delete mode 100644 tff_modular/modules/bloodsucker/sound/owl_8.ogg delete mode 100644 tff_modular/modules/bloodsucker/sound/owl_9.ogg delete mode 100644 tff_modular/modules/bloodsucker/structures/coffin.dm delete mode 100644 tff_modular/modules/bloodsucker/structures/crypt.dm delete mode 100644 tff_modular/modules/bloodsucker/structures/objects.dm delete mode 100644 tff_modular/modules/bloodsucker/vassal/batform.dm delete mode 100644 tff_modular/modules/bloodsucker/vassal/vassal_datum.dm delete mode 100644 tff_modular/modules/bloodsucker/vassal/vassal_pinpointer.dm delete mode 100644 tff_modular/modules/bloodsucker/vassal/vassal_procs.dm delete mode 100644 tff_modular/modules/bloodsucker/vassal/vassal_types/ex_vassal.dm delete mode 100644 tff_modular/modules/bloodsucker/vassal/vassal_types/favorite_vassal.dm delete mode 100644 tff_modular/modules/bloodsucker/vassal/vassal_types/revenge_vassal.dm create mode 100644 tff_modular/modules/vampire/clans/_clan.dm create mode 100644 tff_modular/modules/vampire/clans/assignclan.dm create mode 100644 tff_modular/modules/vampire/clans/brujah.dm create mode 100644 tff_modular/modules/vampire/clans/debug.dm create mode 100644 tff_modular/modules/vampire/clans/flavortext_clans.dm rename tff_modular/modules/{bloodsucker/bloodsuckers/trauma.dm => vampire/clans/malkavian.dm} (51%) create mode 100644 tff_modular/modules/vampire/clans/toreador.dm create mode 100644 tff_modular/modules/vampire/clans/tremere.dm create mode 100644 tff_modular/modules/vampire/clans/ventrue.dm create mode 100644 tff_modular/modules/vampire/component.dm create mode 100644 tff_modular/modules/vampire/config.dm create mode 100644 tff_modular/modules/vampire/conversion_vampire.dm create mode 100644 tff_modular/modules/vampire/crafts.dm create mode 100644 tff_modular/modules/vampire/datum_vampire.dm create mode 100644 tff_modular/modules/vampire/effects.dm create mode 100644 tff_modular/modules/vampire/frenzy_vampire.dm create mode 100644 tff_modular/modules/vampire/icons/64x64.dmi rename tff_modular/modules/{bloodsucker => vampire}/icons/actions_vampire.dmi (100%) create mode 100644 tff_modular/modules/vampire/icons/antag_hud.dmi create mode 100644 tff_modular/modules/vampire/icons/bs_leftinhand.dmi create mode 100644 tff_modular/modules/vampire/icons/bs_rightinhand.dmi rename tff_modular/modules/{bloodsucker => vampire}/icons/clan_icons.dmi (100%) rename tff_modular/modules/{bloodsucker => vampire}/icons/disciplines.dmi (100%) create mode 100644 tff_modular/modules/vampire/icons/feed.dmi create mode 100644 tff_modular/modules/vampire/icons/hud.dmi rename tff_modular/modules/{bloodsucker => vampire}/icons/phobetor_tear.dmi (100%) create mode 100644 tff_modular/modules/vampire/icons/stakes.dmi create mode 100644 tff_modular/modules/vampire/icons/umbrellas.dmi create mode 100644 tff_modular/modules/vampire/icons/umbrellas_inhand_lh.dmi create mode 100644 tff_modular/modules/vampire/icons/umbrellas_inhand_rh.dmi create mode 100644 tff_modular/modules/vampire/icons/vamp_obj.dmi create mode 100644 tff_modular/modules/vampire/icons/vamp_obj_64.dmi create mode 100644 tff_modular/modules/vampire/icons/vampire_bloodboil.dmi create mode 100644 tff_modular/modules/vampire/icons/vampire_bloodbolt.dmi create mode 100644 tff_modular/modules/vampire/icons/vampire_blooddrain.dmi create mode 100644 tff_modular/modules/vampire/icons/vampire_command.dmi create mode 100644 tff_modular/modules/vampire/icons/vampire_entrance.dmi create mode 100644 tff_modular/modules/vampire/icons/vampire_feed.dmi create mode 100644 tff_modular/modules/vampire/icons/vampire_lunge.dmi create mode 100644 tff_modular/modules/vampire/icons/vampire_mesmerize.dmi create mode 100644 tff_modular/modules/vampire/icons/vampire_strength.dmi create mode 100644 tff_modular/modules/vampire/icons/vampire_summon.dmi create mode 100644 tff_modular/modules/vampire/icons/vampire_trespass.dmi rename tff_modular/modules/{bloodsucker => vampire}/icons/vampiric.dmi (100%) create mode 100644 tff_modular/modules/vampire/icons/worn.dmi create mode 100644 tff_modular/modules/vampire/language.dm create mode 100644 tff_modular/modules/vampire/leveling_vampire.dm create mode 100644 tff_modular/modules/vampire/life_vampire.dm create mode 100644 tff_modular/modules/vampire/misc_procs_vampire.dm create mode 100644 tff_modular/modules/vampire/monitor.dm create mode 100644 tff_modular/modules/vampire/moodlets_vampire.dm create mode 100644 tff_modular/modules/vampire/names_vampire.dm create mode 100644 tff_modular/modules/vampire/objectives_vampire.dm create mode 100644 tff_modular/modules/vampire/objects/_vampire_object.dm create mode 100644 tff_modular/modules/vampire/objects/blood_drinking.dm create mode 100644 tff_modular/modules/vampire/objects/blood_throne.dm create mode 100644 tff_modular/modules/vampire/objects/candelabrum.dm create mode 100644 tff_modular/modules/vampire/objects/coffin.dm create mode 100644 tff_modular/modules/vampire/objects/hunter_gear.dm create mode 100644 tff_modular/modules/vampire/objects/kindred.dm create mode 100644 tff_modular/modules/vampire/objects/umbrellas.dm create mode 100644 tff_modular/modules/vampire/objects/vassal_rack.dm create mode 100644 tff_modular/modules/vampire/oozeling_vampire.dm create mode 100644 tff_modular/modules/vampire/powers/_power.dm create mode 100644 tff_modular/modules/vampire/powers/_targeted.dm create mode 100644 tff_modular/modules/vampire/powers/auspex/astral_project.dm create mode 100644 tff_modular/modules/vampire/powers/auspex/auspex.dm create mode 100644 tff_modular/modules/vampire/powers/celerity/celerity.dm create mode 100644 tff_modular/modules/vampire/powers/celerity/haste.dm create mode 100644 tff_modular/modules/vampire/powers/celerity/quickness.dm create mode 100644 tff_modular/modules/vampire/powers/disciplines.dm create mode 100644 tff_modular/modules/vampire/powers/dominate/command.dm create mode 100644 tff_modular/modules/vampire/powers/dominate/dominate.dm create mode 100644 tff_modular/modules/vampire/powers/dominate/mesmerize.dm create mode 100644 tff_modular/modules/vampire/powers/feed.dm create mode 100644 tff_modular/modules/vampire/powers/fortitude/fortitude.dm create mode 100644 tff_modular/modules/vampire/powers/gohome.dm create mode 100644 tff_modular/modules/vampire/powers/levelspells.dm create mode 100644 tff_modular/modules/vampire/powers/masquerade.dm create mode 100644 tff_modular/modules/vampire/powers/obfuscate/cloak.dm create mode 100644 tff_modular/modules/vampire/powers/obfuscate/obfuscate.dm create mode 100644 tff_modular/modules/vampire/powers/obfuscate/trespass.dm create mode 100644 tff_modular/modules/vampire/powers/obfuscate/veil.dm create mode 100644 tff_modular/modules/vampire/powers/potence/brash.dm create mode 100644 tff_modular/modules/vampire/powers/potence/brawn.dm create mode 100644 tff_modular/modules/vampire/powers/potence/lunge.dm create mode 100644 tff_modular/modules/vampire/powers/potence/potence.dm create mode 100644 tff_modular/modules/vampire/powers/presence/awe.dm create mode 100644 tff_modular/modules/vampire/powers/presence/entrance.dm create mode 100644 tff_modular/modules/vampire/powers/presence/force_of_personality.dm create mode 100644 tff_modular/modules/vampire/powers/presence/presence.dm create mode 100644 tff_modular/modules/vampire/powers/presence/summon.dm create mode 100644 tff_modular/modules/vampire/powers/thaumaturgy/bloodboil.dm create mode 100644 tff_modular/modules/vampire/powers/thaumaturgy/bloodbolt.dm create mode 100644 tff_modular/modules/vampire/powers/thaumaturgy/blooddrain.dm create mode 100644 tff_modular/modules/vampire/powers/thaumaturgy/bloodshield.dm create mode 100644 tff_modular/modules/vampire/powers/thaumaturgy/thaumaturgy.dm rename tff_modular/modules/{bloodsucker/controllers.dm => vampire/society.dm} (56%) create mode 100644 tff_modular/modules/vampire/sound/VampireAlert.ogg rename tff_modular/modules/{bloodsucker => vampire}/sound/auspex.ogg (100%) rename tff_modular/modules/{bloodsucker => vampire}/sound/awo1.ogg (100%) rename tff_modular/modules/{bloodsucker => vampire}/sound/bloodbolt.ogg (100%) rename tff_modular/modules/{bloodsucker => vampire}/sound/bloodbolt_fire.ogg (100%) rename tff_modular/modules/{bloodsucker => vampire}/sound/bloodhealing.ogg (100%) rename tff_modular/modules/{bloodsucker => vampire}/sound/bloodneed.ogg (100%) rename tff_modular/modules/{bloodsucker => vampire}/sound/burning_death.ogg (100%) rename tff_modular/modules/{bloodsucker => vampire}/sound/coffin_close.ogg (100%) rename tff_modular/modules/{bloodsucker => vampire}/sound/coffin_open.ogg (100%) create mode 100644 tff_modular/modules/vampire/sound/door_locked.ogg rename tff_modular/modules/{bloodsucker => vampire}/sound/drinkblood1.ogg (100%) rename tff_modular/modules/{bloodsucker => vampire}/sound/fortitude_off.ogg (100%) rename tff_modular/modules/{bloodsucker => vampire}/sound/fortitude_on.ogg (100%) rename tff_modular/modules/{bloodsucker => vampire}/sound/griffin_1.ogg (100%) rename tff_modular/modules/{bloodsucker => vampire}/sound/griffin_10.ogg (100%) rename tff_modular/modules/{bloodsucker => vampire}/sound/griffin_2.ogg (100%) rename tff_modular/modules/{bloodsucker => vampire}/sound/griffin_3.ogg (100%) rename tff_modular/modules/{bloodsucker => vampire}/sound/griffin_4.ogg (100%) rename tff_modular/modules/{bloodsucker => vampire}/sound/griffin_5.ogg (100%) rename tff_modular/modules/{bloodsucker => vampire}/sound/griffin_6.ogg (100%) rename tff_modular/modules/{bloodsucker => vampire}/sound/griffin_7.ogg (100%) rename tff_modular/modules/{bloodsucker => vampire}/sound/griffin_8.ogg (100%) rename tff_modular/modules/{bloodsucker => vampire}/sound/griffin_9.ogg (100%) rename tff_modular/modules/{bloodsucker => vampire}/sound/growl.ogg (100%) rename tff_modular/modules/{bloodsucker => vampire}/sound/humanity_gain.ogg (100%) rename tff_modular/modules/{bloodsucker => vampire}/sound/humanity_loss.ogg (100%) rename tff_modular/modules/{bloodsucker => vampire}/sound/lunge_warn.ogg (100%) rename tff_modular/modules/{bloodsucker => vampire}/sound/masquerade_violation.ogg (100%) rename tff_modular/modules/{bloodsucker => vampire}/sound/mesmerize.ogg (100%) rename tff_modular/modules/{bloodsucker => vampire}/sound/prince.ogg (100%) rename tff_modular/modules/{bloodsucker => vampire}/sound/rage_decrease.ogg (100%) rename tff_modular/modules/{bloodsucker => vampire}/sound/rage_increase.ogg (100%) rename tff_modular/modules/{bloodsucker => vampire}/sound/scourge_offer.ogg (100%) rename tff_modular/modules/{bloodsucker => vampire}/sound/scourge_recruit.ogg (100%) rename tff_modular/modules/{bloodsucker => vampire}/sound/wolf_ask.ogg (100%) rename tff_modular/modules/{bloodsucker => vampire}/sound/wolf_speak.ogg (100%) create mode 100644 tff_modular/modules/vampire/sound/wooden_drop.ogg create mode 100644 tff_modular/modules/vampire/sound/wooden_pickup.ogg create mode 100644 tff_modular/modules/vampire/status_effects.dm create mode 100644 tff_modular/modules/vampire/torpor_vampire.dm create mode 100644 tff_modular/modules/vampire/tracking_vampire.dm create mode 100644 tff_modular/modules/vampire/vassals/datum_vassal.dm create mode 100644 tff_modular/modules/vampire/vassals/powers/distress.dm create mode 100644 tff_modular/modules/vampire/vassals/powers/recuperate.dm delete mode 100644 tgui/packages/tgui/interfaces/AntagInfoBloodsucker.tsx delete mode 100644 tgui/packages/tgui/interfaces/AntagInfoGhoul.tsx create mode 100644 tgui/packages/tgui/interfaces/AntagInfoVampire.tsx rename tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/{bloodsucker.ts => vampire.ts} (71%) rename tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/{midroundbloodsucker.ts => vampiricaccident.ts} (63%) diff --git a/code/__DEFINES/~ff_defines/_globalvars/traits/declarations.dm b/code/__DEFINES/~ff_defines/_globalvars/traits/declarations.dm index b34af8f4b10..656a681350c 100644 --- a/code/__DEFINES/~ff_defines/_globalvars/traits/declarations.dm +++ b/code/__DEFINES/~ff_defines/_globalvars/traits/declarations.dm @@ -5,8 +5,3 @@ /// Determines if something can receive healing from a xeno #define TRAIT_XENO_HEAL_AURA "trait_xeno_heal_aura" -#define GHOUL_SCAN_MIN_DISTANCE 5 -#define GHOUL_SCAN_MAX_DISTANCE 500 -/// 2s update time. -#define GHOUL_SCAN_PING_TIME 20 -#define TRAIT_TORPOR "torpor" diff --git a/code/__DEFINES/~ff_defines/bloodsucker.dm b/code/__DEFINES/~ff_defines/bloodsucker.dm index 3bc69f93438..456a04fd98e 100644 --- a/code/__DEFINES/~ff_defines/bloodsucker.dm +++ b/code/__DEFINES/~ff_defines/bloodsucker.dm @@ -1,98 +1,119 @@ -///Uncomment this to enable testing of Bloodsucker features (such as ghoulizing people with a mind instead of a client). -// #define BLOODSUCKER_TESTING // if this isn't commented out, someone is a dumbfuck - -//Torpor softlock prevention - define it high as it is a failsafe -#define BLOODSUCKER_TORPOR_MAX_TIME (120 SECONDS) -/// You have special interactions with Bloodsuckers -#define TRAIT_BLOODSUCKER_HUNTER "bloodsucker_hunter" - -#define ROLE_BLOODSUCKER "Bloodsucker" -#define ROLE_VAMPIRICACCIDENT "Bloodsucker (Midround)" -#define ROLE_BLOODSUCKERBREAKOUT "Bloodsucker (Latejoin)" -#define ROLE_VASSAL "Vassal" - -///The mob is some kind of vampire, species or antag -#define MOB_VAMPIRIC (1 << 16) - -// how much to multiply the coffin size by mob_size -#define COFFIN_ENLARGE_MULT 0.5 - -/// At what health to burn damage ratio you Final Death -#define FINAL_DEATH_HEALTH_TO_BURN 2.5 -/** - * Blood-level defines - */ -/// Determines Bloodsucker regeneration rate +/// From base of /mob/living/simple_animal/attack_hand() and /mob/living/basic/attack_hand() when petting (non-combat): (mob/living/pet) +#define COMSIG_LIVING_PET_ANIMAL "living_pet_animal" +/// From base of carbon_defense.dm when hugging: (mob/living/carbon/hugged) +#define COMSIG_LIVING_HUG_CARBON "living_hug_carbon" +/// From base of /datum/element/art when appraising art: (atom/art_piece) +#define COMSIG_LIVING_APPRAISE_ART "living_appraise_art" +/// Source trait while Feeding +#define FEED_TRAIT "feed_trait" +/// Hides TRAIT_GENELESS if it's only from the same sources as TRAIT_FAKEGENES. +#define TRAIT_FAKEGENES "fakegenes" +/// You have special interactions with vampires and the occult. +#define TRAIT_OCCULTIST "occultist" +/// The user is "vampire aligned" - i.e a vampire or vassal. +/// Basically just check for `HAS_MIND_TRAIT(user, TRAIT_VAMPIRE_ALIGNED)` instead of `IS_VAMPIRE(user) || IS_VASSAL(user)` +#define TRAIT_VAMPIRE_ALIGNED "vampire_aligned" +#define DOAFTER_SOURCE_PERSUASION_RACK "doafter_persuasion_rack" +/// Checks if the given mob is a vampire +#define IS_VAMPIRE(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/vampire)) +/// Checks if the given mob is a vassal +#define IS_VASSAL(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/vassal)) +#define CAT_VAMPIRE "Vampire" +#define DOAFTER_SOURCE_ARCHIVE_OF_THE_KINDRED "doafter_archive_of_the_kindred" +#define DOAFTER_SOURCE_PERSUASION_RACK "doafter_persuasion_rack" +/// This area can always be claimed as a vampire lair regardless of Z-level and such +#define ALWAYS_VALID_VAMPIRE_LAIR (1<<21) +#define LOG_CATEGORY_UPLINK_VAMPIRE "uplink-vampire" +#define FACTION_VAMPIRE "Vampire" +#define ROLE_VAMPIRE "Vampire" +#define ROLE_VAMPIRIC_ACCIDENT "Vampiric Accident" +#define span_awe(str) ("" + str + "") +/// Uncomment this to enable testing of Vampire features (such as vassalizing people with a mind instead of a client). +//#define VAMPIRE_TESTING +#if defined(VAMPIRE_TESTING) && defined(CIBUILDING) + #error VAMPIRE_TESTING is enabled, disable this! +#endif +#ifdef TESTING + #define VAMPIRE_TESTING +#endif + +// Blood-level defines +/// Determines Vampire regeneration rate #define BS_BLOOD_VOLUME_MAX_REGEN 700 /// Cost to torture someone halfway, in blood. Called twice for full cost -#define TORTURE_BLOOD_HALF_COST 4 +#define TORTURE_BLOOD_HALF_COST 8 /// Cost to convert someone after successful torture, in blood -#define TORTURE_CONVERSION_COST 10 -/// How much blood it costs you to make a ghoul into a special ghoul -#define SPECIAL_GHOUL_COST 150 -/// Minimum and maximum frenzy blood thresholds -/// Once blood is this low, will enter Frenzy +#define TORTURE_CONVERSION_COST 50 +/// Once blood is this low, will enter a Frenzy #define FRENZY_THRESHOLD_ENTER 25 -/// Once blood is this high, will exit Frenzy -#define FRENZY_THRESHOLD_EXIT 250 - -/// a bloodsucker can't loose more humanity than this, and looses the masquerade ability when reaching it -#define HUMANITY_LOST_MAXIMUM 50 - -/// Level up blood cost define, max_blood * this = blood cost -#define BLOODSUCKER_LEVELUP_PERCENTAGE 0.40 -#define BLOODSUCKER_LEVELUP_PERCENTAGE_VENTRUE BLOODSUCKER_LEVELUP_PERCENTAGE - 0.1 - -///The level when at a bloodsucker becomes snobby about who they drink from and gain their non-fledling reputation -#define BLOODSUCKER_HIGH_LEVEL 4 - -/** - * Sol defines - */ -///How long Sol will last until it's night again. -#define TIME_BLOODSUCKER_DAY 60 -///Base time nighttime should be in for, until Sol rises. -// Can't put defines in defines, so we have to use deciseconds. -#define TIME_BLOODSUCKER_NIGHT_MAX 1320 // 22 minutes -#define TIME_BLOODSUCKER_NIGHT_MIN 1020 // 17 minutes - -///Time left to send an alert to Bloodsuckers about an incoming Sol. -#define TIME_BLOODSUCKER_DAY_WARN 90 -///Time left to send an urgent alert to Bloodsuckers about an incoming Sol. -#define TIME_BLOODSUCKER_DAY_FINAL_WARN 30 -///Time left to alert that Sol is rising. -#define TIME_BLOODSUCKER_BURN_INTERVAL 5 - -///How much time Sol can be 'off' by, keeping the time inconsistent. -#define TIME_BLOODSUCKER_SOL_DELAY 90 - -/** - * Ghoul defines - */ -///If someone passes all checks and can be ghouled -#define GHOULING_ALLOWED 0 -///If someone has to accept ghouling -#define GHOULING_DISLOYAL 1 -///If someone is not allowed under any circimstances to become a Ghoul -#define GHOULING_BANNED 2 - -/** - * Cooldown defines - * Used in Cooldowns Bloodsuckers use to prevent spamming - */ -///Spam prevention for healing messages. -#define BLOODSUCKER_SPAM_HEALING (15 SECONDS) -///Span prevention for Sol Masquerade messages. -#define BLOODSUCKER_SPAM_MASQUERADE (60 SECONDS) - -///Span prevention for Sol messages. -#define BLOODSUCKER_SPAM_SOL (30 SECONDS) - - -/** - * Clan defines - */ -#define CLAN_NONE "Caitiff" +/// Once blood is this high, will exit the Frenzy. Intentionally high, we want to kill the person we feed off of +#define FRENZY_THRESHOLD_EXIT 500 +/// How much blood drained from the vampire each lifetick +#define VAMPIRE_PASSIVE_BLOOD_DRAIN 0.1 +/// The number that incoming levels are divided by when comitting the Amaranth. Example: 2 would divide the victims level by 2, and give that to the diablerist +#define DIABLERIE_DIVISOR 1.5 +/// Amount of vitae drunk from another player required to level up. +#define VITAE_GOAL_STANDARD 250 + +/// Default amount of damage the vampire's punch/kick damage increases with each level. +#define VAMPIRE_UNARMED_DMG_INCREASE_ON_RANKUP 0.5 + +/// How many starting levels do we want each one to have? +#define VAMPIRE_STARTING_LEVELS 3 +/// How many free levels the vampire gets gradually. +#define VAMPIRE_FREE_LEVELS 3 +/// Vampire's default stamina resist. +#define VAMPIRE_INHERENT_STAMINA_RESIST 0.75 + +/// When do we warn them about their low blood? +#define VAMPIRE_LOW_BLOOD_WARNING 300 + +/// Minimum blood required for vampires oozelings to auto-revive. +#define OOZELING_MIN_REVIVE_BLOOD_THRESHOLD (FRENZY_THRESHOLD_ENTER * 5) +/// How long it takes for an vampire oozeling to auto-revive, when left alone. +#define OOZELING_VAMPIRE_REVIVE_TIME (1.5 MINUTES) +/// How many times faster an oozeling vampire will revive if their core is being held by a non-vampire/non-ally. +#define OOZELING_VAMPIRE_REVIVE_HELD_MULTIPLIER 0.5 +/// How many times faster an oozeling vampire will revive if their core is being held by an ally. +#define OOZELING_VAMPIRE_REVIVE_ALLY_MULTIPLIER 1.2 +/// How many times faster an oozeling vampire will revive if their core is in a coffin. +#define OOZELING_VAMPIRE_REVIVE_COFFIN_MULTIPLIER 2.5 + +// vassal defines +/// If someone passes all checks and can be vassalized +#define VASSALIZATION_ALLOWED 0 +/// If someone has to accept vassalization +#define VASSALIZATION_DISLOYAL 1 +/// If someone is not allowed under any circimstances to become a vassal +#define VASSALIZATION_BANNED 2 + +// Humanity gains (The actual tracking lists and such are in the datum duh) +// These are supposed to be somewhat nontrivial, to the point of sometimes not being viable. +/// Hugging of separate people +#define HUMANITY_HUGGING_TYPE "hug" + +/// Petting of separate animals +#define HUMANITY_PETTING_TYPE "pet" + +/// Watching of art +#define HUMANITY_ART_TYPE "art" + +#define HUMANITY_GAIN_TYPES list(HUMANITY_HUGGING_TYPE, HUMANITY_PETTING_TYPE, HUMANITY_ART_TYPE) + +/// Default Humanity +#define VAMPIRE_DEFAULT_HUMANITY 7 + +// Cooldown defines +// Used to prevent spamming vampires +/// Spam prevention for healing messages. +#define VAMPIRE_SPAM_HEALING 15 SECONDS +/// Spam prevention for Sol Masquerade messages. +#define VAMPIRE_SPAM_MASQUERADE 60 SECONDS + +/// Spam prevention for Sol messages. +#define VAMPIRE_SPAM_SOL 30 SECONDS + +// Clan defines #define CLAN_BRUJAH "Brujah Clan" #define CLAN_TOREADOR "Toreador Clan" #define CLAN_NOSFERATU "Nosferatu Clan" @@ -101,130 +122,52 @@ #define CLAN_VENTRUE "Ventrue Clan" #define CLAN_MALKAVIAN "Malkavian Clan" #define CLAN_TZIMISCE "Tzimisce Clan" +#define CLAN_HECATA "Hecata Clan" +#define CLAN_LASOMBRA "Lasombra Clan" -#define TREMERE_GHOUL "tremere_ghoul" -#define FAVORITE_GHOUL "favorite_ghoul" -#define REVENGE_GHOUL "revenge_ghoul" - -/** - * Power defines - */ +// Power defines /// This Power can't be used in Torpor #define BP_CANT_USE_IN_TORPOR (1<<0) /// This Power can't be used in Frenzy. #define BP_CANT_USE_IN_FRENZY (1<<1) -/// This Power can be used while transformed, for example by the shapeshift spell -#define BP_CAN_USE_TRANSFORMED (1<<2) -/// This Power can be used with a stake in you -#define BP_CAN_USE_WHILE_STAKED (1<<4) -/// This Power can be used while heartless -#define BP_CAN_USE_HEARTLESS (1<<5) - -/// This Power can be purchased by Bloodsuckers -#define BLOODSUCKER_CAN_BUY (1<<0) -/// This is a Default Power that all Bloodsuckers get. -#define BLOODSUCKER_DEFAULT_POWER (1<<1) -/// This Power can be purchased by Tremere Bloodsuckers -#define TREMERE_CAN_BUY (1<<2) - -/// This Power can be purchased by Ghouls -#define GHOUL_CAN_BUY (1<<3) - -/// If this Power can be bought if you already own it -#define CAN_BUY_OWNED (1<<4) - - -/// This Power is a Continuous Effect, processing every tick -#define BP_CONTINUOUS_EFFECT (1<<0) +/// This Power can't be used with a stake in you +#define BP_CANT_USE_WHILE_STAKED (1<<2) +/// This Power can't be used while incapacitated +#define BP_CANT_USE_WHILE_INCAPACITATED (1<<3) +/// This Power can't be used while unconscious +#define BP_CANT_USE_WHILE_UNCONSCIOUS (1<<4) + +/// This is a Default Power that all Vampires get. +#define VAMPIRE_DEFAULT_POWER (1<<1) + +/// This Power is a Toggled Power +#define BP_AM_TOGGLE (1<<0) /// This Power is a Single-Use Power #define BP_AM_SINGLEUSE (1<<1) /// This Power has a Static cooldown #define BP_AM_STATIC_COOLDOWN (1<<2) /// This Power doesn't cost bloot to run while unconscious #define BP_AM_COSTLESS_UNCONSCIOUS (1<<3) +/// This Power has a cooldown that is more dynamic than a typical power +#define BP_AM_VERY_DYNAMIC_COOLDOWN (1<<4) -#define DEACTIVATE_POWER_DO_NOT_REMOVE (1<<0) -#define DEACTIVATE_POWER_NO_COOLDOWN (1<<1) - -// ability levels that are used cross-file -#define DOMINATE_GHOULIZE_LEVEL 2 -#define TREMERE_OBJECTIVE_POWER_LEVEL 4 - -#define COFFIN_HEAL_COST_MULT 0.5 - - -/** - * Torpor check bitflags - */ -#define TORPOR_SKIP_CHECK_ALL (1<<0) -#define TORPOR_SKIP_CHECK_FRENZY (1<<1) -#define TORPOR_SKIP_CHECK_DAMAGE (1<<2) - -/** - * Bloodsucker Signals - */ -///Called when a Bloodsucker ranks up: (datum/bloodsucker_datum, mob/owner, mob/target) -#define COMSIG_BLOODSUCKER_RANK_UP "bloodsucker_rank_up" -///Called when a Bloodsucker interacts with a Ghoul on their persuasion rack. -#define COMSIG_BLOODSUCKER_INTERACT_WITH_GHOUL "bloodsucker_interact_with_ghoul" -///Called when a Bloodsucker makes a Ghoul into their Favorite Ghoul: (datum/ghoul_datum, mob/master) -#define COMSIG_BLOODSUCKER_MAKE_FAVORITE "bloodsucker_make_favorite" -// called when a bloodsucker looses their favorite ghoul, cleaning up whatever they gained -#define COMSIG_BLOODSUCKER_LOOSE_FAVORITE "bloodsucker_loose_favorite" -///Called when a new Ghoul is successfully made: (datum/bloodsucker_datum) -#define COMSIG_BLOODSUCKER_MADE_GHOUL "bloodsucker_made_ghoul" -///Called when a Bloodsucker exits Torpor. -#define COMSIG_BLOODSUCKER_EXIT_TORPOR "bloodsucker_exit_torpor" -///Called when a Bloodsucker reaches Final Death. -#define COMSIG_BLOODSUCKER_FINAL_DEATH "bloodsucker_final_death" - ///Whether the Bloodsucker should not be dusted when arriving Final Death +///Called when a Vampire reaches Final Death. +#define COMSIG_VAMPIRE_FINAL_DEATH "vampire_final_death" + ///Whether the vampire should not be dusted when arriving Final Death #define DONT_DUST (1<<0) -///Called when a Bloodsucker breaks the Masquerade -#define COMSIG_BLOODSUCKER_BROKE_MASQUERADE "comsig_bloodsucker_broke_masquerade" -///Called when a Bloodsucker enters Frenzy -#define COMSIG_BLOODSUCKER_ENTERS_FRENZY "bloodsucker_enters_frenzy" -///Called when a Bloodsucker exits Frenzy -#define COMSIG_BLOODSUCKER_EXITS_FRENZY "bloodsucker_exits_frenzy" -/// COMSIG_ATOM_EXAMINE that correctly updates when the bloodsucker datum is moved -#define COMSIG_BLOODSUCKER_EXAMINE "bloodsucker_examine" -/// from /obj/item/organ/proc/on_bodypart_remove(obj/item/bodypart/limb, movement_flags) -#define COMSIG_ORGAN_BODYPART_REMOVED "organ_bodypart_removed" -// Called when anyone enters the coffin -#define COMSIG_ENTER_COFFIN "enter_coffin" -#define COMSIG_MOB_STAKED "staked" -#define COMSIG_BODYPART_STAKED "staked" -// called when a targeted ability is cast -#define COMSIG_FIRE_TARGETED_POWER "comsig_fire_targeted_power" - -#define COMSIG_CAN_VENTCRAWL "can_ventcrawl" -#define COMSIG_VENTCRAWL_PRE_ENTER "ventcrawling_pre_enter" -#define COMSIG_VENTCRAWL_PRE_EXIT "ventcrawling_pre_exit" -#define COMSIG_VENTCRAWL_ENTER "ventcrawling_enter" -#define COMSIG_VENTCRAWL_EXIT "ventcrawling_exit" -#define COMSIG_VENTCRAWL_PRE_CANCEL "ventcrawling_pre_cancel" - -/// drink blood via the feed action -#define COMSIG_MOB_FEED_DRINK "mob_feed_drink" -#define FEED_CANCEL_BLOOD_TRANSFER (1 << 0) - -/// returns the bitflag if it indeed reached max blood, otherwise NONE -#define COMSIG_MOB_REACHED_MAX_BLOOD "mob_reached_max_blood" -#define REACHED_MAX_BLOOD (1 << 0) - -/** - * Sol signals & Defines - */ -#define COMSIG_SOL_RANKUP_BLOODSUCKERS "comsig_sol_rankup_bloodsuckers" -#define COMSIG_SOL_RISE_TICK "comsig_sol_rise_tick" -#define COMSIG_SOL_NEAR_START "comsig_sol_near_start" -#define COMSIG_SOL_END "comsig_sol_end" -///Sent when a warning for Sol is meant to go out: (danger_level, vampire_warning_message, ghoul_warning_message) -#define COMSIG_SOL_WARNING_GIVEN "comsig_sol_warning_given" -///Called on a Bloodsucker's Lifetick. -#define COMSIG_BLOODSUCKER_ON_LIFETICK "comsig_bloodsucker_on_lifetick" -/// Called when a Bloodsucker's blood is updated -#define BLOODSUCKER_UPDATE_BLOOD "bloodsucker_update_blood" - #define BLOODSUCKER_UPDATE_BLOOD_DISABLED (1<<0) + +// Vampire Signals +/// Called when a Vampire breaks the Masquerade +#define COMSIG_VAMPIRE_BROKE_MASQUERADE "comsig_vampire_broke_masquerade" + +// Signals & Defines +/// Sent whenever vampires get a "natural" rank up. +#define COMSIG_SOL_RANKUP_VAMPIRES "sol_rankup_vampires" +/// Sent when tracking humanity gain progress: (type, subject) +#define COMSIG_VAMPIRE_TRACK_HUMANITY_GAIN "comsig_vampire_track_humanity_gain" + +/// Called on the mind when a Vampire chooses a clan: (datum/antagonist/vampire, datum/vampire_clan) +#define COMSIG_VAMPIRE_CLAN_CHOSEN "vampire_clan_chosen" #define DANGER_LEVEL_FIRST_WARNING 1 #define DANGER_LEVEL_SECOND_WARNING 2 @@ -232,87 +175,90 @@ #define DANGER_LEVEL_SOL_ROSE 4 #define DANGER_LEVEL_SOL_ENDED 5 -/** - * Clan defines - * - * This is stuff that is used solely by Clans for clan-related activity. - */ -///Drinks blood the normal Bloodsucker way. -#define BLOODSUCKER_DRINK_NORMAL "bloodsucker_drink_normal" -///Drinks blood but is snobby, refusing to drink from mindless -#define BLOODSUCKER_DRINK_SNOBBY "bloodsucker_drink_snobby" -///Drinks blood from disgusting creatures without Humanity consequences. -#define BLOODSUCKER_DRINK_INHUMANELY "bloodsucker_drink_inhumanely" - -/** - * Traits - */ +// Clan defines +/// Drinks blood the normal Vampire way. +#define VAMPIRE_DRINK_NORMAL "vampire_drink_normal" +/// Drinks blood but is snobby, refusing to drink from mindless +#define VAMPIRE_DRINK_SNOBBY "vampire_drink_snobby" +// Masquerade ability given at this point or above +#define VAMPIRE_HUMANITY_MASQUERADE_POWER 7 + +// Traits /// Falsifies Health analyzer blood levels #define TRAIT_MASQUERADE "masquerade" -/// Your body is literal room temperature. Does not make you immune to the temp -#define TRAIT_COLDBLOODED "coldblooded" - -#define TRAIT_COFFIN_ENLARGED "coffin_enlarged" - -/** - * Sources - */ -/// Source trait for Bloodsuckers-related traits -#define BLOODSUCKER_TRAIT "bloodsucker_trait" - -#define GHOUL_TRAIT "ghoul_trait" - -#define TORPOR_TRAIT "torpor" - -/// Source trait for dominate related traits -#define MESMERIZE_TRAIT "meserize_trait" -#define DOMINATE_TRAIT "dominate_trait" - -/// Source trait for Monster Hunter-related traits -#define HUNTER_TRAIT "monsterhunter_trait" -/// Source trait while Feeding -#define FEED_TRAIT "feed_trait" -/// Source trait during a Frenzy -#define FRENZY_TRAIT "frenzy_trait" - -///Whether a mob is a Bloodsucker -#define IS_BLOODSUCKER(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/bloodsucker)) -///Whether a mob is a Ghoul -#define IS_GHOUL(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/ghoul)) -///Whether a mob is a Favorite Ghoul -#define IS_FAVORITE_GHOUL(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/ghoul/favorite)) -///Whether a mob is a Revenge Ghoul -#define IS_REVENGE_GHOUL(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/ghoul/revenge)) -#define IS_EX_GHOUL(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/ex_ghoul)) - -///Whether a mob is a Monster Hunter-NOT NEEDED RIGHT NOW -// #define IS_MONSTERHUNTER(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/monsterhunter)) -///For future use -#define IS_MONSTERHUNTER(mob) (FALSE) - -#define BLOODSUCKER_SIGHT_COLOR_CUTOFF list(25, 8, 5) -#define POLL_IGNORE_GHOUL "ghoul" - -// Why waste memory on a dynamic global list if we can just bake it in on compile time? -#define BLOODSUCKER_BLACKLISTED_ROLES list( \ - JOB_CAPTAIN, \ - JOB_HEAD_OF_PERSONNEL, \ - JOB_HEAD_OF_SECURITY, \ - JOB_WARDEN, \ - JOB_SECURITY_OFFICER, \ - JOB_DETECTIVE, \ -) - -#define BLOODSUCKER_RESTRICTED_SPECIES list( \ - /datum/species/synthetic, \ - /datum/species/plasmaman, \ - /datum/species/shadow/nightmare, \ - /datum/species/abductor, \ - /datum/species/android, \ - /datum/species/golem, \ - /datum/species/shadow, \ - /datum/species/skeleton, \ - /datum/species/zombie, \ - /datum/species/mutant, \ - /datum/species/dullahan \ -) +/// For people in the middle of being staked +#define TRAIT_BEINGSTAKED "beingstaked" +/// This vampire is currently in a frenzy, +#define TRAIT_FRENZY "frenzy" +/// This vampire is currently in torpor. +#define TRAIT_TORPOR "torpor" +/// This vampire can tell if another vampire has committed diablere on examine. +#define TRAIT_SEE_DIABLERIE "see_diablerie" + +// Trait sources +/// Source trait for all vampire traits +#define TRAIT_VAMPIRE "trait_vampire" + +// Macros +#define IS_CURATOR(mob) istype(mob?.mind?.assigned_role, /datum/job/curator) +/// Logging for vampire powers unlocked. +/proc/log_vampire_power(text, list/data) + logger.Log(LOG_CATEGORY_UPLINK_VAMPIRE, text, data) + +/// Trait that says you're shaded by something (ie partially in the dark) +#define TRAIT_SHADED "shaded" + +#define IS_VAMPIRE_HUNTER(mob) (IS_CURATOR(mob)) + +/// Basically just check for `HAS_MIND_TRAIT(user, TRAIT_VAMPIRE_ALIGNED)` instead of `IS_VAMPIRE(user) || IS_VASSAL(user)` +#define TRAIT_VAMPIRE_ALIGNED "vampire_aligned" + +#define LANGUAGE_VAMPIRE "vampire" +#define LANGUAGE_VASSAL "vassal" + +/// /turf/proc/is_softly_lit() but inlined +#define IS_SOFTLY_LIT(turf) (turf.lighting_object && !(turf.luminosity || turf.dynamic_lumcount)) +/// Similar to turf.get_lumcount(), but it checks for soft lighting first, and just assumes the lumcount is 0 if it is. +#define GET_SIMPLE_LUMCOUNT(turf) (IS_SOFTLY_LIT(turf) ? 0 : turf.get_lumcount()) + +//Incapacitated status effect flags +/// If the incapacitated status effect will ignore a mob in restraints (handcuffs) +#define IGNORE_RESTRAINTS (1<<0) +/// If the incapacitated status effect will ignore a mob in stasis (stasis beds) +#define IGNORE_STASIS (1<<1) +/// If the incapacitated status effect will ignore a mob being agressively grabbed +#define IGNORE_GRAB (1<<2) +/// If the incapacited status effect will ignore a mob in softcrit +#define IGNORE_SOFTCRIT (1<<3) + +#define IS_FINITE__UNSAFE(a) (!isinf(a) && !isnan(a)) +#define IS_FINITE(a) (isnum(a) && IS_FINITE__UNSAFE(a)) + +#define IS_SAFE_NUM(a) IS_FINITE(a) + +#define BODY_ZONES_LIMBS list(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) +///from base of atom/expose_reagents(): (/list, /datum/reagents, methods, volume_modifier, show_message) +#define COMSIG_ATOM_EXPOSE_REAGENTS "atom_expose_reagents" + /// Prevents the atom from being exposed to reagents if returned on [COMSIG_ATOM_EXPOSE_REAGENTS] + #define COMPONENT_NO_EXPOSE_REAGENTS (1<<0) +///from base of atom/expose_reagents(): (/list, /datum/reagents, methods, volume_modifier, show_message) +#define COMSIG_ATOM_AFTER_EXPOSE_REAGENTS "atom_after_expose_reagents" +///from base of [/datum/reagent/proc/expose_atom]: (/datum/reagent, reac_volume) +#define COMSIG_ATOM_EXPOSE_REAGENT "atom_expose_reagent" +#define MOVABLE_PHYSICS_PRECISION 0.01 +#define MOVABLE_PHYSICS_MINIMAL_VELOCITY 1 + +// movable physics component flags +/// Remove the component as soon as there's zero velocity, useful for movables that will no longer move after being initially moved (blood splatters) +#define MPHYSICS_QDEL_WHEN_NO_MOVEMENT (1<<0) +/// Movement has started, don't call start_movement() again +#define MPHYSICS_MOVING (1<<1) +/// The component has been "paused" and will not process +#define MPHYSICS_PAUSED (1<<2) +///from base of atom/movable/newtonian_move(): (inertia_direction, start_delay) +#define COMSIG_MOVABLE_NEWTONIAN_MOVE "movable_newtonian_move" + #define COMPONENT_MOVABLE_NEWTONIAN_BLOCK (1<<0) +///from base of [/atom/proc/expose_reagents]: (/atom, /list, methods, volume_modifier, show_message) +#define COMSIG_REAGENTS_EXPOSE_ATOM "reagents_expose_atom" +#define COMSIG_LIVING_TRACKER_REMOVED "tracker_removed" +#define ui_team_finder "CENTER,CENTER" diff --git a/code/_globalvars/lists/crafting.dm b/code/_globalvars/lists/crafting.dm index 48b2b61a42b..3dbc801eade 100644 --- a/code/_globalvars/lists/crafting.dm +++ b/code/_globalvars/lists/crafting.dm @@ -41,4 +41,5 @@ GLOBAL_LIST_INIT(crafting_category, list( CAT_ENTERTAINMENT, CAT_TOOLS, CAT_CULT, + CAT_VAMPIRE, // TFF ADDITION )) diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index d6fa7c53366..7744cb6c597 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -127,6 +127,8 @@ GLOBAL_LIST_INIT(available_erp_ui_styles, list( /// and avoid needing to make changes to all idk 300 consumers if we want to change the appearance var/list/asset_refs_for_reuse = list() + var/list/team_finder_arrows = list() // TFF ADDITION + /datum/hud/New(mob/owner) mymob = owner @@ -246,7 +248,7 @@ GLOBAL_LIST_INIT(available_erp_ui_styles, list( QDEL_NULL(palette_actions) QDEL_NULL(listed_actions) QDEL_LIST(floating_actions) - + QDEL_LIST(team_finder_arrows) // TFF ADDITION QDEL_LIST(static_inventory) // all already deleted by static inventory clear @@ -370,6 +372,10 @@ GLOBAL_LIST_INIT(available_erp_ui_styles, list( screenmob.client.screen += hotkeybuttons if(infodisplay.len) screenmob.client.screen += infodisplay + // TFF ADDITION START + if(team_finder_arrows.len) + screenmob.client.screen += team_finder_arrows + // TFF ADDITION END if(always_visible_inventory.len) screenmob.client.screen += always_visible_inventory if(open_containers.len && screenmob == mymob) // Don't show open inventories to ghosts @@ -384,12 +390,20 @@ GLOBAL_LIST_INIT(available_erp_ui_styles, list( hud_shown = FALSE //Governs behavior of other procs if(static_inventory.len) screenmob.client.screen -= static_inventory + // TFF ADDITION START + if(team_finder_arrows.len) + screenmob.client.screen += team_finder_arrows + // TFF ADDITION END if(toggleable_inventory.len) screenmob.client.screen -= toggleable_inventory if(hotkeybuttons.len) screenmob.client.screen -= hotkeybuttons if(infodisplay.len) screenmob.client.screen += infodisplay + // TFF ADDITION START + if(team_finder_arrows.len) + screenmob.client.screen -= team_finder_arrows + // TFF ADDITION END if(always_visible_inventory.len) screenmob.client.screen += always_visible_inventory diff --git a/code/_onclick/hud/vampire.dm b/code/_onclick/hud/vampire.dm new file mode 100644 index 00000000000..f3f30acb892 --- /dev/null +++ b/code/_onclick/hud/vampire.dm @@ -0,0 +1,196 @@ +/// 1 tile up +#define UI_HUMANITY_DISPLAY "WEST:6,CENTER+1:-8" +/// 1 tile down +#define UI_BLOOD_DISPLAY "WEST:6,CENTER:0" +/// 2 tiles down +#define UI_VAMPRANK_DISPLAY "WEST:6,CENTER-1:-2" + +///Maptext define for Vampire HUDs +#define FORMAT_VAMPIRE_HUD_TEXT(valuecolor, value) MAPTEXT("
    [round(value,1)]
    ") + +/atom/movable/screen/vampire + icon = 'tff_modular/modules/vampire/icons/actions_vampire.dmi' + mouse_over_pointer = MOUSE_HAND_POINTER + +/atom/movable/screen/vampire/blood_counter + name = "Vitae" + icon_state = "blood_display" + screen_loc = UI_BLOOD_DISPLAY + +/atom/movable/screen/vampire/blood_counter/Click() + . = ..() + var/list/msg = list() + var/mob/living/owner_mob = hud.mymob + var/datum/antagonist/vampire/owner_vamp = IS_VAMPIRE(owner_mob) + + if(!owner_vamp) + return + + msg += span_cult_large("This is your Vitae-Counter.") + msg += span_cult("Here you see your current level of blood-energy. This is used for all of your abilities, and sustains your very being.") + msg += span_cult("\nYou need to drink a certain amount from living, sentient beings in order to level up.") + msg += span_cult("Your healing also depends on it. You reach your maximum healing potential at [BS_BLOOD_VOLUME_MAX_REGEN].") + + var/bloodlevel + switch(owner_vamp.current_vitae) + if(0 to 200) + bloodlevel = "starved" + if(201 to 500) + bloodlevel = "thirsty" + if(501 to 700) + bloodlevel = "peckish" + if(701 to INFINITY) + bloodlevel = "content" + + msg += span_cult("Your current maximum is: [owner_vamp.max_vitae].") + msg += span_cult("This shift, you have drank [owner_vamp.total_blood_drank] units of blood.") + + msg += span_cult_large("\nRight now, you are feeling [bloodlevel].") + + if(owner_vamp.vitae_goal_progress <= owner_vamp.current_vitae_goal) + msg += span_cult_large("\nYour progress to the next level is: [owner_vamp.vitae_goal_progress]/[owner_vamp.current_vitae_goal].") + else + msg += span_cult_large("\nYou have drank deeply and greedily. Sleep in a coffin to level up.") + + to_chat(usr, boxed_message(msg.Join("\n"))) + +/atom/movable/screen/vampire/rank_counter + name = "Vampire Rank" + icon_state = "rank" + screen_loc = UI_VAMPRANK_DISPLAY + +/atom/movable/screen/vampire/rank_counter/Click() + . = ..() + var/list/msg = list() + var/mob/living/owner_mob = hud.mymob + var/datum/antagonist/vampire/owner_vamp = IS_VAMPIRE(owner_mob) + + if(!owner_vamp) + return + + /* var/mob/living/carbon/human/vampire_human = owner_mob */ + msg += span_cult_large("This is your Rank-Counter.") + msg += span_cult("Here you see your current progress in the mastery of your disciplines.") + msg += span_cult("This is a measure of your main progress as a vampire, and, should you feed on another vampire(that has broken the masquerade), you will absorb half of their levels.") + msg += span_cult("With your current rank, you are considered as [owner_vamp.get_rank_string()] of your craft.") + msg += span_cult("\nCurrently, your rank affords you the following benefits:") + msg += span_cult("Max Regeneration rate: +[owner_vamp.vampire_regen_rate]") + msg += span_cult("Max Vitae pool: +[owner_vamp.max_vitae - 600] ") + msg += span_cult("Unarmed damage: +[1 + (owner_vamp.vampire_level * owner_vamp.extra_damage_per_rank)]") + + var/list/disciplinestext + for(var/datum/discipline/discipline in owner_vamp.owned_disciplines) + disciplinestext += "\n[discipline.name] - " + disciplinestext += "Level:" + disciplinestext += "[discipline.level - 1]" + + if(disciplinestext) + msg += span_cult("\nYour disciplines and their levels are:[disciplinestext]") + + to_chat(usr, boxed_message(msg.Join("\n"))) + +/atom/movable/screen/vampire/humanity_counter + name = "Humanity" + icon_state = "humanity" + screen_loc = UI_HUMANITY_DISPLAY + +/atom/movable/screen/vampire/humanity_counter/Click() + . = ..() + var/list/msg = list() + var/mob/living/owner_mob = hud.mymob + var/datum/antagonist/vampire/owner_vamp = IS_VAMPIRE(owner_mob) + + msg += span_cult_large("This is your Humanity score.") + msg += span_cult("Humanity is a measure of how closely a vampire clings to the morality and values of mortal life, and consequently how well they are able to resist the urges of the Beast.") + msg += span_cult("This has an active effect on the curse of all cainites. Vampires with little humanity may find it harder to stay awake during the day, or to awaken from long periods of torpor. If your humanity is particularly low, you may even burst into flames in the presence of god's light.") + + var/humanitylevel + switch(owner_vamp.humanity) + if(0) + humanitylevel = "Monstrous" + if(1) + humanitylevel = "Horrific" + if(2) + humanitylevel = "Bestial" + if(3) + humanitylevel = "Cold" + if(4) + humanitylevel = "Unfeeling" + if(5) + humanitylevel = "Removed" + if(6) + humanitylevel = "Distant" + if(7) + humanitylevel = "Normal" + if(8) + humanitylevel = "Caring" + if(9) + humanitylevel = "Compassionate" + if(10) + humanitylevel = "Saintly" + + // Pardon me for my math, i was never good at this. + + var/normal_humanity_divisor = min(2, 1 + (owner_vamp.humanity / 10)) + var/divisor_turned_percentage = ((normal_humanity_divisor - 1) * 200) / 4 + + msg += span_cult("\nRight now, others would describe you as '[humanitylevel]', giving you a [divisor_turned_percentage]% resistance to the ravages of Sol.") + if(owner_vamp.humanity > 7) + msg += span_cult("Due to your connection to your own human soul, you have achieved the masquerade ability.") + + msg += span_cult("\nYou may gain humanity by engaging in human activities, such as:") + msg += span_cult("Hugging different mortals: [length(owner_vamp.humanity_trackgain_hugged)] of [owner_vamp.humanity_hugging_goal].") + msg += span_cult("Petting various animals: [length(owner_vamp.humanity_trackgain_petted)] of [owner_vamp.humanity_petting_goal].") + msg += span_cult("Looking at art: [length(owner_vamp.humanity_trackgain_art)] of [owner_vamp.humanity_art_goal].") + + to_chat(usr, boxed_message(msg.Join("\n"))) + +/// Update Blood Counter + Rank Counter +/datum/antagonist/vampire/proc/update_hud() + var/valuecolor + switch(current_vitae) + if(0 to 200) + valuecolor = "#560808" + if(201 to 300) + valuecolor = "#a32a2a" + if(301 to 500) + valuecolor = "#d55c5c" + if(501 to 700) // This isn't janky, a tiny bit lenience is baked in. + valuecolor = "#ffc2c2" + if(701 to INFINITY) + valuecolor = "#ffffff" + + blood_display?.maptext = FORMAT_VAMPIRE_HUD_TEXT(valuecolor, current_vitae) + + if(vamprank_display) + if(vampire_level_unspent > 0) + vamprank_display.icon_state = "[initial(vamprank_display.icon_state)]_up" + else + vamprank_display.icon_state = initial(vamprank_display.icon_state) + vamprank_display.maptext = FORMAT_VAMPIRE_HUD_TEXT("#ffd8d8", vampire_level) + + if(humanity_display) + var/humanityvaluecolor + switch(humanity) + if(0 to 2) + humanityvaluecolor = "#600000" + if(3 to 4) + humanityvaluecolor = "#a71c1c" + if(4 to 5) + humanityvaluecolor = "#db4646" + if(6 to 8) // same here + humanityvaluecolor = "#e8adad" + if(9 to 10) + humanityvaluecolor = "#ffffff" + + humanity_display.maptext = FORMAT_VAMPIRE_HUD_TEXT(humanityvaluecolor, humanity) + +/// 1 tile up +#undef UI_HUMANITY_DISPLAY +/// 1 tile down +#undef UI_BLOOD_DISPLAY +/// 2 tiles down +#undef UI_VAMPRANK_DISPLAY + +///Maptext define for Vampire HUDs +#undef FORMAT_VAMPIRE_HUD_TEXT diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm index e8494b9e812..4475c3c3e91 100644 --- a/code/controllers/configuration/entries/game_options.dm +++ b/code/controllers/configuration/entries/game_options.dm @@ -512,3 +512,12 @@ /datum/config_entry/number/max_shuttle_size default = 250 + +// TFF ADDITION START +/datum/config_entry/flag/allow_vampire_prince + default = TRUE + +/datum/config_entry/flag/allow_vampire_scourge + default = TRUE + +// TFF ADDITION END diff --git a/code/controllers/subsystem/polling.dm b/code/controllers/subsystem/polling.dm index b434db5031e..23b722b7a40 100644 --- a/code/controllers/subsystem/polling.dm +++ b/code/controllers/subsystem/polling.dm @@ -84,10 +84,10 @@ SUBSYSTEM_DEF(polling) if(!candidate_mob.client) continue // Universal opt-out for all players. - if(!candidate_mob.client.prefs.read_preference(/datum/preference/toggle/ghost_roles)) + if(!candidate_mob.client?.prefs?.read_preference(/datum/preference/toggle/ghost_roles) || HAS_TRAIT(candidate_mob, TRAIT_NO_OBSERVE)) // TFF EDIT - ORIGINAL: if(!candidate_mob.client.prefs.read_preference(/datum/preference/toggle/ghost_roles)) continue // Opt-out for admins whom are currently adminned. - if((!candidate_mob.client.prefs.read_preference(/datum/preference/toggle/ghost_roles_as_admin)) && candidate_mob.client.holder) + if((!candidate_mob.client?.prefs?.read_preference(/datum/preference/toggle/ghost_roles_as_admin)) && candidate_mob.client?.holder) // TFF EDIT - ORIGINAL: if((!candidate_mob.client.prefs.read_preference(/datum/preference/toggle/ghost_roles_as_admin)) && candidate_mob.client.holder) continue if(!is_eligible(candidate_mob, role, check_jobban, ignore_category)) continue diff --git a/code/datums/elements/art.dm b/code/datums/elements/art.dm index 0ec98410b1d..60f026557bf 100644 --- a/code/datums/elements/art.dm +++ b/code/datums/elements/art.dm @@ -35,6 +35,8 @@ user.visible_message(span_notice("[user] stops and looks intently at [source]."), \ span_notice("You appraise [source]... [msg]")) + SEND_SIGNAL(user, COMSIG_LIVING_APPRAISE_ART, source) // TFF ADDITION + /datum/element/art/proc/on_examine(atom/source, mob/user, list/examine_texts) SIGNAL_HANDLER if(!isliving(user)) diff --git a/code/datums/greyscale/json_configs/_umbrella.json b/code/datums/greyscale/json_configs/_umbrella.json new file mode 100644 index 00000000000..224aac4e6dd --- /dev/null +++ b/code/datums/greyscale/json_configs/_umbrella.json @@ -0,0 +1,28 @@ +{ + "umbrella_on": [ + { + "type": "icon_state", + "icon_state": "umbrella_on_handle", + "blend_mode": "overlay" + }, + { + "type": "icon_state", + "icon_state": "umbrella_on", + "blend_mode": "overlay", + "color_ids": [1] + } + ], + "umbrella": [ + { + "type": "icon_state", + "icon_state": "umbrella_handle", + "blend_mode": "overlay" + }, + { + "type": "icon_state", + "icon_state": "umbrella", + "blend_mode": "overlay", + "color_ids": [1] + } + ] +} diff --git a/code/datums/greyscale/json_configs/_umbrella_inhand.json b/code/datums/greyscale/json_configs/_umbrella_inhand.json new file mode 100644 index 00000000000..e8a0b8c4ccb --- /dev/null +++ b/code/datums/greyscale/json_configs/_umbrella_inhand.json @@ -0,0 +1,31 @@ +{ + "umbrella_closed": [ + { + "type": "icon_state", + "icon_state": "umbrella_closed", + "blend_mode": "overlay", + "color_ids": [1] + } + ], + "umbrella_on": [ + { + "type": "icon_state", + "icon_state": "umbrella_handle", + "blend_mode": "overlay" + }, + { + "type": "icon_state", + "icon_state": "umbrella_on", + "blend_mode": "overlay", + "color_ids": [1] + } + ], + "umbrella_on_BACK": [ + { + "type": "icon_state", + "icon_state": "umbrella_on_BACK", + "blend_mode": "overlay", + "color_ids": [1] + } + ] +} diff --git a/code/game/atom/_atom.dm b/code/game/atom/_atom.dm index d3a090e0de7..6b14bf5b53e 100644 --- a/code/game/atom/_atom.dm +++ b/code/game/atom/_atom.dm @@ -425,9 +425,10 @@ . = SEND_SIGNAL(src, COMSIG_ATOM_EXPOSE_REAGENTS, reagents, source, methods, show_message) if(. & COMPONENT_NO_EXPOSE_REAGENTS) return - + SEND_SIGNAL(source, COMSIG_REAGENTS_EXPOSE_ATOM, src, reagents, methods, show_message) // TFF ADDITION for(var/datum/reagent/current_reagent as anything in reagents) . |= current_reagent.expose_atom(src, reagents[current_reagent], methods) + SEND_SIGNAL(src, COMSIG_ATOM_AFTER_EXPOSE_REAGENTS, reagents, source, methods, show_message) // TFF ADDITION /// Are you allowed to drop stuff inside this atom /atom/proc/AllowDrop() diff --git a/code/game/machinery/computer/crew.dm b/code/game/machinery/computer/crew.dm index fb10033b283..ca8423b5792 100644 --- a/code/game/machinery/computer/crew.dm +++ b/code/game/machinery/computer/crew.dm @@ -294,6 +294,12 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new) if (sensor_mode >= SENSOR_VITALS) entry["life_status"] = tracked_living_mob.stat else if (sensor_mode == SENSOR_LIVING) + // TFF ADDITION + if(tracked_living_mob.stat == UNCONSCIOUS && tracked_living_mob.health > tracked_living_mob.crit_threshold) + entry["life_status"] = CONSCIOUS + else + entry["life_status"] = tracked_living_mob.stat + // TFF ADDITION END // binary sensors should only report alive or dead entry["life_status"] = (tracked_living_mob.stat == DEAD) ? DEAD : CONSCIOUS diff --git a/code/game/objects/items/devices/scanners/sequence_scanner.dm b/code/game/objects/items/devices/scanners/sequence_scanner.dm index 96db499a1e6..38c4c12b8cb 100644 --- a/code/game/objects/items/devices/scanners/sequence_scanner.dm +++ b/code/game/objects/items/devices/scanners/sequence_scanner.dm @@ -48,9 +48,17 @@ add_fingerprint(user) //no scanning if its a husk or DNA-less Species - if (!HAS_TRAIT(interacting_with, TRAIT_GENELESS) && !HAS_TRAIT(interacting_with, TRAIT_BADDNA)) + if ((!HAS_TRAIT(interacting_with, TRAIT_GENELESS) || HAS_TRAIT(interacting_with, TRAIT_FAKEGENES)) && !HAS_TRAIT(interacting_with, TRAIT_BADDNA)) // TFF EDIT, ORIGINAL: if (!HAS_TRAIT(interacting_with, TRAIT_GENELESS) && !HAS_TRAIT(interacting_with, TRAIT_BADDNA)) user.visible_message(span_notice("[user] analyzes [interacting_with]'s genetic sequence.")) + // TFF EDIT START - ORIGINAL: + /* balloon_alert(user, "sequence analyzed") + */ + if(!do_after(user, 3 SECONDS, interacting_with)) + balloon_alert(user, "scan_failed!") + user.visible_message(span_warning("[user] fails to scan [interacting_with]'s genetic makeup.")) + return ITEM_INTERACT_BLOCKING + // TFF EDIT END playsound(user, 'sound/items/healthanalyzer.ogg', 50) // close enough gene_scan(interacting_with, user) return ITEM_INTERACT_SUCCESS diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index a01ba7fdeef..e9d36687f90 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -21,6 +21,7 @@ GLOBAL_LIST_EMPTY(roundstart_station_closets) contents_thermal_insulation = 0 pass_flags_self = PASSSTRUCTURE | LETPASSCLICKS custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 2) + var/ash_chance = 10 // TFF ADDITION /// The overlay for the closet's door var/obj/effect/overlay/closet_door/door_obj /// Whether or not this door is being animated @@ -1085,11 +1086,20 @@ GLOBAL_LIST_EMPTY(roundstart_station_closets) // If we reach here, nobody is resisting, so don't shake return FALSE -/obj/structure/closet/proc/bust_open() +/obj/structure/closet/proc/bust_open(destructive = TRUE) SIGNAL_HANDLER welded = FALSE //applies to all lockers unlock() //applies to critter crates and secure lockers only broken = TRUE //applies to secure lockers only + if(destructive) + for(var/obj/item/broken in src.contents) + if(!prob(ash_chance)) + continue + new /obj/effect/decal/cleanable/ash(loc) + + if(istype(broken, /obj/item/ammo_box)) + explosion(src, 0, 0, 2, 0, 2) + qdel(broken) open(force = TRUE, special_effects = FALSE) /obj/structure/closet/attack_hand_secondary(mob/user, modifiers) diff --git a/code/modules/antagonists/_common/antag_datum.dm b/code/modules/antagonists/_common/antag_datum.dm index 5693f550445..95afb2aa8b5 100644 --- a/code/modules/antagonists/_common/antag_datum.dm +++ b/code/modules/antagonists/_common/antag_datum.dm @@ -234,6 +234,17 @@ GLOBAL_LIST_EMPTY(antagonists) /datum/antagonist/proc/create_team(datum/team/team) return +// TFF ADDITION START +/datum/antagonist/proc/make_info_button() as /datum/action/antag_info + if(!ui_name) + return + var/datum/action/antag_info/info_button = new(src) + info_button.Grant(owner.current) + info_button_ref = WEAKREF(info_button) + return info_button + +// TFF ADDITION END + ///Called by the add_antag_datum() mind proc after the instanced datum is added to the mind's antag_datums list. /datum/antagonist/proc/on_gain() SHOULD_CALL_PARENT(TRUE) @@ -241,11 +252,14 @@ GLOBAL_LIST_EMPTY(antagonists) if(!skip_custom_objectives_addition) add_custom_objectives() // FLUFFY FRONTIER CHANGE END - var/datum/action/antag_info/info_button + // TFF REMOVAL: var/datum/action/antag_info/info_button if(!owner) CRASH("[src] ran on_gain() without a mind") if(!owner.current) CRASH("[src] ran on_gain() on a mind without a mob") + + // TFF EDIT START - ORIGINAL: + /* if(ui_name)//in the future, this should entirely replace greet. info_button = new(src) if(antag_flags & ANTAG_OBSERVER_VISIBLE_PANEL) @@ -253,9 +267,12 @@ GLOBAL_LIST_EMPTY(antagonists) info_button.allow_observer_click = TRUE info_button.Grant(owner.current) info_button_ref = WEAKREF(info_button) + */ + var/datum/action/antag_info/info_button = make_info_button() + // TFF EDIT END if(!silent) greet() - if(ui_name) + if(info_button) // TFF EDIT - ORIGINAL: if(ui_name) to_chat(owner.current, span_boldnotice("For more info, read the panel. \ You can always come back to it using the button in the top left.")) info_button.Trigger() diff --git a/code/modules/antagonists/brainwashing/brainwashing.dm b/code/modules/antagonists/brainwashing/brainwashing.dm index 716e2cb494f..019d045d497 100644 --- a/code/modules/antagonists/brainwashing/brainwashing.dm +++ b/code/modules/antagonists/brainwashing/brainwashing.dm @@ -84,3 +84,40 @@ /datum/objective/brainwashing completed = TRUE + +// TFF ADDITION START +/// Removes objectives from someone's brainwash. +/proc/unbrainwash(mob/living/victim, list/directives) + var/datum/antagonist/brainwashed/brainwash = victim?.mind?.has_antag_datum(/datum/antagonist/brainwashed) + if(!brainwash) + return FALSE + if(directives) + if(!isnull(directives) && !islist(directives)) + directives = list(directives) + var/list/removed_objectives = list() + var/list/objective_texts = list() + for(var/datum/objective/directive as anything in directives) + if(istype(directive, /datum/weakref)) + var/datum/weakref/directive_weakref = directive + directive = directive_weakref.resolve() + if(!istype(directive)) + continue + brainwash.objectives -= directive + removed_objectives += directive + objective_texts += "\"[directive.explanation_text]\"" + log_admin("[key_name(victim)] had the following brainwashing objective[length(removed_objectives) > 1 ? "s" : ""] removed: [english_list(objective_texts)].") + if(LAZYLEN(brainwash.objectives)) + to_chat(victim, span_userdanger("[length(removed_objectives) > 1 ? "Some" : "One"] of your Directives fade away! You only have to obey the remaining Directives now.
    ")) + victim.mind.announce_objectives() + else + victim.mind.remove_antag_datum(/datum/antagonist/brainwashed) + QDEL_LIST(removed_objectives) + else + var/list/objective_texts = list() + for(var/datum/objective/directive as anything in brainwash.objectives) + objective_texts += "\"[directive.explanation_text]\"" + log_admin("[key_name(victim)] had all of their brainwashing objectives removed: [english_list(objective_texts)].") + QDEL_LIST(brainwash.objectives) + victim.mind.remove_antag_datum(/datum/antagonist/brainwashed) + +// TFF ADDITION END diff --git a/code/modules/antagonists/cult/blood_magic.dm b/code/modules/antagonists/cult/blood_magic.dm index 7c7c7abb73e..2d9967ee1c9 100644 --- a/code/modules/antagonists/cult/blood_magic.dm +++ b/code/modules/antagonists/cult/blood_magic.dm @@ -482,7 +482,10 @@ animate(target, color = old_color, time = 1 SECONDS, easing = EASE_IN) return ..() // NOVA EDIT ADDITION END - + // TFF ADDITION START + else if(IS_VAMPIRE(target)) + effect_vampire() + // TFF ADDITION END if(target.can_block_magic()) to_chat(user, span_warning("The spell had no effect!")) return ..() @@ -501,6 +504,75 @@ carbon_target.set_jitter_if_lower(30 SECONDS * effect_coef) return ..() +// TFF ADDITION START +/obj/item/melee/blood_magic/stun/proc/effect_vampire(mob/living/target, mob/living/carbon/user) + to_chat(user, span_userdanger("The spell violently reacts with [target], releasing a large burst of sanguine energy!"), type = MESSAGE_TYPE_COMBAT) + to_chat(target, span_userdanger("You're flung back by a violent burst of sanguine energy, as [user] attempts to hit you with ") + span_cult_large("the blood of the Traitor!"), type = MESSAGE_TYPE_COMBAT) + target.visible_message( + span_warning("[user] and [target] are violently flung back by a burst of sanguine energy!"), + ignored_mobs = list(user, target), + ) + + var/obj/effect/temp_visual/sanguine_boom/boom = new(user.loc) + + if(user.loc == target.loc) + boom.pixel_x = -32 + boom.pixel_y = -32 + else + var/dir = get_dir(user, target) + if(dir & NORTH) + boom.pixel_y = 32 + else if(dir & SOUTH) + boom.pixel_y = -32 + + if(dir & WEST) + boom.pixel_x = -32 + else if(dir & EAST) + boom.pixel_x = 32 + + // deactivate any active powers, to ensure the vampire can experience the full force of being flung away at mach fuck + var/datum/antagonist/vampire/vampire_datum = IS_VAMPIRE(target) + vampire_datum.disable_all_powers(forced = TRUE) + // they lose 25% of their current vitae too + vampire_datum.adjust_blood_volume(-vampire_datum.current_vitae * 0.25) + + // ensure they're not buckled to anything, you are NOT escaping this bullshit + user.buckled?.unbuckle_mob(user, force = TRUE) + target.buckled?.unbuckle_mob(target, force = TRUE) + + playsound(user, 'tff_modular/modules/vampire/sound/rage_increase.ogg', vol = 100, vary = FALSE, pressure_affected = FALSE) + + flash_color(user.client, LIGHT_COLOR_BLOOD_MAGIC, 2 SECONDS) + flash_color(target.client, LIGHT_COLOR_BLOOD_MAGIC, 2 SECONDS) + + // cultist gets a little bit of mercy to make it slightly more fair (they won't break an arm or something from the knockback) + ADD_TRAIT(user, TRAIT_NEVER_WOUNDED, REF(src)) + addtimer(TRAIT_CALLBACK_REMOVE(user, TRAIT_NEVER_WOUNDED, REF(src)), 2 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE) + + + var/turf/user_turf = get_turf(user) + var/turf/target_turf = get_turf(target) + + // CLASH! + user.blood_particles(10, get_angle(target, user)) + target.blood_particles(10, get_angle(user, target)) + + // this is gonna hurt for the both of them. + user.throw_at(get_edge_target_turf(user_turf, get_dir(target_turf, user_turf)), range = 200, speed = 5) + target.throw_at(get_edge_target_turf(target_turf, get_dir(user_turf, target_turf)), range = 200, speed = 5) + + // they're both a bit disoriented for a moment + target.set_confusion_if_lower(8 SECONDS) + target.set_eye_blur_if_lower(8 SECONDS) + user.set_confusion_if_lower(8 SECONDS) + user.set_eye_blur_if_lower(8 SECONDS) + +/obj/effect/temp_visual/sanguine_boom + icon = 'tff_modular/modules/vampire/icons/64x64.dmi' + icon_state = "sanguine_boom" + duration = 0.41 SECONDS + +// TFF ADDITION END //Teleportation /obj/item/melee/blood_magic/teleport name = "Teleporting Aura" diff --git a/code/modules/antagonists/heretic/influences.dm b/code/modules/antagonists/heretic/influences.dm index 6a42129f967..75330c7526e 100644 --- a/code/modules/antagonists/heretic/influences.dm +++ b/code/modules/antagonists/heretic/influences.dm @@ -157,7 +157,11 @@ . += span_hypnophrase(pick_list(HERETIC_INFLUENCE_FILE, "examine")) if(IS_HERETIC(user) || !ishuman(user)) return - + // TFF ADDITION START + var/datum/antagonist/vampire/vampire_datum = IS_VAMPIRE(user) + if(istype(vampire_datum?.my_clan, /datum/vampire_clan/malkavian)) + return + // TFF ADDITION END . += span_userdanger("Your mind burns as you stare at the tear!") user.adjust_organ_loss(ORGAN_SLOT_BRAIN, 10, 190) user.add_mood_event("gates_of_mansus", /datum/mood_event/gates_of_mansus) diff --git a/code/modules/client/client_colour.dm b/code/modules/client/client_colour.dm index bb4ad106f73..e8e2b1f899a 100644 --- a/code/modules/client/client_colour.dm +++ b/code/modules/client/client_colour.dm @@ -205,6 +205,12 @@ fade_in = 2 SECONDS fade_out = 2 SECONDS +// TFF ADDITION START +/datum/client_colour/glass_colour/pink + color = "#ffcfe9" + +// TFF ADDITION END + /datum/client_colour/monochrome/New(mob/owner) . = ..() if (owner) diff --git a/code/modules/logging/categories/log_category_uplink.dm b/code/modules/logging/categories/log_category_uplink.dm index 4ef0f1af0c0..847fed4dd94 100644 --- a/code/modules/logging/categories/log_category_uplink.dm +++ b/code/modules/logging/categories/log_category_uplink.dm @@ -26,3 +26,12 @@ category = LOG_CATEGORY_UPLINK_SPY config_flag = /datum/config_entry/flag/log_uplink master_category = /datum/log_category/uplink + +// TFF ADDITION START + +/datum/log_category/uplink_vampire + category = LOG_CATEGORY_UPLINK_VAMPIRE + config_flag = /datum/config_entry/flag/log_uplink + master_category = /datum/log_category/uplink + +// TFF ADDITION END diff --git a/code/modules/mob/living/basic/basic_defense.dm b/code/modules/mob/living/basic/basic_defense.dm index b4100a73cc1..73748381430 100644 --- a/code/modules/mob/living/basic/basic_defense.dm +++ b/code/modules/mob/living/basic/basic_defense.dm @@ -16,6 +16,7 @@ ) to_chat(user, span_notice("You [response_help_simple] [src].")) playsound(loc, 'sound/items/weapons/thudswoosh.ogg', 50, TRUE, -1) + SEND_SIGNAL(user, COMSIG_LIVING_PET_ANIMAL, src) // TFF ADDITION START return TRUE if(HAS_TRAIT(user, TRAIT_PACIFISM)) @@ -73,6 +74,7 @@ span_notice("[user.name] [response_help_continuous] you."), null, COMBAT_MESSAGE_RANGE, user) to_chat(user, span_notice("You [response_help_simple] [src].")) playsound(loc, 'sound/items/weapons/thudswoosh.ogg', 50, TRUE, -1) + SEND_SIGNAL(user, COMSIG_LIVING_PET_ANIMAL, src) /mob/living/basic/attack_alien(mob/living/carbon/alien/adult/user, list/modifiers) diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index 47857983c80..aa84fe31604 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -459,6 +459,7 @@ SEND_SIGNAL(src, COMSIG_CARBON_HELP_ACT, helper) SEND_SIGNAL(helper, COMSIG_CARBON_HELPED, src) + SEND_SIGNAL(helper, COMSIG_LIVING_HUG_CARBON, src) adjust_status_effects_on_shake_up() set_resting(FALSE) diff --git a/code/modules/mob/living/carbon/examine.dm b/code/modules/mob/living/carbon/examine.dm index b7464a63fca..e086e7577cc 100644 --- a/code/modules/mob/living/carbon/examine.dm +++ b/code/modules/mob/living/carbon/examine.dm @@ -8,8 +8,6 @@ /mob/living/carbon/examine(mob/user) if(HAS_TRAIT(src, TRAIT_UNKNOWN_APPEARANCE)) return list(span_warning("You're struggling to make out any details...")) - if(HAS_TRAIT(src, TRAIT_DISFIGURED) && IS_BLOODSUCKER(src)) - return list(span_warning("[src.p_They()] look[src.p_s()] like a pale, grotesque hunchback, with a mouth full of jagged yellowy teeth, and breath that reeks of fresh blood. You feel both afraid and disgusted as you gaze upon [src.p_them()]. [src.p_They()] [src.p_are()] clearly a MUTANT!")) var/t_He = p_They() var/t_His = p_Their() diff --git a/code/modules/mob/living/ventcrawling.dm b/code/modules/mob/living/ventcrawling.dm index db2ea5caee0..e53885fe3bd 100644 --- a/code/modules/mob/living/ventcrawling.dm +++ b/code/modules/mob/living/ventcrawling.dm @@ -23,11 +23,8 @@ if(!Adjacent(ventcrawl_target)) return - // TFF ADDITION START - VENTCRAWLING SIGNAL - var/signal_result = SEND_SIGNAL(src, COMSIG_CAN_VENTCRAWL, ventcrawl_target, provide_feedback) - if(!HAS_TRAIT(src, TRAIT_VENTCRAWLER_NUDE) && !HAS_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS) && !signal_result) + if(!HAS_TRAIT(src, TRAIT_VENTCRAWLER_NUDE) && !HAS_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS)) return - // TFF ADDITION END - VENTCRAWLING SIGNAL if(stat) if(provide_feedback) to_chat(src, span_warning("You must be conscious to do this!")) @@ -48,7 +45,7 @@ if(provide_feedback) to_chat(src, span_warning("You can't vent crawl while buckled!")) return - if(iscarbon(src) && required_nudity && !signal_result) // TFF CHANGE - VENTCRAWLING SIGNAL + if(iscarbon(src) && required_nudity) if(length(get_equipped_items(INCLUDE_POCKETS|INCLUDE_HELD))) if(provide_feedback) to_chat(src, span_warning("You can't crawl around in the ventilation ducts with items!")) @@ -77,16 +74,10 @@ //Handle the exit here if(HAS_TRAIT(src, TRAIT_MOVE_VENTCRAWLING) && istype(loc, /obj/machinery/atmospherics) && movement_type & VENTCRAWLING) - // TFF ADDITION START - VENTCRAWLING SIGNAL - var/exit_time = SEND_SIGNAL(src, COMSIG_VENTCRAWL_PRE_EXIT, ventcrawl_target) - if(!exit_time) - exit_time = 1 SECONDS - // TFF ADDITION END - VENTCRAWLING SIGNAL to_chat(src, span_notice("You begin climbing out from the ventilation system...")) if(has_client && isnull(client)) return - if(!do_after(src, exit_time, target = ventcrawl_target)) // TFF CHANGE - VENTCRAWLING SIGNAL - SEND_SIGNAL(src, COMSIG_VENTCRAWL_PRE_CANCEL, ventcrawl_target) // TFF ADDITION - VENTCRAWLING SIGNAL + if(!do_after(src, 1 SECONDS, target = ventcrawl_target)) return if(ventcrawl_target.welded) // in case it got welded during our sleep to_chat(src, span_warning("You can't crawl around a welded vent!")) @@ -95,21 +86,15 @@ forceMove(ventcrawl_target.loc) REMOVE_TRAIT(src, TRAIT_MOVE_VENTCRAWLING, VENTCRAWLING_TRAIT) update_pipe_vision() - SEND_SIGNAL(src, COMSIG_VENTCRAWL_EXIT, ventcrawl_target) // TFF ADDITION - VENTCRAWLING SIGNAL //Entrance here else var/datum/pipeline/vent_parent = ventcrawl_target.parents[1] if(vent_parent && (vent_parent.members.len || vent_parent.other_atmos_machines)) - // TFF ADDITION START - VENTCRAWLING SIGNAL - var/enter_time = SEND_SIGNAL(src, COMSIG_VENTCRAWL_PRE_ENTER, ventcrawl_target) - if(!enter_time) - enter_time = 2.5 SECONDS // Default time if the signal doesn't return anything - // TFF ADDITION END - VENTCRAWLING SIGNAL ventcrawl_target.flick_overlay_static(image('icons/effects/vent_indicator.dmi', "arrow", ABOVE_MOB_LAYER, dir = get_dir(src.loc, ventcrawl_target.loc)), 2 SECONDS) visible_message(span_notice("[src] begins climbing into the ventilation system...") ,span_notice("You begin climbing into the ventilation system...")) - if(!do_after(src, enter_time, target = ventcrawl_target, extra_checks = CALLBACK(src, PROC_REF(can_enter_vent), ventcrawl_target))) // TFF CHANGE - VENTCRAWLING SIGNAL - SEND_SIGNAL(src, COMSIG_VENTCRAWL_PRE_CANCEL, ventcrawl_target) // TFF ADDITION - VENTCRAWLING SIGNAL + if(!do_after(src, 2.5 SECONDS, target = ventcrawl_target, extra_checks = CALLBACK(src, PROC_REF(can_enter_vent), ventcrawl_target))) + return if(has_client && isnull(client)) return if(ventcrawl_target.welded) // in case it got welded during our sleep @@ -118,7 +103,6 @@ ventcrawl_target.flick_overlay_static(image('icons/effects/vent_indicator.dmi', "insert", ABOVE_MOB_LAYER), 1 SECONDS) visible_message(span_notice("[src] scrambles into the ventilation ducts!"), span_notice("You climb into the ventilation ducts.")) move_into_vent(ventcrawl_target) - SEND_SIGNAL(src, COMSIG_VENTCRAWL_ENTER, ventcrawl_target) // TFF ADDITION - VENTCRAWLING SIGNAL else to_chat(src, span_warning("This ventilation duct is not connected to anything!")) diff --git a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm index 5b08cd876c3..3147c1ddaa9 100644 --- a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm +++ b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm @@ -718,6 +718,10 @@ linked_alert.icon_state = "slime_bluespace_on" if(healthcheck && (healthcheck - owner.health) > 5) + // TFF ADDITION START + if(HAS_TRAIT(owner, TRAIT_FAKEDEATH) && owner.health > owner.crit_threshold) + return ..() + // TFF ADDITION END owner.visible_message(span_warning("[linked_extract] notices the sudden change in [owner]'s physical health, and activates!")) do_sparks(5,FALSE,owner) var/turf/emergency_turf = find_safe_turf(owner.z, extended_safety_checks = TRUE) diff --git a/code/modules/surgery/organs/organ_movement.dm b/code/modules/surgery/organs/organ_movement.dm index 07bcf4baecb..0dc77fd0c35 100644 --- a/code/modules/surgery/organs/organ_movement.dm +++ b/code/modules/surgery/organs/organ_movement.dm @@ -244,7 +244,6 @@ item_flags &= ~ABSTRACT REMOVE_TRAIT(src, TRAIT_NODROP, ORGAN_INSIDE_BODY_TRAIT) - SEND_SIGNAL(src, COMSIG_ORGAN_BODYPART_REMOVED, limb, movement_flags) // TFF ADDITION, added COMSIG_ORGAN_BODYPART_REMOVED to on_bodypart_remove limb.owner?.synchronize_bodytypes() limb.owner?.synchronize_bodyshapes() diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/assets.dm b/tff_modular/modules/bloodsucker/bloodsuckers/assets.dm deleted file mode 100644 index 916f7b579e8..00000000000 --- a/tff_modular/modules/bloodsucker/bloodsuckers/assets.dm +++ /dev/null @@ -1,15 +0,0 @@ -/datum/asset/simple/bloodsucker_icons - -/datum/asset/simple/bloodsucker_icons/register() - for(var/datum/bloodsucker_clan/clans as anything in typesof(/datum/bloodsucker_clan)) - if(!initial(clans.joinable_clan)) - continue - add_bloodsucker_icon(initial(clans.join_icon), initial(clans.join_icon_state)) - - for(var/datum/action/cooldown/bloodsucker/power as anything in subtypesof(/datum/action/cooldown/bloodsucker)) - add_bloodsucker_icon(initial(power.button_icon), initial(power.button_icon_state)) - - return ..() - -/datum/asset/simple/bloodsucker_icons/proc/add_bloodsucker_icon(bloodsucker_icon, bloodsucker_icon_state) - assets[SANITIZE_FILENAME("bloodsucker.[bloodsucker_icon_state].png")] = icon(bloodsucker_icon, bloodsucker_icon_state) diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm b/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm deleted file mode 100644 index f70f17b1e5f..00000000000 --- a/tff_modular/modules/bloodsucker/bloodsuckers/bloodsucker.dm +++ /dev/null @@ -1,648 +0,0 @@ -/datum/antagonist/bloodsucker - name = "\improper Bloodsucker" - show_in_antagpanel = TRUE - roundend_category = "bloodsuckers" - antagpanel_category = "Bloodsucker" - pref_flag = ROLE_BLOODSUCKER - antag_hud_name = "bloodsucker" - show_name_in_check_antagonists = TRUE - hijack_speed = 0.5 - hud_icon = 'tff_modular/modules/bloodsucker/icons/antag_hud.dmi' - ui_name = "AntagInfoBloodsucker" - preview_outfit = /datum/outfit/bloodsucker_outfit - - /// How much blood we have, starting off at default blood levels. Do not adjust this directly, use adjustBloodVolume(), and use getBloodVolume() to get the current value. - VAR_PRIVATE/bloodsucker_blood_volume = BLOOD_VOLUME_NORMAL - /// How much blood we can have without it deckaying quickly, increases per level. - var/max_blood_volume = 600 - - var/datum/bloodsucker_clan/my_clan - - // TIMERS // - ///Timer between alerts for Burn messages - COOLDOWN_DECLARE(bloodsucker_spam_sol_burn) - ///Timer between alerts for Healing messages - COOLDOWN_DECLARE(bloodsucker_spam_healing) - /// Timer between exiting torpor - COOLDOWN_DECLARE(bloodsucker_spam_torpor) - - COOLDOWN_DECLARE(bloodsucker_torpor_max_time) - ///Used for assigning your name - var/bloodsucker_name - ///Used for assigning your title - var/bloodsucker_title - ///Used for assigning your reputation - var/bloodsucker_reputation - - ///Amount of Humanity lost, don't modify this directly, use AddHumanityLost(), and use GetHumanityLost() to get the current value. - VAR_PRIVATE/humanity_lost = 0 - ///Have we been broken the Masquerade? - var/broke_masquerade = FALSE - ///How many Masquerade Infractions do we have? - var/masquerade_infractions = 0 - ///If we are currently in a Frenzy - var/frenzied = FALSE - /// sired by a ventrue - var/ventrue_sired - - ///ALL Powers currently owned - var/list/datum/action/cooldown/bloodsucker/powers = list() - - ///Ghouls under my control. Periodically remove the dead ones. - var/list/datum/antagonist/ghoul/ghouls = list() - ///Special ghouls I own, to not have double of the same type. - var/list/datum/antagonist/ghoul/special_ghouls = list() - - ///How many ranks we have, don't modify this directly, use AdjustRank() and use GetRank() to get the current value. - VAR_PRIVATE/bloodsucker_level = 0 - /// Unspent ranks, don't modify this directly, use AdjustUnspentRank() and use GetUnspentRank() to get the current value. - VAR_PRIVATE/bloodsucker_level_unspent = 1 - var/additional_regen - var/blood_over_cap = 0 - var/bloodsucker_regen_rate = 0.4 - - // Used for Bloodsucker Objectives - var/area/bloodsucker_haven_area - var/obj/structure/closet/crate/coffin - var/total_blood_drank = 0 - - /// Used for Bloodsuckers gaining levels from drinking blood - var/blood_level_gain = 0 - /// How many levels you can get from Sol - var/sol_levels_remaining = 4 - - ///Blood display HUD - var/atom/movable/screen/bloodsucker/blood_counter/blood_display - ///Vampire level display HUD - var/atom/movable/screen/bloodsucker/rank_counter/vamprank_display - - /// Static typecache of all bloodsucker powers. - var/static/list/all_bloodsucker_powers = typecacheof(/datum/action/cooldown/bloodsucker, ignore_root_path = TRUE) - /// Antagonists that cannot be Ghouled no matter what - var/static/list/ghoul_banned_antags = list( - /datum/antagonist/bloodsucker, - /datum/antagonist/changeling, - /datum/antagonist/cult, - ) - ///Default Bloodsucker traits - var/static/list/bloodsucker_traits = list( - TRAIT_NOBREATH, - TRAIT_SLEEPIMMUNE, - TRAIT_GENELESS, - TRAIT_NOCRITDAMAGE, - TRAIT_RESISTCOLD, - TRAIT_RADIMMUNE, - TRAIT_STABLEHEART, - TRAIT_NOSOFTCRIT, - TRAIT_NOHARDCRIT, - TRAIT_AGEUSIA, - TRAIT_COLDBLOODED, - TRAIT_VIRUSIMMUNE, - TRAIT_NO_MIRROR_REFLECTION, - TRAIT_DRINKS_BLOOD, - TRAIT_TOXIMMUNE, - // Fun fact, toxins can still be applied to you if you loose your liver even with TOXIMMUNE - TRAIT_STABLELIVER - ) - var/static/biotype = MOB_VAMPIRIC - - var/static/list/torpor_traits = list( - TRAIT_DEATHCOMA, - TRAIT_FAKEDEATH, - TRAIT_NODEATH, - TRAIT_RESISTHIGHPRESSURE, - TRAIT_RESISTLOWPRESSURE, - ) - - var/list/body_signals = list( - COMSIG_ATOM_EXAMINE = PROC_REF(on_examine), - COMSIG_LIVING_LIFE = PROC_REF(LifeTick), - COMSIG_LIVING_DEATH = PROC_REF(on_death), - COMSIG_SPECIES_GAIN = PROC_REF(on_species_gain), - COMSIG_QDELETING = PROC_REF(on_owner_deletion), - COMSIG_ENTER_COFFIN = PROC_REF(on_enter_coffin), - COMSIG_MOB_STAKED = PROC_REF(on_staked), - COMSIG_CARBON_LOSE_ORGAN = PROC_REF(on_organ_removal), - COMSIG_HUMAN_ON_HANDLE_BLOOD = PROC_REF(HandleBlood), - ) - - var/prince = FALSE - var/scourge = FALSE - -/** - * Apply innate effects is everything given to the mob - * When a body is tranferred, this is called on the new mob - * while on_gain is called ONCE per ANTAG, this is called ONCE per BODY. - */ -/datum/antagonist/bloodsucker/apply_innate_effects(mob/living/mob_override) - . = ..() - var/mob/living/carbon/current_mob = mob_override || owner.current - register_body_signals(current_mob) - talking_head(current_mob) - handle_clown_mutation(current_mob, mob_override ? null : "As a bloodsucker clown, you are no longer a danger to yourself. Your clownish nature has been subdued by your thirst for blood.") - add_team_hud(current_mob) - RegisterSignal(SSsol, COMSIG_SOL_RANKUP_BLOODSUCKERS, PROC_REF(sol_rank_up)) - if(current_mob.hud_used) - on_hud_created() - else - RegisterSignal(current_mob, COMSIG_MOB_HUD_CREATED, PROC_REF(on_hud_created)) - if(ishuman(current_mob)) - current_mob?.dna?.species.on_bloodsucker_gain(current_mob) -#ifdef BLOODSUCKER_TESTING - var/turf/user_loc = get_turf(current_mob) - new /obj/structure/closet/crate/coffin(user_loc) - new /obj/structure/bloodsucker/ghoulrack(user_loc) -#endif - -/** - * Remove innate effects is everything given to the mob - * When a body is transferred, this is called on the old mob. - * while on_removal is called ONCE per ANTAG, this is called ONCE per BODY. - */ -/datum/antagonist/bloodsucker/remove_innate_effects(mob/living/mob_override) - . = ..() - var/mob/living/carbon/current_mob = mob_override || owner.current - UnregisterSignal(SSsol, COMSIG_SOL_RANKUP_BLOODSUCKERS) - unregister_body_signals(current_mob) - handle_clown_mutation(current_mob, removing = FALSE) - if(current_mob.hud_used) - var/datum/hud/hud_used = current_mob.hud_used - hud_used.infodisplay -= blood_display - hud_used.infodisplay -= vamprank_display - QDEL_NULL(blood_display) - QDEL_NULL(vamprank_display) - - if(iscarbon(current_mob)) - current_mob?.dna.species.on_bloodsucker_loss(current_mob) - -/datum/antagonist/bloodsucker/proc/on_hud_created(datum/source) - SIGNAL_HANDLER - var/datum/hud/bloodsucker_hud = owner.current.hud_used - - blood_display = new(null, bloodsucker_hud) - bloodsucker_hud.infodisplay += blood_display - - vamprank_display = new(null, bloodsucker_hud) - bloodsucker_hud.infodisplay += vamprank_display - - bloodsucker_hud.show_hud(bloodsucker_hud.hud_version) - UnregisterSignal(owner.current, COMSIG_MOB_HUD_CREATED) - update_blood_hud() - update_rank_hud() - -/// Override some properties of incompatible species -/datum/antagonist/bloodsucker/proc/on_species_gain(mob/living/carbon/human/target, datum/species/current_species, datum/species/old_species) - SIGNAL_HANDLER - if(!ishuman(owner.current)) - return - var/mob/living/carbon/human/user = owner.current - user?.dna?.species.on_bloodsucker_gain(target) - -/datum/antagonist/bloodsucker/get_admin_commands() - . = ..() - .["Set blood level"] = CALLBACK(src, PROC_REF(admin_set_blood)) - .["Give Level"] = CALLBACK(src, PROC_REF(admin_rankup)) - // I know admins can technically do it via VV's dropdown, but it's super inconvenient. - .["Give Power"] = CALLBACK(src, PROC_REF(admin_give_power)) - .["Remove Power"] = CALLBACK(src, PROC_REF(admin_remove_power)) - .["Set Power Level"] = CALLBACK(src, PROC_REF(admin_set_power_level)) - if(bloodsucker_level_unspent >= 1) - .["Remove Level"] = CALLBACK(src, PROC_REF(RankDown)) - - if(broke_masquerade) - .["Fix Masquerade"] = CALLBACK(src, PROC_REF(fix_masquerade)) - else - .["Break Masquerade"] = CALLBACK(src, PROC_REF(break_masquerade)) - - if(my_clan) - .["Remove Clan"] = CALLBACK(src, PROC_REF(remove_clan)) - else - .["Add Clan"] = CALLBACK(src, PROC_REF(admin_set_clan)) - -///Called when you get the antag datum, called only ONCE per antagonist. -/datum/antagonist/bloodsucker/on_gain() - if(!owner?.current) - return ..() - if(ventrue_sired) // sired bloodsuckers shouldnt be getting the same benefits as roundstart Bloodsuckers. - bloodsucker_level_unspent = 1 - else - // Start Sunlight if first Bloodsucker - // Name and Titles - SelectFirstName() - SelectTitle(am_fledgling = TRUE) - SelectReputation(am_fledgling = TRUE) - // Objectives - forge_bloodsucker_objectives() - - . = ..() - // Assign Powers - give_starting_powers() - assign_starting_stats() - check_start_society() - check_start_sunlight() - GLOB.all_vampires += src - -/// Called by the remove_antag_datum() and remove_all_antag_datums() mind procs for the antag datum to handle its own removal and deletion. -/datum/antagonist/bloodsucker/on_removal() - free_all_ghouls() - if(!owner?.current) - return - if(is_head(owner.current)) - cleanup_talking_head() - if(ishuman(owner.current)) - var/mob/living/carbon/human/user = owner.current - user?.dna?.species.regenerate_organs(user, null, TRUE) - clear_powers_and_stats() - ventrue_sired = null - coffin?.unclaim_coffin(FALSE, TRUE) - GLOB.all_vampires -= src - return ..() - -/datum/antagonist/bloodsucker/add_team_hud(mob/target, antag_to_check) - if(broke_masquerade) - antag_hud_name = "masquerade_broken" - else if(scourge) - antag_hud_name = "scourge" - else if(prince) - antag_hud_name = "prince" - else - antag_hud_name = "bloodsucker" - - QDEL_NULL(team_hud_ref) - - var/datum/atom_hud/alternate_appearance/basic/has_antagonist/hud = target.add_alt_appearance( - /datum/atom_hud/alternate_appearance/basic/has_antagonist, - "antag_team_hud_[REF(src)]", - hud_image_on(target), - ) - team_hud_ref = WEAKREF(hud) - - var/list/mob/living/mob_list = list() - for(var/datum/antagonist/antag as anything in GLOB.antagonists) - if(!istype(antag, /datum/antagonist/bloodsucker) && !istype(antag, /datum/antagonist/ghoul)) - continue - var/mob/living/current = antag.owner?.current - if(!QDELETED(current)) - mob_list |= current - - for (var/datum/atom_hud/alternate_appearance/basic/has_antagonist/antag_hud as anything in GLOB.has_antagonist_huds) - if(!(antag_hud.target in mob_list)) - continue - antag_hud.show_to(target) - hud.show_to(antag_hud.target) - - -/datum/antagonist/bloodsucker/on_body_transfer(mob/living/old_body, mob/living/new_body) - . = ..() - if(!old_body || !new_body) - CRASH("Bloodsucker on_body_transfer called with null bodies!") - for(var/datum/action/cooldown/bloodsucker/all_powers as anything in powers) - if(old_body) - all_powers.Remove(old_body) - all_powers.Grant(new_body) - var/obj/item/bodypart/old_left_arm = old_body?.get_bodypart(BODY_ZONE_L_ARM) - var/obj/item/bodypart/old_right_arm = old_body?.get_bodypart(BODY_ZONE_R_ARM) - var/old_left_arm_unarmed_damage_low - var/old_left_arm_unarmed_damage_high - var/old_right_arm_unarmed_damage_low - var/old_right_arm_unarmed_damage_high - if(old_body && ishuman(old_body)) - var/mob/living/carbon/human/old_user = old_body - old_user.mob_biotypes &= ~biotype - //Keep track of what they were - old_left_arm_unarmed_damage_low = old_left_arm?.unarmed_damage_low - old_left_arm_unarmed_damage_high = old_left_arm?.unarmed_damage_high - old_right_arm_unarmed_damage_low = old_right_arm?.unarmed_damage_low - old_right_arm_unarmed_damage_high = old_right_arm?.unarmed_damage_high - //Then reset them - if(old_left_arm) - old_left_arm.unarmed_damage_low = initial(old_left_arm.unarmed_damage_low) - old_left_arm.unarmed_damage_high = initial(old_left_arm.unarmed_damage_high) - if(old_right_arm) - old_right_arm.unarmed_damage_low = initial(old_right_arm.unarmed_damage_low) - old_right_arm.unarmed_damage_high = initial(old_right_arm.unarmed_damage_high) - if(ishuman(new_body)) - var/mob/living/carbon/human/new_user = new_body - new_user.mob_biotypes |= biotype - var/obj/item/bodypart/new_left_arm - var/obj/item/bodypart/new_right_arm - //Give old punch damage values - new_left_arm = new_body?.get_bodypart(BODY_ZONE_L_ARM) - new_right_arm = new_body?.get_bodypart(BODY_ZONE_R_ARM) - if(old_left_arm) - new_left_arm.unarmed_damage_low = old_left_arm_unarmed_damage_low - new_left_arm.unarmed_damage_high = old_left_arm_unarmed_damage_high - if(old_right_arm) - new_right_arm.unarmed_damage_low = old_right_arm_unarmed_damage_low - new_right_arm.unarmed_damage_high = old_right_arm_unarmed_damage_high - - //Give Bloodsucker Traits - if(old_body) - old_body.remove_traits(bloodsucker_traits, BLOODSUCKER_TRAIT) - new_body.add_traits(bloodsucker_traits, BLOODSUCKER_TRAIT) - -/datum/antagonist/bloodsucker/greet() - . = ..() - var/fullname = return_full_name() - to_chat(owner, span_userdanger("You are [fullname], a strain of vampire known as a Bloodsucker!")) - owner.announce_objectives() - if(bloodsucker_level_unspent >= 2) - to_chat(owner, span_announce("As a latejoiner, you have [bloodsucker_level_unspent] bonus Ranks, entering your claimed coffin allows you to spend a Rank.")) - owner.current.playsound_local(null, 'tff_modular/modules/bloodsucker/sound/BloodsuckerAlert.ogg', 100, FALSE, pressure_affected = FALSE) - antag_memory += "Although you were born a mortal, in undeath you earned the name [fullname].
    " - -/datum/antagonist/bloodsucker/farewell() - to_chat(owner.current, span_userdanger("With a snap, your curse has ended. You are no longer a Bloodsucker. You live once more!")) - // Refill with Blood so they don't instantly die. - if(!HAS_TRAIT(owner.current, TRAIT_NOBLOOD)) - owner.current.blood_volume = max(owner.current.blood_volume, BLOOD_VOLUME_NORMAL) - -// Called when using admin tools to give antag status -/datum/antagonist/bloodsucker/admin_add(datum/mind/new_owner, mob/admin) - var/levels = tgui_input_number(admin, "How many unspent Ranks would you like [new_owner] to have?","Bloodsucker Rank", GetUnspentRank(), 100, 0) - var/msg = " made [key_name_admin(new_owner)] into \a [name]" - if(levels > 1) - bloodsucker_level_unspent = levels - msg += " with [levels] extra unspent Ranks." - message_admins("[key_name_admin(usr)][msg]") - log_admin("[key_name(usr)][msg]") - new_owner.add_antag_datum(src) - -/datum/antagonist/bloodsucker/get_preview_icon() - - var/icon/outfit_icon = render_preview_outfit(preview_outfit) - var/icon/blood_icon = icon('icons/effects/blood.dmi', "uniformblood") - blood_icon.Blend(BLOOD_COLOR_RED, ICON_MULTIPLY) - outfit_icon.Blend(blood_icon, ICON_OVERLAY) - - return finish_preview_icon(outfit_icon) - -/datum/antagonist/bloodsucker/ui_static_data(mob/user) - var/list/data = ability_ui_data(powers) - //we don't need to update this that much. - data["in_clan"] = !!my_clan - var/list/clan_data = list() - if(my_clan) - clan_data["clan_name"] = my_clan.name - clan_data["clan_description"] = my_clan.description - clan_data["clan_icon"] = my_clan.join_icon_state - - data["clan"] += list(clan_data) - - return data + ..() - -/datum/antagonist/bloodsucker/ui_assets(mob/user) - return list( - get_asset_datum(/datum/asset/simple/bloodsucker_icons), - ) - -/datum/antagonist/bloodsucker/ui_act(action, params, datum/tgui/ui) - . = ..() - if(.) - return - - switch(action) - if("join_clan") - if(my_clan) - return - assign_clan_and_bane() - if(ui.closing) - return - ui.send_full_update(force = TRUE) - -/datum/antagonist/bloodsucker/roundend_report() - var/list/report = list() - - // Vamp name - report += "
    \[[return_full_name()]\]" - report += printplayer(owner) - if(my_clan) - report += "They were part of the [my_clan.name]!" - - // Default Report - var/objectives_complete = TRUE - if(objectives.len) - report += printobjectives(objectives) - for(var/datum/objective/objective in objectives) - if(objective.objective_name == "Optional Objective") - continue - if(!objective.check_completion()) - objectives_complete = FALSE - break - - // Now list their ghouls - if(ghouls.len) - report += "Their Ghouls were..." - for(var/datum/antagonist/ghoul/all_ghouls as anything in ghouls) - if(!all_ghouls.owner) - continue - var/list/ghoul_report = list() - ghoul_report += "[all_ghouls.owner.name]" - - if(all_ghouls.owner.assigned_role) - ghoul_report += " the [all_ghouls.owner.assigned_role.title]" - if(IS_FAVORITE_GHOUL(all_ghouls.owner.current)) - ghoul_report += " and was the Favorite Ghoul" - else if(IS_REVENGE_GHOUL(all_ghouls.owner.current)) - ghoul_report += " and was the Revenge Ghoul" - report += ghoul_report.Join() - - if(objectives.len == 0 || objectives_complete) - report += "The [name] was successful!" - else - report += "The [name] has failed!" - - return report.Join("
    ") - -/datum/antagonist/bloodsucker/proc/give_starting_powers() - for(var/datum/action/cooldown/bloodsucker/all_powers as anything in all_bloodsucker_powers) - if(!(initial(all_powers.purchase_flags) & BLOODSUCKER_DEFAULT_POWER)) - continue - BuyPower(all_powers) - -/datum/antagonist/bloodsucker/proc/assign_starting_stats() - //Traits: Species - if(ishuman(owner.current)) - var/mob/living/carbon/human/user = owner.current - var/obj/item/bodypart/user_left_arm = user.get_bodypart(BODY_ZONE_L_ARM) - var/obj/item/bodypart/user_right_arm = user.get_bodypart(BODY_ZONE_R_ARM) - user.dna?.remove_all_mutations() - user_left_arm.unarmed_damage_low += 2 //lowest possible punch damage - 6 now - user_left_arm.unarmed_damage_high += 2 //highest possible punch damage - 11 - user_right_arm.unarmed_damage_low += 2 //lowest possible punch damage - 6 - user_right_arm.unarmed_damage_high += 2 //highest possible punch damage - 11 - user.mob_biotypes |= biotype - //Give Bloodsucker Traits - owner.current.add_traits(bloodsucker_traits, BLOODSUCKER_TRAIT) - //Clear Addictions - for(var/addiction_type in subtypesof(/datum/addiction)) - owner.current.mind.remove_addiction_points(addiction_type, MAX_ADDICTION_POINTS) - //No Skittish "People" allowed - if(HAS_TRAIT(owner.current, TRAIT_SKITTISH)) - REMOVE_TRAIT(owner.current, TRAIT_SKITTISH, ROUNDSTART_TRAIT) - // Tongue & Language - owner.current.grant_language(/datum/language/vampiric, ALL, LANGUAGE_MIND) - /// Clear Disabilities & Organs - heal_vampire_organs() - -/** - * ##clear_power_and_stats() - * - * Removes all Bloodsucker related Powers/Stats changes, setting them back to pre-Bloodsucker - * Order of steps and reason why: - * Remove clan - Clans like Nosferatu give Powers on removal, we have to make sure this is given before removing Powers. - * Powers - Remove all Powers, so things like Masquerade are off. - * Species traits, Traits, Language - Misc stuff, has no priority. - * Organs - At the bottom to ensure everything that changes them has reverted themselves already. - * Update Sight - Done after Eyes are regenerated. - */ -/datum/antagonist/bloodsucker/proc/clear_powers_and_stats() - // Remove clan first - // if(my_clan) - // QDEL_NULL(my_clan) - // Powers - for(var/datum/action/cooldown/bloodsucker/all_powers as anything in powers) - RemovePower(all_powers) - if(QDELETED(owner.current)) - return - /// Stats - if(ishuman(owner.current)) - var/mob/living/carbon/human/user = owner.current - user.mob_biotypes &= ~biotype - var/obj/item/bodypart/left_arm = user.get_bodypart(BODY_ZONE_L_ARM) - var/obj/item/bodypart/right_arm = user.get_bodypart(BODY_ZONE_R_ARM) - if(left_arm) - left_arm.unarmed_damage_low = initial(left_arm.unarmed_damage_low) - left_arm.unarmed_damage_high = initial(left_arm.unarmed_damage_high) - if(right_arm) - right_arm.unarmed_damage_low = initial(right_arm.unarmed_damage_low) - right_arm.unarmed_damage_high = initial(right_arm.unarmed_damage_high) - var/obj/item/bodypart/chest/target_chest = owner.current.get_bodypart(BODY_ZONE_CHEST) - if(target_chest && target_chest.bodypart_flags & BODYPART_UNREMOVABLE) - target_chest.bodypart_flags &= ~BODYPART_UNREMOVABLE - // Remove all bloodsucker traits - owner.current.remove_traits(bloodsucker_traits, BLOODSUCKER_TRAIT) - // Language - owner.current.remove_language(/datum/language/vampiric, ALL, LANGUAGE_MIND) - // Heart & Eyes - var/mob/living/carbon/user = owner.current - var/obj/item/organ/heart/newheart = owner.current.get_organ_slot(ORGAN_SLOT_HEART) - if(newheart) - newheart.Restart() - var/obj/item/organ/eyes/user_eyes = user.get_organ_slot(ORGAN_SLOT_EYES) - if(user_eyes) - user_eyes.flash_protect = initial(user_eyes.flash_protect) - user_eyes.color_cutoffs = initial(user_eyes.color_cutoffs) - user_eyes.sight_flags = initial(user_eyes.sight_flags) - user.update_sight() - -/// Name shown on antag list -/datum/antagonist/bloodsucker/antag_listing_name() - return ..() + "([return_full_name()])" - -/// Whatever interesting things happened to the antag admins should know about -/// Include additional information about antag in this part -/datum/antagonist/bloodsucker/antag_listing_status() - if(owner && !considered_alive(owner)) - return "Final Death" - return ..() - -/datum/antagonist/bloodsucker/proc/considered_alive(datum/mind/player_mind, enforce_human) - if(!player_mind?.current) // no owner.current means there is no body, thus we final-death'd - return FALSE - if(is_head(player_mind.current)) - return FALSE - if(am_staked()) - return FALSE - return TRUE - -/datum/antagonist/bloodsucker/proc/forge_bloodsucker_objectives() - // Claim a haven Objective - var/datum/objective/bloodsucker/haven/haven_objective = new - haven_objective.owner = owner - objectives += haven_objective - // Survive Objective - var/datum/objective/survive/bloodsucker/survive_objective = new - survive_objective.owner = owner - objectives += survive_objective - - // Objective 1: Ghoulize a Head/Command, or a specific target - switch(rand(1, 3)) - if(1) // Conversion Objective - var/datum/objective/bloodsucker/conversion/chosen_subtype = pick(subtypesof(/datum/objective/bloodsucker/conversion)) - var/datum/objective/bloodsucker/conversion/conversion_objective = new chosen_subtype - conversion_objective.owner = owner - conversion_objective.objective_name = "Optional Objective" - objectives += conversion_objective - if(2) // Heart Thief Objective - var/datum/objective/steal_n_of_type/hearts/heartthief_objective = new - heartthief_objective.owner = owner - heartthief_objective.objective_name = "Optional Objective" - objectives += heartthief_objective - if(3) // Drink Blood Objective - var/datum/objective/bloodsucker/gourmand/gourmand_objective = new - gourmand_objective.owner = owner - gourmand_objective.objective_name = "Optional Objective" - objectives += gourmand_objective - -/datum/mood_event/drankblood - description = "I have fed greedily from that which nourishes me.\n" - mood_change = 10 - timeout = 8 MINUTES - -/datum/mood_event/drankblood_bad - description = "I drank the blood of a lesser creature. Disgusting.\n" - mood_change = -4 - timeout = 3 MINUTES - -/datum/mood_event/drankblood_dead - description = "I drank dead blood. I am better than this.\n" - mood_change = -7 - timeout = 8 MINUTES - -/datum/mood_event/drankblood_synth - description = "I drank synthetic blood. What is wrong with me?\n" - mood_change = -7 - timeout = 8 MINUTES - -/datum/mood_event/drankkilled - description = "I fed off of a dead person. I feel... less human.\n" - mood_change = -15 - timeout = 10 MINUTES - -/datum/mood_event/madevamp - description = "A mortal has reached an apotheosis- undeath- by my own hand.\n" - mood_change = 15 - timeout = 20 MINUTES - -/datum/mood_event/coffinsleep - description = "I slept in a coffin during the day. I feel whole again.\n" - mood_change = 10 - timeout = 6 MINUTES - -/datum/mood_event/coffinsleep/quirk - mood_change = 4 - -/datum/mood_event/daylight_bad_sleep - description = "I slept poorly in a makeshift coffin during the day.\n" - mood_change = -3 - timeout = 6 MINUTES - -/datum/mood_event/daylight_sun_scorched - description = "I have been scorched by the unforgiving rays of the sun.\n" - mood_change = -6 - timeout = 6 MINUTES - -///Candelabrum's mood event to non Bloodsucker/Ghouls -/datum/mood_event/vampcandle - description = "Something is making your mind feel... loose.\n" - mood_change = -15 - timeout = 5 MINUTES - -/datum/mood_event/nosferatu_examined - mood_change = -10 - timeout = 5 MINUTES - -/datum/mood_event/nosferatu_examined/add_effects(target, level = 0) - description = span_danger("You feel a deep sense of revulsion at the sight of [target].") - mood_change = level * -5 diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/clans.dm b/tff_modular/modules/bloodsucker/bloodsuckers/clans.dm deleted file mode 100644 index c0ec95caf4e..00000000000 --- a/tff_modular/modules/bloodsucker/bloodsuckers/clans.dm +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Gives Bloodsuckers the ability to choose a Clan. - * If they are already in a Clan, or is in a Frenzy, they will not be able to do so. - * The arg is optional and should really only be an Admin setting a Clan for a player. - * If set however, it will give them the control of their Clan instead of the Bloodsucker. - * This is selected through a radial menu over the player's body, even when an Admin is setting it. - * Args: - * person_selecting - Mob override for stuff like Admins selecting someone's clan. - */ -/datum/antagonist/bloodsucker/proc/assign_clan_and_bane(mob/person_selecting) - if(my_clan) - return - if(owner.current.has_status_effect(/datum/status_effect/frenzy)) - return - if(!person_selecting) - person_selecting = owner.current - - var/list/options = list() - var/list/radial_display = list() - for(var/datum/bloodsucker_clan/all_clans as anything in typesof(/datum/bloodsucker_clan)) - if(!initial(all_clans.joinable_clan)) //flavortext only - continue - options[initial(all_clans.name)] = all_clans - - var/datum/radial_menu_choice/option = new - option.image = image(icon = initial(all_clans.join_icon), icon_state = initial(all_clans.join_icon_state)) - option.info = "[initial(all_clans.name)] - [span_boldnotice(initial(all_clans.join_description))]" - radial_display[initial(all_clans.name)] = option - var/anchor = get_turf(owner.current) == owner.current.loc ? owner.current : get_turf(owner.current) - var/require_near = person_selecting == owner.current ? TRUE : FALSE - var/chosen_clan = show_radial_menu(person_selecting, anchor, radial_display, require_near = require_near) - chosen_clan = options[chosen_clan] - if(QDELETED(src) || QDELETED(owner.current)) - return FALSE - if(!chosen_clan) - to_chat(person_selecting, span_announce("You choose to remain ignorant, for now.")) - return - my_clan = new chosen_clan(src) - -/datum/antagonist/bloodsucker/proc/remove_clan(mob/admin) - if(owner.current.has_status_effect(/datum/status_effect/frenzy)) - to_chat(admin, span_announce("Removing a Bloodsucker from a Clan while they are in a Frenzy will break stuff, this action has been blocked.")) - return - QDEL_NULL(my_clan) - to_chat(owner.current, span_announce("You have been forced out of your clan! You can re-enter one by regular means.")) - -/datum/antagonist/bloodsucker/proc/admin_set_clan(mob/admin) - assign_clan_and_bane(admin) diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/conversion.dm b/tff_modular/modules/bloodsucker/bloodsuckers/conversion.dm deleted file mode 100644 index ea896e695c4..00000000000 --- a/tff_modular/modules/bloodsucker/bloodsuckers/conversion.dm +++ /dev/null @@ -1,97 +0,0 @@ -/** - * Checks if the target has antag datums and, if so, - * are they allowed to be Ghouled, or not, or banned. - * Args: - * target - The person we check for antag datums. - */ -/datum/antagonist/bloodsucker/proc/AmValidAntag(mob/target) - if(HAS_TRAIT(target, TRAIT_UNCONVERTABLE)) - return GHOULING_BANNED - - var/ghouling_status = GHOULING_ALLOWED - for(var/datum/antagonist/antag_datum as anything in target.mind.antag_datums) - if(antag_datum.type in ghoul_banned_antags) - return GHOULING_BANNED - ghouling_status = GHOULING_DISLOYAL - return ghouling_status - -/** - * # can_make_ghoul - * Checks if the person is allowed to turn into the Bloodsucker's - * Ghoul, ensuring they are a player and valid. - * If they are a Ghoul themselves, will check if their master - * has broken the Masquerade, to steal them. - * Args: - * conversion_target - Person being ghouled - */ -/datum/antagonist/bloodsucker/proc/can_make_ghoul(mob/living/conversion_target) - if(!iscarbon(conversion_target) || (conversion_target.stat < CONSCIOUS)) - return FALSE - // No Mind! - if(!conversion_target.mind) - to_chat(owner.current, span_danger("[conversion_target] isn't self-aware enough to be made into a Ghoul.")) - return FALSE - if(AmValidAntag(conversion_target) == GHOULING_BANNED) - to_chat(owner.current, span_danger("[conversion_target] resists the power of your blood to dominate their mind!")) - return FALSE - var/mob/living/master = conversion_target.mind.enslaved_to?.resolve() - if(!master || (master == owner.current)) - return TRUE - var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(master) - if(bloodsuckerdatum && bloodsuckerdatum.broke_masquerade) - //ghoul stealing - return TRUE - to_chat(owner.current, span_danger("[conversion_target]'s mind is overwhelmed with too much external force to put your own!")) - return FALSE - -/** - * First will check if the target can be turned into a Ghoul, if so then it will - * turn them into one, log it, sync their minds, then updates the Rank - * Args: - * conversion_target - The person converted. - */ -/datum/antagonist/bloodsucker/proc/make_ghoul(mob/living/conversion_target) -#ifndef BLOODSUCKER_TESTING - if(!can_make_ghoul(conversion_target)) - return FALSE -#endif - //Check if they used to be a Ghoul and was stolen. - var/datum/antagonist/ghoul/old_ghoul = IS_GHOUL(conversion_target) - if(old_ghoul) - conversion_target.mind.remove_antag_datum(/datum/antagonist/ghoul) - - var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(owner.current) - bloodsuckerdatum.SelectTitle(am_fledgling = FALSE) - - //set the master, then give the datum. - var/datum/antagonist/ghoul/ghouldatum = new(conversion_target.mind) - ghouldatum.master = bloodsuckerdatum - conversion_target.mind.add_antag_datum(ghouldatum) - - message_admins("[conversion_target] has become a Ghoul, and is enslaved to [owner.current].") - log_admin("[conversion_target] has become a Ghoul, and is enslaved to [owner.current].") - return TRUE - -/* - * # can_make_special - * - * MIND Helper proc that ensures the person can be a Special Ghoul, - * without actually giving the antag datum to them. - * This is because Special Ghouls get special abilities, without the unique Bloodsucker blood tracking, - * and we don't want this to be infinite. - * Args: - * creator - Person attempting to convert them. - */ -/datum/mind/proc/can_make_special(datum/mind/creator) - return TRUE - -/// Check if this is a valid person to actually be a bloodsucker -/datum/mind/proc/valid_bloodsucker_candidate() - if(has_antag_datum(/datum/antagonist/bloodsucker)) - return FALSE - if(!(current.mob_biotypes & MOB_ORGANIC)) - return FALSE - // While the antag can function without the mob itself having no blood, it doesn't make sense. - if(HAS_TRAIT(src, TRAIT_NOBLOOD)) - return FALSE - return TRUE diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/crafts.dm b/tff_modular/modules/bloodsucker/bloodsuckers/crafts.dm deleted file mode 100644 index d69c19d79b2..00000000000 --- a/tff_modular/modules/bloodsucker/bloodsuckers/crafts.dm +++ /dev/null @@ -1,87 +0,0 @@ -/datum/crafting_recipe/blackcoffin - name = "Black Coffin" - result = /obj/structure/closet/crate/coffin/blackcoffin - tool_behaviors = list(TOOL_WELDER, TOOL_SCREWDRIVER) - reqs = list( - /obj/item/stack/sheet/cloth = 1, - /obj/item/stack/sheet/mineral/wood = 5, - /obj/item/stack/sheet/iron = 1, - ) - time = 15 SECONDS - category = CAT_FURNITURE - -//VAMPIRE STUFF - -/datum/crafting_recipe/securecoffin - name = "Secure Coffin" - result = /obj/structure/closet/crate/coffin/securecoffin - tool_behaviors = list(TOOL_WELDER, TOOL_SCREWDRIVER) - reqs = list( - /obj/item/stack/rods = 1, - /obj/item/stack/sheet/plasteel = 5, - /obj/item/stack/sheet/iron = 5, - ) - time = 15 SECONDS - category = CAT_FURNITURE - -/datum/crafting_recipe/meatcoffin - name = "Meat Coffin" - result = /obj/structure/closet/crate/coffin/meatcoffin - tool_behaviors = list(TOOL_KNIFE, TOOL_ROLLINGPIN) - reqs = list( - /obj/item/food/meat/slab = 5, - /obj/item/restraints/handcuffs/cable = 1, - ) - time = 15 SECONDS - category = CAT_FURNITURE - crafting_flags = parent_type::crafting_flags | CRAFT_MUST_BE_LEARNED - -/datum/crafting_recipe/metalcoffin - name = "Metal Coffin" - result = /obj/structure/closet/crate/coffin/metalcoffin - reqs = list( - /obj/item/stack/sheet/iron = 6, - /obj/item/stack/rods = 2, - ) - time = 10 SECONDS - category = CAT_FURNITURE - -/datum/crafting_recipe/ghoulrack - name = "Persuasion Rack" - result = /obj/structure/bloodsucker/ghoulrack - tool_behaviors = list(TOOL_WELDER, TOOL_WRENCH) - reqs = list( - /obj/item/stack/sheet/mineral/wood = 3, - /obj/item/stack/sheet/iron = 2, - /obj/item/restraints/handcuffs/cable = 2, - ) - time = 15 SECONDS - category = CAT_FURNITURE - crafting_flags = parent_type::crafting_flags | CRAFT_MUST_BE_LEARNED - -/datum/crafting_recipe/candelabrum - name = "Candelabrum" - result = /obj/structure/bloodsucker/candelabrum - tool_behaviors = list(TOOL_WELDER, TOOL_WRENCH) - reqs = list( - /obj/item/stack/sheet/iron = 3, - /obj/item/stack/rods = 1, - /obj/item/flashlight/flare/candle = 1, - ) - time = 10 SECONDS - category = CAT_FURNITURE - crafting_flags = parent_type::crafting_flags | CRAFT_MUST_BE_LEARNED - -/datum/crafting_recipe/bloodthrone - name = "Blood Throne" - result = /obj/structure/bloodsucker/bloodthrone - tool_behaviors = list(TOOL_WRENCH) - reqs = list( - /obj/item/stack/sheet/cloth = 3, - /obj/item/stack/sheet/iron = 5, - /obj/item/stack/sheet/mineral/wood = 1, - ) - time = 5 SECONDS - category = CAT_FURNITURE - crafting_flags = parent_type::crafting_flags | CRAFT_MUST_BE_LEARNED - diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/dynamic.dm b/tff_modular/modules/bloodsucker/bloodsuckers/dynamic.dm deleted file mode 100644 index 07df6543303..00000000000 --- a/tff_modular/modules/bloodsucker/bloodsuckers/dynamic.dm +++ /dev/null @@ -1,44 +0,0 @@ -////////////////////////////////////////////// -// // -// ROUNDSTART BLOODSUCKER // -// // -////////////////////////////////////////////// - -/datum/dynamic_ruleset/roundstart/bloodsucker - name = "bloodsuckers" - config_tag = "Roundstart Bloodsucker" - pref_flag = ROLE_BLOODSUCKER - preview_antag_datum = /datum/antagonist/bloodsucker - jobban_flag = ROLE_BLOODSUCKER - weight = 10 - max_antag_cap = 4 - -/datum/dynamic_ruleset/roundstart/bloodsucker/assign_role(datum/mind/candidate) - var/datum/antagonist/bloodsucker/suck_datum = candidate.add_antag_datum(/datum/antagonist/bloodsucker) - suck_datum.AdjustUnspentRank(rand(1,3)) - -////////////////////////////////////////////// -// // -// MIDROUND BLOODSUCKER // -// // -////////////////////////////////////////////// - -/datum/dynamic_ruleset/midround/from_living/bloodsucker - name = "Vampiric Accident" - config_tag = "Midround Bloodsucker" - preview_antag_datum = /datum/antagonist/bloodsucker - pref_flag = ROLE_VAMPIRICACCIDENT - jobban_flag = ROLE_BLOODSUCKER - midround_type = LIGHT_MIDROUND - weight = 10 - repeatable = TRUE - max_antag_cap = 4 - -/datum/dynamic_ruleset/midround/from_living/bloodsucker/is_valid_candidate(mob/candidate, client/candidate_client) - if(!is_station_level(candidate.z)) - return FALSE - return ..() - -/datum/dynamic_ruleset/midround/from_living/bloodsucker/assign_role(datum/mind/candidate) - var/datum/antagonist/bloodsucker/suck_datum = candidate.add_antag_datum(/datum/antagonist/bloodsucker) - suck_datum.AdjustUnspentRank(rand(1,3)) diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/hud.dm b/tff_modular/modules/bloodsucker/bloodsuckers/hud.dm deleted file mode 100644 index f3c3038089e..00000000000 --- a/tff_modular/modules/bloodsucker/bloodsuckers/hud.dm +++ /dev/null @@ -1,101 +0,0 @@ -/// 1 tile down -#define UI_BLOOD_DISPLAY "WEST:6,CENTER-1:0" -/// 2 tiles down -#define UI_VAMPRANK_DISPLAY "WEST:6,CENTER-2:-5" -/// 6 pixels to the right, zero tiles & 5 pixels DOWN. -#define UI_SUNLIGHT_DISPLAY "WEST:6,CENTER-0:0" - -///Maptext define for Bloodsucker HUDs -#define FORMAT_BLOODSUCKER_HUD_TEXT(valuecolor, value) MAPTEXT("
    [round(value,1)]
    ") -///Maptext define for Bloodsucker Sunlight HUDs -#define FORMAT_BLOODSUCKER_SUNLIGHT_TEXT(valuecolor, value) MAPTEXT("
    [value]
    ") - -/atom/movable/screen/bloodsucker - icon = 'tff_modular/modules/bloodsucker/icons/bloodsucker.dmi' - -/atom/movable/screen/bloodsucker/blood_counter - name = "Blood Consumed" - icon_state = "blood_display" - screen_loc = UI_BLOOD_DISPLAY - -/atom/movable/screen/bloodsucker/blood_counter/proc/update_blood_hud(blood_volume) - maptext = FORMAT_BLOODSUCKER_HUD_TEXT(hud_text_color(), blood_volume) - -/atom/movable/screen/bloodsucker/rank_counter - name = "Bloodsucker Rank" - icon_state = "rank" - screen_loc = UI_VAMPRANK_DISPLAY - -/atom/movable/screen/bloodsucker/rank_counter/proc/update_rank_hud(level = 0, unspent_level = 0, blood_volume = 0) - if(unspent_level > 0) - icon_state = "[initial(icon_state)]_up" - else - icon_state = initial(icon_state) - maptext = FORMAT_BLOODSUCKER_HUD_TEXT(hud_text_color(), level) - -/* -/atom/movable/screen/bloodsucker/sunlight_counter - name = "Solar Flare Timer" - icon_state = "sunlight" - screen_loc = UI_SUNLIGHT_DISPLAY - -/atom/movable/screen/bloodsucker/sunlight_counter/Initialize(mapload, datum/hud/hud_owner) - . = ..() - update_sol_hud() - START_PROCESSING(SSsunlight, src) - -/atom/movable/screen/bloodsucker/sunlight_counter/Destroy() - STOP_PROCESSING(SSsunlight, src) - . = ..() - -/atom/movable/screen/bloodsucker/sunlight_counter/proc/update_sol_hud() - var/valuecolor = hud_text_color() - if(!SSsunlight) - return - if(SSsunlight.sunlight_active) - valuecolor = "#FF5555" - icon_state = "[initial(icon_state)]_day" - else - switch(round(SSsunlight.time_til_cycle, 1)) - if(0 to 30) - icon_state = "[initial(icon_state)]_30" - valuecolor = "#FFCCCC" - if(31 to 60) - icon_state = "[initial(icon_state)]_60" - valuecolor = "#FFE6CC" - if(61 to 90) - icon_state = "[initial(icon_state)]_90" - valuecolor = "#FFFFCC" - else - icon_state = "[initial(icon_state)]_night" - valuecolor = "#FFFFFF" - maptext = FORMAT_BLOODSUCKER_SUNLIGHT_TEXT( \ - valuecolor, \ - (SSsunlight.time_til_cycle >= 60) ? "[round(SSsunlight.time_til_cycle / 60, 1)] m" : "[round(SSsunlight.time_til_cycle, 1)] s" \ - ) - -/atom/movable/screen/bloodsucker/sunlight_counter/process(seconds_per_tick) - update_sol_hud() -*/ - -/atom/movable/screen/bloodsucker/proc/hud_text_color(blood_volume) - return blood_volume > BLOOD_VOLUME_SAFE ? "#FFDDDD" : "#FFAAAA" - -/// Updated every time blood is changed by either -/datum/antagonist/bloodsucker/proc/update_blood_hud() - blood_display?.update_blood_hud(bloodsucker_blood_volume) - -/datum/antagonist/bloodsucker/proc/update_rank_hud() - vamprank_display?.update_rank_hud(bloodsucker_level, bloodsucker_level_unspent, bloodsucker_blood_volume) - -/// 1 tile down -#undef UI_BLOOD_DISPLAY -/// 2 tiles down -#undef UI_VAMPRANK_DISPLAY -/// 6 pixels to the right, zero tiles & 5 pixels DOWN. -#undef UI_SUNLIGHT_DISPLAY - -///Maptext define for Bloodsucker HUDs -#undef FORMAT_BLOODSUCKER_HUD_TEXT -///Maptext define for Bloodsucker Sunlight HUDs -#undef FORMAT_BLOODSUCKER_SUNLIGHT_TEXT diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/integration.dm b/tff_modular/modules/bloodsucker/bloodsuckers/integration.dm deleted file mode 100644 index f6efc281f77..00000000000 --- a/tff_modular/modules/bloodsucker/bloodsuckers/integration.dm +++ /dev/null @@ -1,120 +0,0 @@ - -// this suggests that your heart is beating, when it is not -/mob/living/carbon/bleed_warn(bleed_amt = 0, forced = FALSE) - if(mind && IS_BLOODSUCKER(src) && !HAS_TRAIT(src, TRAIT_MASQUERADE)) - return - . = ..() - -/datum/reagent/blood/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message=TRUE, touch_protection=0) - var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(exposed_mob) - if(!bloodsuckerdatum) - return ..() - if(!(methods & (INJECT|INGEST))) - return ..() - - if(bloodsuckerdatum.my_clan && istype(bloodsuckerdatum.my_clan, /datum/bloodsucker_clan/ventrue) && bloodsuckerdatum.GetBloodVolume() >= BLOOD_VOLUME_SAFE) - return ..() - if(bloodsuckerdatum.GetBloodVolume() >= BLOOD_VOLUME_NORMAL) - return ..() - bloodsuckerdatum.AdjustBloodVolume(round(reac_volume, 0.1)) - -/mob/living/carbon/transfer_blood_to(atom/movable/receiver, amount, ignore_low_blood = FALSE, ignore_incompatibility = FALSE, transfer_viruses = TRUE) - . = ..() - if(!mind) - return - var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(src) - if(!bloodsuckerdatum) - return - bloodsuckerdatum.AdjustBloodVolume(-amount) - -// Prevents using a Memento Mori -// todo move this to it's own trait -/obj/item/clothing/neck/necklace/memento_mori/memento(mob/living/carbon/human/user) - if(IS_BLOODSUCKER(user)) - to_chat(user, span_warning("The Memento notices your undead soul, and refuses to react..")) - return - return ..() - -/mob/living/carbon/human/natural_bodytemperature_stabilization(datum/gas_mixture/environment, seconds_per_tick, times_fired) - // Return 0 as your natural temperature. Species proc handle_environment() will adjust your temperature based on this. - if(HAS_TRAIT(src, TRAIT_COLDBLOODED)) - return 0 - return ..() - -// Used when analyzing a Bloodsucker, Masquerade will hide brain traumas -/// todo move this to it's own trait or something -/mob/living/carbon/get_traumas() - if(!mind) - return ..() - var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(src) - if(bloodsuckerdatum && HAS_TRAIT(src, TRAIT_MASQUERADE)) - return - return ..() - -// Used to keep track of how much Blood we've drank so far -/mob/living/get_status_tab_items() - . = ..() - if(!mind) - return ..() - var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(src) - if(bloodsuckerdatum) - . += "" - . += "Blood Drank: [bloodsuckerdatum.total_blood_drank]" - . += "Maximum blood: [bloodsuckerdatum.max_blood_volume]" - . += "Blood Thickening: [bloodsuckerdatum.blood_level_gain] / [bloodsuckerdatum.get_level_cost()]" - if(bloodsuckerdatum.sol_levels_remaining > 0) - . += "Time until rank up: [SSsol.time_til_cycle] seconds" - if(bloodsuckerdatum.frenzied) - . += "Frenzy exit blood threshold: [bloodsuckerdatum.frenzy_exit_threshold()]" - else - . += "Frenzy blood threshold: [bloodsuckerdatum.frenzy_enter_threshold()]" - -/datum/outfit/bloodsucker_outfit - name = "Bloodsucker outfit (Preview only)" - suit = /obj/item/clothing/suit/costume/dracula - -/datum/outfit/bloodsucker_outfit/post_equip(mob/living/carbon/human/enrico, visualsOnly=FALSE) - enrico.hairstyle = "Undercut" - enrico.hair_color = "FFF" - enrico.skin_tone = "african2" - enrico.eye_color_left = "#663300" - enrico.eye_color_right = "#663300" - - enrico.update_body(is_creating = TRUE) - - -/** - * CARBON INTEGRATION -* -* All overrides of mob/living and mob/living/carbon -*/ -/// Brute -/mob/living/proc/get_brute_loss_nonProsthetic() - return get_brute_loss() - -/mob/living/carbon/get_brute_loss_nonProsthetic() - var/amount = 0 - for(var/obj/item/bodypart/chosen_bodypart as anything in bodyparts) - if(!IS_ORGANIC_LIMB(chosen_bodypart)) - continue - amount += chosen_bodypart.brute_dam - return amount - -/// Burn -/mob/living/proc/get_fire_loss_nonProsthetic() - return get_fire_loss() - -/mob/living/carbon/get_fire_loss_nonProsthetic() - var/amount = 0 - for(var/obj/item/bodypart/chosen_bodypart as anything in bodyparts) - if(!IS_ORGANIC_LIMB(chosen_bodypart)) - continue - amount += chosen_bodypart.burn_dam - return amount - -/mob/living/brain/can_be_revived() - if(health <= HEALTH_THRESHOLD_DEAD) - return FALSE - if(IS_BLOODSUCKER(src)) - return TRUE - . =..() diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/life.dm b/tff_modular/modules/bloodsucker/bloodsuckers/life.dm deleted file mode 100644 index 2dca18af946..00000000000 --- a/tff_modular/modules/bloodsucker/bloodsuckers/life.dm +++ /dev/null @@ -1,491 +0,0 @@ -///How much Blood it costs to live. -#define BLOODSUCKER_PASSIVE_BLOOD_DRAIN 0.1 - -/// Runs from COMSIG_LIVING_LIFE, handles Bloodsucker constant proccesses. -/datum/antagonist/bloodsucker/proc/LifeTick(mob/living/source, seconds_per_tick, times_fired) - SIGNAL_HANDLER - if(QDELETED(owner) || QDELETED(owner.current)) - INVOKE_ASYNC(src, PROC_REF(HandleDeath)) - return - life_always() - var/is_head = is_head(owner.current) - if(!is_head && owner.current.get_organ_slot(ORGAN_SLOT_HEART) && !am_staked()) - INVOKE_ASYNC(src, PROC_REF(life_active), is_head) - - SEND_SIGNAL(src, COMSIG_BLOODSUCKER_ON_LIFETICK, seconds_per_tick, times_fired) - -/datum/antagonist/bloodsucker/proc/life_always(is_head = FALSE) - if(is_in_torpor()) - check_end_torpor() - if(is_head) - return - if(owner.current.stat == CONSCIOUS && !HAS_TRAIT(owner.current, TRAIT_IMMOBILIZED) && !is_in_torpor()) - INVOKE_ASYNC(src, PROC_REF(AdjustBloodVolume), -BLOODSUCKER_PASSIVE_BLOOD_DRAIN) // -.1 currently - -/datum/antagonist/bloodsucker/proc/life_active() - if(HandleHealing()) - if((COOLDOWN_FINISHED(src, bloodsucker_spam_healing)) && bloodsucker_blood_volume > 0) - to_chat(owner.current, span_notice("The power of your blood begins knitting your wounds...")) - COOLDOWN_START(src, bloodsucker_spam_healing, BLOODSUCKER_SPAM_HEALING) - -/datum/antagonist/bloodsucker/proc/on_death(mob/living/source, gibbed) - SIGNAL_HANDLER - RegisterSignal(owner.current, COMSIG_LIVING_REVIVE, PROC_REF(on_revive)) - RegisterSignal(src, COMSIG_BLOODSUCKER_ON_LIFETICK, PROC_REF(HandleDeath)) - -/datum/antagonist/bloodsucker/proc/on_revive(mob/living/source) - SIGNAL_HANDLER - UnregisterSignal(owner.current, COMSIG_LIVING_REVIVE) - UnregisterSignal(src, COMSIG_BLOODSUCKER_ON_LIFETICK) - -/** - * ## BLOOD STUFF - */ - -/datum/antagonist/bloodsucker/proc/GetBloodVolume() - return bloodsucker_blood_volume - -/datum/antagonist/bloodsucker/proc/AdjustBloodVolume(value) - bloodsucker_blood_volume = clamp(bloodsucker_blood_volume + value, 0, max_blood_volume * 2) - blood_over_cap = max(bloodsucker_blood_volume - max_blood_volume, 0) // Gets how much blood we have over the cap. - update_blood_hud() - -/datum/antagonist/bloodsucker/proc/SetBloodVolume(value) - bloodsucker_blood_volume = clamp(value, 0, max_blood_volume) - update_blood_hud() - -#define MASQUERADE /datum/action/cooldown/bloodsucker/masquerade - -/datum/antagonist/bloodsucker/proc/GetHumanityLost() - return humanity_lost - -/datum/antagonist/bloodsucker/proc/AddHumanityLost(value) - if(value == 0) - return - var/has_masq = is_path_in_list(MASQUERADE, powers) - if(value + humanity_lost >= HUMANITY_LOST_MAXIMUM) - if(has_masq) - RemovePowerByPath(MASQUERADE) - to_chat(owner.current, span_warning("You hit the maximum amount of lost Humanty, you are far from Human. You've forgotten how to pretend to be like your prey...")) - else - to_chat(owner.current, span_hypnophrase("The Beast, it yearns for Blood...")) - else if(!has_masq) - BuyPower(MASQUERADE) - to_chat(owner.current, span_hypnophrase("You've remembered, yet again, how it feels to live again.")) - humanity_lost = clamp(value, 0, HUMANITY_LOST_MAXIMUM) - to_chat(owner.current, span_warning("You feel as if you [value < 0 ? "gained" : "lost" ] some of your humanity, you will now enter Frenzy at [FRENZY_THRESHOLD_ENTER + (humanity_lost * 10)] Blood.")) - -#undef MASQUERADE - -/// mult: SILENT feed is 1/3 the amount -/datum/antagonist/bloodsucker/proc/handle_feeding(mob/living/carbon/target, blood_taken, already_drunk = 0) - // Apply to Volume - AdjustBloodVolume(blood_taken) - total_blood_drank += blood_taken - OverfeedHealing(blood_taken) - // Reagents (NOT Blood!) - if(target.mind) // Checks if the target has a mind - // closer it is to max, the less level up blood you get - var/blood_for_leveling = blood_taken - if(already_drunk > BLOOD_VOLUME_NORMAL) - var/max_threshold = BLOOD_VOLUME_NORMAL * 2 - var/modify_blood_gain = 1 - (already_drunk / max_threshold) - blood_for_leveling = max(blood_taken * modify_blood_gain, 0) - blood_level_gain += blood_for_leveling - return blood_taken - -/** - * ## HEALING - */ - -/// Constantly runs on Bloodsucker's LifeTick, and is increased by being in Torpor/Coffins -/datum/antagonist/bloodsucker/proc/HandleHealing(mult = 1) - // Don't heal if I'm staked or on Masquerade. - var/actual_regen = bloodsucker_regen_rate + additional_regen - if(owner.current.am_staked() || (HAS_TRAIT(owner.current, TRAIT_MASQUERADE))) - return FALSE - owner.current.adjust_organ_loss(ORGAN_SLOT_BRAIN, -1 * actual_regen * mult) //adjustBrainLoss(-1 * (actual_regen * 4) * mult, 0) - if(!iscarbon(owner.current)) // Damage Heal: Do I have damage to ANY bodypart? - return FALSE - var/mob/living/carbon/user = owner.current - var/costMult = 1 // Coffin makes it cheaper - // If you're a synth, you heal prosthetic damage. - var/bruteLoss = get_brute_loss() - var/bruteheal = min(bruteLoss, actual_regen) // BRUTE: Always Heal - var/fireLoss = get_fire_loss() - var/fireheal = min(fireLoss, actual_regen * 0.75) - var/amInCoffin = is_valid_coffin() - if (blood_over_cap > 0) - costMult += round(blood_over_cap / 1000, 0.1) // effectively 1 (normal) + 0.1 for every 100 blood you are over cap - if(amInCoffin && is_in_torpor()) - if(HAS_TRAIT(owner.current, TRAIT_MASQUERADE) && (COOLDOWN_FINISHED(src, bloodsucker_spam_healing))) - to_chat(user, span_alert("You do not heal while your Masquerade ability is active.")) - COOLDOWN_START(src, bloodsucker_spam_healing, BLOODSUCKER_SPAM_MASQUERADE) - return FALSE - mult *= 6 // Increase multiplier if we're sleeping in a coffin. - costMult *= COFFIN_HEAL_COST_MULT // Decrease cost if we're sleeping in a coffin. - user.extinguish_mob() - user.bodytemperature = user.get_body_temp_normal() - if(ishuman(user)) - var/mob/living/carbon/human/humie = user - humie.set_coretemperature(humie.get_body_temp_normal(apply_change = FALSE)) - user.remove_all_embedded_objects() // Remove Embedded! - if(check_limbs(costMult)) - return TRUE - // In Torpor, but not in a Coffin? Heal faster anyways. - else if(is_in_torpor()) - mult *= 4 - // Heal if Damaged - if((bruteheal + fireheal) && mult != 0) // Just a check? Don't heal/spend, and return. - // We have damage. Let's heal (one time), and don't cost any blood if we cannot - user.heal_overall_damage(brute = bruteheal * mult, burn = fireheal * mult) - user.updatehealth() - AdjustBloodVolume(((bruteheal * -0.5) + (fireheal * -1)) * costMult * mult) // Costs blood to heal - return TRUE - -/datum/antagonist/bloodsucker/proc/OverfeedHealing(drunk) - var/mob/living/carbon/user = owner.current - if(blood_over_cap > 0) //Checks if you are over your blood cap - var/overbruteheal = user.get_brute_loss_nonProsthetic() - var/overfireheal = user.get_fire_loss_nonProsthetic() - var/heal_amount = drunk / 3 - if(overbruteheal > 0 && heal_amount > 0) - user.adjust_brute_loss(-heal_amount, updating_health = FALSE, forced = TRUE) // Heal BRUTE / BURN in random portions throughout the body; prioritising BRUTE. - heal_amount = (heal_amount - overbruteheal) // Removes the amount of BRUTE we've healed from the heal amount - else if(overfireheal > 0 && heal_amount > 0) - heal_amount /= 1.5 // Burn should be more difficult to heal - user.adjust_fire_loss(-heal_amount, updating_health = FALSE, forced = TRUE) - user.updatehealth() - -/datum/antagonist/bloodsucker/proc/check_limbs(costMult = 1) - var/limb_regen_cost = 50 * -costMult - var/mob/living/carbon/user = owner.current - var/list/missing = user.get_missing_limbs() - if(missing.len && (bloodsucker_blood_volume < limb_regen_cost + 5)) - return FALSE - for(var/missing_limb in missing) //Find ONE Limb and regenerate it. - user.regenerate_limb(missing_limb, FALSE) - AdjustBloodVolume(-limb_regen_cost) - var/obj/item/bodypart/missing_bodypart = user.get_bodypart(missing_limb) // 2) Limb returns Damaged - missing_bodypart.brute_dam = missing_bodypart.max_damage - to_chat(user, span_notice("Your flesh knits as it regrows your [missing_bodypart]!")) - playsound(user, 'sound/effects/magic/demon_consume.ogg', 50, TRUE) - return TRUE - -/* - * # Heal Vampire Organs - * - * This is used by Bloodsuckers, these are the steps of this proc: - * Step 1 - Cure husking and Regenerate organs. regenerate_organs() removes their Vampire Heart & Eye augments, which leads us to... - * Step 2 - Repair any (shouldn't be possible) Organ damage, then return their Vampiric Heart & Eye benefits. - * Step 3 - Revive them, clear all wounds, remove any Tumors (If any). - * - * This is called on Bloodsucker's Assign, and when they end Torpor. - */ -// TODO: Separate this into smaller functions -/datum/antagonist/bloodsucker/proc/heal_vampire_organs() - var/mob/living/carbon/bloodsuckeruser = owner.current - // please don't poison or asphyxiate the immune - bloodsuckeruser.set_tox_loss(0, forced = TRUE) - bloodsuckeruser.set_oxy_loss(0, forced = TRUE) - - if(QDELETED(bloodsuckeruser)) - return - - if(HAS_TRAIT_FROM_ONLY(bloodsuckeruser, TRAIT_HUSK, CHANGELING_DRAIN) || bloodsuckeruser.has_status_effect(/datum/status_effect/gutted)) - to_chat(bloodsuckeruser, span_danger("Your immortal blood has healed your body from near-irrecoverable damage, but has used nearly all of your blood in doing so!")) - AddHumanityLost(2) - SetBloodVolume(min(bloodsucker_blood_volume, frenzy_enter_threshold() * 2)) - bloodsuckeruser.cure_husk(CHANGELING_DRAIN) - - bloodsuckeruser.cure_husk(BURN) - - if(bloodsuckeruser.get_organ_slot(ORGAN_SLOT_HEART)) - bloodsuckeruser.regenerate_organs(remove_hazardous = FALSE) - - if(!HAS_TRAIT(bloodsuckeruser, TRAIT_MASQUERADE)) - var/obj/item/organ/heart/current_heart = bloodsuckeruser.get_organ_slot(ORGAN_SLOT_HEART) - current_heart?.Stop() - - var/obj/item/organ/eyes/current_eyes = bloodsuckeruser.get_organ_slot(ORGAN_SLOT_EYES) - if(current_eyes && !(current_eyes.organ_flags & ORGAN_ROBOTIC)) - current_eyes.flash_protect = max(initial(current_eyes.flash_protect) - 1, FLASH_PROTECTION_SENSITIVE) - current_eyes.color_cutoffs = BLOODSUCKER_SIGHT_COLOR_CUTOFF - current_eyes.sight_flags = SEE_MOBS - - bloodsuckeruser.update_sight() - /// Disable gutting for the chest - var/obj/item/bodypart/chest/target_chest = bloodsuckeruser.get_bodypart(BODY_ZONE_CHEST) - if(target_chest && !(target_chest.bodypart_flags & BODYPART_UNREMOVABLE)) - target_chest.bodypart_flags |= BODYPART_UNREMOVABLE - - // Sometimes bloodsuckers can get into a loop of reviving and dying, if they somehow get a new body without being revived. - if(bloodsuckeruser.stat == DEAD) - . = bloodsuckeruser.revive() - - for(var/datum/wound/iter_wound in bloodsuckeruser.all_wounds) - iter_wound.remove_wound() - - // From [powers/panacea.dm] - var/list/bad_organs = list( - bloodsuckeruser.get_organ_by_type(/obj/item/organ/body_egg), - bloodsuckeruser.get_organ_by_type(/obj/item/organ/zombie_infection) - ) - for(var/tumors in bad_organs) - var/obj/item/organ/yucky_organs = tumors - if(!istype(yucky_organs)) - continue - to_chat(bloodsuckeruser, span_warning("You feel a little ill for a moment, but it passes. Did you just cough up a tumor?")) - yucky_organs.Remove(bloodsuckeruser) - yucky_organs.forceMove(get_turf(bloodsuckeruser)) - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -// DEATH - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -/// FINAL DEATH -/datum/antagonist/bloodsucker/proc/HandleDeath() - if(QDELETED(owner.current)) - if(length(ghouls)) - free_all_ghouls() - ghouls = list() - return - // Fire Damage? (above double health) - if(owner.current.get_fire_loss() >= owner.current.maxHealth * FINAL_DEATH_HEALTH_TO_BURN) // 337.5 burn with 135 maxHealth - FinalDeath() - return - // Temporary Death? Convert to Torpor. - if(is_in_torpor() || isbrain(owner.current)) - return - check_begin_torpor(TORPOR_SKIP_CHECK_ALL) - -/datum/antagonist/bloodsucker/proc/HandleBlood() - INVOKE_ASYNC(src, PROC_REF(update_blood)) - INVOKE_ASYNC(src, PROC_REF(HandleStarving)) - return HANDLE_BLOOD_NO_OXYLOSS | HANDLE_BLOOD_NO_NUTRITION_DRAIN - -/datum/antagonist/bloodsucker/proc/HandleStarving() // I am thirsty for blood! - // Nutrition - The amount of blood is how full we are. - owner.current.set_nutrition(min(bloodsucker_blood_volume, NUTRITION_LEVEL_FED)) - - // BLOOD_VOLUME_GOOD: [336] - Pale -// handled in bloodsucker_integration.dm - // BLOOD_VOLUME_EXIT: [250] - Exit Frenzy (If in one) This is high because we want enough to kill the poor soul they feed off of. - var/datum/status_effect/frenzy/status_effect = owner.current.has_status_effect(/datum/status_effect/frenzy) - if(bloodsucker_blood_volume >= frenzy_exit_threshold() && frenzied) - owner.current.remove_status_effect(status_effect) - owner.current.balloon_alert(owner.current, "frenzy ends in 10 seconds!") - // BLOOD_VOLUME_BAD: [224] - Jitter - if(bloodsucker_blood_volume < BLOOD_VOLUME_BAD && prob(0.5) && !is_in_torpor() && !HAS_TRAIT(owner.current, TRAIT_MASQUERADE)) - owner.current.set_timed_status_effect(3 SECONDS, /datum/status_effect/jitter, only_if_higher = TRUE) - // BLOOD_VOLUME_SURVIVE: [122] - Blur Vision - if(bloodsucker_blood_volume < BLOOD_VOLUME_SURVIVE) - owner.current.set_eye_blur_if_lower((8 - 8 * (bloodsucker_blood_volume / BLOOD_VOLUME_BAD))*2 SECONDS) - - // The more blood, the better the Regeneration, get too low blood, and you enter Frenzy. - if(bloodsucker_blood_volume < frenzy_enter_threshold() && !frenzied) - owner.current.apply_status_effect(/datum/status_effect/frenzy) - else if(bloodsucker_blood_volume < BLOOD_VOLUME_BAD) - additional_regen = 0.2 - else if(bloodsucker_blood_volume < BLOOD_VOLUME_OKAY) - additional_regen = 0.3 - else if(bloodsucker_blood_volume < BLOOD_VOLUME_NORMAL) - additional_regen = 0.4 - else if(bloodsucker_blood_volume < BS_BLOOD_VOLUME_MAX_REGEN) - additional_regen = 0.5 - else if(bloodsucker_blood_volume < max_blood_volume) - additional_regen = 0.6 - else if(bloodsucker_blood_volume > max_blood_volume) - additional_regen = 1.35 + round((blood_over_cap / 1000) * 2, 0.1) - AdjustBloodVolume(-1 - blood_over_cap / 100) - -/// Makes your blood_volume look like your bloodsucker blood, unless you're Masquerading. -/datum/antagonist/bloodsucker/proc/update_blood() - if(SEND_SIGNAL(src, BLOODSUCKER_UPDATE_BLOOD) & BLOODSUCKER_UPDATE_BLOOD_DISABLED) - return - if(HAS_TRAIT(owner.current, TRAIT_NOBLOOD)) - return - //If we're on Masquerade, we appear to have full blood, unless we are REALLY low, in which case we don't look as bad. - if(HAS_TRAIT(owner.current, TRAIT_MASQUERADE)) - switch(bloodsucker_blood_volume) - if(BLOOD_VOLUME_OKAY to INFINITY) // 336 and up, we are perfectly fine. - owner.current.blood_volume = initial(bloodsucker_blood_volume) - if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY) // 224 to 336 - owner.current.blood_volume = BLOOD_VOLUME_SAFE - else // 224 and below - owner.current.blood_volume = BLOOD_VOLUME_OKAY - return - - owner.current.blood_volume = bloodsucker_blood_volume - -/// Turns the bloodsucker into a wacky talking head. -/datum/antagonist/bloodsucker/proc/talking_head(mob/target) - var/mob/living/poor_fucker = target - if(QDELETED(poor_fucker)) - return - // Don't do anything if we're not actually inside a brain and a head - var/obj/item/bodypart/head/head = is_head(poor_fucker) - if(!head || poor_fucker.stat != DEAD || !poor_fucker.can_be_revived()) - return - if(istype(poor_fucker.loc, /obj/item/organ/brain)) - RegisterSignal(poor_fucker.loc, COMSIG_QDELETING, PROC_REF(on_brain_remove)) - RegisterSignal(poor_fucker.loc, COMSIG_ORGAN_BODYPART_REMOVED, PROC_REF(on_brain_remove)) - - RegisterSignal(poor_fucker, COMSIG_MOB_TRY_SPEECH, PROC_REF(allow_head_to_talk)) - RegisterSignal(poor_fucker, COMSIG_MOB_SAY, PROC_REF(shake_head_on_talk)) - poor_fucker.revive() - poor_fucker.stat = CONSCIOUS - to_chat(poor_fucker, span_warning("Your immortal [pick(list("blood", "curse"))] keeps your head alive! Though... what will you do now?")) - // No lungs to speak, let's make it spooky - poor_fucker.speech_span = SPAN_PAPYRUS - -/datum/antagonist/bloodsucker/proc/cleanup_talking_head(obj/item/organ/brain) - var/mob/living/poor_fucker = owner.current - if(brain) - UnregisterSignal(brain, list(COMSIG_QDELETING, COMSIG_ORGAN_BODYPART_REMOVED)) - // fucked up if this happens, but we're probably final deathed at this point - if(QDELETED(poor_fucker)) - return - UnregisterSignal(poor_fucker, list(COMSIG_MOB_TRY_SPEECH, COMSIG_MOB_SAY, COMSIG_QDELETING)) - poor_fucker.death() - poor_fucker.speech_span = initial(poor_fucker.speech_span) - -/datum/antagonist/bloodsucker/proc/on_brain_remove(obj/item/organ/brain) - SIGNAL_HANDLER - cleanup_talking_head(brain) - -/datum/antagonist/bloodsucker/proc/on_brainmob_qdel() - SIGNAL_HANDLER - if(istype(owner.current.loc, /obj/item/organ/brain)) - cleanup_talking_head(owner.current.loc) - else - cleanup_talking_head() - -/// Gibs the Bloodsucker, roundremoving them. -/datum/antagonist/bloodsucker/proc/FinalDeath(check_organs = FALSE) - SIGNAL_HANDLER - // If we have no body, end here. - if(QDELETED(owner.current) || isbrain(owner.current)) - return - unregister_body_signals() - free_all_ghouls() - DisableAllPowers(forced = TRUE) - if(!iscarbon(owner.current)) - owner.current.gib(DROP_ITEMS) - return - // Drop anything in us and play a tune - var/mob/living/carbon/user = owner.current - owner.current.drop_all_held_items() - owner.current.unequip_everything() - INVOKE_ASYNC(user, TYPE_PROC_REF(/mob/living/carbon, remove_all_embedded_objects)) - playsound(owner.current, 'sound/effects/tendril_destroyed.ogg', 40, TRUE) - - var/unique_death = SEND_SIGNAL(src, COMSIG_BLOODSUCKER_FINAL_DEATH) - if(unique_death & DONT_DUST) - return - - // Elders get dusted, Fledglings get gibbed. - if(bloodsucker_level >= 4) - user.visible_message( - span_warning("[user]'s skin crackles and dries, their skin and bones withering to dust. A hollow cry whips from what is now a sandy pile of remains."), - span_userdanger("Your soul escapes your withering body as the abyss welcomes you to your Final Death."), - span_hear("You hear a dry, crackling sound.")) - addtimer(CALLBACK(user, TYPE_PROC_REF(/atom/movable, dust)), 5 SECONDS, TIMER_UNIQUE|TIMER_STOPPABLE) - return - user.visible_message( - span_warning("[user]'s skin bursts forth in a spray of gore and detritus. A horrible cry echoes from what is now a wet pile of decaying meat."), - span_userdanger("Your soul escapes your withering body as the abyss welcomes you to your Final Death."), - span_hear("You hear a wet, bursting sound.")) - addtimer(CALLBACK(user, TYPE_PROC_REF(/mob/living, gib), DROP_ITEMS), 2 SECONDS, TIMER_UNIQUE|TIMER_STOPPABLE) - user.investigate_log("Died as a bloodsucker from Final Death.", INVESTIGATE_DEATHS) - -#undef BLOODSUCKER_PASSIVE_BLOOD_DRAIN - - -/** - * # Status effect - * - * This is the status effect given to Bloodsuckers in a Frenzy - * This deals with everything entering/exiting Frenzy is meant to deal with. - */ - -/atom/movable/screen/alert/status_effect/frenzy - name = "Frenzy" - desc = "You are in a Frenzy! You are entirely Feral and, depending on your Clan, fighting for your life! Find and drink blood, or you will suffer a Final Death!" - icon = 'tff_modular/modules/bloodsucker/icons/bloodsucker.dmi' - icon_state = "power_recover" - alerttooltipstyle = "cult" - -/datum/status_effect/frenzy - id = "Frenzy" - status_type = STATUS_EFFECT_UNIQUE - duration = STATUS_EFFECT_PERMANENT - alert_type = /atom/movable/screen/alert/status_effect/frenzy - ///Boolean on whether they were an AdvancedToolUser, to give the trait back upon exiting. - var/was_tooluser = FALSE - /// The stored Bloodsucker antag datum - var/datum/antagonist/bloodsucker/bloodsuckerdatum - var/trait_list = list(TRAIT_MUTE, TRAIT_DEAF, TRAIT_STRONG_GRABBER) - -/datum/status_effect/frenzy/get_examine_text() - return span_notice("They seem... inhumane, and feral!") - -/atom/movable/screen/alert/status_effect/masquerade/MouseEntered(location,control,params) - desc = initial(desc) - return ..() - -/datum/status_effect/frenzy/on_apply() - var/mob/living/carbon/human/user = owner - bloodsuckerdatum = IS_BLOODSUCKER(user) - - // Disable ALL Powers and notify their entry - bloodsuckerdatum.DisableAllPowers(forced = TRUE) - to_chat(owner, span_userdanger("Blood! You need Blood, now! You enter a total Frenzy! You will DIE if you do not get BLOOD.")) - to_chat(owner, span_announce("* Bloodsucker Tip: While in Frenzy, you quickly accrue burn damage, instantly Aggresively grab, have stun resistance, cannot speak, hear, or use any powers outside of Feed and Trespass (If you have it).")) - owner.balloon_alert(owner, "you enter a frenzy! Drink blood, or you will die!") - SEND_SIGNAL(bloodsuckerdatum, COMSIG_BLOODSUCKER_ENTERS_FRENZY) - - // Give the other Frenzy effects - owner.add_traits(trait_list, FRENZY_TRAIT) - if(HAS_TRAIT(owner, TRAIT_ADVANCEDTOOLUSER)) - was_tooluser = TRUE - REMOVE_TRAIT(owner, TRAIT_ADVANCEDTOOLUSER, SPECIES_TRAIT) - owner.add_movespeed_modifier(/datum/movespeed_modifier/frenzy_speedup) - owner.add_client_colour(/datum/client_colour/manual_heart_blood, REF(src)) - var/obj/cuffs = user.get_item_by_slot(ITEM_SLOT_HANDCUFFED) - var/obj/legcuffs = user.get_item_by_slot(ITEM_SLOT_LEGCUFFED) - if((user.handcuffed && cuffs) || (user.legcuffed && legcuffs)) - user.clear_cuffs(cuffs, TRUE) - user.clear_cuffs(legcuffs, TRUE) - bloodsuckerdatum.frenzied = TRUE - return ..() - -/datum/status_effect/frenzy/on_remove() - owner.balloon_alert(owner, "you come back to your senses.") - owner.remove_traits(trait_list, FRENZY_TRAIT) - if(was_tooluser) - ADD_TRAIT(owner, TRAIT_ADVANCEDTOOLUSER, SPECIES_TRAIT) - was_tooluser = FALSE - owner.remove_movespeed_modifier(/datum/movespeed_modifier/frenzy_speedup) - owner.remove_client_colour(REF(src)) - - SEND_SIGNAL(bloodsuckerdatum, COMSIG_BLOODSUCKER_EXITS_FRENZY) - bloodsuckerdatum.frenzied = FALSE - return ..() - -/datum/status_effect/frenzy/tick() - var/mob/living/carbon/human/user = owner - // If duration is not -1, that means we're about to loose frenzy, let's give them some safe time. - if(!bloodsuckerdatum.frenzied || duration > 0 || user.stat != CONSCIOUS ) - return - user.adjust_fire_loss(1 + (bloodsuckerdatum.GetHumanityLost() / 10)) - -/datum/movespeed_modifier/frenzy_speedup - blacklisted_movetypes = (FLYING|FLOATING) - multiplicative_slowdown = -0.4 - -/datum/movespeed_modifier/mesmerize_slowdown - blacklisted_movetypes = (FLYING|FLOATING) - multiplicative_slowdown = 0.5 diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/movable_hud.dm b/tff_modular/modules/bloodsucker/bloodsuckers/movable_hud.dm deleted file mode 100644 index 89729506b57..00000000000 --- a/tff_modular/modules/bloodsucker/bloodsuckers/movable_hud.dm +++ /dev/null @@ -1,207 +0,0 @@ - -/// UI obj holders for all your maptext needs -/atom/movable/screen/text - name = null - icon = null - icon_state = null - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - screen_loc = "CENTER-7,CENTER-7" - maptext_height = 480 - maptext_width = 480 - -/// A screen object that shows the time left on a timer -/atom/movable/screen/text/screen_timer - screen_loc = "CENTER-7,CENTER-7" - /// The actual displayed content of the maptext, use ${timer}, and it'll be replaced with formatted time left - var/maptext_string - /// Timer ID that we're tracking, the time left of this is displayed as maptext - var/timer_id - /// The list of mobs in whose client.screens we are added to - var/list/timer_mobs = list() - -/atom/movable/screen/text/screen_timer/Initialize( - mapload, - list/mobs, - timer, - text, - offset_x = 150, - offset_y = -70, - ) - . = ..(mapload, null) - - if(!islist(mobs) && mobs) - mobs = list(mobs) - // Copy the list just in case the arguments list is a list we don't want to modify - if(length(mobs)) - mobs = mobs.Copy() - if(!timer) - return INITIALIZE_HINT_QDEL - maptext_string = text - timer_id = timer - maptext_x = offset_x - maptext_y = offset_y - update_maptext() - if(length(mobs)) - apply_to(mobs) - -/atom/movable/screen/text/screen_timer/process() - if(!timeleft(timer_id)) - qdel(src) - return - update_maptext() - -/// Adds the object to the client.screen of all mobs in the list, and registers the needed signals -/atom/movable/screen/text/screen_timer/proc/apply_to(list/mobs) - if(!mobs) - return - if(!islist(mobs)) - mobs = list(mobs) - if(!length(timer_mobs) && length(mobs)) - START_PROCESSING(SSprocessing, src) - for(var/player in mobs) - if(player in timer_mobs) - continue - if(istype(player, /datum/weakref)) - var/datum/weakref/ref = player - player = ref.resolve() - attach(player) - RegisterSignal(player, COMSIG_MOB_LOGIN, PROC_REF(attach)) // doesn't currently cleanup properly - timer_mobs += WEAKREF(player) - -/// Removes the object from the client.screen of all mobs in the list, and unregisters the needed signals, while also stopping processing if there's no more mobs in the screen timers mob list -/atom/movable/screen/text/screen_timer/proc/remove_from(list/mobs) - if(!mobs) - return - if(!islist(mobs)) - mobs = list(mobs) - for(var/player in mobs) - // when the player is a weakref, assume it's the same pointer that we use in the timer_mobs list - var/datum/weakref/found_weakref - if(istype(player, /datum/weakref)) - var/datum/weakref/ref = player - found_weakref = ref - // otherwise we have to search through and resolve each one and compare it - else - for(var/datum/weakref/possible_match as anything in timer_mobs) - if(player == possible_match.resolve()) - found_weakref = possible_match - break - timer_mobs -= found_weakref - var/found_player = found_weakref.resolve() - if(!found_player) - return - UnregisterSignal(found_player, COMSIG_MOB_LOGIN) - de_attach(found_player) - if(!length(timer_mobs)) - STOP_PROCESSING(SSprocessing, src) - -/// Updates the maptext to show the current time left on the timer -/atom/movable/screen/text/screen_timer/proc/update_maptext() - var/time_formatted = time2text(timeleft(timer_id), "mm:ss") - var/timer_text = replacetextEx(maptext_string, "${timer}", time_formatted) - // If we don't find ${timer} in the string, just use the time formatted - var/result_text = MAPTEXT("[timer_text]") - apply_change(result_text) - -/atom/movable/screen/text/screen_timer/proc/apply_change(result_text) - maptext = result_text - -/// Adds the object to the client.screen of the mob, or removes it if add_to_screen is FALSE -/atom/movable/screen/text/screen_timer/proc/attach(mob/source, add_to_screen = TRUE) - SIGNAL_HANDLER - if(!source?.client) - return - var/client/client = source.client - // this checks if the screen is already added or removed - if(!can_attach(client, add_to_screen)) - return - if(!ismob(source)) - CRASH("Invalid source passed to screen_timer/attach()!") - do_attach(client, add_to_screen) - -/atom/movable/screen/text/screen_timer/proc/can_attach(client/client, add_to_screen) - return add_to_screen == (src in client.screen) - -/atom/movable/screen/text/screen_timer/proc/do_attach(client/client, add_to_screen) - if(add_to_screen) - client.screen += src - else - client.screen -= src - -/// Signal handler to run attach with specific args -/atom/movable/screen/text/screen_timer/proc/de_attach(mob/source) - SIGNAL_HANDLER - attach(source, FALSE) - -/atom/movable/screen/text/screen_timer/Destroy() - if(length(timer_mobs)) - remove_from(timer_mobs) - - STOP_PROCESSING(SSprocessing, src) - . = ..() - -/atom/movable/screen/text/screen_timer/attached - maptext_x = 0 - maptext_y = 16 - maptext_height = 32 - maptext_width = 32 - var/following_object - var/image/text_image - -/atom/movable/screen/text/screen_timer/attached/Initialize( - mapload, - list/mobs, - timer, - text, - offset_x, - offset_y, - following_object, - ) - if(following_object && get_turf(following_object)) - attach_self_to(following_object, offset_x, offset_y) - else - return INITIALIZE_HINT_QDEL - . = ..() - -/atom/movable/screen/text/screen_timer/attached/can_attach(client/client) - return !(src in client.images) - -// attached screen timers are a visible timer in the gameworld that are only visible to the mobs listed in the timer_mobs list -/atom/movable/screen/text/screen_timer/attached/do_attach(client/client, add_to_screen) - if(add_to_screen) - client.images += text_image - else - client.images -= text_image - -/atom/movable/screen/text/screen_timer/attached/proc/attach_self_to(atom/movable/target, maptext_x, maptext_y) - text_image = image(src, target) - - text_image.maptext_x = maptext_x - text_image.maptext_y = maptext_y - - text_image.maptext_height = maptext_height - text_image.maptext_width = maptext_width - - SET_PLANE_EXPLICIT(text_image, ABOVE_HUD_PLANE, target) - -/atom/movable/screen/text/screen_timer/attached/apply_change(result_text) - ..() - text_image?.maptext = result_text - -/atom/movable/screen/text/screen_timer/attached/proc/hide_timer(atom/movable/target) - unregister_follower() - -/atom/movable/screen/text/screen_timer/attached/proc/unregister_follower() - following_object = null - text_image = null - -/atom/movable/screen/text/screen_timer/attached/proc/update_glide_speed(atom/movable/tracked) - set_glide_size(tracked.glide_size) - -/atom/movable/screen/text/screen_timer/attached/proc/timer_follow(atom/movable/tracked, atom/mover, atom/oldloc, direction) - abstract_move(get_turf(tracked)) - -/atom/movable/screen/text/screen_timer/attached/Destroy() - if(following_object) - unregister_follower() - . = ..() diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/names.dm b/tff_modular/modules/bloodsucker/bloodsuckers/names.dm deleted file mode 100644 index 60a9c1c1d74..00000000000 --- a/tff_modular/modules/bloodsucker/bloodsuckers/names.dm +++ /dev/null @@ -1,136 +0,0 @@ - -/datum/antagonist/bloodsucker/proc/return_full_name() - var/fullname = bloodsucker_name ? bloodsucker_name : owner.current.name - if(bloodsucker_title) - fullname = "[bloodsucker_title] [fullname]" - if(bloodsucker_reputation) - fullname += " the [bloodsucker_reputation]" - - return fullname - -///Returns a First name for the Bloodsucker. -/datum/antagonist/bloodsucker/proc/SelectFirstName() - if(owner.current.gender == MALE) - bloodsucker_name = pick( - "Desmond","Rudolph","Dracula","Vlad","Pyotr","Gregor", - "Cristian","Christoff","Marcu","Andrei","Constantin", - "Gheorghe","Grigore","Ilie","Iacob","Luca","Mihail","Pavel", - "Vasile","Octavian","Sorin","Sveyn","Aurel","Alexe","Iustin", - "Theodor","Dimitrie","Octav","Damien","Magnus","Caine","Abel", // Romanian/Ancient - "Lucius","Gaius","Otho","Balbinus","Arcadius","Romanos","Alexios","Vitellius", // Latin - "Melanthus","Teuthras","Orchamus","Amyntor","Axion", // Greek - "Thoth","Thutmose","Osorkon,","Nofret","Minmotu","Khafra", // Egyptian - "Dio", - ) - else - bloodsucker_name = pick( - "Islana","Tyrra","Greganna","Pytra","Hilda", - "Andra","Crina","Viorela","Viorica","Anemona", - "Camelia","Narcisa","Sorina","Alessia","Sophia", - "Gladda","Arcana","Morgan","Lasarra","Ioana","Elena", - "Alina","Rodica","Teodora","Denisa","Mihaela", - "Svetla","Stefania","Diyana","Kelssa","Lilith", // Romanian/Ancient - "Alexia","Athanasia","Callista","Karena","Nephele","Scylla","Ursa", // Latin - "Alcestis","Damaris","Elisavet","Khthonia","Teodora", // Greek - "Nefret","Ankhesenpep", // Egyptian - ) - -///Returns a Title for the Bloodsucker. -/datum/antagonist/bloodsucker/proc/SelectTitle(am_fledgling = FALSE, forced = FALSE) - // Already have Title - if(!forced && bloodsucker_title != null) - return - // Titles [Master] - if(am_fledgling) - bloodsucker_title = null - return - if(owner.current.gender == MALE) - bloodsucker_title = pick( - "Count", - "Baron", - "Viscount", - "Prince", - "Duke", - "Tzar", - "Dreadlord", - "Lord", - "Master", - ) - else - bloodsucker_title = pick( - "Countess", - "Baroness", - "Viscountess", - "Princess", - "Duchess", - "Tzarina", - "Dreadlady", - "Lady", - "Mistress", - ) - to_chat(owner, span_announce("You have earned a title! You are now known as [return_full_name()]!")) - -///Returns a Reputation for the Bloodsucker. -/datum/antagonist/bloodsucker/proc/SelectReputation(am_fledgling = FALSE, forced = FALSE) - // Already have Reputation - if(!forced && bloodsucker_reputation != null) - return - - if(am_fledgling) - bloodsucker_reputation = pick( - "Crude", - "Callow", - "Unlearned", - "Neophyte", - "Novice", - "Unseasoned", - "Fledgling", - "Young", - "Neonate", - "Scrapling", - "Untested", - "Unproven", - "Unknown", - "Newly Risen", - "Born", - "Scavenger", - "Unknowing", - "Unspoiled", - "Disgraced", - "Defrocked", - "Shamed", - "Meek", - "Timid", - "Broken", - "Fresh", - ) - else if(owner.current.gender == MALE && prob(10)) - bloodsucker_reputation = pick( - "King of the Damned", - "Blood King", - "Emperor of Blades", - "Sinlord", - "God-King", - ) - else if(owner.current.gender == FEMALE && prob(10)) - bloodsucker_reputation = pick( - "Queen of the Damned", - "Blood Queen", - "Empress of Blades", - "Sinlady", - "God-Queen", - ) - else - bloodsucker_reputation = pick( - "Butcher","Blood Fiend","Crimson","Red","Black","Terror", - "Nightman","Feared","Ravenous","Fiend","Malevolent","Wicked", - "Ancient","Plaguebringer","Sinister","Forgotten","Wretched","Baleful", - "Inqisitor","Harvester","Reviled","Robust","Betrayer","Destructor", - "Damned","Accursed","Terrible","Vicious","Profane","Vile", - "Depraved","Foul","Slayer","Manslayer","Sovereign","Slaughterer", - "Forsaken","Mad","Dragon","Savage","Villainous","Nefarious", - "Inquisitor","Marauder","Horrible","Immortal","Undying","Overlord", - "Corrupt","Hellspawn","Tyrant","Sanguineous", - ) - - to_chat(owner, span_announce("You have earned a reputation! You are now known as [return_full_name()]!")) diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/objectives.dm b/tff_modular/modules/bloodsucker/bloodsuckers/objectives.dm deleted file mode 100644 index 25c7811bcf8..00000000000 --- a/tff_modular/modules/bloodsucker/bloodsuckers/objectives.dm +++ /dev/null @@ -1,372 +0,0 @@ -/* - * # Hide a random object somewhere on the station: - * - * var/turf/targetturf = get_random_station_turf() - * var/turf/targetturf = get_safe_random_station_turf() - */ - -/datum/objective/bloodsucker - martyr_compatible = TRUE - -// GENERATE -/datum/objective/bloodsucker/New() - update_explanation_text() - ..() - -////////////////////////////////////////////////////////////////////////////// -// // PROCS // // - -/// Look at all crew members, and for/loop through. -/datum/objective/bloodsucker/proc/return_possible_targets() - var/list/possible_targets = list() - for(var/datum/mind/possible_target in get_crewmember_minds()) - // Check One: Default Valid User - if(possible_target != owner && ishuman(possible_target.current) && possible_target.current.stat != DEAD) - // Check Two: Am Bloodsucker? - if(IS_BLOODSUCKER(possible_target.current)) - continue - possible_targets += possible_target - - return possible_targets - -/// Check Ghouls and get their occupations -/datum/objective/bloodsucker/proc/get_ghoul_occupations() - var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(owner.current) - if(!bloodsuckerdatum || !bloodsuckerdatum.ghouls.len) - return FALSE - var/list/all_ghoul_jobs = list() - var/ghoul_job - for(var/datum/antagonist/ghoul/bloodsucker_ghouls in bloodsuckerdatum.ghouls) - if(!bloodsucker_ghouls || !bloodsucker_ghouls.owner) // Must exist somewhere, and as a ghoul. - continue - // Mind Assigned - if(bloodsucker_ghouls.owner?.assigned_role) - ghoul_job = bloodsucker_ghouls.owner.assigned_role - // Mob Assigned - else if(bloodsucker_ghouls.owner?.current?.job) - ghoul_job = SSjob.get_job(bloodsucker_ghouls.owner.current.job) - // PDA Assigned - else if(bloodsucker_ghouls.owner?.current && ishuman(bloodsucker_ghouls.owner.current)) - var/mob/living/carbon/human/ghoul = bloodsucker_ghouls.owner.current - ghoul_job = SSjob.get_job(ghoul.get_assignment()) - if(ghoul_job) - all_ghoul_jobs += ghoul_job - return all_ghoul_jobs - -////////////////////////////////////////////////////////////////////////////////////// -// // OBJECTIVES // // -////////////////////////////////////////////////////////////////////////////////////// - -////////////////////////////// -// DEFAULT OBJECTIVES // -////////////////////////////// - -/datum/objective/bloodsucker/haven - name = "claimhaven" - -// EXPLANATION -/datum/objective/bloodsucker/haven/update_explanation_text() - explanation_text = "Create a haven by claiming a coffin, and protect it until the end of the shift."// Make sure to keep it safe!" - -// WIN CONDITIONS? -/datum/objective/bloodsucker/haven/check_completion() - var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(owner.current) - if(bloodsuckerdatum && bloodsuckerdatum.coffin && bloodsuckerdatum.bloodsucker_haven_area) - return TRUE - return FALSE - -/// Space_Station_13_areas.dm <--- all the areas - -////////////////////////////////////////////////////////////////////////////////////// - -/datum/objective/survive/bloodsucker - name = "bloodsuckersurvive" - explanation_text = "Survive the entire shift without succumbing to Final Death." - -/datum/objective/survive/bloodsucker/check_completion() - var/list/datum/mind/owners = get_owners() - for(var/datum/mind/mind in owners) - var/datum/antagonist/bloodsucker/vamp = IS_BLOODSUCKER(mind.current) - if(!vamp) - return FALSE - if(!vamp.considered_alive(mind)) - return FALSE - return TRUE - -////////////////////////////////////////////////////////////////////////////////////// - - -/// Ghoulify a certain person / people -/datum/objective/bloodsucker/conversion - name = "ghouling" - -///////////////////////////////// - -// Ghoulify a head of staff -/datum/objective/bloodsucker/conversion/command - name = "ghoulingcommand" - target_amount = 1 - -// EXPLANATION -/datum/objective/bloodsucker/conversion/command/update_explanation_text() - explanation_text = "Guarantee a Ghoul ends up as a Department Head or in a Leadership role." - -// WIN CONDITIONS? -/datum/objective/bloodsucker/conversion/command/check_completion() - var/list/ghoul_jobs = get_ghoul_occupations() - for(var/datum/job/checked_job in ghoul_jobs) - if(checked_job.departments_bitflags & DEPARTMENT_BITFLAG_COMMAND) - return TRUE // We only need one, so we stop as soon as we get a match - return FALSE - -///////////////////////////////// - -// Ghoulify crewmates in a department -/datum/objective/bloodsucker/conversion/department - name = "ghoulify department" - - ///The selected department we have to ghoulify. - var/datum/job_department/target_department - ///List of all departments that can be selected for the objective. - var/static/list/possible_departments = list( - /datum/job_department/security, - /datum/job_department/engineering, - /datum/job_department/medical, - /datum/job_department/science, - /datum/job_department/cargo, - /datum/job_department/service, - ) - - -// GENERATE! -/datum/objective/bloodsucker/conversion/department/New() - target_department = SSjob.get_department_type(pick(possible_departments)) - target_amount = rand(2, 3) - return ..() - -// EXPLANATION -/datum/objective/bloodsucker/conversion/department/update_explanation_text() - explanation_text = "Have [target_amount] Ghoul[target_amount == 1 ? "" : "s"] in the [target_department.department_name] department." - return ..() - -// WIN CONDITIONS? -/datum/objective/bloodsucker/conversion/department/check_completion() - var/list/ghoul_jobs = get_ghoul_occupations() - var/converted_count = 0 - for(var/datum/job/checked_job in ghoul_jobs) - if(checked_job.departments_bitflags & target_department.department_bitflags) - converted_count++ - if(converted_count >= target_amount) - return TRUE - return FALSE - - /** - * # IMPORTANT NOTE!! - * - * Look for Job Values on mobs! This is assigned at the start, but COULD be changed via the HoP - * ALSO - Search through all jobs (look for prefs earlier that look for all jobs, and search through all jobs to see if their head matches the head listed, or it IS the head) - * ALSO - registered_account in _vending.dm for banks, and assigning new ones. - */ - -////////////////////////////////////////////////////////////////////////////////////// - -// NOTE: Look up /steal in objective.dm for inspiration. -/// Steal hearts. You just really wanna have some hearts. -/datum/objective/steal_n_of_type/hearts - martyr_compatible = TRUE - name = "heartthief" - wanted_items = (/obj/item/organ/heart) - -// GENERATE! -/datum/objective/steal_n_of_type/hearts/New() - amount = rand(2, 3) - explanation_text = "Steal and keep [amount] organic hearts. Must be obtained from non-monkeys. Examine hearts thoroughly to see if they are valid." - update_explanation_text() - ..() - -/datum/objective/steal_n_of_type/hearts/check_if_valid_item(obj/item/organ/heart/current_item) - . = ..() - if(current_item.type == /obj/item/organ/heart/monkey || IS_ROBOTIC_ORGAN(current_item)) - return FALSE - -////////////////////////////////////////////////////////////////////////////////////// - -///Eat blood from a lot of people -/datum/objective/bloodsucker/gourmand - name = "gourmand" - -// GENERATE! -/datum/objective/bloodsucker/gourmand/New() - target_amount = rand(800, 3 * BLOOD_VOLUME_NORMAL) - ..() - -// EXPLANATION -/datum/objective/bloodsucker/gourmand/update_explanation_text() - . = ..() - explanation_text = "Using your Feed ability, drink [target_amount] units of Blood." - -// WIN CONDITIONS? -/datum/objective/bloodsucker/gourmand/check_completion() - var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(owner.current) - if(!bloodsuckerdatum) - return FALSE - var/stolen_blood = bloodsuckerdatum.total_blood_drank - if(stolen_blood >= target_amount) - return TRUE - return FALSE - -// HOW: Track each feed (if human). Count victory. - - - -////////////////////////////// -// CLAN OBJECTIVES // -////////////////////////////// - -/// Steal the Book of Nod - Nosferatu Clan objective -/datum/objective/bloodsucker/kindred - name = "steal the Book of Nod" - -// EXPLANATION -/datum/objective/bloodsucker/kindred/update_explanation_text() - . = ..() - explanation_text = "A Noddist Scholar has posted a bounty on SchreckNet for a scrap of the Book of Nod located in your sector. Their advise? Read a book." - -// WIN CONDITIONS? -/datum/objective/bloodsucker/kindred/check_completion() - if(!owner.current) - return FALSE - var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(owner.current) - if(!bloodsuckerdatum) - return FALSE - - for(var/datum/mind/bloodsucker_minds as anything in get_antag_minds(/datum/antagonist/bloodsucker)) - var/obj/item/book/kindred/the_book = locate() in bloodsucker_minds.current.get_all_contents() - if(the_book) - return TRUE - return FALSE - -////////////////////////////////////////////////////////////////////////////////////// - -/// Max out a Tremere Power - Tremere Clan objective -/datum/objective/bloodsucker/tremere_power - name = "tremerepower" - var/power_level = TREMERE_OBJECTIVE_POWER_LEVEL - -// EXPLANATION -/datum/objective/bloodsucker/tremere_power/update_explanation_text() - explanation_text = "Your Regent is doubting your abilities, level some Blood Magic to [power_level] to prove them wrong! Remember that Ghoulifying gives more Ranks!" - -// WIN CONDITIONS? -/datum/objective/bloodsucker/tremere_power/check_completion() - var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(owner.current) - if(!bloodsuckerdatum) - return FALSE - for(var/datum/action/cooldown/bloodsucker/tremere_powers in bloodsuckerdatum.powers) - if(tremere_powers.purchase_flags & TREMERE_CAN_BUY && tremere_powers.level_current >= power_level) - return TRUE - return FALSE - -////////////////////////////////////////////////////////////////////////////////////// - -/// Convert a crewmate - Ventrue Clan objective -/datum/objective/bloodsucker/embrace - name = "embrace" - -// EXPLANATION -/datum/objective/bloodsucker/embrace/update_explanation_text() - . = ..() - explanation_text = "Your Strategoi has granted you permission to embrace your favourite ghoul , use the Rack to 'level' them up." - -// WIN CONDITIONS? -/datum/objective/bloodsucker/embrace/check_completion() - var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(owner.current) - if(!bloodsuckerdatum) - return FALSE - for(var/datum/antagonist/bloodsucker/sired_vamp in GLOB.antagonists) - if(sired_vamp.ventrue_sired == bloodsuckerdatum) - return TRUE - return FALSE - - - -////////////////////////////// -// MONSTERHUNTER OBJECTIVES // -////////////////////////////// - -/datum/objective/bloodsucker/monsterhunter - name = "destroymonsters" - -// EXPLANATION -/datum/objective/bloodsucker/monsterhunter/update_explanation_text() - . = ..() - explanation_text = "Destroy all monsters on [station_name()]." - -// WIN CONDITIONS? -/datum/objective/bloodsucker/monsterhunter/check_completion() - var/list/datum/mind/monsters = list() - for(var/datum/antagonist/monster in GLOB.antagonists) - var/datum/mind/brain = monster.owner - if(!brain || brain == owner) - continue - if(brain.current.stat == DEAD) - continue - if(IS_HERETIC(brain.current) || IS_CULTIST(brain.current) || IS_BLOODSUCKER(brain.current) || IS_WIZARD(brain.current)) - monsters += brain - if(brain.has_antag_datum(/datum/antagonist/changeling)) - monsters += brain - - return completed || !monsters.len - - - -////////////////////////////// -// GHOUL OBJECTIVES // -////////////////////////////// - -/datum/objective/bloodsucker/ghoul - -// EXPLANATION -/datum/objective/bloodsucker/ghoul/update_explanation_text() - . = ..() - explanation_text = "Guarantee the success of your Master's mission!" - -// WIN CONDITIONS? -/datum/objective/bloodsucker/ghoul/check_completion() - var/datum/antagonist/ghoul/antag_datum = owner.has_antag_datum(/datum/antagonist/ghoul) - return antag_datum.master?.owner?.current?.stat != DEAD - - - -////////////////////////////// -// REMOVED OBJECTIVES // -// NOT GUARANTEED FUNCTIONAL// -////////////////////////////// - -// NOTE: Look up /assassinate in objective.dm for inspiration. -/// Ghoulify a target. -/datum/objective/bloodsucker/ghoulhim - name = "ghoulhim" - var/target_department_type = FALSE - -/datum/objective/bloodsucker/ghoulhim/New() - var/list/possible_targets = return_possible_targets() - find_target(possible_targets) - ..() - -// EXPLANATION -/datum/objective/bloodsucker/ghoulhim/update_explanation_text() - . = ..() - if(target?.current) - explanation_text = "Ensure [target.name], the [!target_department_type ? target.assigned_role.title : english_list(target.get_special_roles())], is Ghoulifyd via the Persuasion Rack." - else - explanation_text = "Free Objective" - -/datum/objective/bloodsucker/ghoulhim/admin_edit(mob/admin) - admin_simple_target_pick(admin) - -// WIN CONDITIONS? -/datum/objective/bloodsucker/ghoulhim/check_completion() - if(!target || target.has_antag_datum(/datum/antagonist/ghoul)) - return TRUE - return FALSE diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/procs.dm b/tff_modular/modules/bloodsucker/bloodsuckers/procs.dm deleted file mode 100644 index e1f986918fe..00000000000 --- a/tff_modular/modules/bloodsucker/bloodsuckers/procs.dm +++ /dev/null @@ -1,381 +0,0 @@ -/datum/antagonist/bloodsucker/proc/on_examine(datum/source, mob/examiner, examine_text) - SIGNAL_HANDLER - - if(!iscarbon(source)) - return - var/vamp_examine = return_vamp_examine(examiner) - if(vamp_examine) - examine_text += vamp_examine - SEND_SIGNAL(src, COMSIG_BLOODSUCKER_EXAMINE, source, examiner, examine_text) - -/datum/antagonist/bloodsucker/proc/BuyPowers(powers = list()) - for(var/datum/action/cooldown/bloodsucker/power as anything in powers) - BuyPower(power) - -///Called when a Bloodsucker buys a power: (power) -/datum/antagonist/bloodsucker/proc/BuyPower(datum/action/cooldown/bloodsucker/power) - for(var/datum/action/cooldown/bloodsucker/current_powers as anything in powers) - if(current_powers.type == power.type) - return null - power = new power() - powers += power - power.Grant(owner.current) - log_uplink("[key_name(owner.current)] purchased [power].") - return power - -///Called when a Bloodsucker loses a power: (power) -/datum/antagonist/bloodsucker/proc/RemovePower(datum/action/cooldown/bloodsucker/power) - if(power.active) - power.DeactivatePower() - powers -= power - power.Remove(owner.current) - -/datum/antagonist/bloodsucker/proc/RemovePowerByPath(datum/action/cooldown/bloodsucker/power_to_remove) - for(var/datum/action/cooldown/bloodsucker/power as anything in powers) - if(power?.type == power_to_remove) - RemovePower(power) - -///When a Bloodsucker breaks the Masquerade, they get their HUD icon changed, and Malkavian Bloodsuckers get alerted. -/datum/antagonist/bloodsucker/proc/break_masquerade(mob/admin) - if(broke_masquerade) - return - owner.current.playsound_local(null, 'tff_modular/modules/bloodsucker/sound/lunge_warn.ogg', 100, FALSE, pressure_affected = FALSE) - to_chat(owner.current, span_cult_bold_italic("You have broken the Masquerade!")) - to_chat(owner.current, span_warning("Bloodsucker Tip: When you break the Masquerade, you become open for termination by fellow Bloodsuckers, and your Ghouls are no longer completely loyal to you, as other Bloodsuckers can steal them for themselves!")) - broke_masquerade = TRUE - antag_hud_name = "masquerade_broken" - add_team_hud(owner.current) - SEND_GLOBAL_SIGNAL(COMSIG_BLOODSUCKER_BROKE_MASQUERADE, src) - -///This is admin-only of reverting a broken masquerade, sadly it doesn't remove the Malkavian objectives yet. -/datum/antagonist/bloodsucker/proc/fix_masquerade(mob/admin) - if(!broke_masquerade) - return - to_chat(owner.current, span_cult_bold_italic("You have re-entered the Masquerade.")) - broke_masquerade = FALSE - antag_hud_name = "bloodsucker" - add_team_hud(owner.current) - -/datum/antagonist/bloodsucker/proc/give_masquerade_infraction() - if(broke_masquerade) - return - masquerade_infractions++ - if(masquerade_infractions >= 3) - break_masquerade() - else - to_chat(owner.current, span_cult_bold("You violated the Masquerade! Break the Masquerade [3 - masquerade_infractions] more times and you will become a criminal to the Bloodsucker's Cause!")) - -/datum/antagonist/bloodsucker/proc/RankUp(force = FALSE) - if(!owner || !owner.current) - return - AdjustUnspentRank(1) - if(!my_clan) - to_chat(owner.current, span_notice("You have gained a rank. Join a Clan to spend it.")) - return - // Spend Rank Immediately? - if(!is_valid_coffin()) - to_chat(owner, span_notice("You have grown more ancient! Sleep in a coffin (or put your Favorite Ghoul on a persuasion rack for Ventrue) that you have claimed to thicken your blood and become more powerful.")) - if(bloodsucker_level_unspent >= 2) - to_chat(owner, span_announce("Bloodsucker Tip: If you cannot find or steal a coffin to use, you can build one from wood or metal.")) - return - SpendRank() - -/datum/antagonist/bloodsucker/proc/RankDown() - AdjustUnspentRank(-1) - -/datum/antagonist/bloodsucker/proc/remove_nondefault_powers(return_levels = FALSE) - for(var/datum/action/cooldown/bloodsucker/power as anything in powers) - if(power.purchase_flags & BLOODSUCKER_DEFAULT_POWER) - continue - RemovePower(power) - if(return_levels) - AdjustUnspentRank(1) - -/datum/antagonist/bloodsucker/proc/LevelUpPowers() - for(var/datum/action/cooldown/bloodsucker/power as anything in powers) - if(power.purchase_flags & TREMERE_CAN_BUY) - continue - power.upgrade_power() - -///Disables all powers, accounting for torpor -/datum/antagonist/bloodsucker/proc/DisableAllPowers(forced = FALSE) - for(var/datum/action/cooldown/bloodsucker/power as anything in powers) - if(forced || ((power.check_flags & BP_CANT_USE_IN_TORPOR) && is_in_torpor())) - if(power.active) - power.DeactivatePower() - -/datum/antagonist/bloodsucker/proc/SpendRank(mob/living/carbon/human/target, cost_rank = TRUE, blood_cost) - if(!owner || !owner.current || !owner.current.client || (cost_rank && bloodsucker_level_unspent <= 0)) - return - SEND_SIGNAL(src, COMSIG_BLOODSUCKER_RANK_UP, target, cost_rank, blood_cost) - -/datum/antagonist/bloodsucker/proc/GetRank() - return bloodsucker_level - -/datum/antagonist/bloodsucker/proc/AdjustRank(amount) - bloodsucker_level = max(bloodsucker_level + amount, 0) - update_rank_hud() - -/datum/antagonist/bloodsucker/proc/GetUnspentRank() - return bloodsucker_level_unspent - -/datum/antagonist/bloodsucker/proc/AdjustUnspentRank(amount) - bloodsucker_level_unspent = max(bloodsucker_level_unspent + amount, 0) - update_rank_hud() -/** - * Called when a Bloodsucker reaches Final Death - * Releases all Ghouls and gives them the ex_ghoul datum. - */ -/datum/antagonist/bloodsucker/proc/free_all_ghouls() - for(var/datum/antagonist/ghoul/all_ghouls in ghouls) - // Skip over any Bloodsucker Ghouls, they're too far gone to have all their stuff taken away from them - if(IS_BLOODSUCKER(all_ghouls.owner.current)) - all_ghouls.owner.current.remove_status_effect(/datum/status_effect/agent_pinpointer/ghoul_edition) - continue - if(all_ghouls.special_type == REVENGE_GHOUL || !all_ghouls.owner) - continue - all_ghouls.owner.add_antag_datum(/datum/antagonist/ex_ghoul) - all_ghouls.owner.remove_antag_datum(/datum/antagonist/ghoul) - -/** - * Returns a Vampire's examine strings. - * Args: - * viewer - The person examining. - */ -/datum/antagonist/bloodsucker/proc/return_vamp_examine(mob/living/viewer) - if(!viewer.mind && !isobserver(viewer)) - return FALSE - // Viewer is Target's Ghoul? - if(!isobserver(viewer) && (viewer.mind.has_antag_datum(/datum/antagonist/ghoul) in ghouls)) - var/returnString = "\[This is your Master!\]" - var/returnIcon = "[icon2html('tff_modular/modules/bloodsucker/icons/language.dmi', world, "bloodsucker")]" - returnString += "\n" - return returnIcon + returnString - // Viewer not a Vamp AND not the target's ghoul? - if(!isobserver(viewer) && !viewer.mind.has_antag_datum((/datum/antagonist/bloodsucker)) && !(viewer in ghouls)) - if(!(HAS_TRAIT(viewer.mind, TRAIT_BLOODSUCKER_HUNTER) && broke_masquerade)) - return FALSE - // Default String - var/returnString = "\[[return_full_name()]\]" - var/returnIcon = "[icon2html('tff_modular/modules/bloodsucker/icons/language.dmi', world, "bloodsucker")]" - - // In Disguise (Veil)? - //if (name_override != null) - // returnString += " ([real_name] in disguise!) " - - //returnString += "\n" Don't need spacers. Using . += "" in examine.dm does this on its own. - return returnIcon + returnString - -/datum/antagonist/bloodsucker/proc/can_gain_blood_rank(silent = TRUE, requires_blood = FALSE) - var/level_cost = get_level_cost() - var/mob/living/carbon/user = owner.current - if(blood_level_gain < level_cost) - if(!silent) - user.balloon_alert(user, "not enough blood thickening points!") - return FALSE - if(requires_blood && bloodsucker_blood_volume < level_cost) - if(!silent) - user.balloon_alert(user, "not enough blood!") - return FALSE - return TRUE - -// Blood level gain is used to give Bloodsuckers more levels if they are being agressive and drinking from real, sentient people. -// The maximum blood that counts towards this -/datum/antagonist/bloodsucker/proc/blood_level_gain(silent = TRUE, requires_blood = FALSE) - var/level_cost = get_level_cost() - if(can_gain_blood_rank(silent, requires_blood)) // Checks if we have drunk enough blood from the living to allow us to gain a level up as well as checking if we have enough blood to actually use on the level up - var/input = tgui_alert(owner.current, "You have drunk enough blood from the living to thicken your blood, this will cost you [level_cost] blood and give you another level", "Thicken your blood?.", list("Yes", "No")) //asks user if they want to spend their blood on a level - if(input == "Yes") - AdjustUnspentRank(1) // gives level - blood_level_gain -= level_cost // Subtracts the cost from the pool of drunk blood - if(requires_blood) - AdjustBloodVolume(-level_cost) // Subtracts the cost from the bloodsucker's actual blood - return TRUE - return FALSE - -/datum/antagonist/bloodsucker/proc/get_level_cost() - var/percentage_needed = my_clan ? my_clan.level_cost : BLOODSUCKER_LEVELUP_PERCENTAGE - return max_blood_volume * percentage_needed - -/datum/antagonist/bloodsucker/proc/max_ghouls() - return round(bloodsucker_level * 0.5) - -/datum/antagonist/bloodsucker/proc/free_ghoul_slots() - return max(max_ghouls() - length(ghouls), 0) - -/datum/antagonist/bloodsucker/proc/frenzy_enter_threshold() - return FRENZY_THRESHOLD_ENTER + (humanity_lost * 10) - -/datum/antagonist/bloodsucker/proc/frenzy_exit_threshold() - return FRENZY_THRESHOLD_EXIT + (humanity_lost * 10) - -/datum/antagonist/bloodsucker/proc/on_organ_removal(mob/living/carbon/old_owner, obj/item/organ/organ, special) - SIGNAL_HANDLER - if(old_owner?.get_organ_slot(ORGAN_SLOT_HEART) || organ?.slot != ORGAN_SLOT_HEART || !old_owner?.dna?.species.mutantheart) - return - DisableAllPowers(TRUE) - if(HAS_TRAIT_FROM_ONLY(old_owner, TRAIT_NODEATH, BLOODSUCKER_TRAIT)) - torpor_end(TRUE) - to_chat(old_owner, span_userdanger("You have lost your [organ.slot]!")) - to_chat(old_owner, span_warning("This means you will no longer enter torpor nor revive from death, and you will no longer heal any damage, nor can you use your abilities.")) - -/// checks if we're a brainmob inside a brain & the brain is inside a head -/datum/antagonist/bloodsucker/proc/is_head(mob/living/poor_fucker) - if(!istype(poor_fucker?.loc, /obj/item/organ/brain)) - return - var/obj/brain = poor_fucker.loc - if(!istype(brain?.loc, /obj/item/bodypart/head)) - return - return brain.loc - -// helper procs for damage checking, just in case a synth becomes one, let's them heal thesmelves -/datum/antagonist/bloodsucker/proc/get_brute_loss() - var/mob/living/carbon/human/humie = owner.current - return issynthetic(humie) ? humie.get_brute_loss() : humie.get_brute_loss_nonProsthetic() - -/datum/antagonist/bloodsucker/proc/get_fire_loss() - var/mob/living/carbon/human/humie = owner.current - return issynthetic(humie) ? humie.get_fire_loss() : humie.get_fire_loss_nonProsthetic() - -/datum/antagonist/bloodsucker/proc/admin_set_blood(mob/admin) - var/blood = tgui_input_number(admin, "What blood level to set [owner.current]'s to?", "Blood is life.", floor(bloodsucker_blood_volume), max_blood_volume, 0) - // 0 input is falsey - if(blood == null) - return - SetBloodVolume(blood) - -/datum/antagonist/bloodsucker/proc/admin_rankup(mob/admin) - to_chat(admin, span_notice("[owner.current] has been given a free level")) - RankUp() - -/datum/antagonist/bloodsucker/proc/admin_give_power(mob/admin) - var/power_type = tgui_input_list(admin, "What power to give [owner.current]?", "Might is right.", all_bloodsucker_powers) - if(!power_type) - return - var/datum/action/cooldown/bloodsucker/power = BuyPower(power_type) - power.upgrade_power() - -/datum/antagonist/bloodsucker/proc/admin_remove_power(mob/admin) - var/datum/action/cooldown/bloodsucker/power = tgui_input_list(admin, "What power to remove from [owner.current]?", "Might is right.", powers) - if(!power) - return - RemovePower(power) - -/datum/antagonist/bloodsucker/proc/admin_set_power_level(mob/admin) - var/list/valid_powers = list() - for(var/datum/action/cooldown/bloodsucker/power as anything in powers) - if(power.purchase_flags & BLOODSUCKER_DEFAULT_POWER) - continue - valid_powers += power - var/datum/action/cooldown/bloodsucker/power = tgui_input_list(admin, "What power to set the level of for [owner.current]?", "Might is right.", valid_powers) - if(!power) - return - var/level = tgui_input_number(admin, "What level to set [power] to?", "Might is right.", power.level_current, 30, 0) - if(level == null) - return - power.level_current = level - power.on_power_upgrade() - -/datum/antagonist/bloodsucker/proc/regain_heart(mob/living/carbon/target, obj/structure/closet/crate/coffin/coffin) - var/obj/item/organ/heart = locate(/obj/item/organ/heart) in coffin.contents - if(heart && !target.get_organ_slot(ORGAN_SLOT_HEART) && heart.Insert(target)) - to_chat(target, span_warning("You have regained your heart!")) - -/datum/antagonist/bloodsucker/proc/allow_head_to_talk(mob/speaker, message, ignore_spam, forced) - SIGNAL_HANDLER - if(!is_head(speaker) || speaker.stat >= UNCONSCIOUS) - return - return COMPONENT_IGNORE_CAN_SPEAK - -/datum/antagonist/bloodsucker/proc/shake_head_on_talk(mob/speaker, speech_args) - SIGNAL_HANDLER - var/obj/head = is_head(speaker) - if(!head) - return - var/animation_time = max(2, length_char(speech_args[SPEECH_MESSAGE]) * 0.5) - head.Shake(duration = animation_time) - -/datum/antagonist/bloodsucker/proc/stake_can_kill() - if(owner.current.IsSleeping() || owner.current.stat >= UNCONSCIOUS || is_in_torpor()) - for(var/stake in get_stakes()) - var/obj/item/stake/killin_stake = stake - if(killin_stake?.kills_blodsuckers) - return TRUE - return FALSE - -/datum/antagonist/bloodsucker/proc/am_staked() - var/obj/item/bodypart/chosen_bodypart = owner.current.get_bodypart(BODY_ZONE_CHEST) - if(!chosen_bodypart) - return FALSE - var/obj/item/stake/stake = locate() in chosen_bodypart.embedded_objects - return stake - -/datum/antagonist/bloodsucker/proc/get_stakes() - var/obj/item/bodypart/chosen_bodypart = owner.current.get_bodypart(BODY_ZONE_CHEST) - if(!chosen_bodypart) - return FALSE - var/list/stakes = list() - for(var/obj/item/embedded_stake in chosen_bodypart.embedded_objects) - if(istype(embedded_stake, /obj/item/stake)) - stakes += list(embedded_stake) - return stakes - -/datum/antagonist/bloodsucker/proc/on_staked(atom/target, forced) - SIGNAL_HANDLER - if(stake_can_kill()) - FinalDeath() - else - to_chat(target, span_userdanger("You have been staked! Your powers are useless, your death forever, while it remains in place.")) - target.balloon_alert(target, "you have been staked!") - -/// is it something that is close enough to a coffin to let us heal/level up in it? -/datum/antagonist/bloodsucker/proc/is_valid_coffin() - if(istype(owner.current.loc, /obj/structure/closet/crate/coffin)) - return TRUE - // if(istype(owner.current.loc, /obj/structure/closet/crate/grave)) - // return TRUE - return FALSE - -/datum/antagonist/bloodsucker/proc/on_enter_coffin(mob/living/carbon/target, obj/structure/closet/crate/coffin/coffin, mob/living/carbon/user) - SIGNAL_HANDLER - check_limbs(COFFIN_HEAL_COST_MULT) - regain_heart(target, coffin) - if(!check_begin_torpor()) - heal_vampire_organs() - if(user == owner.current && (user in coffin)) - if(can_claim_coffin(coffin, get_area(coffin))) - INVOKE_ASYNC(src, PROC_REF(try_claim_coffin), coffin) - else - INVOKE_ASYNC(src, PROC_REF(try_coffin_level_up)) - -/datum/antagonist/bloodsucker/proc/try_claim_coffin(obj/structure/closet/crate/coffin/coffin) - if(coffin.prompt_coffin_claim(src)) - try_coffin_level_up() - -/datum/antagonist/bloodsucker/proc/try_coffin_level_up() - var/mob/living/carbon/user = owner.current - //Level up if possible. - if(!my_clan) - user.balloon_alert(user, "enter a clan!") - to_chat(user, span_notice("You must enter a Clan to rank up. Do it in the antag menu, which you can see by pressing the action button in the top left.")) - else if(!frenzied) - if(GetUnspentRank() < 1) - blood_level_gain() - // Level ups cost 30% of your max blood volume, which scales with your rank. - SpendRank() - -/datum/antagonist/bloodsucker/proc/on_owner_deletion(mob/living/deleted_mob) - SIGNAL_HANDLER - free_all_ghouls() - if(deleted_mob != owner.current) - return - if(is_head(deleted_mob)) - on_brainmob_qdel() - -/datum/antagonist/bloodsucker/proc/register_body_signals(mob/target) - for(var/signal in body_signals) - RegisterSignal(target, signal, body_signals[signal]) - -/datum/antagonist/bloodsucker/proc/unregister_body_signals(mob/target) - for(var/signal in body_signals) - UnregisterSignal(target, signal) diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/shaded_bloodsucker.dm b/tff_modular/modules/bloodsucker/bloodsuckers/shaded_bloodsucker.dm deleted file mode 100644 index 4f9d905cafa..00000000000 --- a/tff_modular/modules/bloodsucker/bloodsuckers/shaded_bloodsucker.dm +++ /dev/null @@ -1,5 +0,0 @@ -///a malkavian bloodsucker that has entered final death. does nothing, other than signify they are dead - -/obj/item/soulstone/bloodsucker - theme = THEME_WIZARD - required_role = null diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/sol.dm b/tff_modular/modules/bloodsucker/bloodsuckers/sol.dm deleted file mode 100644 index 18f6b488083..00000000000 --- a/tff_modular/modules/bloodsucker/bloodsuckers/sol.dm +++ /dev/null @@ -1,121 +0,0 @@ - -/** - * # Assigning Sol - * - * Sol is a legacy name, now simply referring to the system used to give all vampires free levels at the same time. - */ - -/// Start Sol, called when someone is assigned Bloodsucker -/datum/antagonist/bloodsucker/proc/check_start_sunlight() - var/list/existing_suckers = get_antag_minds(/datum/antagonist/bloodsucker) - owner - if(!length(existing_suckers)) - message_admins("New Sol has been created due to Bloodsucker assignment.") - SSsol.can_fire = TRUE - -/// End Sol, if you're the last Bloodsucker -/datum/antagonist/bloodsucker/proc/check_cancel_sunlight() - var/list/existing_suckers = get_antag_minds(/datum/antagonist/bloodsucker) - owner - if(!length(existing_suckers)) - message_admins("Sol has been deleted due to the lack of Bloodsuckers") - SSsol.can_fire = FALSE - -///Ranks the Bloodsucker up, called by Sol. -/datum/antagonist/bloodsucker/proc/sol_rank_up(atom/source) - SIGNAL_HANDLER - - if(sol_levels_remaining > 0) - sol_levels_remaining-- - INVOKE_ASYNC(src, PROC_REF(RankUp)) - -/** - * # Torpor - * - * Torpor is what deals with the Bloodsucker falling asleep, their healing, the effects, ect. - * This is basically what Sol is meant to do to them, but they can also trigger it manually if they wish to heal, as Burn is only healed through Torpor. - * You cannot manually exit Torpor, it is instead entered/exited by: - * - * Torpor is triggered by: - * - Being in a Coffin while Sol is on, dealt with by Sol - * - Entering a Coffin with more than 10 combined Brute/Burn damage, dealt with by /datum/antagonist/bloodsucker/on_enter_coffin() [procs.dm] - * - Death, dealt with by /HandleDeath() - * Torpor is ended by: - * - Having less than maxHealth * 0.8 damage while OUTSIDE of your Coffin while it isnt Sol. - * - Having less than 10 Damage Combined while INSIDE of your Coffin while it isnt Sol. - * - Sol being over, dealt with by /datum/controller/subsystem/processing/sunlight/process() [sol_subsystem.dm] -*/ -/datum/antagonist/bloodsucker/proc/check_begin_torpor(SkipChecks = FALSE) - var/mob/living/carbon/user = owner.current - if(QDELETED(user)) - return - /// Are we entering Torpor via Sol/Death? Then entering it isnt optional! - if(SkipChecks) - torpor_begin() - return - if(user.has_status_effect(/datum/status_effect/frenzy)) - to_chat(user, span_userdanger("You are restless! Collect enough blood to end your frenzy.")) - return - var/total_brute = user.get_brute_loss_nonProsthetic() - var/total_burn = user.get_fire_loss_nonProsthetic() - var/total_damage = total_brute + total_burn - /// Checks - Not daylight & Has more than 10 Brute/Burn & not already in Torpor - if((total_damage >= 10 || length(user.get_missing_limbs()) > 0) && !is_in_torpor()) - torpor_begin() - -/datum/antagonist/bloodsucker/proc/check_end_torpor() - var/mob/living/carbon/user = owner.current - if(QDELETED(user)) - return - var/total_brute = user.get_brute_loss_nonProsthetic() - var/total_burn = user.get_fire_loss_nonProsthetic() - var/total_damage = total_brute + total_burn - if(total_burn >= 199) - return FALSE - - // You are in a Coffin, so instead we'll check TOTAL damage, here. - if(istype(user.loc, /obj/structure/closet/crate/coffin)) - if(total_damage <= 10 && length(user.get_missing_limbs()) == 0) - torpor_end() - else - if(total_brute <= 10) - torpor_end() - if(COOLDOWN_FINISHED(src, bloodsucker_torpor_max_time)) - torpor_end() // YOUR TAKING TOO LONG - -/datum/antagonist/bloodsucker/proc/is_in_torpor() - if(QDELETED(owner.current)) - return FALSE - return HAS_TRAIT_FROM(owner.current, TRAIT_NODEATH, TORPOR_TRAIT) - -/datum/antagonist/bloodsucker/proc/torpor_begin() - var/mob/living/current = owner.current - if(QDELETED(current)) - return - to_chat(current, span_notice("You enter the horrible slumber of deathless Torpor. You will heal until you are renewed.")) - // Force them to go to sleep - REMOVE_TRAIT(current, TRAIT_SLEEPIMMUNE, BLOODSUCKER_TRAIT) - // Without this, you'll just keep dying while you recover. - current.add_traits(torpor_traits, TORPOR_TRAIT) - current.set_timed_status_effect(0 SECONDS, /datum/status_effect/jitter, only_if_higher = TRUE) - //monkestation edit - // Failsafe to prevent players taking too long in torpor - COOLDOWN_START(src, bloodsucker_torpor_max_time, BLOODSUCKER_TORPOR_MAX_TIME) - //monkestation end - // Disable ALL Powers - DisableAllPowers() - -/datum/antagonist/bloodsucker/proc/torpor_end() - var/mob/living/current = owner.current - if(QDELETED(current)) - return - - if(!COOLDOWN_FINISHED(src, bloodsucker_torpor_max_time)) - COOLDOWN_RESET(src, bloodsucker_torpor_max_time) - - current.grab_ghost() - to_chat(current, span_warning("You have recovered from Torpor.")) - current.remove_traits(torpor_traits, TORPOR_TRAIT) - if(!HAS_TRAIT(current, TRAIT_MASQUERADE)) - ADD_TRAIT(current, TRAIT_SLEEPIMMUNE, BLOODSUCKER_TRAIT) - heal_vampire_organs() - current.update_stat() - SEND_SIGNAL(src, COMSIG_BLOODSUCKER_EXIT_TORPOR) diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/species.dm b/tff_modular/modules/bloodsucker/bloodsuckers/species.dm deleted file mode 100644 index 7321cd1f1ef..00000000000 --- a/tff_modular/modules/bloodsucker/bloodsuckers/species.dm +++ /dev/null @@ -1,84 +0,0 @@ -/datum/species - var/sort_bottom = FALSE -//Whether or not a given species is sorted to the bottom of the list. We mainly want to do this for species that are used only for ghostroles, and template species. - -/// Called once the target is made into a bloodsucker. Used for removing conflicting species organs mostly -/datum/species/proc/on_bloodsucker_gain(mob/living/carbon/human/target) - return null - -/datum/species/proc/on_bloodsucker_loss(mob/living/carbon/human/target) - return null - -/// Replaces a couple organs to normal variants to not cause issues. Not super happy with this, alternative is disallowing vampiric races from being bloodsuckers -/datum/species/proc/humanize_organs(mob/living/carbon/human/target, organs = list()) - if(!organs || !length(organs)) - organs = list( - ORGAN_SLOT_HEART = /obj/item/organ/heart, - ORGAN_SLOT_LIVER = /obj/item/organ/liver, - ORGAN_SLOT_STOMACH = /obj/item/organ/stomach, - ORGAN_SLOT_TONGUE = /obj/item/organ/tongue, - ) - mutantheart = organs[ORGAN_SLOT_HEART] - mutantliver = organs[ORGAN_SLOT_LIVER] - mutantstomach = organs[ORGAN_SLOT_STOMACH] - mutanttongue = organs[ORGAN_SLOT_TONGUE] - for(var/organ_slot in organs) - var/obj/item/organ/old_organ = target.get_organ_slot(organ_slot) - var/organ_path = organs[organ_slot] - if(old_organ?.type == organ_path) - continue - var/obj/item/organ/new_organ = SSwardrobe.provide_type(organ_path) - new_organ.Insert(target, FALSE, DELETE_IF_REPLACED) - -/datum/species/proc/normalize_organs(mob/living/carbon/human/target) - mutantheart = initial(mutantheart) - mutantliver = initial(mutantliver) - mutantstomach = initial(mutantstomach) - mutanttongue = initial(mutanttongue) - regenerate_organs(target, replace_current = TRUE) - - -/datum/species/get_species_description() - SHOULD_CALL_PARENT(FALSE) - - //stack_trace("Species [name] ([type]) did not have a description set, and is a selectable roundstart race! Override get_species_description.") - return list("No species description set, file a bug report!",) - -/datum/language/vampiric - name = "Enochian" - desc = "Rumored to be created by the Dark Father, Caine himself as a way to talk to his Childer, the truth, like many things in unlife is uncertain. Spoken by creatures of the night." - key = "L"//Capital L, lowercase l is for ashies. - space_chance = 40 - default_priority = 90 - - flags = TONGUELESS_SPEECH | LANGUAGE_HIDE_ICON_IF_NOT_UNDERSTOOD - syllables = list( - "luk","cha","no","kra","pru","chi","busi","tam","pol","spu","och", - "umf","ora","stu","si","ri","li","ka","red","ani","lup","ala","pro", - "to","siz","nu","pra","ga","ump","ort","a","ya","yach","tu","lit", - "wa","mabo","mati","anta","tat","tana","prol", - "tsa","si","tra","te","ele","fa","inz", - "nza","est","sti","ra","pral","tsu","ago","esch","chi","kys","praz", - "froz","etz","tzil", - "t'","k'","t'","k'","th'","tz'" - ) - - icon_state = "bloodsucker" - icon = 'tff_modular/modules/bloodsucker/icons/language.dmi' - secret = TRUE - -// second fallback just in case the map is missing both the curator display case and codex gigas -/datum/job/curator/after_spawn(mob/living/spawned, client/player_client) - mind_traits += (TRAIT_BLOODSUCKER_HUNTER) - . = ..() - var/list/points_of_interest = SSpoints_of_interest.get_other_pois() - var/obj/item/book/kindred/book_to_spawn - for(var/poi in points_of_interest) - var/thing = points_of_interest[poi] - if(istype(thing, /obj/item/book/kindred)) - return - book_to_spawn = new(get_turf(spawned)) - if(iscarbon(spawned)) - var/mob/living/carbon/carbon_spawned = spawned - // Not suspicious but convenient in this case - carbon_spawned.equip_conspicuous_item(book_to_spawn, FALSE) diff --git a/tff_modular/modules/bloodsucker/clans/clan.dm b/tff_modular/modules/bloodsucker/clans/clan.dm deleted file mode 100644 index d72e97b3d05..00000000000 --- a/tff_modular/modules/bloodsucker/clans/clan.dm +++ /dev/null @@ -1,341 +0,0 @@ -/** - * Bloodsucker clans - * - * Handles everything related to clans. - * the entire idea of datumizing this came to me in a dream. - */ -/datum/bloodsucker_clan - ///The bloodsucker datum that owns this clan. Use this over 'source', because while it's the same thing, this is more consistent (and used for deletion). - var/datum/antagonist/bloodsucker/bloodsuckerdatum - ///The name of the clan we're in. - var/name = CLAN_NONE - ///Description of what the clan is, given when joining and through your antag UI. - var/description = "The Caitiff is as basic as you can get with Bloodsuckers. \n\ - Entirely without the help of a formal Clan, they are blissfully unaware of who they really are. \n\ - No additional abilities is gained, nothing is lost, if you want a plain Bloodsucker, this is it. \n\ - The Favorite Ghoul will gain the Brawn ability, to help in combat." - ///The clan objective that is required to greentext. - var/datum/objective/bloodsucker/clan_objective - ///The icon of the radial icon to join this clan. - var/join_icon = 'tff_modular/modules/bloodsucker/icons/clan_icons.dmi' - ///Same as join_icon, but the state - var/join_icon_state = "caitiff" - ///Description shown when trying to join the clan. - var/join_description = "The default, Classic Bloodsucker." - ///Whether the clan can be joined by players. FALSE for flavortext-only clans. - var/joinable_clan = TRUE - - ///How we will drink blood using Feed. - var/blood_drink_type = BLOODSUCKER_DRINK_NORMAL - /// How much stamina armor we get in frenzy - var/frenzy_stamina_mod = 0.4 - var/buy_power_flags = BLOODSUCKER_CAN_BUY - // what percentage of blood you need to spend to level up, divided by 100 - var/level_cost = BLOODSUCKER_LEVELUP_PERCENTAGE - // what bonus do we get for prince vote - var/princely_score_bonus = -10 - -// TODO add handling for body transfers -/datum/bloodsucker_clan/New(datum/antagonist/bloodsucker/owner_datum) - . = ..() - src.bloodsuckerdatum = owner_datum - - RegisterSignal(bloodsuckerdatum, COMSIG_BLOODSUCKER_ON_LIFETICK, PROC_REF(handle_clan_life)) - RegisterSignal(bloodsuckerdatum, COMSIG_BLOODSUCKER_RANK_UP, PROC_REF(on_spend_rank)) - - RegisterSignal(bloodsuckerdatum, COMSIG_BLOODSUCKER_INTERACT_WITH_GHOUL, PROC_REF(on_interact_with_ghoul)) - RegisterSignal(bloodsuckerdatum, COMSIG_BLOODSUCKER_MAKE_FAVORITE, PROC_REF(favorite_ghoul_gain)) - RegisterSignal(bloodsuckerdatum, COMSIG_BLOODSUCKER_LOOSE_FAVORITE, PROC_REF(favorite_ghoul_loss)) - - RegisterSignal(bloodsuckerdatum, COMSIG_BLOODSUCKER_MADE_GHOUL, PROC_REF(on_ghoul_made)) - RegisterSignal(bloodsuckerdatum, COMSIG_BLOODSUCKER_EXIT_TORPOR, PROC_REF(on_exit_torpor)) - RegisterSignal(bloodsuckerdatum, COMSIG_BLOODSUCKER_FINAL_DEATH, PROC_REF(on_final_death)) - - RegisterSignal(bloodsuckerdatum, COMSIG_BLOODSUCKER_ENTERS_FRENZY, PROC_REF(on_enter_frenzy)) - RegisterSignal(bloodsuckerdatum, COMSIG_BLOODSUCKER_EXITS_FRENZY, PROC_REF(on_exit_frenzy)) - - give_clan_objective() - -/datum/bloodsucker_clan/Destroy(force) - UnregisterSignal(bloodsuckerdatum, list( - COMSIG_BLOODSUCKER_ON_LIFETICK, - COMSIG_BLOODSUCKER_RANK_UP, - COMSIG_BLOODSUCKER_INTERACT_WITH_GHOUL, - COMSIG_BLOODSUCKER_MAKE_FAVORITE, - COMSIG_BLOODSUCKER_MADE_GHOUL, - COMSIG_BLOODSUCKER_EXIT_TORPOR, - COMSIG_BLOODSUCKER_FINAL_DEATH, - COMSIG_BLOODSUCKER_ENTERS_FRENZY, - COMSIG_BLOODSUCKER_EXITS_FRENZY, - )) - remove_clan_objective() - bloodsuckerdatum = null - return ..() - -/datum/bloodsucker_clan/proc/on_enter_frenzy(datum/antagonist/bloodsucker/source) - SIGNAL_HANDLER - var/mob/living/carbon/human/human_bloodsucker = bloodsuckerdatum.owner.current - if(!istype(human_bloodsucker)) - return - human_bloodsucker.physiology.stamina_mod *= frenzy_stamina_mod - -/datum/bloodsucker_clan/proc/on_exit_frenzy(datum/antagonist/bloodsucker/source) - SIGNAL_HANDLER - var/mob/living/carbon/human/human_bloodsucker = bloodsuckerdatum.owner.current - if(!istype(human_bloodsucker)) - return - human_bloodsucker.set_timed_status_effect(3 SECONDS, /datum/status_effect/dizziness, only_if_higher = TRUE) - human_bloodsucker.Paralyze(2 SECONDS) - human_bloodsucker.physiology.stamina_mod /= frenzy_stamina_mod - -/datum/bloodsucker_clan/proc/give_clan_objective() - if(isnull(clan_objective)) - return - clan_objective = new clan_objective() - clan_objective.objective_name = "Clan Objective" - clan_objective.owner = bloodsuckerdatum.owner - bloodsuckerdatum.objectives += clan_objective - bloodsuckerdatum.owner.announce_objectives() - -/datum/bloodsucker_clan/proc/remove_clan_objective() - bloodsuckerdatum.objectives -= clan_objective - QDEL_NULL(clan_objective) - bloodsuckerdatum.owner.announce_objectives() - -/** - * Called when a Bloodsucker exits Torpor - * args: - * source - the Bloodsucker exiting Torpor - */ -/datum/bloodsucker_clan/proc/on_exit_torpor(datum/antagonist/bloodsucker/source) - SIGNAL_HANDLER - -/** - * Called when a Bloodsucker enters Final Death - * args: - * source - the Bloodsucker exiting Torpor - */ -/datum/bloodsucker_clan/proc/on_final_death(datum/antagonist/bloodsucker/source) - SIGNAL_HANDLER - return FALSE - -/** - * Called during Bloodsucker's LifeTick - * args: - * bloodsuckerdatum - the antagonist datum of the Bloodsucker running this. - */ -/datum/bloodsucker_clan/proc/handle_clan_life(datum/antagonist/bloodsucker/source, seconds_per_tick, times_fired) - SIGNAL_HANDLER - -/** - * Called when a Bloodsucker successfully Ghoulizes someone. - * args: - * bloodsuckerdatum - the antagonist datum of the Bloodsucker running this. - */ -/datum/bloodsucker_clan/proc/on_ghoul_made(datum/antagonist/bloodsucker/source, mob/living/user, mob/living/target) - SIGNAL_HANDLER - user.playsound_local(null, 'sound/effects/explosion/explosion_distant.ogg', 40, TRUE) - target.playsound_local(null, 'sound/effects/singlebeat.ogg', 40, TRUE) - target.set_timed_status_effect(15 SECONDS, /datum/status_effect/jitter, only_if_higher = TRUE) - INVOKE_ASYNC(target, TYPE_PROC_REF(/mob, emote), "laugh") - -/** - * Called when a Bloodsucker successfully starts spending their Rank - * args: - * bloodsuckerdatum - the antagonist datum of the Bloodsucker running this. - * target - The Ghoul (if any) we are upgrading. - * cost_rank - TRUE/FALSE on whether this will cost us a rank when we go through with it. - * blood_cost - A number saying how much it costs to rank up. - */ -/datum/bloodsucker_clan/proc/on_spend_rank(datum/antagonist/bloodsucker/source, mob/living/carbon/human/target, cost_rank = TRUE, blood_cost, force) - SIGNAL_HANDLER - - INVOKE_ASYNC(src, PROC_REF(spend_rank), bloodsuckerdatum, cost_rank, blood_cost) - -/datum/bloodsucker_clan/proc/spend_rank(datum/antagonist/bloodsucker/source, cost_rank = TRUE, blood_cost, requires_coffin = TRUE) - var/list/options = list_available_powers() - if(length(options)) - var/datum/action/cooldown/bloodsucker/choice = choose_powers( - "You have the opportunity to grow more ancient. [blood_cost > 0 ? " Spend [round(blood_cost, 1)] blood to advance your rank" : ""]", - "Your Blood Thickens...", - options - ) - if(!is_valid_choice(choice, cost_rank, blood_cost, requires_coffin)) - return FALSE - // Good to go - Buy Power! - purchase_choice(source, choice) - level_message(initial(choice.name)) - - return finalize_spend_rank(bloodsuckerdatum, cost_rank, blood_cost) - -/datum/bloodsucker_clan/proc/level_message(power_name) - var/mob/living/carbon/human/human_user = bloodsuckerdatum.owner.current - human_user.balloon_alert(human_user, "learned [power_name]!") - to_chat(human_user, span_notice("You have learned how to use [power_name]!")) - -/datum/bloodsucker_clan/proc/choose_powers(message, title, options = list()) - var/mob/living/carbon/human/human_user = bloodsuckerdatum.owner.current - if(!length(options)) - return FALSE - - var/choice = tgui_input_list(human_user, message, title, options) - return options[choice] - -/datum/bloodsucker_clan/proc/is_valid_choice(datum/action/cooldown/bloodsucker/power, cost_rank, blood_cost, requires_coffin) - var/mob/living/carbon/human/human_user = bloodsuckerdatum.owner.current - if(!power) - return FALSE - if(cost_rank && bloodsuckerdatum.GetUnspentRank() <= 0) - return FALSE - if(blood_cost && bloodsuckerdatum.GetBloodVolume() < blood_cost) - human_user.balloon_alert(human_user, "not enough blood!") - to_chat(human_user, span_notice("You need at the very least [blood_cost] blood to thicken your blood.")) - return FALSE - // Prevent Bloodsuckers from purchasing a power while outside of their Coffin. - if(requires_coffin && !istype(human_user.loc, /obj/structure/closet/crate/coffin)) - to_chat(human_user, span_warning("You must be in your Coffin to purchase Powers.")) - return FALSE - if(!(initial(power.purchase_flags) & buy_power_flags)) - to_chat(human_user, span_notice("[initial(power.name)] is not available for purchase.")) - return FALSE - if(!(buy_power_flags & CAN_BUY_OWNED) && locate(power) in bloodsuckerdatum.powers) - to_chat(human_user, span_notice("You already know [initial(power.name)]!")) - return FALSE - return TRUE - -/datum/bloodsucker_clan/proc/finalize_spend_rank(datum/antagonist/bloodsucker/source, cost_rank = TRUE, blood_cost) - level_up_powers(source) - bloodsuckerdatum.bloodsucker_regen_rate += 0.1 - bloodsuckerdatum.max_blood_volume += 100 - - if(ishuman(bloodsuckerdatum.owner.current)) - var/mob/living/carbon/human/human_user = bloodsuckerdatum.owner.current - var/obj/item/bodypart/user_left_hand = human_user.get_bodypart(BODY_ZONE_L_ARM) - var/obj/item/bodypart/user_right_hand = human_user.get_bodypart(BODY_ZONE_R_ARM) - user_left_hand.unarmed_damage_low += 0.5 - user_right_hand.unarmed_damage_low += 0.5 - // This affects the hitting power of Brawn. - user_left_hand.unarmed_damage_high += 0.5 - user_right_hand.unarmed_damage_high += 0.5 - - // We're almost done - Spend your Rank now. - bloodsuckerdatum.AdjustRank(1) - if(cost_rank) - bloodsuckerdatum.AdjustUnspentRank(-1) - - if(blood_cost) - bloodsuckerdatum.AdjustBloodVolume(-blood_cost) - - // Ranked up enough to get your true Reputation? - if(bloodsuckerdatum.GetRank() == BLOODSUCKER_HIGH_LEVEL) - bloodsuckerdatum.SelectReputation(am_fledgling = FALSE, forced = TRUE) - - - to_chat(bloodsuckerdatum.owner.current, span_notice("You are now a rank [bloodsuckerdatum.GetRank()] Bloodsucker. \ - Your strength, feed rate, regen rate, and maximum blood capacity have all increased! \n\ - * Your existing powers have all ranked up as well!")) - bloodsuckerdatum.owner.current.playsound_local(null, 'sound/effects/pope_entry.ogg', 25, TRUE, pressure_affected = FALSE) - bloodsuckerdatum.update_static_data_for_all_viewers() - - // unlock ghoulizing if we have a ghoul slot - if(bloodsuckerdatum.max_ghouls() >= 1 && !(/datum/crafting_recipe/ghoulrack in bloodsuckerdatum.owner?.learned_recipes)) - bloodsuckerdatum.owner.teach_crafting_recipe(/datum/crafting_recipe/ghoulrack) - bloodsuckerdatum.owner.teach_crafting_recipe(/datum/crafting_recipe/candelabrum) - bloodsuckerdatum.owner.teach_crafting_recipe(/datum/crafting_recipe/bloodthrone) - bloodsuckerdatum.owner.teach_crafting_recipe(/datum/crafting_recipe/meatcoffin) - bloodsuckerdatum.owner.current.balloon_alert(bloodsuckerdatum.owner.current, "new recipes learned! Ghouling unlocked!") - return TRUE - - -/datum/bloodsucker_clan/proc/list_available_powers(already_known = bloodsuckerdatum.powers, powers_list = bloodsuckerdatum.all_bloodsucker_powers) - var/list/options = list() - for(var/datum/action/cooldown/bloodsucker/power as anything in powers_list) - if(initial(power.purchase_flags) & buy_power_flags && !(locate(power) in already_known)) - options[initial(power.name)] = power - return options - -/datum/bloodsucker_clan/proc/purchase_choice(datum/antagonist/bloodsucker/source, datum/action/cooldown/bloodsucker/purchased_power) - return bloodsuckerdatum.BuyPower(purchased_power) - -/datum/bloodsucker_clan/proc/level_up_powers(datum/antagonist/bloodsucker/source) - bloodsuckerdatum.LevelUpPowers() -/** - * Called when we are trying to turn someone into a Favorite Ghoul - * args: - * bloodsuckerdatum - the antagonist datum of the Bloodsucker performing this. - * ghouldatum - the antagonist datum of the Ghoul being offered up. - */ -/datum/bloodsucker_clan/proc/on_interact_with_ghoul(datum/antagonist/bloodsucker/source, datum/antagonist/ghoul/ghouldatum) - SIGNAL_HANDLER - - INVOKE_ASYNC(src, PROC_REF(interact_with_ghoul), bloodsuckerdatum, ghouldatum) - -/datum/bloodsucker_clan/proc/interact_with_ghoul(datum/antagonist/bloodsucker/source, datum/antagonist/ghoul/ghouldatum) - var/mob/living/carbon/human/master = bloodsuckerdatum.owner.current - var/mob/living/carbon/human/servant = ghouldatum.owner.current - if(ghouldatum.special_type || IS_BLOODSUCKER(servant)) - to_chat(master, span_notice("This Ghoul was already assigned a special position.")) - return FALSE - if(!ghouldatum.owner.can_make_special(creator = bloodsuckerdatum.owner)) - to_chat(master, span_notice("This Ghoul is unable to gain a Special rank due to innate features.")) - return FALSE - if(bloodsuckerdatum.GetBloodVolume() < SPECIAL_GHOUL_COST) - to_chat(master, span_notice("You need at least 150 blood to make a Ghoul a Favorite Ghoul.")) - return FALSE - var/list/options = list() - var/list/radial_display = list() - for(var/datum/antagonist/ghoul/ghouldatums as anything in subtypesof(/datum/antagonist/ghoul)) - var/ghoul_type = initial(ghouldatums.special_type) - var/slot = bloodsuckerdatum.special_ghouls[ghoul_type] - if(ghoul_type && slot) - continue - options[initial(ghouldatums.name)] = ghouldatums - - var/datum/radial_menu_choice/option = new - option.image = image(icon = initial(ghouldatums.hud_icon), icon_state = initial(ghouldatums.antag_hud_name), pixel_y = -12, pixel_x = -12) - option.info = "[initial(ghouldatums.name)] - [span_boldnotice(initial(ghouldatums.ghoul_description))]" - radial_display[initial(ghouldatums.name)] = option - if(!length(options)) - master.balloon_alert(master, "out of Special Ghoul slots!") - return FALSE - - to_chat(master, span_notice("You can change who this Ghoul is, who are they to you? This will cost [SPECIAL_GHOUL_COST] blood.")) - var/ghoul_response = show_radial_menu(master, servant, radial_display) - if(!ghoul_response || !is_valid_ghoul(options[ghoul_response])) - return FALSE - var/datum/antagonist/ghoul/ghoul_type = options[ghoul_response] - - // let's ask if the ghoul themselves actually wants to be a favorite -#ifndef BLOODSUCKER_TESTING - servant.balloon_alert(master, "asking...") - var/ghoul_permission = tgui_alert(servant, initial(ghoul_type.ghoul_description), "Become a Special Ghoul?", list("Yes", "No"), 1 MINUTES) == "Yes" - if(!ghoul_permission) - servant.balloon_alert(master, "refused!") - return FALSE -#endif - if(QDELETED(src) || QDELETED(master) || QDELETED(servant) || !ghoul_type) - return FALSE - - if(bloodsuckerdatum.GetBloodVolume() < SPECIAL_GHOUL_COST) - to_chat(master, span_notice("You took too long to make your ghoul, you no longer have enough blood!")) - return FALSE - ghouldatum.make_special(ghoul_type) - bloodsuckerdatum.AdjustBloodVolume(-SPECIAL_GHOUL_COST) - return TRUE - -/datum/bloodsucker_clan/proc/is_valid_ghoul(datum/antagonist/ghoul/ghoul_type) - if(!ghoul_type) - return FALSE - return TRUE -/** - * Called when we are successfully turn a Ghoul into a Favorite Ghoul - * args: - * bloodsuckerdatum - antagonist datum of the Bloodsucker who turned them into a Ghoul. - * ghouldatum - the antagonist datum of the Ghoul being offered up. - */ -/datum/bloodsucker_clan/proc/favorite_ghoul_gain(datum/antagonist/bloodsucker/source, datum/antagonist/ghoul/ghouldatum) - SIGNAL_HANDLER - ghouldatum.BuyPower(/datum/action/cooldown/bloodsucker/targeted/brawn) - -/datum/bloodsucker_clan/proc/favorite_ghoul_loss(datum/antagonist/bloodsucker/source, datum/antagonist/ghoul/ghouldatum) - SIGNAL_HANDLER diff --git a/tff_modular/modules/bloodsucker/clans/clan_flavortext.dm b/tff_modular/modules/bloodsucker/clans/clan_flavortext.dm deleted file mode 100644 index b55cfce68ce..00000000000 --- a/tff_modular/modules/bloodsucker/clans/clan_flavortext.dm +++ /dev/null @@ -1,47 +0,0 @@ -/datum/bloodsucker_clan/gangrel - name = CLAN_GANGREL - description = "Closer to Animals than Bloodsuckers, known as Werewolves waiting to happen, \n\ - these are the most fearful of True Faith, being the most lethal thing they would ever see the night of. \n\ - Full Moons do not seem to have an effect, despite common-told stories. \n\ - The Favorite Ghoul turns into a Werewolf whenever their Master does." - joinable_clan = FALSE - blood_drink_type = BLOODSUCKER_DRINK_INHUMANELY - -/datum/bloodsucker_clan/gangrel/on_enter_frenzy(datum/antagonist/bloodsucker/source) - ADD_TRAIT(bloodsuckerdatum.owner.current, TRAIT_STUNIMMUNE, FRENZY_TRAIT) - -/datum/bloodsucker_clan/gangrel/on_exit_frenzy(datum/antagonist/bloodsucker/source) - REMOVE_TRAIT(bloodsuckerdatum.owner.current, TRAIT_STUNIMMUNE, FRENZY_TRAIT) - -/datum/bloodsucker_clan/gangrel/handle_clan_life(datum/antagonist/bloodsucker/source, seconds_per_tick, times_fired) - . = ..() - var/area/current_area = get_area(bloodsuckerdatum.owner.current) - if(istype(current_area, /area/station/service/chapel)) - to_chat(bloodsuckerdatum.owner.current, span_warning("You don't belong in holy areas! The Faith burns you to a crisp!")) - bloodsuckerdatum.owner.current.adjust_fire_loss(20) - bloodsuckerdatum.owner.current.adjust_fire_stacks(2) - bloodsuckerdatum.owner.current.ignite_mob() - -/datum/bloodsucker_clan/toreador - name = CLAN_TOREADOR - description = "The most charming Clan of them all, allowing them to very easily disguise among the crew. \n\ - More in touch with their morals, they suffer and benefit more strongly from humanity cost or gain of their actions. \n\ - Known as 'The most humane kind of vampire', they have an obsession with perfectionism and beauty \n\ - The Favorite Ghoul gains the Mesmerize ability." - joinable_clan = FALSE - blood_drink_type = BLOODSUCKER_DRINK_SNOBBY - -/datum/bloodsucker_clan/brujah - name = CLAN_BRUJAH - description = "The Brujah Clan has proven to be the strongest in melee combat, boasting a powerful punch. \n\ - They also appear to be more calm than the others, entering their 'frenzies' whenever they want, but dont seem affected much by them. \n\ - Be wary, as they are fearsome warriors, rebels and anarchists, with an inclination towards Frenzy. \n\ - The Favorite Ghoul gains brawn and a massive increase in brute damage from punching." - joinable_clan = FALSE - -/datum/bloodsucker_clan/tzimisce - name = CLAN_TZIMISCE - description = "The Tzimisce Clan has no knowledge about it. \n\ - If you see one, you should probably run away.\n\ - *the rest of the page is full of undecipherable scribbles...*" - joinable_clan = FALSE diff --git a/tff_modular/modules/bloodsucker/clans/clan_malkavian.dm b/tff_modular/modules/bloodsucker/clans/clan_malkavian.dm deleted file mode 100644 index 027a109558e..00000000000 --- a/tff_modular/modules/bloodsucker/clans/clan_malkavian.dm +++ /dev/null @@ -1,101 +0,0 @@ -/datum/bloodsucker_clan/malkavian - name = CLAN_MALKAVIAN - description = "Little is documented about Malkavians. Complete insanity is the most common theme. \n\ - The Favorite Ghoul will suffer the same fate as the Master, while gaining the ability to tap into the madness when fighting." - join_icon_state = "malkavian" - join_description = "Completely insane. You gain constant hallucinations, become a prophet with unintelligable rambling, \ - and become the enforcer of the Masquerade code." - blood_drink_type = BLOODSUCKER_DRINK_INHUMANELY - /// The prob chance of a malkavian spouting a revelation. - var/max_madness_chance = 10 - var/min_madness_chance = 5 - princely_score_bonus = 6 - -/datum/bloodsucker_clan/malkavian/on_enter_frenzy(datum/antagonist/bloodsucker/source) - ADD_TRAIT(bloodsuckerdatum.owner.current, TRAIT_STUNIMMUNE, FRENZY_TRAIT) - -/datum/bloodsucker_clan/malkavian/on_exit_frenzy(datum/antagonist/bloodsucker/source) - REMOVE_TRAIT(bloodsuckerdatum.owner.current, TRAIT_STUNIMMUNE, FRENZY_TRAIT) - -/datum/bloodsucker_clan/malkavian/New(datum/antagonist/bloodsucker/owner_datum) - . = ..() - RegisterSignal(SSdcs, COMSIG_BLOODSUCKER_BROKE_MASQUERADE, PROC_REF(on_bloodsucker_broke_masquerade)) - ADD_TRAIT(bloodsuckerdatum.owner.current, TRAIT_XRAY_VISION, BLOODSUCKER_TRAIT) - var/mob/living/carbon/carbon_owner = bloodsuckerdatum.owner.current - if(istype(carbon_owner)) - carbon_owner.gain_trauma(/datum/brain_trauma/mild/hallucinations, TRAUMA_RESILIENCE_ABSOLUTE) - carbon_owner.gain_trauma(/datum/brain_trauma/special/bluespace_prophet/phobetor , TRAUMA_RESILIENCE_ABSOLUTE) - owner_datum.owner.current.update_sight() - - bloodsuckerdatum.owner.current.playsound_local(get_turf(bloodsuckerdatum.owner.current), 'sound/music/antag/creepalert.ogg', 80, FALSE, pressure_affected = FALSE, use_reverb = FALSE) - to_chat(bloodsuckerdatum.owner.current, span_hypnophrase("Welcome to the Malkavian...")) - -/datum/bloodsucker_clan/malkavian/Destroy(force) - UnregisterSignal(SSdcs, COMSIG_BLOODSUCKER_BROKE_MASQUERADE) - REMOVE_TRAIT(bloodsuckerdatum.owner.current, TRAIT_XRAY_VISION, BLOODSUCKER_TRAIT) - var/mob/living/carbon/carbon_owner = bloodsuckerdatum.owner.current - if(istype(carbon_owner)) - carbon_owner.cure_trauma_type(/datum/brain_trauma/mild/hallucinations, TRAUMA_RESILIENCE_ABSOLUTE) - carbon_owner.cure_trauma_type(/datum/brain_trauma/special/bluespace_prophet/phobetor, TRAUMA_RESILIENCE_ABSOLUTE) - bloodsuckerdatum.owner.current.update_sight() - return ..() - -/datum/bloodsucker_clan/malkavian/handle_clan_life(datum/antagonist/bloodsucker/source, seconds_per_tick, times_fired) - . = ..() - // Using linear interpolation to calculate the chance of a revelation. The more humanity lost, the higher the chance. - // This is the reversed version since we want to increase the prob as the number decreases. - // Equation: interpolated value = end + normalized factor * (start - end) - // normalized factor(between 0 and 1, in decimals) - var/humanity_lost_modifier = source.GetHumanityLost() / 50 - if(humanity_lost_modifier == 0) - // 0 * anything = 0, this makes having 0 humanity not max out the chance. - humanity_lost_modifier = 1 - var/interpolated_chance = max_madness_chance + humanity_lost_modifier * (min_madness_chance - max_madness_chance) - var/madness_chance = clamp(interpolated_chance, min_madness_chance, max_madness_chance) - if(!prob(madness_chance) || source.owner.current.stat != CONSCIOUS || HAS_TRAIT(source.owner.current, TRAIT_MASQUERADE)) - return - var/message = pick(strings("malkavian_revelations.json", "revelations", "tff_modular/strings/bloodsuckers")) - INVOKE_ASYNC(source.owner.current, TYPE_PROC_REF(/atom/movable, say), message, forced = CLAN_MALKAVIAN) - -/datum/bloodsucker_clan/malkavian/favorite_ghoul_gain(datum/antagonist/bloodsucker/source, datum/antagonist/ghoul/ghouldatum) - var/mob/living/carbon/carbonowner = ghouldatum.owner.current - if(istype(carbonowner)) - carbonowner.gain_trauma(/datum/brain_trauma/mild/hallucinations, TRAUMA_RESILIENCE_ABSOLUTE) - carbonowner.gain_trauma(/datum/brain_trauma/special/bluespace_prophet/phobetor, TRAUMA_RESILIENCE_ABSOLUTE) - var/datum/martial_art/psychotic_brawling/psychotic_brawling = new(null) - psychotic_brawling.teach(ghouldatum.owner.current, TRUE) - to_chat(ghouldatum.owner.current, span_notice("Additionally, you now suffer the same fate as your Master, while also gaining the ability to tap into the madness when fighting.")) - -/datum/bloodsucker_clan/malkavian/favorite_ghoul_loss(datum/antagonist/bloodsucker/source, datum/antagonist/ghoul/ghouldatum) - var/mob/living/carbon/carbonowner = ghouldatum.owner.current - if(istype(carbonowner)) - carbonowner.cure_trauma_type(/datum/brain_trauma/mild/hallucinations, TRAUMA_RESILIENCE_ABSOLUTE) - carbonowner.cure_trauma_type(/datum/brain_trauma/special/bluespace_prophet/phobetor, TRAUMA_RESILIENCE_ABSOLUTE) - var/datum/martial_art/psychotic_brawling/psychotic_brawling = locate() in ghouldatum.owner.current.martial_arts - if(isnull(psychotic_brawling)) - return - psychotic_brawling.unlearn(ghouldatum.owner.current) - -/datum/bloodsucker_clan/malkavian/on_exit_torpor(datum/antagonist/bloodsucker/source) - var/mob/living/carbon/carbonowner = bloodsuckerdatum.owner.current - if(istype(carbonowner)) - carbonowner.gain_trauma(/datum/brain_trauma/mild/hallucinations, TRAUMA_RESILIENCE_ABSOLUTE) - carbonowner.gain_trauma(/datum/brain_trauma/special/bluespace_prophet, TRAUMA_RESILIENCE_ABSOLUTE) - -/datum/bloodsucker_clan/malkavian/on_final_death(datum/antagonist/bloodsucker/source) - var/obj/item/soulstone/bloodsucker/stone = new /obj/item/soulstone/bloodsucker(get_turf(bloodsuckerdatum.owner.current)) - if(!bloodsuckerdatum.owner.current.ckey) - return - ASYNC - stone.capture_soul(bloodsuckerdatum.owner.current, forced = TRUE) - return DONT_DUST - -/datum/bloodsucker_clan/malkavian/proc/on_bloodsucker_broke_masquerade(datum/source, datum/antagonist/bloodsucker/masquerade_breaker) - SIGNAL_HANDLER - to_chat(bloodsuckerdatum.owner.current, span_userdanger("[masquerade_breaker.owner.current] has broken the Masquerade! Ensure [masquerade_breaker.owner.current.p_they()] [masquerade_breaker.owner.current.p_are()] eliminated at all costs!")) - var/datum/objective/assassinate/masquerade_objective = new() - masquerade_objective.target = masquerade_breaker.owner.current - masquerade_objective.objective_name = "Clan Objective" - masquerade_objective.explanation_text = "Ensure [masquerade_breaker.owner.current], who has broken the Masquerade, succumbs to Final Death." - bloodsuckerdatum.objectives += masquerade_objective - bloodsuckerdatum.owner.announce_objectives() diff --git a/tff_modular/modules/bloodsucker/clans/clan_nosferatu.dm b/tff_modular/modules/bloodsucker/clans/clan_nosferatu.dm deleted file mode 100644 index 03ed6f8f51b..00000000000 --- a/tff_modular/modules/bloodsucker/clans/clan_nosferatu.dm +++ /dev/null @@ -1,125 +0,0 @@ -/datum/bloodsucker_clan/nosferatu - name = CLAN_NOSFERATU - description = "The Nosferatu Clan is unable to blend in with the crew, with no abilities such as Masquerade and Veil. \n\ - Additionally, has a permanent bad back and looks like a Bloodsucker upon a simple examine, and their face is disfigured \n\ - they can fit in the vents. \n\ - The Favorite Ghoul is also permanently disfigured, and can also ventcrawl, but only while entirely nude. \n\ - They also have night vision, know what each wire does, and have silent footsteps." - clan_objective = /datum/objective/bloodsucker/kindred - join_icon_state = "nosferatu" - join_description = "You are permanetly disfigured, look like a Bloodsucker to all who examine you, \ - lose your Masquerade ability, but gain the ability to Ventcrawl even while clothed." - blood_drink_type = BLOODSUCKER_DRINK_INHUMANELY - var/ventcrawl_time = 10 SECONDS - princely_score_bonus = 3 - var/static/list/traits_to_add = list(TRAIT_DISFIGURED, TRAIT_VENTCRAWLER_NUDE, TRAIT_UNKNOWN_VOICE, TRAIT_TRUE_NIGHT_VISION, TRAIT_KNOW_ENGI_WIRES, TRAIT_SILENT_FOOTSTEPS) - -/datum/bloodsucker_clan/nosferatu/New(datum/antagonist/bloodsucker/owner_datum) - . = ..() - for(var/datum/action/cooldown/bloodsucker/power as anything in bloodsuckerdatum.powers) - if(istype(power, /datum/action/cooldown/bloodsucker/masquerade) || istype(power, /datum/action/cooldown/bloodsucker/veil)) - bloodsuckerdatum.RemovePower(power) - var/mob/living/mob = bloodsuckerdatum.owner.current - if(!mob.has_quirk(/datum/quirk/badback)) - mob.add_quirk(/datum/quirk/badback) - - mob.add_traits(traits_to_add, BLOODSUCKER_TRAIT) - - RegisterSignal(bloodsuckerdatum, COMSIG_BLOODSUCKER_EXAMINE, PROC_REF(on_mob_examine)) - RegisterSignal(mob, COMSIG_CAN_VENTCRAWL, PROC_REF(can_ventcrawl)) - RegisterSignal(mob, COMSIG_VENTCRAWL_PRE_ENTER, PROC_REF(on_ventcrawl_enter)) - RegisterSignal(mob, COMSIG_VENTCRAWL_PRE_EXIT, PROC_REF(on_ventcrawl_pre_exit)) - RegisterSignal(mob, COMSIG_VENTCRAWL_EXIT, PROC_REF(on_ventcrawl_exit)) - RegisterSignal(mob, COMSIG_VENTCRAWL_PRE_CANCEL, PROC_REF(on_ventcrawl_cancel)) - -/datum/bloodsucker_clan/nosferatu/proc/get_ventcrawl_time() - return max(ventcrawl_time - bloodsuckerdatum.GetRank() SECONDS, 2 SECONDS) - -/datum/bloodsucker_clan/nosferatu/proc/can_ventcrawl(mob/living/carbon/human/owner_mob, atom/vent, provide_feedback) - SIGNAL_HANDLER - for(var/item in owner_mob.held_items) - if(isnull(item)) - continue - if(provide_feedback) - to_chat(owner_mob, span_warning("You cannot ventcrawl while holding items!")) - return FALSE - return TRUE - -/datum/bloodsucker_clan/nosferatu/proc/on_ventcrawl_cancel(mob/living/carbon/human/owner_mob, obj/machinery/atmospherics/components/ventcrawl_target) - SIGNAL_HANDLER - animate(ventcrawl_target) - -/datum/bloodsucker_clan/nosferatu/proc/on_ventcrawl_enter(mob/living/carbon/human/owner_mob, obj/machinery/atmospherics/components/ventcrawl_target) - SIGNAL_HANDLER - var/crawl_time = get_ventcrawl_time() - ventcrawl_target.Shake(pixelshiftx = 1, pixelshifty = 1, duration = crawl_time, shake_interval = 0.3 SECONDS) - return crawl_time - -/datum/bloodsucker_clan/nosferatu/proc/on_ventcrawl_pre_exit(mob/living/carbon/human/owner_mob, obj/machinery/atmospherics/components/ventcrawl_target) - SIGNAL_HANDLER - var/crawl_time = get_ventcrawl_time() - playsound(ventcrawl_target, 'sound/effects/bang.ogg', 25) - addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(playsound), crawl_time, 'sound/effects/bang.ogg', 25), ventcrawl_time * 0.6) - ventcrawl_target.Shake(pixelshiftx = 1, pixelshifty = 1, duration = crawl_time, shake_interval = 0.3 SECONDS) - return crawl_time - -/datum/bloodsucker_clan/nosferatu/proc/on_ventcrawl_exit(mob/living/carbon/human/owner_mob, obj/machinery/atmospherics/components/ventcrawl_target) - SIGNAL_HANDLER - // cooldown all non-inherent abilities on exit to prevent instant ambushes - for(var/datum/action/cooldown/bloodsucker/power as anything in bloodsuckerdatum.powers) - if(power.purchase_flags & BLOODSUCKER_DEFAULT_POWER) - continue - power.StartCooldown() - -/datum/bloodsucker_clan/nosferatu/proc/on_mob_examine(datum/antagonist/bloodsucker/owner_datum, datum/source, mob/examiner, examine_text) - SIGNAL_HANDLER - var/mob/living/carbon/human/ogled = owner_datum.owner.current - var/mob/living/ogler = examiner - if(isliving(examiner) && examiner != ogled && !ogler.mob_mood.has_mood_of_category("nosferatu_examine")) - ogler.add_mood_event("nosferatu_examine", /datum/mood_event/nosferatu_examined, ogled, owner_datum.GetRank()) - ogler.adjust_disgust(owner_datum.GetRank() * 10) - -/datum/bloodsucker_clan/nosferatu/Destroy(force) - var/datum/action/cooldown/bloodsucker/feed/suck = locate() in bloodsuckerdatum.powers - if(suck) - bloodsuckerdatum.RemovePower(suck) - bloodsuckerdatum.give_starting_powers() - bloodsuckerdatum.owner.current.remove_quirk(/datum/quirk/badback) - bloodsuckerdatum.owner.current.remove_traits(traits_to_add, BLOODSUCKER_TRAIT) - UnregisterSignal(bloodsuckerdatum, list(COMSIG_BLOODSUCKER_EXAMINE, COMSIG_CAN_VENTCRAWL, COMSIG_VENTCRAWL_PRE_ENTER, COMSIG_VENTCRAWL_PRE_EXIT, COMSIG_VENTCRAWL_EXIT)) - return ..() - -/datum/bloodsucker_clan/nosferatu/favorite_ghoul_gain(datum/antagonist/bloodsucker/source, datum/antagonist/ghoul/ghouldatum) - ghouldatum.owner.current.add_traits(traits_to_add, GHOUL_TRAIT) - ghouldatum.traits += traits_to_add - ghouldatum.owner.current.update_sight() - to_chat(ghouldatum.owner.current, span_notice("Additionally, you can now ventcrawl while naked, and are permanently disfigured. You also have night vision, know how which wires to cut, and have silent footsteps.")) - -/datum/bloodsucker_clan/nosferatu/favorite_ghoul_loss(datum/antagonist/bloodsucker/source, datum/antagonist/ghoul/ghouldatum) - ghouldatum.owner.current.update_sight() - -/datum/bloodsucker_clan/nosferatu/handle_clan_life(datum/antagonist/bloodsucker/source, seconds_per_tick, times_fired) - var/area/nosf_area = get_area(source.owner.current) - if(nosf_area && istype(nosf_area, /area/station/maintenance)) - source.owner.current.apply_status_effect(/datum/status_effect/nosferatu_effect) - -/datum/status_effect/nosferatu_effect - id = "nosferatu" - duration = 2 SECONDS - status_type = STATUS_EFFECT_REFRESH - alert_type = null - -/datum/status_effect/nosferatu_effect/on_apply() - . = ..() - if(!.) - return FALSE - var/mob/living/carbon/human/nosferatu = owner - nosferatu.add_movespeed_modifier(/datum/movespeed_modifier/nosferatu) - -/datum/status_effect/nosferatu_effect/on_remove() - . = ..() - var/mob/living/carbon/human/nosferatu = owner - nosferatu.remove_movespeed_modifier(/datum/movespeed_modifier/nosferatu) - -/datum/movespeed_modifier/nosferatu - multiplicative_slowdown = -0.1 diff --git a/tff_modular/modules/bloodsucker/clans/clan_tremere.dm b/tff_modular/modules/bloodsucker/clans/clan_tremere.dm deleted file mode 100644 index 6c41f42cc3c..00000000000 --- a/tff_modular/modules/bloodsucker/clans/clan_tremere.dm +++ /dev/null @@ -1,64 +0,0 @@ -/datum/bloodsucker_clan/tremere - name = CLAN_TREMERE - description = "The Tremere Clan is extremely weak to True Faith, and will burn when entering areas considered such, like the Chapel. \n\ - Additionally, a whole new moveset is learned, built on Blood magic rather than Blood abilities, which are upgraded overtime. \n\ - More ranks can be gained by Ghoulizing crewmembers. \n\ - The Favorite Ghoul gains the Batform spell, being able to morph themselves at will." - clan_objective = /datum/objective/bloodsucker/tremere_power - join_icon_state = "tremere" - join_description = "You will burn if you enter the Chapel, lose all default powers, \ - but gain Blood Magic instead, stronger powers you level up overtime." - buy_power_flags = TREMERE_CAN_BUY|CAN_BUY_OWNED - princely_score_bonus = 8 - -/datum/bloodsucker_clan/tremere/New(mob/living/carbon/user) - . = ..() - bloodsuckerdatum.remove_nondefault_powers(return_levels = TRUE) - for(var/datum/action/cooldown/bloodsucker/power as anything in bloodsuckerdatum.all_bloodsucker_powers) - if((initial(power.purchase_flags) & buy_power_flags) && initial(power.level_current) == 1) - bloodsuckerdatum.BuyPower(power) - -/datum/bloodsucker_clan/tremere/Destroy(force) - for(var/datum/action/cooldown/bloodsucker/power in bloodsuckerdatum.powers) - if(power.purchase_flags & buy_power_flags) - bloodsuckerdatum.RemovePower(power) - return ..() - -/datum/bloodsucker_clan/tremere/handle_clan_life(datum/antagonist/bloodsucker/source, seconds_per_tick, times_fired) - . = ..() - var/area/current_area = get_area(bloodsuckerdatum.owner.current) - if(istype(current_area, /area/station/service/chapel)) - to_chat(bloodsuckerdatum.owner.current, span_warning("You don't belong in holy areas! The Faith burns you!")) - bloodsuckerdatum.owner.current.adjust_fire_loss(10) - bloodsuckerdatum.owner.current.adjust_fire_stacks(2) - bloodsuckerdatum.owner.current.ignite_mob() - -/datum/bloodsucker_clan/tremere/level_up_powers(datum/antagonist/bloodsucker/source) - return - -/datum/bloodsucker_clan/tremere/level_message(power_name) - var/mob/living/carbon/human/human_user = bloodsuckerdatum.owner.current - human_user.balloon_alert(human_user, "upgraded [power_name]!") - to_chat(human_user, span_notice("You have upgraded [power_name]!")) - -// redefine the default args -/datum/bloodsucker_clan/tremere/list_available_powers(already_known, powers_list) - already_known = list() - powers_list = bloodsuckerdatum.powers - return ..() - -/datum/bloodsucker_clan/tremere/purchase_choice(datum/antagonist/bloodsucker/source, datum/action/cooldown/bloodsucker/purchased_power) - return purchased_power.upgrade_power() - -/datum/bloodsucker_clan/tremere/favorite_ghoul_gain(datum/antagonist/bloodsucker/source, datum/antagonist/ghoul/ghouldatum) - var/datum/action/cooldown/spell/shapeshift/bat/batform = new(ghouldatum.owner || ghouldatum.owner.current) - batform.Grant(ghouldatum.owner.current) - -/datum/bloodsucker_clan/tremere/favorite_ghoul_loss(datum/antagonist/bloodsucker/source, datum/antagonist/ghoul/ghouldatum) - var/datum/action/cooldown/spell/shapeshift/bat/batform = locate() in ghouldatum.owner.current.actions - batform.Remove(ghouldatum.owner.current) - -/datum/bloodsucker_clan/tremere/on_ghoul_made(datum/antagonist/bloodsucker/source, mob/living/user, mob/living/target) - . = ..() - to_chat(bloodsuckerdatum.owner.current, span_danger("You have now gained an additional Rank to spend!")) - bloodsuckerdatum.AdjustUnspentRank(1) diff --git a/tff_modular/modules/bloodsucker/clans/clan_ventrue.dm b/tff_modular/modules/bloodsucker/clans/clan_ventrue.dm deleted file mode 100644 index 8c629faf656..00000000000 --- a/tff_modular/modules/bloodsucker/clans/clan_ventrue.dm +++ /dev/null @@ -1,154 +0,0 @@ -///The maximum level a Ventrue Bloodsucker can be, before they have to level up their ghoul instead. -#define VENTRUE_MAX_POWERS 7 - -/datum/bloodsucker_clan/ventrue - name = CLAN_VENTRUE - description = "The Ventrue Clan is extremely snobby with their meals, and refuse to drink blood from people without a mind. \n\ - You may have up to %MAX_POWERS% powers, anything further will be ranks to spend on their Favorite Ghoul through a Persuasion Rack. \n\ - The Favorite Ghoul will slowly turn more Vampiric this way, until they finally lose their last bits of Humanity. \n\ - Once you finish your embracing, the newly sired vampire will become just a ghoul, and you'll be able to sire another bloodsucker." - clan_objective = /datum/objective/bloodsucker/embrace - join_icon_state = "ventrue" - join_description = "Lose the ability to drink from mindless mobs, can't level up or gain new powers, \ - instead you raise a ghoul into a Bloodsucker." - blood_drink_type = BLOODSUCKER_DRINK_SNOBBY - level_cost = BLOODSUCKER_LEVELUP_PERCENTAGE_VENTRUE - princely_score_bonus = 15 - -/datum/bloodsucker_clan/ventrue/New(datum/antagonist/bloodsucker/owner_datum) - . = ..() - description = replacetext(description, "%MAX_POWERS%", VENTRUE_MAX_POWERS) - -/datum/bloodsucker_clan/ventrue/proc/has_enough_abilities() - var/power_count = 0 - for(var/datum/action/cooldown/bloodsucker/power in bloodsuckerdatum.powers) - if(!(power.purchase_flags & BLOODSUCKER_DEFAULT_POWER)) - power_count++ - if(power_count >= VENTRUE_MAX_POWERS) - return TRUE - return FALSE - -/datum/bloodsucker_clan/ventrue/spend_rank(datum/antagonist/bloodsucker/source, cost_rank = TRUE, blood_cost) - if(has_enough_abilities()) - to_chat(bloodsuckerdatum.owner.current, span_danger("You can only have up to [VENTRUE_MAX_POWERS] powers, anything further must be ranks to spend on your Favorite Ghoul through a Persuasion Rack.")) - return FALSE - . = ..() - -/datum/bloodsucker_clan/ventrue/proc/finish_spend_rank(datum/antagonist/ghoul/ghouldatum, cost_rank, blood_cost) - finalize_spend_rank(bloodsuckerdatum, cost_rank, blood_cost) - ghouldatum.LevelUpPowers() - -/datum/bloodsucker_clan/ventrue/interact_with_ghoul(datum/antagonist/bloodsucker/source, datum/antagonist/ghoul/favorite/ghouldatum) - . = ..() - if(.) - return TRUE - if(!istype(ghouldatum)) - return FALSE - to_chat(bloodsuckerdatum.owner.current, span_warning("Do you wish to Rank [ghouldatum.owner.current] up?")) - to_chat(bloodsuckerdatum.owner.current, span_warning("This will use [bloodsuckerdatum.GetUnspentRank() >= 1 ? "a unspent Rank" : "[bloodsuckerdatum.get_level_cost()] Blood Thickening Points"]!")) - - var/static/list/rank_options = list( - "Yes" = image(icon = 'icons/hud/radial.dmi', icon_state = "radial_yes"), - "No" = image(icon = 'icons/hud/radial.dmi', icon_state = "radial_no"), - ) - var/rank_response = show_radial_menu(bloodsuckerdatum.owner.current, ghouldatum.owner.current, rank_options, radius = 36, require_near = TRUE) - if(rank_response == "Yes") - if(!bloodsuckerdatum.GetUnspentRank() >= 1 && !source.blood_level_gain(FALSE)) - to_chat(bloodsuckerdatum.owner.current, span_danger("You don't have any levels or enough blood thickening points to Rank [ghouldatum.owner.current] up with.")) - return FALSE - return ghoul_level(ghouldatum) - return FALSE - -/datum/bloodsucker_clan/ventrue/proc/ghoul_level(datum/antagonist/ghoul/favorite/ghouldatum) - var/list/options = list_available_powers(ghouldatum.bloodsucker_powers) - var/mob/living/carbon/human/target = ghouldatum.owner.current - var/datum/action/cooldown/bloodsucker/choice = choose_powers( - "You have the opportunity to level up your Favorite Ghoul. Select a power you wish them to receive.", - "A wise master's hand is neccesary", - options - ) - if(!choice) - return FALSE - var/power_name = initial(choice.name) - if(!ghouldatum.BuyPower(choice, ghouldatum.bloodsucker_powers)) - bloodsuckerdatum.owner.current.balloon_alert(bloodsuckerdatum.owner.current, "[target] already knows [power_name]!") - return FALSE - bloodsuckerdatum.owner.current.balloon_alert(bloodsuckerdatum.owner.current, "taught [power_name]!") - to_chat(bloodsuckerdatum.owner.current, span_notice("You taught [target] how to use [power_name]!")) - - target.balloon_alert(target, "learned [power_name]!") - to_chat(target, span_notice("Your master taught you how to use [power_name]!")) - - ghouldatum.ghoul_level++ - finish_spend_rank(ghouldatum, TRUE, FALSE) - bloodsuckerify(ghouldatum) - return TRUE - -/datum/bloodsucker_clan/ventrue/proc/bloodsuckerify(datum/antagonist/ghoul/favorite/ghouldatum) - var/mob/living/carbon/human/target = ghouldatum.owner.current - var/stage = ghouldatum.ghoul_level - var/list/traits_possible = list( - list(TRAIT_COLDBLOODED, TRAIT_NOBREATH, TRAIT_AGEUSIA), - list(TRAIT_NOCRITDAMAGE, TRAIT_NOSOFTCRIT, TRAIT_SLEEPIMMUNE, TRAIT_VIRUSIMMUNE), - list(TRAIT_NOHARDCRIT, TRAIT_HARDLY_WOUNDED) - ) - var/traits_to_add = length(traits_possible) >= stage ? traits_possible[stage] : list() - switch(stage) - - if(1) - to_chat(target, span_notice("Your blood begins to feel cold, and as a mote of ash lands upon your tongue, you stop breathing...")) - - if(2) - to_chat(target, span_notice("You feel your Master's blood reinforce you, strengthening you up.")) - if(ishuman(target)) - var/mob/living/carbon/human/human_target = target - human_target.skin_tone = "albino" - - if(3) - to_chat(target, span_notice("You feel yourself able to take cuts and stabbings like it's nothing.")) - - if(4 to INFINITY) - var/datum/antagonist/bloodsucker/bloodsucker_target = IS_BLOODSUCKER(target) - if(!bloodsucker_target) - to_chat(target, span_notice("You feel your heart stop pumping for the last time as you begin to thirst for blood, you feel... dead.")) - // Unfavorites you, so the ventrue isn't stuck with you forever - var/powers_to_transfer = list() - // Get rid of the favorite datum and replace with a normal ghoul datum - if(ghouldatum) - ghouldatum.silent = TRUE - for(var/datum/power as anything in ghouldatum.bloodsucker_powers) - powers_to_transfer += power.type - target.mind.remove_antag_datum(/datum/antagonist/ghoul/favorite) - else - target.remove_traits(assoc_to_values(traits_to_add), GHOUL_TRAIT) - - - var/datum/antagonist/bloodsucker/vamp = new() - vamp.ventrue_sired = bloodsuckerdatum - bloodsucker_target = target.mind.add_antag_datum(vamp) - bloodsucker_target.BuyPowers(powers_to_transfer) - // Check for the recuperate power and remove it if they have it - bloodsuckerdatum.owner.current.add_mood_event("madevamp", /datum/mood_event/madevamp) - - - if(ghouldatum && QDELETED(ghouldatum) && length(traits_to_add)) - target.add_traits(traits_to_add, GHOUL_TRAIT) - ghouldatum.traits += traits_to_add - -/datum/bloodsucker_clan/ventrue/favorite_ghoul_gain(datum/antagonist/bloodsucker/source, datum/antagonist/ghoul/ghouldatum) - to_chat(source.owner.current, span_announce("* Bloodsucker Tip: You can now upgrade your Favorite Ghoul by buckling them onto a persuasion rack!")) - ghouldatum.BuyPower(/datum/action/cooldown/bloodsucker/distress) - -/datum/bloodsucker_clan/ventrue/is_valid_ghoul(datum/antagonist/ghoul/ghoul_type) - . = ..() - if(!.) - return FALSE - var/datum/antagonist/ghoul/favorite = /datum/antagonist/ghoul/favorite - if(ghoul_type != favorite) - // no ghoul slots and trying to make a non-favorite ghoul, don't softlock yourself - if(bloodsuckerdatum.free_ghoul_slots() < 1 && !bloodsuckerdatum.special_ghouls[initial(favorite.special_type)]) - to_chat(bloodsuckerdatum.owner.current, span_danger("Making a non-favorite Ghoul will prevent you from leveling up, as you have no slots left!")) - return FALSE - return TRUE - -#undef VENTRUE_MAX_POWERS diff --git a/tff_modular/modules/bloodsucker/credit_file.md b/tff_modular/modules/bloodsucker/credit_file.md deleted file mode 100644 index 427f3f28ef4..00000000000 --- a/tff_modular/modules/bloodsucker/credit_file.md +++ /dev/null @@ -1,32 +0,0 @@ -## File containing credit for all sprites in this folder.area and related files moved out of it -Sheits (Throne, vamp_obj_64.dmi) https://github.com/fulpstation/fulpstation/pull/393 -modular_zubbers/icons/obj/structures/vamp_obj_64.dmi - -ReinaCoder (Book, vamp_obj.dmi) https://github.com/fulpstation/fulpstation/pull/649 -modular_zubbers/icons/obj/structures/vamp_obj.dmi - -A majority of credit goes to JohnFulpWillard for coding and spriting Bloodsuckers. -Code paths: -This folder, -modular_zubbers/code/datums/components/crafting/crafting/furniture.dm -modular_zubbers/code/datums/components/crafting/crafting/melee_weapon.dm -modular_zubbers/code/controllers/subsystem/sol_subsystem.dm -modular_zubbers/code/modules/languages/vampiric.dm -modular_zubbers/code/__DEFINES/bloodsucker.dm - - -Sprite paths: -modular_zubbers/icons/obj/equipment/stakes.dmi -modular_zubbers/icons/mob/inhands/weapons/bloodsucker_lefthand.dmi -modular_zubbers/icons/mob/inhands/weapons/bloodsucker_righthand.dmi -modular_zubbers/icons/mob/actions/bloodsucker.dmi -modular_zubbers/icons/mob/actions/tremere_bloodsucker.dmi -modular_zubbers/icons/effects/radials/clan_icons.dmi -modular_zubbers/icons/misc/language.dmi -modular_zubbers/icons/huds/bloodsucker.dmi -modular_zubbers/icons/effects/phobetor_tear.dmi - -Sound paths: -everything in modular_zubbers/sound/bloodsucker -modular_zubbers/sound/machines/coffin_close.ogg -modular_zubbers/sound/machines/coffin_open.ogg diff --git a/tff_modular/modules/bloodsucker/icons/antag_hud.dmi b/tff_modular/modules/bloodsucker/icons/antag_hud.dmi deleted file mode 100644 index 5b1f91fc771d85fb64a0b811f077423e34312c7c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1687 zcmZuydoXFmQEW%*4TTYaOF-D?ZRp~QYRKzf-q}YrmX}qapixb}9LI^;XWt+w{thlfXEVt8UU)P8ZftK|+C-%Glj5=A@ zxQ32ZrTJv0t#>ckUl3J7C6|BgJOaUsL(-GZpwg52OJ~03nt(x?-&CoL@+Om4Zc{4W z^;_NeQK5^Xa@VG|^M>YK-!^WCAGYWW)xYJH1A@Pvs?oN27!IMe%kE@1%JWbQMuz!vz+M{aO{3pN4?FDj4$+F|D+%FP4p}a71=BB8Z^K}tUL{ink{S9IMdr~ zdJQ7&o9STBJ57h4F9QJ+@Hi?^y^`&YW`^(FnufIW=x75+)*t+KUYzlQ(f?1453nFY z`k4M-9JJwD3`P_VtoqR%xq_S(*-&rYEaefJ<;lX^q;~nW{yI{70)xT4eZ%vhr`(3a zrOWob0VX~!D!#wec1{wDcQKOWO7BB0%6*HJYJeHz9vFTA0jeGv{&E(z)%lVbe6ClF zz1u;(4|}VI=HTz8FF>eSGFL?(bh$x;UF(CwJun-W0+Tz~$gfUVHUI59hd2iF=et)u zt)l`8act!w1Q#~FcdmUW-hUVFMuOzv3tK~-UTD3)d4OdrFYv$XUA&(s9-IGN%ui&4}2R@oLDb!1S z_BEu0U9%Z69eS(aQ?!_U$jY31G%BV*5B#^=<%<+{i4hRL+P|sVg_nvKq(hUNDu(yx z&lQKlGU~P)g{0Ipn$_(I6d~Y?B&7m!D5GP%xWOx8Z$+()PGs1LF!VdC97cgyXOvU9 zPlHcsELBUkR(5UVLF7XYU*0Bqnpa#Ld`h*I(h{Y{b8uIK!Rbq(FIH;D;<_g;W z43=)_9F;~ZW?8LX5g%gZ+m>ZhSlZT(!^=OJEV4j)!jHj>$+gwoh5qYt$;0W(vy&PhX4*vzvtu(nWEIW?2>=UxOsqHLaC4-y zw5HkgK|JcbY)-tl?gH-hJI}tQ;*v>Y=aHAyHRCFe6n^kC;or+{#N%DLP0@mj;I-t} zko#bXWpQeJBKZkw=p>_d!v(l@97``AQjs{J^yON(+>m`Gw%zGrw(Ol$1Td3y2HFHZ zuw+oQiSOxK{lf-s`Jxy9ZnOgChbKp9SrnB-N)!PA`SL}fE%+YX?Xpy+!2BP(vKfXY zxkrBhlskI$P05aIQ0%K5^-3v?#2{Wl0L0TLo`eJDWjMf`w681ylOqtFy~6B#FPec@ z`O=p$n20_#usHP9!cBm(?4-B}R6Ub-&99Huzw^0O(N&vgXL!%TEoDXstj diff --git a/tff_modular/modules/bloodsucker/icons/bloodsucker.dmi b/tff_modular/modules/bloodsucker/icons/bloodsucker.dmi deleted file mode 100644 index b179e1c27c3dc49530dd7f73804bf68cb1dc9dc9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26432 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 aMX;*A!|}aVYbL%K2hdd4RjXF9iTEFZk-#bd diff --git a/tff_modular/modules/bloodsucker/icons/bloodsucker_lefthand.dmi b/tff_modular/modules/bloodsucker/icons/bloodsucker_lefthand.dmi deleted file mode 100644 index 7e69d1073dfe311516172dbbca2cab38cf12dba0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6531 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 diff --git a/tff_modular/modules/bloodsucker/icons/bloodsucker_righthand.dmi b/tff_modular/modules/bloodsucker/icons/bloodsucker_righthand.dmi deleted file mode 100644 index 14069ad34f0de0cc6e4375dd14a53ab84c67640d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6751 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 diff --git a/tff_modular/modules/bloodsucker/icons/language.dmi b/tff_modular/modules/bloodsucker/icons/language.dmi deleted file mode 100644 index 1cf92d5c97a7cf5a75ba5f09bd19af492f7f90fe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 722 zcmV;@0xkWCP)V=-0C=2JR&a84_w-Y6@%7{?OD!tS%+FJ>RWQ*r;NmRLOex7wuvIWLl;joY$>g`NEMAD=Lm};D^-fPO@UI*0ajvr`vzNDpzSgzm@UGv0~i9> zuuXo+;x`uazIp!VA*RzQr<977t>lnjx3|K1UtgS&Qd+IGaK3FZ|GD$WDAEl8l^k-h z{xFV}9T~$Bv0N5!+;sSaIfQr=*Aoso+`}bmf5J@TR$QYh&$mQjG!MC@orSEe7+q5wU zmSm#F7=tkeA!^uGI60AJ$a0pXqfQ)nXtPA&^@ zy4~*ta1hXc@b(5chgv70uOvxqQ4|aY1L3@{G)+5oXJ-hvNhyU=s!QFY0me!x*1K>v zfXQTX-#5hG07;VA*=%Ngh(2D!havPdR!Zf-N)XdDJsUt?6a`8t2hxl72Jm*B_t}9D z2T_tFJO9t;^LeK^(0LNZaop+mM-8Gr^$G9^@ZSOc0`403H@7u0Z~y=R07*qoM6N<$ Eg1`SsmjD0& diff --git a/tff_modular/modules/bloodsucker/icons/stakes.dmi b/tff_modular/modules/bloodsucker/icons/stakes.dmi deleted file mode 100644 index dfc1dc08bf4334835cf6f2ab74919b1eda6c7679..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 866 zcmV-o1D*VdP))f<<+_Q;ID;0vEzf@py*Qj}hK_JcZ{C9+zt!5wa(5CV=- z0C=2JR&a84_w-Y6@%7{?OD!tS%+FJ>RWQ*r;NmRLOex6#a*U0*I5Sc+(=$pSoZ^zi zl2jm5sXRYFMTv_uC9|j)$Tj5ROe;#vO@*-GiZT+5Qd09$2`enl%mF%ppfZr9PL9sr zp#el&O{8*&1Mn+WR&e!m0S6WU%*t0)k-GxD0005~Nkl7ykSg=2IIlO_Ra|ZH# zq#6te=>ouj(p@gjeMkJdw(AxXWJs*G%L=J z_=<0u9rGXM{ZD*C#8-UNTowMu1^l&dniKP%ML#3Y7XUs`&3B0}f1eDfYqVeW-Sq|X zv#bN(-x~jR!~9K~Hf{QXBE?t3Db}FyQL^}>lZYP(4&danV!-hzEEi~s2l)ISf%^-kE5Q6K;@{nGrh*3e s_x2m7^6ykCXrIYX1#S8NZPS0CcX7iktM*kz?EnA(07*qoM6N<$g3fKDng9R* diff --git a/tff_modular/modules/bloodsucker/icons/tremere_bloodsucker.dmi b/tff_modular/modules/bloodsucker/icons/tremere_bloodsucker.dmi deleted file mode 100644 index 057b17bbe103d2053b2fdf2a701ec73818365061..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5371 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 diff --git a/tff_modular/modules/bloodsucker/icons/vamp_obj.dmi b/tff_modular/modules/bloodsucker/icons/vamp_obj.dmi deleted file mode 100644 index fa6228f45e056049e62d5e47d78f2139e5380f13..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10653 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 diff --git a/tff_modular/modules/bloodsucker/icons/vamp_obj_64.dmi b/tff_modular/modules/bloodsucker/icons/vamp_obj_64.dmi deleted file mode 100644 index 4367da28b32b8e74f93adcfea4d20a6b7c7cca37..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1109 zcmV-b1giUqP)bB>(^b0d!JM zQvg8b*k%9#0Caj(Sad{Xb7OL8aCB*JZU6vyoKseCa&`CgQ*iP1i4QC_gV%iHkEOv#1!Pi;FX@ zC^0t`#5P1%mROXFOQo`ctDg(l1poprClvZq%31&b16D~yK~!jg?U=uAA~6ugja`F+ z(xqD2cM3re5sxkqM7BsC;U3}MAQVdt1y?5(NfoG)JV8PS^_?Qpo)F5m2hVU`7XMjx zb4J%(;}42__Ri1tjM+$okdu>>lao_gxxJ*vo?$$cDQp^2OHL;Ir)hCryvP zWCOk$JM&I26B|nU(`>*uV-0kAX`Xb;x3d9tGeDf#`^e)SWW__nh$!x#6cdw_>Y&5! zm4{Nohovj|w})~;u&2x7Arb^N>2dHqxJm;K#jxb&_8URaJ5g5wvqrzu2)-^-;w0?zx#)!BO}w@8Q&%Q=L#nmhu8;aeDnB=$Am_s@MF^btT1M7+*& zfrNf-VPrj=uih3iiv$YitEF$g_)&hfdPSxd1(fuQg=q_gt$CDxMNUpmPEJlvPEJlv zPEP+MOaH(sTmQfgu=EeCvh@$_vh@#k1bo~-u*lv&u*up#u*%Xuu*u#(uxW?>fmPQ2 b!T-}AaD_*nX)b$H00000NkvXXu0mjf=H29G diff --git a/tff_modular/modules/bloodsucker/powers/_powers.dm b/tff_modular/modules/bloodsucker/powers/_powers.dm deleted file mode 100644 index 82295560ef1..00000000000 --- a/tff_modular/modules/bloodsucker/powers/_powers.dm +++ /dev/null @@ -1,319 +0,0 @@ -/datum/action - /// Extended description of the action, usually shown in an antag UI. - var/power_explanation = "" - -/datum/antagonist - var/antag_panel_title = "Antagonist Panel" - var/antag_panel_description = "This is the antagonist panel. It contains all the abilities you have access to as an antagonist. Use them wisely." - -/datum/antagonist/proc/ability_ui_data(actions = list()) - var/list/data = list() - data["title"] = "[antag_panel_title]\n[antag_panel_data()]" - data["description"] = antag_panel_description - for(var/datum/action/cooldown/power as anything in actions) - var/list/power_data = list() - - power_data["power_name"] = power.name - power_data["power_icon"] = power.button_icon_state - if(istype(power, /datum/action/cooldown/bloodsucker)) - var/datum/action/cooldown/bloodsucker/bloodsucker_power = power - power_data["power_explanation"] = bloodsucker_power.get_power_explanation() - - data["powers"] += list(power_data) - return data - -/datum/action/cooldown/bloodsucker - name = "Vampiric Gift" - background_icon = 'tff_modular/modules/bloodsucker/icons/bloodsucker.dmi' - background_icon_state = "vamp_power_off" - button_icon = 'tff_modular/modules/bloodsucker/icons/bloodsucker.dmi' - button_icon_state = "power_feed" - buttontooltipstyle = "cult" - transparent_when_unavailable = TRUE - - /// Cooldown you'll have to wait between each use, decreases depending on level. - cooldown_time = 2 SECONDS - - ///Background icon when the Power is active. - active_background_icon_state = "vamp_power_on" - ///Background icon when the Power is NOT active. - base_background_icon_state = "vamp_power_off" - - /// The text that appears when using the help verb, meant to explain how the Power changes when ranking up. - ///The owner's stored Bloodsucker datum - var/datum/antagonist/bloodsucker/bloodsuckerdatum_power - - // FLAGS // - /// The effects on this Power (Toggled/Single Use/Static Cooldown) - var/power_flags = BP_AM_SINGLEUSE|BP_AM_STATIC_COOLDOWN|BP_AM_COSTLESS_UNCONSCIOUS - /// Requirement flags for checks - check_flags = AB_CHECK_INCAPACITATED|AB_CHECK_CONSCIOUS|AB_CHECK_PHASED - var/bloodsucker_check_flags = BP_CANT_USE_IN_TORPOR|BP_CANT_USE_IN_FRENZY - /// Who can purchase the Power - var/purchase_flags = NONE // BLOODSUCKER_CAN_BUY|BLOODSUCKER_DEFAULT_POWER|TREMERE_CAN_BUY|GHOUL_CAN_BUY - - // VARS // - /// If the Power is currently active, differs from action cooldown because of how powers are handled. - var/active = FALSE - ///Can increase to yield new capabilities - Each Power ranks up each Rank, with the oldest power being the highest rank. - var/level_current = 0 - ///The cost to ACTIVATE this Power - var/bloodcost = 0 - ///The cost to MAINTAIN this Power - Only used for Constant Cost Powers - var/constant_bloodcost = 0 - ///Most powers happen the moment you click. Some, like Mesmerize, require time and shouldn't cost you if they fail. - var/power_activates_immediately = TRUE - -// Modify description to add cost. -/datum/action/cooldown/bloodsucker/New(Target) - SHOULD_CALL_PARENT(TRUE) - . = ..() - desc = get_power_desc() - -/datum/action/cooldown/bloodsucker/Destroy() - SHOULD_CALL_PARENT(TRUE) - if(active) - DeactivatePower() - bloodsuckerdatum_power = null - return ..() - -/datum/action/cooldown/bloodsucker/IsAvailable(feedback = FALSE) - return next_use_time <= world.time - -/datum/action/cooldown/bloodsucker/Grant(mob/user) - . = ..() - var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(owner) - if(bloodsuckerdatum) - bloodsuckerdatum_power = bloodsuckerdatum - -/datum/action/cooldown/bloodsucker/Trigger(trigger_flags, atom/target) - if(trigger_flags & TRIGGER_SECONDARY_ACTION) - RightClickActivate(trigger_flags) - return - . = ..() - -//This is when we CLICK on the ability Icon, not USING. -/datum/action/cooldown/bloodsucker/PreActivate(atom/target) - if(QDELETED(owner)) - return FALSE - if(SEND_SIGNAL(src, COMSIG_ACTION_TRIGGER) & COMPONENT_ACTION_BLOCK_TRIGGER) - return FALSE - if(active && can_deactivate()) // Active? DEACTIVATE AND END! - DeactivatePower() - return FALSE - if(!can_pay_cost() || !can_use(owner)) - return FALSE - . = ..() - // base type returns true? Pay costs - if(!click_to_activate && power_activates_immediately) - pay_cost() - -/datum/action/cooldown/bloodsucker/proc/can_pay_cost() - if(QDELETED(owner) || !owner.mind) - return FALSE - // Cooldown? - if(!COOLDOWN_FINISHED(src, next_use_time)) - owner.balloon_alert(owner, "power unavailable!") - return FALSE - if(!bloodsuckerdatum_power) - var/mob/living/living_owner = owner - if(!HAS_TRAIT(living_owner, TRAIT_NOBLOOD) && living_owner.blood_volume <= bloodcost) - to_chat(owner, span_warning("You need at least [bloodcost] blood to activate [name]")) - return FALSE - return TRUE - - // Have enough blood? Bloodsuckers in a Frenzy don't need to pay them - if(bloodsuckerdatum_power.frenzied) - return TRUE - if(bloodsuckerdatum_power.GetBloodVolume() < bloodcost) - to_chat(owner, span_warning("You need at least [bloodcost] blood to activate [name]")) - return FALSE - return TRUE - -///Called when the Power is upgraded. -/datum/action/cooldown/bloodsucker/proc/upgrade_power() - SHOULD_CALL_PARENT(TRUE) - DeactivatePower() - if(level_current == -1) // -1 means it doesn't rank up ever - return FALSE - level_current++ - on_power_upgrade() - return TRUE - -/datum/action/cooldown/bloodsucker/proc/on_power_upgrade() - SHOULD_CALL_PARENT(TRUE) - desc = get_power_desc() - if(purchase_flags & TREMERE_CAN_BUY && level_current >= TREMERE_OBJECTIVE_POWER_LEVEL) - background_icon_state = "tremere_power_gold_off" - active_background_icon_state = "tremere_power_gold_on" - base_background_icon_state = "tremere_power_gold_off" - build_all_button_icons(ALL) - -///Checks if the Power is available to use. -/datum/action/cooldown/bloodsucker/proc/can_use(mob/living/carbon/user) - if(QDELETED(owner)) - return FALSE - if(!isliving(user)) - return FALSE - if(!(bloodsucker_check_flags & BP_CAN_USE_HEARTLESS) && bloodsuckerdatum_power && !owner.get_organ_slot(ORGAN_SLOT_HEART)) - to_chat(user, span_warning("To channel your powers you need a heart!")) - return FALSE - if(isbrain(user)) - to_chat(user, span_warning("What are you going to do, jump on someone and suck their blood? You're just a head.")) - return FALSE - // Torpor? - if((bloodsucker_check_flags & BP_CANT_USE_IN_TORPOR) && bloodsuckerdatum_power?.is_in_torpor()) - to_chat(user, span_warning("Not while you're in Torpor.")) - return FALSE - if(!(bloodsucker_check_flags & BP_CAN_USE_TRANSFORMED) && (user.has_status_effect(/datum/status_effect/shapechange_mob/from_spell) || user.has_status_effect(/datum/status_effect/shapechange_mob))) - to_chat(user, span_warning("You can't do this while transformed!")) - return FALSE - // Frenzy? - if((bloodsucker_check_flags & BP_CANT_USE_IN_FRENZY) && (bloodsuckerdatum_power?.frenzied)) - to_chat(user, span_warning("You cannot use powers while in a Frenzy!")) - return FALSE - // Stake? - if(!(bloodsucker_check_flags & BP_CAN_USE_WHILE_STAKED) && user.am_staked()) - to_chat(user, span_warning("You have a stake in your chest! Your powers are useless.")) - return FALSE - // Constant Cost (out of blood) - if(constant_bloodcost > 0 && !can_pay_blood(user)) - to_chat(user, span_warning("You don't have the blood to upkeep [src].")) - return FALSE - return TRUE - -/// NOTE: With this formula, you'll hit half cooldown at level 8 for that power. -/datum/action/cooldown/bloodsucker/StartCooldown(override_cooldown_time, override_melee_cooldown_time) - // Calculate Cooldown (by power's level) - if(!(power_flags & BP_AM_STATIC_COOLDOWN)) - var/custom_cooldown = max(initial(cooldown_time) / 2, initial(cooldown_time) - (initial(cooldown_time) / 16 * (level_current-1))) - // calling parent proc with custom args - return ..(custom_cooldown, override_melee_cooldown_time) - return ..() - -/datum/action/cooldown/bloodsucker/proc/can_pay_blood(mob/living/carbon/user) - return bloodsuckerdatum_power ? bloodsuckerdatum_power?.GetBloodVolume() >= 0 : user.blood_volume >= 0 - -/datum/action/cooldown/bloodsucker/proc/can_deactivate() - return TRUE - -/datum/action/cooldown/bloodsucker/is_action_active() - return active - -/datum/action/cooldown/bloodsucker/proc/pay_cost(cost_override) - // Non-bloodsuckers will pay in other ways. - if(!bloodsuckerdatum_power) - var/mob/living/living_owner = owner - var/blood_cost = cost_override ? cost_override : bloodcost - if(HAS_TRAIT(living_owner, TRAIT_NOBLOOD)) - living_owner.adjust_brute_loss(blood_cost * 0.1) - else - living_owner.blood_volume = max(0, living_owner.blood_volume - blood_cost) - return - // Bloodsuckers in a Frenzy don't have enough Blood to pay it, so just don't. - if(bloodsuckerdatum_power.frenzied) - return - bloodsuckerdatum_power.AdjustBloodVolume(cost_override ? -cost_override : -bloodcost) - -// TODO refactor the Trigger -> PreActivate -> Activate -> ActivatePower / set_click_ability -> Activate -> ActivatePower chain -/datum/action/cooldown/bloodsucker/Activate(atom/target) - if(active) - return FALSE - active = TRUE - . = ActivatePower(target) - if(!.) - DeactivatePower(DEACTIVATE_POWER_NO_COOLDOWN) - return FALSE - if(power_flags & BP_CONTINUOUS_EFFECT || constant_bloodcost) - START_PROCESSING(SSprocessing, src) - - owner.log_message("used [src][bloodcost != 0 ? " at the cost of [bloodcost]" : ""].", LOG_ATTACK, color="red") - build_all_button_icons(UPDATE_BUTTON_BACKGROUND) - -/datum/action/cooldown/bloodsucker/proc/RightClickActivate(trigger_flags) - if(!owner) - return FALSE - -/// return TRUE if you want the ability to be considered activated, put your ability activate logic here -/datum/action/cooldown/bloodsucker/proc/ActivatePower(atom/target) - return TRUE - -/datum/action/cooldown/bloodsucker/proc/DeactivatePower(deactivate_flags) - SHOULD_CALL_PARENT(TRUE) - if(!active) //Already inactive? Return - return FALSE - if(power_flags & BP_CONTINUOUS_EFFECT || constant_bloodcost) - STOP_PROCESSING(SSprocessing, src) - if(power_flags & BP_AM_SINGLEUSE && !(deactivate_flags & DEACTIVATE_POWER_DO_NOT_REMOVE)) - remove_after_use() - return FALSE - active = FALSE - if(!click_to_activate && !(deactivate_flags & DEACTIVATE_POWER_NO_COOLDOWN)) - StartCooldown() - build_all_button_icons(UPDATE_BUTTON_BACKGROUND) - return TRUE - -///Used by powers that are scontinuously active (That have BP_CONTINUOUS_EFFECT flag) -/datum/action/cooldown/bloodsucker/process(seconds_per_tick) - SHOULD_CALL_PARENT(TRUE) //Need this to call parent so the cooldown system works - . = ..() - if(!active || !(power_flags & BP_CONTINUOUS_EFFECT)) - return FALSE - if(!ContinueActive(owner)) // We can't afford the Power? Deactivate it. - DeactivatePower() - return FALSE - // We can keep this up (For now), so Pay Cost! - if(power_flags & BP_AM_COSTLESS_UNCONSCIOUS && owner.stat != CONSCIOUS) - return TRUE - if(constant_bloodcost < 0) - return TRUE - if(bloodsuckerdatum_power) - bloodsuckerdatum_power.AdjustBloodVolume(-constant_bloodcost * seconds_per_tick) - else - pay_cost(constant_bloodcost * seconds_per_tick) - return TRUE - -/// Checks to make sure this power can stay active -/datum/action/cooldown/bloodsucker/proc/ContinueActive(mob/living/user, mob/living/target) - if(QDELETED(user)) - return FALSE - if(!constant_bloodcost > 0 || can_pay_blood(user)) - return TRUE - -/// Used to unlearn Single-Use Powers -/datum/action/cooldown/bloodsucker/proc/remove_after_use() - bloodsuckerdatum_power?.powers -= src - Remove(owner) - -/datum/action/cooldown/bloodsucker/proc/get_power_explanation() - SHOULD_CALL_PARENT(TRUE) - . = list() - if(level_current != -1) - . += "LEVEL: [level_current] [name]:" - else - . += "(Inherent Power) [name]:" - - . += get_power_explanation_extended() - -/datum/action/cooldown/bloodsucker/proc/get_power_explanation_extended() - return list() - -/datum/action/cooldown/bloodsucker/proc/get_power_desc() - SHOULD_CALL_PARENT(TRUE) - var/new_desc = "" - if(level_current != -1) - new_desc += "
    LEVEL: [level_current]" - else - new_desc += "
    (Inherent Power)" - if(bloodcost > 0) - new_desc += "

    COST: [bloodcost] Blood" - if(constant_bloodcost > 0) - new_desc += "

    CONSTANT COST: [name] costs [constant_bloodcost] blood per second to keep it active." - if(power_flags & BP_AM_SINGLEUSE) - new_desc += "


    SINGLE USE:
    [name] can only be used once per night." - new_desc += "

    DESCRIPTION: [get_power_desc_extended()]" - new_desc += "
    " - return new_desc - -/datum/action/cooldown/bloodsucker/proc/get_power_desc_extended() - return initial(desc) diff --git a/tff_modular/modules/bloodsucker/powers/cloak.dm b/tff_modular/modules/bloodsucker/powers/cloak.dm deleted file mode 100644 index 3165734f67f..00000000000 --- a/tff_modular/modules/bloodsucker/powers/cloak.dm +++ /dev/null @@ -1,86 +0,0 @@ -#define USE_SEEN_CLOAK_LEVEL 2 -#define USE_RUN_CLOAK_LEVEL 4 - -/datum/action/cooldown/bloodsucker/cloak - name = "Cloak of Darkness" - desc = "Blend into the shadows and become invisible to the untrained and Artificial eye." - button_icon_state = "power_cloak" - power_explanation = "Cloak of Darkness:\n\ - Activate this Power in the shadows and you will slowly turn nearly invisible.\n\ - While using Cloak of Darkness, attempting to run will crush you.\n\ - Additionally, while Cloak is active, you are completely invisible to the AI.\n\ - Higher levels will increase how invisible you are.\n\ - At level 2, you will no longer need to be unseen to activate this power.\n\ - At level 4, you will be able to run while cloaked." - power_flags = BP_CONTINUOUS_EFFECT - check_flags = AB_CHECK_CONSCIOUS - purchase_flags = BLOODSUCKER_CAN_BUY|GHOUL_CAN_BUY - bloodcost = 5 - constant_bloodcost = 0.2 - cooldown_time = 5 SECONDS - var/was_running - -/// Must have nobody around to see the cloak -/datum/action/cooldown/bloodsucker/cloak/can_use(mob/living/carbon/user, trigger_flags) - . = ..() - if(!.) - return FALSE - if(level_current < USE_SEEN_CLOAK_LEVEL) - for(var/mob/living/watcher in oviewers(9, owner)) - if(!watcher.mind) - continue - if(!can_see(watcher, owner)) - continue - if(IS_BLOODSUCKER(watcher) || IS_GHOUL(watcher)) - continue - owner.balloon_alert(owner, "you can only vanish unseen.") - return FALSE - return TRUE - -/datum/action/cooldown/bloodsucker/cloak/ActivatePower(atom/target) - var/mob/living/user = owner - was_running = (user.move_intent == MOVE_INTENT_RUN) - if(level_current < USE_RUN_CLOAK_LEVEL && was_running) - user.toggle_move_intent() - user.AddElement(/datum/element/digitalcamo) - user.balloon_alert(user, "cloak turned on.") - return TRUE - -/datum/action/cooldown/bloodsucker/cloak/process(seconds_per_tick) - // Checks that we can keep using this. - . = ..() - if(!.) - return - if(!active) - return - var/mob/living/user = owner - animate(user, alpha = max(25, owner.alpha - min(75, 10 + 5 * level_current)), time = 1.5 SECONDS) - // Prevents running while on Cloak of Darkness - if(level_current < USE_RUN_CLOAK_LEVEL && user.move_intent != MOVE_INTENT_WALK) - owner.balloon_alert(owner, "you attempt to run, crushing yourself.") - user.toggle_move_intent() - user.adjust_brute_loss(rand(5, 15)) - -/datum/action/cooldown/bloodsucker/cloak/ContinueActive(mob/living/user, mob/living/target) - . = ..() - if(!.) - return FALSE - /// Must be CONSCIOUS - if(user.stat != CONSCIOUS) - to_chat(owner, span_warning("Your cloak failed due to you falling unconcious!")) - return FALSE - return TRUE - -/datum/action/cooldown/bloodsucker/cloak/DeactivatePower(deactivate_flags) - . = ..() - if(!.) - return - var/mob/living/user = owner - animate(user, alpha = 255, time = 1 SECONDS) - user.RemoveElement(/datum/element/digitalcamo) - if(level_current < USE_RUN_CLOAK_LEVEL && was_running && user.move_intent == MOVE_INTENT_WALK) - user.toggle_move_intent() - user.balloon_alert(user, "cloak turned off.") - -#undef USE_SEEN_CLOAK_LEVEL -#undef USE_RUN_CLOAK_LEVEL diff --git a/tff_modular/modules/bloodsucker/powers/feed.dm b/tff_modular/modules/bloodsucker/powers/feed.dm deleted file mode 100644 index d095f130ece..00000000000 --- a/tff_modular/modules/bloodsucker/powers/feed.dm +++ /dev/null @@ -1,458 +0,0 @@ -#define FEED_NOTICE_RANGE 2 -#define FEED_DEFAULT_TIMER (10 SECONDS) -#define FEED_MIN_TIMER (1 SECONDS) - -/datum/action/cooldown/bloodsucker/feed - name = "Feed" - desc = "Feed blood off of a living creature. Feeding while aggressively grabbing them will put them to sleep for a short moment." - button_icon_state = "power_feed" - power_explanation = list( - "Activate Feed while next to someone and you will begin to feed blood off of them.", - "The time needed before you start feeding speeds up the higher level you are.", - "Feeding off of someone next to you will not be noticed by the victim, but it will by nearby onlookers", - "Feeding off of someone while you have them aggressively grabbed will put them to sleep.", - "While feeding, you can't speak, as your mouth is covered.", - "Feeding while nearby (2 tiles away from) a mortal who is unaware of Bloodsuckers' existence, will cause a Masquerade Infraction", - "If you get too many Masquerade Infractions, you will break the Masquerade.", - "If you are in desperate need of blood, mice can be fed off of, at a cost.", - "You must use the ability again to stop sucking blood.", - ) - level_current = -1 // scales itself based on your actual level, since you always have it - power_flags = BP_CONTINUOUS_EFFECT|BP_AM_STATIC_COOLDOWN - bloodsucker_check_flags = BP_CANT_USE_IN_TORPOR|BP_CAN_USE_WHILE_STAKED|BP_CAN_USE_HEARTLESS - purchase_flags = BLOODSUCKER_DEFAULT_POWER - bloodcost = 0 - cooldown_time = 15 SECONDS - - COOLDOWN_DECLARE(feed_movement_notify_cooldown) - ///Amount of blood taken, reset after each Feed. Used for logging. - var/blood_taken = 0 - ///The amount of Blood a target has since our last feed, this loops and lets us not spam alerts of low blood. - var/warning_target_bloodvol = BLOOD_VOLUME_MAX_LETHAL - ///Reference to the target we've fed off of - var/datum/weakref/target_ref - ///Have we notified you already that you are at maximum blood? - var/notified_overfeeding = FALSE - ///assoc list of weakrefs to targets and how much blood we've taken from them. - var/list/targets_and_blood = list() - /// What level of protection you need to prevent feeding - var/penetration = NONE - ///Did we start feeding with aggressive grab or not, or grabbed by someone else? - var/aggressive_feed = TRUE - -/datum/action/cooldown/bloodsucker/feed/get_power_explanation_extended() - . = list() - . += "Activate Feed while next to someone and you will begin to feed blood off of them." - . += "The time needed before you start feeding is [DisplayTimeText(get_feed_start_time())]." - . += "Feeding off of someone while you have them aggressively grabbed will put them to sleep for [DisplayTimeText(get_sleep_time())]." - . += "While feeding, you can't speak, as you are using your mouth to drink blood." - . += "Feeding while nearby ([FEED_NOTICE_RANGE] tiles away from) a mortal who is unaware of Bloodsuckers' existence, will cause a Masquerade Infraction" - . += "If you get too many Masquerade Infractions, you will break the Masquerade." - . += "If you are in desperate need of blood, mice can be fed off of, at a cost to your humanity." - . += "If you are handcuffed, you can use feed to feed off whoever is grabbing you, however this is slower, and very obvious." - . += "You must use the ability again to stop sucking blood." - -/datum/action/cooldown/bloodsucker/feed/can_use(mob/living/carbon/user, trigger_flags) - . = ..() - if(!.) - return FALSE - var/mob/target = target_ref?.resolve() - if(target) //already sucking blood. - var/aggro_feed = check_aggro_feed(target) - if(!ContinueActive(user, target, aggro_feed)) - target_ref = null - else - owner.balloon_alert(owner, "already feeding!") - return FALSE - if(user.is_mouth_covered() && !isplasmaman(user)) - owner.balloon_alert(owner, "mouth covered!") - return FALSE - //Find target, it will alert what the problem is, if any. - if(!find_target()) - return FALSE - return TRUE - -/datum/action/cooldown/bloodsucker/feed/ContinueActive(mob/living/user, mob/living/target, check_aggresive_grab) - if(!target) - return FALSE - if(!user.Adjacent(target)) - return FALSE - if(check_aggresive_grab && !check_aggro_feed(target)) - return FALSE - return TRUE - -/datum/action/cooldown/bloodsucker/feed/DeactivatePower(deactivate_flags) - // run before parent checks just to ensure that this always gets cleaned up - UnregisterSignal(owner, COMSIG_MOB_CLIENT_PRE_LIVING_MOVE) - REMOVE_TRAIT(owner, TRAIT_IMMOBILIZED, FEED_TRAIT) - REMOVE_TRAIT(owner, TRAIT_MUTE, FEED_TRAIT) - . = ..() - if(!.) - return - var/mob/living/user = owner - var/mob/living/feed_target = target_ref?.resolve() - - if(!blood_taken) - return - if(isnull(feed_target) && blood_taken) - log_combat(user, user, "fed on blood (target not found)", addition="(and took [blood_taken] blood)") - else - log_combat(user, feed_target, "fed on blood", addition="(and took [blood_taken] blood)") - to_chat(user, span_notice("You slowly release [feed_target].")) - if(feed_target.client && feed_target.stat == DEAD) - user.add_mood_event("drankkilled", /datum/mood_event/drankkilled) - bloodsuckerdatum_power?.AddHumanityLost(5) - - target_ref = null - warning_target_bloodvol = initial(warning_target_bloodvol) - blood_taken = initial(blood_taken) - notified_overfeeding = initial(notified_overfeeding) - -/datum/action/cooldown/bloodsucker/feed/ActivatePower(atom/target) - // if this happens this means that we didn't properly deactivate the power - if(HAS_TRAIT_FROM(owner, TRAIT_IMMOBILIZED, FEED_TRAIT) || HAS_TRAIT_FROM(owner, TRAIT_MUTE, FEED_TRAIT)) - DeactivatePower() - var/mob/living/feed_target = target_ref?.resolve() - if(!feed_target) - DeactivatePower() - return FALSE - if(istype(feed_target, /mob/living/basic/mouse)) - to_chat(owner, span_notice("You recoil at the taste of a lesser lifeform.")) - if(snobby_drinking_check()) - var/mob/living/user = owner - user.add_mood_event("drankblood", /datum/mood_event/drankblood_bad) - bloodsuckerdatum_power?.AddHumanityLost(1) - bloodsuckerdatum_power?.AdjustBloodVolume(25) - feed_target.death() - StartCooldown() - return FALSE - - owner.balloon_alert(owner, "feeding off [feed_target]...") - owner.face_atom(feed_target) - if(!do_after(owner, get_feed_start_time(), feed_target, hidden = TRUE)) - owner.balloon_alert(owner, "feed stopped") - target_ref = null - return FALSE - if(check_aggro_feed(feed_target)) - aggressive_feed = TRUE - if(!IS_BLOODSUCKER(feed_target) && !IS_GHOUL(feed_target) && !IS_MONSTERHUNTER(feed_target)) - feed_target.Unconscious(get_sleep_time()) - if(!feed_target.density) - feed_target.Move(owner.loc) - owner.visible_message( - span_warning("[owner] closes [owner.p_their()] mouth around [feed_target]'s neck!"), - span_warning("You sink your fangs into [feed_target]'s neck.")) - else - aggressive_feed = FALSE - // Only people who AREN'T the target will notice this action. - var/dead_message = feed_target.stat != DEAD ? " [feed_target.p_they(TRUE)] looks dazed, and will not notice this." : "" - owner.visible_message( - span_warning("[owner] puts [feed_target]'s wrist up to [owner.p_their()] mouth."), - span_notice("You slip your fangs into [feed_target]'s wrist.[dead_message]"), - vision_distance = FEED_NOTICE_RANGE, ignored_mobs = feed_target - ) - - check_if_seen(feed_target) - - ADD_TRAIT(owner, TRAIT_MUTE, FEED_TRAIT) - ADD_TRAIT(owner, TRAIT_IMMOBILIZED, FEED_TRAIT) - RegisterSignal(owner, COMSIG_MOB_CLIENT_PRE_LIVING_MOVE, PROC_REF(notify_move_block)) - return TRUE - -/datum/action/cooldown/bloodsucker/feed/proc/check_if_seen(mob/living/feed_target) - for(var/mob/living/watchers in oviewers(FEED_NOTICE_RANGE) - feed_target) - if(!watchers.client) - continue - if(watchers.stat >= DEAD) - continue - if(watchers.is_blind() || watchers.is_nearsighted_currently()) - continue - if(IS_BLOODSUCKER(watchers) || IS_GHOUL(watchers) || HAS_TRAIT(watchers.mind, TRAIT_BLOODSUCKER_HUNTER)) - continue - owner.balloon_alert(owner, "feed noticed!") - bloodsuckerdatum_power?.give_masquerade_infraction() - break - -/datum/action/cooldown/bloodsucker/feed/process(seconds_per_tick) - if(!active) //If we aren't active (running on SSfastprocess) - return ..() //Manage our cooldown timers - var/mob/living/user = owner - var/mob/living/feed_target = target_ref?.resolve() - if(!feed_target) - DeactivatePower() - return - if(!ContinueActive(user, feed_target, aggressive_feed)) - if(aggressive_feed) - user.visible_message( - span_warning("[user] is ripped from [feed_target]'s throat. [feed_target.p_Their(TRUE)] blood sprays everywhere!"), - span_warning("Your teeth are ripped from [feed_target]'s throat. [feed_target.p_Their(TRUE)] blood sprays everywhere!") - ) - // Deal Damage to Target (should have been more careful!) - if(iscarbon(feed_target)) - var/mob/living/carbon/carbon_target = feed_target - carbon_target.bleed(15) - playsound(get_turf(feed_target), 'sound/effects/splat.ogg', 40, TRUE) - if(ishuman(feed_target)) - var/mob/living/carbon/human/target_user = feed_target - var/obj/item/bodypart/head_part = target_user.get_bodypart(BODY_ZONE_HEAD) - if(head_part) - head_part.generic_bleedstacks += 5 - feed_target.add_splatter_floor(get_turf(feed_target)) - user.add_mob_blood(feed_target) // Put target's blood on us. The donor goes in the ( ) - feed_target.add_mob_blood(feed_target) - feed_target.apply_damage(10, BRUTE, BODY_ZONE_HEAD, wound_bonus = CANT_WOUND) - INVOKE_ASYNC(feed_target, TYPE_PROC_REF(/mob, emote), "scream") - DeactivatePower() - return - - var/feed_strength_mult = 0.3 - if(aggressive_feed) - feed_strength_mult = 1 - if(bloodsuckerdatum_power?.frenzied) - feed_strength_mult *= 2 - - var/already_drunk = targets_and_blood[target_ref] || 0 - var/blood_eaten = drink_blood(feed_target, feed_strength_mult, level_current, already_drunk) - blood_taken += blood_eaten - targets_and_blood[target_ref] += blood_eaten - modify_blood_drunk(blood_eaten * 0.5) - - if(feed_target.mind) - user.add_mood_event("drankblood", /datum/mood_event/drankblood) - // Drank mindless as Ventrue? - BAD - else if(snobby_drinking_check()) - user.add_mood_event("drankblood", /datum/mood_event/drankblood_bad) - if(feed_target.stat >= DEAD) - user.add_mood_event("drankblood", /datum/mood_event/drankblood_dead) - - if(!IS_BLOODSUCKER(feed_target)) - if(feed_target.blood_volume <= BLOOD_VOLUME_BAD && warning_target_bloodvol > BLOOD_VOLUME_BAD) - owner.balloon_alert(owner, "your victim's blood is fatally low!") - else if(feed_target.blood_volume <= BLOOD_VOLUME_OKAY && warning_target_bloodvol > BLOOD_VOLUME_OKAY) - owner.balloon_alert(owner, "your victim's blood is dangerously low.") - else if(feed_target.blood_volume <= BLOOD_VOLUME_SAFE && warning_target_bloodvol > BLOOD_VOLUME_SAFE) - owner.balloon_alert(owner, "your victim's blood is at an unsafe level.") - else if(feed_target.blood_volume <= BLOOD_VOLUME_SAFE && owner.pulling != feed_target) - owner.balloon_alert(owner, "you cannot drink more without first getting a better grip!.") - DeactivatePower() - return - warning_target_bloodvol = feed_target.blood_volume - - if(max_blood_reached(feed_target)) - var/message = "full on blood!" - var/can_overfeed = can_overfeed() - if(can_overfeed) - message += " Anything more we drink now will be burnt on quicker healing" - user.balloon_alert(owner, message) - if(!can_overfeed) - DeactivatePower() - return - notified_overfeeding = TRUE - if(feed_target.blood_volume <= 0) - user.balloon_alert(owner, "no blood left!") - DeactivatePower() - return - owner.playsound_local(get_turf(owner), 'sound/effects/singlebeat.ogg', 40, TRUE) - //play sound to target to show they're dying. - if(aggressive_feed) - feed_target.playsound_local(get_turf(src), 'sound/effects/singlebeat.ogg', 40, TRUE) - -/datum/action/cooldown/bloodsucker/feed/proc/drink_blood(mob/living/feed_target, feed_strength_mult, level_current, already_drunk) - // overridden in bloodsucker power.dm - var/feed_amount = 15 + (level_current * 2) - var/max_drink = feed_amount * feed_strength_mult - var/blood_eatable = min(max_drink, feed_target.blood_volume) - var/owner_blood_volume = 0 - - blood_eatable = apply_drink_modifiers(feed_target, blood_eatable) - - var/sigval = SEND_SIGNAL(owner, COMSIG_MOB_FEED_DRINK, feed_target, blood_eatable, already_drunk) - - if(!(sigval & FEED_CANCEL_BLOOD_TRANSFER)) - if(IS_BLOODSUCKER(owner)) - bloodsuckerdatum_power.handle_feeding(feed_target, blood_eatable, already_drunk) - owner_blood_volume = bloodsuckerdatum_power.GetBloodVolume() - - else if(isliving(owner) && !HAS_TRAIT(owner, TRAIT_NOBLOOD)) - var/mob/living/living_owner = owner - living_owner.blood_volume += blood_eatable - owner_blood_volume = living_owner.blood_volume - - if(feed_target.reagents && feed_target.reagents.total_volume) - feed_target.reagents.trans_to(owner, INGEST, 1) // Run transfer of 1 unit of reagent from them to me. - feed_target.blood_volume = max(0, feed_target.blood_volume - blood_eatable) - - if(owner_blood_volume > 0) - owner.bodytemperature = ((owner_blood_volume * owner.bodytemperature) + (blood_eatable * feed_target.bodytemperature)) / (owner_blood_volume + blood_eatable) - return blood_eatable - -/datum/action/cooldown/bloodsucker/feed/proc/apply_drink_modifiers(mob/living/feed_target, blood_eatable) - if(feed_target.stat == DEAD) // Penalty for Dead Blood - blood_eatable /= 3 - if(!ishuman(feed_target)) // Penalty for Non-Human Blood - blood_eatable /= 2 - else if(!feed_target?.mind) // Penalty for Mindless Blood - blood_taken /= 2 - return blood_eatable - -/datum/action/cooldown/bloodsucker/feed/proc/check_aggro_feed(mob/living/feed_target) - var/mob/living/carbon/carbon = owner - if(owner.pulling != feed_target && owner.pulledby != feed_target \ - || (feed_target.pulledby != owner && iscarbon(carbon) && carbon.handcuffed)) - return FALSE - return TRUE - -/datum/action/cooldown/bloodsucker/feed/proc/max_blood_reached(mob/living/feed_target) - if(bloodsuckerdatum_power && bloodsuckerdatum_power.GetBloodVolume() >= bloodsuckerdatum_power.max_blood_volume && !notified_overfeeding) - return TRUE - if(HAS_TRAIT(owner, TRAIT_NOBLOOD)) - return FALSE - var/sigval = SEND_SIGNAL(owner, COMSIG_MOB_REACHED_MAX_BLOOD, feed_target) - if(sigval & REACHED_MAX_BLOOD) - return TRUE - if(astype(owner, /mob/living).blood_volume >= BLOOD_VOLUME_MAXIMUM) - return TRUE - return FALSE - -/datum/action/cooldown/bloodsucker/proc/snobby_drinking_check() - if(bloodsuckerdatum_power?.my_clan && bloodsuckerdatum_power.my_clan.blood_drink_type != BLOODSUCKER_DRINK_INHUMANELY) - return TRUE - return FALSE - -/datum/action/cooldown/bloodsucker/feed/proc/find_target() - // grabbing or grabbed, you're close enough to bite. - if(safe_set_target(owner.pulling)) - return TRUE - if(safe_set_target(owner.pulledby)) - return TRUE - if(bloodsuckerdatum_power?.frenzied) - owner.balloon_alert(owner, "beast active! must grab someone to feed!") - return FALSE - var/mob/living/carbon/carbon = owner - if(iscarbon(carbon) && carbon.handcuffed) - owner.balloon_alert(owner, "you cannot stealthily feed while handcuffed!") - return FALSE - var/list/close_living_mobs = list() - var/list/close_dead_mobs = list() - for(var/mob/living/near_targets in oview(1, owner)) - if(!owner.Adjacent(near_targets)) - continue - if(near_targets.stat) - close_living_mobs |= near_targets - else - close_dead_mobs |= near_targets - //Check living first - for(var/mob/living/suckers in close_living_mobs) - if(can_feed_from(suckers)) - set_target(suckers) - return TRUE - //If not, check dead - for(var/mob/living/suckers in close_dead_mobs) - if(can_feed_from(suckers)) - set_target(suckers) - return TRUE - //No one to suck blood from. - return FALSE - -/datum/action/cooldown/bloodsucker/feed/proc/safe_set_target(mob/living/target, give_warnings = TRUE) - if(!can_feed_from(target, give_warnings)) - return FALSE - set_target(target) - return TRUE - -// this lets us compare and access things by weakrefs, if we use the actual same weakref instance in the assoc list -/datum/action/cooldown/bloodsucker/feed/proc/set_target(mob/living/target) - if(!length(targets_and_blood)) - target_ref = WEAKREF(target) - return - - for(var/datum/weakref/weakref as anything in targets_and_blood) - var/mob/living/old_target = weakref.resolve() - if(old_target == target) - target_ref = weakref - break - if(!target_ref) - target_ref = WEAKREF(target) - -/datum/action/cooldown/bloodsucker/feed/proc/can_feed_from(mob/living/target, give_warnings = FALSE) - if(istype(target, /mob/living/basic/mouse)) - if(snobby_drinking_check()) - if(give_warnings) - owner.balloon_alert(owner, "too disgusting!") - return FALSE - return TRUE - //Mice check done, only humans are otherwise allowed - if(!ishuman(target)) - return FALSE - - var/mob/living/carbon/human/target_user = target - if(!(target_user.dna?.species) || !(target_user.mob_biotypes & MOB_ORGANIC) || HAS_TRAIT(target_user, TRAIT_NOBLOOD)) - if(give_warnings) - owner.balloon_alert(owner, "no blood!") - return FALSE - if(!target_user.can_inject(owner, BODY_ZONE_HEAD, penetration)) - if(give_warnings) - owner.balloon_alert(owner, "headgear too thick!") - return FALSE - if(!can_overfeed() && max_blood_reached(target_user)) - if(give_warnings) - owner.balloon_alert(owner, "too full to drink more!") - return FALSE - if(!target.mind && !can_drink_from_mindless(target_user)) - if(give_warnings) - owner.balloon_alert(owner, "cant drink from mindless!") - return FALSE - if(target_user.has_reagent(/datum/reagent/consumable/garlic, 5)) - if(give_warnings) - owner.balloon_alert(owner, "too much garlic!") - return FALSE - return TRUE - -/datum/action/cooldown/bloodsucker/feed/proc/can_drink_from_mindless(mob/living/target) - if(!bloodsuckerdatum_power?.my_clan) - return TRUE - if(snobby_drinking_check() && !bloodsuckerdatum_power.frenzied) - return FALSE - return TRUE - -/datum/action/cooldown/bloodsucker/feed/proc/get_sleep_time() - return (5 + bloodsuckerdatum_power?.GetRank() || 1) SECONDS - -/datum/action/cooldown/bloodsucker/feed/proc/get_feed_start_time() - var/bloodsucker_level_divider = 1.25 * (bloodsuckerdatum_power?.GetRank() || 1) - var/feed_time = FEED_DEFAULT_TIMER / bloodsucker_level_divider - if(bloodsuckerdatum_power?.frenzied) - feed_time *= 0.5 - var/mob/living/carbon/carbon = owner - if(iscarbon(carbon) && carbon.handcuffed) - feed_time *= 2 - return clamp(round(feed_time), FEED_MIN_TIMER, FEED_DEFAULT_TIMER) - -/datum/action/cooldown/bloodsucker/feed/proc/notify_move_block() - SIGNAL_HANDLER - if(!active) - DeactivatePower() - return - if (!COOLDOWN_FINISHED(src, feed_movement_notify_cooldown)) - return - COOLDOWN_START(src, feed_movement_notify_cooldown, 3 SECONDS) - owner.balloon_alert(owner, "you cannot move while feeding! Click the power to stop.") - -/datum/action/cooldown/bloodsucker/feed/proc/modify_blood_drunk(amount = 0) - for(var/datum/weakref/weakref as anything in targets_and_blood) - if(weakref == target_ref) - continue - targets_and_blood[weakref] = max(0, targets_and_blood[weakref] - amount) - if(targets_and_blood[weakref] <= 0) - targets_and_blood -= weakref - -/datum/action/cooldown/bloodsucker/feed/proc/can_overfeed() - return IS_BLOODSUCKER(owner) - - -#undef FEED_NOTICE_RANGE -#undef FEED_DEFAULT_TIMER -#undef FEED_MIN_TIMER - - - diff --git a/tff_modular/modules/bloodsucker/powers/fortitude.dm b/tff_modular/modules/bloodsucker/powers/fortitude.dm deleted file mode 100644 index c7ba5fecb06..00000000000 --- a/tff_modular/modules/bloodsucker/powers/fortitude.dm +++ /dev/null @@ -1,75 +0,0 @@ -#define FORTITUDE_STUN_IMMUNITY_LEVEL 4 -/datum/action/cooldown/bloodsucker/fortitude - name = "Fortitude" - desc = "Withstand egregious physical wounds and walk away from attacks that would stun, pierce, and dismember lesser beings, but will render you unable to heal." - button_icon_state = "power_fortitude" - power_flags = BP_CONTINUOUS_EFFECT|BP_AM_COSTLESS_UNCONSCIOUS - check_flags = BP_CANT_USE_IN_TORPOR|BP_CANT_USE_IN_FRENZY - purchase_flags = BLOODSUCKER_CAN_BUY|GHOUL_CAN_BUY - cooldown_time = 10 SECONDS - bloodcost = 30 - constant_bloodcost = 0.2 - var/fortitude_resist // So we can raise and lower your brute resist based on what your level_current WAS. - var/list/trigger_listening = list() - var/traits_to_add = list(TRAIT_PIERCEIMMUNE, TRAIT_NODISMEMBER, TRAIT_PUSHIMMUNE) - -/datum/action/cooldown/bloodsucker/fortitude/get_power_explanation_extended() - . = list() - . += "Fortitude will provide pierce, stun and dismember immunity." - . += "You will additionally gain resistance to both brute, burn and stamina damage, scaling with level." - . += "Fortitude will make you receive [GetFortitudeResist() * 10]% less brute, stamina and [GetFortitudeResist() * 10]% less burn damage." - . += "At level [FORTITUDE_STUN_IMMUNITY_LEVEL], you gain complete stun immunity while [src] is active." - . += "Higher levels will increase Brute and Stamina resistance." - -/datum/action/cooldown/bloodsucker/fortitude/upgrade_power() - . = ..() - if(level_current >= FORTITUDE_STUN_IMMUNITY_LEVEL) - traits_to_add |= TRAIT_STUNIMMUNE - -/datum/action/cooldown/bloodsucker/fortitude/ActivatePower(atom/target) - owner.balloon_alert(owner, "fortitude turned on.") - to_chat(owner, span_notice("Your flesh, skin, and muscles become as steel.")) - // Traits & Effects - owner.add_traits(traits_to_add, BLOODSUCKER_TRAIT) - - var/mob/living/carbon/human/bloodsucker_user = owner - if(IS_BLOODSUCKER(owner) || IS_GHOUL(owner)) - fortitude_resist = GetFortitudeResist() - bloodsucker_user.physiology.brute_mod *= fortitude_resist - bloodsucker_user.physiology.burn_mod *= fortitude_resist - bloodsucker_user.physiology.stamina_mod *= fortitude_resist - - RegisterSignal(owner, COMSIG_LIVING_ADJUST_BRUTE_DAMAGE, PROC_REF(on_heal)) - RegisterSignal(owner, COMSIG_LIVING_ADJUST_BURN_DAMAGE, PROC_REF(on_heal)) - return TRUE - -/datum/action/cooldown/bloodsucker/fortitude/proc/on_heal(mob/current_mob, type, amount, forced) - if(!forced && active && amount < 0) - return COMPONENT_IGNORE_CHANGE - return NONE - -/datum/action/cooldown/bloodsucker/fortitude/proc/GetFortitudeResist() - return max(0.3, 0.7 - level_current * 0.05) - -/datum/action/cooldown/bloodsucker/fortitude/DeactivatePower(deactivate_flags) - if(length(trigger_listening)) - for(var/power in trigger_listening) - UnregisterSignal(power, COMSIG_FIRE_TARGETED_POWER) - trigger_listening -= power - . = ..() - if(!. || !ishuman(owner)) - return - var/mob/living/carbon/human/bloodsucker_user = owner - if(IS_BLOODSUCKER(owner) || IS_GHOUL(owner) && fortitude_resist) - bloodsucker_user.physiology.brute_mod /= fortitude_resist - bloodsucker_user.physiology.burn_mod /= fortitude_resist - bloodsucker_user.physiology.stamina_mod /= fortitude_resist - // Remove Traits & Effects - owner.remove_traits(traits_to_add, BLOODSUCKER_TRAIT) - - owner.balloon_alert(owner, "fortitude turned off.") - fortitude_resist = 1 - UnregisterSignal(owner, list(COMSIG_LIVING_ADJUST_BRUTE_DAMAGE, COMSIG_LIVING_ADJUST_BURN_DAMAGE)) - return ..() - -#undef FORTITUDE_STUN_IMMUNITY_LEVEL diff --git a/tff_modular/modules/bloodsucker/powers/gohome.dm b/tff_modular/modules/bloodsucker/powers/gohome.dm deleted file mode 100644 index fe1fbbcef32..00000000000 --- a/tff_modular/modules/bloodsucker/powers/gohome.dm +++ /dev/null @@ -1,144 +0,0 @@ -#define GOHOME_START 0 -#define GOHOME_FLICKER_ONE 2 -#define GOHOME_FLICKER_TWO 4 -#define GOHOME_TELEPORT 6 - -/** - * Given to Bloodsuckers near Sol if they have a Coffin claimed. - * Teleports them to their Coffin after a delay. - * Makes them drop everything if someone witnesses the act. - */ -/datum/action/cooldown/bloodsucker/gohome - name = "Vanishing Act" - desc = "As dawn aproaches, disperse into mist and return directly to your Haven.
    WARNING: You will drop ALL of your possessions if observed by mortals." - button_icon_state = "power_gohome" - active_background_icon_state = "vamp_power_off_oneshot" - base_background_icon_state = "vamp_power_off_oneshot" - power_flags = BP_AM_STATIC_COOLDOWN - bloodsucker_check_flags = BP_CANT_USE_IN_FRENZY - check_flags = BP_CANT_USE_IN_FRENZY | BP_CANT_USE_IN_TORPOR - purchase_flags = NONE - bloodcost = 100 - cooldown_time = 5 MINUTES - power_activates_immediately = FALSE - level_current = -1 - - ///What stage of the teleportation are we in - var/teleporting_stage = GOHOME_START - ///The types of mobs that will drop post-teleportation. - var/static/list/spawning_mobs = list( - /mob/living/basic/mouse = 3, - /mob/living/basic/bat = 1, - ) - -/datum/action/cooldown/bloodsucker/gohome/get_power_explanation_extended() - . = list() - . += "Vanishing Act will, after a short delay, teleport the user to their Claimed Coffin." - . += "The user will drop all belongings if seen by a mortal." - . += "The power will cancel out if the Claimed Coffin is somehow destroyed." - . += "Immediately after activating, lights around the user will begin to flicker." - . += "Once the user teleports to their coffin, in their place will be a Rat or Bat." - -/datum/action/cooldown/bloodsucker/gohome/can_use(mob/living/carbon/user, trigger_flags) - . = ..() - if(!.) - return FALSE - /// Have No Haven (NOTE: You only got this power if you had a haven, so this means it's destroyed) - if(!istype(bloodsuckerdatum_power) || !bloodsuckerdatum_power.coffin) - owner.balloon_alert(owner, "coffin was destroyed!") - return FALSE - if(owner.loc == bloodsuckerdatum_power.coffin) - owner.balloon_alert(owner, "you're arleady in your coffin!") - return FALSE - if(!check_teleport_valid(owner, bloodsuckerdatum_power.coffin, TELEPORT_CHANNEL_MAGIC)) - owner.balloon_alert(owner, "something holds you back!") - return FALSE - return TRUE - -/datum/action/cooldown/bloodsucker/gohome/ActivatePower(atom/target) - owner.balloon_alert(owner, "preparing to teleport...") - return TRUE - -/datum/action/cooldown/bloodsucker/gohome/DeactivatePower(deactivate_flags) - if(active && teleporting_stage != GOHOME_TELEPORT) - owner.balloon_alert(owner, "teleportation cancelled.") - teleporting_stage = GOHOME_START - return . = ..(DEACTIVATE_POWER_DO_NOT_REMOVE) - . = ..() - -/datum/action/cooldown/bloodsucker/gohome/process(seconds_per_tick) - . = ..() - if(!.) - return FALSE - - switch(teleporting_stage) - if(GOHOME_START) - INVOKE_ASYNC(src, PROC_REF(flicker_lights), 3, 20) - if(GOHOME_FLICKER_ONE) - INVOKE_ASYNC(src, PROC_REF(flicker_lights), 4, 40) - if(GOHOME_FLICKER_TWO) - INVOKE_ASYNC(src, PROC_REF(flicker_lights), 4, 60) - if(GOHOME_TELEPORT) - INVOKE_ASYNC(src, PROC_REF(teleport_to_coffin), owner) - teleporting_stage++ - -/datum/action/cooldown/bloodsucker/gohome/ContinueActive(mob/living/user, mob/living/target) - . = ..() - if(!.) - return FALSE - if(!isturf(owner.loc)) - return FALSE - if(!bloodsuckerdatum_power.coffin) - user.balloon_alert(user, "coffin destroyed!") - to_chat(owner, span_warning("Your coffin has been destroyed! You no longer have a destination.")) - return FALSE - return TRUE - -/datum/action/cooldown/bloodsucker/gohome/proc/flicker_lights(flicker_range, beat_volume) - for(var/obj/machinery/light/nearby_lights in view(flicker_range, get_turf(owner))) - nearby_lights.flicker(5) - playsound(get_turf(owner), 'sound/effects/singlebeat.ogg', beat_volume, 1) - -/datum/action/cooldown/bloodsucker/gohome/proc/teleport_to_coffin(mob/living/carbon/user) - var/drop_item = FALSE - var/turf/current_turf = get_turf(user) - // If we aren't in the dark, anyone watching us will cause us to drop out stuff - if(current_turf && current_turf.lighting_object && current_turf.get_lumcount() >= 0.2) - for(var/mob/living/watchers in viewers(world.view, get_turf(user)) - user) - if(QDELETED(watchers.client) || watchers.stat != CONSCIOUS) - continue - if(watchers.is_blind()) - continue - if(!IS_BLOODSUCKER(watchers) && !IS_GHOUL(watchers)) - drop_item = TRUE - break - // Drop all necessary items (handcuffs, legcuffs, items if seen) - user.uncuff() - if(drop_item) - for(var/obj/item/literally_everything in owner) - owner.dropItemToGround(literally_everything) - - playsound(current_turf, 'sound/effects/magic/summon_karp.ogg', 60, 1) - - var/datum/effect_system/steam_spread/bloodsucker/puff = new /datum/effect_system/steam_spread/bloodsucker() - puff.set_up(3, 0, current_turf) - puff.start() - - /// STEP FIVE: Create animal at prev location - var/mob/living/simple_animal/new_mob = pick_weight(spawning_mobs) - new new_mob(current_turf) - /// TELEPORT: Move to Coffin & Close it! - user.set_resting(TRUE, TRUE, FALSE) - do_teleport(user, bloodsuckerdatum_power.coffin, no_effects = TRUE, forced = TRUE, channel = TELEPORT_CHANNEL_QUANTUM) - bloodsuckerdatum_power.coffin.force_enter(user) - - DeactivatePower() - pay_cost() - -/datum/effect_system/steam_spread/bloodsucker - effect_type = /obj/effect/particle_effect/fluid/smoke/vampsmoke - -#undef GOHOME_START -#undef GOHOME_FLICKER_ONE -#undef GOHOME_FLICKER_TWO -#undef GOHOME_TELEPORT diff --git a/tff_modular/modules/bloodsucker/powers/masquerade.dm b/tff_modular/modules/bloodsucker/powers/masquerade.dm deleted file mode 100644 index a7e4af8d3d2..00000000000 --- a/tff_modular/modules/bloodsucker/powers/masquerade.dm +++ /dev/null @@ -1,115 +0,0 @@ -/** - * # WITHOUT THIS POWER: - * - * - Mid-Blood: SHOW AS PALE - * - Low-Blood: SHOW AS DEAD - * - No Heartbeat - * - Examine shows actual blood - * - Thermal homeostasis (ColdBlooded) - * WITH THIS POWER: - * - Normal body temp -- remove Cold Blooded (return on deactivate) - */ - -/datum/action/cooldown/bloodsucker/masquerade - name = "Masquerade" - desc = "Feign the vital signs of a mortal, and escape both casual and medical notice as the monster you truly are." - button_icon_state = "power_human" - power_flags = BP_CONTINUOUS_EFFECT|BP_AM_STATIC_COOLDOWN|BP_AM_COSTLESS_UNCONSCIOUS - check_flags = NONE - bloodsucker_check_flags = BP_CANT_USE_IN_FRENZY - purchase_flags = BLOODSUCKER_DEFAULT_POWER - bloodcost = 10 - level_current = -1 - cooldown_time = 5 SECONDS - constant_bloodcost = 0.1 - -/datum/action/cooldown/bloodsucker/masquerade/get_power_explanation_extended() - . = list() - . += "Masquerade will forge your identity to be practically identical to that of a human." - . += "- You lose nearly all Bloodsucker benefits, including healing, sleep, radiation, crit, virus, gutting and cold immunity." - . += "- Your eyes turn to that of a regular human as your heart begins to beat." - . += "- You gain a Genetic sequence, and appear to have 100% blood when scanned by a Health Analyzer." - . += "- You will not appear as Pale when examined. Anything further than Pale, however, will not be hidden." - . += "At the end of a Masquerade, you will re-gain your Vampiric abilities, as well as lose any diseases you might have." - -/datum/action/cooldown/bloodsucker/masquerade/ActivatePower(atom/target) - var/mob/living/carbon/user = owner - owner.balloon_alert(owner, "masquerade turned on.") - to_chat(user, span_notice("Your heart beats falsely within your lifeless chest, and your eyes are no longer sensitive to the light. You may yet pass for a mortal.")) - to_chat(user, span_warning("Your vampiric healing is halted while imitating life.")) - - // Give status effect - user.apply_status_effect(/datum/status_effect/masquerade) - - // Handle Traits - user.remove_traits(bloodsuckerdatum_power.bloodsucker_traits, BLOODSUCKER_TRAIT) - - ADD_TRAIT(user, TRAIT_MASQUERADE, BLOODSUCKER_TRAIT) - var/obj/item/bodypart/chest/target_chest = user.get_bodypart(BODY_ZONE_CHEST) - if(target_chest) - target_chest.bodypart_flags &= ~BODYPART_UNREMOVABLE - // Handle organs - var/obj/item/organ/heart/vampheart = user.get_organ_slot(ORGAN_SLOT_HEART) - if(vampheart) - vampheart.Restart() - var/obj/item/organ/eyes/eyes = user.get_organ_slot(ORGAN_SLOT_EYES) - if(eyes) - eyes.flash_protect = initial(eyes.flash_protect) - eyes.color_cutoffs = initial(eyes.color_cutoffs) - eyes.sight_flags = initial(eyes.sight_flags) - user.update_sight() - return TRUE - -/// todo, make bloodsuckerification into it's own proc, ie, eyes, traits, and such -/datum/action/cooldown/bloodsucker/masquerade/DeactivatePower(deactivate_flags) - . = ..() // activate = FALSE - if(!.) - return - var/mob/living/carbon/user = owner - owner.balloon_alert(owner, "masquerade turned off.") - - // Remove status effect, mutations & diseases that you got while on masq. - user.remove_status_effect(/datum/status_effect/masquerade) - for(var/datum/disease/diseases as anything in user.diseases) - diseases.cure() - - // Handle Traits - user.add_traits(bloodsuckerdatum_power.bloodsucker_traits, BLOODSUCKER_TRAIT) - REMOVE_TRAIT(user, TRAIT_MASQUERADE, BLOODSUCKER_TRAIT) - var/obj/item/bodypart/chest/target_chest = user.get_bodypart(BODY_ZONE_CHEST) - if(target_chest) - target_chest.bodypart_flags |= BODYPART_UNREMOVABLE - // Handle organs - var/obj/item/organ/heart/vampheart = user.get_organ_slot(ORGAN_SLOT_HEART) - if(vampheart) - vampheart.Stop() - var/obj/item/organ/eyes/eyes = user.get_organ_slot(ORGAN_SLOT_EYES) - if(eyes) - eyes.flash_protect = max(initial(eyes.flash_protect) - 1, FLASH_PROTECTION_SENSITIVE) - eyes.color_cutoffs = BLOODSUCKER_SIGHT_COLOR_CUTOFF - eyes.sight_flags = SEE_MOBS - user.update_sight() - to_chat(user, span_notice("Your heart beats one final time, while your skin dries out and your icy pallor returns.")) - -/** - * # Status effect - * - * This is what the Masquerade power gives, handles their bonuses and gives them a neat icon to tell them they're on Masquerade. - */ - -/datum/status_effect/masquerade - id = "masquerade" - duration = STATUS_EFFECT_PERMANENT - duration = STATUS_EFFECT_NO_TICK - alert_type = /atom/movable/screen/alert/status_effect/masquerade - -/atom/movable/screen/alert/status_effect/masquerade - name = "Masquerade" - desc = "You are currently hiding your identity using the Masquerade power. This halts Vampiric healing." - icon = 'tff_modular/modules/bloodsucker/icons/bloodsucker.dmi' - icon_state = "power_human" - alerttooltipstyle = "cult" - -/atom/movable/screen/alert/status_effect/masquerade/MouseEntered(location,control,params) - desc = initial(desc) - return ..() diff --git a/tff_modular/modules/bloodsucker/powers/prince/scourgify.dm b/tff_modular/modules/bloodsucker/powers/prince/scourgify.dm deleted file mode 100644 index d81b325c59d..00000000000 --- a/tff_modular/modules/bloodsucker/powers/prince/scourgify.dm +++ /dev/null @@ -1,125 +0,0 @@ -/datum/action/cooldown/bloodsucker/targeted/scourgify - name = "Select Scourge" - desc = "Select another kindred or one of your ghoul as your scourge." - button_icon_state = "power_scourge" - power_explanation = "Activate to select another kindred, or one of your ghoul, as your personal scourge.\n\n\ - When used on another kindred, they will receive some levels and an objective to obey you.\n\ - When used on your ghoul, you will become their sire, embracing them as a full-blooded vampire.\n\ - They will be part of your own clan, and of course receive some bonus levels as well.\n\n\ - The Scourge is your enforcer, your tool to wield in the name of the Camarilla. Use them to enforce the masquerade, and to keep control over your fellow kindred." - bloodsucker_check_flags = BP_CANT_USE_IN_TORPOR | BP_CANT_USE_IN_FRENZY - bloodcost = 0 - cooldown_time = 35 SECONDS - power_activates_immediately = FALSE - prefire_message = "Whom will you choose?" - var/datum/weakref/target_ref - var/promoting = FALSE - -/datum/action/cooldown/bloodsucker/targeted/scourgify/CheckValidTarget(atom/target_atom) - . = ..() - if(!isliving(target_atom)) - return FALSE - var/mob/living/living_target = target_atom - var/datum/antagonist/bloodsucker/target_vampire = IS_BLOODSUCKER(living_target) - if(!living_target.mind || !living_target.client) - owner.balloon_alert(owner, "mindless") - return FALSE - if(living_target.stat != CONSCIOUS) - owner.balloon_alert(owner, "not [(living_target.stat == DEAD || HAS_TRAIT(living_target, TRAIT_FAKEDEATH)) ? "alive" : "conscious"]") - return FALSE - - if(IS_GHOUL(living_target) && !(IS_GHOUL(living_target) in bloodsuckerdatum_power.ghouls)) - owner.balloon_alert(owner, "not your ghoul") - return FALSE - - if(!IS_BLOODSUCKER(living_target) && !IS_GHOUL(living_target)) - owner.balloon_alert(owner, "not ghoul or bloodsucker") - return FALSE - - if(target_vampire && (target_vampire.prince || target_vampire.scourge)) - owner.balloon_alert(owner, "cannot promote elders") - return FALSE - - if(target_ref || promoting) - owner.balloon_alert(owner, "already offering!") - return FALSE - - return TRUE - -/datum/action/cooldown/bloodsucker/targeted/scourgify/FireTargetedPower(atom/target, params) - . = ..() - var/mob/living/living_target = target - - var/datum/antagonist/ghoul/vassal = IS_GHOUL(living_target) - - promoting = TRUE - - if(vassal) // We don't need to ask a lowly vassal. - // Pull them into our clan - var/datum/bloodsucker_clan/masterclan_type = bloodsuckerdatum_power.my_clan?.type - - if(!masterclan_type) // How did a caitiff get prince, bro. Fine. - owner.balloon_alert(owner, "select clan first!") - DeactivatePower() - return - - vassal.silent = TRUE - living_target.mind.remove_antag_datum(/datum/antagonist/ghoul) - - // Make, then give the datum - var/datum/antagonist/bloodsucker/scourgedatum = new(living_target.mind) - scourgedatum.stinger_sound = null // to avoid several sounds stacking on top of each other - living_target.mind.add_antag_datum(scourgedatum) - - scourgedatum.my_clan = new masterclan_type(scourgedatum) - - // Scourgify and end power - scourgedatum.scourgify() - target_ref = null - PowerActivatedSuccesfully() - return - else - target_ref = WEAKREF(IS_BLOODSUCKER(living_target)) - - owner.balloon_alert(owner, "you offer [living_target] the rank of Scourge...") - living_target.playsound_local(null, 'tff_modular/modules/bloodsucker/sound/scourge_offer.ogg', 100, FALSE, pressure_affected = FALSE) - - ASYNC - var/choice = tgui_alert(living_target, - message = "Your Prince has selected you as [owner.p_their()] enforcer. Should you accept, you will receive the rank of 'Scourge', be bound to [owner.p_their()] authority, and increase in power considerably.", - title = "Scourge Offer", - buttons = list("Accept", "Refuse"), - timeout = cooldown_time - 5 SECONDS, - autofocus = TRUE - ) - handle_choice(choice) - - addtimer(CALLBACK(src, PROC_REF(choice_timeout)), cooldown_time) - DeactivatePower() - -/datum/action/cooldown/bloodsucker/targeted/scourgify/proc/accepted() - var/datum/antagonist/bloodsucker/target_datum = target_ref.resolve() - target_datum.scourgify() - target_ref = null - PowerActivatedSuccesfully() - bloodsuckerdatum_power.RemovePower(src) - -/datum/action/cooldown/bloodsucker/targeted/scourgify/proc/refused() - owner.balloon_alert(owner, "offer refused") - target_ref = null - promoting = FALSE - -/datum/action/cooldown/bloodsucker/targeted/scourgify/proc/choice_timeout() - if(owner && target_ref) // This might happen AFTER we remove the power from our owner. - owner.balloon_alert(owner, "offer ignored") - target_ref = null - promoting = FALSE - -/datum/action/cooldown/bloodsucker/targeted/scourgify/proc/handle_choice(choice) - switch(choice) - if("Accept") - accepted() - return - if("Refuse") - refused() - return diff --git a/tff_modular/modules/bloodsucker/powers/targeted/_powers_targeted.dm b/tff_modular/modules/bloodsucker/powers/targeted/_powers_targeted.dm deleted file mode 100644 index e41ecc0fc65..00000000000 --- a/tff_modular/modules/bloodsucker/powers/targeted/_powers_targeted.dm +++ /dev/null @@ -1,119 +0,0 @@ -// NOTE: All Targeted spells are Toggles! We just don't bother checking here. -/datum/action/cooldown/bloodsucker/targeted - power_flags = NONE - click_to_activate = TRUE - ///If set, how far the target has to be for the power to work. - var/target_range - ///Message sent to chat when clicking on the power, before you use it. - var/prefire_message - ///Is this power LOCKED due to being used? - var/power_in_use = FALSE - -/// Modify description to add notice that this is aimed. -/datum/action/cooldown/bloodsucker/targeted/get_power_desc() - . = ..() - var/current_desc = "
    \[Targeted Power\]" - if(target_range) - current_desc += "
    Cast Range: [target_range]
    " - current_desc += . - return current_desc - - -// *Don't read this if you don't care about how actions work.* -// Actions are a wee complicated, but for anyone else who's going to take a look at this, let me explain. -// Actions start at Trigger, which is/ called by the client clicking the action button, -// if it's a targeted power, like this one here, it will call set_click_ability, -// which will set up the click interception. Thus clicking will call Trigger again, but with a target this time. -// Otherwise, if click_to_activate is false, it will simply always call Trigger without a target, -// and call PreActivate, which then calls Activate. -// For this ability, we call InterceptClickOn to trigger the ability with a target, as we want -// to be able to use trigger_flags, which Activate doesn't have. - - -// If click_to_activate is true, only these two procs are called when the ability is clicked on -/datum/action/cooldown/bloodsucker/targeted/set_click_ability(mob/on_who) - // activate runs before - if(!PreActivate()) - return - . = ..() - if(prefire_message) - to_chat(owner, span_announce("[prefire_message]")) - -/datum/action/cooldown/bloodsucker/targeted/unset_click_ability(mob/on_who, refund_cooldown) - . = ..() - if(active) //todo refactor active into is_action_active() - DeactivatePower() - -/// Check if target is VALID (wall, turf, or character?) -/datum/action/cooldown/bloodsucker/targeted/proc/CheckValidTarget(atom/target_atom) - if(target_atom == owner) - return FALSE - if(!target_atom) - return FALSE - return TRUE - -/// Check if valid target meets conditions -/datum/action/cooldown/bloodsucker/targeted/proc/CheckCanTarget(atom/target_atom) - if(target_range) - // Out of Range - if(!(target_atom in view(target_range, owner))) - if(target_range > 1) // Only warn for range if it's greater than 1 - owner.balloon_alert(owner, "out of range.") - return FALSE - return istype(target_atom) - -/// Click Target -/datum/action/cooldown/bloodsucker/targeted/PreActivate(atom/target) - if(!target) - return ..() - // CANCEL RANGED TARGET check - if(power_in_use || !CheckValidTarget(target)) - return FALSE - // Valid? (return true means DON'T cancel power!) - if(!can_pay_cost() || !can_use(owner) || !CheckCanTarget(target)) - return FALSE - if(power_activates_immediately) - PowerActivatedSuccesfully() // Mesmerize pays only after success. - power_in_use = FALSE - return TRUE - -/datum/action/cooldown/bloodsucker/targeted/proc/FireTargetedPower(atom/target, params) - return FALSE - -/// Called on right click -/datum/action/cooldown/bloodsucker/targeted/proc/FireSecondaryTargetedPower(atom/target, params) - return FireTargetedPower(target, params) - -/datum/action/cooldown/bloodsucker/targeted/ActivatePower(atom/target) - . = ..() - if(!target) - return . - log_combat(owner, target, "used [name] on [target].") - return TRUE - -/datum/action/cooldown/bloodsucker/targeted/DeactivatePower(deactivate_flags) - . = ..() - if(!.) - return - // sometimes things will call DeactivatePower, but not unset_click_ability, so we have to unset the click interception here. - if(owner.click_intercept == src) // TODO test if this is no longer needed - owner.click_intercept = null - -/// The power went off! We now pay the cost of the power. -/datum/action/cooldown/bloodsucker/targeted/proc/PowerActivatedSuccesfully(cooldown_override, cost_override) - StartCooldown(cooldown_override) - unset_click_ability(owner) - pay_cost(cost_override) - // if(active) - // DeactivatePower() - -/datum/action/cooldown/bloodsucker/targeted/InterceptClickOn(mob/living/clicker, params, atom/target) - . = ..() - if(!.) - return FALSE - var/list/modifiers = params2list(params) - SEND_SIGNAL(src, COMSIG_FIRE_TARGETED_POWER, target) - if(LAZYACCESS(modifiers, RIGHT_CLICK)) - return FireSecondaryTargetedPower(target, modifiers) - else - return FireTargetedPower(target, modifiers) diff --git a/tff_modular/modules/bloodsucker/powers/targeted/brawn.dm b/tff_modular/modules/bloodsucker/powers/targeted/brawn.dm deleted file mode 100644 index a27bf47362e..00000000000 --- a/tff_modular/modules/bloodsucker/powers/targeted/brawn.dm +++ /dev/null @@ -1,229 +0,0 @@ - -#define BRAWN_BREAKOUT_LEVEL 3 -#define BRAWN_AIRLOCK_LEVEL 4 -/datum/action/cooldown/bloodsucker/targeted/brawn - name = "Brawn" - desc = "Snap restraints, break lockers and doors at higher levels, or deal terrible damage with your bare hands." - button_icon_state = "power_strength" - purchase_flags = BLOODSUCKER_CAN_BUY|GHOUL_CAN_BUY - bloodcost = 10 - cooldown_time = 8 SECONDS - target_range = 1 - prefire_message = "Select a target." - -/datum/action/cooldown/bloodsucker/targeted/brawn/get_power_explanation_extended() - . = list() - . += "Click any person to bash into them, break restraints you have or knocking a grabber down. Only one of these can be done per use." - . += "Brawn will do [GetDamage()] brute damage to the target and knockdown them for [DisplayTimeText(GetKnockdown())]." - . += "Punching a Cyborg will heavily EMP them in addition to deal damage." - . += "At level [BRAWN_BREAKOUT_LEVEL], you get the ability to break closets open, additionally can both break restraints AND knock a grabber down in the same use." - . += "At level [BRAWN_AIRLOCK_LEVEL], you get the ability to bash airlocks open, as long as they aren't bolted." - . += "Higher levels will increase the damage and knockdown when punching someone." - -/datum/action/cooldown/bloodsucker/targeted/brawn/ActivatePower(atom/target) - // Did we break out of our handcuffs? - if(break_restraints()) - playsound(get_turf(owner), 'sound/effects/grillehit.ogg', 80, 1, -1) - PowerActivatedSuccesfully() - return FALSE - // Did we knock a grabber down? We can only do this while not also breaking restraints if strong enough. - if(owner.pulledby) - if(level_current >= BRAWN_BREAKOUT_LEVEL && escape_puller()) - PowerActivatedSuccesfully() - return FALSE - owner.balloon_alert(owner, "ability level too low to break free!") - // Did neither, now we can PUNCH. - if(HAS_TRAIT(owner, TRAIT_HANDS_BLOCKED)) - owner.balloon_alert(owner, "your hands are blocked!") - return FALSE - // check if we have atleast one arm - if(!owner.get_active_hand()) - owner.balloon_alert(owner, "you need a usable arm!") - return FALSE - return TRUE - -// Look at 'biodegrade.dm' for reference -/datum/action/cooldown/bloodsucker/targeted/brawn/proc/break_restraints() - var/mob/living/carbon/human/user = owner - ///Only one form of shackles removed per use - var/obj/handcuffed = user.get_item_by_slot(ITEM_SLOT_HANDCUFFED) - if(user.buckled && handcuffed && user.buckled.unbuckle_mob(user)) - user.visible_message( - span_warning("[user] breaks free of [user.buckled]!"), - span_warning("We break free of [user.buckled]!"), - ) - user.buckled = null - return TRUE - - // Breaks out of lockers - if(istype(user.loc, /obj/structure/closet)) - var/obj/structure/closet/closet = user.loc - if(!istype(closet)) - return FALSE - closet.visible_message( - span_warning("[closet] tears apart as [user] bashes it open from within!"), - span_warning("[closet] tears apart as you bash it open from within!"), - ) - to_chat(user, span_warning("We bash [closet] wide open!")) - addtimer(CALLBACK(src, PROC_REF(break_closet), user, closet), 1) - return TRUE - - // Remove both Handcuffs & Legcuffs in one step - var/legcuffed = user.get_item_by_slot(ITEM_SLOT_LEGCUFFED) - if(handcuffed || legcuffed) - var/hand_cuffs = user.clear_cuffs(handcuffed, TRUE) - var/leg_cuffs = user.clear_cuffs(legcuffed, TRUE) - if(hand_cuffs || leg_cuffs) - user.visible_message( - span_warning("[user] discards their restraints like it's nothing!"), - span_warning("We break through our restraints!"), - ) - return TRUE - - // Remove Straightjackets - if(user.wear_suit?.breakouttime) - var/obj/item/clothing/suit/straightjacket = user.get_item_by_slot(ITEM_SLOT_OCLOTHING) - user.visible_message( - span_warning("[user] rips straight through the [user.p_their()] [straightjacket]!"), - span_warning("We tear through our [straightjacket]!"), - ) - if(straightjacket && user.wear_suit == straightjacket) - qdel(straightjacket) - return TRUE - return FALSE - -// This is its own proc because its done twice, to repeat code copypaste. -/datum/action/cooldown/bloodsucker/targeted/brawn/proc/break_closet(mob/living/carbon/human/user, obj/structure/closet/closet) - if(closet) - closet.welded = FALSE - closet.locked = FALSE - closet.broken = TRUE - closet.open() - -/datum/action/cooldown/bloodsucker/targeted/brawn/proc/escape_puller() - var/mob/pulled_mob = owner.pulledby - var/pull_power = pulled_mob.grab_state - playsound(get_turf(pulled_mob), 'sound/effects/woodhit.ogg', 75, 1, -1) - // Knock Down (if Living) - if(isliving(pulled_mob)) - var/mob/living/hit_target = pulled_mob - hit_target.Knockdown(pull_power * 10 + 20) - // Knock Back (before Knockdown, which probably cancels pull) - var/send_dir = get_dir(owner, pulled_mob) - var/turf/turf_thrown_at = get_ranged_target_turf(pulled_mob, send_dir, pull_power) - owner.newtonian_move(send_dir) // Bounce back in 0 G - pulled_mob.throw_at(turf_thrown_at, pull_power, TRUE, owner, FALSE) // Throw distance based on grab state! Harder grabs punished more aggressively. - // /proc/log_combat(atom/user, atom/target, what_done, atom/object=null, addition=null) - log_combat(owner, pulled_mob, "used Brawn power") - owner.visible_message( - span_warning("[owner] tears free of [pulled_mob]'s grasp!"), - span_warning("You shrug off [pulled_mob]'s grasp!"), - ) - owner.pulledby = null // It's already done, but JUST IN CASE. - return TRUE - -/datum/action/cooldown/bloodsucker/targeted/brawn/FireTargetedPower(atom/target, params) - . = ..() - var/mob/living/user = owner - // Target Type: Mob - if(isliving(target)) - var/mob/living/target_atom = target - //You know what I'm just going to take the average of the user's limbs max damage instead of dealing with 2 hands - var/hitStrength = GetDamage() - // Knockdown! - var/powerlevel = GetPowerLevel() - if(rand(5 + powerlevel) >= 5) - target_atom.visible_message( - span_danger("[user] lands a vicious punch, sending [target_atom] away!"), \ - span_userdanger("[user] has landed a horrifying punch on you, sending you flying!"), - ) - target_atom.Knockdown(GetKnockdown()) - // Attack! - owner.balloon_alert(owner, "you punch [target_atom]!") - playsound(get_turf(target_atom), 'sound/items/weapons/punch4.ogg', 60, 1, -1) - user.do_attack_animation(target_atom, ATTACK_EFFECT_SMASH) - var/obj/item/bodypart/affecting = target_atom.get_bodypart(ran_zone(target_atom.zone_selected)) - target_atom.apply_damage(hitStrength, BRUTE, affecting) - // Knockback - var/send_dir = get_dir(owner, target_atom) - var/turf/turf_thrown_at = get_ranged_target_turf(target_atom, send_dir, powerlevel) - owner.newtonian_move(send_dir) // Bounce back in 0 G - target_atom.throw_at(turf_thrown_at, powerlevel, TRUE, owner) //new /datum/forced_movement(target_atom, get_ranged_target_turf(target_atom, send_dir, (hitStrength / 4)), 1, FALSE) - // Target Type: Cyborg (Also gets the effects above) - if(issilicon(target_atom)) - target_atom.emp_act(EMP_HEAVY) - // Target Type: Locker - else if(istype(target, /obj/structure/closet)) - if(level_current <= BRAWN_BREAKOUT_LEVEL) - target.balloon_alert(user, "ability level too low to break open!") - return FALSE - var/obj/structure/closet/target_closet = target - user.balloon_alert(user, "you prepare to bash [target_closet] open...") - if(!do_after(user, 2.5 SECONDS, target_closet)) - user.balloon_alert(user, "interrupted!") - return FALSE - target_closet.visible_message(span_danger("[target_closet] breaks open as [user] bashes it!")) - addtimer(CALLBACK(src, PROC_REF(break_closet), user, target_closet), 1) - playsound(get_turf(user), 'sound/effects/grillehit.ogg', 80, TRUE, -1) - // Target Type: Door - else if(istype(target, /obj/machinery/door)) - if(level_current <= BRAWN_AIRLOCK_LEVEL) - target.balloon_alert(user, "ability level too low to break open!") - return FALSE - var/obj/machinery/door/target_airlock = target - playsound(get_turf(user), 'sound/machines/airlock/airlock_alien_prying.ogg', 40, TRUE, -1) - owner.balloon_alert(owner, "you prepare to tear open [target_airlock]...") - if(!do_after(user, 2.5 SECONDS, target_airlock)) - user.balloon_alert(user, "interrupted!") - return FALSE - if(target_airlock.Adjacent(user)) - target_airlock.visible_message(span_danger("[target_airlock] breaks open as [user] bashes it!")) - user.Stun(10) - user.do_attack_animation(target_airlock, ATTACK_EFFECT_SMASH) - playsound(get_turf(target_airlock), 'sound/effects/bang.ogg', 30, 1, -1) - target_airlock.open(2) // open(2) is like a crowbar or jaws of life. - -/datum/action/cooldown/bloodsucker/targeted/brawn/proc/GetPowerLevel() - return min(5, 1 + level_current) - -/datum/action/cooldown/bloodsucker/targeted/brawn/proc/GetKnockdown() - return min(5, rand(10, 10 * GetPowerLevel())) - -/datum/action/cooldown/bloodsucker/targeted/brawn/proc/GetDamage() - var/mob/living/carbon/human/user = owner - var/obj/item/bodypart/user_active_arm - user_active_arm = user.get_active_hand() - if(!user || !user_active_arm) - return GetPunchDamage(initial(user_active_arm.unarmed_damage_high)) - return GetPunchDamage(user_active_arm.unarmed_damage_high) - -/datum/action/cooldown/bloodsucker/targeted/brawn/proc/GetPunchDamage(punch_damage) - return punch_damage * 2 + 5 - -/datum/action/cooldown/bloodsucker/targeted/brawn/CheckValidTarget(atom/target_atom) - . = ..() - if(!.) - return FALSE - return isliving(target_atom) || istype(target_atom, /obj/machinery/door) || istype(target_atom, /obj/structure/closet) - -/datum/action/cooldown/bloodsucker/targeted/brawn/CheckCanTarget(atom/target_atom) - // DEFAULT CHECKS (Distance) - . = ..() - if(!.) // Disable range notice for Brawn. - return FALSE - // Must outside Closet to target anyone! - if(!isturf(owner.loc)) - return FALSE - // Target Type: Living - if(isliving(target_atom)) - return TRUE - // Target Type: Door - else if(istype(target_atom, /obj/machinery/door)) - return TRUE - // Target Type: Locker - else if(istype(target_atom, /obj/structure/closet)) - return TRUE - return FALSE - -#undef BRAWN_BREAKOUT_LEVEL -#undef BRAWN_AIRLOCK_LEVEL diff --git a/tff_modular/modules/bloodsucker/powers/targeted/haste.dm b/tff_modular/modules/bloodsucker/powers/targeted/haste.dm deleted file mode 100644 index 94b841ed27c..00000000000 --- a/tff_modular/modules/bloodsucker/powers/targeted/haste.dm +++ /dev/null @@ -1,120 +0,0 @@ -/* Level 1: Speed to location - * Level 2: Dodge Bullets - * Level 3: Stun People Passed - */ - -#define HASTE_GETUP_LEVEL 3 -/datum/action/cooldown/bloodsucker/targeted/haste - name = "Immortal Haste" - desc = "Force yourself to stand up if you're down and dash somewhere with supernatural speed. Those nearby may be knocked away, stunned, or left empty-handed." - button_icon_state = "power_speed" - prefire_message = "You prepare to dash!" - purchase_flags = BLOODSUCKER_CAN_BUY|GHOUL_CAN_BUY - bloodcost = 6 - cooldown_time = 8 SECONDS - target_range = 5 - power_activates_immediately = FALSE - ///List of all people hit by our power, so we don't hit them again. - var/list/hit = list() - -/datum/action/cooldown/bloodsucker/targeted/haste/get_power_desc_extended() - . = "Dash to a location, knocking down anyone in your way, and refilling your stamina. Those nearby may be knocked away, stunned, or left empty-handed.\n" - if(level_current >= HASTE_GETUP_LEVEL) - . += "Dashing from lying down will get you up, but won't affect your foes." - else - . += "You cannot dash while knocked down." - -/datum/action/cooldown/bloodsucker/targeted/haste/get_power_explanation_extended() - . = list() - . += "Click anywhere to immediately dash towards that location." - . += "At level [HASTE_GETUP_LEVEL], if you are lying down, you will get up and regain your stamina, but the resulting dash will not knock down those nearby." - . += "Haste will knockdown your enemies for [DisplayTimeText(GetKnockdown())] and refill your stamina, but using haste while knocked down will make it go on cooldown for [DisplayTimeText(cooldown_time * 3)]" - . += "The Power will not work if you are lying down, in no gravity, or are aggressively grabbed." - . += "Anyone in your way during your Haste will be knocked down." - . += "Higher levels will increase the knockdown dealt to enemies." - . += "It will also refill your stamina so you can keep moving." - . += "If Fortitude is active, using haste will disable it." - -/datum/action/cooldown/bloodsucker/targeted/haste/can_use(mob/living/carbon/user, trigger_flags) - . = ..() - if(!.) - return FALSE - // Being Grabbed - if(user.pulledby && user.pulledby.grab_state >= GRAB_AGGRESSIVE) - user.balloon_alert(user, "you're being grabbed!") - return FALSE - if(!user.has_gravity(user.loc)) //We dont want people to be able to use this to fly around in space - user.balloon_alert(user, "you cannot dash while floating!") - return FALSE - if(level_current < HASTE_GETUP_LEVEL && user.body_position == LYING_DOWN) - user.balloon_alert(user, "you must be standing to dash!") - return FALSE - return TRUE - -/// Anything will do, if it's not mea or my square -/datum/action/cooldown/bloodsucker/targeted/haste/CheckValidTarget(atom/target_atom) - . = ..() - if(!.) - return FALSE - return target_atom.loc != owner.loc - -/// This is a non-async proc to make sure the power is "locked" until this finishes. -/datum/action/cooldown/bloodsucker/targeted/haste/FireTargetedPower(atom/target, params) - . = ..() - var/mob/living/user = owner - var/stuns_mobs = TRUE - var/temp_cooldown = cooldown_time - if(level_current >= HASTE_GETUP_LEVEL && user.body_position == LYING_DOWN) - to_chat(user, span_danger("Your heart takes a beat, and you force yourself to stand up!")) - user.SetKnockdown(0) - user.set_stamina_loss(0) - user.set_resting(FALSE, FALSE, TRUE) - stuns_mobs = FALSE - temp_cooldown = GetGetupCooldown() - if(stuns_mobs) - RegisterSignal(owner, COMSIG_MOVABLE_MOVED, PROC_REF(on_move)) - var/turf/targeted_turf = isturf(target) ? target : get_turf(target) - // Pulled? Not anymore. - user.pulledby?.stop_pulling() - // Go to target turf - // DO NOT USE WALK TO. - owner.balloon_alert(owner, "you dash into the air!") - playsound(get_turf(owner), 'sound/items/weapons/punchmiss.ogg', 25, 1, -1) - var/safety = get_dist(user, targeted_turf) * 3 + 1 - var/consequetive_failures = 0 - active = TRUE - while(--safety && (get_turf(user) != targeted_turf)) - var/success = step_towards(user, targeted_turf) //This does not try to go around obstacles. - if(!success) - success = step_to(user, targeted_turf) //this does - if(!success) - consequetive_failures++ - if(consequetive_failures >= 3) //if 3 steps don't work - break //just stop - else - consequetive_failures = 0 //reset so we can keep moving - if(user.resting || INCAPACITATED_IGNORING(user, INCAPABLE_GRAB|INCAPABLE_RESTRAINTS)) //actually down? stop. - break - if(success) //don't sleep if we failed to move. - sleep(world.tick_lag) - UnregisterSignal(owner, COMSIG_MOVABLE_MOVED) - hit.Cut() - user.adjust_stamina_loss(-user.staminaloss) - PowerActivatedSuccesfully(temp_cooldown) - -/datum/action/cooldown/bloodsucker/targeted/haste/proc/GetKnockdown() - return 10 + level_current * 4 - -/datum/action/cooldown/bloodsucker/targeted/haste/proc/GetGetupCooldown() - return cooldown_time * 3 - -/datum/action/cooldown/bloodsucker/targeted/haste/proc/on_move() - for(var/mob/living/hit_living in dview(1, get_turf(owner)) - owner) - if(hit.Find(hit_living)) - continue - hit += hit_living - playsound(hit_living, "sound/weapons/punch[rand(1,4)].ogg", 15, 1, -1) - hit_living.Knockdown(GetKnockdown()) - hit_living.spin(10, 1) - -#undef HASTE_GETUP_LEVEL diff --git a/tff_modular/modules/bloodsucker/powers/targeted/lunge.dm b/tff_modular/modules/bloodsucker/powers/targeted/lunge.dm deleted file mode 100644 index 18985b1ec79..00000000000 --- a/tff_modular/modules/bloodsucker/powers/targeted/lunge.dm +++ /dev/null @@ -1,191 +0,0 @@ - -#define LUNGE_INSTANT_LEVEL 4 -#define LUNGE_INSTANT_RANGE 6 -/datum/action/cooldown/bloodsucker/targeted/lunge - name = "Predatory Lunge" - desc = "Spring at your target to grapple them without warning, or tear the dead's heart out. Attacks from concealment or the rear may even knock them down if strong enough." - button_icon_state = "power_lunge" - check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_INCAPACITATED|AB_CHECK_LYING|AB_CHECK_PHASED|AB_CHECK_LYING - purchase_flags = BLOODSUCKER_CAN_BUY|GHOUL_CAN_BUY - bloodcost = 10 - cooldown_time = 9 SECONDS - power_activates_immediately = FALSE - unset_after_click = FALSE - -/datum/action/cooldown/bloodsucker/targeted/lunge/get_power_explanation_extended() - . = list() - . += "Click any player to start spinning wildly and, after a short delay, dash at them." - . += "When lunging at someone, you will grab them, immediately starting off at aggressive." - . += "Riot gear and Monster Hunters are protected and will only be passively grabbed." - . += "You cannot use the Power if you are already grabbing someone, or are being grabbed." - . += "If you grab from behind, or while using cloak of darkness, you will knock the target down." - . += "If used on a dead body, will tear out a random organ from the zone you are targeting." - . += "Higher levels increase how long enemies are knocked down." - . += "At level [LUNGE_INSTANT_LEVEL], you will no longer spin, but you will be limited to tackling from only [LUNGE_INSTANT_RANGE] tiles away." - -/datum/action/cooldown/bloodsucker/targeted/lunge/on_power_upgrade() - . = ..() - //range is lowered when you get stronger, since it's instant now. - if(level_current > LUNGE_INSTANT_LEVEL) - target_range = LUNGE_INSTANT_RANGE - -/datum/action/cooldown/bloodsucker/targeted/lunge/can_use(mob/living/carbon/user, trigger_flags) - . = ..() - if(!.) - return FALSE - // Are we being grabbed? - if(user.pulledby && user.pulledby.grab_state >= GRAB_AGGRESSIVE) - owner.balloon_alert(user, "grabbed!") - return FALSE - if(user.pulling) - owner.balloon_alert(user, "grabbing someone!") - return FALSE - return TRUE - -/// Check: Are we lunging at a person? -/datum/action/cooldown/bloodsucker/targeted/lunge/CheckValidTarget(atom/target_atom) - . = ..() - if(!.) - return FALSE - return isliving(target_atom) - -/datum/action/cooldown/bloodsucker/targeted/lunge/CheckCanTarget(atom/target_atom) - // Default Checks - . = ..() - if(!.) - return FALSE - // Check: Turf - var/mob/living/turf_target = target_atom - if(!isturf(turf_target.loc)) - return FALSE - return TRUE - -/datum/action/cooldown/bloodsucker/targeted/lunge/can_deactivate() - return !(datum_flags & DF_ISPROCESSING) //only if you aren't lunging - -/datum/action/cooldown/bloodsucker/targeted/lunge/FireTargetedPower(atom/target, params) - . = ..() - owner.face_atom(target) - if(level_current >= LUNGE_INSTANT_LEVEL) - do_lunge(target) - return - - prepare_target_lunge(target) - return TRUE - -///Starts processing the power and prepares the lunge by spinning, calls lunge at the end of it. -/datum/action/cooldown/bloodsucker/targeted/lunge/proc/prepare_target_lunge(atom/target_atom) - START_PROCESSING(SSprocessing, src) - owner.balloon_alert(owner, "lunge started!") - //animate them shake - var/base_x = owner.base_pixel_x - var/base_y = owner.base_pixel_y - animate(owner, pixel_x = base_x, pixel_y = base_y, time = 1, loop = -1) - for(var/i in 1 to 25) - var/x_offset = base_x + rand(-3, 3) - var/y_offset = base_y + rand(-3, 3) - animate(pixel_x = x_offset, pixel_y = y_offset, time = 1) - - if(!do_after(owner, 2 SECONDS, timed_action_flags = (IGNORE_USER_LOC_CHANGE|IGNORE_TARGET_LOC_CHANGE|IGNORE_SLOWDOWNS), extra_checks = CALLBACK(src, PROC_REF(CheckCanTarget), target_atom))) - end_target_lunge(base_x, base_y) - - return FALSE - - end_target_lunge() - do_lunge(target_atom) - return TRUE - -///When preparing to lunge ends, this clears it up. -/datum/action/cooldown/bloodsucker/targeted/lunge/proc/end_target_lunge(base_x, base_y) - animate(owner, pixel_x = base_x, pixel_y = base_y, time = 1) - STOP_PROCESSING(SSprocessing, src) - -/datum/action/cooldown/bloodsucker/targeted/lunge/process() - if(!active) //If running SSfasprocess (on cooldown) - return ..() //Manage our cooldown timers - if(prob(75)) - owner.spin(8, 1) - owner.balloon_alert_to_viewers("spins wildly!", "you spin!") - return - do_smoke(0, owner.loc, smoke_type = /obj/effect/particle_effect/fluid/smoke/transparent) - -///Actually lunges the target, then calls lunge end. -/datum/action/cooldown/bloodsucker/targeted/lunge/proc/do_lunge(atom/hit_atom) - var/turf/targeted_turf = get_turf(hit_atom) - - var/safety = get_dist(owner, targeted_turf) * 3 + 1 - var/consequetive_failures = 0 - while(--safety && !hit_atom.Adjacent(owner)) - if(!step_to(owner, targeted_turf)) - consequetive_failures++ - if(consequetive_failures >= 3) // If 3 steps don't work, just stop. - break - - lunge_end(hit_atom, targeted_turf) - -/datum/action/cooldown/bloodsucker/targeted/lunge/proc/lunge_end(atom/hit_atom, turf/target_turf) - PowerActivatedSuccesfully() - // Am I next to my target to start giving the effects? - if(!owner.Adjacent(hit_atom)) - return - - var/mob/living/user = owner - var/mob/living/carbon/target = hit_atom - - // Did I slip or get knocked unconscious? - if(user.body_position != STANDING_UP || user.incapacitated) - user.throw_at(target_turf, 12, 0.8) - user.spin(10) - return - // Is my target a Monster hunter? - if(HAS_TRAIT(target, TRAIT_BRAWLING_KNOCKDOWN_BLOCKED)) - user.balloon_alert(user, "pushed away!") - target.grabbedby(user) - return - - user.balloon_alert(user, "you lunge at [target]!") - user.changeNext_move(CLICK_CD_MELEE) - if(target.stat == DEAD) - var/obj/item/bodypart/bodypart = target.get_bodypart(check_zone(user.zone_selected)) - if(!bodypart) - target.balloon_alert(user, "bodypart missing!") - return - var/datum/wound/slash/flesh/moderate/crit_wound = new - crit_wound.sound_effect = null - crit_wound.apply_wound(bodypart) - user.visible_message( - span_warning("[user] tears into [target]'s [bodypart]!"), - span_warning("You tear into [target]'s [bodypart]!")) - playsound(target, 'sound/effects/wounds/crackandbleed.ogg', 100, TRUE, 5) - var/obj/item/organ/myheart_now - if(bodypart.body_zone == BODY_ZONE_CHEST) - myheart_now = target.get_organ_slot(ORGAN_SLOT_HEART) - if(!myheart_now) - var/list/organs = target.get_organs_for_zone(bodypart.body_zone) - if(!length(organs)) - to_chat(user, span_warning("[target] has no organs in [bodypart]!")) - target.balloon_alert(user, "no organs!") - return - myheart_now = pick(organs) - - if(myheart_now) - myheart_now.Remove(target) - user.put_in_hands(myheart_now) - - else - if(!is_source_facing_target(target, user) || user.alpha <= 40) - target.Knockdown(10 + level_current * 5) - target.Paralyze(0.1) - target.grabbedby(user) - target.grippedby(user, instant = TRUE) - // Did we knock them down? - - -/datum/action/cooldown/bloodsucker/targeted/lunge/DeactivatePower(deactivate_flags) - . = ..() - if(!.) - return - REMOVE_TRAIT(owner, TRAIT_IMMOBILIZED, BLOODSUCKER_TRAIT) - -#undef LUNGE_INSTANT_LEVEL -#undef LUNGE_INSTANT_RANGE diff --git a/tff_modular/modules/bloodsucker/powers/targeted/mesmerize.dm b/tff_modular/modules/bloodsucker/powers/targeted/mesmerize.dm deleted file mode 100644 index b1f3c976729..00000000000 --- a/tff_modular/modules/bloodsucker/powers/targeted/mesmerize.dm +++ /dev/null @@ -1,243 +0,0 @@ -/** - * MEZMERIZE - * Locks a target in place for a certain amount of time. - * - * Level 2: Additionally mutes - * Level 3: Can be used through face protection - * Level 5: Doesn't need to be facing you anymore - */ - -#define MESMERIZE_MUTE_LEVEL 2 -#define MESMERIZE_GLASSES_LEVEL 3 -#define MESMERIZE_FACING_LEVEL 5 -/datum/action/cooldown/bloodsucker/targeted/mesmerize - name = "Mesmerize" - button_icon_state = "power_mez" - power_flags = NONE - purchase_flags = BLOODSUCKER_CAN_BUY|GHOUL_CAN_BUY - bloodcost = 30 - cooldown_time = 15 SECONDS - target_range = 4 - power_activates_immediately = FALSE - unset_after_click = FALSE - prefire_message = "Whom will you subvert to your will?" - ///Our mesmerized target - Prevents several mesmerizes. - var/datum/weakref/target_ref - /// How long it takes us to mesmerize our target. - var/mesmerize_delay = 5 SECONDS - /// At what level this ability will blind the target at. Level 0 = never. - var/blind_at_level = 0 - /// if the ability requires you to be physically facing the target - var/requires_facing_target = FALSE - /// if the ability requires you to not have your eyes covered - var/blocked_by_glasses = TRUE - /// if the ability will knockdown on secondary click - var/knockdown_on_secondary = FALSE - // string id timer of the current cast, used for combat glare - var/timer - // a cooldown to ensure you can't spam both the primary and secondary mesmerizes - COOLDOWN_DECLARE(mesmerize_cooldown) - -/datum/action/cooldown/bloodsucker/targeted/mesmerize/get_power_desc_extended() - . += "[src] a target, locking them in place for a short time[level_current >= MESMERIZE_MUTE_LEVEL ? " and muting them" : ""].
    " - if(knockdown_on_secondary) - . += "Right clicking on your victim will apply a knockdown for [DisplayTimeText(combat_mesmerize_time())].
    " - else - . += "Right clicking on your victim will confuse them for [DisplayTimeText(combat_mesmerize_time())]." - -/datum/action/cooldown/bloodsucker/targeted/mesmerize/get_power_explanation_extended() - . = list() - . += "Click any player to attempt to mesmerize them. This will stun the victim." - . += "The victim will realize they are being mesmerized, but will be unable to talk, but at level [MESMERIZE_MUTE_LEVEL] they will be also muted." - if(blocked_by_glasses && requires_facing_target) - . += "[src] requires you to not be wearing glasses and to be facing your target." - else if(blocked_by_glasses) - . += "[src] requires you to not be wearing glasses." - else if(requires_facing_target) - . += "[src] requires you to be facing your target." - . += "You cannot wear anything covering your face, and both parties must be facing eachother." - . += "Obviously, both parties need to not be blind." - . += "Right clicking with the ability will apply a knockdown for [DisplayTimeText(combat_mesmerize_time())], but will also confuse your victim for [DisplayTimeText(get_power_time())]." - . += "If your target is already mesmerized or a bloodsucker, the Power will fail." - . += "Once mesmerized, the target will be unable to move for [DisplayTimeText(get_power_time())] and muted for [DisplayTimeText(get_mute_time())], scaling with level." - . += "At level [MESMERIZE_GLASSES_LEVEL], you will be able to use the power through items covering your face." - . += "At level [MESMERIZE_FACING_LEVEL], you will be able to mesmerize regardless of your target's direction." - . += "Additionally it works on silicon lifeforms, causing a EMP effect instead of a freeze." - -/datum/action/cooldown/bloodsucker/targeted/mesmerize/can_use(mob/living/carbon/user, trigger_flags) - . = ..() - if(!.) // Default checks - return FALSE - if(!user.get_organ_slot(ORGAN_SLOT_EYES)) - // Cant use balloon alert, they've got no eyes! - to_chat(user, span_warning("You have no eyes with which to mesmerize.")) - return FALSE - // Check: Eyes covered? - if(blocked_by_glasses && istype(user) && (user.is_eyes_covered() && level_current <= 2) || !isturf(user.loc)) - user.balloon_alert(user, "your eyes are concealed from sight.") - return FALSE - return TRUE - -/datum/action/cooldown/bloodsucker/targeted/mesmerize/CheckValidTarget(atom/target_atom) - . = ..() - if(!.) - return FALSE - return isliving(target_atom) - -/datum/action/cooldown/bloodsucker/targeted/mesmerize/CheckCanTarget(atom/target_atom) - . = ..() - if(!.) - return FALSE - var/mob/living/current_target = target_atom // We already know it's carbon due to CheckValidTarget() - // No mind -#ifndef BLOODSUCKER_TESTING - if(!current_target.mind) - owner.balloon_alert(owner, "[current_target] is mindless.") - return FALSE -#endif - // Bloodsucker - if(IS_BLOODSUCKER(current_target)) - owner.balloon_alert(owner, "bloodsuckers are immune to [src].") - return FALSE - // Dead/Unconscious - if(current_target.stat > CONSCIOUS) - owner.balloon_alert(owner, "[current_target] is not [(current_target.stat == DEAD || HAS_TRAIT(current_target, TRAIT_FAKEDEATH)) ? "alive" : "conscious"].") - return FALSE - // Target has eyes? - if(!current_target.get_organ_slot(ORGAN_SLOT_EYES) && !issilicon(current_target)) - owner.balloon_alert(owner, "[current_target] has no eyes.") - return FALSE - // Target blind? - if(current_target.is_blind() && !issilicon(current_target)) - owner.balloon_alert(owner, "[current_target] is blind.") - return FALSE - // Facing target? - if(requires_facing_target && !is_source_facing_target(owner, current_target)) // in unsorted.dm - owner.balloon_alert(owner, "you must be facing [current_target].") - return FALSE - // Target facing me? (On the floor, they're facing everyone) - if(((current_target.mobility_flags & MOBILITY_STAND) && requires_facing_target && !is_source_facing_target(current_target, owner) && level_current <= MESMERIZE_FACING_LEVEL)) - owner.balloon_alert(owner, "[current_target] must be facing you.") - return FALSE - - // Gone through our checks, let's mark our guy. - target_ref = WEAKREF(current_target) - return TRUE - -/datum/action/cooldown/bloodsucker/targeted/mesmerize/FireTargetedPower(atom/target, params) - var/mob/living/user = owner - var/mob/living/carbon/mesmerized_target = target_ref?.resolve() - if(!COOLDOWN_FINISHED(src, mesmerize_cooldown)) - return - if(!mesmerized_target) - CRASH("mesmerized_target is null") - - perform_indicators(mesmerized_target, mesmerize_delay) - - if(issilicon(mesmerized_target)) - var/mob/living/silicon/mesmerized = mesmerized_target - mesmerized.emp_act(EMP_HEAVY) - owner.balloon_alert(owner, "temporarily shut [mesmerized] down.") - PowerActivatedSuccesfully() // PAY COST! BEGIN COOLDOWN! - return - // slow them down during the mesmerize - mute_target(mesmerized_target) - - COOLDOWN_START(src, mesmerize_cooldown, mesmerize_delay) - if(!do_after(user, mesmerize_delay, mesmerized_target, IGNORE_USER_LOC_CHANGE | IGNORE_TARGET_LOC_CHANGE, TRUE, extra_checks = CALLBACK(src, PROC_REF(ContinueActive), user, mesmerized_target))) - StartCooldown(cooldown_time * 0.5) - return - // Can't quite time it here, but oh well - to_chat(mesmerized_target, "[user]'s eyes look into yours, and [span_hypnophrase("you feel your mind slipping away")]...") - /*if(IS_MONSTERHUNTER(mesmerized_target)) - to_chat(mesmerized_target, span_notice("You feel your eyes burn for a while, but it passes.")) - return*/ - if(HAS_TRAIT_FROM_ONLY(mesmerized_target, TRAIT_NO_TRANSFORM, MESMERIZE_TRAIT)) - owner.balloon_alert(owner, "[mesmerized_target] is already in a hypnotic gaze.") - return - owner.balloon_alert(owner, "successfully mesmerized [mesmerized_target].") - mesmerize_effects(user, mesmerized_target) - PowerActivatedSuccesfully() // PAY COST! BEGIN COOLDOWN! - -/datum/action/cooldown/bloodsucker/targeted/mesmerize/FireSecondaryTargetedPower(atom/target, params) - if(!isliving(target)) - CRASH("[src] somehow casted on a non-living target, should have been stopped by CheckCanTarget.") - if(timer || !COOLDOWN_FINISHED(src, mesmerize_cooldown)) - return - COOLDOWN_START(src, mesmerize_cooldown, 2 SECONDS) - var/mob/living/mesmerized_target = target - owner.balloon_alert(owner, "gazing [mesmerized_target]...") - perform_indicators(mesmerized_target, 3 SECONDS) - timer = addtimer(CALLBACK(src, PROC_REF(combat_mesmerize_effects), owner, mesmerized_target), 2 SECONDS) - -/datum/action/cooldown/bloodsucker/targeted/mesmerize/proc/mesmerize_effects(mob/living/user, mob/living/mesmerized_target) - var/power_time = get_power_time() - mute_target(mesmerized_target) - mesmerized_target.Immobilize(power_time) - mesmerized_target.next_move = world.time + power_time // <--- Use direct change instead. We want an unmodified delay to their next move // mesmerized_target.changeNext_move(power_time) // check click.dm - ADD_TRAIT(mesmerized_target, TRAIT_NO_TRANSFORM, MESMERIZE_TRAIT) // <--- Fuck it. We tried using next_move, but they could STILL resist. We're just doing a hard freeze. - addtimer(CALLBACK(src, PROC_REF(end_mesmerize), user, mesmerized_target), power_time) - -/datum/action/cooldown/bloodsucker/targeted/mesmerize/proc/combat_mesmerize_effects(mob/living/user, mob/living/mesmerized_target) - if(!ContinueActive(user, mesmerized_target)) - StartCooldown(cooldown_time * 0.5) - owner.balloon_alert(owner, "failed!") - return - to_chat(mesmerized_target, "[src]'s eyes look into yours, and [span_hypnophrase("your head becomes fuzzy for a moment")]...") - var/effect_time = combat_mesmerize_time() - mute_target(mesmerized_target) - if(knockdown_on_secondary) - mesmerized_target.Knockdown(effect_time) - else - mesmerized_target.adjust_confusion(effect_time) - PowerActivatedSuccesfully(cost_override = bloodcost * 0.5) - -/datum/action/cooldown/bloodsucker/targeted/mesmerize/proc/get_power_time() - return 9 SECONDS + level_current * 1 SECONDS - -/datum/action/cooldown/bloodsucker/targeted/mesmerize/proc/get_mute_time() - return get_power_time() - -/datum/action/cooldown/bloodsucker/targeted/mesmerize/proc/combat_mesmerize_time() - return get_power_time() * 0.3 - -/datum/action/cooldown/bloodsucker/targeted/mesmerize/proc/blind_target(mob/living/mesmerized_target) - if(!blind_at_level && level_current < blind_at_level) - return - mesmerized_target.become_blind(MESMERIZE_TRAIT) - -/datum/action/cooldown/bloodsucker/targeted/mesmerize/proc/mute_target(mob/living/mesmerized_target) - if(level_current >= MESMERIZE_MUTE_LEVEL) - mesmerized_target.set_silence_if_lower(get_mute_time()) - -/datum/action/cooldown/bloodsucker/targeted/mesmerize/DeactivatePower(deactivate_flags) - . = ..() - target_ref = null - timer = null - -/datum/action/cooldown/bloodsucker/targeted/mesmerize/proc/end_mesmerize(mob/living/user, mob/living/target) - REMOVE_TRAIT(target, TRAIT_NO_TRANSFORM, MESMERIZE_TRAIT) - target.cure_blind(MESMERIZE_TRAIT) - // They Woke Up! (Notice if within view) - if(istype(user) && target.stat == CONSCIOUS && (target in view(target_range, get_turf(user)))) - target.balloon_alert(owner, "[target] snapped out of their trance.") - -/datum/action/cooldown/bloodsucker/targeted/mesmerize/ContinueActive(mob/living/user, mob/living/target) - return ..() && can_use(user) && CheckCanTarget(target) - -/datum/action/cooldown/bloodsucker/targeted/mesmerize/proc/perform_indicators(mob/target, duration) - // Display an animated overlay over our head to indicate what's going on - eldritch_eye(target, "eye_open", 1 SECONDS) - var/main_duration = max(duration - 2 SECONDS, 1 SECONDS) - addtimer(CALLBACK(src, PROC_REF(eldritch_eye), target, "eye_flash", main_duration), 1 SECONDS) - addtimer(CALLBACK(src, PROC_REF(eldritch_eye), target, "eye_close", 1 SECONDS), main_duration + 1 SECONDS) - -/// Display an animated overlay over our head to indicate what's going on -/datum/action/cooldown/bloodsucker/targeted/mesmerize/proc/eldritch_eye(mob/target, icon_state = "eye_open", duration = 1 SECONDS) - var/image/image = image('icons/effects/eldritch.dmi', owner, icon_state, ABOVE_ALL_MOB_LAYER, pixel_x = -owner.pixel_x, pixel_y = 28) /// TODO make this disable cloak - SET_PLANE_EXPLICIT(image, ABOVE_LIGHTING_PLANE, owner) - flick_overlay_global(image, list(owner?.client, target?.client), duration) - -#undef MESMERIZE_GLASSES_LEVEL -#undef MESMERIZE_FACING_LEVEL -#undef MESMERIZE_MUTE_LEVEL diff --git a/tff_modular/modules/bloodsucker/powers/targeted/trespass.dm b/tff_modular/modules/bloodsucker/powers/targeted/trespass.dm deleted file mode 100644 index 22f423b1cb5..00000000000 --- a/tff_modular/modules/bloodsucker/powers/targeted/trespass.dm +++ /dev/null @@ -1,109 +0,0 @@ -/datum/action/cooldown/bloodsucker/targeted/trespass - name = "Trespass" - desc = "Become mist and advance two tiles in one direction. Useful for skipping past doors and barricades." - button_icon_state = "power_tres" - bloodsucker_check_flags = BP_CANT_USE_IN_TORPOR - purchase_flags = BLOODSUCKER_CAN_BUY|GHOUL_CAN_BUY - bloodcost = 10 - cooldown_time = 8 SECONDS - prefire_message = "Select a destination." - target_range = 2 - var/turf/target_turf // We need to decide where we're going based on where we clicked. It's not actually the tile we clicked. - -/datum/action/cooldown/bloodsucker/targeted/trespass/get_power_explanation_extended() - . = list() - . += "Click anywhere [target_range] tiles away from you to teleport." - . += "This power goes through all obstacles except Walls." - . += "Higher levels decrease the sound played from using the Power, and increase the speed of the transition." - . += "It takes [DisplayTimeText(GetTeleportDelay())] to teleport." - -/datum/action/cooldown/bloodsucker/targeted/trespass/can_use(mob/living/carbon/user, trigger_flags) - . = ..() - if(!.) - return FALSE - if(HAS_TRAIT(user, TRAIT_NO_TRANSFORM) || !get_turf(user)) - return FALSE - return TRUE - -/datum/action/cooldown/bloodsucker/targeted/trespass/CheckValidTarget(atom/target_atom) - . = ..() - if(!.) - return FALSE - // Can't target my tile - if(target_atom == get_turf(owner) || get_turf(target_atom) == get_turf(owner)) - return FALSE - return TRUE // All we care about is destination. Anything you click is fine. - -/datum/action/cooldown/bloodsucker/targeted/trespass/CheckCanTarget(atom/target_atom) - // NOTE: Do NOT use ..()! We don't want to check distance or anything. - - // Get clicked tile - var/final_turf = isturf(target_atom) ? target_atom : get_turf(target_atom) - - // Are either tiles WALLS? - var/turf/from_turf = get_turf(owner) - var/this_dir // = get_dir(from_turf, target_turf) - for(var/i = 1 to 2) - // Keep Prev Direction if we've reached final turf - if(from_turf != final_turf) - this_dir = get_dir(from_turf, final_turf) // Recalculate dir so we don't overshoot on a diagonal. - from_turf = get_step(from_turf, this_dir) - // ERROR! Wall! - if(iswallturf(from_turf)) - var/wallwarning = (i == 1) ? "in the way" : "at your destination" - owner.balloon_alert(owner, "there is a wall [wallwarning].") - return FALSE - // Done - target_turf = from_turf - - return TRUE - -/datum/action/cooldown/bloodsucker/targeted/trespass/FireTargetedPower(atom/target, params) - . = ..() - - // Find target turf, at or below Atom - var/mob/living/carbon/user = owner - var/turf/my_turf = get_turf(owner) - - user.visible_message( - span_warning("[user]'s form dissipates into a cloud of mist!"), - span_notice("You disspiate into formless mist."), - ) - // Effect Origin - var/sound_strength = max(60, 70 - level_current * 10) - playsound(get_turf(owner), 'sound/effects/magic/summon_karp.ogg', sound_strength, 1) - var/datum/effect_system/steam_spread/bloodsucker/puff = new /datum/effect_system/steam_spread() - puff.set_up(3, 0, my_turf) - puff.start() - - var/mist_delay = GetTeleportDelay() // Level up and do this faster. - - // Freeze Me - user.Stun(mist_delay, ignore_canstun = TRUE) - user.density = FALSE - var/invis_was = user.invisibility - user.invisibility = INVISIBILITY_MAXIMUM - - // Wait... - sleep(mist_delay / 2) - // Move & Freeze - if(isturf(target_turf)) - do_teleport(owner, target_turf, no_effects=TRUE, channel = TELEPORT_CHANNEL_QUANTUM) // in teleport.dm? - user.Stun(mist_delay / 2, ignore_canstun = TRUE) - - // Wait... - sleep(mist_delay / 2) - // Un-Hide & Freeze - user.dir = get_dir(my_turf, target_turf) - user.Stun(mist_delay / 2, ignore_canstun = TRUE) - user.density = 1 - user.invisibility = invis_was - // Effect Destination - playsound(get_turf(owner), 'sound/effects/magic/summon_karp.ogg', 60, 1) - puff = new /datum/effect_system/steam_spread/() - puff.effect_type = /obj/effect/particle_effect/fluid/smoke/vampsmoke - puff.set_up(3, 0, target_turf) - puff.start() - -/datum/action/cooldown/bloodsucker/targeted/trespass/proc/GetTeleportDelay() - return max(5, 20 - level_current * 2.5) diff --git a/tff_modular/modules/bloodsucker/powers/tremere/_powers_tremere.dm b/tff_modular/modules/bloodsucker/powers/tremere/_powers_tremere.dm deleted file mode 100644 index 60b8fe125cb..00000000000 --- a/tff_modular/modules/bloodsucker/powers/tremere/_powers_tremere.dm +++ /dev/null @@ -1,22 +0,0 @@ -/** - * # Tremere Powers - * - * This file is for Tremere power procs and Bloodsucker procs that deals exclusively with Tremere. - * Tremere has quite a bit of unique things to it, so I thought it's own subtype would be nice - */ - -/datum/action/cooldown/bloodsucker/targeted/tremere - name = "Tremere Gift" - desc = "" - power_explanation = "" - active_background_icon_state = "tremere_power_on" - base_background_icon_state = "tremere_power_off" - button_icon = 'tff_modular/modules/bloodsucker/icons/tremere_bloodsucker.dmi' - background_icon = 'tff_modular/modules/bloodsucker/icons/tremere_bloodsucker.dmi' - - level_current = 0 - // Re-defining these as we want total control over them - power_flags = BP_AM_STATIC_COOLDOWN - // Targeted stuff - unset_after_click = FALSE - diff --git a/tff_modular/modules/bloodsucker/powers/tremere/auspex.dm b/tff_modular/modules/bloodsucker/powers/tremere/auspex.dm deleted file mode 100644 index 90f801aa006..00000000000 --- a/tff_modular/modules/bloodsucker/powers/tremere/auspex.dm +++ /dev/null @@ -1,122 +0,0 @@ -/** - * # Auspex - * - * Level 1 - Cloak of Darkness until clicking an area, teleports the user to the selected area (max 2 tile) - * Level 2 - Cloak of Darkness until clicking an area, teleports the user to the selected area (max 3 tiles) - * Level 3 - Cloak of Darkness until clicking an area, teleports the user to the selected area - * Level 4 - Cloak of Darkness until clicking an area, teleports the user to the selected area, causes nearby people to bleed. - * Level 5 - Cloak of Darkness until clicking an area, teleports the user to the selected area, causes nearby people to fall asleep. - */ - -#define AUSPEX_BLOOD_COST_PER_TILE 5 -#define AUSPEX_BLEED_LEVEL 4 -#define AUSPEX_KNOCKDOWN_LEVEL 5 -#define AUSPEX_ANYWHERE_LEVEL 6 -/datum/action/cooldown/bloodsucker/targeted/tremere/auspex - name = "Auspex" - level_current = 1 - button_icon_state = "power_auspex" - bloodsucker_check_flags = BP_CANT_USE_IN_TORPOR - purchase_flags = TREMERE_CAN_BUY - bloodcost = 10 - constant_bloodcost = 1.1 - cooldown_time = 12 SECONDS - target_range = 2 - power_activates_immediately = FALSE - prefire_message = "Right click to teleport" - -/datum/action/cooldown/bloodsucker/targeted/tremere/auspex/on_power_upgrade() - // 1 + for default, the other + is for the upgrade that hasn't been added yet. - if(level_current >= AUSPEX_ANYWHERE_LEVEL) - target_range = 0 - else - target_range = min(level_current + 2, 10) - . = ..() - -/datum/action/cooldown/bloodsucker/targeted/tremere/auspex/get_power_desc_extended() - . = "Hide yourself within a Cloak of Darkness, click on a tile to teleport" - . = "Costs [AUSPEX_BLOOD_COST_PER_TILE] blood per tile teleported." - if(target_range) - . += " up to [target_range] tiles away." - else - . += " anywhere you can see." - if(level_current >= AUSPEX_BLEED_LEVEL) - if(level_current >= AUSPEX_KNOCKDOWN_LEVEL) - . += " This will cause people at your destination to start bleeding and fall asleep." - else - . += " This will cause people at your destination to start bleeding." - -/datum/action/cooldown/bloodsucker/targeted/tremere/auspex/get_power_explanation_extended() - . = list() - . += "When Activated, you will be hidden in a Cloak of Darkness." - . += "[target_range ? "Click to teleport up to [target_range] tiles away, as long as you can see it" : "You can teleport anywhere you can see"]." - . += "Teleporting will refill your stamina to full." - . += "At level [AUSPEX_BLEED_LEVEL] you will cause people at your end location to start bleeding." - . += "At level [AUSPEX_KNOCKDOWN_LEVEL] you will cause people at your end location to be knocked down." - . += "At level [AUSPEX_ANYWHERE_LEVEL] you will be able to teleport anywhere, even if you cannot properly see the tile." - . += "The power will cost [AUSPEX_BLOOD_COST_PER_TILE] blood per tile that you teleport." - -/datum/action/cooldown/bloodsucker/targeted/tremere/auspex/CheckValidTarget(atom/target_atom) - . = ..() - if(!.) - return FALSE - if(!isturf(target_atom)) - return FALSE - var/turf/target_turf = target_atom - if(target_turf.is_blocked_turf_ignore_climbable()) - return FALSE - if(level_current < AUSPEX_ANYWHERE_LEVEL && !(target_turf in view(owner.client.view, owner.client))) - owner.balloon_alert(owner, "out of view!") - return FALSE - return TRUE - -/datum/action/cooldown/bloodsucker/targeted/tremere/auspex/ActivatePower(trigger_flags) - . = ..() - if(bloodsuckerdatum_power.frenzied) - return TRUE - owner.AddElement(/datum/element/digitalcamo) - animate(owner, alpha = 70, time = 2 SECONDS) - return TRUE - -/datum/action/cooldown/bloodsucker/targeted/tremere/auspex/DeactivatePower(deactivate_flags) - . = ..() - if(!.) - return FALSE - animate(owner, alpha = 255, time = 2 SECONDS) - owner.RemoveElement(/datum/element/digitalcamo) - -/datum/action/cooldown/bloodsucker/targeted/tremere/auspex/FireSecondaryTargetedPower(atom/target, params) - . = ..() - var/mob/living/user = owner - var/turf/targeted_turf = get_turf(target) - auspex_blink(user, targeted_turf) - -/datum/action/cooldown/bloodsucker/targeted/tremere/auspex/proc/auspex_blink(mob/living/user, turf/targeted_turf) - var/blood_cost = AUSPEX_BLOOD_COST_PER_TILE * get_dist(user, targeted_turf) - if(!can_pay_blood(blood_cost)) - owner.balloon_alert(owner, "not enough blood!") - return - playsound(user, 'sound/effects/magic/summon_karp.ogg', 60) - playsound(targeted_turf, 'sound/effects/magic/summon_karp.ogg', 60) - - new /obj/effect/particle_effect/fluid/smoke/vampsmoke(user.drop_location()) - new /obj/effect/particle_effect/fluid/smoke/vampsmoke(targeted_turf) - - for(var/mob/living/carbon/living_mob in range(1, targeted_turf)-user) - if(IS_BLOODSUCKER(living_mob) || IS_GHOUL(living_mob)) - continue - if(level_current >= AUSPEX_BLEED_LEVEL) - var/obj/item/bodypart/bodypart = pick(living_mob.bodyparts) - bodypart.force_wound_upwards(/datum/wound/slash/flesh/critical) - living_mob.adjust_brute_loss(15) - if(level_current >= AUSPEX_KNOCKDOWN_LEVEL) - living_mob.Knockdown(10 SECONDS, ignore_canstun = TRUE) - - do_teleport(owner, targeted_turf, no_effects = TRUE, channel = TELEPORT_CHANNEL_QUANTUM) - user.adjust_stamina_loss(-user.staminaloss) - PowerActivatedSuccesfully(cost_override = blood_cost) - -#undef AUSPEX_BLOOD_COST_PER_TILE -#undef AUSPEX_BLEED_LEVEL -#undef AUSPEX_KNOCKDOWN_LEVEL -#undef AUSPEX_ANYWHERE_LEVEL diff --git a/tff_modular/modules/bloodsucker/powers/tremere/dominate.dm b/tff_modular/modules/bloodsucker/powers/tremere/dominate.dm deleted file mode 100644 index dca84b9a606..00000000000 --- a/tff_modular/modules/bloodsucker/powers/tremere/dominate.dm +++ /dev/null @@ -1,217 +0,0 @@ -/** - * # Dominate; - * - * Level 1 - Mesmerizes target - * Level 2 - Mesmerizes and mutes target - * Level 3 - Mesmerizes, blinds and mutes target - * Level 4 - Target (if at least in crit & has a mind) will revive as a Mute/Deaf Ghoul for 5 minutes before dying. - * Level 5 - Target (if at least in crit & has a mind) will revive as a Ghoul for 8 minutes before dying. - */ - -#define TEMP_GHOULIZE_COST 150 -#define DOMINATE_XRAY_LEVEL 3 -#define DOMINATE_NON_MUTE_GHOULIZE_LEVEL 4 -/datum/action/cooldown/bloodsucker/targeted/mesmerize/dominate - name = "Dominate" - button_icon_state = "power_auspex" - background_icon_state = "tremere_power_off" - active_background_icon_state = "tremere_power_on" - base_background_icon_state = "tremere_power_off" - button_icon = 'tff_modular/modules/bloodsucker/icons/tremere_bloodsucker.dmi' - background_icon = 'tff_modular/modules/bloodsucker/icons/tremere_bloodsucker.dmi' - level_current = 1 - button_icon_state = "power_dominate" - purchase_flags = TREMERE_CAN_BUY - bloodcost = 15 - constant_bloodcost = 0.1 - target_range = 6 - mesmerize_delay = 4 SECONDS - blind_at_level = 3 - requires_facing_target = FALSE - blocked_by_glasses = FALSE - knockdown_on_secondary = TRUE - /// Data huds to show while the power is active - var/list/datahuds = list(DATA_HUD_SECURITY_ADVANCED, DATA_HUD_MEDICAL_ADVANCED, DATA_HUD_DIAGNOSTIC, DATA_HUD_BOT_PATH) - var/list/thralls = list() - -/datum/action/cooldown/bloodsucker/targeted/mesmerize/dominate/Remove(mob/removed_from) - . = ..() - for(var/thrall in thralls) - if(!thrall) - continue - end_possession(thrall) - -/datum/action/cooldown/bloodsucker/targeted/mesmerize/dominate/get_power_desc_extended() - . = ..() - if(level_current >= DOMINATE_GHOULIZE_LEVEL) - . += "If your target is in critical condition or dead, they will instead be turned into a temporary Ghoul. This will cost [TEMP_GHOULIZE_COST] blood. Pre-existing dead ghouls will simply be revived." - -/datum/action/cooldown/bloodsucker/targeted/mesmerize/dominate/get_power_explanation_extended() - . = list() - . += "Click any person to, after [DisplayTimeText(mesmerize_delay)], stun them for [DisplayTimeText(get_power_time())]." - . += "Right clicking on your victim however will apply a knockdown will confuse and slow them down for [DisplayTimeText(get_power_time())]." - . += "A left click will completely immobilize, and blind them for the next [DisplayTimeText(get_power_time())] seconds, and will also mute them for [DisplayTimeText(get_power_time())] seconds." - . += "While this ability is active, you will be able to see additional information about everyone in the room." - . += "At level [DOMINATE_XRAY_LEVEL], you will gain X-Ray vision while this ability is active." - . += "At level [DOMINATE_GHOULIZE_LEVEL], while adjacent to the target, if your target is in critical condition or dead, they will instead be turned into a temporary Ghoul. This will cost [TEMP_GHOULIZE_COST] blood." - . += "The victim must have atleast [BLOOD_VOLUME_BAD] blood to be ghouled." - . += "The ghoul will be mute and deaf if the level of [src] is not at least [DOMINATE_NON_MUTE_GHOULIZE_LEVEL]" - . += "If you use this on a currently dead normal Ghoul, they will will not suddenly cease to live as if a temporary Ghoul." - . += "They will have complete loyalty to you, until their death in [DisplayTimeText(get_ghoul_duration())] upon use." - . += "Ghoulizing or reviving a ghoul will make this ability go on cooldown for [DisplayTimeText(get_ghoulize_cooldown())]." - -/datum/action/cooldown/bloodsucker/targeted/mesmerize/dominate/CheckCanTarget(atom/target_atom) - var/mob/living/selected_target = target_atom - if(level_current >= DOMINATE_GHOULIZE_LEVEL && (IS_GHOUL(selected_target) || selected_target.stat >= SOFT_CRIT)) - if(selected_target?.mind && owner.Adjacent(selected_target)) - return TRUE - . = ..() - if(!.) - return FALSE - return TRUE - -/datum/action/cooldown/bloodsucker/targeted/mesmerize/dominate/ContinueActive(mob/living/user, mob/living/target) - if(!target) - return can_use(user) - . = ..() - -/datum/action/cooldown/bloodsucker/targeted/mesmerize/dominate/ActivatePower(atom/target) - . = ..() - if(level_current >= DOMINATE_XRAY_LEVEL) - ADD_TRAIT(owner, TRAIT_XRAY_VISION, DOMINATE_TRAIT) - for(var/hudtype in datahuds) - var/datum/atom_hud/data_hud = GLOB.huds[hudtype] - data_hud.show_to(owner) - owner.update_sight() - return TRUE - -/datum/action/cooldown/bloodsucker/targeted/mesmerize/dominate/DeactivatePower(deactivate_flags) - . = ..() - if(!.) - return - if(level_current >= DOMINATE_XRAY_LEVEL) - REMOVE_TRAIT(owner, TRAIT_XRAY_VISION, DOMINATE_TRAIT) - for(var/hudtype in datahuds) - var/datum/atom_hud/data_hud = GLOB.huds[hudtype] - data_hud.hide_from(owner) - owner.update_sight() - -/datum/action/cooldown/bloodsucker/targeted/mesmerize/dominate/FireTargetedPower(atom/target, params) - var/mob/living/target_mob = target - var/mob/living/user = owner - if(target_mob.stat != CONSCIOUS && level_current >= DOMINATE_GHOULIZE_LEVEL) - if(user.Adjacent(target)) - attempt_ghoulize(target, user) - else - if(IS_GHOUL(target_mob)) - owner.balloon_alert(owner, "too far to revive!") - else - owner.balloon_alert(owner, "too far to ghoul!") - return TRUE - return ..() - -/datum/action/cooldown/bloodsucker/targeted/mesmerize/dominate/proc/attempt_ghoulize(mob/living/target, mob/living/user) - owner.face_atom(target) - var/datum/antagonist/ghoul/ghoul = IS_GHOUL(target) - if(!victim_has_blood(target)) - return FALSE - if(ghoul) - owner.balloon_alert(owner, "attempting to revive.") - else - owner.balloon_alert(owner, "attempting to ghoul.") - if(!do_after(user, 6 SECONDS, target, NONE, TRUE)) - return FALSE - if(!victim_has_blood(target)) - return FALSE - if(ghoul?.master == bloodsuckerdatum_power) - if(target.stat != DEAD) - owner.balloon_alert(owner, "not dead!") - return FALSE - PowerActivatedSuccesfully(get_ghoulize_cooldown()) - to_chat(user, span_warning("We revive [target]!")) - owner.balloon_alert(owner, "successfully revived!") - target.mind?.grab_ghost() - target.revive(ADMIN_HEAL_ALL) - pay_cost(TEMP_GHOULIZE_COST - bloodcost) - log_combat(owner, target, "tremere revived", addition="Revived their ghoul using dominate") - return FALSE - if(!bloodsuckerdatum_power.make_ghoul(target)) - owner.balloon_alert(owner, "not a valid target for ghouling!.") - return - - /*if(IS_MONSTERHUNTER(target)) - to_chat(target, span_notice("Their body refuses to react...")) - return*/ - PowerActivatedSuccesfully(get_ghoulize_cooldown()) - to_chat(user, span_warning("We revive [target]!")) - // no escaping at this point - target.mind?.grab_ghost(TRUE) - target.revive(ADMIN_HEAL_ALL) - var/datum/antagonist/ghoul/ghouldatum = target.mind.has_antag_datum(/datum/antagonist/ghoul) - ghouldatum.special_type = TREMERE_GHOUL //don't turn them into a favorite please - var/living_time = get_ghoul_duration() - log_combat(owner, target, "tremere mindslaved", addition="Revived and converted [target] into a temporary tremere ghoul for [DisplayTimeText(living_time)].") - if(level_current <= DOMINATE_NON_MUTE_GHOULIZE_LEVEL) - target.add_traits(list(TRAIT_MUTE, TRAIT_DEAF), DOMINATE_TRAIT) - user.balloon_alert(target, "only [DisplayTimeText(living_time)] left to live!") - to_chat(target, span_warning("You will only live for [DisplayTimeText(living_time)]! Obey your master and go out in a blaze of glory!")) - var/timer_id = addtimer(CALLBACK(src, PROC_REF(end_possession), target), living_time, TIMER_STOPPABLE) - // timer that only the master and thrall can see - setup_timer(user, target, living_time, timer_id) - thralls += target - RegisterSignals(target, list(COMSIG_LIVING_DEATH, COMSIG_QDELETING), PROC_REF(end_possession), timer_id) - RegisterSignal(ghouldatum, COMSIG_ANTAGONIST_REMOVED, PROC_REF(on_antag_datum_removal), target, timer_id) - pay_cost(TEMP_GHOULIZE_COST - bloodcost) - return TRUE - -/datum/action/cooldown/bloodsucker/targeted/mesmerize/dominate/proc/victim_has_blood(mob/living/target) - // you can always revive non-temporary ghouls - if(IS_GHOUL(target)) - return TRUE - if(target.blood_volume < BLOOD_VOLUME_BAD) - owner.balloon_alert(owner, "not enough blood in victim!") - return FALSE - return TRUE - -/datum/action/cooldown/bloodsucker/targeted/mesmerize/dominate/proc/setup_timer(mob/living/user, mob/living/target, living_time, timer_id) - var/list/show_to = list(user, target) - if(bloodsuckerdatum_power && length(bloodsuckerdatum_power.ghouls)) - for(var/datum/antagonist/ghoul in bloodsuckerdatum_power.ghouls) - if(!ghoul?.owner?.current) - continue - show_to += ghoul.owner.current - new /atom/movable/screen/text/screen_timer/attached(null, show_to, timer_id, "Dies in ${timer}", null, null, target) - new /atom/movable/screen/text/screen_timer(null, target, timer_id, "You die in ${timer}") - -/datum/action/cooldown/bloodsucker/targeted/mesmerize/dominate/proc/on_antag_datum_removal(datum/antagonist/ghoul, mob/living/thrall, timer_id) - end_possession(thrall, timer_id) - -/datum/action/cooldown/bloodsucker/targeted/mesmerize/dominate/proc/end_possession(mob/living/user, timer_id) - if(timer_id) - deltimer(timer_id) - if(!user) - CRASH("[src] end_possession called with no user!") - if(!(user in thralls)) - return - thralls -= user - user.remove_traits(list(TRAIT_MUTE, TRAIT_DEAF), DOMINATE_TRAIT) - if(!HAS_TRAIT(user, TRAIT_NOBLOOD)) - user.blood_volume = 0 - if(!IS_GHOUL(user)) - to_chat(user, span_warning("You feel the blood keeping you alive run out!")) - return - to_chat(user, span_warning("You feel the Blood of your Master run out!")) - user.mind?.remove_antag_datum(/datum/antagonist/ghoul) - if(user.stat == DEAD) - return - user.death() - -/datum/action/cooldown/bloodsucker/targeted/mesmerize/dominate/proc/get_ghoul_duration() - return 4 MINUTES * max(level_current, 1) - -/datum/action/cooldown/bloodsucker/targeted/mesmerize/dominate/proc/get_ghoulize_cooldown() - return cooldown_time * 3 - -#undef TEMP_GHOULIZE_COST -#undef DOMINATE_XRAY_LEVEL -#undef DOMINATE_NON_MUTE_GHOULIZE_LEVEL diff --git a/tff_modular/modules/bloodsucker/powers/tremere/thaumaturgy.dm b/tff_modular/modules/bloodsucker/powers/tremere/thaumaturgy.dm deleted file mode 100644 index 656987b538e..00000000000 --- a/tff_modular/modules/bloodsucker/powers/tremere/thaumaturgy.dm +++ /dev/null @@ -1,293 +0,0 @@ -/** - * # Thaumaturgy - * - * Level 1 - One shot bloodbeam spell - * Level 2 - Bloodbeam spell - Gives them a Blood shield until they use Bloodbeam - * Level 3 - Bloodbeam spell that breaks open lockers/doors - Gives them a Blood shield until they use Bloodbeam - * Level 4 - Bloodbeam spell that breaks open lockers/doors + double damage to victims - Gives them a Blood shield until they use Bloodbeam - * Level 5 - Bloodbeam spell that breaks open lockers/doors + double damage & steals blood - Gives them a Blood shield until they use Bloodbeam - */ - -#define BLOOD_SHIELD_BLOCK_CHANCE 50 -#define BLOOD_SHIELD_BLOCK_CHANCE_UPGRADED 60 -#define BLOOD_SHIELD_BLOOD_COST 5 -#define THAUMATURGY_BLOOD_COST_PER_CHARGE 5 -#define THAUMATURGY_COOLDOWN_PER_CHARGE 5 SECONDS - -#define THAUMATURGY_SHIELD_LEVEL 2 -#define THAUMATURGY_DOOR_BREAK_LEVEL 3 -#define THAUMATURGY_EXTRA_DAMAGE_LEVEL 4 -#define THAUMATURGY_BLOOD_STEAL_LEVEL 5 -#define THAUMATURGY_SHIELD_UPGRADE_LEVEL 6 - -/datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy - name = "Thaumaturgy" - level_current = 1 - button_icon_state = "power_thaumaturgy" - check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_HANDS_BLOCKED - purchase_flags = TREMERE_CAN_BUY - // custom cooldown handling based on charges - power_flags = BP_AM_STATIC_COOLDOWN - bloodcost = 5 - constant_bloodcost = 0 - // 5 seconds per charge - cooldown_time = 5 SECONDS - prefire_message = "Right click where you wish to fire." - click_to_activate = TRUE // you pay to replenish charges - power_activates_immediately = FALSE - unset_after_click = FALSE // Lets us cast multiple times - /// How many times you can shoot before you need to recast - var/charges = 0 - /// How long it takes before you can shoot again - var/shot_cooldown = 0 - var/datum/weakref/blood_shield - var/obj/projectile/magic/arcane_barrage/bloodsucker/magic_9ball - -/datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy/Grant() - charges = get_max_charges() - . = ..() - -/datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy/Remove() - . = ..() - var/shield = blood_shield?.resolve() - if(shield) - QDEL_NULL(shield) - -/datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy/on_power_upgrade() - cooldown_time = get_max_charges() * THAUMATURGY_COOLDOWN_PER_CHARGE - bloodcost = get_max_charges() * THAUMATURGY_BLOOD_COST_PER_CHARGE - // just in case you somehow level up while the power is active - charges = get_max_charges() - . = ..() - -/datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy/get_power_desc_extended() - . = "
    Projectile can seek for [get_shot_range()] tiles.
    " - . += "Fire a slow seeking blood bolt at your enemy.
    " - if(level_current >= THAUMATURGY_SHIELD_LEVEL) - . += "Right click the button to create a blood shield
    " - if(level_current >= THAUMATURGY_DOOR_BREAK_LEVEL) - . += "The projectile will open doors/lockers" - if(level_current >= THAUMATURGY_BLOOD_STEAL_LEVEL) - . += " and steal blood from the target" - -/datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy/get_power_explanation_extended() - . = list() - . += "Thaumaturgy grants you the ability to cast and shoot a slow moving target seeking blood projectile." - . += "The projectile will auto aim to a nearby mob if you aim at the ground." - . += "If the Blood blast hits a person, it will deal [get_blood_bolt_damage()] [initial(magic_9ball.damage_type)] damage, and is blocked by [initial(magic_9ball.armor_flag)] armor." - . += "You can use Blood blast [get_max_charges()] times before needing to recast Thaumaturgy. After each shot you will have to wait [DisplayTimeText(get_shot_cooldown())]." - . += "At level [THAUMATURGY_SHIELD_LEVEL] it will grant you a shield that will block [BLOOD_SHIELD_BLOCK_CHANCE]% of incoming damage, costing you [THAUMATURGY_BLOOD_COST_PER_CHARGE] blood each time." - . += "To activate the shield, right click the action button." - . += "At level [THAUMATURGY_DOOR_BREAK_LEVEL], it will also break open lockers and doors." - . += "At level [THAUMATURGY_BLOOD_STEAL_LEVEL], it will also steal blood to feed yourself, just as much as each charge costs." - . += "The cooldown increases by [DisplayTimeText(THAUMATURGY_COOLDOWN_PER_CHARGE)] per charge used, and each blast costs [THAUMATURGY_BLOOD_COST_PER_CHARGE] blood." - -/datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy/ActivatePower(mob/target) - . = ..() - charges = get_max_charges() - toggle_blood_shield(TRUE) - return TRUE - -/datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy/proc/toggle_blood_shield(toggle) - if(level_current < THAUMATURGY_SHIELD_LEVEL) - return - // don't toggle if we're already in the state we want to be in - if(toggle == !!blood_shield) - return - - if(blood_shield) - var/shield = blood_shield?.resolve() - owner.visible_message( - span_warning("[owner]\'s [blood_shield] loses its form and disappears into [owner.p_their()] hands "), - span_warning("We unform our Blood shield!"), - span_hear("You hear liquids sloshing around."), - ) - owner.balloon_alert(owner, "you unform the [shield]") - qdel(shield) - blood_shield = null - else - var/obj/item/shield/bloodsucker/new_shield = new - blood_shield = WEAKREF(new_shield) - if(!owner.put_in_inactive_hand(new_shield)) - QDEL_NULL(new_shield) - owner.balloon_alert(owner, "off hand is full!") - to_chat(owner, span_notice("[capitalize(src)] couldn't be activated as your off hand is full.")) - return FALSE - owner.balloon_alert(owner, "you form the [src]") - owner.visible_message( - span_warning("[owner]\'s hands begins to bleed and forms into a [src]!"), - span_warning("We form our [src]!"), - span_hear("You hear liquids forming together."), - ) - if(level_current >= THAUMATURGY_SHIELD_UPGRADE_LEVEL) - new_shield.block_chance = BLOOD_SHIELD_BLOCK_CHANCE_UPGRADED - -/datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy/DeactivatePower(deactivate_flags) - . = ..() - if(!.) - return - var/used_charges = get_max_charges() - charges - toggle_blood_shield(FALSE) - if(used_charges > 0) - StartCooldown() - -/datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy/StartCooldown(override_cooldown_time, override_melee_cooldown_time) - var/used_charges = get_max_charges() - charges - // no cooldown if we didn't use any charges - if(used_charges <= 0) - return - charges = get_max_charges() - return ..(used_charges * THAUMATURGY_COOLDOWN_PER_CHARGE, override_melee_cooldown_time) - -/datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy/proc/get_blood_bolt_damage() - if(level_current >= THAUMATURGY_EXTRA_DAMAGE_LEVEL) - return 54 - return 27 - -/datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy/proc/get_max_charges() - return level_current * 2 - -/datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy/proc/get_shot_cooldown() - return max(1.5 - (level_current * 0.1), 0) SECONDS - -/datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy/proc/get_shot_range() - return initial(magic_9ball.range) + level_current * 10 - -/datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy/update_button_status(atom/movable/screen/movable/action_button/button, force) - . = ..() - if(next_use_time - world.time <= 0) - button.maptext = MAPTEXT_TINY_UNICODE(span_italics("[charges]/[get_max_charges()]")) - -/datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy/FireSecondaryTargetedPower(atom/target, params) - if(shot_cooldown > world.time) - return - if(!can_pay_blood(THAUMATURGY_BLOOD_COST_PER_CHARGE)) - owner.balloon_alert(owner, "not enough blood!") - DeactivatePower() - return - shot_cooldown = world.time + get_shot_cooldown() - var/mob/living/user = owner - owner.balloon_alert(owner, "you fire a blood bolt!") - owner.visible_message( - span_warning("[owner] fires a blood bolt at [target]!"), - span_warning("You fire a blood bolt at [target]!"), - span_hear("You hear a loud crackling sound."), - ) - user.changeNext_move(CLICK_CD_RANGE) - user.newtonian_move(get_dir(target, user)) - user.face_atom(target) - handle_shot(user, target) - - pay_cost(THAUMATURGY_BLOOD_COST_PER_CHARGE) - playsound(user, 'sound/effects/magic/wand_teleport.ogg', 60, TRUE) - charges -= 1 - build_all_button_icons(UPDATE_BUTTON_STATUS) - if(charges <= 0) - // delay the message so it doesn't overlap with the cooldown message - addtimer(CALLBACK(owner, TYPE_PROC_REF(/atom, balloon_alert), owner, "no charges left!"), 0.5 SECONDS) - PowerActivatedSuccesfully(cost_override = 0) - -/datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy/proc/handle_shot(mob/user, atom/target) - magic_9ball = new(get_turf(user)) - magic_9ball.firer = user - magic_9ball.power_ref = WEAKREF(src) - magic_9ball.damage = get_blood_bolt_damage() - magic_9ball.def_zone = ran_zone(user.zone_selected, min(level_current * 10, 90)) - magic_9ball.aim_projectile(target, user) - // autotarget if we aim at a turf - if(isturf(target)) - var/list/targets = list() - for(var/mob/living/possible_target in orange(1, target)) - if(!ismob(possible_target)) - continue - var/datum/antagonist/ghoul/ghoul = IS_GHOUL(possible_target) - if(length(bloodsuckerdatum_power?.ghouls) && ghoul && (ghoul in bloodsuckerdatum_power?.ghouls)) - continue - targets += possible_target - if(length(targets)) - magic_9ball.set_homing_target(pick(targets)) - else if(ismob(target)) - magic_9ball.homing_target = target - magic_9ball.homing_turn_speed = min(10 * level_current, 90) - magic_9ball.range = initial(magic_9ball.range) + level_current * 10 - INVOKE_ASYNC(magic_9ball, TYPE_PROC_REF(/obj/projectile, fire)) - // ditch the pointer to reduce harddels - magic_9ball = null -/** - * # Blood Bolt - * - * This is the projectile this Power will fire. - */ -/obj/projectile/magic/arcane_barrage/bloodsucker - name = "blood bolt" - icon_state = "mini_leaper" - damage = 1 - wound_bonus = 20 - armour_penetration = 30 - speed = 0.6 - impact_effect_type = /obj/effect/temp_visual/impact_effect/red_laser - range = 30 - armor_flag = LASER - var/datum/weakref/power_ref - -/obj/projectile/magic/arcane_barrage/bloodsucker/on_hit(target, blocked = 0, pierce_hit) - var/datum/action/cooldown/bloodsucker/targeted/tremere/thaumaturgy/bloodsucker_power = power_ref?.resolve() - if(!bloodsucker_power) - return ..() - if(istype(target, /obj/structure/closet) && bloodsucker_power.level_current >= THAUMATURGY_DOOR_BREAK_LEVEL) - var/obj/structure/closet/hit_closet = target - if(hit_closet) - hit_closet.welded = FALSE - hit_closet.locked = FALSE - hit_closet.broken = TRUE - hit_closet.update_appearance() - return ..() - if(istype(target, /obj/machinery/door) && bloodsucker_power.level_current >= THAUMATURGY_DOOR_BREAK_LEVEL) - var/obj/machinery/door/hit_airlock = target - hit_airlock.open(2) - qdel(src) - return ..() - if(ismob(target)) - if(bloodsucker_power.level_current >= THAUMATURGY_BLOOD_STEAL_LEVEL) - var/mob/living/person_hit = target - person_hit.blood_volume -= THAUMATURGY_BLOOD_COST_PER_CHARGE - bloodsucker_power.bloodsuckerdatum_power.AdjustBloodVolume(THAUMATURGY_BLOOD_COST_PER_CHARGE) - return ..() - . = ..() - -/** - * # Blood Shield - * - * The shield spawned when using Thaumaturgy when strong enough. - * Copied mostly from '/obj/item/shield/changeling' - */ - -/obj/item/shield/bloodsucker - name = "blood shield" - desc = "A shield made out of blood, requiring blood to sustain hits." - item_flags = ABSTRACT | DROPDEL - icon = 'tff_modular/modules/bloodsucker/icons/vamp_obj.dmi' - icon_state = "blood_shield" - lefthand_file = 'tff_modular/modules/bloodsucker/icons/bloodsucker_lefthand.dmi' - righthand_file = 'tff_modular/modules/bloodsucker/icons/bloodsucker_righthand.dmi' - block_chance = BLOOD_SHIELD_BLOCK_CHANCE - -/obj/item/shield/bloodsucker/Initialize(mapload) - . = ..() - ADD_TRAIT(src, TRAIT_NODROP, BLOODSUCKER_TRAIT) - -/obj/item/shield/bloodsucker/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) - var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(owner) - if(bloodsuckerdatum) - bloodsuckerdatum.AdjustBloodVolume(-BLOOD_SHIELD_BLOOD_COST) - return ..() - -#undef BLOOD_SHIELD_BLOCK_CHANCE -#undef BLOOD_SHIELD_BLOOD_COST -#undef THAUMATURGY_BLOOD_COST_PER_CHARGE -#undef THAUMATURGY_COOLDOWN_PER_CHARGE - -#undef THAUMATURGY_SHIELD_LEVEL -#undef THAUMATURGY_DOOR_BREAK_LEVEL -#undef THAUMATURGY_BLOOD_STEAL_LEVEL -#undef THAUMATURGY_EXTRA_DAMAGE_LEVEL diff --git a/tff_modular/modules/bloodsucker/powers/vassal/distress.dm b/tff_modular/modules/bloodsucker/powers/vassal/distress.dm deleted file mode 100644 index 788f80feb8f..00000000000 --- a/tff_modular/modules/bloodsucker/powers/vassal/distress.dm +++ /dev/null @@ -1,24 +0,0 @@ -/datum/action/cooldown/bloodsucker/distress - name = "Distress" - desc = "Injure yourself, allowing you to make a desperate call for help to your Master." - button_icon_state = "power_distress" - power_explanation = "Distress:\n\ - Use this Power from anywhere and your Master Bloodsucker will instantly be alerted of your location." - power_flags = NONE - check_flags = NONE - purchase_flags = NONE - bloodcost = 10 - cooldown_time = 10 SECONDS - level_current = -1 - -/datum/action/cooldown/bloodsucker/distress/ActivatePower(trigger_flags) - . = ..() - var/turf/open/floor/target_area = get_area(owner) - var/datum/antagonist/ghoul/ghouldatum = owner.mind.has_antag_datum(/datum/antagonist/ghoul) - - owner.balloon_alert(owner, "you call out for your master!") - to_chat(ghouldatum.master.owner, "[owner], your loyal Ghoul, is desperately calling for aid at [target_area]!") - - var/mob/living/user = owner - user.adjust_brute_loss(10) - return TRUE diff --git a/tff_modular/modules/bloodsucker/powers/vassal/recuperate.dm b/tff_modular/modules/bloodsucker/powers/vassal/recuperate.dm deleted file mode 100644 index 108dd5a7c92..00000000000 --- a/tff_modular/modules/bloodsucker/powers/vassal/recuperate.dm +++ /dev/null @@ -1,75 +0,0 @@ -/// Used by Ghouls -/datum/action/cooldown/bloodsucker/recuperate - name = "Sanguine Recuperation" - desc = "Slowly heals you overtime using your master's blood, in exchange for some of your own blood and effort." - button_icon_state = "power_recup" - power_explanation = "Recuperate:\n\ - Activating this Power will begin to heal your wounds.\n\ - You will heal Brute and Toxin damage, at the cost of Stamina damage, and blood from both you and your Master.\n\ - If you aren't a bloodless race, you will additionally heal Burn damage.\n\ - The power will cancel out if you are dead or unconcious." - power_flags = BP_CONTINUOUS_EFFECT - check_flags = AB_CHECK_CONSCIOUS - bloodsucker_check_flags = NONE - purchase_flags = NONE - bloodcost = 1.5 - cooldown_time = 10 SECONDS - level_current = -1 - -/datum/action/cooldown/bloodsucker/recuperate/can_use(mob/living/carbon/user, trigger_flags) - . = ..() - if(!.) - return - if(user.stat >= DEAD || user.incapacitated) - user.balloon_alert(user, "you are incapacitated...") - return FALSE - return TRUE - -/datum/action/cooldown/bloodsucker/recuperate/ActivatePower(trigger_flags) - . = ..() - to_chat(owner, span_notice("Your muscles clench as your master's immortal blood mixes with your own, knitting your wounds.")) - owner.balloon_alert(owner, "recuperate turned on.") - return TRUE - -/datum/action/cooldown/bloodsucker/recuperate/process(seconds_per_tick) - . = ..() - if(!.) - return - - if(!active) - return - var/mob/living/carbon/user = owner - var/datum/antagonist/ghoul/ghouldatum = IS_GHOUL(user) - if(!ghouldatum || QDELETED(ghouldatum.master)) - to_chat(owner, span_warning("No master to draw blood from!")) - DeactivatePower() - return - ghouldatum.master.AdjustBloodVolume(-1) - user.set_timed_status_effect(5 SECONDS, /datum/status_effect/jitter, only_if_higher = TRUE) - user.adjust_stamina_loss(bloodcost * 1.1) - user.adjust_brute_loss(-2.5, updating_health = FALSE) - user.adjust_tox_loss(-2, forced = TRUE, updating_health = FALSE) - // Plasmamen won't lose blood, they don't have any, so they don't heal from Burn. - if(!HAS_TRAIT(user, TRAIT_NOBLOOD)) - user.blood_volume -= bloodcost - user.adjust_fire_loss(-1.5, updating_health = FALSE) - user.updatehealth() - // Stop Bleeding - if(istype(user) && user.is_bleeding()) - for(var/obj/item/bodypart/part in user.bodyparts) - part.generic_bleedstacks-- - -/datum/action/cooldown/bloodsucker/recuperate/ContinueActive(mob/living/user, mob/living/target) - if(user.stat >= DEAD) - return FALSE - if(INCAPACITATED_IGNORING(user, INCAPABLE_GRAB|INCAPABLE_RESTRAINTS)) - owner?.balloon_alert(owner, "too exhausted...") - return FALSE - return TRUE - -/datum/action/cooldown/bloodsucker/recuperate/DeactivatePower(deactivate_flags) - . = ..() - if(!.) - return - owner.balloon_alert(owner, "recuperate turned off.") - return ..() diff --git a/tff_modular/modules/bloodsucker/powers/vassal/vassal_fold.dm b/tff_modular/modules/bloodsucker/powers/vassal/vassal_fold.dm deleted file mode 100644 index 8e6a942debf..00000000000 --- a/tff_modular/modules/bloodsucker/powers/vassal/vassal_fold.dm +++ /dev/null @@ -1,90 +0,0 @@ -/datum/action/cooldown/bloodsucker/ghoul_blood - name = "Help Ghoul" - desc = "Bring an ex-Ghoul back into the fold, or create blood using a bag. RMB: Check Ghoul status." - button_icon_state = "power_torpor" - power_explanation = "Help Ghoul:\n\ - Use this power while you have an ex-Ghoul grabbed to bring them back into the fold. \ - Use this power with a bloodbag in your hand to instead fill it with Vampiric Blood which \ - can be used to reset ex-ghoul deconversion timers. \ - Right-Click will show the status of all Ghouls." - check_flags = NONE - purchase_flags = NONE - bloodcost = 10 - cooldown_time = 10 SECONDS - level_current = -1 - ///Bloodbag we have in our hands. - var/obj/item/reagent_containers/blood/bloodbag - ///Weakref to a target we're bringing into the fold. - var/datum/weakref/target_ref - -/datum/action/cooldown/bloodsucker/ghoul_blood/can_use(mob/living/carbon/user, trigger_flags) - . = ..() - if(!.) - return FALSE - var/datum/antagonist/ghoul/revenge/revenge_ghoul = IS_REVENGE_GHOUL(owner) - if(revenge_ghoul) - return FALSE - - if(trigger_flags & TRIGGER_SECONDARY_ACTION) - if(!revenge_ghoul.ex_ghouls.len) - owner.balloon_alert(owner, "no ghouls!") - return FALSE - return TRUE - - if(owner.pulling && isliving(owner.pulling)) - var/mob/living/pulled_target = owner.pulling - var/datum/antagonist/ex_ghoul/former_ghoul = IS_EX_GHOUL(pulled_target) - if(!former_ghoul) - owner.balloon_alert(owner, "not a former ghoul!") - return FALSE - target_ref = WEAKREF(owner.pulling) - return TRUE - - var/blood_bag = locate(/obj/item/reagent_containers/blood) in user.held_items - if(!blood_bag) - owner.balloon_alert(owner, "blood bag needed!") - return FALSE - if(istype(blood_bag, /obj/item/reagent_containers/blood/o_minus/bloodsucker)) - owner.balloon_alert(owner, "already bloodsucker blood!") - - bloodbag = blood_bag - return TRUE - -/datum/action/cooldown/bloodsucker/ghoul_blood/ActivatePower(trigger_flags) - . = ..() - var/datum/antagonist/ghoul/revenge/revenge_ghoul = IS_REVENGE_GHOUL(owner) - if(trigger_flags & TRIGGER_SECONDARY_ACTION) - for(var/datum/antagonist/ex_ghoul/former_ghouls as anything in revenge_ghoul.ex_ghouls) - var/information = "[former_ghouls.owner.current]" - information += " - has [round(COOLDOWN_TIMELEFT(former_ghouls, blood_timer) / 600)] minutes left of Blood" - var/turf/open/floor/target_area = get_area(owner) - if(target_area) - information += " - currently at [target_area]." - if(former_ghouls.owner.current.stat >= DEAD) - information += " - DEAD." - - to_chat(owner, "[information]") - - DeactivatePower() - return FALSE - - if(target_ref) - var/mob/living/target = target_ref.resolve() - var/datum/antagonist/ex_ghoul/former_ghoul = IS_EX_GHOUL(target) - if(!former_ghoul || former_ghoul.revenge_ghoul) - target_ref = null - return - if(do_after(owner, 5 SECONDS, target)) - former_ghoul.return_to_fold(revenge_ghoul) - target_ref = null - DeactivatePower() - return FALSE - - if(bloodbag) - var/mob/living/living_owner = owner - living_owner.blood_volume -= 150 - QDEL_NULL(bloodbag) - var/obj/item/reagent_containers/blood/o_minus/bloodsucker/new_bag = new(owner.loc) - owner.put_in_active_hand(new_bag) - DeactivatePower() - return TRUE diff --git a/tff_modular/modules/bloodsucker/powers/veil.dm b/tff_modular/modules/bloodsucker/powers/veil.dm deleted file mode 100644 index 9d5d69b0262..00000000000 --- a/tff_modular/modules/bloodsucker/powers/veil.dm +++ /dev/null @@ -1,162 +0,0 @@ -/datum/action/cooldown/bloodsucker/veil - name = "Veil of Many Faces" - desc = "Disguise yourself in the illusion of another identity." - button_icon_state = "power_veil" - power_flags = NONE - check_flags = AB_CHECK_CONSCIOUS - bloodsucker_check_flags = BP_CANT_USE_IN_FRENZY|BP_CANT_USE_IN_TORPOR - purchase_flags = BLOODSUCKER_DEFAULT_POWER - bloodcost = 15 - level_current = -1 - constant_bloodcost = 0.1 - cooldown_time = 10 SECONDS - // Outfit Vars -// var/list/original_items = list() - // Identity Vars - var/prev_gender - var/prev_skin_tone - var/prev_hair_style - var/prev_facial_hair_style - var/prev_hair_color - var/prev_facial_hair_color - var/prev_underwear - var/prev_undershirt - var/prev_socks - var/prev_disfigured - var/prev_mutant_bodyparts - var/prev_markings - var/list/prev_features // For lizards and such - var/disguise_name - -/datum/action/cooldown/bloodsucker/veil/get_power_explanation_extended() - . = list() - . += "Activating Veil of Many Faces will shroud you in smoke and forge you a new identity." - . += "Your name and appearance will be completely randomized, and turning the ability off again will undo it all." - . += "Clothes, gear, and Security/Medical HUD status is kept the same while this power is active." - -/datum/action/cooldown/bloodsucker/veil/ActivatePower(atom/target) - . = ..() - cast_effect() // POOF -// if(blahblahblah) -// Disguise_Outfit() - veil_user() - owner.balloon_alert(owner, "veil turned on.") - return TRUE - -/* // Meant to disguise your character's clothing into fake ones. -/datum/action/cooldown/bloodsucker/veil/proc/Disguise_Outfit() - return - // Step One: Back up original items -*/ - -/datum/action/cooldown/bloodsucker/veil/proc/veil_user() - // Change Name/Voice - var/mob/living/carbon/human/user = owner - to_chat(owner, span_warning("You mystify the air around your person. Your identity is now altered.")) - - // Store Prev Appearance - disguise_name = generate_random_name(user.gender, TRUE) - prev_gender = user.gender - prev_skin_tone = user.skin_tone - prev_hair_style = user.hairstyle - prev_facial_hair_style = user.facial_hairstyle - prev_hair_color = user.hair_color - prev_facial_hair_color = user.facial_hair_color - prev_underwear = user.underwear - prev_undershirt = user.undershirt - prev_socks = user.socks -// prev_eye_color - prev_disfigured = HAS_TRAIT(user, TRAIT_DISFIGURED) // I was disfigured! //prev_disabilities = user.disabilities - prev_features = user.dna.features - prev_mutant_bodyparts = user.dna.mutant_bodyparts - prev_markings = user.dna.body_markings - - // Change Appearance - user.gender = pick(MALE, FEMALE, PLURAL, NEUTER) - user.skin_tone = pick(GLOB.skin_tones) - user.hairstyle = random_hairstyle(user.gender) - user.facial_hairstyle = pick(random_facial_hairstyle(user.gender), "Shaved") - user.hair_color = "#[random_short_color()]" - user.facial_hair_color = user.hair_color - user.underwear = random_underwear(user.gender) - user.undershirt = random_undershirt(user.gender) - user.socks = random_socks(user.gender) - - //user.eye_color = random_eye_color() - if(prev_disfigured) - REMOVE_TRAIT(user, TRAIT_DISFIGURED, null) - var/datum/dna/dna = user.dna - // - // dna.features = dna.species.randomize_features() - dna.features = dna.species.randomize_features(user) - // dna.body_markings = dna.species.get_random_body_markings(dna.features) - dna.body_markings = list() - dna.mutant_bodyparts = dna.species.get_mutant_bodyparts(dna.features) - - // Apply Appearance - user.regenerate_organs() // Actually regenerates the mutant_bodyparts. - user.update_body(TRUE) // Outfit and underware, also body. - user.update_body_parts(TRUE) // Lizard tails etc - - RegisterSignal(user, COMSIG_HUMAN_GET_VISIBLE_NAME, PROC_REF(return_disguise_name)) - -/datum/action/cooldown/bloodsucker/veil/proc/return_disguise_name(mob/living/carbon/human/user, list/identity) - SIGNAL_HANDLER - - identity[VISIBLE_NAME_FACE] = disguise_name - user.get_message_voice(disguise_name) - -/datum/action/cooldown/bloodsucker/veil/DeactivatePower(deactivate_flags) - . = ..() - if(!. || !ishuman(owner)) - return - var/mob/living/carbon/human/user = owner - // Revert Identity - user.get_message_voice() - - // Revert Appearance - user.gender = prev_gender - user.skin_tone = prev_skin_tone - user.hairstyle = prev_hair_style - user.facial_hairstyle = prev_facial_hair_style - user.hair_color = prev_hair_color - user.facial_hair_color = prev_facial_hair_color - user.underwear = prev_underwear - user.undershirt = prev_undershirt - user.socks = prev_socks - user.dna.mutant_bodyparts = prev_mutant_bodyparts - user.dna.body_markings = prev_markings - - //user.disabilities = prev_disabilities // Restore HUSK, CLUMSY, etc. - if(prev_disfigured) - //We are ASSUMING husk. // user.status_flags |= DISFIGURED // Restore "Unknown" disfigurement - ADD_TRAIT(user, TRAIT_DISFIGURED, TRAIT_HUSK) - user.dna.features = prev_features - - // Apply Appearance - user.regenerate_organs() - user.update_body(is_creating = TRUE) // Outfit and underware, also body. - user.update_body_parts(update_limb_data = TRUE) // Body itself, maybe skin color? - - cast_effect() // POOF - owner.balloon_alert(owner, "veil turned off.") - - UnregisterSignal(user, COMSIG_HUMAN_GET_VISIBLE_NAME) - - -// CAST EFFECT // General effect (poof, splat, etc) when you cast. Doesn't happen automatically! -/datum/action/cooldown/bloodsucker/veil/proc/cast_effect() - // Effect - playsound(get_turf(owner), 'sound/effects/magic/smoke.ogg', 20, 1) - var/datum/effect_system/steam_spread/bloodsucker/puff = new /datum/effect_system/steam_spread/() - puff.set_up(3, 0, get_turf(owner)) - puff.attach(owner) //OPTIONAL - puff.start() - owner.spin(8, 1) //Spin around like a loon. - -/obj/effect/particle_effect/fluid/smoke/vampsmoke - opacity = FALSE - lifetime = 0 - -/obj/effect/particle_effect/fluid/smoke/vampsmoke/fade_out(frames = 0.8 SECONDS) - ..(frames) diff --git a/tff_modular/modules/bloodsucker/sound/BloodsuckerAlert.ogg b/tff_modular/modules/bloodsucker/sound/BloodsuckerAlert.ogg deleted file mode 100644 index 686f15bb711eae7f062f530453bf9ff42abfc0cc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 218645 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�l8GPyI#u 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
  • W_eO@b4Zr#4y}T=C86YD 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 diff --git a/tff_modular/modules/bloodsucker/sound/owl_10.ogg b/tff_modular/modules/bloodsucker/sound/owl_10.ogg deleted file mode 100644 index 97f45d433788668ddd603260a53c8b054e84aaea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7811 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") + +/atom/movable/screen/vampire + icon = 'tff_modular/modules/vampire/icons/actions_vampire.dmi' + mouse_over_pointer = MOUSE_HAND_POINTER + +/atom/movable/screen/vampire/blood_counter + name = "Vitae" + icon_state = "blood_display" + screen_loc = UI_BLOOD_DISPLAY + +/atom/movable/screen/vampire/blood_counter/Click() + . = ..() + var/list/msg = list() + var/mob/living/owner_mob = hud.mymob + var/datum/antagonist/vampire/owner_vamp = IS_VAMPIRE(owner_mob) + + if(!owner_vamp) + return + + msg += span_cult_large("This is your Vitae-Counter.") + msg += span_cult("Here you see your current level of blood-energy. This is used for all of your abilities, and sustains your very being.") + msg += span_cult("\nYou need to drink a certain amount from living, sentient beings in order to level up.") + msg += span_cult("Your healing also depends on it. You reach your maximum healing potential at [BS_BLOOD_VOLUME_MAX_REGEN].") + + var/bloodlevel + switch(owner_vamp.current_vitae) + if(0 to 200) + bloodlevel = "starved" + if(201 to 500) + bloodlevel = "thirsty" + if(501 to 700) + bloodlevel = "peckish" + if(701 to INFINITY) + bloodlevel = "content" + + msg += span_cult("Your current maximum is: [owner_vamp.max_vitae].") + msg += span_cult("This shift, you have drank [owner_vamp.total_blood_drank] units of blood.") + + msg += span_cult_large("\nRight now, you are feeling [bloodlevel].") + + if(owner_vamp.vitae_goal_progress <= owner_vamp.current_vitae_goal) + msg += span_cult_large("\nYour progress to the next level is: [owner_vamp.vitae_goal_progress]/[owner_vamp.current_vitae_goal].") + else + msg += span_cult_large("\nYou have drank deeply and greedily. Sleep in a coffin to level up.") + + to_chat(usr, boxed_message(msg.Join("\n"))) + +/atom/movable/screen/vampire/rank_counter + name = "Vampire Rank" + icon_state = "rank" + screen_loc = UI_VAMPRANK_DISPLAY + +/atom/movable/screen/vampire/rank_counter/Click() + . = ..() + var/list/msg = list() + var/mob/living/owner_mob = hud.mymob + var/datum/antagonist/vampire/owner_vamp = IS_VAMPIRE(owner_mob) + + if(!owner_vamp) + return + + /* var/mob/living/carbon/human/vampire_human = owner_mob */ + msg += span_cult_large("This is your Rank-Counter.") + msg += span_cult("Here you see your current progress in the mastery of your disciplines.") + msg += span_cult("This is a measure of your main progress as a vampire, and, should you feed on another vampire(that has broken the masquerade), you will absorb half of their levels.") + msg += span_cult("With your current rank, you are considered as [owner_vamp.get_rank_string()] of your craft.") + msg += span_cult("\nCurrently, your rank affords you the following benefits:") + msg += span_cult("Max Regeneration rate: +[owner_vamp.vampire_regen_rate]") + msg += span_cult("Max Vitae pool: +[owner_vamp.max_vitae - 600] ") + msg += span_cult("Unarmed damage: +[1 + (owner_vamp.vampire_level * owner_vamp.extra_damage_per_rank)]") + + var/list/disciplinestext + for(var/datum/discipline/discipline in owner_vamp.owned_disciplines) + disciplinestext += "\n[discipline.name] - " + disciplinestext += "Level:" + disciplinestext += "[discipline.level - 1]" + + if(disciplinestext) + msg += span_cult("\nYour disciplines and their levels are:[disciplinestext]") + + to_chat(usr, boxed_message(msg.Join("\n"))) + +/atom/movable/screen/vampire/humanity_counter + name = "Humanity" + icon_state = "humanity" + screen_loc = UI_HUMANITY_DISPLAY + +/atom/movable/screen/vampire/humanity_counter/Click() + . = ..() + var/list/msg = list() + var/mob/living/owner_mob = hud.mymob + var/datum/antagonist/vampire/owner_vamp = IS_VAMPIRE(owner_mob) + + msg += span_cult_large("This is your Humanity score.") + msg += span_cult("Humanity is a measure of how closely a vampire clings to the morality and values of mortal life, and consequently how well they are able to resist the urges of the Beast.") + msg += span_cult("This has an active effect on the curse of all cainites. Vampires with little humanity may find it harder to stay awake during the day, or to awaken from long periods of torpor. If your humanity is particularly low, you may even burst into flames in the presence of god's light.") + + var/humanitylevel + switch(owner_vamp.humanity) + if(0) + humanitylevel = "Monstrous" + if(1) + humanitylevel = "Horrific" + if(2) + humanitylevel = "Bestial" + if(3) + humanitylevel = "Cold" + if(4) + humanitylevel = "Unfeeling" + if(5) + humanitylevel = "Removed" + if(6) + humanitylevel = "Distant" + if(7) + humanitylevel = "Normal" + if(8) + humanitylevel = "Caring" + if(9) + humanitylevel = "Compassionate" + if(10) + humanitylevel = "Saintly" + + // Pardon me for my math, i was never good at this. + + var/normal_humanity_divisor = min(2, 1 + (owner_vamp.humanity / 10)) + var/divisor_turned_percentage = ((normal_humanity_divisor - 1) * 200) / 4 + + msg += span_cult("\nRight now, others would describe you as '[humanitylevel]', giving you a [divisor_turned_percentage]% resistance to the ravages of Sol.") + if(owner_vamp.humanity > 7) + msg += span_cult("Due to your connection to your own human soul, you have achieved the masquerade ability.") + + msg += span_cult("\nYou may gain humanity by engaging in human activities, such as:") + msg += span_cult("Hugging different mortals: [length(owner_vamp.humanity_trackgain_hugged)] of [owner_vamp.humanity_hugging_goal].") + msg += span_cult("Petting various animals: [length(owner_vamp.humanity_trackgain_petted)] of [owner_vamp.humanity_petting_goal].") + msg += span_cult("Looking at art: [length(owner_vamp.humanity_trackgain_art)] of [owner_vamp.humanity_art_goal].") + + to_chat(usr, boxed_message(msg.Join("\n"))) + +/// Update Blood Counter + Rank Counter +/datum/antagonist/vampire/proc/update_hud() + var/valuecolor + switch(current_vitae) + if(0 to 200) + valuecolor = "#560808" + if(201 to 300) + valuecolor = "#a32a2a" + if(301 to 500) + valuecolor = "#d55c5c" + if(501 to 700) // This isn't janky, a tiny bit lenience is baked in. + valuecolor = "#ffc2c2" + if(701 to INFINITY) + valuecolor = "#ffffff" + + blood_display?.maptext = FORMAT_VAMPIRE_HUD_TEXT(valuecolor, current_vitae) + + if(vamprank_display) + if(vampire_level_unspent > 0) + vamprank_display.icon_state = "[initial(vamprank_display.icon_state)]_up" + else + vamprank_display.icon_state = initial(vamprank_display.icon_state) + vamprank_display.maptext = FORMAT_VAMPIRE_HUD_TEXT("#ffd8d8", vampire_level) + + if(humanity_display) + var/humanityvaluecolor + switch(humanity) + if(0 to 2) + humanityvaluecolor = "#600000" + if(3 to 4) + humanityvaluecolor = "#a71c1c" + if(4 to 5) + humanityvaluecolor = "#db4646" + if(6 to 8) // same here + humanityvaluecolor = "#e8adad" + if(9 to 10) + humanityvaluecolor = "#ffffff" + + humanity_display.maptext = FORMAT_VAMPIRE_HUD_TEXT(humanityvaluecolor, humanity) + +/// 1 tile up +#undef UI_HUMANITY_DISPLAY +/// 1 tile down +#undef UI_BLOOD_DISPLAY +/// 2 tiles down +#undef UI_VAMPRANK_DISPLAY + +///Maptext define for Vampire HUDs +#undef FORMAT_VAMPIRE_HUD_TEXT diff --git a/tff_modular/modules/vampire/moodlets_vampire.dm b/tff_modular/modules/vampire/moodlets_vampire.dm new file mode 100644 index 00000000000..de89ae6dd0b --- /dev/null +++ b/tff_modular/modules/vampire/moodlets_vampire.dm @@ -0,0 +1,35 @@ +/datum/mood_event/drankblood + description = span_nicegreen("I have fed greedily from that which nourishes me.") + mood_change = 10 + timeout = 8 MINUTES + +/datum/mood_event/drankblood_bad + description = span_boldwarning("I drank the blood of a lesser creature. Disgusting.") + mood_change = -4 + timeout = 3 MINUTES + +/datum/mood_event/drankblood_dead + description = span_boldwarning("I drank dead blood. I am better than this.") + mood_change = -7 + timeout = 8 MINUTES + +/datum/mood_event/drankblood_synth + description = span_boldwarning("I drank synthetic blood. What is wrong with me?") + mood_change = -7 + timeout = 8 MINUTES + +/datum/mood_event/drankkilled + description = span_boldwarning("I drained a mortal to death. I feel... inhuman.") + mood_change = -15 + timeout = 10 MINUTES + +/datum/mood_event/coffinsleep + description = span_nicegreen("I slept in a coffin during the day. I feel whole again.") + mood_change = 10 + timeout = 6 MINUTES + +///Candelabrum's mood event to non Vampire/Vassals +/datum/mood_event/vampcandle + description = span_boldwarning("You feel something crawling in your mind...") + mood_change = -15 + timeout = 5 MINUTES diff --git a/tff_modular/modules/vampire/names_vampire.dm b/tff_modular/modules/vampire/names_vampire.dm new file mode 100644 index 00000000000..27009ef7bf3 --- /dev/null +++ b/tff_modular/modules/vampire/names_vampire.dm @@ -0,0 +1,42 @@ +GLOBAL_VAR_INIT(vampire_names_male, shuffle(list( + "Desmond","Rudolph","Dracula","Vlad","Pyotr","Gregor", + "Cristian","Christoff","Marcu","Andrei","Constantin", + "Gheorghe","Grigore","Ilie","Iacob","Luca","Mihail","Pavel", + "Vasile","Octavian","Sorin","Sveyn","Aurel","Alexe","Iustin", + "Theodor","Dimitrie","Octav","Damien","Magnus","Caine","Abel", // Romanian/Ancient + "Lucius","Gaius","Otho","Balbinus","Arcadius","Romanos","Alexios","Vitellius", // Latin + "Melanthus","Teuthras","Orchamus","Amyntor","Axion", // Greek + "Thoth","Thutmose","Osorkon,","Nofret","Minmotu","Khafra", // Egyptian + "Dio", +))) + +GLOBAL_VAR_INIT(vampire_names, shuffle(list( + "Islana","Tyrra","Greganna","Pytra","Hilda", + "Andra","Crina","Viorela","Viorica","Anemona", + "Camelia","Narcisa","Sorina","Alessia","Sophia", + "Gladda","Arcana","Morgan","Lasarra","Ioana","Elena", + "Alina","Rodica","Teodora","Denisa","Mihaela", + "Svetla","Stefania","Diyana","Kelssa","Lilith", // Romanian/Ancient + "Alexia","Athanasia","Callista","Karena","Nephele","Scylla","Ursa", // Latin + "Alcestis","Damaris","Elisavet","Khthonia","Teodora", // Greek + "Nefret","Ankhesenpep", // Egyptian +))) + +/datum/antagonist/vampire/proc/return_full_name() + var/fullname = vampire_name || owner.name || owner.current.real_name || owner.current.name + + fullname += " the [get_rank_string(vampire_level)]" + + return fullname + +///Returns a First name for the Vampire. +/datum/antagonist/vampire/proc/select_first_name() + var/list/name_list // blah blah blah lists are references + if(owner.current.gender == MALE) + name_list = GLOB.vampire_names_male + else + name_list = GLOB.vampire_names + // as the list is shuffled initially, we can just pick the first name, then move it to the back. + // in theory, as long as there's not a morbillion vampires, we should never have any duplicate names + vampire_name = popleft(name_list) + name_list += vampire_name diff --git a/tff_modular/modules/vampire/objectives_vampire.dm b/tff_modular/modules/vampire/objectives_vampire.dm new file mode 100644 index 00000000000..0f85755c180 --- /dev/null +++ b/tff_modular/modules/vampire/objectives_vampire.dm @@ -0,0 +1,182 @@ +/datum/objective/vampire + martyr_compatible = TRUE + +/datum/objective/vampire/New() + update_explanation_text() + return ..() + +////////////////////////////////////////////////////////////////////////////////////// +// // EGO OBJECTIVES // // +////////////////////////////////////////////////////////////////////////////////////// +/datum/objective/vampire/ego + name = "Dominion" + explanation_text = "You crave power, the authority to rule:" + +////////////////////////////////////////////////// Lair +//////////////////////////////////////////////////////////////////// + +/datum/objective/vampire/ego/vassals + name = "Vassalize Mortals" + +/datum/objective/vampire/ego/vassals/New() + target_amount = rand(1, 3) + return ..() + +/datum/objective/vampire/ego/vassals/update_explanation_text() + . = ..() + explanation_text = "[initial(explanation_text)] Vassalize [target_amount] mortal\s using a Vassalization Rack, and ensure they survive the shift." + +// WIN CONDITIONS? +/datum/objective/vampire/ego/vassals/check_completion() + var/datum/antagonist/vampire/vampire_datum = owner.has_antag_datum(/datum/antagonist/vampire) + return vampire_datum?.count_vassals(only_living = TRUE) >= target_amount + + +////////////////////////////////////////////////// Department Vassal +//////////////////////////////////////////////////////////////////// + +/datum/objective/vampire/ego/department_vassal + name = "Bind a Department" + + ///The selected department we have to vassalize. + var/target_department + ///List of all departments that can be selected for the objective. + var/static/list/possible_departments = list( + "engineering" = DEPARTMENT_BITFLAG_ENGINEERING, + "medical" = DEPARTMENT_BITFLAG_MEDICAL, + "science" = DEPARTMENT_BITFLAG_SCIENCE, + "cargo" = DEPARTMENT_BITFLAG_CARGO, + "service" = DEPARTMENT_BITFLAG_SERVICE, + ) + +/datum/objective/vampire/ego/department_vassal/New() + target_department = pick(possible_departments) + target_amount = 1 + return ..() + +/datum/objective/vampire/ego/department_vassal/update_explanation_text() + explanation_text = "[initial(explanation_text)] Convert a crew member from the [target_department] department into your vassal." + return ..() + +/datum/objective/vampire/ego/department_vassal/proc/get_vassal_occupations() + var/datum/antagonist/vampire/vampire_datum = owner.has_antag_datum(/datum/antagonist/vampire) + if(!length(vampire_datum?.vassals)) + return FALSE + + var/list/all_vassal_jobs = list() + for(var/datum/antagonist/vassal/vassal_datum in vampire_datum.vassals) + if(!vassal_datum.owner) + continue + + var/datum/mind/vassal_mind = vassal_datum.owner + + // Mind Assigned + if(vassal_mind.assigned_role) + all_vassal_jobs += vassal_mind.assigned_role + continue + // Mob Assigned + if(vassal_mind.current?.job) + all_vassal_jobs += vassal_mind.current.GetJob() + continue + // PDA Assigned + if(ishuman(vassal_mind.current)) + var/mob/living/carbon/human/human_vassal = vassal_mind.current + all_vassal_jobs += human_vassal.GetJob() + continue + + return all_vassal_jobs + +/datum/objective/vampire/ego/department_vassal/check_completion() + var/list/vassal_jobs = get_vassal_occupations() + var/converted_count = 0 + for(var/datum/job/checked_job in vassal_jobs) + if(checked_job.departments_bitflags & possible_departments[target_department]) + converted_count++ + if(converted_count >= target_amount) + return TRUE + return FALSE + + +////////////////////////////////////////////////// Big Places +//////////////////////////////////////////////////////////////////// + +/datum/objective/vampire/ego/bigplaces + name = "Ascend the Ranks" + +/datum/objective/vampire/ego/bigplaces/update_explanation_text() + . = ..() + explanation_text = "[initial(explanation_text)] Rise in power, reach prince or scourge, or prey on enough mortals to rank up as much as possible. You must reach at least rank 8 by the end of the shift!" + +// WIN CONDITIONS? +/datum/objective/vampire/ego/bigplaces/check_completion() + var/datum/antagonist/vampire/vampire_datum = owner.has_antag_datum(/datum/antagonist/vampire) + if(!vampire_datum) + return FALSE + + if(vampire_datum.vampire_level + vampire_datum.vampire_level_unspent >= 8) + return TRUE + + return FALSE + + +////////////////////////////////////////////////////////////////////////////////////// +// // HEDONISM OBJECTIVES // // +////////////////////////////////////////////////////////////////////////////////////// + +/datum/objective/vampire/hedonism + name = "Hunger" + explanation_text = "You crave depravity, to sate your thirst on the mortals:" + + +////////////////////////////////////////////////// Gourmand +//////////////////////////////////////////////////////////////////// + +/datum/objective/vampire/hedonism/gourmand + name = "Gorge" + +/datum/objective/vampire/hedonism/gourmand/New() + target_amount = rand(500, 1000) // This is blood, not vitae. + return ..() + +/datum/objective/vampire/hedonism/gourmand/update_explanation_text() + . = ..() + explanation_text = "[initial(explanation_text)] Consume at least [target_amount] units of blood to sate your ravenous thirst." + +/datum/objective/vampire/hedonism/gourmand/check_completion() + var/datum/antagonist/vampire/vampiredatum = owner.has_antag_datum(/datum/antagonist/vampire) + if(!vampiredatum) + return FALSE + var/stolen_blood = vampiredatum.total_blood_drank + if(stolen_blood >= target_amount) + return TRUE + return FALSE + +////////////////////////////////////////////////// Thirster +//////////////////////////////////////////////////////////////////// + +/datum/objective/vampire/hedonism/thirster + name = "Complete Drain" + // no check_completion, we just manually set `completed` in feed. + +/datum/objective/vampire/hedonism/thirster/update_explanation_text() + . = ..() + explanation_text = "[initial(explanation_text)] Drain a mortal completely, letting their lifeblood become your sustenance and their body fall cold and spent." + +////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////// MISC ////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////// + +/datum/objective/survive/vampire + name = "Endure" + explanation_text = "Avoid final death at all costs." + +/** + * Vassal + */ +/datum/objective/vampire/vassal + name = "assist master" + explanation_text = "You crave the blood of your sire! Obey and protect them at all costs!" + +/datum/objective/vampire/vassal/check_completion() + var/datum/antagonist/vassal/vassal_datum = owner.has_antag_datum(/datum/antagonist/vassal) + return vassal_datum.master?.owner?.current?.stat != DEAD diff --git a/tff_modular/modules/vampire/objects/_vampire_object.dm b/tff_modular/modules/vampire/objects/_vampire_object.dm new file mode 100644 index 00000000000..4a5e0af1a7d --- /dev/null +++ b/tff_modular/modules/vampire/objects/_vampire_object.dm @@ -0,0 +1,92 @@ +/obj/structure/vampire + pass_flags_self = parent_type::pass_flags_self | LETPASSCLICKS + /// Who owns this structure? + var/datum/mind/owner + /* + * We use vars to add descriptions to items. + * This way we don't have to make a new /examine for each structure + * And it's easier to edit. + */ + var/ghost_desc + var/vampire_desc + var/vassal_desc + var/curator_desc + +/obj/structure/vampire/Destroy() + owner = null + return ..() + +/obj/structure/vampire/examine(mob/user) + . = ..() + if(!user.mind && ghost_desc) + . += span_cult(ghost_desc) + if(IS_VAMPIRE(user) && vampire_desc) + if(!owner) + . += span_cult("It is unsecured. Click on [src] while in your lair to secure it in place to get its full potential") + return + . += span_cult(vampire_desc) + if(IS_VASSAL(user) && vassal_desc) + . += span_cult(vassal_desc) + if(IS_VAMPIRE_HUNTER(user) && curator_desc) + . += span_cult(curator_desc) + +/// This handles bolting down the structure. +/obj/structure/vampire/proc/bolt(mob/user) + if(!user?.mind) + return + to_chat(user, span_danger("You have secured [src] in place.")) + to_chat(user, span_announce("* Vampire Tip: Examine [src] to understand how it functions!")) + user.playsound_local(null, 'sound/items/tools/ratchet.ogg', 70, FALSE, pressure_affected = FALSE) + set_anchored(TRUE) + owner = user.mind + +/// This handles unbolting of the structure. +/obj/structure/vampire/proc/unbolt(mob/user) + if(user) + to_chat(user, span_danger("You have unsecured [src].")) + user.playsound_local(null, 'sound/items/tools/ratchet.ogg', 70, FALSE, pressure_affected = FALSE) + set_anchored(FALSE) + owner = null + +/obj/structure/vampire/attackby(obj/item/item, mob/living/user, params) + /// If a Vampire tries to wrench it in place, yell at them. + if(item.tool_behaviour == TOOL_WRENCH && !anchored && IS_VAMPIRE(user)) + user.playsound_local(null, 'sound/machines/buzz/buzz-sigh.ogg', 40, FALSE, pressure_affected = FALSE) + to_chat(user, span_announce("* Vampire Tip: Examine vampire structures to understand how they function!")) + return + return ..() + +/obj/structure/vampire/attack_hand(mob/user, list/modifiers) + var/datum/antagonist/vampire/vampiredatum = IS_VAMPIRE(user) + /// Claiming the Rack instead of using it? + if(vampiredatum && !owner) + if(!vampiredatum.vampire_lair_area) + to_chat(user, span_danger("You don't have a lair. Claim a coffin to make that location your lair.")) + return FALSE + if(vampiredatum.vampire_lair_area != get_area(src)) + to_chat(user, span_danger("You may only activate this structure in your lair: [vampiredatum.vampire_lair_area].")) + return FALSE + + /// Radial menu for securing your Persuasion rack in place. + to_chat(user, span_notice("Do you wish to secure [src] here?")) + var/list/secure_options = list( + "Yes" = image(icon = 'icons/hud/radial.dmi', icon_state = "radial_yes"), + "No" = image(icon = 'icons/hud/radial.dmi', icon_state = "radial_no")) + var/secure_response = show_radial_menu(user, src, secure_options, radius = 36, require_near = TRUE) + if(secure_response == "Yes") + bolt(user) + return FALSE + return TRUE + +/obj/structure/vampire/click_alt(mob/user) + if(!owner || user != owner.current || !user.Adjacent(src)) + return NONE + balloon_alert(user, "unbolt [src]?") + var/list/unsecure_options = list( + "Yes" = image(icon = 'icons/hud/radial.dmi', icon_state = "radial_yes"), + "No" = image(icon = 'icons/hud/radial.dmi', icon_state = "radial_no"), + ) + var/unsecure_response = show_radial_menu(user, src, unsecure_options, radius = 36, require_near = TRUE) + if(unsecure_response == "Yes") + unbolt(user) + return CLICK_ACTION_SUCCESS diff --git a/tff_modular/modules/vampire/objects/blood_drinking.dm b/tff_modular/modules/vampire/objects/blood_drinking.dm new file mode 100644 index 00000000000..cd88c2bb1e8 --- /dev/null +++ b/tff_modular/modules/vampire/objects/blood_drinking.dm @@ -0,0 +1,39 @@ +/obj/item/reagent_containers/blood/attack(mob/living/victim, mob/living/attacker, params) + if(!can_drink(victim, attacker)) + return + + var/to_feed = reagents.total_volume + if(victim != attacker) + if(!do_after(attacker, 5 SECONDS, victim, hidden = TRUE)) + return + attacker.visible_message( + span_notice("[attacker] forces [victim] to drink from \the [src]."), + span_notice("You put \the [src] up to [victim]'s mouth.") + ) + reagents.trans_to(victim, to_feed, transfered_by = attacker, methods = INGEST) + playsound(victim, 'sound/items/drink.ogg', vol = 30, vary = TRUE) + return TRUE + + attacker.visible_message( + span_notice("[victim] puts \the [src] up to [victim.p_their()] mouth."), + span_notice("You put \the [src] up to your mouth.") + ) + + if(!do_after(victim, 5 SECONDS, victim, timed_action_flags = IGNORE_USER_LOC_CHANGE, extra_checks = CALLBACK(src, PROC_REF(can_drink), victim, attacker), hidden = TRUE)) + return + + victim.visible_message( + span_notice("[victim] sucks the contents out of \the [src]!"), + span_notice("You feed from \the [src].") + ) + reagents.trans_to(victim, to_feed, transfered_by = attacker, methods = INGEST) + playsound(victim, 'sound/items/drink.ogg', vol = 30, vary = TRUE) + return TRUE + +/obj/item/reagent_containers/blood/proc/can_drink(mob/living/victim, mob/living/attacker) + if(!canconsume(victim, attacker)) + return FALSE + if(!reagents?.total_volume) + to_chat(victim, span_warning("[src] is empty!")) + return FALSE + return TRUE diff --git a/tff_modular/modules/vampire/objects/blood_throne.dm b/tff_modular/modules/vampire/objects/blood_throne.dm new file mode 100644 index 00000000000..6072c9bc13f --- /dev/null +++ b/tff_modular/modules/vampire/objects/blood_throne.dm @@ -0,0 +1,112 @@ +/// Blood Throne - Allows Vampires to remotely speak with their vassals. - Code (Mostly) stolen from comfy chairs (armrests) and chairs (layers) +/obj/structure/vampire/bloodthrone + name = "blood throne" + desc = "Twisted metal shards jut from the arm rests. Very uncomfortable looking. It would take a masochistic sort to sit on this jagged piece of furniture." + icon = 'tff_modular/modules/vampire/icons/vamp_obj_64.dmi' + icon_state = "throne" + buckle_lying = 0 + anchored = FALSE + density = TRUE + can_buckle = TRUE + ghost_desc = "This is a blood throne. Any vampire sitting on it can remotely speak to all other vampires by attempting to speak aloud." + vampire_desc = "This is a blood throne. Sitting on it will allow you to communicate telepathically to all other vampires by simply speaking." + vassal_desc = "This is a blood throne. It allows your master to telepathically speak to all other vampires." + curator_desc = "This is a chair that hurts those who try to buckle themselves onto it, though the undead have no problem latching on.\n\ + While buckled, monsters can use this to telepathically communicate with each other." + +// Add rotating and armrest +/obj/structure/vampire/bloodthrone/Initialize(mapload) + AddComponent(/datum/component/simple_rotation) + return ..() + +// Rotating +/obj/structure/vampire/bloodthrone/setDir(newdir) + . = ..() + for(var/mob/living/buckled in buckled_mobs) + buckled.setDir(newdir) + + if(has_buckled_mobs() && dir == NORTH) + layer = ABOVE_MOB_LAYER + else + layer = OBJ_LAYER + +/obj/structure/vampire/bloodthrone/update_overlays() + . = ..() + if(has_buckled_mobs()) + var/mutable_appearance/armrest = mutable_appearance('tff_modular/modules/vampire/icons/vamp_obj_64.dmi', "thronearm") + armrest.layer = ABOVE_MOB_LAYER + . += armrest + +// Buckling +/obj/structure/vampire/bloodthrone/buckle_mob(mob/living/user, force = FALSE, check_loc = TRUE) + if(!anchored) + to_chat(user, span_announce("[src] is not bolted to the ground!")) + return + set_density(FALSE) + . = ..() + set_density(TRUE) + user.visible_message( + span_notice("[user] sits down on \the [src]."), + span_boldnotice("You sit down onto [src]."), + ) + if(IS_VAMPIRE(user)) + RegisterSignal(user, COMSIG_MOB_SAY, PROC_REF(handle_speech)) + else + unbuckle_mob(user) + user.Paralyze(10 SECONDS) + to_chat(user, span_cult("The power of the blood throne overwhelms you!")) + +/obj/structure/vampire/bloodthrone/post_buckle_mob(mob/living/target) + update_appearance(UPDATE_OVERLAYS) + target.pixel_z += 2 + +// Unbuckling +/obj/structure/vampire/bloodthrone/unbuckle_mob(mob/living/user, force = FALSE, can_fall = TRUE) + visible_message(span_danger("[user] unbuckles [user.p_them()]self from \the [src].")) + UnregisterSignal(user, COMSIG_MOB_SAY) + return ..() + +/obj/structure/vampire/bloodthrone/post_unbuckle_mob(mob/living/target) + target.pixel_z -= 2 + update_appearance(UPDATE_OVERLAYS) + +// The speech itself +/obj/structure/vampire/bloodthrone/proc/handle_speech(datum/source, list/speech_args) + SIGNAL_HANDLER + + if(speech_args[SPEECH_FORCED]) + return + + var/mob/living/carbon/human/user = source + var/datum/antagonist/vampire/vampire_datum = IS_VAMPIRE(user) + if(!vampire_datum) + CRASH("Non-vampire speaking on blood throne somehow!") + + var/rank_icon_state = "vampire" + if(vampire_datum.prince) + rank_icon_state = "prince" + else if(vampire_datum.scourge) + rank_icon_state = "scourge" + + var/icon_html = "" + var/message = speech_args[SPEECH_MESSAGE] + var/rendered = span_cult_large("[icon_html] [user.real_name]: [message]") + user.log_talk(message, LOG_SAY, tag = ROLE_VAMPIRE) + + for(var/datum/antagonist/vampire/receiver as anything in GLOB.all_vampires) + if(!receiver.owner.current) + continue + var/mob/receiver_mob = receiver.owner.current + to_chat(receiver_mob, rendered, type = MESSAGE_TYPE_RADIO, avoid_highlighting = receiver_mob == user) + + for(var/datum/antagonist/vassal/vassal as anything in vampire_datum.vassals) + if(!vassal.owner.current) + continue + var/mob/receiver_mob = vassal.owner.current + to_chat(receiver_mob, rendered, type = MESSAGE_TYPE_RADIO) + + for(var/mob/dead_mob in GLOB.dead_mob_list) + var/link = FOLLOW_LINK(dead_mob, user) + to_chat(dead_mob, "[link] [rendered]", type = MESSAGE_TYPE_RADIO) + + speech_args[SPEECH_MESSAGE] = "" diff --git a/tff_modular/modules/vampire/objects/candelabrum.dm b/tff_modular/modules/vampire/objects/candelabrum.dm new file mode 100644 index 00000000000..b4daf5924a2 --- /dev/null +++ b/tff_modular/modules/vampire/objects/candelabrum.dm @@ -0,0 +1,159 @@ +/obj/structure/vampire/candelabrum + name = "candelabrum" + desc = "It burns slowly, but doesn't radiate any heat." + icon = 'tff_modular/modules/vampire/icons/vamp_obj.dmi' + icon_state = "candelabrum" + base_icon_state = "candelabrum" + light_color = "#66FFFF" + light_power = 3 + light_range = 2 + light_on = FALSE + density = FALSE + anchored = FALSE + ghost_desc = "This is a magical candle which drains the sanity of non-vampires and non-vassals." + vampire_desc = "This is a magical candle which drains the sanity of mortals who are not under your command while it is active." + vassal_desc = "This is a magical candle which drains the sanity of the fools who haven't yet accepted your master." + curator_desc = "This is a blue Candelabrum, which causes insanity to those near it while active." + var/lit = FALSE + +/obj/structure/vampire/candelabrum/Initialize(mapload) + . = ..() + RegisterSignal(src, COMSIG_CLICK, PROC_REF(distance_toggle)) + update_appearance() + register_context() + +/obj/structure/vampire/candelabrum/Destroy() + STOP_PROCESSING(SSobj, src) + return ..() + +/obj/structure/vampire/candelabrum/add_context(atom/source, list/context, obj/item/held_item, mob/user) + . = NONE + if(held_item) + return NONE + if(!anchored) + if(Adjacent(user) && IS_VAMPIRE(user)) + context[SCREENTIP_CONTEXT_LMB] = "Bolt" + return CONTEXTUAL_SCREENTIP_SET + return NONE + + if(!HAS_MIND_TRAIT(user, TRAIT_VAMPIRE_ALIGNED)) + return NONE + + var/is_full_vampire = IS_VAMPIRE(user) + if(Adjacent(user) || is_full_vampire) + context[SCREENTIP_CONTEXT_LMB] = lit ? "Extinguish" : "Light" + . = CONTEXTUAL_SCREENTIP_SET + + if(is_full_vampire) + context[SCREENTIP_CONTEXT_RMB] = lit ? "Extinguish All Nearby" : "Light All Nearby" + . = CONTEXTUAL_SCREENTIP_SET + + +/obj/structure/vampire/candelabrum/update_icon_state() + icon_state = "[base_icon_state][lit ? "_lit" : ""]" + return ..() + +/obj/structure/vampire/candelabrum/update_overlays() + . = ..() + if(lit) + . += emissive_appearance(icon, "[base_icon_state]_emissive", src) + +/obj/structure/vampire/candelabrum/update_desc(updates) + if(lit) + desc = initial(desc) + else + desc = "Despite not being lit, it makes your skin crawl." + return ..() + +/obj/structure/vampire/candelabrum/bolt() + set_density(TRUE) + return ..() + +/obj/structure/vampire/candelabrum/unbolt() + set_density(FALSE) + return ..() + +/obj/structure/vampire/candelabrum/set_anchored(anchorvalue) + . = ..() + if(!anchored) + set_lit(FALSE) + +/obj/structure/vampire/candelabrum/attack_hand(mob/living/user, list/modifiers) + if(!..()) + return + if(anchored && HAS_MIND_TRAIT(user, TRAIT_VAMPIRE_ALIGNED)) + set_lit(!lit) + return ..() + +/obj/structure/vampire/candelabrum/attack_hand_secondary(mob/user, list/modifiers) + . = ..() + if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN) + return + + if(!anchored || !IS_VAMPIRE(user)) + return + + user.balloon_alert_to_viewers("gestures dramatically") + dramatic_toggle_all(user, !lit) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + +/obj/structure/vampire/candelabrum/proc/dramatic_toggle_all(mob/user, value) + var/turf/our_turf = get_turf(src) + var/list/nearby_candels = list() + for(var/obj/structure/vampire/candelabrum/candel in view(7, src) | view(user)) + if(!candel.anchored || candel.lit == value) + continue + nearby_candels[candel] = get_dist(our_turf, get_turf(candel)) + + if(!length(nearby_candels)) + return + + sortTim(nearby_candels, cmp = value ? GLOBAL_PROC_REF(cmp_numeric_asc) : GLOBAL_PROC_REF(cmp_numeric_dsc), associative = TRUE) + + // maximum aurafarming + user.visible_message( + span_notice("[user] waves [user.p_their()] hand around, [value ? "igniting" : "extinguishing"] nearby candelabrums with a single gesture."), + span_notice("You wave your hand around, [value ? "igniting" : "extinguishing"] nearby candelabrums with a single gesture."), + ) + for(var/i = 1 to length(nearby_candels)) + var/obj/structure/vampire/candelabrum/candel = nearby_candels[i] + addtimer(CALLBACK(candel, PROC_REF(set_lit), value), i * (0.2 SECONDS), TIMER_UNIQUE | TIMER_OVERRIDE) + +/obj/structure/vampire/candelabrum/proc/distance_toggle(datum/source, atom/location, control, params, mob/user) + SIGNAL_HANDLER + if(!anchored || user.incapacitated() || user.get_active_held_item() || !IS_VAMPIRE(user) || user.Adjacent(src)) + return + var/list/modifiers = params2list(params) + user.balloon_alert_to_viewers("gestures dramatically") + if(LAZYACCESS(modifiers, RIGHT_CLICK)) + dramatic_toggle_all(user, !lit) + else + set_lit(!lit) + // gotta aurafarm + user.visible_message( + span_notice("[user] waves [user.p_their()] hand towards \the [src], causing its cold flame to [lit ? "ignite" : "extinguish"]."), + span_notice("You wave your hand towards \the [src], [lit ? "igniting" : "extinguishing"] it."), + ) + +/obj/structure/vampire/candelabrum/proc/set_lit(value) + if(lit == value) + return + lit = value + if(lit) + set_light_on(TRUE) + START_PROCESSING(SSobj, src) + else + set_light_on(FALSE) + STOP_PROCESSING(SSobj, src) + update_light() + update_appearance() + +/obj/structure/vampire/candelabrum/process() + if(!lit) + return PROCESS_KILL + for(var/mob/living/carbon/nearby_people in viewers(7, src)) + /// We don't want vampires or vassals affected by this + if(HAS_MIND_TRAIT(nearby_people, TRAIT_VAMPIRE_ALIGNED) || IS_VAMPIRE_HUNTER(nearby_people)) + continue + nearby_people.set_hallucinations_if_lower(10 SECONDS) + nearby_people.add_mood_event("vampcandle", /datum/mood_event/vampcandle) diff --git a/tff_modular/modules/vampire/objects/coffin.dm b/tff_modular/modules/vampire/objects/coffin.dm new file mode 100644 index 00000000000..754346fb6f2 --- /dev/null +++ b/tff_modular/modules/vampire/objects/coffin.dm @@ -0,0 +1,250 @@ +/obj/structure/closet/crate/coffin + name = "coffin" + desc = "It's a burial receptacle for the dearly departed." + icon_state = "coffin" + base_icon_state = "coffin" + resistance_flags = FLAMMABLE + max_integrity = 70 + material_drop = /obj/item/stack/sheet/mineral/wood + material_drop_amount = 5 + open_sound = 'sound/machines/closet/wooden_closet_open.ogg' + close_sound = 'sound/machines/closet/wooden_closet_close.ogg' + open_sound_volume = 25 + close_sound_volume = 50 + can_install_electronics = FALSE + paint_jobs = null + can_weld_shut = FALSE + +/obj/structure/closet/crate/coffin/Destroy() + unclaim_coffin() + return ..() + +/obj/structure/closet/crate/coffin/examine(mob/user) + . = ..() + if(user.mind == resident) + . += span_cult("This is your Claimed Coffin.") + . += span_cult("Rest in it while injured to enter Torpor. Entering it with unspent Ranks will allow you to spend one.") + . += span_cult("Alt-Click while inside the Coffin to Lock/Unlock.") + . += span_cult("Alt-Click while outside of your Coffin to Unclaim it, unwrenching it and all your other structures as a result.") + +/obj/structure/closet/crate/coffin/can_open(mob/living/user, force) + if(!locked) + return ..() + if(user.mind == resident) + if(welded) + welded = FALSE + update_appearance(UPDATE_ICON) + locked = FALSE + return TRUE + playsound(get_turf(src), 'tff_modular/modules/vampire/sound/door_locked.ogg', vol = 20, vary = TRUE) + to_chat(user, span_notice("[src] appears to be locked tight from the inside.")) + return FALSE + +/obj/structure/closet/crate/coffin/after_close(mob/living/user, force) + if(!user || user.loc != src) + return + var/datum/antagonist/vampire/vampire = IS_VAMPIRE(user) + if(!vampire) + return + if(!vampire.coffin && !resident) + switch(tgui_alert(user, "Do you wish to claim this as your coffin? [get_area(src)] will be your lair.", "Claim lair", list("Yes", "No"))) + if("Yes") + claim_coffin(user) + if("No") + return + lock_me(user) + + INVOKE_ASYNC(vampire, TYPE_PROC_REF(/datum/antagonist/vampire, rank_up_if_goal)) + + // You're in a Coffin, everything else is done, you're likely here to heal. Let's offer them the opportunity to do so. + vampire.check_begin_torpor() + +/obj/structure/closet/crate/click_alt(mob/living/user) + if(!isliving(user) || !IS_VAMPIRE(user)) + return NONE + if(user.loc == src) + return lock_me(user) ? CLICK_ACTION_SUCCESS : CLICK_ACTION_BLOCKING + if(user.mind == resident && user.Adjacent(src)) + balloon_alert(user, "unclaim coffin?") + var/list/unclaim_options = list( + "Yes" = image(icon = 'icons/hud/radial.dmi', icon_state = "radial_yes"), + "No" = image(icon = 'icons/hud/radial.dmi', icon_state = "radial_no") + ) + var/unclaim_response = show_radial_menu(user, src, unclaim_options, radius = 36, require_near = TRUE) + if(unclaim_response == "Yes") + unclaim_coffin(TRUE) + return CLICK_ACTION_SUCCESS + return NONE + +/obj/structure/closet/crate/coffin/crowbar_act(mob/living/user, obj/item/tool) + if(!locked) + return FALSE + user.visible_message( + span_notice("[user] tries to pry the lid off of [src] with [tool]."), + span_notice("You begin prying the lid off of [src] with [tool]."), + ) + if(!tool.use_tool(src, user, pry_lid_timer)) + return FALSE + bust_open() + user.visible_message( + span_notice("[user] snaps the door of [src] wide open."), + span_notice("The door of [src] snaps open."), + ) + return TRUE + +/obj/structure/closet/crate/coffin/wrench_act_secondary(mob/living/user, obj/item/tool) + if(!resident) + return ..() + to_chat(user, span_danger("The coffin won't detach from the floor.[user.mind == resident ? " You can Alt-Click to unclaim and unwrench your Coffin." : ""]")) + return TRUE + +/obj/structure/closet/crate/coffin/proc/claim_coffin(mob/living/claimer) + var/datum/antagonist/vampire/vampiredatum = IS_VAMPIRE(claimer) + if(vampiredatum.claim_coffin(src)) + resident = claimer.mind + set_anchored(TRUE) + +/obj/structure/closet/crate/proc/unclaim_coffin(manual = FALSE) + if(!resident) + return + + // Unanchor it (If it hasn't been broken, anyway) + if(!QDELETED(src)) + set_anchored(FALSE) + + // Unclaiming + var/datum/antagonist/vampire/vampiredatum = resident.has_antag_datum(/datum/antagonist/vampire) + if(vampiredatum?.coffin == src) + vampiredatum.coffin = null + vampiredatum.vampire_lair_area = null + for(var/datum/action/cooldown/vampire/gohome/gohome in vampiredatum.powers) + vampiredatum.remove_power(gohome) + + for(var/obj/structure/vampire/vampire_structure in get_area(src)) + if(vampire_structure.owner == resident) + vampire_structure.unbolt() + + if(manual) + to_chat(resident.current, span_cult_italic("You have unclaimed your coffin! This also unclaims all your other Vampire structures!")) + else + to_chat(resident.current, span_cult_italic("You sense that the link with your coffin and your lair has been broken! You will need to seek another.")) + + // Remove resident. Because this objec (GC?) we need to give them a way to see they don't have a home anymore. + resident = null + +/obj/structure/closet/crate/proc/lock_me(mob/user, in_locked = TRUE) + if(user.mind != resident) + return FALSE + if(!broken) + locked = in_locked + if(locked) + to_chat(user, span_notice("You flip a secret latch and lock yourself inside [src].")) + else + to_chat(user, span_notice("You flip a secret latch and unlock [src].")) + return TRUE + + // Broken? Let's fix it. + to_chat(user, span_notice("The secret latch that would lock [src] from the inside is broken. You set it back into place...")) + if(!do_after(user, 5 SECONDS, src)) + to_chat(user, span_notice("You fail to fix [src]'s mechanism.")) + return TRUE + to_chat(user, span_notice("You fix the mechanism and lock it.")) + broken = FALSE + locked = TRUE + return TRUE + +/obj/structure/closet/crate/coffin/blackcoffin + name = "black coffin" + desc = "For those departed who are not so dear." + icon_state = "coffin" + base_icon_state = "coffin" + icon = 'tff_modular/modules/vampire/icons/vamp_obj.dmi' + open_sound = 'tff_modular/modules/vampire/sound/coffin_open.ogg' + close_sound = 'tff_modular/modules/vampire/sound/coffin_close.ogg' + breakout_time = 30 SECONDS + pry_lid_timer = 20 SECONDS + resistance_flags = NONE + material_drop = /obj/item/stack/sheet/iron + material_drop_amount = 2 + armor_type = /datum/armor/blackcoffin + +/datum/armor/blackcoffin + melee = 50 + bullet = 20 + laser = 30 + bomb = 50 + fire = 70 + acid = 60 + +/obj/structure/closet/crate/coffin/securecoffin + name = "secure coffin" + desc = "For those too scared of having their place of rest disturbed." + icon_state = "securecoffin" + base_icon_state = "securecoffin" + icon = 'tff_modular/modules/vampire/icons/vamp_obj.dmi' + open_sound = 'tff_modular/modules/vampire/sound/coffin_open.ogg' + close_sound = 'tff_modular/modules/vampire/sound/coffin_close.ogg' + breakout_time = 35 SECONDS + pry_lid_timer = 35 SECONDS + resistance_flags = FIRE_PROOF | LAVA_PROOF | ACID_PROOF + material_drop = /obj/item/stack/sheet/iron + material_drop_amount = 2 + armor_type = /datum/armor/securecoffin + +/datum/armor/securecoffin + melee = 35 + bullet = 20 + laser = 20 + bomb = 100 + fire = 100 + acid = 100 + +/obj/structure/closet/crate/coffin/meatcoffin + name = "meat coffin" + desc = "When you're ready to meat your maker, the steaks can never be too high." + icon_state = "meatcoffin" + base_icon_state = "meatcoffin" + icon = 'tff_modular/modules/vampire/icons/vamp_obj.dmi' + resistance_flags = FIRE_PROOF + open_sound = 'sound/effects/footstep/slime1.ogg' + close_sound = 'sound/effects/footstep/slime1.ogg' + breakout_time = 25 SECONDS + pry_lid_timer = 20 SECONDS + material_drop = /obj/item/food/meat/slab/human + material_drop_amount = 3 + armor_type = /datum/armor/meatcoffin + +/datum/armor/meatcoffin + melee = 70 + bullet = 10 + laser = 10 + bomb = 70 + fire = 70 + acid = 60 + +/obj/structure/closet/crate/coffin/metalcoffin + name = "metal coffin" + desc = "A big metal sardine can inside of another big metal sardine can, in space." + icon_state = "metalcoffin" + base_icon_state = "metalcoffin" + icon = 'tff_modular/modules/vampire/icons/vamp_obj.dmi' + resistance_flags = FIRE_PROOF | LAVA_PROOF + open_sound = 'sound/effects/pressureplate.ogg' + close_sound = 'sound/effects/pressureplate.ogg' + breakout_time = 25 SECONDS + pry_lid_timer = 30 SECONDS + material_drop = /obj/item/stack/sheet/iron + material_drop_amount = 5 + armor_type = /datum/armor/metalcoffin + +/datum/armor/metalcoffin + melee = 40 + bullet = 15 + laser = 50 + bomb = 10 + fire = 70 + acid = 60 + +/obj/structure/closet/crate + var/datum/mind/resident + var/pry_lid_timer = 25 SECONDS diff --git a/tff_modular/modules/vampire/objects/hunter_gear.dm b/tff_modular/modules/vampire/objects/hunter_gear.dm new file mode 100644 index 00000000000..7039e84bd43 --- /dev/null +++ b/tff_modular/modules/vampire/objects/hunter_gear.dm @@ -0,0 +1,188 @@ +/obj/item/clothing/suit/armor/vamphunter + name = "vampire hunter garb" + desc = "This worn outfit saw much use back in the day. Internal reinforcements help protect against bites and scratches." + allowed = list( + /obj/item/book/bible, + /obj/item/book/kindred, + /obj/item/food/garlic_kimchi, + /obj/item/food/garlicbread, + /obj/item/food/grown/garlic, + /obj/item/reagent_containers/cup/glass/bottle/holywater, + /obj/item/stake, + ) + icon = 'tff_modular/modules/vampire/icons/vamp_obj.dmi' + worn_icon = 'tff_modular/modules/vampire/icons/worn.dmi' + icon_state = "monsterhunter" + inhand_icon_state = null + body_parts_covered = CHEST|GROIN|LEGS|ARMS + armor_type = /datum/armor/jacket_curator + strip_delay = 8 SECONDS + equip_delay_other = 6 SECONDS + +/datum/armor/jacket_curator + melee = 25 + bullet = 10 + laser = 25 + energy = 10 + acid = 45 + wound = 10 + +/obj/item/clothing/head/helmet/vamphunter_hat + name = "vampire hunter hat" + desc = "This hat saw much use back in the day." + icon = 'tff_modular/modules/vampire/icons/vamp_obj.dmi' + worn_icon = 'tff_modular/modules/vampire/icons/worn.dmi' + icon_state = "monsterhunterhat" + inhand_icon_state = null + flags_cover = HEADCOVERSEYES + flags_inv = HIDEEYES + armor_type = /datum/armor/jacket_curator + strip_delay = 8 SECONDS + dog_fashion = null + +/obj/item/stake + name = "wooden stake" + desc = "A simple wooden stake carved to a sharp point." + icon = 'tff_modular/modules/vampire/icons/stakes.dmi' + icon_state = "wood" + inhand_icon_state = "wood" + lefthand_file = 'tff_modular/modules/vampire/icons/bs_leftinhand.dmi' + righthand_file = 'tff_modular/modules/vampire/icons/bs_rightinhand.dmi' + slot_flags = ITEM_SLOT_POCKETS + hitsound = 'sound/items/weapons/bladeslice.ogg' + attack_verb_continuous = list("staked", "stabbed", "tore into") + attack_verb_simple = list("staked", "stabbed", "tore into") + sharpness = SHARP_POINTY + force = 6 + throwforce = 10 + max_integrity = 30 + embed_type = /datum/embedding/stake + + ///Time it takes to embed the stake into someone's chest. + var/staketime = 4 SECONDS + +/datum/embedding/stake + embed_chance = 100 + fall_chance = 0 + rip_time = 2.5 SECONDS + +/obj/item/stake/attack(mob/living/target, mob/living/user, params) + . = ..() + if(.) + return + + if(DOING_INTERACTION_WITH_TARGET(user, target)) + return + // Cannot target yourself, must be in combat mode and targeting the chest + if(target == user) + return + if(check_zone(user.zone_selected) != BODY_ZONE_CHEST) + return + + if(HAS_TRAIT(target, TRAIT_BEINGSTAKED)) + to_chat(user, span_notice("[target] is already having a stake driven into [target.p_their()] chest!")) + return + + // lol, cry about it + if(HAS_TRAIT(target, TRAIT_PIERCEIMMUNE)) + to_chat(user, span_notice("[target]'s chest is too thick! [src] won't go in!")) + return + + // Cannot have something in your chest + var/obj/item/bodypart/chest = target.get_bodypart(BODY_ZONE_CHEST) + if(!chest) + return + for(var/obj/item/embedded_object in chest.embedded_objects) + to_chat(user, span_boldannounce("[target]'s chest already has [embedded_object] inside of it!")) + return + + playsound(target, 'sound/effects/magic/Demon_consume.ogg', vol = 50, vary = TRUE) + to_chat(target, span_userdanger("[user] is driving a stake into your chest!")) + to_chat(user, span_notice("You put all your weight into embedding [src] into [target]'s chest...")) + + ADD_TRAIT(target, TRAIT_BEINGSTAKED, TRAIT_VAMPIRE) + if(!do_after(user, staketime, target)) + REMOVE_TRAIT(target, TRAIT_BEINGSTAKED, TRAIT_VAMPIRE) + return + + REMOVE_TRAIT(target, TRAIT_BEINGSTAKED, TRAIT_VAMPIRE) + + // Actually embed the stake and apply damage + if(!force_embed(target, BODY_ZONE_CHEST)) + return + + target.apply_damage(force * 2, BRUTE, BODY_ZONE_CHEST) + + playsound(target, 'sound/effects/splat.ogg', vol = 40, vary = TRUE) + user.visible_message( + span_danger("[user] drives the [src] into [target]'s chest!"), + span_danger("You drive the [src] into [target]'s chest!"), + ) + + var/datum/antagonist/vampire/vampire_datum = IS_VAMPIRE(target) + if(vampire_datum) + if(HAS_TRAIT(target, TRAIT_TORPOR) || target.stat >= UNCONSCIOUS) + vampire_datum.final_death() + else + to_chat(target, span_userdanger("You have been staked! Your powers are useless while it's in your chest!")) + target.balloon_alert(target, "you have been staked!") + +/obj/item/stake/examine(mob/user) + . = ..() + . += span_notice("To stake someone: Target the chest, activate combat mode, and hit them.") + . += span_notice("* Hunter Tip: Remember that they can just pull it out if they are awake. Cuff them or kill them. A stake will stop them from reviving, not from regenerating. It will also stop all of their abilities.") + +///Can this target be staked? If someone stands up before this is complete, it fails. Best used on someone stationary. +/obj/item/stake/proc/can_be_staked(mob/living/carbon/target) + if(!istype(target)) + return FALSE + if(!(target.mobility_flags & MOBILITY_MOVE)) + return TRUE + return FALSE + +/// Created by welding and acid-treating a simple stake. +/obj/item/stake/hardened + name = "hardened stake" + desc = "A wooden stake carved to a sharp point and hardened by fire." + icon_state = "hardened" + force = 8 + throwforce = 12 + armour_penetration = 10 + staketime = 3 SECONDS + +/obj/item/stake/hardened/silver + name = "silver stake" + desc = "Polished and sharp at the end. For when some mofo is always trying to iceskate uphill." + icon_state = "silver" + inhand_icon_state = "silver" + siemens_coefficient = 1 + force = 9 + armour_penetration = 25 + staketime = 2 SECONDS + +/obj/item/stack/sheet/mineral/wood/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(!tool.get_sharpness()) + return NONE + user.visible_message( + span_notice("[user] begins whittling [src] into a pointy object."), + span_notice("You begin whittling [src] into a sharp point at one end."), + span_hear("You hear wood carving."), + ) + // 5 Second Timer + if(!do_after(user, 5 SECONDS, src)) + return ITEM_INTERACT_BLOCKING + // Make Stake + var/obj/item/stake/new_item = new(user.drop_location()) + user.visible_message( + span_notice("[user] finishes carving a stake out of [src]."), + span_notice("You finish carving a stake out of [src]."), + ) + // Prepare to Put in Hands (if holding wood) + var/obj/item/stack/sheet/mineral/wood/wood_stack = src + var/replace = (user.get_inactive_held_item() == wood_stack) + // Use Wood + wood_stack.use(1) + // If stack depleted, put item in that hand (if it had one) + if(!wood_stack && replace) + user.put_in_hands(new_item) + return ITEM_INTERACT_SUCCESS diff --git a/tff_modular/modules/vampire/objects/kindred.dm b/tff_modular/modules/vampire/objects/kindred.dm new file mode 100644 index 00000000000..0da73006081 --- /dev/null +++ b/tff_modular/modules/vampire/objects/kindred.dm @@ -0,0 +1,97 @@ +/** + * # Archives of the Kindred: + * + * A book that can only be used by Curators and Monster Hnters. + * When used on a player, after a short timer, will reveal if the player is a Vampire, including their real name and Clan. + * This book should not work on Vampires using the Masquerade ability. + * If it reveals a Vampire, the Curator will then be able to tell they are a Vampire on examine (Like a vassal). + * Reading it normally will allow Curators to read what each Clan does, with some extra flavor text ones. + * + * Regular Vampires won't have any negative effects from the book, while everyone else will get burns/eye damage. + */ +/obj/item/book/kindred + name = "\improper Archive of the Kindred" + desc = "Cryptic documents explaining hidden truths behind Undead beings. It is said only Curators can decipher what they really mean." + icon = 'tff_modular/modules/vampire/icons/vamp_obj.dmi' + lefthand_file = 'tff_modular/modules/vampire/icons/bs_leftinhand.dmi' + righthand_file = 'tff_modular/modules/vampire/icons/bs_rightinhand.dmi' + icon_state = "kindred_book" + starting_title = "the Archive of the Kindred" + starting_author = "dozens of generations of Curators" + unique = TRUE + cannot_carve = TRUE + throw_speed = 1 + throw_range = 10 + resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF + +/obj/item/book/kindred/Initialize(mapload) + . = ..() + AddComponent(/datum/component/stationloving) + +///Attacking someone with the book. +/obj/item/book/kindred/interact_with_atom(mob/target, mob/living/user, list/modifiers) + if(!ismob(target) || user == target || !user.can_read(src)) + return NONE + if(DOING_INTERACTION(user, DOAFTER_SOURCE_ARCHIVE_OF_THE_KINDRED)) + return ITEM_INTERACT_BLOCKING + if(!IS_VAMPIRE_HUNTER(user)) + if(!IS_VAMPIRE(user)) + to_chat(user, span_warning("[src] burns your hands as you try to use it!")) + user.apply_damage(3, BURN, pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM)) + else + to_chat(user, span_notice("[src] seems to be too complicated for you. It would be best to leave this for someone else to take.")) + return ITEM_INTERACT_BLOCKING + + to_chat(user, span_notice("You begin carefully examining [target] while consulting [src]...")) + user.visible_message(span_notice("[user] looks at [target] while reading [src]."), ignored_mobs = list(user)) + if(!do_after(user, 3 SECONDS, target, interaction_key = DOAFTER_SOURCE_ARCHIVE_OF_THE_KINDRED)) + to_chat(user, span_notice("You quickly close [src].")) + return ITEM_INTERACT_SUCCESS + + var/datum/antagonist/vampire/vampiredatum = IS_VAMPIRE(target) + // Are we a Vampire | Are we on Masquerade. If one is true, they will fail. + if(vampiredatum && !HAS_TRAIT(target, TRAIT_MASQUERADE)) + if(vampiredatum.broke_masquerade) + to_chat(user, span_warning("[target], also known as '[vampiredatum.return_full_name()]', is indeed a Vampire, but you already knew this.")) + return ITEM_INTERACT_SUCCESS + to_chat(user, span_warning("[target], also known as '[vampiredatum.return_full_name()]', [vampiredatum.my_clan ? "is part of the [vampiredatum.my_clan]!" : "is not part of a clan."] You quickly note this information down, memorizing it.")) + user.log_message("used [src] to break [key_name(target)]'s masquerade.", LOG_ATTACK, color = "red") + target.log_message("had their masquerade broken by [key_name(user)] with [src].", LOG_VICTIM, color = "orange", log_globally = FALSE) + vampiredatum.break_masquerade() + else + to_chat(user, span_notice("You fail to draw any conclusions to [target] being a Vampire.")) + return ITEM_INTERACT_SUCCESS + +/obj/item/book/kindred/ranged_interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers) + return interact_with_atom(interacting_with, user, modifiers) + +/obj/item/book/kindred/attack_self(mob/living/user) + if(!IS_VAMPIRE_HUNTER(user)) + if(IS_VAMPIRE(user)) + to_chat(user, span_notice("[src] seems to be too complicated for you. It would be best to leave this for someone else to take.")) + else + to_chat(user, span_warning("You feel your eyes unable to read the boring texts...")) + return + ui_interact(user) + +/obj/item/book/kindred/ui_interact(mob/living/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "KindredBook", name) + ui.set_autoupdate(FALSE) + ui.open() + +/obj/item/book/kindred/ui_static_data(mob/user) + . = list("clans" = list()) + + for(var/datum/vampire_clan/clan as anything in subtypesof(/datum/vampire_clan)) + .["clans"] += list(list( + "name" = clan::name, + "desc" = clan::description, + )) + + +/obj/item/book/codex_gigas/Initialize(mapload) + . = ..() + if(mapload && !(locate(/obj/item/book/kindred) in loc)) + new /obj/item/book/kindred(loc) diff --git a/tff_modular/modules/vampire/objects/umbrellas.dm b/tff_modular/modules/vampire/objects/umbrellas.dm new file mode 100644 index 00000000000..092892e943e --- /dev/null +++ b/tff_modular/modules/vampire/objects/umbrellas.dm @@ -0,0 +1,167 @@ +/* + * # Umbrellas! + * This file has code for umbrellas! + * Umbrellas you can hold, and open and close. + * Currently not coding for protecting against rain as ???I dont think??? rain exists. + * The rest don't and it just for looks. + */ +/obj/item/umbrella + name = "umbrella" + desc = "A plain umbrella." + icon = 'tff_modular/modules/vampire/icons/umbrellas.dmi' + icon_state = "umbrella" + inhand_icon_state = "umbrella_closed" + lefthand_file = 'tff_modular/modules/vampire/icons/umbrellas_inhand_lh.dmi' + righthand_file = 'tff_modular/modules/vampire/icons/umbrellas_inhand_rh.dmi' + force = 5 + throwforce = 5 + w_class = WEIGHT_CLASS_SMALL + custom_materials = list(/datum/material/iron= SMALL_MATERIAL_AMOUNT * 0.5) + attack_verb_continuous = list("bludgeons", "whacks", "disciplines", "pummels") + attack_verb_simple = list("bludgeon", "whack", "discipline", "pummel") + drop_sound = 'tff_modular/modules/vampire/sound/wooden_drop.ogg' + pickup_sound = 'tff_modular/modules/vampire/sound/wooden_pickup.ogg' + hitsound = 'sound/items/weapons/genhit1.ogg' + + //open umbrella offsets for the inhands + var/open_x_offset = 2 + var/open_y_offset = 2 + + //Whether it's open or not + var/open = FALSE + + /// The sound effect played when our umbrella is opened + var/on_sound = 'sound/items/weapons/batonextend.ogg' + /// The inhand icon state used when our umbrella is opened. + var/on_inhand_icon_state = "umbrella_on" + + //greyscale stuff + greyscale_config = /datum/greyscale_config/umbrella + greyscale_config_inhand_left = /datum/greyscale_config/umbrella_inhand_left + greyscale_config_inhand_right = /datum/greyscale_config/umbrella_inhand_right + greyscale_colors = "#dddddd" + /// If the item should be assigned a random color + var/random_color = TRUE + /// List of possible random colors + var/static/list/umbrella_colors = list( + COLOR_BLUE, + COLOR_RED, + COLOR_PINK, + COLOR_BROWN, + COLOR_GREEN, + COLOR_CYAN, + COLOR_YELLOW, + COLOR_WHITE + ) + flags_1 = IS_PLAYER_COLORABLE_1 + +/obj/item/umbrella/Initialize(mapload) + . = ..() + if(random_color) + set_greyscale(colors = list(pick(umbrella_colors))) + AddComponent( \ + /datum/component/transforming, \ + force_on = 7, \ + hitsound_on = "sound/items/weapons/genhit1.ogg", \ + w_class_on = WEIGHT_CLASS_BULKY, \ + clumsy_check = FALSE, \ + attack_verb_continuous_on = list("swooshes", "whacks", "fwumps"), \ + attack_verb_simple_on = list("swoosh", "whack", "fwump"), \ + ) + RegisterSignal(src, COMSIG_TRANSFORMING_ON_TRANSFORM, PROC_REF(on_transform)) + +/obj/item/umbrella/worn_overlays(mutable_appearance/standing, isinhands) + . = ..() + if(!isinhands) + return + var/mob/holder = loc + if(open) + if(ISODD(holder.get_held_index_of_item(src))) //left hand or right hand? + . += mutable_appearance(lefthand_file, inhand_icon_state + "_BACK", BELOW_MOB_LAYER) + else + . += mutable_appearance(righthand_file, inhand_icon_state + "_BACK", BELOW_MOB_LAYER) + + +/obj/item/umbrella/proc/on_transform(obj/item/source, mob/user, active) + SIGNAL_HANDLER + inhand_icon_state = active ? on_inhand_icon_state : inhand_icon_state + open = active + if(user) + balloon_alert(user, active ? "opened" : "closed") + if(active) + ADD_TRAIT(user, TRAIT_SHADED, REF(src)) + else + REMOVE_TRAIT(user, TRAIT_SHADED, REF(src)) + playsound(src, on_sound, 50, TRUE) + return COMPONENT_NO_DEFAULT_MESSAGE + +/obj/item/umbrella/pickup(mob/user) + . = ..() + RegisterSignal(user, COMSIG_ATOM_DIR_CHANGE, PROC_REF(on_dir_change)) + if(open) + ADD_TRAIT(user, TRAIT_SHADED, REF(src)) + +/obj/item/umbrella/dropped(mob/user, silent) + . = ..() + REMOVE_TRAIT(user, TRAIT_SHADED, REF(src)) + UnregisterSignal(user, COMSIG_ATOM_DIR_CHANGE) + +/obj/item/umbrella/proc/on_dir_change(mob/living/carbon/owner, olddir, newdir) + SIGNAL_HANDLER + owner.update_held_items() + +/obj/item/umbrella/get_worn_offsets(isinhands) + . = ..() + var/mob/holder = loc + if(open) + .[2] += open_y_offset + switch(loc.dir) + if(NORTH) + .[1] += ISODD(holder.get_held_index_of_item(src)) ? -open_x_offset : open_x_offset + if(SOUTH) + .[1] += ISODD(holder.get_held_index_of_item(src)) ? open_x_offset : -open_x_offset + if(EAST) + .[1] -= open_x_offset + if(WEST) + .[1] += open_x_offset + + + +//other umbrellas + +/obj/item/umbrella/parasol + name = "parasol" + desc = "A black laced parsol, how intricate." + icon_state = "parasol" + inhand_icon_state = "parasol_closed" + on_inhand_icon_state = "parasol_on" + random_color = FALSE + greyscale_config = null + greyscale_config_inhand_left = null + greyscale_config_inhand_right = null + +/datum/greyscale_config/umbrella + name = "Umbrella" + icon_file = 'tff_modular/modules/vampire/icons/umbrellas.dmi' + json_config = 'code/datums/greyscale/json_configs/_umbrella.json' + +/datum/greyscale_config/umbrella_inhand_left + name = "Held Umbrella, Left, Closed" + icon_file = 'tff_modular/modules/vampire/icons/umbrellas_inhand_lh.dmi' + json_config = 'code/datums/greyscale/json_configs/_umbrella_inhand.json' + +/datum/greyscale_config/umbrella_inhand_right + name = "Held Umbrella, Right, Closed" + icon_file = 'tff_modular/modules/vampire/icons/umbrellas_inhand_rh.dmi' + json_config = 'code/datums/greyscale/json_configs/_umbrella_inhand.json' + +/datum/crafting_recipe/umbrella + name = "Umbrella" + result = /obj/item/umbrella + reqs = list( + /obj/item/stack/sheet/cloth = 3, + /obj/item/stack/rods = 1, + ) + tool_behaviors = list(TOOL_CROWBAR) + time = 5 SECONDS + category = CAT_EQUIPMENT diff --git a/tff_modular/modules/vampire/objects/vassal_rack.dm b/tff_modular/modules/vampire/objects/vassal_rack.dm new file mode 100644 index 00000000000..9434624f35c --- /dev/null +++ b/tff_modular/modules/vampire/objects/vassal_rack.dm @@ -0,0 +1,271 @@ +/obj/structure/vampire/vassalrack + name = "vassalization rack" + desc = "If this wasn't meant for torture, then someone has some fairly horrifying hobbies." + icon = 'tff_modular/modules/vampire/icons/vamp_obj.dmi' + icon_state = "vassalrack" + anchored = FALSE + density = TRUE + can_buckle = TRUE + buckle_lying = 180 + ghost_desc = "This is a vassalization rack, which allows vampires to turn crew members into loyal vassals." + vampire_desc = "This is the vassalization rack, which allows you to turn crew members into loyal vassals in your service. This costs blood to do.\n\ + Simply click and hold on a victim, and then drag their sprite onto the vassalization rack. Right-click on the vassalization rack to unbuckle them.\n\ + To convert into a vassal, repeatedly click on the vassalization rack. The time required scales with the tool in your hand." + vassal_desc = "This is the vassalization rack, which allows your master to turn crew members into loyal vassals.\n\ + Aid your master in bringing their victims here and keeping them secure.\n\ + You can secure victims to the vassalization rack by click-dragging the victim onto the rack while it is secured." + curator_desc = "This is the vassalization rack, which monsters use to blood-slave crew members into vassals.\n\ + They usually ensure that victims are handcuffed to prevent them from running away.\n\ + Their rituals take time, allowing us to disrupt them." + + /// How many times a buckled person has to be tortured to be converted. + var/convert_progress = 3 + /// Mindshielded individuals and antagonists must willingly accept you as their master. + var/wants_vassalization = FALSE + /// Prevents popup spam. + var/vassalization_offered = FALSE + /// No spamming torture + var/is_torturing = FALSE + +/obj/structure/vampire/vassalrack/examine(mob/user) + . = ..() + var/datum/antagonist/vampire/vampiredatum = IS_VAMPIRE(user) + if(vampiredatum) + var/remaining_vassals = 4 - vampiredatum.count_vassals() + if(remaining_vassals > 0) + . += span_info("You are currently capable of creating [remaining_vassals] more vassal[remaining_vassals == 1 ? "" : "s"].") + else + . += span_warning("You cannot create any more vassals at the moment!") + +/obj/structure/vampire/vassalrack/deconstruct(disassembled = TRUE) + . = ..() + new /obj/item/stack/sheet/iron(src.loc, 4) + new /obj/item/stack/rods(loc, 4) + qdel(src) + +/obj/structure/vampire/vassalrack/mouse_drop_receive(atom/dropped, mob/user, params) + if(DOING_INTERACTION(user, DOAFTER_SOURCE_PERSUASION_RACK)) + return + var/mob/living/living_target = dropped + if(!anchored && IS_VAMPIRE(user)) + to_chat(user, span_danger("Until this rack is secured in place, it cannot serve its purpose.")) + to_chat(user, span_announce("* Vampire Tip: Examine the vassal rack to understand how it functions!")) + return + // Default checks + if(!isliving(living_target) || !living_target.Adjacent(src) || living_target == user || !isliving(user) || has_buckled_mobs() || user.incapacitated() || living_target.buckled) + return + // Don't buckle Silicon to it please. + if(issilicon(living_target)) + to_chat(user, span_danger("You realize that this machine cannot be vassalized, therefore it is useless to buckle [living_target.p_them()].")) + return + if(do_after(user, 5 SECONDS, living_target, interaction_key = DOAFTER_SOURCE_PERSUASION_RACK)) + set_density(FALSE) + attach_victim(living_target, user) + set_density(TRUE) + +/** + * Attempts to buckle target into the Vassalization Rack + */ +/obj/structure/vampire/vassalrack/proc/attach_victim(mob/living/target, mob/living/user) + if(!buckle_mob(target)) + return + user.visible_message( + span_notice("[user] straps [target] into the rack, immobilizing [target.p_them()]."), + span_boldnotice("You secure [target] tightly in place. [target.p_They()] won't escape you now.")) + + playsound(loc, 'sound/effects/pop_expl.ogg', vol = 25, vary = TRUE) + update_appearance(UPDATE_ICON) + + // Set up Torture stuff now + reset_progress() + +/// Attempt Unbuckle +/obj/structure/vampire/vassalrack/user_unbuckle_mob(mob/living/buckled_mob, mob/user) + if(HAS_MIND_TRAIT(user, TRAIT_VAMPIRE_ALIGNED)) + return ..() + + if(buckled_mob == user) + buckled_mob.visible_message( + span_danger("[user] tries to release [user.p_them()]self from the rack!"), + span_danger("You attempt to release yourself from the rack!"), + span_hear("You hear a squishy wet noise."), + ) + if(!do_after(user, 20 SECONDS, buckled_mob)) + return FALSE + else + buckled_mob.visible_message( + span_danger("[user] tries to pull [buckled_mob] from the rack!"), + span_danger("You attempt to release [buckled_mob] from the rack!"), + span_hear("You hear a squishy wet noise."), + ) + if(!do_after(user, 10 SECONDS, buckled_mob)) + return FALSE + + return ..() + +/obj/structure/vampire/vassalrack/post_unbuckle_mob(mob/living/unbuckled_mob) + visible_message(span_danger("[unbuckled_mob][unbuckled_mob.stat == DEAD ? "'s corpse" : ""] slides off of the rack.")) + unbuckled_mob.Paralyze(2 SECONDS) + update_appearance(UPDATE_ICON) + reset_progress() + +/obj/structure/vampire/vassalrack/attack_hand(mob/user, list/modifiers) + . = ..() + if(!. || !has_buckled_mobs() || DOING_INTERACTION(user, DOAFTER_SOURCE_PERSUASION_RACK)) + return FALSE + + var/datum/antagonist/vampire/vampiredatum = IS_VAMPIRE(user) + var/mob/living/carbon/buckled_person = pick(buckled_mobs) + + // oh no let me free this poor soul + if(!vampiredatum) + user_unbuckle_mob(buckled_person, user) + return TRUE + + var/obj/item/held_item = user.get_inactive_held_item() + try_to_torture(user, buckled_person, held_item) + +/obj/structure/vampire/vassalrack/attack_hand_secondary(mob/user, list/modifiers) + . = ..() + if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN) + return + if(!has_buckled_mobs() || !isliving(user) || DOING_INTERACTION(user, DOAFTER_SOURCE_PERSUASION_RACK)) + return + var/mob/living/carbon/buckled_carbons = pick(buckled_mobs) + if(buckled_carbons) + if(user == owner.current) + unbuckle_mob(buckled_carbons) + else + user_unbuckle_mob(buckled_carbons, user) + +/obj/structure/vampire/vassalrack/attackby(obj/item/attacking_item, mob/living/user, params) + if(IS_VAMPIRE(user) && has_buckled_mobs()) + return try_to_torture(user, pick(buckled_mobs), attacking_item) + return ..() + +/** + * Torture steps: + * + * * When convert_progress reaches 0, the victim is ready to be converted + * * Using a better tool will reduce the time required to torture + * * If the victim has a mindshield or is an antagonist, they must accept the conversion. If they don't accept, they aren't converted + * * vassalize target + */ +/obj/structure/vampire/vassalrack/proc/try_to_torture(mob/living/living_vampire, mob/living/living_target, obj/item/held_item) + if(DOING_INTERACTION(living_vampire, DOAFTER_SOURCE_PERSUASION_RACK)) + return + + if(vassalization_offered) + balloon_alert(living_vampire, "wait a moment!") + return + + var/datum/antagonist/vampire/vampiredatum = IS_VAMPIRE(living_vampire) + + if(!vampiredatum.can_make_vassal(living_target) || is_torturing) + return + + // These if statements can be simplified but aren't for better code-readability. + if(convert_progress > 0) + balloon_alert(living_vampire, "spilling blood...") + + is_torturing = TRUE + living_target.Paralyze(1 SECONDS) + vampiredatum.adjust_blood_volume(-TORTURE_BLOOD_HALF_COST) + + if(!do_torture(living_vampire, living_target, held_item)) + is_torturing = FALSE + return + is_torturing = FALSE + + vampiredatum.adjust_blood_volume(-TORTURE_BLOOD_HALF_COST) + convert_progress-- + + if(convert_progress > 0) + balloon_alert(living_vampire, "needs more persuasion...") + return + + // If the victim is mindshielded or an antagonist, they choose to accept or refuse vassilization. + if(!wants_vassalization && (HAS_TRAIT(living_target, TRAIT_MINDSHIELD) || living_target.is_antag())) + balloon_alert(living_vampire, "has external loyalties! more persuasion required!") + if(!ask_for_vassalization(living_vampire, living_target)) + balloon_alert(living_vampire, "refused persuasion!") + convert_progress++ + return + + balloon_alert(living_vampire, "ready for communion!") + return + + if(wants_vassalization || !(HAS_TRAIT(living_target, TRAIT_MINDSHIELD) || living_target.is_antag())) + living_vampire.balloon_alert_to_viewers("smears blood...", "paints bloody marks...") + if(!do_after(living_vampire, 5 SECONDS, living_target, interaction_key = DOAFTER_SOURCE_PERSUASION_RACK)) + balloon_alert(living_vampire, "interrupted!") + return + + // Make our target into a vassal + vampiredatum.adjust_blood_volume(-TORTURE_CONVERSION_COST) + if(vampiredatum.make_vassal(living_target)) + // We've made a vassal the proper way, do clan stuff + vampiredatum.my_clan?.on_vassal_made(living_vampire, living_target) + vampiredatum.rank_up(1, ignore_reqs = TRUE) + remove_loyalties(living_target) + +/obj/structure/vampire/vassalrack/proc/do_torture(mob/living/user, mob/living/carbon/target, obj/item/held_item) + var/torture_time = 15 + torture_time -= held_item?.force / 4 + torture_time -= held_item?.sharpness + 1 + + // Minimum 5 seconds + torture_time = max(5 SECONDS, torture_time SECONDS) + if(do_after(user, torture_time, target, interaction_key = DOAFTER_SOURCE_PERSUASION_RACK)) + held_item?.play_tool_sound(target) + + var/obj/item/bodypart/selected_bodypart = pick(target.bodyparts) + target.visible_message( + span_danger("[user] performs a ritual, spilling some of [target]'s blood from [target.p_their()] [selected_bodypart.name]!"), + span_userdanger("[user] performs a ritual, spilling some blood from your [selected_bodypart.name]!")) + + INVOKE_ASYNC(target, TYPE_PROC_REF(/mob, emote), "scream") + target.set_jitter_if_lower(10 SECONDS) + target.apply_damage(held_item ? held_item.force / 4 : 2, held_item ? held_item.damtype : BRUTE, selected_bodypart) + return TRUE + else + balloon_alert(user, "interrupted!") + return FALSE + +/// Offer them the oppertunity to join now. +/obj/structure/vampire/vassalrack/proc/ask_for_vassalization(mob/living/user, mob/living/target) + if(vassalization_offered) + balloon_alert(user, "wait a moment!") + return FALSE + vassalization_offered = TRUE + + to_chat(user, span_notice("[target] has been given the opportunity for servitude. You await [target.p_their()] decision...")) + var/alert_response = tgui_alert( + user = target, \ + message = "You are being tortured! Do you want to give in and pledge your undying loyalty to [user]? \n\ + You will not lose your current objectives, but they come second to the will of your new master!", \ + title = "THE HORRIBLE PAIN! WHEN WILL IT END?!", + buttons = list("Accept", "Refuse"), + timeout = 15 SECONDS, \ + autofocus = TRUE + ) + if(alert_response == "Accept") + wants_vassalization = TRUE + else + target.balloon_alert_to_viewers("refused vassalization!") + + vassalization_offered = FALSE + + return wants_vassalization + +/obj/structure/vampire/vassalrack/proc/reset_progress() + convert_progress = initial(convert_progress) + wants_vassalization = initial(wants_vassalization) + vassalization_offered = initial(vassalization_offered) + is_torturing = initial(is_torturing) + +/obj/structure/vampire/vassalrack/proc/remove_loyalties(mob/living/target) + // Find Mind Implant & Destroy + for(var/obj/item/implant/implant as anything in target.implants) + if(istype(implant, /obj/item/implant/mindshield) && implant.removed(target, silent = TRUE)) + qdel(implant) diff --git a/tff_modular/modules/vampire/oozeling_vampire.dm b/tff_modular/modules/vampire/oozeling_vampire.dm new file mode 100644 index 00000000000..5c2a79ca345 --- /dev/null +++ b/tff_modular/modules/vampire/oozeling_vampire.dm @@ -0,0 +1,91 @@ +/* +// Oozeling vampires have some unique behavior, so I'm just gonna stick it all in this one file. + +/// Handles setting up self-revival when an oozeling vampire dies. +/datum/antagonist/vampire/proc/on_oozeling_core_ejected(datum/source, obj/item/organ/internal/brain/slime/core) + SIGNAL_HANDLER + if(QDELETED(core) || final_death) + return + ADD_TRAIT(core, TRAIT_NO_ORGAN_DECAY, TRAIT_VAMPIRE) + if(current_vitae < OOZELING_MIN_REVIVE_BLOOD_THRESHOLD) + to_chat(core.brainmob, span_narsiesmall("You do not have enough vitae to recollect yourself on your own!"), type = MESSAGE_TYPE_WARNING) + return + adjust_blood_volume(-OOZELING_MIN_REVIVE_BLOOD_THRESHOLD * 0.5) + to_chat(core.brainmob, span_narsiesmall("You begin recollecting yourself. You will rise again soon, if your core remains undisturbed."), type = MESSAGE_TYPE_INFO) + new /datum/vampire_oozeling_reviver(src, core) + +/// Heals an oozeling vampire's organs when they revive. +/datum/antagonist/vampire/proc/on_oozeling_revive(datum/source, mob/living/carbon/human/new_body, obj/item/organ/internal/brain/slime/core) + SIGNAL_HANDLER + REMOVE_TRAIT(core, TRAIT_NO_ORGAN_DECAY, TRAIT_VAMPIRE) + heal_vampire_organs() + +/datum/antagonist/vampire/proc/oozeling_self_revive(obj/item/organ/internal/brain/slime/core) + if(QDELETED(core) || final_death) + return + var/mob/living/carbon/human/new_body = core.rebuild_body(nugget = FALSE, revival_policy = POLICY_ANTAGONISTIC_REVIVAL) + to_chat(new_body, span_cult_large("You recollect yourself, your vitae reforming your body from your core!"), type = MESSAGE_TYPE_INFO) + +/// Stupid datum used for, to avoid a bunch of oozeling-specific vars on the vampire datum +/datum/vampire_oozeling_reviver + /// The parent vampire antag datum. + var/datum/antagonist/vampire/vampire + /// The oozeling core we're reviving. + var/obj/item/organ/brain/core + /// Progress ticker used for reviving. + var/oozeling_revival_progress = OOZELING_VAMPIRE_REVIVE_TIME + /// The last world.time where we processed. + var/last_process + /// Cooldown for sending a chat message to the oozeling player how long until they revive. + COOLDOWN_DECLARE(reminder_cooldown) + +/datum/vampire_oozeling_reviver/New(datum/antagonist/vampire/vampire, obj/item/organ/internal/brain/slime/core) + src.vampire = vampire + src.core = core + src.last_process = world.time + RegisterSignal(core, COMSIG_QDELETING, PROC_REF(delete_self)) + RegisterSignal(vampire.owner, COMSIG_OOZELING_REVIVED, PROC_REF(delete_self)) + START_PROCESSING(SSfastprocess, src) + +/datum/vampire_oozeling_reviver/Destroy(force) + UnregisterSignal(core, COMSIG_QDELETING) + UnregisterSignal(vampire.owner, COMSIG_OOZELING_REVIVED) + STOP_PROCESSING(SSfastprocess, src) + vampire = null + core = null + return ..() + +/datum/vampire_oozeling_reviver/proc/delete_self() + SIGNAL_HANDLER + if(!QDELETED(src)) + qdel(src) + +/datum/vampire_oozeling_reviver/proc/progress_multiplier() + . = 1 + if(HAS_TRAIT(core, TRAIT_BEINGSTAKED)) + return 0 + if(istype(core.loc, /obj/structure/closet/crate/coffin)) + return OOZELING_VAMPIRE_REVIVE_COFFIN_MULTIPLIER + else + var/mob/living/holder = get(core, /mob/living) + if(!QDELETED(holder)) + if(HAS_MIND_TRAIT(holder, TRAIT_VAMPIRE_ALIGNED)) + return OOZELING_VAMPIRE_REVIVE_ALLY_MULTIPLIER + else + return OOZELING_VAMPIRE_REVIVE_HELD_MULTIPLIER + +/datum/vampire_oozeling_reviver/process(seconds_per_tick) + if(QDELETED(core) || !core.core_ejected || vampire.final_death) + delete_self() + return + oozeling_revival_progress -= (world.time - last_process) * progress_multiplier() + last_process = world.time + if(oozeling_revival_progress <= 0) + vampire.oozeling_self_revive(core) + delete_self() + else if(COOLDOWN_FINISHED(src, reminder_cooldown)) + var/progress = round((1 - (oozeling_revival_progress / OOZELING_VAMPIRE_REVIVE_TIME)) * 100, 1) + to_chat(core.brainmob, span_cult_large("Your vitae coagulates... You are approximately [progress]% reformed."), type = MESSAGE_TYPE_INFO) + core.balloon_alert(core.brainmob, "[progress]% reformed...") + COOLDOWN_START(src, reminder_cooldown, 15 SECONDS) +*/ diff --git a/tff_modular/modules/vampire/powers/_power.dm b/tff_modular/modules/vampire/powers/_power.dm new file mode 100644 index 00000000000..7cb3994579e --- /dev/null +++ b/tff_modular/modules/vampire/powers/_power.dm @@ -0,0 +1,244 @@ +/datum/action/cooldown/vampire + name = "Vampiric Gift" + desc = "A vampiric gift." + background_icon = 'tff_modular/modules/vampire/icons/actions_vampire.dmi' + background_icon_state = "vamp_power_off" + button_icon = 'tff_modular/modules/vampire/icons/actions_vampire.dmi' + button_icon_state = "power_feed" + buttontooltipstyle = "cult" + transparent_when_unavailable = TRUE + + /// Cooldown you'll have to wait between each use, decreases depending on level. + cooldown_time = 2 SECONDS + + active_background_icon_state = "vamp_power_on" + base_background_icon_state = "vamp_power_off" + + /// A sort of tutorial text found in the Antagonist tab. + var/power_explanation = "Use this power to do... something" + /// The owner's vampire datum + var/datum/antagonist/vampire/vampiredatum_power + + /// The effects on this Power (Toggled/Single Use/Static Cooldown) + var/vampire_power_flags = BP_AM_TOGGLE | BP_AM_SINGLEUSE | BP_AM_STATIC_COOLDOWN | BP_AM_COSTLESS_UNCONSCIOUS + /// Vampire-specific requirement flags for checks + var/vampire_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 + + // Special flags you can give to powers. Mainly used for any powers we want them to have by default, so, feed. + var/special_flags = NONE + /// If the Power is currently active, differs from action cooldown because of how powers are handled. + var/currently_active = FALSE + ///Can increase to yield new abilities + var/level_current = 1 + ///The cost to ACTIVATE this Power + var/vitaecost = 0 + ///The cost to MAINTAIN this Power Only used for constant powers + var/constant_vitaecost = 0 + + ///The upgraded version of this Power. 'null' means it's the max level. + var/upgraded_power = null + +// Modify description to add cost. +/datum/action/cooldown/vampire/New(Target) + . = ..() + update_desc() + +/datum/action/cooldown/vampire/Destroy() + vampiredatum_power = null + return ..() + +/datum/action/cooldown/vampire/Grant(mob/user) + . = ..() + var/datum/antagonist/vampire/vampiredatum = IS_VAMPIRE(owner) + if(vampiredatum) + vampiredatum_power = vampiredatum + + if(vampire_check_flags & BP_CANT_USE_IN_TORPOR) + RegisterSignals(owner, list(SIGNAL_ADDTRAIT(TRAIT_TORPOR), SIGNAL_REMOVETRAIT(TRAIT_TORPOR)), PROC_REF(update_status_on_signal)) + if(vampire_check_flags & BP_CANT_USE_IN_FRENZY) + RegisterSignals(owner, list(SIGNAL_ADDTRAIT(TRAIT_FRENZY), SIGNAL_REMOVETRAIT(TRAIT_FRENZY)), PROC_REF(update_status_on_signal)) + if(vampire_check_flags & BP_CANT_USE_WHILE_INCAPACITATED) + RegisterSignals(owner, list(SIGNAL_ADDTRAIT(TRAIT_INCAPACITATED), SIGNAL_REMOVETRAIT(TRAIT_INCAPACITATED)), PROC_REF(update_status_on_signal)) + if(vampire_check_flags & BP_CANT_USE_WHILE_UNCONSCIOUS) + RegisterSignal(owner, COMSIG_MOB_STATCHANGE, PROC_REF(update_status_on_signal)) + +/datum/action/cooldown/vampire/Remove(mob/removed_from) + if(owner) + UnregisterSignal(owner, list( + COMSIG_MOB_STATCHANGE, + SIGNAL_ADDTRAIT(TRAIT_TORPOR), + SIGNAL_ADDTRAIT(TRAIT_FRENZY), + SIGNAL_ADDTRAIT(TRAIT_INCAPACITATED), + SIGNAL_REMOVETRAIT(TRAIT_TORPOR), + SIGNAL_REMOVETRAIT(TRAIT_FRENZY), + SIGNAL_REMOVETRAIT(TRAIT_INCAPACITATED), + )) + return ..() + +/datum/action/cooldown/vampire/is_action_active(atom/movable/screen/movable/action_button/current_button) + if(currently_active) + return TRUE + return ..() + +//This is when we CLICK on the ability Icon, not USING. +/datum/action/cooldown/vampire/Activate(atom/target) + if(currently_active) + deactivate_power() + return FALSE + if(!can_pay_cost() || !can_use()) + return FALSE + pay_cost() + activate_power() + if(!(vampire_power_flags & BP_AM_TOGGLE) || !currently_active) + StartCooldown() + + return TRUE + +/datum/action/cooldown/vampire/proc/update_desc() + desc = initial(desc) + if(vitaecost > 0) + desc += "

    COST: [vitaecost] Blood" + if(constant_vitaecost > 0) + desc += "

    CONSTANT COST: [constant_vitaecost] Blood." + if(vampire_power_flags & BP_AM_SINGLEUSE) + desc += "

    SINGLE USE:
    Can only be used once per night." + +/datum/action/cooldown/vampire/proc/can_pay_cost() + if(QDELETED(owner)) + return FALSE + + // Check if we have enough blood for non-vampires + if(!vampiredatum_power) + var/mob/living/living_owner = owner + if(!HAS_TRAIT(living_owner, TRAIT_NOBLOOD) && living_owner.blood_volume < vitaecost) + living_owner.balloon_alert(living_owner, "not enough blood.") + return FALSE + + return TRUE + + // Have enough blood? Vampires in a Frenzy don't need to pay them + if(HAS_TRAIT(owner, TRAIT_FRENZY)) + return TRUE + if(vampiredatum_power.current_vitae < vitaecost) + owner.balloon_alert(owner, "not enough blood.") + return FALSE + + return TRUE + +///Checks if the Power is available to use. +/datum/action/cooldown/vampire/proc/can_use() + if(!iscarbon(owner)) + return FALSE + var/mob/living/carbon/carbon_owner = owner + + // Torpor? + if((vampire_check_flags & BP_CANT_USE_IN_TORPOR) && HAS_TRAIT(carbon_owner, TRAIT_TORPOR)) + to_chat(carbon_owner, span_warning("Not while you're in Torpor.")) + return FALSE + // Frenzy? + if((vampire_check_flags & BP_CANT_USE_IN_FRENZY) && HAS_TRAIT(carbon_owner, TRAIT_FRENZY)) + to_chat(carbon_owner, span_warning("You cannot use powers while in a Frenzy!")) + return FALSE + // Stake? + if((vampire_check_flags & BP_CANT_USE_WHILE_STAKED) && vampiredatum_power?.check_if_staked()) + to_chat(carbon_owner, span_warning("You have a stake in your chest! Your powers are useless.")) + return FALSE + // Conscious? -- We use our own (AB_CHECK_CONSCIOUS) here so we can control it more, like the error message. + if((vampire_check_flags & BP_CANT_USE_WHILE_UNCONSCIOUS) && carbon_owner.stat != CONSCIOUS) + to_chat(carbon_owner, span_warning("You can't do this while you are unconcious!")) + return FALSE + // Incapacitated? + if((vampire_check_flags & BP_CANT_USE_WHILE_INCAPACITATED) && carbon_owner.IsUnconscious()) + to_chat(carbon_owner, span_warning("Not while you're incapacitated!")) + return FALSE + // Constant Cost (out of blood) + if(constant_vitaecost > 0 && vampiredatum_power?.current_vitae <= 0) + to_chat(carbon_owner, span_warning("You don't have the blood to upkeep [src].")) + return FALSE + return TRUE + +/datum/action/cooldown/vampire/proc/pay_cost() + // Vassals get powers too! + if(!vampiredatum_power) + var/mob/living/living_owner = owner + if(!HAS_TRAIT(living_owner, TRAIT_NOBLOOD)) + living_owner.blood_volume -= vitaecost + return + + // Vampires in a Frenzy don't have enough Blood to pay it, so just don't. + if(!HAS_TRAIT(owner, TRAIT_FRENZY)) + vampiredatum_power.current_vitae -= vitaecost + vampiredatum_power.update_hud() + +/datum/action/cooldown/vampire/proc/activate_power() + currently_active = TRUE + if(vampire_power_flags & BP_AM_TOGGLE) + RegisterSignal(owner, COMSIG_LIVING_LIFE, PROC_REF(use_power)) + + owner.log_message("used [src][vitaecost != 0 ? " at the cost of [vitaecost]" : ""].", LOG_ATTACK, color="red") + build_all_button_icons(UPDATE_BUTTON_NAME | UPDATE_BUTTON_BACKGROUND) + +/datum/action/cooldown/vampire/proc/deactivate_power() + if(!currently_active) //Already inactive? Return + return + + if(vampire_power_flags & BP_AM_TOGGLE) + UnregisterSignal(owner, COMSIG_LIVING_LIFE) + if(vampire_power_flags & BP_AM_SINGLEUSE) + remove_after_use() + return + + currently_active = FALSE + StartCooldown() + build_all_button_icons(UPDATE_BUTTON_NAME | UPDATE_BUTTON_BACKGROUND) + +/// Used by powers that are continuously active (That have BP_AM_TOGGLE flag) +/datum/action/cooldown/vampire/proc/use_power() + if(!continue_active()) // We can't afford the Power? Deactivate it. + deactivate_power() + return FALSE + + // IF USER IS UNCONSCIOUS + if((vampire_power_flags & BP_AM_COSTLESS_UNCONSCIOUS) && owner.stat != CONSCIOUS) + return TRUE + else + if(vampiredatum_power) + vampiredatum_power.adjust_blood_volume(-constant_vitaecost) + else + var/mob/living/living_owner = owner + if(!HAS_TRAIT(living_owner, TRAIT_NOBLOOD)) + living_owner.blood_volume = max(living_owner.blood_volume - constant_vitaecost, 0) + return TRUE + +/// Checks to make sure this power can stay active +/datum/action/cooldown/vampire/proc/continue_active() + if(QDELETED(owner)) + return FALSE + if(vampiredatum_power && vampiredatum_power.current_vitae < constant_vitaecost) + return FALSE + + return TRUE + +/// Used to unlearn Single-Use Powers +/datum/action/cooldown/vampire/proc/remove_after_use() + vampiredatum_power?.powers -= src + Remove(owner) + +// If there's a mortal in line of sight, we get a masq infraction +/datum/action/cooldown/vampire/proc/check_witnesses(mob/living/target) + var/turf/our_turf = get_turf(owner) + var/turf/target_turf = get_turf(target) + var/min_darkness = target_turf ? min(GET_SIMPLE_LUMCOUNT(our_turf), GET_SIMPLE_LUMCOUNT(target_turf)) : GET_SIMPLE_LUMCOUNT(our_turf) + var/is_dark = min_darkness <= 0.2 + for(var/mob/living/watcher in oviewers(6, owner) - target) + if(!vampiredatum_power.is_masq_watcher(watcher)) + continue + if(is_dark && !watcher.Adjacent(owner) && (!target || !watcher.Adjacent(target))) + continue + if(!watcher.incapacitated(IGNORE_RESTRAINTS)) + watcher.face_atom(owner) + + watcher.do_alert_animation(watcher) + playsound(watcher, 'sound/machines/chime.ogg', 50, FALSE, -5) + vampiredatum_power.give_masquerade_infraction() + break diff --git a/tff_modular/modules/vampire/powers/_targeted.dm b/tff_modular/modules/vampire/powers/_targeted.dm new file mode 100644 index 00000000000..273d1813b56 --- /dev/null +++ b/tff_modular/modules/vampire/powers/_targeted.dm @@ -0,0 +1,111 @@ +// NOTE: All Targeted spells are Toggles! We just don't bother checking here. +/datum/action/cooldown/vampire/targeted + vampire_power_flags = BP_AM_TOGGLE + + ///If set, how far the target has to be for the power to work. + var/target_range + ///Message sent to chat when clicking on the power, before you use it. + var/prefire_message + ///Most powers happen the moment you click. Some, like Mesmerize, require time and shouldn't cost you if they fail. + var/power_activates_immediately = TRUE + ///Is this power LOCKED due to being used? + var/power_in_use = FALSE + +/// Modify description to add notice that this is aimed. +/datum/action/cooldown/vampire/targeted/update_desc() + . = ..() + desc += "

    Targeted Power" + +/datum/action/cooldown/vampire/targeted/Activate(atom/target) + if(currently_active) + deactivate_power() + return FALSE + if(owner.click_intercept) + owner.balloon_alert(owner, "already using a targeted power!") + return FALSE + if(!can_pay_cost(owner) || !can_use()) + return FALSE + + if(prefire_message) + to_chat(owner, span_announce(prefire_message)) + + activate_power() + + if(currently_active) + set_click_ability(owner) + +/datum/action/cooldown/vampire/targeted/Remove(mob/removed_from) + if(removed_from?.click_intercept == src) + unset_click_ability(removed_from, refund_cooldown = FALSE) + return ..() + +/datum/action/cooldown/vampire/targeted/activate_power() + currently_active = TRUE + + owner.log_message("used [src][vitaecost != 0 ? " at the cost of [vitaecost]" : ""].", LOG_ATTACK, color="red") + build_all_button_icons(UPDATE_BUTTON_NAME | UPDATE_BUTTON_BACKGROUND) + +/datum/action/cooldown/vampire/targeted/deactivate_power(successful = FALSE) + if(vampire_power_flags & BP_AM_TOGGLE) + UnregisterSignal(owner, COMSIG_LIVING_LIFE) + + if((vampire_power_flags & BP_AM_SINGLEUSE) && successful) + remove_after_use() + return + + currently_active = FALSE + build_all_button_icons(UPDATE_BUTTON_NAME | UPDATE_BUTTON_BACKGROUND) + unset_click_ability(owner) + + + +/// Check if target is VALID (wall, turf, or character?) +/datum/action/cooldown/vampire/targeted/proc/check_valid_target(atom/target_atom) + // No targeting yourself + if(target_atom == owner) + return FALSE + // Check if in range + if(target_range && !(target_atom in view(target_range, owner))) + if(target_range > 1) + owner.balloon_alert(owner, "out of range.") + return FALSE + + return TRUE + +/datum/action/cooldown/vampire/targeted/InterceptClickOn(mob/living/user, params, atom/target) + INVOKE_ASYNC(src, PROC_REF(click_with_power), target) + return TRUE + +/// Click Target +/datum/action/cooldown/vampire/targeted/proc/click_with_power(atom/target_atom) + // Already using? + if(power_in_use) + return + // Can use? + if(!can_use()) + return + // Valid target? + if(!check_valid_target(target_atom)) + return + // Enough blood? + if(!can_pay_cost()) + return + + power_in_use = TRUE + fire_targeted_power(target_atom) + if(vampire_power_flags & BP_AM_TOGGLE) + RegisterSignal(owner, COMSIG_LIVING_LIFE, PROC_REF(use_power)) + // Skip this part so we can return TRUE right away. + if(power_activates_immediately) + power_activated_sucessfully() // Mesmerize pays only after success. + power_in_use = FALSE + +/datum/action/cooldown/vampire/targeted/proc/fire_targeted_power(atom/target_atom) + unset_click_ability(owner) + log_combat(owner, target_atom, "used [name] on") + +/// The power went off! We now pay the cost of the power. +/datum/action/cooldown/vampire/targeted/proc/power_activated_sucessfully() + pay_cost() + StartCooldown() + deactivate_power(TRUE) diff --git a/tff_modular/modules/vampire/powers/auspex/astral_project.dm b/tff_modular/modules/vampire/powers/auspex/astral_project.dm new file mode 100644 index 00000000000..ba4dced2182 --- /dev/null +++ b/tff_modular/modules/vampire/powers/auspex/astral_project.dm @@ -0,0 +1,25 @@ +/datum/action/cooldown/vampire/astral_projection + name = "Astral Projection" + desc = "The power of your blood empowers your auspex. Become able to project your consciousness outside your body." + power_explanation = "When Activated, you will become a ghost.\n\ + Visit anywhere you like, watch anyone you want.\n\ + Talk to the spriits, and know all things." + active_background_icon_state = "tremere_power_gold_on" + base_background_icon_state = "tremere_power_gold_off" + button_icon_state = "power_astral_projection" + vampire_power_flags = BP_AM_TOGGLE + vampire_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 + vitaecost = 400 + cooldown_time = 60 SECONDS + +/datum/action/cooldown/vampire/astral_projection/activate_power() + . = ..() + owner.playsound_local(null, 'tff_modular/modules/vampire/sound/auspex.ogg', 50, TRUE, pressure_affected = FALSE) + var/mob/dead/observer/ghost = owner.ghostize(can_reenter_corpse = TRUE) + ADD_TRAIT(ghost, TRAIT_NO_OBSERVE, TRAIT_VAMPIRE) + ghost.add_atom_colour(COLOR_VOID_PURPLE, ADMIN_COLOUR_PRIORITY) + var/ghost_name = "Astral Shade of [ghost.name]" + ghost.name = ghost_name + ghost.deadchat_name = ghost_name + ghost.add_filter("astral_projection", 1, outline_filter(size = 1, color = LIGHT_COLOR_BLOOD_MAGIC)) + deactivate_power() diff --git a/tff_modular/modules/vampire/powers/auspex/auspex.dm b/tff_modular/modules/vampire/powers/auspex/auspex.dm new file mode 100644 index 00000000000..87f60efbea7 --- /dev/null +++ b/tff_modular/modules/vampire/powers/auspex/auspex.dm @@ -0,0 +1,143 @@ +/datum/discipline/auspex + name = "Auspex" + discipline_explanation = "Auspex is a Discipline that grants vampires supernatural senses, letting them peer far further and see things best left unseen.\n\ + The malkavians especially have a bond with it, being seers at heart." + icon_state = "auspex" + + // Lists of abilities granted per level + level_1 = list(/datum/action/cooldown/vampire/auspex) + level_2 = list(/datum/action/cooldown/vampire/auspex/two) + level_3 = list(/datum/action/cooldown/vampire/auspex/three) + level_4 = list(/datum/action/cooldown/vampire/auspex/four) + +/datum/discipline/auspex/malkavian + level_5 = list(/datum/action/cooldown/vampire/auspex/four, /datum/action/cooldown/vampire/astral_projection) + +/** + * # Auspex + * + * Level 1 - Raise sightrange by 2, project sight 2 tiles ahead. + * Level 2 - Raise sightrange by 3, project sight 4 tiles ahead. Meson Vision + * Level 3 - Raise sightrange by 5, project sight 6 tiles ahead. + * Level 4 - Raise sightrange by 7, project sight 8 tiles ahead. Xray Vision + * Level 5 - For Malkavians: Gain ability to astral project like a wizard. + */ +/datum/action/cooldown/vampire/auspex + name = "Auspex" + desc = "Sense the vitae of any creature directly, and use your keen senses to widen your perception." + button_icon_state = "power_auspex" + power_explanation = "- Level 1: When Activated, you will see further. \n\ + - Level 2: When Activated, you will see further, be able to sense walls and the layout of rooms, and, upon examining a fellow Kindred, be able to tell if they have committed Diablerie. \n\ + - Level 3: When Activated, You still have meson vision, same as level 3, but even more range. \n\ + - Level 4: When Activated, you will see further, and be able to sense anything in sight, seeing through walls and barriers as if they were glass." + vampire_power_flags = BP_AM_TOGGLE | BP_AM_STATIC_COOLDOWN + vampire_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 + vitaecost = 50 + constant_vitaecost = 1 + cooldown_time = 10 SECONDS + var/add_meson = FALSE + var/add_xray = FALSE + var/zoom_out_amt = 2 + var/zoom_amt = 6 + var/see_diablerie = FALSE + + + var/looking = FALSE + var/mob/listening_to + +/datum/action/cooldown/vampire/auspex/two + name = "Auspex" + vitaecost = 40 + constant_vitaecost = 2 + zoom_out_amt = 4 + zoom_amt = 7 + add_meson = TRUE + see_diablerie = TRUE + +/datum/action/cooldown/vampire/auspex/three + name = "Auspex" + vitaecost = 30 + constant_vitaecost = 3 + zoom_out_amt = 6 + zoom_amt = 8 + add_meson = TRUE + see_diablerie = TRUE + +/datum/action/cooldown/vampire/auspex/four + name = "Auspex" + vitaecost = 20 + constant_vitaecost = 4 + zoom_out_amt = 10 + zoom_amt = 10 + add_xray = TRUE + see_diablerie = TRUE + +/datum/action/cooldown/vampire/auspex/activate_power() + . = ..() + if(!looking) + lookie() + +/datum/action/cooldown/vampire/auspex/deactivate_power() + . = ..() + if(looking) + unlooky() + +/datum/action/cooldown/vampire/auspex/proc/lookie() + SIGNAL_HANDLER + + if(!listening_to) + RegisterSignals(owner, list(COMSIG_MOVABLE_MOVED, COMSIG_MOB_LOGOUT), PROC_REF(deactivate_power)) + RegisterSignal(owner, COMSIG_ATOM_POST_DIR_CHANGE, PROC_REF(lookie)) + listening_to = owner + var/client/client = owner?.client + if(!client) + return + var/_x = 0 + var/_y = 0 + switch(owner.dir) + if(NORTH) + _y = zoom_amt + if(EAST) + _x = zoom_amt + if(SOUTH) + _y = -zoom_amt + if(WEST) + _x = -zoom_amt + + client?.change_view(get_zoomed_view(world.view, zoom_out_amt)) + client?.pixel_x = ICON_SIZE_X * _x + client?.pixel_y = ICON_SIZE_Y * _y + looking = TRUE + + if(see_diablerie) + ADD_TRAIT(owner, TRAIT_SEE_DIABLERIE, REF(src)) + + if(add_meson) + ADD_TRAIT(owner, TRAIT_MESON_VISION, REF(src)) + + if(add_xray) + ADD_TRAIT(owner, TRAIT_XRAY_VISION, REF(src)) + + owner.update_sight() + +/datum/action/cooldown/vampire/auspex/proc/unlooky() + SIGNAL_HANDLER + + if(listening_to) + UnregisterSignal(listening_to, list(COMSIG_MOVABLE_MOVED, COMSIG_MOB_LOGOUT, COMSIG_ATOM_POST_DIR_CHANGE)) + listening_to = null + + looking = FALSE + owner.remove_traits(list(TRAIT_SEE_DIABLERIE, TRAIT_MESON_VISION, TRAIT_XRAY_VISION), REF(src)) + owner.update_sight() + + // do this last in case weird client shit happens and runtimes + var/client/client = owner.client + if(client) + client?.change_view(CONFIG_GET(string/default_view)) + client?.pixel_x = 0 + client?.pixel_y = 0 + +/datum/action/cooldown/vampire/auspex/Destroy() + listening_to = null + return ..() diff --git a/tff_modular/modules/vampire/powers/celerity/celerity.dm b/tff_modular/modules/vampire/powers/celerity/celerity.dm new file mode 100644 index 00000000000..bdd33096c36 --- /dev/null +++ b/tff_modular/modules/vampire/powers/celerity/celerity.dm @@ -0,0 +1,11 @@ +/datum/discipline/celerity + name = "Celerity" + discipline_explanation = "Celerity is a Discipline that grants vampires supernatural quickness and reflexes." + icon_state = "celerity" + + // Lists of abilities granted per level + level_1 = list(/datum/action/cooldown/vampire/targeted/haste) + level_2 = list(/datum/action/cooldown/vampire/targeted/haste/two) + level_3 = list(/datum/action/cooldown/vampire/targeted/haste/three) + level_4 = list(/datum/action/cooldown/vampire/targeted/haste/three, /datum/action/cooldown/vampire/exactitude) + level_5 = null diff --git a/tff_modular/modules/vampire/powers/celerity/haste.dm b/tff_modular/modules/vampire/powers/celerity/haste.dm new file mode 100644 index 00000000000..0cc08dfd33c --- /dev/null +++ b/tff_modular/modules/vampire/powers/celerity/haste.dm @@ -0,0 +1,102 @@ +/* Level 1: Speed to location + * Level 2: Dodge Bullets + * Level 3: Stun People Passed + */ +/datum/action/cooldown/vampire/targeted/haste + name = "Immortal Haste" + desc = "Dash somewhere with supernatural speed. Those nearby may be knocked away or stunned." + button_icon_state = "power_speed" + power_explanation = "Click anywhere to immediately dash towards that location.\n\ + The Power will not work if you are lying down, zero-gravity, or are being aggressively grabbed.\n\ + Anyone in your way during your Haste will be knocked down.\n\ + Higher levels will increase the knockdown dealt to enemies." + vampire_power_flags = BP_AM_TOGGLE + vampire_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 + vitaecost = 15 + cooldown_time = 12 SECONDS + target_range = 15 + power_activates_immediately = TRUE + ///List of all people hit by our power, so we don't hit them again. + var/list/hit = list() + +/datum/action/cooldown/vampire/targeted/haste/two + vitaecost = 30 + cooldown_time = 6 SECONDS + level_current = 2 + +/datum/action/cooldown/vampire/targeted/haste/three + vitaecost = 45 + cooldown_time = 2 SECONDS + level_current = 3 + +/datum/action/cooldown/vampire/targeted/haste/can_use() + . = ..() + if(!.) + return FALSE + + // Being Grabbed + if(owner.pulledby && owner.pulledby.grab_state >= GRAB_AGGRESSIVE) + owner.balloon_alert(owner, "you're being grabbed!") + return FALSE + if(!owner.has_gravity(owner.loc)) //We dont want people to be able to use this to fly around in space + owner.balloon_alert(owner, "you cannot dash while floating!") + return FALSE + var/mob/living/carbon/user = owner + if(user?.body_position == LYING_DOWN) + owner.balloon_alert(owner, "you must be standing to tackle!") + return FALSE + return TRUE + +/// Anything will do, if it's not me or my square +/datum/action/cooldown/vampire/targeted/haste/check_valid_target(atom/target_atom) + . = ..() + if(!.) + return FALSE + + // Can't dash to the same tile we're already on + if(target_atom.loc == owner.loc) + return FALSE + +/// This is a non-async proc to make sure the power is "locked" until this finishes. +/datum/action/cooldown/vampire/targeted/haste/fire_targeted_power(atom/target_atom) + . = ..() + RegisterSignal(owner, COMSIG_MOVABLE_MOVED, PROC_REF(on_move)) + var/mob/living/user = owner + var/turf/targeted_turf = get_turf(target_atom) + // Pulled? Not anymore. + user.pulledby?.stop_pulling() + // Go to target turf + // DO NOT USE WALK TO. + // check_witnesses() + owner.balloon_alert(owner, "you dash into the air!") + playsound(get_turf(owner), 'sound/items/weapons/punchmiss.ogg', 25, TRUE, -1) + var/safety = get_dist(user, targeted_turf) * 3 + 1 + var/consequetive_failures = 0 + while(--safety && (get_turf(user) != targeted_turf)) + var/success = step_towards(user, targeted_turf) //This does not try to go around obstacles. + if(!success) + success = step_to(user, targeted_turf) //this does + if(!success) + consequetive_failures++ + if(consequetive_failures >= 3) //if 3 steps don't work + break //just stop + else + consequetive_failures = 0 //reset so we can keep moving + if(user.resting || user.incapacitated(IGNORE_RESTRAINTS | IGNORE_GRAB)) //actually down? stop. + break + if(success) //don't sleep if we failed to move. + sleep(world.tick_lag) + +/datum/action/cooldown/vampire/targeted/haste/power_activated_sucessfully() + . = ..() + UnregisterSignal(owner, COMSIG_MOVABLE_MOVED) + hit.Cut() + +/datum/action/cooldown/vampire/targeted/haste/proc/on_move() + for(var/mob/living/hit_living in dview(1, get_turf(owner)) - owner) + if(hit.Find(hit_living)) + continue + hit += hit_living + playsound(hit_living, SFX_PUNCH, 15, TRUE, -1) + hit_living.Knockdown(10 + level_current * 8) + hit_living.spin(1 SECONDS, 1) diff --git a/tff_modular/modules/vampire/powers/celerity/quickness.dm b/tff_modular/modules/vampire/powers/celerity/quickness.dm new file mode 100644 index 00000000000..11b33073372 --- /dev/null +++ b/tff_modular/modules/vampire/powers/celerity/quickness.dm @@ -0,0 +1,54 @@ +/datum/action/cooldown/vampire/exactitude + name = "Exactitude" + desc = "Focus your powers into your hands, enabling you to attack with preternatural precision." + button_icon_state = "power_exactitude" + power_explanation = "Imbues your hands with supernatural precision. Cannot be used with gloves on.\n\ + Use with combat mode. When punching, you will automatically hit the closest being. Best used without moving your mouse at all." + vampire_power_flags = BP_AM_TOGGLE + vampire_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 + cooldown_time = 30 SECONDS + vitaecost = 50 + constant_vitaecost = 5 + + +/datum/action/cooldown/vampire/exactitude/can_use() + . = ..() + if(!.) + return FALSE + if(owner.get_item_by_slot(ITEM_SLOT_GLOVES)) + owner.balloon_alert(owner, "you're wearing gloves!") + return FALSE + +/datum/action/cooldown/vampire/exactitude/activate_power() + . = ..() + RegisterSignal(owner, COMSIG_LIVING_EARLY_UNARMED_ATTACK, PROC_REF(on_unarmed_attack)) + ADD_TRAIT(owner, TRAIT_PERFECT_ATTACKER, REF(src)) + +/datum/action/cooldown/vampire/exactitude/deactivate_power() + . = ..() + UnregisterSignal(owner, COMSIG_LIVING_EARLY_UNARMED_ATTACK) + REMOVE_TRAIT(owner, TRAIT_PERFECT_ATTACKER, REF(src)) + +/datum/action/cooldown/vampire/exactitude/continue_active() + . = ..() + if(owner.get_item_by_slot(ITEM_SLOT_GLOVES)) + return FALSE + +/datum/action/cooldown/vampire/exactitude/proc/on_unarmed_attack(mob/living/source, atom/target, proximity, modifiers) + if(!currently_active) + return NONE + + if(isliving(target) && target != source) + var/mob/living/living_target = target + if(living_target.stat != DEAD) // don't focus on dead targets + return NONE + + for(var/mob/living/to_attack in oview(1, source)) + if(to_attack.stat == DEAD || to_attack.invisibility > source.see_invisible) + continue + source.face_atom(to_attack) + to_attack.attack_hand(source, modifiers) + source.changeNext_move(CLICK_CD_MELEE) + return COMPONENT_CANCEL_ATTACK_CHAIN + + diff --git a/tff_modular/modules/vampire/powers/disciplines.dm b/tff_modular/modules/vampire/powers/disciplines.dm new file mode 100644 index 00000000000..7d41009ee32 --- /dev/null +++ b/tff_modular/modules/vampire/powers/disciplines.dm @@ -0,0 +1,75 @@ +/datum/discipline + ///Name of this Discipline. + var/name = "ERROR" + ///Text description of this Discipline. + var/discipline_explanation = "ERROR" + + ///Icon for this Discipline + var/icon_state = "error" + + // Lists of abilities granted per level. Set to null if unused. + var/list/level_1 = null // Level 1 + var/list/level_2 = null // Level 2 + var/list/level_3 = null // Level 3 + var/list/level_4 = null // Level 4 + var/list/level_5 = null // Level 5 + + // Backend shit + ///What level the user has in this Discipline. In case we want to add persistant effects to having a discipline. + var/level = 1 + ///The mob that owns and is using this Discipline. + var/mob/living/carbon/human/owner + /// The owner's vampire datum + var/datum/antagonist/vampire/vampiredatum_discipline + +/datum/discipline/Destroy() + vampiredatum_discipline = null + owner = null + return ..() + +/** + * Needs to be called after we have been created and assigned to a vampire. + */ +/datum/discipline/proc/assigned_to_owner(mob/living/carbon/carbon_owner) + owner = carbon_owner + vampiredatum_discipline = IS_VAMPIRE(carbon_owner) + +// 0 is null, and false is also null, which is 0. So, we gotta use 1 as the starting point that doesn't have any abilities. +// Yes this means all levels everywhere else do not match up with this. +// You know, null kind of exists so we can tell if there is no data vs it being a 0. Just a thought, lummox. +// You can also give it a string "current" and it'll return the current set! +/datum/discipline/proc/get_abilities_with_level(what_level) + if(what_level == "current") + what_level = level + + if(what_level == "next") + what_level = level + 1 + + switch(what_level) + if(1) // 0, null, do not change + return null + if(2) + return level_1 + if(3) + return level_2 + if(4) + return level_3 + if(5) + return level_4 + if(6) + return level_5 + else + return null + +/// Can't go over 5 even if you define more +/datum/discipline/proc/level_up() + if(level >= 6) // it's six cuz 1 is null, yadda yadda + level = 6 + return FALSE + else + level++ + return TRUE + +// For example, extra damage for potence. +/datum/discipline/proc/apply_discipline_quirks(datum/antagonist/vampire/clan_owner) + return diff --git a/tff_modular/modules/vampire/powers/dominate/command.dm b/tff_modular/modules/vampire/powers/dominate/command.dm new file mode 100644 index 00000000000..62e1a75003e --- /dev/null +++ b/tff_modular/modules/vampire/powers/dominate/command.dm @@ -0,0 +1,250 @@ +/** + * Command + * Gives a one-word brainwash-command to a target for 60 seconds. + * Level 2: Now lasts 180 seconds. + */ +/datum/action/cooldown/vampire/targeted/command + name = "Command" + desc = "Dominate the mind of another with a simple command." + button_icon_state = "power_command" + power_explanation = "Click any player to attempt to compel them.\n\ + If your target is already commanded, a Curator, or a vampire, you will fail.\n\ + Once commanded, the target will do their best to fulfill it, with a duration scaling with level.\n\ + If your target is mindshielded, your command's duration will be halved, and commanding them will take longer.\n\ + At level 1, your command will stay for 60 seconds.\n\ + At level 2, it will remain for 3 minutes.\n\ + Be smart with your wording. They will become pacified, and won't obey violent commands.\n\ + In addition, attacking your target will immediately snap them out of their compulsion." + vampire_power_flags = NONE + vampire_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 + vitaecost = 120 + cooldown_time = 80 SECONDS + target_range = 3 + power_activates_immediately = FALSE + prefire_message = "Whom will you subvert to your will?" + ranged_mousepointer = 'tff_modular/modules/vampire/icons/vampire_command.dmi' + + /// How long the command is in effect. + var/power_time = 60 SECONDS + /// How long you have to channel in order to command someone. + var/channel_time = 8 SECONDS + + /// Reference to the target + var/datum/weakref/target_ref + +/datum/action/cooldown/vampire/targeted/command/two + name = "Command" + power_time = 180 SECONDS + vitaecost = 240 + cooldown_time = 200 SECONDS + target_range = 6 + channel_time = 5 SECONDS + +/datum/action/cooldown/vampire/targeted/command/can_use() + . = ..() + if(!.) + return FALSE + var/mob/living/carbon/carbon_owner = owner + + // Must have ears + if(!owner.get_organ_slot(ORGAN_SLOT_TONGUE)) + to_chat(owner, span_warning("You have no tongue with which to command!")) + return FALSE + + // Must have mouth unobstructed + if(carbon_owner.is_mouth_covered() || !isturf(carbon_owner.loc)) + owner.balloon_alert(owner, "your mouth is blocked.") + return FALSE + + if(HAS_TRAIT(carbon_owner, TRAIT_MUTE) || !isturf(carbon_owner.loc)) + owner.balloon_alert(owner, "you cannot speak!") + return FALSE + return TRUE + +/datum/action/cooldown/vampire/targeted/command/check_valid_target(atom/target_atom) + . = ..() + if(!.) + return FALSE + + // Must be a carbon or silicon + if(!iscarbon(target_atom)) + return FALSE + + var/mob/living/living_target = target_atom + // No mind + if(!living_target.mind) + owner.balloon_alert(owner, "[living_target] is mindless.") + return FALSE + + // Vampire/Curator check + if(IS_VAMPIRE(living_target) || IS_CURATOR(living_target) || HAS_MIND_TRAIT(living_target, TRAIT_UNCONVERTABLE)) + owner.balloon_alert(owner, "too powerful.") + return FALSE + + // Is our target alive or unconcious? + if(living_target.stat != CONSCIOUS) + owner.balloon_alert(owner, "[living_target] is not [(living_target.stat == DEAD || HAS_TRAIT(living_target, TRAIT_FAKEDEATH)) ? "alive" : "conscious"].") + return FALSE + + // Is our target deaf? + if(!living_target.can_hear()) + owner.balloon_alert(owner, "[living_target] cannot hear you!") + return FALSE + + // Is our target a silicon? + if(issilicon(living_target)) + owner.balloon_alert(owner, "[living_target] cannot be compelled!") + return FALSE + + // Already commanded? + if(living_target.has_status_effect(/datum/status_effect/commanded)) + owner.balloon_alert(owner, "[living_target] is already compelled!") + return FALSE + +/datum/action/cooldown/vampire/targeted/command/fire_targeted_power(atom/target_atom) + . = ..() + + var/mob/living/living_target = target_atom + target_ref = WEAKREF(living_target) + + owner.balloon_alert(owner, "commanding [living_target]...") + + var/command = get_single_word_command() + + if(!command) + deactivate_power() + return + + // They left while we were writing + if(!(living_target in hearers(target_range, owner))) + deactivate_power() + return + + var/modified_delay = channel_time + if(HAS_TRAIT(living_target, TRAIT_MINDSHIELD)) + modified_delay *= 1.5 + + // instant on your own vassals + var/datum/antagonist/vassal/victim_vassal = IS_VASSAL(living_target) + if(victim_vassal && (victim_vassal in vampiredatum_power.vassals)) + modified_delay = 0 + + if(modified_delay > 0) + living_target.balloon_alert(living_target, "your thoughts begin to blur!") + living_target.add_client_colour(/datum/client_colour/glass_colour/pink) + if(!do_after(owner, modified_delay, living_target, IGNORE_TARGET_LOC_CHANGE | IGNORE_HELD_ITEM, extra_checks = CALLBACK(src, PROC_REF(continue_active)), hidden = TRUE)) + living_target.balloon_alert(living_target, "your thoughts come back into focus.") + living_target.remove_client_colour(/datum/client_colour/glass_colour/pink) + deactivate_power() + return + living_target.remove_client_colour(/datum/client_colour/glass_colour/pink) + + // they're out of range once more + if(!(living_target in hearers(target_range, owner))) + living_target.balloon_alert(living_target, "your thoughts come back into focus.") + deactivate_power() + return + + //Actually command them now + owner.say(command, forced = "[type]") + + var/time_multiplier = 1 + if(HAS_TRAIT(living_target, TRAIT_MINDSHIELD)) + time_multiplier = 0.5 + + living_target.apply_status_effect(/datum/status_effect/commanded, owner, command, power_time * time_multiplier) + + power_activated_sucessfully() // PAY COST! BEGIN COOLDOWN! + +/datum/action/cooldown/vampire/targeted/command/proc/get_single_word_command() + . = TRUE + var/command = tgui_input_text(owner, "What would you like to command?", "Input a command", "STOP", encode = FALSE, timeout = 2 MINUTES) + if(QDELETED(src)) + return FALSE + /* if(CHAT_FILTER_CHECK(command)) + to_chat(owner, span_warning("The command '[span_bold("[command]")]' is forbidden!")) + return FALSE */ + if(findtext_char(command, " ")) + to_chat(owner, span_warning("Please only input a single word.")) + return FALSE + if(length_char(command) > 7) + to_chat(owner, span_warning("Command too long!")) + return FALSE + if(copytext(command, 1, 5) == "kill" || copytext(command, 1, 7) == "murder" || copytext(command, 1, 8) == "suicide" || copytext(command, 1, 4) == "die") + owner.balloon_alert(owner, "that won't work!") + to_chat(owner, span_warning(" * Remember, victims will be pacified for the duration of the command!")) + return FALSE + + return command + +/datum/action/cooldown/vampire/targeted/command/continue_active() + . = ..() + if(!.) + return FALSE + + if(!can_use()) + return FALSE + + var/mob/living/living_target = target_ref?.resolve() + if(!living_target || !check_valid_target(living_target)) + return FALSE + +/datum/action/cooldown/vampire/targeted/command/deactivate_power() + . = ..() + target_ref = null + +/datum/status_effect/commanded + id = "commanded" + duration = 1 MINUTES + tick_interval = STATUS_EFFECT_NO_TICK + on_remove_on_mob_delete = TRUE + alert_type = null + /// The vampire that casted this command. + var/mob/living/caster + /// The actual command used for the objective. + var/command + /// The brainwash objectives, so we can unbrainwash when it ends. + var/list/directives + +/datum/status_effect/commanded/on_creation(mob/living/new_owner, mob/living/caster, command, duration) + src.caster = caster + src.command = command + if(duration) + src.duration = duration + return ..() + +/datum/status_effect/commanded/on_apply() + ADD_TRAIT(owner, TRAIT_PACIFISM, TRAIT_STATUS_EFFECT(id)) + directives = brainwash(owner, "[command]!", "[caster.real_name]'s Command") + + // make sure they have a moment to realize what's going on + owner.Immobilize(2 SECONDS, TRUE) + to_chat(owner, "
    " + span_awe(span_extremelybig("[command]!")) + "
    ", type = MESSAGE_TYPE_WARNING) + + // also log it. + message_admins("[ADMIN_LOOKUPFLW(caster)] used the COMMAND ability on [ADMIN_LOOKUPFLW(owner)], commanding them to [command].") + log_game("[key_name(caster)] used the command ability on [key_name(owner)], commanding them to [command].") + + owner.AddElement(/datum/element/relay_attackers) + RegisterSignal(owner, COMSIG_ATOM_WAS_ATTACKED, PROC_REF(on_attacked)) + return TRUE + +/datum/status_effect/commanded/on_remove() + UnregisterSignal(owner, COMSIG_ATOM_WAS_ATTACKED) + REMOVE_TRAIT(owner, TRAIT_PACIFISM, TRAIT_STATUS_EFFECT(id)) + unbrainwash(owner, directives) + directives = null + owner.balloon_alert(caster, "[owner] snapped out of [owner.p_their()] trance!") + caster = null + +/datum/status_effect/commanded/proc/on_attacked(datum/source, atom/attacker, attack_flags) + SIGNAL_HANDLER + if(attacker != caster || !(attack_flags & ATTACKER_DAMAGING_ATTACK)) + return + if(owner.pulledby == caster) + caster.stop_pulling() + owner.SetAllImmobility(0) + if(caster.Adjacent(owner)) // give them a split second to run away + caster.Stun(0.5 SECONDS, TRUE) + to_chat(owner, span_awe(span_reallybig("You quickly come back to your senses as you're hit by [attacker]!"))) + qdel(src) diff --git a/tff_modular/modules/vampire/powers/dominate/dominate.dm b/tff_modular/modules/vampire/powers/dominate/dominate.dm new file mode 100644 index 00000000000..1e336aa484c --- /dev/null +++ b/tff_modular/modules/vampire/powers/dominate/dominate.dm @@ -0,0 +1,15 @@ +/datum/discipline/dominate + name = "Dominate" + discipline_explanation = "Dominate is a Discipline that overwhelms another person's mind with the vampire's will, forcing victims to think or act according to the vampire's decree." + icon_state = "dominate" + + // Base only has mez, ventrue get command earlier and can upgrade it + level_1 = list(/datum/action/cooldown/vampire/targeted/mesmerize) + level_2 = list(/datum/action/cooldown/vampire/targeted/mesmerize/two) + level_3 = list(/datum/action/cooldown/vampire/targeted/mesmerize/three) + level_4 = list(/datum/action/cooldown/vampire/targeted/mesmerize/four, /datum/action/cooldown/vampire/targeted/command) + level_5 = null + +/datum/discipline/dominate/ventrue + level_3 = list(/datum/action/cooldown/vampire/targeted/mesmerize/three, /datum/action/cooldown/vampire/targeted/command) + level_4 = list(/datum/action/cooldown/vampire/targeted/mesmerize/four, /datum/action/cooldown/vampire/targeted/command/two) diff --git a/tff_modular/modules/vampire/powers/dominate/mesmerize.dm b/tff_modular/modules/vampire/powers/dominate/mesmerize.dm new file mode 100644 index 00000000000..2a0101084d3 --- /dev/null +++ b/tff_modular/modules/vampire/powers/dominate/mesmerize.dm @@ -0,0 +1,214 @@ +/** + * MEZMERIZE + * Locks a target in place for a certain amount of time. + * + * Level 2: Additionally mutes + * Level 3: Can be used through face protection + * Level 5: Doesn't need to be facing you anymore + */ +/datum/action/cooldown/vampire/targeted/mesmerize + name = "Mesmerize" + desc = "Transfix the mind of a mortal after a few seconds, freezing them in place." + button_icon_state = "power_mez" + power_explanation = "Click any player to attempt to mesmerize them, and freeze them in place.\n\ + You cannot wear anything covering your face.\n\ + This will take a few seconds, and they may attempt to flee - the spell will fail if they exit the range.\n\ + If your target is already mesmerized or a Curator, you will fail.\n\ + Once mesmerized, the target will be unable to move or speak for a certain amount of time, scaling with level.\n\ + At level 3, you will be able to use the power through masks and helmets.\n\ + At level 4, you will be able to mesmerize regardless of your target's direction." + vampire_power_flags = NONE + vampire_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 + vitaecost = 75 + cooldown_time = 20 SECONDS + target_range = 4 + power_activates_immediately = FALSE + prefire_message = "Whom will you submit to your will?" + level_current = 1 + ranged_mousepointer = 'tff_modular/modules/vampire/icons/vampire_mesmerize.dmi' + + /// Reference to the target + var/datum/weakref/target_ref + /// How long it takes us to mesmerize our target. + var/mesmerize_delay = 5 SECONDS + +/datum/action/cooldown/vampire/targeted/mesmerize/Destroy() + target_ref = null + return ..() + +/datum/action/cooldown/vampire/targeted/mesmerize/two + vitaecost = 45 + level_current = 2 + +/datum/action/cooldown/vampire/targeted/mesmerize/three + vitaecost = 60 + level_current = 3 + +/datum/action/cooldown/vampire/targeted/mesmerize/four + vitaecost = 85 + level_current = 4 + target_range = 6 + +/datum/action/cooldown/vampire/targeted/mesmerize/can_use() + . = ..() + if(!.) + return FALSE + + // Must have eyes + if(!owner.get_organ_slot(ORGAN_SLOT_EYES)) + to_chat(owner, span_warning("You have no eyes with which to mesmerize."), type = MESSAGE_TYPE_COMBAT) + return FALSE + + // Must have eyes unobstructed + var/mob/living/carbon/carbon_owner = owner + if((carbon_owner.is_eyes_covered() && level_current <= 2) || !isturf(carbon_owner.loc)) + // stupid workaround for a weird edge case with prescription glasses + if(HAS_TRAIT(carbon_owner, TRAIT_NEARSIGHTED_CORRECTED) && !carbon_owner.is_eyes_covered(~ITEM_SLOT_EYES)) + return TRUE + owner.balloon_alert(owner, "your eyes are concealed from sight.") + return FALSE + return TRUE + +/datum/action/cooldown/vampire/targeted/mesmerize/check_valid_target(atom/target_atom) + . = ..() + if(!.) + return FALSE + + // Must be a carbon or silicon + if(!iscarbon(target_atom) && !issilicon(target_atom)) + return FALSE + var/mob/living/living_target = target_atom + + // No mind + if(!living_target.mind) + owner.balloon_alert(owner, "[living_target] is mindless.") + return FALSE + + // Vampire/Curator check + if(IS_VAMPIRE(living_target) || IS_CURATOR(living_target) || HAS_MIND_TRAIT(living_target, TRAIT_UNCONVERTABLE)) + owner.balloon_alert(owner, "too powerful.") + return FALSE + + // Is our target alive or unconcious? + if(living_target.stat != CONSCIOUS) + owner.balloon_alert(owner, "[living_target] is not [(living_target.stat == DEAD || HAS_TRAIT(living_target, TRAIT_FAKEDEATH)) ? "alive" : "conscious"].") + return FALSE + + // Is our target blind? + if((!living_target.get_organ_slot(ORGAN_SLOT_EYES) || living_target.is_blind()) && !issilicon(living_target)) + owner.balloon_alert(owner, "[living_target] is blind.") + return FALSE + + // Already mesmerized? + if(living_target.has_status_effect(/datum/status_effect/mesmerized)) + owner.balloon_alert(owner, "[living_target] is already in a hypnotic gaze.") + return FALSE + +/datum/action/cooldown/vampire/targeted/mesmerize/fire_targeted_power(atom/target_atom) + . = ..() + var/mob/living/living_target = target_atom + target_ref = WEAKREF(living_target) + + // Mesmerizing silicons is instant + if(issilicon(living_target)) + var/mob/living/silicon/silicon_target = living_target + silicon_target.emp_act(EMP_HEAVY) + owner.balloon_alert(owner, "temporarily shut [silicon_target] down.") + power_activated_sucessfully() // PAY COST! BEGIN COOLDOWN! + return + + var/modified_delay = mesmerize_delay + var/eye_protection = living_target.get_eye_protection() + to_chat(living_target, span_warning("[owner]'s eyes look into yours, and [span_awe("you feel your mind slipping away")]..."), type = MESSAGE_TYPE_COMBAT) + if(eye_protection > 0) + modified_delay += (eye_protection * 0.25) * mesmerize_delay + to_chat(living_target, span_warning("It feels like your eye-protection is helping you resist the gaze!"), type = MESSAGE_TYPE_COMBAT) + to_chat(living_target, span_warning("But, you can still feel it making your eyes grow heavy."), type = MESSAGE_TYPE_COMBAT) + to_chat(owner, span_warning("[living_target] is wearing eye-protection, it will take longer to mesmerize [living_target.p_them()]."), type = MESSAGE_TYPE_COMBAT) + owner.balloon_alert(owner, "attempting to hypnotize [living_target], but [living_target.p_they()] [living_target.p_are()] partially protected!") + else + owner.balloon_alert(owner, "attempting to hypnotize [living_target]...") + + perform_indicators(living_target, modified_delay) + + if(!do_after(owner, modified_delay, living_target, IGNORE_USER_LOC_CHANGE | IGNORE_TARGET_LOC_CHANGE, extra_checks = CALLBACK(src, PROC_REF(continue_active)), hidden = TRUE)) + deactivate_power() + return + + owner.balloon_alert(owner, "successfully mesmerized [living_target].") + + //Actually mesmerize them now + var/power_time = 9 SECONDS + level_current * 1.5 SECONDS + living_target.apply_status_effect(/datum/status_effect/mesmerized, owner, power_time) + + power_activated_sucessfully() // PAY COST! BEGIN COOLDOWN! + +/datum/action/cooldown/vampire/targeted/mesmerize/continue_active() + . = ..() + if(!.) + return FALSE + + if(!can_use()) + return FALSE + + var/mob/living/living_target = target_ref?.resolve() + if(!living_target || !check_valid_target(living_target)) + return FALSE + +/datum/action/cooldown/vampire/targeted/mesmerize/deactivate_power() + . = ..() + target_ref = null + +/datum/action/cooldown/vampire/targeted/mesmerize/proc/perform_indicators(mob/target, duration) + // Display an animated overlay over our head to indicate what's going on + eldritch_eye(target, "eye_open", 1 SECONDS) + var/main_duration = max(duration - 2 SECONDS, 1 SECONDS) + addtimer(CALLBACK(src, PROC_REF(eldritch_eye), target, "eye_flash", main_duration), 1 SECONDS) + addtimer(CALLBACK(src, PROC_REF(eldritch_eye), target, "eye_close", 1 SECONDS), main_duration + 1 SECONDS) + +/// Display an animated overlay over our head to indicate what's going on +/datum/action/cooldown/vampire/targeted/mesmerize/proc/eldritch_eye(mob/target, icon_state = "eye_open", duration = 1 SECONDS) + var/image/image = image('icons/effects/eldritch.dmi', owner, icon_state, ABOVE_ALL_MOB_LAYER) + image.pixel_w = -(owner.pixel_x + owner.pixel_w) + image.pixel_z = 28 + image.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA + SET_PLANE_EXPLICIT(image, ABOVE_HUD_PLANE, owner) + flick_overlay_global(image, list(owner?.client, target?.client), duration) + +/datum/status_effect/mesmerized + id = "mesmerized" + duration = 15 SECONDS + tick_interval = STATUS_EFFECT_NO_TICK + alert_type = null + /// The mob that mesmerized the victim. + var/mob/living/caster + /// Traits given to the mesmerized victim. + var/list/mesmerized_traits = list( + TRAIT_HANDS_BLOCKED, + TRAIT_IMMOBILIZED, + TRAIT_INCAPACITATED, + TRAIT_MUTE, + ) + +/datum/status_effect/mesmerized/Destroy() + . = ..() + caster = null + +/datum/status_effect/mesmerized/on_creation(mob/living/new_owner, mob/living/caster, duration) + src.caster = caster + src.duration = duration + return ..() + +/datum/status_effect/mesmerized/on_apply() + owner.add_client_colour(/datum/client_colour/glass_colour/pink) + owner.add_traits(mesmerized_traits, TRAIT_STATUS_EFFECT(id)) + to_chat(owner, span_awe("[caster]'s eyes glitter so beautifully... You're mesmerized!"), type = MESSAGE_TYPE_COMBAT) + owner.playsound_local(null, 'tff_modular/modules/vampire/sound/mesmerize.ogg', 100, FALSE, pressure_affected = FALSE) + return TRUE + +/datum/status_effect/mesmerized/on_remove() + owner.remove_client_colour(/datum/client_colour/glass_colour/pink) + owner.remove_traits(mesmerized_traits, TRAIT_STATUS_EFFECT(id)) + to_chat(owner, span_awe(span_big("With the spell waning, so does your memory of being mesmerized.")), type = MESSAGE_TYPE_COMBAT) + if(CAN_THEY_SEE(owner, caster)) + owner.balloon_alert(caster, "snapped out of [owner.p_their()] trance!") diff --git a/tff_modular/modules/vampire/powers/feed.dm b/tff_modular/modules/vampire/powers/feed.dm new file mode 100644 index 00000000000..6713e2ff68c --- /dev/null +++ b/tff_modular/modules/vampire/powers/feed.dm @@ -0,0 +1,617 @@ +#define FEED_SILENT_NOTICE_RANGE 1 +#define FEED_LOUD_NOTICE_RANGE 7 +#define FEED_DEFAULT_TIME 10 SECONDS +#define FEED_FRENZY_TIME 2 SECONDS +#define FEED_BLOOD_FROM_MICE 25 + +/datum/action/cooldown/vampire/targeted/feed + name = "Feed" + desc = "Feed blood off of a living creature." + button_icon_state = "power_feed" + power_explanation = "Activate Feed and select a target to start draining their blood.\n\ + You will begin to entrance them into accepting your advances.\n\ + The time needed before you start feeding decreases the higher level you are.\n\ + If you are feeding normally they will forget that they were ever fed off.\n\ + Mice can be fed off if you are in desperate need of blood.\n\ + Feeding off of someone while you have them aggressively grabbed while in combat mode, will put them to sleep and make you feed faster. \ + This is very obvious and the radius in which you can be detected is much larger!\n\ + IMPORTANT: You are given a Masquerade Infraction if a mortal witnesses you while feeding.\n\ + IMPORTANT: Should you drain another vampire, you will absorb their power!" + vampire_power_flags = BP_AM_TOGGLE | BP_AM_STATIC_COOLDOWN + vampire_check_flags = BP_CANT_USE_IN_TORPOR | BP_CANT_USE_WHILE_STAKED | BP_CANT_USE_WHILE_INCAPACITATED | BP_CANT_USE_WHILE_UNCONSCIOUS + special_flags = VAMPIRE_DEFAULT_POWER + cooldown_time = 1 SECONDS + target_range = 1 + prefire_message = "Select a target." + power_activates_immediately = FALSE + ranged_mousepointer = 'tff_modular/modules/vampire/icons/vampire_feed.dmi' + /// Amount of blood taken, reset after each Feed. Used for logging. + var/blood_taken = 0 + /// The amount of Blood a target has since our last feed, this loops and lets us not spam alerts of low blood. + var/warning_target_bloodvol = BLOOD_VOLUME_MAXIMUM + /// Reference to the target we've fed off of + var/datum/weakref/target_ref + /// Are we feeding with passive grab or not? + var/silent_feed = TRUE + + /// Have we fed till fatal? + var/feed_fatal = FALSE + /// During feeding, have we breached the masquerade? + var/masquerade_breached = FALSE + /// Are we at a stage of the process where we can be noticed? + var/currently_feeding = FALSE + /// Did we complete the thirster objective this drain? + /// We won't give a bad moodlet for dead bodies if so. + var/completing_thirster = FALSE + +/datum/action/cooldown/vampire/targeted/feed/can_use() + . = ..() + if(!.) + return FALSE + + // Already feeding + if(target_ref) + return FALSE + // Mouth covered + var/mob/living/carbon/user = owner + if(user?.is_mouth_covered() && !isplasmaman(user)) + owner.balloon_alert(owner, "mouth covered!") + return FALSE + +/datum/action/cooldown/vampire/targeted/feed/continue_active() + . = ..() + if(!.) + return FALSE + + var/mob/living/target = target_ref.resolve() + if(!target) + return FALSE + if(!owner.Adjacent(target)) + return FALSE + + // Check if we are seen while feeding, from the vampire's POV + if(currently_feeding) + var/turf/our_turf = get_turf(owner) + var/turf/target_turf = get_turf(target) + var/is_dark = min(GET_SIMPLE_LUMCOUNT(our_turf), GET_SIMPLE_LUMCOUNT(target_turf)) <= 0.2 + + var/notice_range = silent_feed ? FEED_SILENT_NOTICE_RANGE : FEED_LOUD_NOTICE_RANGE + var/list/potential_watchers = oviewers(notice_range, target) | oviewers(notice_range, owner) + for(var/mob/living/watcher in potential_watchers - target) + if(!vampiredatum_power.is_masq_watcher(watcher)) + continue + if(is_dark && !watcher.Adjacent(owner) && !watcher.Adjacent(target)) + continue + + if(!watcher.incapacitated(IGNORE_RESTRAINTS)) + watcher.face_atom(owner) + watcher.do_alert_animation(watcher) + to_chat(watcher, span_warning("[owner] is biting [target]'s neck!"), type = MESSAGE_TYPE_WARNING) + playsound(watcher, 'sound/machines/chime.ogg', 50, FALSE, -5) + + owner.balloon_alert(owner, "feed noticed!") + if(!masquerade_breached) + masquerade_breached = TRUE + vampiredatum_power.give_masquerade_infraction() + + return TRUE + +/datum/action/cooldown/vampire/targeted/feed/check_valid_target(atom/target_atom) + . = ..() + if(!.) + return FALSE + + // Must be living + if(!isliving(target_atom)) + return FALSE + var/mob/living/target = target_atom + // Mice check + if(ismouse(target)) + if(vampiredatum_power.my_clan?.blood_drink_type == VAMPIRE_DRINK_SNOBBY) + owner.balloon_alert(owner, "too disgusting!") + return FALSE + else + return TRUE + // Has to be human or a monkey + if(!ishuman(target)) + owner.balloon_alert(owner, "cant feed off!") + return FALSE + // Mindless and snobby? + if(!target.mind && vampiredatum_power.my_clan?.blood_drink_type == VAMPIRE_DRINK_SNOBBY && !HAS_TRAIT(owner, TRAIT_FRENZY)) + owner.balloon_alert(owner, "ew, no!") + return FALSE + // Cannot be a curator + if(IS_VAMPIRE_HUNTER(target)) + owner.balloon_alert(owner, "[target] is too powerful!") + return FALSE + var/datum/antagonist/vampire/target_vampire = IS_VAMPIRE(target) + if(target_vampire && (vampiredatum_power.scourge || vampiredatum_power.prince) && !target_vampire.broke_masquerade) + owner.balloon_alert(owner, "cannot diablerize non-masquerade breakers as royalty!") + return FALSE + // Human checks + if(ishuman(target)) + // Cannot drink from inorganics + var/mob/living/carbon/human/human_target = target + if(!human_target.dna?.species || !(human_target.mob_biotypes & MOB_ORGANIC)) + owner.balloon_alert(owner, "no blood!") + return FALSE + // Cannot be wearing super thick gear + if(!human_target.can_inject(owner, BODY_ZONE_HEAD, INJECT_CHECK_PENETRATE_THICK)) + owner.balloon_alert(owner, "suit too thick!") + return FALSE + + if(isliving(owner)) + var/mob/living/living_owner = owner + if(living_owner.body_position != STANDING_UP) + living_owner.balloon_alert(living_owner, "must be standing!") + return FALSE + + if(iscarbon(owner)) + var/mob/living/carbon/carbon_owner = owner + if(carbon_owner.handcuffed) + carbon_owner.balloon_alert(carbon_owner, "can't feed while restrained!") + return FALSE + + silent_feed = TRUE + +/datum/action/cooldown/vampire/targeted/feed/fire_targeted_power(atom/target_atom) + . = ..() + var/mob/living/carbon/feed_target = target_atom + var/mob/living/carbon/living_owner = owner + target_ref = WEAKREF(feed_target) + + // Mice + if(ismouse(feed_target)) + to_chat(owner, span_warning("You recoil at the taste of a lesser lifeform.")) + vampiredatum_power.adjust_blood_volume(FEED_BLOOD_FROM_MICE) + power_activated_sucessfully() + feed_target.death() + return + + ////////////////////////// + //We start here properly// + ////////////////////////// + + currently_feeding = FALSE + masquerade_breached = FALSE + + if(feed_target.grabbedby(living_owner) && !living_owner.grab_state == GRAB_AGGRESSIVE) + + // Don't allow normal feed on vamps. It's too easy and feels unfair. + if(IS_VAMPIRE(feed_target)) + owner.balloon_alert(owner, "too powerful, knock them out and combat feed on them!") + deactivate_power() + return + + if(!IS_VASSAL(feed_target)) // Vassals don't need all this shit. + owner.balloon_alert(owner, "mesmerizing [feed_target]...") + + // Initial ""mesmerize"" + if(!do_after(owner, 2 SECONDS, feed_target, hidden = TRUE)) + owner.balloon_alert(owner, "interrupted!") + deactivate_power() + return + + // Succesful. Start feeding process by getting feed time. + var/feed_time = (HAS_TRAIT(owner, TRAIT_FRENZY) ? FEED_FRENZY_TIME : clamp(round(FEED_DEFAULT_TIME / (1.25 * (level_current || 1))), 1, FEED_DEFAULT_TIME)) / 2 + + if(!IS_VASSAL(feed_target)) + feed_time /= 4 + + feed_target.playsound_local(null, 'tff_modular/modules/vampire/sound/mesmerize.ogg', 100, FALSE, pressure_affected = FALSE) + feed_target.Stun(feed_time, TRUE) + feed_target.become_blind(REF(src)) + ADD_TRAIT(feed_target, TRAIT_DEAF, REF(src)) + + to_chat(feed_target, span_hypnophrase("You suddenly fall into a deep trance..."), type = MESSAGE_TYPE_WARNING) + owner.balloon_alert(owner, "subdued! starting feed...") + + // Do the pre-feed. + if(!do_after(owner, feed_time, feed_target, NONE, TRUE, hidden = TRUE)) + owner.balloon_alert(owner, "interrupted!") + deactivate_power() + return + + // It begins... + currently_feeding = TRUE + living_owner.playsound_local(null, 'tff_modular/modules/vampire/sound/drinkblood1.ogg', 100, FALSE, pressure_affected = FALSE) + + // Just to make sure + living_owner.stop_pulling() + feed_target.stop_pulling() + + // omega switch + switch(get_dir(owner.loc, feed_target.loc)) + if(NORTH) + owner.dir = WEST + feed_target.dir = EAST + animate(owner, 0.2 SECONDS, pixel_x = 8, pixel_y = 16) + animate(feed_target, 0.2 SECONDS, pixel_x = -8, pixel_y = -16) + if(NORTHEAST) + owner.dir = EAST + feed_target.dir = WEST + animate(owner, 0.2 SECONDS, pixel_x = 8, pixel_y = 16) + animate(feed_target, 0.2 SECONDS, pixel_x = -8, pixel_y = -16) + if(EAST) + owner.dir = EAST + feed_target.dir = WEST + animate(owner, 0.2 SECONDS, pixel_x = 8) + animate(feed_target, 0.2 SECONDS, pixel_x = -8) + if(SOUTH) + owner.dir = EAST + feed_target.dir = WEST + animate(owner, 0.2 SECONDS, pixel_x = -8, pixel_y = -16) + animate(feed_target, 0.2 SECONDS, pixel_x = 8, pixel_y = 16) + if(SOUTHEAST) + owner.dir = EAST + feed_target.dir = WEST + animate(owner, 0.2 SECONDS, pixel_x = 8, pixel_y = -16) + animate(feed_target, 0.2 SECONDS, pixel_x = -8, pixel_y = 16) + if(SOUTHWEST) + owner.dir = WEST + feed_target.dir = EAST + animate(owner, 0.2 SECONDS, pixel_x = -8, pixel_y = -16) + animate(feed_target, 0.2 SECONDS, pixel_x = 8, pixel_y = 16) + if(WEST) + owner.dir = WEST + feed_target.dir = EAST + animate(owner, 0.2 SECONDS, pixel_x = -8) + animate(feed_target, 0.2 SECONDS, pixel_x = 8) + if(NORTHWEST) + owner.dir = WEST + feed_target.dir = EAST + animate(owner, 0.2 SECONDS, pixel_x = -8, pixel_y = 16) + animate(feed_target, 0.2 SECONDS, pixel_x = 8, pixel_y = -16) + if(0) // We are on the same tile. Just move them a bit so they don't overlap + owner.dir = WEST + feed_target.dir = EAST + animate(owner, 0.2 SECONDS, pixel_x = 8,) + animate(feed_target, 0.2 SECONDS, pixel_x = -8) + + owner.visible_message( + span_notice("[owner] grabs [feed_target] tightly, biting into [feed_target.p_their()] neck!"), + span_notice("You slip your fangs into [feed_target]'s neck."), + vision_distance = FEED_SILENT_NOTICE_RANGE, ignored_mobs = feed_target + ) + + else if(owner.pulling == feed_target && owner.grab_state == GRAB_AGGRESSIVE) // COMBAT FEED BELOW HERE!!!!!!!!!! + + playsound(living_owner, 'tff_modular/modules/vampire/sound/drinkblood1.ogg', 50) + + feed_target.Stun((5 + level_current) SECONDS) + feed_target.set_jitter_if_lower((5 + level_current) SECONDS) + + owner.visible_message( + span_warning("[owner] closes [owner.p_their()] mouth around [feed_target]'s neck!"), + span_warning("You sink your fangs into [feed_target]'s neck."), ignored_mobs = feed_target + ) + + to_chat(feed_target, span_bolddanger("[owner] seizes you with incredible strength, sinking [owner.p_their()] fangs into your neck!"), type = MESSAGE_TYPE_WARNING) + + to_chat(owner, span_announce("* Vampire Tip: Combat feeding does not erase their memories!")) + + currently_feeding = TRUE + silent_feed = FALSE + + // Garlic in 'em + var/mob/living/smacked = feed_target + if(smacked.reagents?.has_reagent(/datum/reagent/consumable/garlic, 2)) + + // We check which turf is one step away from our target, in the direction of the angle of the bullet. Christ. We do this twice, for range. + var/target_turf = get_step_away(smacked.loc, owner, 2) + + to_chat(owner, span_hypnophrase(span_big("eugh.. garlic..."))) + + living_owner.Stun(5 SECONDS) + living_owner.set_dizzy_if_lower(1 SECONDS) + living_owner.set_jitter_if_lower(1.5 SECONDS) + living_owner.set_eye_blur_if_lower(0.5 SECONDS) + + smacked.Unconscious(1 SECONDS) + smacked.throw_at(target_turf, 2, 1, spin = TRUE) + playsound(smacked, 'sound/items/weapons/cqchit2.ogg', 80) + deactivate_power() + return + if(currently_feeding) // Check if we actually started successfully. + owner.add_traits(list(TRAIT_IMMOBILIZED, TRAIT_MUTE, TRAIT_HANDS_BLOCKED), REF(src)) + feed_target.add_traits(list(TRAIT_IMMOBILIZED, TRAIT_MUTE, TRAIT_HANDS_BLOCKED), REF(src)) + + // Normally removed traits are done. Now we give the victim a lil something to remember us by. + feed_target.apply_status_effect(/datum/status_effect/feed_marked) + else + owner.balloon_alert(owner, "combat feed requires aggressive grab!") + deactivate_power() + return FALSE + +/datum/action/cooldown/vampire/targeted/feed/use_power() + var/mob/living/user = owner + + var/mob/living/feed_target = target_ref?.resolve() + if(!feed_target) + power_activated_sucessfully() + return + + if(!continue_active()) + if(!silent_feed) + user.visible_message( + span_warning("[user] is ripped from [feed_target]'s throat. [feed_target.p_their(TRUE)] blood sprays everywhere!"), + span_warning("Your teeth are ripped from [feed_target]'s throat. [feed_target.p_their(TRUE)] blood sprays everywhere!")) + + // Time to start bleeding + if(iscarbon(feed_target)) + var/mob/living/carbon/carbon_target = feed_target + carbon_target.bleed(15) + playsound(get_turf(feed_target), 'sound/effects/splat.ogg', 40, TRUE) + + feed_target.add_splatter_floor(get_turf(feed_target)) + + // Cover both parties in blood + user.add_mob_blood(feed_target) // Put target's blood on us. The donor goes in the ( ) + feed_target.add_mob_blood(feed_target) + + if(ishuman(feed_target)) + var/mob/living/carbon/human/target_user = feed_target + var/obj/item/bodypart/head_part = target_user.get_bodypart(BODY_ZONE_HEAD) + if(head_part) + head_part.adjustBleedStacks(10) + + // Ow + feed_target.apply_damage(10, BRUTE, BODY_ZONE_HEAD) + INVOKE_ASYNC(feed_target, TYPE_PROC_REF(/mob, emote), "scream") + + power_activated_sucessfully() + return + + // Adjust blood + var/feed_strength_mult = 0.3 + if(HAS_TRAIT(user, TRAIT_FRENZY)) + feed_strength_mult = 2 + else if(!silent_feed) + feed_strength_mult = 1 + + handle_feeding(feed_target, feed_strength_mult) + + // Mood events + if(vampiredatum_power.my_clan?.blood_drink_type == VAMPIRE_DRINK_SNOBBY && !feed_target.mind) // Snobby + user.add_mood_event("drankblood", /datum/mood_event/drankblood_bad) + else if(feed_target.stat == DEAD) // Dead + user.add_mood_event("drankblood", /datum/mood_event/drankblood_dead) + else // Normal + user.add_mood_event("drankblood", /datum/mood_event/drankblood) + + // Alert the vampire to the target's blood level + if(feed_target.blood_volume <= BLOOD_VOLUME_BAD && warning_target_bloodvol > BLOOD_VOLUME_BAD) + owner.balloon_alert(owner, "your victim's blood is fatally low!") + feed_fatal = TRUE + else if(feed_target.blood_volume <= BLOOD_VOLUME_OKAY && warning_target_bloodvol > BLOOD_VOLUME_OKAY) + owner.balloon_alert(owner, "your victim's blood is dangerously low.") + else if(feed_target.blood_volume <= BLOOD_VOLUME_SAFE && warning_target_bloodvol > BLOOD_VOLUME_SAFE) + owner.balloon_alert(owner, "your victim's blood is at an unsafe level.") + warning_target_bloodvol = feed_target.blood_volume + + // Check if full on blood + if(vampiredatum_power.current_vitae >= vampiredatum_power.max_vitae) + if(IS_VAMPIRE(feed_target)) + owner.balloon_alert(owner, "we are full on blood, but we can continue feeding to absorb [feed_target.p_their()] power!") + else + owner.balloon_alert(owner, "we are full on blood!") + + // Check if target has an acceptable amount of blood left + if(feed_target.blood_volume <= 10) + owner.balloon_alert(owner, "no blood left!") + if(feed_target.client) + var/datum/objective/vampire/hedonism/thirster/yumy = locate() in vampiredatum_power.objectives + if(yumy && !yumy.completed) + yumy.completed = TRUE + completing_thirster = TRUE + power_activated_sucessfully() + return + + if(IS_VAMPIRE(feed_target)) + var/datum/antagonist/vampire/target_vampire = IS_VAMPIRE(feed_target) + if(target_vampire.current_vitae <= 50) + diablerie(feed_target) + power_activated_sucessfully() + return + + // Play heartbeat sound effect to vampire and target + owner.playsound_local(null, 'sound/effects/singlebeat.ogg', 40, TRUE) + feed_target.playsound_local(null, 'sound/effects/singlebeat.ogg', 40, TRUE) + +/// We assume the target is a vampire. +/datum/action/cooldown/vampire/targeted/feed/proc/diablerie(mob/living/poor_sap) + var/datum/antagonist/vampire/victim = IS_VAMPIRE(poor_sap) + + var/levels_absorbed = ceil((victim.vampire_level + victim.vampire_level_unspent) / DIABLERIE_DIVISOR) + + vampiredatum_power.rank_up(levels_absorbed, TRUE) + vampiredatum_power.adjust_humanity(-victim.humanity / 3) + vampiredatum_power.diablerie_count++ + + victim.final_death() + +/datum/action/cooldown/vampire/targeted/feed/deactivate_power() + . = ..() + REMOVE_TRAITS_IN(owner, REF(src)) + + // Did we already take humanity for killing them? + var/humanity_deducted = FALSE + var/mob/living/feed_target = target_ref?.resolve() + var/mob/living/living_owner = owner + + if(feed_target) + // Call cure_blind after a (truly tiny) delay to make sure they don't see NOTHING + addtimer(CALLBACK(feed_target, TYPE_PROC_REF(/mob/living, remove_status_effect), /datum/status_effect/grouped/blindness, REF(src)), 1 SECONDS) + REMOVE_TRAITS_IN(feed_target, REF(src)) + if(currently_feeding) + + animate(owner, 0.2 SECONDS, pixel_x = 0, pixel_y = 0) + animate(feed_target, 0.2 SECONDS, pixel_x = 0, pixel_y = 0) + + log_combat(owner, feed_target, "fed on blood [silent_feed ? "silently" : "aggressively"]", addition = "(and took [blood_taken] blood)") + + to_chat(owner, span_notice("You slowly release [feed_target].")) + + if(feed_target.stat != DEAD && silent_feed) + to_chat(owner, span_notice("[feed_target.p_They()] look[feed_target.p_s()] dazed, and will not remember this."), type = MESSAGE_TYPE_INFO) + if(!IS_VASSAL(feed_target)) + to_chat(feed_target, span_awe(span_reallybig("You wake from your trance. Everything is so... hazy... You don't remember the last few moments...")), type = MESSAGE_TYPE_INFO) + to_chat(feed_target, span_warning(" * You do not remember that you have been fed on, the identity of the person who just fed on you, or the fact that they are a vampire."), type = MESSAGE_TYPE_INFO) + to_chat(feed_target, span_notice(" * If you already knew this person was a vampire from before your current encounter with them, however, you retain memory of that."), type = MESSAGE_TYPE_INFO) + else + to_chat(feed_target, span_awe(span_reallybig("You wake from your trance. Everything is so... hazy...")), type = MESSAGE_TYPE_INFO) + if(feed_target.blood_volume >= BLOOD_VOLUME_OKAY) + to_chat(feed_target, span_announce("You feel dizzy, but it will probably pass by itself!"), type = MESSAGE_TYPE_INFO) + + if(!completing_thirster) + if(feed_target.stat == DEAD) + living_owner.add_mood_event("drankkilled", /datum/mood_event/drankkilled) + humanity_deducted = TRUE + + if(feed_fatal && !humanity_deducted) + living_owner.add_mood_event("drankkilled", /datum/mood_event/drankkilled) + to_chat(owner, span_userdanger("No way will [feed_target.p_they()] survive that...")) + vampiredatum_power.adjust_humanity(-1) + +/* + if(iscarbon(feed_target)) + var/mob/living/carbon/carbon_target = feed_target + // More/less humanity adds/deducts bleedy. + switch(vampiredatum_power.humanity) + if(0 to 2) + carbon_target.bleed(BLEED_CRITICAL) + if(3 to 4) + carbon_target.bleed(BLEED_DEEP_WOUND) + if(5 to 6) + carbon_target.bleed(BLEED_CUT) + if(7 to 8) + carbon_target.bleed(BLEED_SURFACE) + if(9 to 10) + carbon_target.bleed(BLEED_SCRATCH) +*/ + + feed_fatal = FALSE + humanity_deducted = FALSE + completing_thirster = FALSE + + target_ref = null + + warning_target_bloodvol = BLOOD_VOLUME_MAXIMUM + blood_taken = 0 + +/datum/action/cooldown/vampire/targeted/feed/proc/handle_feeding(mob/living/carbon/target, mult = 1) + var/mob/living/living_owner = owner + var/feed_amount = 50 + (level_current * 2) + + // If we are already at fatal, we speed up more. + if(feed_fatal) + feed_amount *= 1.5 + + // But, if we are in combat we want to get them some time to react. + if(!silent_feed) + feed_amount *= 0.3 + + var/blood_to_take = min(feed_amount * mult, target.blood_volume) + + // Remove target's blood + target.blood_volume -= blood_to_take + + // Shift body temperature (toward target's temp, by volume taken) + // ((vamp_blood_volume * vamp_temp) + (target_blood_volume * target_temp)) / (vamp_blood_volume + blood_to_take) + // owner.bodytemperature = ((vampiredatum_power.current_vitae * owner.bodytemperature) + (blood_to_take * target.bodytemperature)) / (vampiredatum_power.current_vitae + blood_to_take) + + // Penalty for dead blood(at least it's still human, right?) + if(target.stat == DEAD) + blood_to_take /= 3 + // Penalty for non-human blood + if(!ishuman(target) || ismonkey(target)) + blood_to_take /= 10 + // Penalty for frenzy(messy eater) + if(HAS_TRAIT(living_owner, TRAIT_FRENZY)) + blood_to_take /= 2 + + // Give vampire the blood^ + var/vitae_absorbed = blood_to_take * 4 + + /// Tracking of the vitae goal + if(target.client && !target.mind?.has_antag_datum(/datum/antagonist/changeling)) + vampiredatum_power.vitae_goal_progress += vitae_absorbed + + vampiredatum_power.adjust_blood_volume(vitae_absorbed) + + // Diablerie takes vitae directly + var/datum/antagonist/vampire/vampire_target = IS_VAMPIRE(target) + if(vampire_target) + vampire_target.adjust_blood_volume(- (blood_to_take * 4)) + + // Transfer the target's reagents into the vampire's blood + if(target.reagents?.total_volume) + target.reagents.trans_to(owner, 1, methods = INGEST) // Run transfer of 1 unit of reagent from them to me. + + // Play heartbeat sound for flavor + owner.playsound_local(null, 'sound/effects/singlebeat.ogg', 40, TRUE) + + vampiredatum_power.total_blood_drank += blood_to_take + blood_taken += blood_to_take + + // If we are on combat feed, we only want it to take a bit and then stop. Except if they are not conscious or if they're restrained. + if(!silent_feed && blood_taken >= 60 && target.stat <= SOFT_CRIT && !HAS_TRAIT(target, TRAIT_RESTRAINED)) + + playsound(target, 'sound/items/weapons/cqchit2.ogg', 80) + + owner.visible_message( + span_warning("[target] struggles, pushing [owner] away!"), + span_warning("[target] manages to struggle free from your grip!"), ignored_mobs = target + ) + + var/shove_dir = get_dir(target.loc, owner.loc) + var/turf/target_shove_turf = get_step(owner.loc, shove_dir) + owner.Move(target_shove_turf, shove_dir) + + target.SetStun(0 SECONDS) + living_owner.Stun(1 SECONDS) + + owner.balloon_alert(owner, "struggles free!") + deactivate_power() + +#undef FEED_SILENT_NOTICE_RANGE +#undef FEED_LOUD_NOTICE_RANGE +#undef FEED_DEFAULT_TIME +#undef FEED_FRENZY_TIME +#undef FEED_BLOOD_FROM_MICE + +/atom/movable/screen/fullscreen/blind/feed + icon_state = "feed" + render_target = "blind_fullscreen_overlay" + layer = BLIND_LAYER + plane = FULLSCREEN_PLANE + +/datum/status_effect/feed_marked + id = "feed marked" + tick_interval = STATUS_EFFECT_NO_TICK + processing_speed = STATUS_EFFECT_NORMAL_PROCESS + status_type = STATUS_EFFECT_REFRESH + alert_type = null + remove_on_fullheal = TRUE + heal_flag_necessary = HEAL_WOUNDS + +/datum/status_effect/feed_marked/on_apply() + if(!iscarbon(owner)) + return FALSE + RegisterSignal(owner, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) + return TRUE + +/datum/status_effect/feed_marked/on_remove() + UnregisterSignal(owner, COMSIG_ATOM_EXAMINE) + +/datum/status_effect/feed_marked/on_creation(mob/living/new_owner, ...) + duration = rand(5 MINUTES, 10 MINUTES) + return ..() + +/datum/status_effect/feed_marked/refresh(effect, ...) + duration = max(duration, world.time + rand(5 MINUTES, 10 MINUTES)) + +/datum/status_effect/feed_marked/proc/on_examine(atom/source, mob/user, list/examine_list) + SIGNAL_HANDLER + if(isobserver(user) || (get_dist(user, owner) <= 3 && !user.is_nearsighted_currently())) + examine_list += span_warning("There are two strange punctures on [owner.p_their()] neck.") diff --git a/tff_modular/modules/vampire/powers/fortitude/fortitude.dm b/tff_modular/modules/vampire/powers/fortitude/fortitude.dm new file mode 100644 index 00000000000..e93953b11fe --- /dev/null +++ b/tff_modular/modules/vampire/powers/fortitude/fortitude.dm @@ -0,0 +1,118 @@ +/datum/discipline/fortitude + name = "Fortitude" + discipline_explanation = "Fortitude is a Discipline that grants Kindred unearthly toughness." + icon_state = "fortitude" + + // Lists of abilities granted per level + level_1 = list(/datum/action/cooldown/vampire/fortitude) + level_2 = list(/datum/action/cooldown/vampire/fortitude/two) + level_3 = list(/datum/action/cooldown/vampire/fortitude/three) + level_4 = list(/datum/action/cooldown/vampire/fortitude/four) + level_5 = null + +/** + * FORTITUDE + * All levels: Incrementally increasing brute and stamina resistance. + * Level 1: Pierce resistance + * Level 2: Push immunity + * Level 3: Dismember resistance + * Level 4: Complete stun immunity + */ + +/datum/action/cooldown/vampire/fortitude + name = "Fortitude" + desc = "Withstand egregious physical wounds and walk away from attacks that would stun, pierce, and dismember lesser beings." + button_icon_state = "power_fortitude" + power_explanation = "Grants increasing levels of brute and stamina resistance, as well as various immunities to physical harm.\n\ + At level 1: Gain pierce resistance.\n\ + At level 2: Gain push immunity.\n\ + At level 3: Gain dismember resistance.\n\ + At level 4: Gain complete stun immunity." + vampire_power_flags = BP_AM_TOGGLE | BP_AM_COSTLESS_UNCONSCIOUS + vampire_check_flags = BP_CANT_USE_IN_TORPOR | BP_CANT_USE_IN_FRENZY | BP_CANT_USE_WHILE_STAKED + vitaecost = 50 + cooldown_time = 5 SECONDS + constant_vitaecost = 1 + + var/resistance = 0.8 + + // Flags for what immunities to turn on at which level + var/pierce = TRUE + var/push = FALSE + var/dismember = FALSE + var/stun = FALSE + + var/calculated_burn_resist // do not touch + +/datum/action/cooldown/vampire/fortitude/two + vitaecost = 40 + constant_vitaecost = 2 + resistance = 0.6 + pierce = TRUE + push = TRUE + +/datum/action/cooldown/vampire/fortitude/three + vitaecost = 30 + constant_vitaecost = 3 + resistance = 0.4 + pierce = TRUE + push = TRUE + dismember = TRUE + +/datum/action/cooldown/vampire/fortitude/four + vitaecost = 20 + constant_vitaecost = 4 + resistance = 0.3 + pierce = TRUE + push = TRUE + dismember = TRUE + stun = TRUE + +/datum/action/cooldown/vampire/fortitude/activate_power() + . = ..() + owner.balloon_alert(owner, "fortitude turned on.") + to_chat(owner, span_notice("Your flesh has become as hard as steel!")) + owner.playsound_local(null, 'tff_modular/modules/vampire/sound/fortitude_on.ogg', 100, FALSE, pressure_affected = FALSE) + + calculated_burn_resist = min(1, resistance * 3) + + // Traits & Effects + if(pierce) + ADD_TRAIT(owner, TRAIT_PIERCEIMMUNE, REF(src)) + if(dismember) + ADD_TRAIT(owner, TRAIT_NODISMEMBER, REF(src)) + if(push) + ADD_TRAIT(owner, TRAIT_PUSHIMMUNE, REF(src)) + if(stun) + ADD_TRAIT(owner, TRAIT_STUNIMMUNE, REF(src)) // They'll get stun resistance + this, who cares. + + var/mob/living/carbon/human/user = owner + user.physiology.brute_mod *= resistance + user.physiology.stamina_mod *= resistance * 2 // Stamina resistance is half as effective because they have it inherently. + user.physiology.burn_mod *= calculated_burn_resist // they get burn resistance, but way less + +/datum/action/cooldown/vampire/fortitude/use_power() + . = ..() + if(!.) + return + + var/mob/living/carbon/user = owner + if(istype(user.buckled, /obj/vehicle)) + user.buckled.unbuckle_mob(src, force = TRUE) + +/datum/action/cooldown/vampire/fortitude/deactivate_power() + if(!ishuman(owner)) + return + + var/mob/living/carbon/human/vampire_user = owner + vampire_user.physiology.brute_mod /= resistance + vampire_user.physiology.burn_mod /= calculated_burn_resist + vampire_user.physiology.stamina_mod /= resistance * 2 + + // Remove Traits & Effects + REMOVE_TRAITS_IN(owner, REF(src)) + + owner.balloon_alert(owner, "fortitude turned off.") + owner.playsound_local(null, 'tff_modular/modules/vampire/sound/fortitude_off.ogg', 100, FALSE, pressure_affected = FALSE) + + return ..() diff --git a/tff_modular/modules/vampire/powers/gohome.dm b/tff_modular/modules/vampire/powers/gohome.dm new file mode 100644 index 00000000000..f710d22ec66 --- /dev/null +++ b/tff_modular/modules/vampire/powers/gohome.dm @@ -0,0 +1,101 @@ +#define GOHOME_START 0 +#define GOHOME_FLICKER_ONE 2 +#define GOHOME_FLICKER_TWO 4 +#define GOHOME_TELEPORT 6 + +/** + * Given to Vampires if they have a Coffin claimed. + * Teleports them to their Coffin on use. + * Makes them drop everything if someone witnesses the act. + */ +/datum/action/cooldown/vampire/gohome + name = "Vanishing Act" + desc = "As dawn aproaches, disperse into mist and return directly to your lair.
    WARNING: You will drop ALL of your possessions if observed by mortals." + button_icon_state = "power_gohome" + power_explanation = "Activating Vanishing Act will, after a short delay, teleport you to your Claimed Coffin.\n\ + Immediately after activating, lights around the user will begin to flicker.\n\ + Once the user teleports to their coffin, in their place will be a Rat or Bat." + vampire_power_flags = BP_AM_STATIC_COOLDOWN + vampire_check_flags = BP_CANT_USE_IN_TORPOR | BP_CANT_USE_WHILE_STAKED | BP_CANT_USE_WHILE_INCAPACITATED | BP_CANT_USE_WHILE_UNCONSCIOUS | BP_CANT_USE_IN_FRENZY + vitaecost = 100 + cooldown_time = 5 MINUTES + ///What stage of the teleportation are we in + var/teleporting_stage = GOHOME_START + /// The types of mobs that will drop post-teleportation. + var/static/list/spawning_mobs = list( + /mob/living/basic/mouse = 3, + /mob/living/basic/bat = 1, + ) + +/datum/action/cooldown/vampire/gohome/can_use() + . = ..() + if(!.) + return FALSE + + /// Have No haven (NOTE: You only got this power if you had a haven, so this means it's destroyed) + if(!vampiredatum_power?.coffin) + owner.balloon_alert(owner, "coffin was destroyed!") + return FALSE + + if(owner.loc == vampiredatum_power.coffin) + owner.balloon_alert(owner, "you're already in your coffin!") + return FALSE + + if(!check_teleport_valid(owner, vampiredatum_power.coffin, TELEPORT_CHANNEL_MAGIC)) + owner.balloon_alert(owner, "something holds you back!") + return FALSE + + if((vampiredatum_power.current_vitae - vitaecost) <= vampiredatum_power.frenzy_threshold) + owner.balloon_alert(owner, "using this would send you into a frenzy!") + return FALSE + + if(!isturf(owner.loc)) + owner.balloon_alert(owner, "you cannot teleport right now!") + return FALSE + +/datum/action/cooldown/vampire/gohome/activate_power() + . = ..() + var/turf/old_turf = get_turf(owner) + teleport_to_coffin(owner) + flicker_lights(4, 60, old_turf) + +/datum/action/cooldown/vampire/gohome/proc/flicker_lights(flicker_range, beat_volume) + for(var/obj/machinery/light/nearby_lights in view(flicker_range, get_turf(owner))) + nearby_lights.flicker(5) + playsound(get_turf(owner), 'sound/effects/singlebeat.ogg', vol = beat_volume, vary = TRUE) + +/datum/action/cooldown/vampire/gohome/proc/teleport_to_coffin(mob/living/carbon/user) + var/turf/current_turf = get_turf(owner) + // If we aren't in the dark, anyone watching us will cause us to drop out stuff + if(GET_SIMPLE_LUMCOUNT(current_turf) >= 0.2) + for(var/mob/living/watcher in oviewers(world.view, get_turf(owner)) - owner) + if(vampiredatum_power.is_masq_watcher(watcher)) + user.unequip_everything() + break + user.uncuff() + + playsound(current_turf, 'sound/effects/magic/summon_karp.ogg', 60, 1) + + var/datum/effect_system/steam_spread/vampire/puff = new /datum/effect_system/steam_spread/vampire() + puff.set_up(3, 0, current_turf) + puff.start() + + /// STEP FIVE: Create animal at prev location + var/mob/living/simple_animal/new_mob = pick_weight(spawning_mobs) + new new_mob(current_turf) + /// TELEPORT: Move to Coffin & Close it! + user.set_resting(TRUE, TRUE, FALSE) + do_teleport(owner, vampiredatum_power.coffin, channel = TELEPORT_CHANNEL_MAGIC, no_effects = TRUE) + vampiredatum_power.coffin.close(owner) + vampiredatum_power.coffin.take_contents() + playsound(vampiredatum_power.coffin.loc, vampiredatum_power.coffin.close_sound, 15, TRUE, -3) + + deactivate_power() + +/datum/effect_system/steam_spread/vampire + effect_type = /obj/effect/particle_effect/fluid/smoke/vampsmoke + +#undef GOHOME_START +#undef GOHOME_FLICKER_ONE +#undef GOHOME_FLICKER_TWO +#undef GOHOME_TELEPORT diff --git a/tff_modular/modules/vampire/powers/levelspells.dm b/tff_modular/modules/vampire/powers/levelspells.dm new file mode 100644 index 00000000000..b9a247a48ed --- /dev/null +++ b/tff_modular/modules/vampire/powers/levelspells.dm @@ -0,0 +1,181 @@ +/** + * Given to Vampires at the start and taken away as soon as they select a clan. + */ +/datum/action/cooldown/vampire/clanselect + name = "Select Clan" + desc = "Take the first step as a true kindred and remember your true lineage." + button_icon_state = "clanselect" + power_explanation = "Activate to select your unique vampire clan." + vampire_power_flags = BP_AM_SINGLEUSE + vampire_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 + vitaecost = 0 + cooldown_time = 5 SECONDS + +/datum/action/cooldown/vampire/clanselect/activate_power() + . = ..() + vampiredatum_power.assign_clan_and_bane() + deactivate_power() + +/** + * Given to Vampires every levelup. Opens the radial. + */ +/datum/action/cooldown/vampire/levelup + name = "Level Up" + desc = "Take another step as a full kindred, and remember your true lineage." + button_icon_state = "power_levelup" + power_explanation = "Activate to level one of your disciplines." + vampire_power_flags = BP_AM_SINGLEUSE + vampire_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 + vitaecost = 0 + cooldown_time = 5 SECONDS + +/datum/action/cooldown/vampire/levelup/activate_power() + . = ..() + vampiredatum_power.my_clan.spend_rank() + deactivate_power() + +/** + * Given to Princes once chosen. Picks a scourge. + */ +/datum/action/cooldown/vampire/targeted/scourgify + name = "Select Scourge" + desc = "Select another kindred or one of your vassals as your scourge." + button_icon_state = "power_scourge" + power_explanation = "Activate to select another kindred, or one of your vassals, as your personal scourge.\n\n\ + When used on another kindred, they will receive some levels and an objective to obey you.\n\ + When used on your vassal, you will become their sire, embracing them as a full-blooded vampire.\n\ + They will be part of your own clan, and of course receive some bonus levels as well.\n\n\ + The Scourge is your enforcer, your tool to wield in the name of the Camarilla. Use them to enforce the masquerade, and to keep control over your fellow kindred." + vampire_power_flags = BP_AM_SINGLEUSE + vampire_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 + vitaecost = 0 + cooldown_time = 35 SECONDS + power_activates_immediately = FALSE + prefire_message = "Whom will you choose?" + + /// Reference to the target antag datum + var/datum/weakref/target_ref + + /// Are we currently in the process of promote someone? + /// This is just so we don't have any issues with using the power in the time between using it to scourgify someone and when it's removed. + var/promoting = FALSE + +/datum/action/cooldown/vampire/targeted/scourgify/check_valid_target(atom/target_atom) + . = ..() + if(!isliving(target_atom)) + return FALSE + + var/mob/living/living_target = target_atom + var/datum/antagonist/vampire/target_vampire = IS_VAMPIRE(living_target) + + // No mind + if(!living_target.mind) + owner.balloon_alert(owner, "mindless") + return FALSE + + // No client + if(!living_target.client) + owner.balloon_alert(owner, "not a player") + return FALSE + + // Is our target alive or unconcious? + if(living_target.stat != CONSCIOUS) + owner.balloon_alert(owner, "not [(living_target.stat == DEAD || HAS_TRAIT(living_target, TRAIT_FAKEDEATH)) ? "alive" : "conscious"]") + return FALSE + + if(IS_VASSAL(living_target) && !(IS_VASSAL(living_target) in vampiredatum_power.vassals)) // Only our own vassal may be promoted. + owner.balloon_alert(owner, "not your vassal") + return FALSE + + if(!IS_VAMPIRE(living_target) && !IS_VASSAL(living_target)) + owner.balloon_alert(owner, "not vassal or vampire") + return FALSE + + if(target_vampire && (target_vampire.prince || target_vampire.scourge)) + owner.balloon_alert(owner, "cannot promote elders!") + return FALSE + + if(target_ref || promoting) // Already offering + owner.balloon_alert(owner, "already offering!") + return FALSE + + return TRUE + +/datum/action/cooldown/vampire/targeted/scourgify/fire_targeted_power(atom/target_atom) + . = ..() + var/mob/living/living_target = target_atom + + var/datum/antagonist/vassal/vassal = IS_VASSAL(living_target) + + promoting = TRUE + + if(vassal) // We don't need to ask a lowly vassal. + // Pull them into our clan + var/datum/vampire_clan/masterclan_type = vampiredatum_power.my_clan?.type + + if(!masterclan_type) // How did a caitiff get prince, bro. Fine. + owner.balloon_alert(owner, "select clan first!") + deactivate_power() + return + + vassal.silent = TRUE + living_target.mind.remove_antag_datum(/datum/antagonist/vassal) + + // Make, then give the datum + var/datum/antagonist/vampire/scourgedatum = new(living_target.mind) + scourgedatum.should_forge_objectives = FALSE // their one objective is to enforce their prince's authority + scourgedatum.stinger_sound = null // to avoid several sounds stacking on top of each other + living_target.mind.add_antag_datum(scourgedatum) + + scourgedatum.my_clan = new masterclan_type(scourgedatum) + scourgedatum.my_clan.on_apply() + + // Scourgify and end power + scourgedatum.scourgify() + target_ref = null + power_activated_sucessfully() + return + else + target_ref = WEAKREF(IS_VAMPIRE(living_target)) + + owner.balloon_alert(owner, "you offer [living_target] the rank of Scourge...") + living_target.playsound_local(null, 'tff_modular/modules/vampire/sound/scourge_offer.ogg', 100, FALSE, pressure_affected = FALSE) + + ASYNC + var/choice = tgui_alert(living_target, + message = "Your Prince has selected you as [owner.p_their()] enforcer. Should you accept, you will receive the rank of 'Scourge', be bound to [owner.p_their()] authority, and increase in power considerably.", + title = "Scourge Offer", + buttons = list("Accept", "Refuse"), + timeout = cooldown_time - 5 SECONDS, + autofocus = TRUE + ) + handle_choice(choice) + + addtimer(CALLBACK(src, PROC_REF(choice_timeout)), cooldown_time) + deactivate_power() + +/datum/action/cooldown/vampire/targeted/scourgify/proc/accepted() + var/datum/antagonist/vampire/target_datum = target_ref.resolve() + target_datum.scourgify() + target_ref = null + power_activated_sucessfully() + +/datum/action/cooldown/vampire/targeted/scourgify/proc/refused() + owner.balloon_alert(owner, "offer refused") + target_ref = null + promoting = FALSE + +/datum/action/cooldown/vampire/targeted/scourgify/proc/choice_timeout() + if(owner && target_ref) // This might happen AFTER we remove the power from our owner. + owner.balloon_alert(owner, "offer ignored") + target_ref = null + promoting = FALSE + +/datum/action/cooldown/vampire/targeted/scourgify/proc/handle_choice(choice) + switch(choice) + if("Accept") + accepted() + return + if("Refuse") + refused() + return diff --git a/tff_modular/modules/vampire/powers/masquerade.dm b/tff_modular/modules/vampire/powers/masquerade.dm new file mode 100644 index 00000000000..659af49ddae --- /dev/null +++ b/tff_modular/modules/vampire/powers/masquerade.dm @@ -0,0 +1,79 @@ +/datum/action/cooldown/vampire/masquerade + name = "Masquerade" + desc = "Feign the vital signs of a mortal, and escape both casual and medical notice as the monster you truly are." + button_icon_state = "power_human" + power_explanation = "Masquerade will forge your identity to be practically identical to that of a human.\n\ + You lose nearly all Vampire benefits, including your passive healing.\n\ + You gain a Genetic sequence, and appear to have 100% blood when scanned by a Health Analyzer.\n\ + You won't appear as pale when examined. Anything further than pale, however, will not be hidden.\n\ + After deactivating Masquerade, you will re-gain your Vampiric abilities, as well as lose any Diseases or mutations you might have gained." + vampire_power_flags = BP_AM_TOGGLE | BP_AM_STATIC_COOLDOWN | BP_AM_COSTLESS_UNCONSCIOUS + vampire_check_flags = BP_CANT_USE_IN_FRENZY | BP_CANT_USE_IN_TORPOR | BP_CANT_USE_WHILE_STAKED + vitaecost = 10 + cooldown_time = 5 SECONDS + constant_vitaecost = 0.1 + +/datum/action/cooldown/vampire/masquerade/activate_power() + . = ..() + var/mob/living/carbon/carbon_owner = owner + carbon_owner.balloon_alert(carbon_owner, "masquerade turned on.") + carbon_owner.apply_status_effect(/datum/status_effect/masquerade) + +/datum/action/cooldown/vampire/masquerade/deactivate_power() + . = ..() + var/mob/living/carbon/carbon_owner = owner + carbon_owner.balloon_alert(carbon_owner, "masquerade turned off.") + carbon_owner.remove_status_effect(/datum/status_effect/masquerade) + +/datum/status_effect/masquerade + id = "masquerade" + duration = STATUS_EFFECT_PERMANENT + tick_interval = STATUS_EFFECT_NO_TICK + alert_type = /atom/movable/screen/alert/status_effect/masquerade + +/atom/movable/screen/alert/status_effect/masquerade + name = "Masquerade" + desc = "You are currently hiding your identity using the Masquerade power. This halts Vampiric healing." + icon = 'tff_modular/modules/vampire/icons/actions_vampire.dmi' + icon_state = "masquerade_alert" + alerttooltipstyle = "cult" + +/datum/status_effect/masquerade/on_apply() + var/mob/living/carbon/carbon_owner = owner + var/datum/antagonist/vampire/vampiredatum = IS_VAMPIRE(carbon_owner) + if(!vampiredatum) + return FALSE + + // Handle Traits + carbon_owner.remove_traits(vampiredatum.vampire_traits - vampiredatum.always_traits, TRAIT_VAMPIRE) + carbon_owner.add_traits(list(TRAIT_MASQUERADE, TRAIT_FAKEGENES), TRAIT_STATUS_EFFECT(id)) + + // Handle organs + var/obj/item/organ/heart/vampheart = carbon_owner.get_organ_by_type(/obj/item/organ/heart) + vampheart?.Restart() + + to_chat(carbon_owner, span_notice("Your heart beats falsely within your lifeless chest. You may yet pass for a mortal.")) + to_chat(carbon_owner, span_warning("Your vampiric healing is halted while imitating life.")) + + return TRUE + +/datum/status_effect/masquerade/on_remove() + var/mob/living/carbon/carbon_owner = owner + var/datum/antagonist/vampire/vampiredatum = IS_VAMPIRE(carbon_owner) + if(!vampiredatum) + return + + // Clear mutations and diseases + carbon_owner.dna.remove_all_mutations() + for(var/datum/disease/diseases in carbon_owner.diseases) + diseases.cure(target = carbon_owner, safe = TRUE) + + // Handle Traits + carbon_owner.add_traits(vampiredatum.vampire_traits, TRAIT_VAMPIRE) + carbon_owner.remove_traits(list(TRAIT_MASQUERADE, TRAIT_FAKEGENES), TRAIT_STATUS_EFFECT(id)) + + // Handle organs + var/obj/item/organ/heart/vampheart = carbon_owner.get_organ_slot(ORGAN_SLOT_HEART) + vampheart?.Stop() + + to_chat(carbon_owner, span_notice("Your heart beats one final time, while your skin dries out and your icy pallor returns.")) diff --git a/tff_modular/modules/vampire/powers/obfuscate/cloak.dm b/tff_modular/modules/vampire/powers/obfuscate/cloak.dm new file mode 100644 index 00000000000..b32f69fb541 --- /dev/null +++ b/tff_modular/modules/vampire/powers/obfuscate/cloak.dm @@ -0,0 +1,70 @@ +/datum/action/cooldown/vampire/cloak + name = "Cloak of Darkness" + desc = "Blend into the shadows and become invisible to the artificial eye." + button_icon_state = "power_cloak" + power_explanation = "Activate this Power while unseen and you will turn nearly invisible, scaling with your rank.\n\ + Additionally, while Cloak is active, you are completely invisible to silicons." + vampire_power_flags = BP_AM_TOGGLE + vampire_check_flags = BP_CANT_USE_IN_TORPOR | BP_CANT_USE_WHILE_STAKED | BP_CANT_USE_IN_FRENZY | BP_CANT_USE_WHILE_UNCONSCIOUS + vitaecost = 50 + constant_vitaecost = 1 + cooldown_time = 5 SECONDS + var/cloaklevel = 20 + +/datum/action/cooldown/vampire/cloak/two + vitaecost = 40 + constant_vitaecost = 2 + cloaklevel = 15 + +/datum/action/cooldown/vampire/cloak/three + vitaecost = 30 + constant_vitaecost = 3 + cloaklevel = 10 + +/datum/action/cooldown/vampire/cloak/four + vitaecost = 20 + constant_vitaecost = 4 + cloaklevel = 5 + +/// Must have nobody around to see the cloak +/datum/action/cooldown/vampire/cloak/can_use() + . = ..() + if(!.) + return FALSE + + return TRUE + +/datum/action/cooldown/vampire/cloak/activate_power() + . = ..() + check_witnesses() + var/mob/living/user = owner + ADD_TRAIT(user, TRAIT_UNKNOWN_APPEARANCE, REF(src)) + user.add_movespeed_modifier(/datum/movespeed_modifier/cloak) + user.AddElement(/datum/element/digitalcamo) + user.balloon_alert(user, "cloak turned on.") + animate(user, alpha = cloaklevel, time = 1 SECONDS) + apply_wibbly_filters(user) + +/datum/action/cooldown/vampire/cloak/continue_active() + . = ..() + if(!.) + return FALSE + + if(owner.stat != CONSCIOUS) + to_chat(owner, span_warning("Your cloak failed because you fell unconcious!")) + return FALSE + return TRUE + +/datum/action/cooldown/vampire/cloak/deactivate_power() + var/mob/living/user = owner + + remove_wibbly_filters(user, 1 SECONDS) + animate(user, alpha = 255, time = 1 SECONDS) + REMOVE_TRAIT(user, TRAIT_UNKNOWN_APPEARANCE, REF(src)) + user.RemoveElement(/datum/element/digitalcamo) + user.remove_movespeed_modifier(/datum/movespeed_modifier/cloak) + user.balloon_alert(user, "cloak turned off.") + return ..() + +/datum/movespeed_modifier/cloak + multiplicative_slowdown = 1.5 diff --git a/tff_modular/modules/vampire/powers/obfuscate/obfuscate.dm b/tff_modular/modules/vampire/powers/obfuscate/obfuscate.dm new file mode 100644 index 00000000000..6e2d231d304 --- /dev/null +++ b/tff_modular/modules/vampire/powers/obfuscate/obfuscate.dm @@ -0,0 +1,11 @@ +/datum/discipline/obfuscate + name = "Obfuscate" + discipline_explanation = "Obfuscate is a Discipline that allows vampires to conceal themselves, deceive the mind of others, or make them ignore what the user does not want to be seen." + icon_state = "obfuscate" + + // Lists of abilities granted per level + level_1 = list(/datum/action/cooldown/vampire/cloak) + level_2 = list(/datum/action/cooldown/vampire/cloak/two, /datum/action/cooldown/vampire/targeted/trespass) + level_3 = list(/datum/action/cooldown/vampire/cloak/three, /datum/action/cooldown/vampire/targeted/trespass/two) + level_4 = list(/datum/action/cooldown/vampire/cloak/four, /datum/action/cooldown/vampire/targeted/trespass/three, /datum/action/cooldown/vampire/veil) + level_5 = null diff --git a/tff_modular/modules/vampire/powers/obfuscate/trespass.dm b/tff_modular/modules/vampire/powers/obfuscate/trespass.dm new file mode 100644 index 00000000000..2a42b8ce996 --- /dev/null +++ b/tff_modular/modules/vampire/powers/obfuscate/trespass.dm @@ -0,0 +1,107 @@ +/datum/action/cooldown/vampire/targeted/trespass + name = "Trespass" + desc = "Become mist and advance two tiles in one direction. Useful for skipping past doors and barricades." + button_icon_state = "power_tres" + power_explanation = "Click anywhere from 1-2 tiles away from you to teleport.\n\ + This power goes through all obstacles except Walls.\n\ + Higher levels decrease the sound played from using the Power, and increase the speed of the transition." + vampire_power_flags = BP_AM_TOGGLE + vampire_check_flags = BP_CANT_USE_IN_TORPOR | BP_CANT_USE_WHILE_STAKED | BP_CANT_USE_WHILE_INCAPACITATED | BP_CANT_USE_WHILE_UNCONSCIOUS + vitaecost = 30 + cooldown_time = 8 SECONDS + prefire_message = "Select a destination." + ranged_mousepointer = 'tff_modular/modules/vampire/icons/vampire_trespass.dmi' + //target_range = 2 + var/turf/target_turf // We need to decide where we're going based on where we clicked. It's not actually the tile we clicked. + level_current = 1 + +/datum/action/cooldown/vampire/targeted/trespass/two + level_current = 2 + vitaecost = 50 + +/datum/action/cooldown/vampire/targeted/trespass/three + level_current = 3 + vitaecost = 70 + +/datum/action/cooldown/vampire/targeted/trespass/can_use() + . = ..() + if(!.) + return FALSE + + if(HAS_TRAIT(owner, TRAIT_NO_TRANSFORM)) + return FALSE + if(!get_turf(owner)) + return FALSE + +/datum/action/cooldown/vampire/targeted/trespass/check_valid_target(atom/target_atom) + . = ..() + if(!.) + return FALSE + + // Can't trespass to the same tile we're already on + if(target_atom.loc == owner.loc) + return FALSE + // Check if path is obstructed + var/turf/starting_turf = get_turf(owner) + var/turf/ending_turf = isturf(target_atom) ? target_atom : get_turf(target_atom) + var/this_dir + for(var/i = 1 to 2) + // Keep Prev Direction if we've reached final turf + if(starting_turf != ending_turf) + this_dir = get_dir(starting_turf, ending_turf) + starting_turf = get_step(starting_turf, this_dir) + // Walls block trespass + if(iswallturf(starting_turf)) + var/wallwarning = (i == 1) ? "in the way" : "at your destination" + owner.balloon_alert(owner, "there is a wall [wallwarning].") + return FALSE + + target_turf = starting_turf + +/datum/action/cooldown/vampire/targeted/trespass/fire_targeted_power(atom/target_atom) + . = ..() + + // Find target turf, at or below Atom + var/mob/living/carbon/user = owner + var/turf/my_turf = get_turf(owner) + + user.visible_message( + span_warning("[user]'s form dissipates into a cloud of mist!"), + span_notice("You disspiate into formless mist."), + ) + // Effect Origin + var/sound_strength = max(40, 100 - level_current * 20) + playsound(get_turf(owner), 'sound/effects/magic/summon_karp.ogg', vol = sound_strength, vary = TRUE) + var/datum/effect_system/steam_spread/vampire/puff = new /datum/effect_system/steam_spread() + puff.set_up(3, FALSE, my_turf) + puff.start() + + var/mist_delay = max(5, 20 - level_current * 2.5) // Level up and do this faster. + + // Freeze Me + user.Stun(mist_delay, ignore_canstun = TRUE) + ADD_TRAIT(user, TRAIT_UNDENSE, REF(src)) + user.SetInvisibility(INVISIBILITY_MAXIMUM, "vampire_trespass") + + // Wait... + sleep(mist_delay / 2) + // Move & Freeze + if(isturf(target_turf)) + do_teleport(owner, target_turf, no_effects = TRUE, channel = TELEPORT_CHANNEL_QUANTUM) // in teleport.dm? + user.Stun(mist_delay / 2, ignore_canstun = TRUE) + + // Wait... + sleep(mist_delay / 2) + + // Un-Hide & Freeze + user.setDir(get_dir(my_turf, target_turf)) + user.Stun(mist_delay / 2, ignore_canstun = TRUE) + REMOVE_TRAIT(user, TRAIT_UNDENSE, REF(src)) + user.RemoveInvisibility("vampire_trespass") + + check_witnesses() + // Effect Destination + playsound(get_turf(owner), 'sound/effects/magic/summon_karp.ogg', vol = 60, vary = TRUE) + puff = new /datum/effect_system/steam_spread() + puff.set_up(3, FALSE, target_turf) + puff.start() diff --git a/tff_modular/modules/vampire/powers/obfuscate/veil.dm b/tff_modular/modules/vampire/powers/obfuscate/veil.dm new file mode 100644 index 00000000000..ed2b78417b1 --- /dev/null +++ b/tff_modular/modules/vampire/powers/obfuscate/veil.dm @@ -0,0 +1,76 @@ +/datum/action/cooldown/vampire/veil + name = "Veil of Many Faces" + desc = "Disguise yourself in the illusion of another identity." + button_icon_state = "power_veil" + power_explanation = "Activating Veil of Many Faces will shroud you in smoke and forge you a new identity.\n\ + Your name and appearance will be completely randomized, deactivating the ability will restore you to your former self." + vampire_power_flags = BP_AM_TOGGLE + vampire_check_flags = BP_CANT_USE_IN_FRENZY | BP_CANT_USE_WHILE_STAKED + vitaecost = 100 + constant_vitaecost = 4 + cooldown_time = 10 SECONDS + + var/datum/dna/original_dna + var/prev_disfigured + var/original_name + var/alist/original_clothing_prefs + +/datum/action/cooldown/vampire/veil/activate_power() + . = ..() + cast_effect() // POOF + veil_user() + owner.balloon_alert(owner, "veil turned on.") + +/datum/action/cooldown/vampire/veil/proc/veil_user() + if(!ishuman(owner)) + return + var/mob/living/carbon/human/user = owner + to_chat(owner, span_warning("You mystify the air around your person. Your identity is now altered.")) + original_dna = new user.dna.type + original_name = user.real_name + original_clothing_prefs = user.backup_clothing_prefs() + user.dna.copy_dna(original_dna) + randomize_human(user) + prev_disfigured = HAS_TRAIT(user, TRAIT_DISFIGURED) // I was disfigured! //prev_disabilities = user.disabilities + if(prev_disfigured) + REMOVE_TRAIT(user, TRAIT_DISFIGURED, null) + + to_chat(owner, span_warning("You mystify the air around your person. Your identity is now altered.")) + +/datum/action/cooldown/vampire/veil/deactivate_power() + . = ..() + if(!ishuman(owner)) + return + var/mob/living/carbon/human/user = owner + to_chat(user, span_notice("You return to your old form.")) + original_dna.copy_dna(user.dna, COPY_DNA_SE|COPY_DNA_SPECIES|COPY_DNA_MUTATIONS) + user.real_name = original_name + user.restore_clothing_prefs(original_clothing_prefs) + user.updateappearance(mutcolor_update = TRUE) + //user.disabilities = prev_disabilities // Restore HUSK, CLUMSY, etc. + if(prev_disfigured) + //We are ASSUMING husk. // user.status_flags |= DISFIGURED // Restore "Unknown" disfigurement + ADD_TRAIT(user, TRAIT_DISFIGURED, TRAIT_HUSK) + + original_dna = null + + cast_effect() // POOF + owner.balloon_alert(owner, "veil turned off.") + +// CAST EFFECT // General effect (poof, splat, etc) when you cast. Doesn't happen automatically! +/datum/action/cooldown/vampire/veil/proc/cast_effect() + // Effect + playsound(get_turf(owner), 'sound/effects/smoke.ogg', 20, 1) + var/datum/effect_system/steam_spread/vampire/puff = new /datum/effect_system/steam_spread/() + puff.set_up(3, 0, get_turf(owner)) + puff.attach(owner) //OPTIONAL + puff.start() + owner.spin(0.8 SECONDS, 1) //Spin around like a loon. + check_witnesses() + +/obj/effect/particle_effect/fluid/smoke/vampsmoke + opacity = FALSE + lifetime = 0 + +/obj/effect/particle_effect/fluid/smoke/vampsmoke/fade_out(frames = 0.8 SECONDS) + ..(frames) diff --git a/tff_modular/modules/vampire/powers/potence/brash.dm b/tff_modular/modules/vampire/powers/potence/brash.dm new file mode 100644 index 00000000000..cdd3065c9ed --- /dev/null +++ b/tff_modular/modules/vampire/powers/potence/brash.dm @@ -0,0 +1,170 @@ +/** + * A Brujah exclusive ability that acts as an enhanced version of "Brawn" + * 'vitaecost' and 'cooldown_time' vary depending on what the power is used for. + * Lots of code has been copied over from Brawn wherever inheritance might prove insufficient. + * Comments from copied code have been removed (they can still be found in their original location.) +**/ + +/datum/action/cooldown/vampire/targeted/brawn/brash + name = "Brash" + desc = "Break most structures apart with overwhelming force. Cooldown and cost vary depending on the object broken." + button_icon_state = "power_strength_brujah" + power_explanation = "This is an enhanced version of the regular 'Brawn' ability.\n\ + Use on a person to send them flying. Use while restrained, grabbed, or trapped in a locker to break free.\n\ + Punching a cyborg will temporarily disable it in addition to usual damage. \n\ + At level 2 this ability will allow you to break through unbolted airlocks. \n\ + At level 3 this ability will allow you to break through bolted airlocks. \n\ + At level 4 this ability will allow you to break through normal walls and windows, and can break silver handcuffs. \n\ + At level 5 this ability will allow you to break through reinforced walls and windows. \n\ + Higher levels will increase this ability's damage and knockdown." + vampire_power_flags = BP_AM_VERY_DYNAMIC_COOLDOWN + vitaecost = 0 // Set on use + cooldown_time = 1 SECONDS // Same as above + damage_coefficient = 1.625 + brujah = TRUE + level_current = 1 + +/datum/action/cooldown/vampire/targeted/brawn/brash/two + level_current = 2 + +/datum/action/cooldown/vampire/targeted/brawn/brash/three + level_current = 3 + +/datum/action/cooldown/vampire/targeted/brawn/brash/four + level_current = 4 + +/datum/action/cooldown/vampire/targeted/brawn/brash/five + level_current = 5 + +/// Hit an atom, set vitaecost, set cooldown time, play a sound, and deconstruct the atom +/// with this one convenient proc! +/datum/action/cooldown/vampire/targeted/brawn/brash/proc/hit_with_style(atom/target_atom, sound, vol as num, cost as num, cooldown) + if(!isobj(target_atom)) + return + + var/obj/target_obj = target_atom + owner.do_attack_animation(target_obj) + vitaecost = cost + cooldown_time = cooldown + playsound(target_atom, sound, 75, TRUE) + target_obj.deconstruct(FALSE) + +/datum/action/cooldown/vampire/targeted/brawn/brash/fire_targeted_power(atom/target_atom) + . = ..() + // People + if(isliving(target_atom)) + vitaecost = 50 + cooldown_time = 10 SECONDS + return + + // Closets + if(istype(target_atom, /obj/structure/closet)) + vitaecost = 50 + cooldown_time = 7 SECONDS + return + + // Girders + if(istype(target_atom, /obj/structure/girder)) + hit_with_style(target_atom, 'sound/effects/bang.ogg', 60, 300, 5 SECONDS) + return + + // Grilles + if(istype(target_atom, /obj/structure/grille)) + hit_with_style(target_atom, 'sound/effects/grillehit.ogg', 50, 10, 0.5 SECONDS) + return + + // Windows + if(istype(target_atom, /obj/structure/window)) + var/obj/structure/window/window = target_atom + if(istype(target_atom, /obj/structure/window/reinforced) && level_current < 5) + window.balloon_alert(owner, "level 5 required!") + return + else if(level_current < 4) + window.balloon_alert(owner, "level 4 required!") + return + + if(istype(window, /obj/structure/window/reinforced) || istype(window, /obj/structure/window/plasma)) + hit_with_style(window, 'sound/effects/bang.ogg', 30, 50, 15 SECONDS) + else + hit_with_style(window, 'sound/effects/bang.ogg', 20, 75, 10 SECONDS) + return + + // Windoors + if(istype(target_atom, /obj/machinery/door/window)) + hit_with_style(target_atom, 'sound/effects/bang.ogg', 50, 35, 5 SECONDS) + return + + // Tables + if(istype(target_atom, /obj/structure/table)) + hit_with_style(target_atom, 'sound/effects/bang.ogg', 35, 25, 5 SECONDS) + return + + // Walls + if(iswallturf(target_atom)) + if(isindestructiblewall(target_atom)) + target_atom.balloon_alert(owner, "this wall is indestructible!") + return + + if(istype(target_atom, /turf/closed/wall/r_wall) && level_current < 5) + target_atom.balloon_alert(owner, "level 5 required!") + return + else if(level_current < 4) + target_atom.balloon_alert(owner, "level 4 required!") + return + + rip_and_tear(owner, target_atom) + +/// Copied over from '/datum/element/wall_tearer/proc/rip_and_tear' with appropriate adjustment. +/datum/action/cooldown/vampire/targeted/brawn/brash/proc/rip_and_tear(mob/living/tearer, atom/target) + var/tear_time = 0.75 SECONDS + var/reinforced_multiplier = 5 + var/rip_time = (istype(target, /turf/closed/wall/r_wall) ? tear_time * reinforced_multiplier : tear_time) + + if(istype(target, /turf/closed/wall/r_wall)) + vitaecost = 100 + cooldown_time = 20 SECONDS + else + vitaecost = 85 + cooldown_time = 15 SECONDS + + while(iswallturf(target)) + var/turf/closed/wall/wall = target + + tearer.visible_message(span_warning("[tearer] viciously rips into [wall]!")) + playsound(tearer, 'sound/machines/airlock/airlock_alien_prying.ogg', vol = 50, vary = TRUE, frequency = 2) + wall.balloon_alert(tearer, "tearing...") + + if(do_after(tearer, delay = rip_time, target = wall, interaction_key = "vampire interaction")) + playsound(tearer, 'sound/effects/meteorimpact.ogg', 100, TRUE) + tearer.do_attack_animation(wall) + wall.dismantle_wall(1) + return + else + tearer.balloon_alert(tearer, "interrupted!") + +/// TODO: check if switch statements work with istype() +/datum/action/cooldown/vampire/targeted/brawn/brash/check_valid_target(atom/target_atom) + . = ..() + if(!.) + return FALSE + + if(target_atom.resistance_flags & INDESTRUCTIBLE) + return FALSE + if(isliving(target_atom)) + return TRUE + if(istype(target_atom, /obj/machinery/door/airlock)) + return TRUE + if(istype(target_atom, /obj/structure/table)) + return TRUE + if(istype(target_atom, /obj/structure/closet)) + return TRUE + if(istype(target_atom, /obj/structure/girder)) + return TRUE + if(istype(target_atom, /obj/structure/grille)) + return TRUE + if(istype(target_atom, /obj/structure/window)) + return TRUE + if(iswallturf(target_atom)) + return TRUE + + return FALSE diff --git a/tff_modular/modules/vampire/powers/potence/brawn.dm b/tff_modular/modules/vampire/powers/potence/brawn.dm new file mode 100644 index 00000000000..f92645ab92d --- /dev/null +++ b/tff_modular/modules/vampire/powers/potence/brawn.dm @@ -0,0 +1,235 @@ +/datum/action/cooldown/vampire/targeted/brawn + name = "Brawn" + desc = "Snap restraints, break lockers and doors, or deal terrible damage with your bare hands." + button_icon_state = "power_strength" + power_explanation = "Use this power to deal a horrific blow. Punching a Cyborg will EMP it and deal high damage.\n\ + At level 3, you can break closets open and break restraints.\n\ + At level 4, you can bash airlocks open, and you get the ability to break even silver handcuffs. Use wisely - security is unlikely to try and capture you alive again after the first time!\n\ + Higher ranks will increase the damage when punching someone." + vampire_power_flags = BP_AM_TOGGLE + vampire_check_flags = BP_CANT_USE_IN_TORPOR | BP_CANT_USE_WHILE_STAKED | BP_CANT_USE_IN_FRENZY | BP_CANT_USE_WHILE_INCAPACITATED | BP_CANT_USE_WHILE_UNCONSCIOUS + vitaecost = 50 + cooldown_time = 9 SECONDS + target_range = 1 + power_activates_immediately = TRUE + prefire_message = "Select a target." + level_current = 1 + ranged_mousepointer = 'tff_modular/modules/vampire/icons/vampire_strength.dmi' + + /// Only changed by the '/brawn/brash' subtype; acts as a general purpose damage multipler. + var/damage_coefficient = 1.25 + /// Boolean indicating whether or not this version of '/brawn' is in the '/brash' subtype and should + /// bypass typical ability level restrictions. (There is probably a better way to do this.) + var/brujah = FALSE + +/datum/action/cooldown/vampire/targeted/brawn/two + level_current = 2 + +/datum/action/cooldown/vampire/targeted/brawn/three + level_current = 3 + +/datum/action/cooldown/vampire/targeted/brawn/four + level_current = 4 + +/datum/action/cooldown/vampire/targeted/brawn/activate_power() + // Did we break out of our handcuffs? + if(break_restraints()) + power_activated_sucessfully() + return + // Did we knock a grabber down? We can only do this while not also breaking restraints if strong enough. + if(level_current >= 3 && escape_puller()) + power_activated_sucessfully() + return + // Did neither, now we can PUNCH. + . = ..() + +// Look at 'biodegrade.dm' for reference +/datum/action/cooldown/vampire/targeted/brawn/proc/break_restraints() + if(!ishuman(owner)) + return FALSE + + var/mob/living/carbon/human/human_owner = owner + + var/used = FALSE + + // Lockers + if(istype(human_owner.loc, /obj/structure/closet)) + var/obj/structure/closet/closet = human_owner.loc + addtimer(CALLBACK(closet, TYPE_PROC_REF(/obj/structure/closet, bust_open), FALSE), 0.1 SECONDS) + closet.visible_message( + span_warning("[closet] tears apart as [human_owner] bashes it open from within!"), + span_warning("[closet] tears apart as you bash it open from within!") + ) + to_chat(human_owner, span_warning("We bash [closet] wide open!")) + used = TRUE + + // Cuffs + if(human_owner.handcuffed || human_owner.legcuffed) + human_owner.uncuff() + human_owner.visible_message( + span_warning("[human_owner] discards [human_owner.p_their()] restraints like it's nothing!"), + span_warning("We break through our restraints!") + ) + used = TRUE + + // Straightjackets + if(human_owner.wear_suit?.breakouttime) + var/obj/item/clothing/suit/straightjacket = human_owner.get_item_by_slot(ITEM_SLOT_OCLOTHING) + if(straightjacket && human_owner.wear_suit == straightjacket) + qdel(straightjacket) + human_owner.visible_message( + span_warning("[human_owner] rips straight through the [human_owner.p_their()] [straightjacket]!"), + span_warning("We tear through our [straightjacket]!") + ) + used = TRUE + + if(used) + playsound(get_turf(human_owner), 'sound/effects/grillehit.ogg', 80, TRUE, -1) + + /* if(used) + check_witnesses() */ + return used + +/datum/action/cooldown/vampire/targeted/brawn/proc/escape_puller() + if(!owner.pulledby) + return FALSE + + var/mob/pulled_mob = owner.pulledby + var/pull_power = pulled_mob.grab_state + playsound(get_turf(pulled_mob), 'sound/effects/woodhit.ogg', 75, TRUE, -1) + + // Knock Down (if Living) + if(isliving(pulled_mob)) + var/mob/living/hit_target = pulled_mob + hit_target.Knockdown(pull_power * 10 + 20) + + // Knock Back (before Knockdown, which probably cancels pull) + var/send_dir = get_dir(owner, pulled_mob) + var/turf/turf_thrown_at = get_ranged_target_turf(pulled_mob, send_dir, pull_power) + owner.newtonian_move(send_dir) // Bounce back in 0 G + pulled_mob.throw_at(turf_thrown_at, pull_power, TRUE, owner, FALSE) // Throw distance based on grab state! Harder grabs punished more aggressively. + + log_combat(owner, pulled_mob, "used [src.name] power") + owner.visible_message( + span_warning("[owner] tears free of [pulled_mob]'s grasp!"), + span_warning("You shrug off [pulled_mob]'s grasp!") + ) + owner.pulledby?.stop_pulling() // It's already done, but JUST IN CASE. + + // check_witnesses() + return TRUE + +/datum/action/cooldown/vampire/targeted/brawn/fire_targeted_power(atom/target_atom) + . = ..() + var/mob/living/carbon/carbon_owner = owner + + // Living Targets + if(isliving(target_atom)) + var/mob/living/living_target = target_atom + + // Strength of the attack + var/obj/item/bodypart/user_active_arm = carbon_owner.get_active_hand() + var/hit_strength = user_active_arm.unarmed_damage_high * damage_coefficient + 2 + + var/powerlevel = min(5, 1 + level_current) + + if(rand(5 + powerlevel) >= 5) + living_target.visible_message( + span_danger("[carbon_owner] lands a vicious punch, sending [living_target] away!"), \ + span_userdanger("[carbon_owner] has landed a horrifying punch on you, sending you flying!"), + ) + living_target.Knockdown(min(5, rand(10, 10 * powerlevel))) + + // Attack! + owner.balloon_alert(owner, "you punch [living_target]!") + playsound(get_turf(living_target), 'sound/items/weapons/punch4.ogg', 60, TRUE, -1) + // check_witnesses(living_target) + carbon_owner.do_attack_animation(living_target, ATTACK_EFFECT_SMASH) + + var/obj/item/bodypart/affecting = living_target.get_bodypart(ran_zone(living_target.zone_selected)) + living_target.apply_damage(hit_strength, BRUTE, affecting) + + // Knockback + var/send_dir = get_dir(owner, living_target) + var/turf/turf_thrown_at = get_ranged_target_turf(living_target, send_dir, powerlevel) + owner.newtonian_move(send_dir) // Bounce back in 0 G + living_target.throw_at(turf_thrown_at, powerlevel, TRUE, owner) + + // Target Type: Cyborg (Also gets the effects above) + if(issilicon(living_target)) + living_target.emp_act(EMP_HEAVY) + // Lockers + else if(istype(target_atom, /obj/structure/closet)) + var/obj/structure/closet/target_closet = target_atom + + playsound(get_turf(carbon_owner), 'sound/machines/airlock/airlock_alien_prying.ogg', 40, TRUE, -1) + carbon_owner.balloon_alert(carbon_owner, "you prepare to bash [target_closet] open...") + if(!do_after(carbon_owner, 2.5 SECONDS, target_closet)) + carbon_owner.balloon_alert(carbon_owner, "interrupted!") + return FALSE + target_closet.visible_message(span_danger("[target_closet] breaks open as [carbon_owner] bashes it!")) + + INVOKE_ASYNC(target_closet, TYPE_PROC_REF(/obj/structure/closet, bust_open), FALSE) + playsound(get_turf(carbon_owner), 'sound/effects/grillehit.ogg', 80, TRUE, -1) + // check_witnesses() + // Airlocks + else if(istype(target_atom, /obj/machinery/door/airlock)) + var/obj/machinery/door/airlock/target_airlock = target_atom + + playsound(get_turf(carbon_owner), 'sound/machines/airlock/airlock_alien_prying.ogg', 40, TRUE, -1) + // check_witnesses() + owner.balloon_alert(owner, "you prepare to tear open [target_airlock]...") + if(!do_after(carbon_owner, 2.5 SECONDS, target_airlock)) + carbon_owner.balloon_alert(carbon_owner, "interrupted!") + return FALSE + + if(target_airlock.Adjacent(carbon_owner)) + target_airlock.visible_message(span_danger("[target_airlock] breaks open as [carbon_owner] bashes it!")) + + // Adjust cost and cooldown if Brujah + if(brujah) + if(target_airlock.locked) + vitaecost = 100 + cooldown_time = 10 SECONDS + else + vitaecost = 75 + cooldown_time = 6 SECONDS + else // If not Brujah then just make the vampire wait a second... + carbon_owner.Stun(1 SECONDS) + + carbon_owner.Stun(1 SECONDS) + carbon_owner.do_attack_animation(target_airlock, ATTACK_EFFECT_SMASH) + playsound(get_turf(target_airlock), 'sound/effects/bang.ogg', 30, TRUE, -1) + if(brujah && level_current >= 3 && target_airlock.locked) + target_airlock.unbolt() + target_airlock.open(BYPASS_DOOR_CHECKS) + +/datum/action/cooldown/vampire/targeted/brawn/check_valid_target(atom/target_atom) + . = ..() + if(!.) + return FALSE + + // Brujah has their own checks + if(brujah) + return TRUE + + if(isliving(target_atom)) + return TRUE + + if(istype(target_atom, /obj/machinery/door/airlock)) + if(level_current < 4) + owner.balloon_alert(owner, "level 4 required!") + return FALSE + + return TRUE + + if(istype(target_atom, /obj/structure/closet)) + if(level_current < 3) + owner.balloon_alert(owner, "level 3 required!") + return FALSE + + var/obj/structure/closet/target_closet = target_atom + if(target_closet.welded || target_closet.locked) + return TRUE + + return FALSE diff --git a/tff_modular/modules/vampire/powers/potence/lunge.dm b/tff_modular/modules/vampire/powers/potence/lunge.dm new file mode 100644 index 00000000000..79480eaec06 --- /dev/null +++ b/tff_modular/modules/vampire/powers/potence/lunge.dm @@ -0,0 +1,178 @@ +#define LUNGE_TIME 3 SECONDS + +/datum/action/cooldown/vampire/targeted/lunge + name = "Predatory Lunge" + desc = "Spring at your target to grapple them without warning, or tear the dead's heart out. Attacks from concealment or the rear may even knock them down if strong enough." + button_icon_state = "power_lunge" + power_explanation = "Click any player to start spinning wildly and, after a short delay, lunge at them.\n\ + You cannot lunge if you are already grabbing someone, or are being grabbed.\n\ + If you lunge from behind or darkness, you will aggro-grab and knock the target down, scaling with your rank.\n\ + If used on a dead body, you will tear their organs out.\n\ + At level 4, you will instantly lunge, but are limited to tackling from only 6 tiles away." + vampire_power_flags = NONE + vampire_check_flags = BP_CANT_USE_IN_TORPOR | BP_CANT_USE_WHILE_STAKED | BP_CANT_USE_IN_FRENZY | BP_CANT_USE_WHILE_INCAPACITATED | BP_CANT_USE_WHILE_UNCONSCIOUS + vitaecost = 45 + cooldown_time = 10 SECONDS + power_activates_immediately = FALSE + ranged_mousepointer = 'tff_modular/modules/vampire/icons/vampire_lunge.dmi' + + var/instant = FALSE + var/knockdown_bonus = 1 + +/datum/action/cooldown/vampire/targeted/lunge/two + vitaecost = 60 + cooldown_time = 10 SECONDS + knockdown_bonus = 2 + +/datum/action/cooldown/vampire/targeted/lunge/three + vitaecost = 75 + cooldown_time = 8 SECONDS + knockdown_bonus = 3 + +/datum/action/cooldown/vampire/targeted/lunge/four + vitaecost = 90 + cooldown_time = 6 SECONDS + knockdown_bonus = 4 + instant = TRUE + +/datum/action/cooldown/vampire/targeted/lunge/can_use() + . = ..() + if(!.) + return FALSE + + if(owner.pulledby && owner.pulledby.grab_state >= GRAB_AGGRESSIVE) + owner.balloon_alert(owner, "grabbed!") + return FALSE + if(owner.pulling) + owner.balloon_alert(owner, "grabbing someone!") + return FALSE + if(datum_flags & DF_ISPROCESSING) + owner.balloon_alert(owner, "already lunging!") + return FALSE + return TRUE + +/// Check: Are we lunging at a person? +/datum/action/cooldown/vampire/targeted/lunge/check_valid_target(atom/target_atom) + . = ..() + if(!.) + return FALSE + + // Has to be alive + if(!isliving(target_atom)) + return FALSE + // Has to be on a turf + if(!isturf(target_atom.loc)) + return FALSE + // Has to be mobile + var/mob/living/user = owner + if(user.body_position == LYING_DOWN || HAS_TRAIT(owner, TRAIT_IMMOBILIZED)) + return FALSE + + if(get_dist(owner, target_atom) > 7) + owner.balloon_alert(owner, "too far away!") + return FALSE + +/datum/action/cooldown/vampire/targeted/lunge/fire_targeted_power(atom/target_atom) + . = ..() + owner.face_atom(target_atom) + if(instant) + do_lunge(target_atom) + return TRUE + + prepare_target_lunge(target_atom) + return TRUE + +///Starts processing the power and prepares the lunge by spinning, calls lunge at the end of it. +/datum/action/cooldown/vampire/targeted/lunge/proc/prepare_target_lunge(atom/target_atom) + START_PROCESSING(SSprocessing, src) + owner.balloon_alert(owner, "lunge started!") + + // Spin + owner.spin(8, 1) + owner.balloon_alert_to_viewers("spins wildly!", "you spin!") + // Smoke + do_smoke(0, owner.loc, smoke_type = /obj/effect/particle_effect/fluid/smoke/transparent) + //animate them shake + var/base_x = owner.base_pixel_x + var/base_y = owner.base_pixel_y + animate(owner, pixel_x = base_x, pixel_y = base_y, time = 0.1 SECONDS, loop = -1) + for(var/i in 1 to 25) + var/x_offset = base_x + rand(-3, 3) + var/y_offset = base_y + rand(-3, 3) + animate(pixel_x = x_offset, pixel_y = y_offset, time = 0.1 SECONDS) + + // Actually lunge now + if(!do_after(owner, LUNGE_TIME, timed_action_flags = (IGNORE_USER_LOC_CHANGE|IGNORE_TARGET_LOC_CHANGE), extra_checks = CALLBACK(src, PROC_REF(check_valid_target), target_atom))) + end_target_lunge(base_x, base_y) + return FALSE + + end_target_lunge() + do_lunge(target_atom) + return TRUE + +///When preparing to lunge ends, this clears it up. +/datum/action/cooldown/vampire/targeted/lunge/proc/end_target_lunge(base_x, base_y) + animate(owner, pixel_x = base_x, pixel_y = base_y, time = 0.1 SECONDS) + STOP_PROCESSING(SSprocessing, src) + +/datum/action/cooldown/vampire/targeted/lunge/process() + if(!power_in_use) //If running SSfasprocess (on cooldown) + return ..() //Manage our cooldown timers + +///Actually lunges the target, then calls lunge end. +/datum/action/cooldown/vampire/targeted/lunge/proc/do_lunge(atom/hit_atom) + var/turf/targeted_turf = get_turf(hit_atom) + + var/safety = get_dist(owner, targeted_turf) * 3 + 1 + var/consequetive_failures = 0 + while(--safety && !hit_atom.Adjacent(owner)) + if(!step_to(owner, targeted_turf)) + consequetive_failures++ + if(consequetive_failures >= 3) // If 3 steps don't work, just stop. + break + + lunge_end(hit_atom, targeted_turf) + +/datum/action/cooldown/vampire/targeted/lunge/proc/lunge_end(atom/hit_atom, turf/target_turf) + power_activated_sucessfully() + // Am I next to my target to start giving the effects? + if(!owner.Adjacent(hit_atom)) + // check_witnesses() + return + + var/mob/living/user = owner + var/mob/living/carbon/target = hit_atom + + // check_witnesses(target) + // Did I slip or get knocked unconscious? + if(user.body_position != STANDING_UP || user.incapacitated()) + var/send_dir = get_dir(user, target_turf) + new /datum/forced_movement(user, get_ranged_target_turf(user, send_dir, 1), 1, FALSE) + user.spin(1 SECONDS) + return + + if(IS_VAMPIRE_HUNTER(target)) + owner.balloon_alert(owner, "pushed away!") + target.grabbedby(owner) + return + + owner.balloon_alert(owner, "you lunge at [target]!") + if(target.stat == DEAD) + playsound(get_turf(target), 'sound/effects/splat.ogg', 40, TRUE) + owner.visible_message( + span_warning("[owner] tears into [target]'s chest!"), + span_warning("You tear into [target]'s chest!"), + ) + var/obj/item/bodypart/chest/chest = target.get_bodypart(BODY_ZONE_CHEST) + chest.dismember() + else + // Did we knock them down? + if(!is_source_facing_target(target, owner) || owner.alpha <= 40) + target.Knockdown((1 SECONDS) + knockdown_bonus * 5) + target.Paralyze(0.1) + + target.drop_all_held_items() + target.grabbedby(owner) + target.grippedby(owner, instant = TRUE) + +#undef LUNGE_TIME diff --git a/tff_modular/modules/vampire/powers/potence/potence.dm b/tff_modular/modules/vampire/powers/potence/potence.dm new file mode 100644 index 00000000000..9e5b4b073b4 --- /dev/null +++ b/tff_modular/modules/vampire/powers/potence/potence.dm @@ -0,0 +1,25 @@ +/datum/discipline/potence + name = "Potence" + discipline_explanation = "Potence is the Discipline that endows vampires with physical vigor and preternatural strength.\n\ + Vampires with the Potence Discipline possess physical prowess beyond mortal bounds." + icon_state = "potence" + + // Lists of abilities granted per level + level_1 = list(/datum/action/cooldown/vampire/targeted/brawn, /datum/action/cooldown/vampire/targeted/lunge) + level_2 = list(/datum/action/cooldown/vampire/targeted/brawn/two, /datum/action/cooldown/vampire/targeted/lunge/two) + level_3 = list(/datum/action/cooldown/vampire/targeted/brawn/three, /datum/action/cooldown/vampire/targeted/lunge/three) + level_4 = list(/datum/action/cooldown/vampire/targeted/brawn/four, /datum/action/cooldown/vampire/targeted/lunge/four) + level_5 = null + +/datum/discipline/potence/brujah + level_1 = list(/datum/action/cooldown/vampire/targeted/brawn/brash, /datum/action/cooldown/vampire/targeted/lunge) + level_2 = list(/datum/action/cooldown/vampire/targeted/brawn/brash/two, /datum/action/cooldown/vampire/targeted/lunge/two) + level_3 = list(/datum/action/cooldown/vampire/targeted/brawn/brash/three, /datum/action/cooldown/vampire/targeted/lunge/three) + level_4 = list(/datum/action/cooldown/vampire/targeted/brawn/brash/four, /datum/action/cooldown/vampire/targeted/lunge/four) + level_5 = list(/datum/action/cooldown/vampire/targeted/brawn/brash/five, /datum/action/cooldown/vampire/targeted/lunge/four) + +/datum/discipline/potence/apply_discipline_quirks(datum/antagonist/vampire/clan_owner) + . = ..() + clan_owner.cleanup_limbs(clan_owner.owner.current) + clan_owner.extra_damage_per_rank = VAMPIRE_UNARMED_DMG_INCREASE_ON_RANKUP * 2 + clan_owner.setup_limbs(clan_owner.owner.current) diff --git a/tff_modular/modules/vampire/powers/presence/awe.dm b/tff_modular/modules/vampire/powers/presence/awe.dm new file mode 100644 index 00000000000..4d796fd1be4 --- /dev/null +++ b/tff_modular/modules/vampire/powers/presence/awe.dm @@ -0,0 +1,118 @@ +/datum/action/cooldown/vampire/awe + name = "Awe" + desc = "Project an aura of supernatural presence that subtly influences those around you." + button_icon_state = "power_awe" + power_explanation = "Project an aura around yourself that subtly affects everyone nearby.\n\ + Effects on those in your aura:\n\ + - They can only whisper, unable to speak loudly.\n\ + - They are slightly slowed.\n\ + - They occasionally lose focus: facing you, stepping towards you, or dropping items.\n\ + Targets must be able to see you to be affected." + vampire_power_flags = BP_AM_TOGGLE | BP_AM_STATIC_COOLDOWN + vampire_check_flags = BP_CANT_USE_IN_TORPOR | BP_CANT_USE_WHILE_STAKED | BP_CANT_USE_IN_FRENZY + vitaecost = 30 + constant_vitaecost = 2 + cooldown_time = 10 SECONDS + /// The range of the aura in tiles + var/aura = 5 + +/datum/action/cooldown/vampire/awe/activate_power() + . = ..() + to_chat(owner, span_notice("You extend your supernatural presence."), type = MESSAGE_TYPE_INFO) + +/datum/action/cooldown/vampire/awe/deactivate_power() + . = ..() + to_chat(owner, span_notice("You withdraw your supernatural presence."), type = MESSAGE_TYPE_INFO) + +/datum/action/cooldown/vampire/awe/use_power() + . = ..() + for(var/mob/living/victim in oviewers(aura, owner)) + if(can_affect(victim)) + victim.apply_status_effect(/datum/status_effect/awed, owner) + +/// Checks if this victim can be affected by the awe aura +/datum/action/cooldown/vampire/awe/proc/can_affect(mob/living/victim) + if(!victim.client) + return FALSE + if(HAS_SILICON_ACCESS(victim)) + return FALSE + if(victim.stat != CONSCIOUS) + return FALSE + if(victim.is_blind() || victim.is_nearsighted_currently()) + return FALSE + if(HAS_MIND_TRAIT(victim, TRAIT_VAMPIRE_ALIGNED) || HAS_MIND_TRAIT(victim, TRAIT_UNCONVERTABLE) || IS_CURATOR(victim)) + return FALSE + return TRUE + +/datum/status_effect/awed + id = "awed" + status_type = STATUS_EFFECT_REFRESH + duration = 4 SECONDS + tick_interval = 1 SECONDS + processing_speed = STATUS_EFFECT_PRIORITY + alert_type = null + var/mob/living/source_vampire + COOLDOWN_DECLARE(awe_effect_cooldown) + +/datum/status_effect/awed/on_creation(mob/living/new_owner, mob/living/vampire) + source_vampire = vampire + return ..() + +/datum/status_effect/awed/Destroy() + source_vampire = null + return ..() + +/datum/status_effect/awed/on_apply() + if(!iscarbon(owner)) + return FALSE + ADD_TRAIT(owner, TRAIT_SOFTSPOKEN, TRAIT_STATUS_EFFECT(id)) + owner.add_movespeed_modifier(/datum/movespeed_modifier/status_effect/awed) + return TRUE + +/datum/status_effect/awed/on_remove() + REMOVE_TRAIT(owner, TRAIT_SOFTSPOKEN, TRAIT_STATUS_EFFECT(id)) + owner.remove_movespeed_modifier(/datum/movespeed_modifier/status_effect/awed) + +/datum/status_effect/awed/tick(seconds_between_ticks) + if(QDELETED(source_vampire) || source_vampire.stat == DEAD) + qdel(src) + return + + if(HAS_TRAIT(owner, TRAIT_INCAPACITATED) || !COOLDOWN_FINISHED(src, awe_effect_cooldown)) + return + + COOLDOWN_START(src, awe_effect_cooldown, 5 SECONDS) + // Pick a random disruptive effect each tick + switch(rand(1, 5)) + // Nothingburger + if(1) + to_chat(owner, span_awe("Your mind drifts...")) + // Only face them, nothing else + if(2) + owner.face_atom(source_vampire) + // Smile + if(3) + owner.face_atom(source_vampire) + owner.emote("smiles") + to_chat(owner, span_awe("You find yourself smiling...")) + // Step Towards + if(4) + owner.face_atom(source_vampire) + if(owner.body_position == STANDING_UP && get_step(owner.loc, get_dir(owner.loc, source_vampire.loc)) != source_vampire.loc) + owner.balloon_alert(owner, "you stumble...") + owner.visible_message(span_warning("[owner] stumbles."), span_awe("You suddenly stumble...")) + owner.Move(get_step(owner.loc, get_dir(owner.loc, source_vampire.loc))) + // Wobbly Knees + if(5) + owner.face_atom(source_vampire) + if(owner.body_position == STANDING_UP && owner.get_stamina_loss() <= (100 / 2)) + owner.balloon_alert(owner, "your knees feel wobbly...") + owner.visible_message(span_warning("[owner] seems quite wobbly on [owner.p_their()] feet."), span_awe("Your knees feel wobbly...")) + owner.adjust_stamina_loss(rand(20, 40), 10) + +/datum/status_effect/awed/get_examine_text() + return span_warning("[owner.p_They()] seem[owner.p_s()] distracted and unfocused.") + +/// Movespeed modifier for the awed status effect +/datum/movespeed_modifier/status_effect/awed + multiplicative_slowdown = 0.6 diff --git a/tff_modular/modules/vampire/powers/presence/entrance.dm b/tff_modular/modules/vampire/powers/presence/entrance.dm new file mode 100644 index 00000000000..ac283d88acf --- /dev/null +++ b/tff_modular/modules/vampire/powers/presence/entrance.dm @@ -0,0 +1,115 @@ +/** + * ENTRANCE + * A stunning spell that slows, mutes, and impairs the target for a short duration. + * Like a softer mesmerize - target isn't fully out of commission but is very impaired. + */ +/datum/action/cooldown/vampire/targeted/entrance + name = "Entrance" + desc = "Capture a mortal's attention momentarily, leaving them slowed, muted, and dazed." + button_icon_state = "power_entrance" + power_explanation = "Click any player to entrance them, leaving them momentarily impaired.\n\ + Your target will be slowed, muted, and unable to use items for a short duration.\n\ + The effect only lasts half as long on mindshielded targets.\n\ + If the target is attacked by anyone, the effect will instantly wear off.\n\ + This is a softer form of control - they can still move and resist, but are heavily hindered." + vampire_power_flags = NONE + vampire_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 + vitaecost = 80 + cooldown_time = 60 SECONDS + target_range = 7 + prefire_message = "Who will you entrance?" + ranged_mousepointer = 'tff_modular/modules/vampire/icons/vampire_entrance.dmi' + +/datum/action/cooldown/vampire/targeted/entrance/check_valid_target(atom/target_atom) + . = ..() + if(!.) + return FALSE + + if(!iscarbon(target_atom)) + return FALSE + var/mob/living/carbon/carbon_target = target_atom + + if(!carbon_target.mind) + owner.balloon_alert(owner, "[carbon_target] is mindless.") + return FALSE + + if(HAS_MIND_TRAIT(carbon_target, TRAIT_VAMPIRE_ALIGNED) || HAS_MIND_TRAIT(carbon_target, TRAIT_UNCONVERTABLE) || IS_CURATOR(carbon_target)) + owner.balloon_alert(owner, "immune to your presence.") + return FALSE + + if(carbon_target.stat != CONSCIOUS) + owner.balloon_alert(owner, "[carbon_target] is not [(carbon_target.stat == DEAD || HAS_TRAIT(carbon_target, TRAIT_FAKEDEATH)) ? "alive" : "conscious"].") + return FALSE + + if(carbon_target.has_status_effect(/datum/status_effect/entranced)) + owner.balloon_alert(owner, "[carbon_target] is already entranced.") + return FALSE + + if(carbon_target.get_eye_protection() >= FLASH_PROTECTION_WELDER) + owner.balloon_alert(owner, "[carbon_target] has too much eye protection.") + return FALSE + + return TRUE + +/datum/action/cooldown/vampire/targeted/entrance/fire_targeted_power(atom/target_atom) + . = ..() + var/mob/living/carbon/carbon_target = target_atom + + carbon_target.apply_status_effect(/datum/status_effect/entranced, 20 SECONDS) + + owner.balloon_alert(owner, "entranced [carbon_target]") + to_chat(carbon_target, span_awe("Your mind goes blank..."), type = MESSAGE_TYPE_WARNING) + to_chat(owner, span_notice("You capture [carbon_target]'s attention, leaving [carbon_target.p_them()] dazed."), type = MESSAGE_TYPE_INFO) + + carbon_target.playsound_local(null, 'tff_modular/modules/vampire/sound/mesmerize.ogg', 50, FALSE, pressure_affected = FALSE) + +/// Status effect for being entranced +/datum/status_effect/entranced + id = "entranced" + status_type = STATUS_EFFECT_UNIQUE + tick_interval = STATUS_EFFECT_NO_TICK + alert_type = /atom/movable/screen/alert/status_effect/entranced + +/datum/status_effect/entranced/on_creation(mob/living/new_owner, set_duration) + if(IS_SAFE_NUM(set_duration)) + duration = set_duration + if(HAS_MIND_TRAIT(new_owner, TRAIT_MINDSHIELD)) + duration /= 2 + return ..() + +/datum/status_effect/entranced/on_apply() + if(!iscarbon(owner)) + return FALSE + owner.add_traits(list(TRAIT_MUTE, TRAIT_HANDS_BLOCKED, TRAIT_GRABWEAKNESS), TRAIT_STATUS_EFFECT(id)) + owner.add_movespeed_modifier(/datum/movespeed_modifier/status_effect/entranced) + owner.set_jitter_if_lower(duration) + owner.add_client_colour(/datum/client_colour/glass_colour/pink) + owner.AddElement(/datum/element/relay_attackers) + RegisterSignal(owner, COMSIG_ATOM_WAS_ATTACKED, PROC_REF(on_attacked)) + return TRUE + +/datum/status_effect/entranced/on_remove() + UnregisterSignal(owner, COMSIG_ATOM_WAS_ATTACKED) + owner.remove_traits(list(TRAIT_MUTE, TRAIT_HANDS_BLOCKED, TRAIT_GRABWEAKNESS), TRAIT_STATUS_EFFECT(id)) + owner.remove_movespeed_modifier(/datum/movespeed_modifier/status_effect/entranced) + owner.remove_client_colour(/datum/client_colour/glass_colour/pink) + to_chat(owner, span_awe("Your mind clears and you regain your focus.")) + +/datum/status_effect/entranced/get_examine_text() + return span_warning("[owner.p_They()] seem[owner.p_s()] dazed and unfocused.") + +/datum/status_effect/entranced/proc/on_attacked(datum/source, atom/attacker, attack_flags) + SIGNAL_HANDLER + if(attacker != owner && (attack_flags & ATTACKER_DAMAGING_ATTACK)) + to_chat(owner, span_awe("You quickly come back to your senses as you're hit by [attacker]!")) + qdel(src) + +/// Alert for entranced status +/atom/movable/screen/alert/status_effect/entranced + name = "Entranced" + desc = "Your mind has been captured by a supernatural presence. You cannot speak or use items." + icon_state = "hypnosis" + +/// Movespeed modifier for the entranced status effect +/datum/movespeed_modifier/status_effect/entranced + multiplicative_slowdown = 2 diff --git a/tff_modular/modules/vampire/powers/presence/force_of_personality.dm b/tff_modular/modules/vampire/powers/presence/force_of_personality.dm new file mode 100644 index 00000000000..1c1d0cbd505 --- /dev/null +++ b/tff_modular/modules/vampire/powers/presence/force_of_personality.dm @@ -0,0 +1,101 @@ +/datum/action/cooldown/vampire/force_of_personality + name = "Force of Personality" + desc = "Project an overwhelming aura of authority that causes those around you to involuntarily step back." + button_icon_state = "power_fop" + power_explanation = "Project an aura around yourself that subtly pushes people away.\n\ + Effects on those in 3 tile range. No one will be able to voluntarily approach you.\n\ + Targets must be able to see you to be affected.\n\ + Lasts 1 minute." + vampire_power_flags = BP_AM_TOGGLE | BP_AM_STATIC_COOLDOWN + vampire_check_flags = BP_CANT_USE_IN_TORPOR | BP_CANT_USE_WHILE_STAKED | BP_CANT_USE_IN_FRENZY + vitaecost = 30 + constant_vitaecost = 2 + cooldown_time = 30 SECONDS + /// The range of the aura in tiles, this is further than the actual effect just so we can hit them with the status effect before they even get close enough. + var/aura_range = 7 + var/deactivate_timer + +/datum/action/cooldown/vampire/force_of_personality/activate_power() + . = ..() + to_chat(owner, span_notice("You project an overwhelming sense of authority."), type = MESSAGE_TYPE_INFO) + deactivate_timer = addtimer(CALLBACK(src, PROC_REF(deactivate_power)), 1 MINUTES, TIMER_STOPPABLE) + +/datum/action/cooldown/vampire/force_of_personality/deactivate_power() + . = ..() + to_chat(owner, span_notice("You withdraw your authoritative presence."), type = MESSAGE_TYPE_INFO) + if(deactivate_timer) + deltimer(deactivate_timer) + deactivate_timer = null + +/datum/action/cooldown/vampire/force_of_personality/use_power() + . = ..() + for(var/mob/living/victim in oviewers(aura_range, owner)) + if(can_affect(victim)) + victim.apply_status_effect(/datum/status_effect/intimidated, owner) + +/// Checks if this victim can be affected by the force of personality aura +/datum/action/cooldown/vampire/force_of_personality/proc/can_affect(mob/living/victim) + if(!victim.client) + return FALSE + if(HAS_SILICON_ACCESS(victim)) + return FALSE + if(victim.stat != CONSCIOUS) + return FALSE + if(victim.is_blind() || victim.is_nearsighted_currently()) + return FALSE + if(HAS_MIND_TRAIT(victim, TRAIT_VAMPIRE_ALIGNED) || IS_CURATOR(victim) || HAS_MIND_TRAIT(victim, TRAIT_UNCONVERTABLE)) + return FALSE + return TRUE + +/// Status effect for being affected by Force of Personality +/datum/status_effect/intimidated + id = "intimidated" + status_type = STATUS_EFFECT_REFRESH + duration = 10 SECONDS + tick_interval = 0.2 SECONDS + processing_speed = STATUS_EFFECT_PRIORITY + alert_type = null + /// The vampire projecting the aura + var/mob/living/source_vampire + /// The range at which the effect triggers + var/trigger_range = 3 + COOLDOWN_DECLARE(message_cooldown) + +/datum/status_effect/intimidated/on_creation(mob/living/new_owner, mob/living/vampire) + source_vampire = vampire + return ..() + +/datum/status_effect/intimidated/Destroy() + source_vampire = null + return ..() + +/datum/status_effect/intimidated/on_apply() + if(!iscarbon(owner)) + return FALSE + return TRUE + +/datum/status_effect/intimidated/tick(seconds_between_ticks) + if(QDELETED(source_vampire) || source_vampire.stat == DEAD) + qdel(src) + return + + if(owner.incapacitated(IGNORE_RESTRAINTS)) + return + + // Only check if we're within range of the vampire + if(get_dist(owner, source_vampire) > trigger_range) + return + + // Step away from the vampire + if(owner.body_position == STANDING_UP) + var/away_dir = get_dir(source_vampire.loc, owner.loc) + var/turf/retreat_turf = get_step(owner.loc, away_dir) + // Make sure we're not stepping into the vampire or into a wall + if(retreat_turf && !retreat_turf.is_blocked_turf()) + if(COOLDOWN_FINISHED(src, message_cooldown)) + COOLDOWN_START(src, message_cooldown, 3 SECONDS) + owner.visible_message(span_warning("[owner] takes a hurried step back."), span_awe("You don't dare approach [source_vampire.p_them()]...")) + owner.Move(retreat_turf, away_dir) + +/datum/status_effect/intimidated/get_examine_text() + return span_warning("[owner.p_They()] seem[owner.p_s()] intimidated.") diff --git a/tff_modular/modules/vampire/powers/presence/presence.dm b/tff_modular/modules/vampire/powers/presence/presence.dm new file mode 100644 index 00000000000..e6151021a73 --- /dev/null +++ b/tff_modular/modules/vampire/powers/presence/presence.dm @@ -0,0 +1,9 @@ +/datum/discipline/presence + name = "Presence" + discipline_explanation = "Presence is the Discipline of supernatural presence and subtle manipulation which allows Kindred to dominate the attention of those around them." + icon_state = "presence" + level_1 = list(/datum/action/cooldown/vampire/targeted/entrance) + level_2 = list(/datum/action/cooldown/vampire/targeted/entrance, /datum/action/cooldown/vampire/targeted/summon) + level_3 = list(/datum/action/cooldown/vampire/awe, /datum/action/cooldown/vampire/targeted/entrance, /datum/action/cooldown/vampire/targeted/summon) + level_4 = list(/datum/action/cooldown/vampire/awe, /datum/action/cooldown/vampire/targeted/entrance, /datum/action/cooldown/vampire/targeted/summon, /datum/action/cooldown/vampire/force_of_personality) + level_5 = null diff --git a/tff_modular/modules/vampire/powers/presence/summon.dm b/tff_modular/modules/vampire/powers/presence/summon.dm new file mode 100644 index 00000000000..ab5ea71bf0f --- /dev/null +++ b/tff_modular/modules/vampire/powers/presence/summon.dm @@ -0,0 +1,182 @@ +/** + * SUMMON + * Target can no longer act and is forced to approach the vampire. + * Uses an AI controller to force movement towards the caster. + */ +/datum/action/cooldown/vampire/targeted/summon + name = "Summon" + desc = "Compel a mortal to approach you against their will." + button_icon_state = "power_summon" + power_explanation = "Click any player to summon them towards you.\n\ + Your target will be unable to act and will be compelled to walk towards you.\n\ + The effect ends when they reach you, after a duration, or if line of sight is broken.\n\ + They must be able to see you to be affected." + vampire_power_flags = NONE + vampire_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 + vitaecost = 100 + cooldown_time = 60 SECONDS + target_range = 10 + prefire_message = "Who will you summon to your presence?" + ranged_mousepointer = 'tff_modular/modules/vampire/icons/vampire_summon.dmi' + + /// Maximum duration of the summon effect + var/summon_duration = 30 SECONDS + +/datum/action/cooldown/vampire/targeted/summon/check_valid_target(atom/target_atom) + . = ..() + if(!.) + return FALSE + + if(!iscarbon(target_atom)) + return FALSE + var/mob/living/carbon/carbon_target = target_atom + + if(!carbon_target.mind) + owner.balloon_alert(owner, "[carbon_target] is mindless.") + return FALSE + + if(HAS_MIND_TRAIT(carbon_target, TRAIT_VAMPIRE_ALIGNED) || IS_CURATOR(carbon_target) || HAS_MIND_TRAIT(carbon_target, TRAIT_UNCONVERTABLE)) + owner.balloon_alert(owner, "immune to your presence.") + return FALSE + + if(HAS_SILICON_ACCESS(carbon_target)) + owner.balloon_alert(owner, "[carbon_target] is immune.") + return FALSE + + if(carbon_target.stat != CONSCIOUS) + owner.balloon_alert(owner, "[carbon_target] is not [(carbon_target.stat == DEAD || HAS_TRAIT(carbon_target, TRAIT_FAKEDEATH)) ? "alive" : "conscious"].") + return FALSE + + if(carbon_target.is_blind()) + owner.balloon_alert(owner, "[carbon_target] is blind.") + return FALSE + + if(carbon_target.has_status_effect(/datum/status_effect/summoned)) + owner.balloon_alert(owner, "[carbon_target] is already being summoned.") + return FALSE + + return TRUE + +/datum/action/cooldown/vampire/targeted/summon/fire_targeted_power(atom/target_atom) + . = ..() + var/mob/living/carbon/carbon_target = target_atom + + carbon_target.apply_status_effect(/datum/status_effect/summoned, summon_duration, owner) + + owner.balloon_alert(owner, "summoning [carbon_target]") + to_chat(carbon_target, span_awe("An irresistible compulsion draws you towards [owner]..."), type = MESSAGE_TYPE_WARNING) + to_chat(owner, span_notice("You beckon [carbon_target] towards you."), type = MESSAGE_TYPE_INFO) + + carbon_target.playsound_local(null, 'tff_modular/modules/vampire/sound/mesmerize.ogg', 70, FALSE, pressure_affected = FALSE) + +/// Status effect for being summoned towards the vampire +/datum/status_effect/summoned + id = "summoned" + status_type = STATUS_EFFECT_UNIQUE + duration = 30 SECONDS + tick_interval = 0.5 SECONDS + processing_speed = STATUS_EFFECT_PRIORITY + alert_type = /atom/movable/screen/alert/status_effect/summoned + /// The vampire who is summoning us + var/mob/living/source_vampire + /// The move loop handling our movement + var/datum/move_loop/move_loop + /// How long between each step (slow, staggering movement) + var/step_delay = 1.5 SECONDS + +/datum/status_effect/summoned/on_creation(mob/living/new_owner, set_duration, mob/living/vampire) + if(IS_SAFE_NUM(set_duration)) + duration = set_duration + source_vampire = vampire + return ..() + +/datum/status_effect/summoned/Destroy() + source_vampire = null + QDEL_NULL(move_loop) + return ..() + +/datum/status_effect/summoned/on_apply() + if(!iscarbon(owner)) + return FALSE + ADD_TRAIT(owner, TRAIT_MUTE, TRAIT_STATUS_EFFECT(id)) + RegisterSignal(owner, COMSIG_MOB_CLIENT_PRE_MOVE, PROC_REF(block_player_move)) + owner.add_client_colour(/datum/client_colour/glass_colour/pink) + start_movement() + return TRUE + +/datum/status_effect/summoned/on_remove() + REMOVE_TRAIT(owner, TRAIT_MUTE, TRAIT_STATUS_EFFECT(id)) + UnregisterSignal(owner, COMSIG_MOB_CLIENT_PRE_MOVE) + + owner.remove_client_colour(/datum/client_colour/glass_colour/pink) + + if(move_loop) + UnregisterSignal(move_loop, COMSIG_QDELETING) + qdel(move_loop) + move_loop = null + + // Stop any residual movement + GLOB.move_manager.stop_looping(owner) + + to_chat(owner, span_awe("The compulsion fades and you regain control of yourself.")) + +/datum/status_effect/summoned/tick(seconds_between_ticks) + // Check if vampire is still valid + if(QDELETED(source_vampire) || source_vampire.stat == DEAD) + qdel(src) + return + + // Check if we've reached the vampire (adjacent) + if(owner.Adjacent(source_vampire)) + to_chat(owner, span_awe("You have arrived before [source_vampire]...")) + to_chat(source_vampire, span_notice("[owner] has arrived before you.")) + // Brief stun when arriving so we don't look weird with the movespeed + owner.Immobilize(2 SECONDS) + qdel(src) + return + + // Check line of sight - if broken, end the effect + if(!CAN_SEE_RANGED(source_vampire, owner, 10)) + to_chat(owner, span_awe("You lose sight of your summoner and the compulsion breaks.")) + qdel(src) + return + + // Make sure we're facing the vampire + owner.face_atom(source_vampire) + + // Restart movement if it stopped for some reason (blocked by obstacle, etc) + if(!move_loop) + start_movement() + +/datum/status_effect/summoned/get_examine_text() + return span_warning("[owner.p_They()] [owner.p_are()] walking with a blank expression, as if compelled.") + +/datum/status_effect/summoned/nextmove_modifier() + return 2 + +/// Blocks the player from moving themselves while summoned +/datum/status_effect/summoned/proc/block_player_move(mob/source, atom/new_loc) + SIGNAL_HANDLER + return COMSIG_MOB_CLIENT_BLOCK_PRE_MOVE + +/// Starts or restarts the movement loop towards the vampire +/datum/status_effect/summoned/proc/start_movement() + if(move_loop) + qdel(move_loop) + if(QDELETED(source_vampire) || QDELETED(owner)) + return + move_loop = GLOB.move_manager.home_onto(owner, source_vampire, step_delay, timeout = INFINITY) + if(move_loop) + RegisterSignal(move_loop, COMSIG_QDELETING, PROC_REF(on_move_loop_deleted)) + +/// Called when the move loop is deleted externally +/datum/status_effect/summoned/proc/on_move_loop_deleted(datum/source) + SIGNAL_HANDLER + move_loop = null + +/// Alert for summoned status +/atom/movable/screen/alert/status_effect/summoned + name = "Summoned" + desc = "You are being compelled to approach someone. You cannot resist." + icon_state = "vampire_summon" + diff --git a/tff_modular/modules/vampire/powers/thaumaturgy/bloodboil.dm b/tff_modular/modules/vampire/powers/thaumaturgy/bloodboil.dm new file mode 100644 index 00000000000..6803a7f56db --- /dev/null +++ b/tff_modular/modules/vampire/powers/thaumaturgy/bloodboil.dm @@ -0,0 +1,130 @@ +/datum/action/cooldown/vampire/targeted/bloodboil + name = "Thaumaturgy: Boil Blood" + desc = "Boil the target's blood inside their body." + button_icon_state = "power_bloodboil" + active_background_icon_state = "tremere_power_bronze_on" + base_background_icon_state = "tremere_power_bronze_off" + power_explanation = "Afflict a debilitating status effect on a target within range, causing them to suffer bloodloss and burn damage.\n\ + The effect weakens if the target is further than 5 tiles away from you, or if you are also draining their blood.\n\ + This is the only thaumaturgy ability to scale with level. It will become more powerful, last longer, gain range, and have a shorter cooldown." + vampire_power_flags = NONE + vampire_check_flags = BP_CANT_USE_IN_TORPOR | BP_CANT_USE_IN_FRENZY | BP_CANT_USE_WHILE_INCAPACITATED | BP_CANT_USE_WHILE_STAKED | BP_CANT_USE_WHILE_UNCONSCIOUS + vitaecost = 30 + cooldown_time = 35 SECONDS + target_range = 7 + power_activates_immediately = FALSE + prefire_message = "Whom will you afflict?" + ranged_mousepointer = 'tff_modular/modules/vampire/icons/vampire_bloodboil.dmi' + + var/powerlevel = 1 + /// How much burn damage is done to the victim per second. + var/burn_damage = 8 + /// How much blood is taken from the victim per second. + var/blood_loss = 8 + /// How long the blood boil effect lasts. + var/effect_duration = 8 SECONDS + +/datum/action/cooldown/vampire/targeted/bloodboil/two + cooldown_time = 30 SECONDS + vitaecost = 45 + target_range = 10 + powerlevel = 2 + burn_damage = 9 + blood_loss = 10 + effect_duration = 10 SECONDS + +/datum/action/cooldown/vampire/targeted/bloodboil/check_valid_target(mob/living/carbon/target) + . = ..() + if(!.) + return FALSE + + // Must be a carbon + if(!iscarbon(target)) + owner.balloon_alert(owner, "not a valid target.") + return FALSE + + if(HAS_TRAIT(target, TRAIT_NOBLOOD)) + owner.balloon_alert(owner, "[target.p_they()] [target.p_have()] no blood anyways!") + return FALSE + + // Check for magic immunity + if(target.can_block_magic(MAGIC_RESISTANCE_HOLY)) + owner.balloon_alert(owner, "your curse was blocked.") + return FALSE + + // Already boiled + if(target.has_status_effect(/datum/status_effect/bloodboil)) + owner.balloon_alert(owner, "[target.p_their()] blood is already boiling!") + return FALSE + +/datum/action/cooldown/vampire/targeted/bloodboil/fire_targeted_power(mob/living/carbon/target) + . = ..() + // Just to make absolutely sure + if(!iscarbon(target)) + return FALSE + + owner.whisper("Potestas Vitae...", forced = "[src]") + + if(target.apply_status_effect(/datum/status_effect/bloodboil, owner, effect_duration, burn_damage, blood_loss)) + to_chat(owner, span_warning("You cause [target]'s blood to boil inside [target.p_their()] body!")) + owner.log_message("used [name] (level [powerlevel]) on [key_name(target)]", LOG_ATTACK) + target.log_message("was hit by [key_name(owner)] with [name] (level [powerlevel])", LOG_VICTIM, log_globally = FALSE) + power_activated_sucessfully() // PAY COST! BEGIN COOLDOWN! + else + to_chat(owner, span_warning("Your thaumaturgy fails to take hold.")) + deactivate_power() + +/datum/status_effect/bloodboil + id = "bloodboil" + duration = 4 SECONDS + tick_interval = 1 SECONDS + status_type = STATUS_EFFECT_UNIQUE + processing_speed = STATUS_EFFECT_PRIORITY + alert_type = /atom/movable/screen/alert/status_effect/bloodboil + /// How much burn damage is dealt per second. + var/burn_damage = 8 + /// How much blood is lost per second. + var/blood_loss = 8 + /// The vampire that casted blood boil. + var/mob/living/caster + +/datum/status_effect/bloodboil/Destroy() + caster = null + return ..() + +/datum/status_effect/bloodboil/on_creation(mob/living/new_owner, mob/living/caster, duration, burn_damage, blood_loss) + src.caster = caster + src.duration = duration + src.burn_damage = burn_damage + src.blood_loss = blood_loss + return ..() + +/datum/status_effect/bloodboil/on_apply() + if(!iscarbon(owner) || HAS_TRAIT(owner, TRAIT_NOBLOOD)) + return FALSE + return TRUE + +/datum/status_effect/bloodboil/tick(seconds_between_ticks) + var/multiplier = 1 + // if their blood is also being drained, halve the damage. + if(owner.has_status_effect(/datum/status_effect/blood_drain)) + multiplier *= 0.5 + + if(get_dist(owner, caster) > 5) + multiplier *= 0.5 + + owner.take_overall_damage(burn = round(burn_damage * multiplier, 1)) + owner.blood_volume = max(owner.blood_volume - round(blood_loss * multiplier, 1), 0) + + if(SPT_PROB(50, seconds_between_ticks)) + to_chat(owner, span_warning("Oh god! IT BURNS!")) + INVOKE_ASYNC(owner, TYPE_PROC_REF(/mob, emote), "scream") + playsound(owner, pick('sound/effects/wounds/sizzle1.ogg', 'sound/effects/wounds/sizzle2.ogg'), 50, vary = TRUE) + +/datum/status_effect/bloodboil/get_examine_text() + return span_warning("[owner.p_They()] writhe[owner.p_s()] and squirm[owner.p_s()], [owner.p_they()] seem[owner.p_s()] weirdly red?") + +/atom/movable/screen/alert/status_effect/bloodboil + name = "Blood Boil" + desc = "You feel an intense heat coursing through your veins. Your blood is boiling!" + icon_state = "bloodboil" diff --git a/tff_modular/modules/vampire/powers/thaumaturgy/bloodbolt.dm b/tff_modular/modules/vampire/powers/thaumaturgy/bloodbolt.dm new file mode 100644 index 00000000000..83c72954857 --- /dev/null +++ b/tff_modular/modules/vampire/powers/thaumaturgy/bloodbolt.dm @@ -0,0 +1,73 @@ +/datum/action/cooldown/vampire/targeted/bloodbolt + name = "Thaumaturgy: Blood Bolt" + desc = "Fire a blood bolt at your enemy, dealing Burn damage." + button_icon_state = "power_bloodbolt" + active_background_icon_state = "tremere_power_plat_on" + base_background_icon_state = "tremere_power_plat_off" + power_explanation = "Shoots a blood bolt spell that deals burn damage" + vampire_power_flags = NONE + vampire_check_flags = BP_CANT_USE_IN_TORPOR | BP_CANT_USE_WHILE_STAKED | BP_CANT_USE_IN_FRENZY | BP_CANT_USE_WHILE_INCAPACITATED | BP_CANT_USE_WHILE_UNCONSCIOUS + vitaecost = 75 + cooldown_time = 60 SECONDS + target_range = 80 // Sniper :) + power_activates_immediately = FALSE + prefire_message = "Select your target." + ranged_mousepointer = 'tff_modular/modules/vampire/icons/vampire_bloodbolt.dmi' + +/datum/action/cooldown/vampire/targeted/bloodbolt/fire_targeted_power(atom/target_atom) + . = ..() + var/mob/living/living_owner = owner + // check_witnesses(target_atom) + living_owner.balloon_alert(living_owner, "you fire a blood bolt!") + living_owner.face_atom(target_atom) + living_owner.changeNext_move(CLICK_CD_RANGE) + living_owner.newtonian_move(get_dir(target_atom, living_owner)) + + var/obj/projectile/magic/arcane_barrage/vampire/bolt = new(living_owner.loc) + // bolt.vampire_power = src + bolt.firer = living_owner + bolt.fired_from = src + bolt.original = target_atom + bolt.def_zone = ran_zone(living_owner.zone_selected) + INVOKE_ASYNC(bolt, TYPE_PROC_REF(/obj/projectile, fire)) + + playsound(living_owner, 'tff_modular/modules/vampire/sound/bloodbolt_fire.ogg', 60, TRUE) + power_activated_sucessfully() + +/** + * # Blood Bolt + * + * This is the projectile this Power will fire. + */ +/obj/projectile/magic/arcane_barrage/vampire + name = "blood bolt" + icon_state = "mini_leaper" + damage = 40 + hitsound = 'tff_modular/modules/vampire/sound/bloodbolt.ogg' + antimagic_flags = MAGIC_RESISTANCE_HOLY + // var/datum/action/cooldown/vampire/targeted/bloodbolt/vampire_power + +/obj/projectile/magic/arcane_barrage/vampire/on_hit(atom/target, blocked = 0, pierce_hit) + if(istype(target, /obj/structure/closet)) + var/obj/structure/closet/hit_closet = target + hit_closet.bust_open(destructive = FALSE) + qdel(src) + return BULLET_ACT_HIT + + if(istype(target, /obj/machinery/door/airlock)) + var/obj/machinery/door/airlock/airlock = target + airlock.open(FORCING_DOOR_CHECKS) + qdel(src) + return BULLET_ACT_HIT + + if(isliving(target)) + var/mob/living/living_target = target + living_target.blood_particles(5, angle = rand(0, 360), min_deviation = -180, max_deviation = 180) + living_target.blood_volume = max(living_target.blood_volume - 50, 0) + living_target.emote("scream") + living_target.set_jitter_if_lower(6 SECONDS) + living_target.Unconscious(3 SECONDS) + visible_message(span_danger("[living_target]'s wounds spray boiling hot blood!"), span_userdanger("Oh god it burns!")) + qdel(src) + return BULLET_ACT_HIT + . = ..() diff --git a/tff_modular/modules/vampire/powers/thaumaturgy/blooddrain.dm b/tff_modular/modules/vampire/powers/thaumaturgy/blooddrain.dm new file mode 100644 index 00000000000..58767cc80db --- /dev/null +++ b/tff_modular/modules/vampire/powers/thaumaturgy/blooddrain.dm @@ -0,0 +1,147 @@ +/datum/action/cooldown/vampire/targeted/blooddrain + name = "Thaumaturgy: Blood Drain" + desc = "Cast a beam of draining magic that saps the vitality of your target to steal their blood and heal yourself." + button_icon_state = "power_blooddrain" + active_background_icon_state = "tremere_power_on" + base_background_icon_state = "tremere_power_off" + power_explanation = "Cast a beam of draining magic that saps the vitality of your target to steal their blood and heal yourself.\n\ + You must maintain line of sight to the victim for the effect to continue." + vampire_power_flags = BP_AM_TOGGLE + vampire_check_flags = BP_CANT_USE_IN_TORPOR | BP_CANT_USE_WHILE_STAKED | BP_CANT_USE_IN_FRENZY | BP_CANT_USE_WHILE_INCAPACITATED | BP_CANT_USE_WHILE_UNCONSCIOUS + vitaecost = 75 + cooldown_time = 10 SECONDS // Very unlikely to ever last past 10 seconds even if the actual duration is longer. Combat is a fuck. + target_range = 7 + power_activates_immediately = FALSE + prefire_message = "Select your target." + ranged_mousepointer = 'tff_modular/modules/vampire/icons/vampire_blooddrain.dmi' + + var/datum/status_effect/blood_drain/active_effect + +/datum/action/cooldown/vampire/targeted/blooddrain/fire_targeted_power(atom/target_atom) + . = ..() + var/mob/living/living_owner = owner + /* var/mob/living/living_target = target_atom + check_witnesses(living_target) */ + living_owner.face_atom(target_atom) + living_owner.changeNext_move(CLICK_CD_RANGE) + living_owner.newtonian_move(get_dir(target_atom, living_owner)) + + var/obj/projectile/magic/blood_drain/drain = new(living_owner.loc) + drain.firer = living_owner + drain.fired_from = src + if(isliving(target_atom)) + drain.original = target_atom + drain.def_zone = ran_zone(living_owner.zone_selected) + INVOKE_ASYNC(drain, TYPE_PROC_REF(/obj/projectile, fire)) + + playsound(living_owner, 'sound/effects/magic/wandodeath.ogg', 60, TRUE) + +/datum/action/cooldown/vampire/targeted/blooddrain/deactivate_power() + . = ..() + if(!isnull(active_effect)) + active_effect.end_drain() + +/obj/projectile/magic/blood_drain + name = "vitality draining stream" + icon_state = "nothing" + range = 7 + antimagic_flags = MAGIC_RESISTANCE_HOLY + hitsound = 'tff_modular/modules/vampire/sound/bloodbolt.ogg' + var/datum/beam/drain_beam + +/obj/projectile/magic/blood_drain/fire(angle, atom/direct_target) + if(!firer) + CRASH("Projectile [src] fired with no firer") //We don't even want any of the rest of this to play out if we don't have a firer + drain_beam = firer.Beam(src, icon = 'icons/effects/beam.dmi', icon_state = "lifedrain", time = 10 SECONDS, maxdistance = 7, beam_color = COLOR_RED) + return ..() + +/obj/projectile/magic/blood_drain/on_hit(mob/living/target, blocked, pierce_hit) + . = ..() + if(isliving(target)) + target.apply_status_effect(/datum/status_effect/blood_drain, firer, fired_from) + +/obj/projectile/magic/blood_drain/Destroy() + if(!QDELETED(drain_beam)) + qdel(drain_beam) + drain_beam = null + return ..() + +/// +/// Status Effect. Literally copied from life drain spell of wizards, but modified to work with vampires. +/// +/datum/status_effect/blood_drain + id = "blood_drain" + duration = 20 SECONDS + tick_interval = 0.25 SECONDS + status_type = STATUS_EFFECT_REPLACE + processing_speed = STATUS_EFFECT_PRIORITY + alert_type = null + var/datum/beam/drain_beam + var/mob/living/carbon/vampire + var/datum/action/cooldown/vampire/targeted/blooddrain/spell + var/blood_drain = 5 // Amount of blood drained per second + +/datum/status_effect/blood_drain/Destroy() + . = ..() + vampire = null + +/datum/status_effect/blood_drain/on_creation(mob/living/new_owner, mob/living/firer, fired_from, duration_override) + if(isnull(firer) || isnull(fired_from) || !iscarbon(firer) || !iscarbon(new_owner)) + qdel(src) + return + vampire = firer + spell = fired_from + spell.active_effect = src + drain_beam = vampire.Beam(new_owner, icon = 'icons/effects/beam.dmi', icon_state = "blood_drain", time = 22 SECONDS, maxdistance = 7, beam_color = COLOR_RED) + RegisterSignal(drain_beam, COMSIG_QDELETING, PROC_REF(end_drain)) + new_owner.visible_message(span_boldwarning("[vampire] begins draining the life force from [new_owner]!"), span_boldwarning("[vampire] is draining your life force! You need to get away from [vampire.p_them()] to stop it!")) + . = ..() + +/datum/status_effect/blood_drain/on_apply() + owner.add_movespeed_modifier(/datum/movespeed_modifier/status_effect/life_drain) + return TRUE + +/datum/status_effect/blood_drain/on_remove() + owner.remove_movespeed_modifier(/datum/movespeed_modifier/status_effect/life_drain) + if(spell) + spell.active_effect = null + spell.deactivate_power() + spell.StartCooldown() + spell = null + if(!QDELETED(drain_beam)) + qdel(drain_beam) + drain_beam = null + +/datum/status_effect/blood_drain/tick(seconds_between_ticks) + if(!iscarbon(owner) || owner.stat > HARD_CRIT) //If they're dead or non-humanoid, this spell fails + end_drain() + return + if(!iscarbon(vampire)) //You never know what might happen with wizards around + end_drain() + return + if(!CAN_THEY_SEE(vampire, owner)) // if they leave line of sight, no more drain. + end_drain() + return + + if(HAS_TRAIT(owner, TRAIT_INCAPACITATED) || owner.stat) + //If the victim is incapacitated, drain their blood + owner.blood_volume -= blood_drain * seconds_between_ticks + else + //If they aren't incapacitated yet, drain only their stamina + owner.adjust_stamina_loss(7 * seconds_between_ticks) + + if(SPT_PROB(20, seconds_between_ticks)) + INVOKE_ASYNC(owner, TYPE_PROC_REF(/mob, emote), "scream") + owner.visible_message(span_boldwarning("[vampire] absorbs blood from [owner]!"), span_boldwarning("It BURNS!")) + + //Vampire heals at a steady rate over the duration of the spell regardless of the victim's state + vampire.heal_overall_damage(brute = 0.5, burn = 0.5, stamina = 5) + + spell.vampiredatum_power.adjust_blood_volume(blood_drain * seconds_between_ticks * 2) // Vampires get double the blood drained because of balance + //Weird beam visuals if it isn't redrawn due to the beam sending players into crit + drain_beam.redrawing() + +/datum/status_effect/blood_drain/proc/end_drain() + SIGNAL_HANDLER + if(!QDELETED(src)) + qdel(src) diff --git a/tff_modular/modules/vampire/powers/thaumaturgy/bloodshield.dm b/tff_modular/modules/vampire/powers/thaumaturgy/bloodshield.dm new file mode 100644 index 00000000000..bdef3ee26fa --- /dev/null +++ b/tff_modular/modules/vampire/powers/thaumaturgy/bloodshield.dm @@ -0,0 +1,69 @@ +/datum/action/cooldown/vampire/bloodshield + name = "Thaumaturgy: Blood Shield" + desc = "Create a Blood shield to protect yourself from damage." + button_icon_state = "power_bloodshield" + active_background_icon_state = "tremere_power_gold_on" + base_background_icon_state = "tremere_power_gold_off" + power_explanation = "Activating Thaumaturgy will temporarily give you a Blood Shield.\n\ + The blood shield has very good block power, but costs 15 Blood per hit to maintain.\n\ + However, it is slightly less effective at blocking lasers or lethal energy projectiles." + + vampire_power_flags = BP_AM_TOGGLE | BP_AM_STATIC_COOLDOWN + vampire_check_flags = BP_CANT_USE_IN_TORPOR | BP_CANT_USE_WHILE_STAKED | BP_CANT_USE_IN_FRENZY | BP_CANT_USE_WHILE_INCAPACITATED | BP_CANT_USE_WHILE_UNCONSCIOUS + + vitaecost = 50 + cooldown_time = 10 SECONDS + constant_vitaecost = 6 + + /// Blood shield given while this Power is active. + var/datum/weakref/blood_shield + +/datum/action/cooldown/vampire/bloodshield/activate_power() + . = ..() + var/obj/item/shield/vampire/new_shield = new + if(!owner.put_in_inactive_hand(new_shield)) + qdel(new_shield) + owner.balloon_alert(owner, "off hand is full!") + to_chat(owner, span_notice("Blood shield couldn't be activated as your off hand is full.")) + deactivate_power() + return FALSE + blood_shield = WEAKREF(new_shield) + owner.visible_message( + span_warning("[owner]'s hands begins to bleed and forms into a blood shield!"), + span_warning("We activate our Blood shield!"), + span_hear("You hear liquids forming together."), + ) + +/datum/action/cooldown/vampire/bloodshield/deactivate_power() + . = ..() + to_chat(owner, span_notice("Blood shield couldn't be activated as your off hand is full.")) + if(blood_shield) + QDEL_NULL(blood_shield) + +/** + * # Blood Shield + * Copied mostly from '/obj/item/shield/changeling' + */ +/obj/item/shield/vampire + name = "blood shield" + desc = "A shield made out of blood, requiring blood to sustain hits." + item_flags = ABSTRACT | DROPDEL + icon = 'tff_modular/modules/vampire/icons/vamp_obj.dmi' + icon_state = "blood_shield" + lefthand_file = 'tff_modular/modules/vampire/icons/bs_leftinhand.dmi' + righthand_file = 'tff_modular/modules/vampire/icons/bs_rightinhand.dmi' + block_chance = 100 + +/obj/item/shield/vampire/Initialize(mapload) + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, INNATE_TRAIT) + +/obj/item/shield/vampire/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) + if(attack_type == PROJECTILE_ATTACK) + // energy and laser beams have less block chance + if(istype(hitby, /obj/projectile/energy) || istype(hitby, /obj/projectile/beam/laser)) + final_block_chance -= 25 + . = ..() + if(. && damage > 0) + var/datum/antagonist/vampire/vampire = IS_VAMPIRE(owner) + vampire?.adjust_blood_volume(-15) diff --git a/tff_modular/modules/vampire/powers/thaumaturgy/thaumaturgy.dm b/tff_modular/modules/vampire/powers/thaumaturgy/thaumaturgy.dm new file mode 100644 index 00000000000..a7a1f31cac5 --- /dev/null +++ b/tff_modular/modules/vampire/powers/thaumaturgy/thaumaturgy.dm @@ -0,0 +1,11 @@ +/datum/discipline/thaumaturgy + name = "Thaumaturgy" + discipline_explanation = "Thaumaturgy is the closely guarded form of blood magic practiced by the vampiric clan Tremere." + icon_state = "thaumaturgy" + + // Lists of abilities granted per level + level_1 = list(/datum/action/cooldown/vampire/targeted/bloodbolt) + level_2 = list(/datum/action/cooldown/vampire/targeted/bloodbolt, /datum/action/cooldown/vampire/bloodshield) + level_3 = list(/datum/action/cooldown/vampire/targeted/bloodbolt, /datum/action/cooldown/vampire/bloodshield, /datum/action/cooldown/vampire/targeted/blooddrain) + level_4 = list(/datum/action/cooldown/vampire/targeted/bloodbolt, /datum/action/cooldown/vampire/bloodshield, /datum/action/cooldown/vampire/targeted/blooddrain, /datum/action/cooldown/vampire/targeted/bloodboil) + level_5 = list(/datum/action/cooldown/vampire/targeted/bloodbolt, /datum/action/cooldown/vampire/bloodshield, /datum/action/cooldown/vampire/targeted/blooddrain, /datum/action/cooldown/vampire/targeted/bloodboil/two) diff --git a/tff_modular/modules/bloodsucker/controllers.dm b/tff_modular/modules/vampire/society.dm similarity index 56% rename from tff_modular/modules/bloodsucker/controllers.dm rename to tff_modular/modules/vampire/society.dm index 9c3cdebc3b8..6830952ac71 100644 --- a/tff_modular/modules/bloodsucker/controllers.dm +++ b/tff_modular/modules/vampire/society.dm @@ -1,44 +1,13 @@ -///Legacy name - now refers to the time between free levels for vampires. -#define TIME_BLOODSUCKER_NIGHT 600 - -SUBSYSTEM_DEF(sol) - name = "Sol" - can_fire = FALSE - wait = 20 // ticks, not seconds (so this runs every second, actually) - flags = SS_NO_INIT | SS_BACKGROUND | SS_TICKER | SS_KEEP_TIMING - - ///The time between the next cycle. - var/time_til_cycle = TIME_BLOODSUCKER_NIGHT - ///If Bloodsucker levels for the night has been given out yet. - var/issued_XP = FALSE - -/datum/controller/subsystem/sol/Recover() - can_fire = SSsol.can_fire - time_til_cycle = SSsol.time_til_cycle - issued_XP = SSsol.issued_XP - -/datum/controller/subsystem/sol/fire(resumed = FALSE) - time_til_cycle-- - - if (time_til_cycle > 0 && time_til_cycle <= 15) - if (!issued_XP) - issued_XP = TRUE - SEND_SIGNAL(src, COMSIG_SOL_RANKUP_BLOODSUCKERS) - - if (time_til_cycle < 1) - issued_XP = FALSE - time_til_cycle = TIME_BLOODSUCKER_NIGHT - -#undef TIME_BLOODSUCKER_NIGHT - SUBSYSTEM_DEF(vsociety) name = "Vampire Society" wait = 5 MINUTES flags = SS_NO_INIT | SS_BACKGROUND can_fire = FALSE - var/pooling = FALSE + // Are we currently polling? + var/currently_polling = FALSE + // Ref to the prince datum var/datum/weakref/princedatum var/start_time = 0 @@ -46,38 +15,41 @@ SUBSYSTEM_DEF(vsociety) /datum/controller/subsystem/vsociety/fire(resumed = FALSE) var/time_elapsed = world.time - start_time + // Give them some breathing room if(time_elapsed < 9 MINUTES) return - if(!princedatum && !pooling) + if(!princedatum && !currently_polling) for(var/datum/antagonist/vampire as anything in GLOB.all_vampires) - to_chat(vampire.owner.current, span_announce("*Vampire Tip: A vote for Prince will occur soon. If you are interested in leading your fellow kindred, press voting button!")) + to_chat(vampire.owner.current, span_announce("* Vampire Tip: A vote for Prince will occur soon. If you are interested in leading your fellow kindred, read up on princes in your info panel now!")) addtimer(CALLBACK(src, PROC_REF(poll_for_prince)), 2 MINUTES) - message_admins("Vampire Society has fired, and a prince poll will occur in 2 minutes.") + message_admins("Vampire society has fired, and a prince poll will occur in 2 minutes.") log_game("Vampire society has fired, and a prince poll will occur soon.") /datum/controller/subsystem/vsociety/proc/poll_for_prince() message_admins("Vampire society is now polling for a new prince.") log_game("Vampire society is now polling for a new prince.") + //Build a list of mobs in GLOB.all_vampires var/list/vampire_living_candidates = list() for(var/datum/antagonist/vampire as anything in GLOB.all_vampires) var/currentmob = vampire.owner?.current - if(!isliving(currentmob)) + if(!isliving(currentmob)) //Are we mob/living? continue var/mob/living/livingmob = currentmob - if(livingmob.health <= HEALTH_THRESHOLD_DEAD) + if(livingmob.health <= HEALTH_THRESHOLD_DEAD) // we check health instead of stat to avoid skipping out on vamps that are in torpor or something continue vampire_living_candidates += currentmob - pooling = TRUE - var/icon/prince_icon = icon('tff_modular/modules/bloodsucker/icons/bloodsucker.dmi', "prince") + // Build a poll_config datum to match the new polling API + currently_polling = TRUE + var/icon/prince_icon = icon('tff_modular/modules/vampire/icons/vampiric.dmi', "prince") prince_icon.Scale(24, 24) - var/list/poolers = SSpolling.poll_candidates( + var/list/pollers = SSpolling.poll_candidates( "You are eligible for princedom.", poll_time = 3 MINUTES, flash_window = TRUE, @@ -85,58 +57,72 @@ SUBSYSTEM_DEF(vsociety) alert_pic = prince_icon, role_name_text = "Prince", custom_response_messages = list( - POLL_RESPONSE_SIGNUP = "You have made your bid for princedom.
    * Note: Princedom has certain expectations placed upon you. If you are not in a position to enforce a masquerade, consider letting someone else take this burden.", + POLL_RESPONSE_SIGNUP = "You have made your bid for princedom.
    * Note: Princedom has certain expectations placed upon you. If you are not in a position to enforce the masquerade, consider letting someone else take this burden.", POLL_RESPONSE_UNREGISTERED = "You have removed your bid to princedom.", ), amount_to_pick = length(GLOB.all_vampires), announce_chosen = FALSE, ) - pooling = FALSE + currently_polling = FALSE - var/datum/antagonist/bloodsucker/chosen_datum + var/datum/antagonist/vampire/chosen_datum var/mob/living/chosen_candidate + // We have to do this shit because the polling proc doesn't always return a list. Sometimes it just returns a mob. var/list/candidates = list() - candidates += poolers + candidates += pollers + + for(var/mob/living/current_candidate in candidates) // Pick the ideal one from the list. + var/datum/antagonist/vampire/current_datum = IS_VAMPIRE(current_candidate) - for(var/mob/living/current_candidate in candidates) - var/datum/antagonist/bloodsucker/current_datum = IS_BLOODSUCKER(current_candidate) - if(!chosen_candidate) + if(!chosen_candidate) // If we are the first in line, just be the prince by default chosen_candidate = current_candidate - chosen_datum = IS_BLOODSUCKER(current_candidate) + chosen_datum = IS_VAMPIRE(current_candidate) continue + if(current_datum.get_princely_score() >= chosen_datum.get_princely_score()) chosen_candidate = current_candidate - chosen_datum = IS_BLOODSUCKER(current_candidate) + chosen_datum = IS_VAMPIRE(current_candidate) - if(chosen_datum) - chosen_datum.princify() + if(chosen_datum) + chosen_datum.princify() +/** + * Resumes society, called when someone is assigned Vampire +**/ +/datum/antagonist/vampire/proc/check_start_society() - - -/datum/antagonist/bloodsucker/proc/check_start_society() - if(SSvsociety.can_fire) + if(SSvsociety.can_fire || !CONFIG_GET(flag/allow_vampire_prince)) return + if(length(GLOB.all_vampires) >= 3) SSvsociety.start_time = world.time SSvsociety.can_fire = TRUE message_admins("Vampire Society has started, as there are [length(GLOB.all_vampires)] vampires active.") log_game("Vampire Society has started, as there are [length(GLOB.all_vampires)] vampires active.") -/datum/antagonist/bloodsucker/proc/check_cancel_society() +/** + * Pauses society, called when someone is unassigned Vampire +**/ +/datum/antagonist/vampire/proc/check_cancel_society() + if(!SSvsociety.can_fire) return - if(length(GLOB.all_vampires) < 3) + + if(length(GLOB.all_vampires) < 3 || !CONFIG_GET(flag/allow_vampire_prince)) SSvsociety.can_fire = FALSE message_admins("Vampire Society has paused, as there are only [length(GLOB.all_vampires)] vampires active.") log_game("Vampire Society has paused, as there are only [length(GLOB.all_vampires)] vampires active.") -/datum/antagonist/bloodsucker/proc/princify() +/** + * Turns the player into a prince. +**/ +/datum/antagonist/vampire/proc/princify() SSvsociety.princedatum = WEAKREF(src) - AdjustUnspentRank(8) + + rank_up(8, TRUE) // Rank up a lot. to_chat(owner.current, span_cult_bold("As a true prince, you find some of your old power returning to you!")) - owner.current.playsound_local(null, 'tff_modular/modules/bloodsucker/sound/prince.ogg', 100, FALSE, pressure_affected = FALSE) + owner.current.playsound_local(null, 'tff_modular/modules/vampire/sound/prince.ogg', 100, FALSE, pressure_affected = FALSE) prince = TRUE add_team_hud(owner.current) @@ -144,9 +130,10 @@ SUBSYSTEM_DEF(vsociety) for(var/datum/antagonist/vampire as anything in GLOB.all_vampires) to_chat(vampire.owner.current, span_narsiesmall("[full_name], also known as [owner.name || owner.current.real_name || owner.current.name], has claimed the role of Prince!")) - BuyPower(/datum/action/cooldown/bloodsucker/targeted/scourgify) + if(CONFIG_GET(flag/allow_vampire_scourge)) + grant_power(new /datum/action/cooldown/vampire/targeted/scourgify) - var/datum/objective/bloodsucker/prince/prince_objective = new() + var/datum/objective/vampire/prince/prince_objective = new() objectives += prince_objective owner.announce_objectives() @@ -154,50 +141,66 @@ SUBSYSTEM_DEF(vsociety) log_game("[key_name(owner.current)] has become the Vampire Prince. ([get_princely_score()] princely score, with [my_clan?.princely_score_bonus]/[min(50, owner.current?.client?.get_exp_living(TRUE) / 60) / 10] clan/hour bonus.)") notify_ghosts( - "[owner.name] has become the Bloodsucker Prince!", + "[owner.name] has become the Vampire Prince!", source = owner.current, - header = "All hail the Prince!" + notify_flags = NOTIFY_CATEGORY_NOFLASH, + header = "bloodclan confirmed???", ) update_static_data_for_all_viewers() tgui_alert(owner.current, "Congratulations, you have been chosen for Princedom.\nPlease note that this entails a certain responsibility. Your job, now, is to keep order, and to enforce the masquerade.", "Welcome, my Prince.", list("I understand"), 30 SECONDS, TRUE) -/datum/antagonist/bloodsucker/proc/scourgify() - ASSERT(!prince, "Somehow a prince was going to be turned into a scourge") - AdjustUnspentRank(4) +/** + * Turns the player into a scourge. +**/ +/datum/antagonist/vampire/proc/scourgify() + ASSERT(!prince, "Somehow a prince was going to be turned into a scourge") // Literally how would this happen. Still, just in case. + + rank_up(4, TRUE) // Rank up less. to_chat(owner.current, span_cult_bold("As a Camarilla scourge, your newfound purpose empowers you!")) - owner.current.playsound_local(null, 'tff_modular/modules/bloodsucker/sound/scourge_recruit.ogg', 100, FALSE, pressure_affected = FALSE) + owner.current.playsound_local(null, 'tff_modular/modules/vampire/sound/scourge_recruit.ogg', 100, FALSE, pressure_affected = FALSE) scourge = TRUE add_team_hud(owner.current) - var/datum/objective/bloodsucker/scourge/scourge_objectives = new() - objectives += scourge_objectives + + var/datum/objective/vampire/scourge/scourge_objective = new() + objectives += scourge_objective owner.announce_objectives() - for(var/datum/antagonist/bloodsucker as anything in GLOB.all_vampires) - to_chat(bloodsucker.owner.current, span_cult_bold(span_big("Under authority of the Prince, [owner.name || owner.current.real_name || owner.current.name] has been raised to the duty of the Scourge!"))) - message_admins("[ADMIN_LOOKUPFLW(owner.current)] has been made a Scourge of the Bloodsuckers!") - log_game("[key_name(owner.current)] has become a Scourge of the Bloodsuckers.") + for(var/datum/antagonist/vampire as anything in GLOB.all_vampires) + to_chat(vampire.owner.current, span_cult_bold(span_big("Under authority of the Prince, [owner.name || owner.current.real_name || owner.current.name] has been raised to the duty of the Scourge!"))) + + message_admins("[ADMIN_LOOKUPFLW(owner.current)] has been made a Scourge of the Vampires!") + log_game("[key_name(owner.current)] has become a Scourge of the Vampires.") notify_ghosts( - "[owner.name] has been raised to the duty Scourge of the Bloodsuckers!", + "[owner.name] has been raised to the duty Scourge of the Vampires!", source = owner.current, - header = "All hail the Prince!", + notify_flags = NOTIFY_CATEGORY_NOFLASH, + header = "bloodclan confirmed???", ) update_static_data_for_all_viewers() -/datum/antagonist/bloodsucker/proc/get_princely_score() +/** + * Returns the princyness of this vampire. + * get the players hours, convert it into a 10 point scale, 0-100 hours. + * get their clans default princely score. 0-10(mostly). + * Add those together. +**/ +/datum/antagonist/vampire/proc/get_princely_score() var/calculated_hour_score = min(50, owner.current?.client?.get_exp_living(TRUE) / 60) / 10 + var/clan_bonus = my_clan?.princely_score_bonus || -10 return clan_bonus + calculated_hour_score -/datum/objective/bloodsucker/scourge +// We could put this in objectives but like, it's just two tiny hardcoded things. It's fine here. +/datum/objective/vampire/scourge name = "Camarilla Scourge" explanation_text = "Obey your prince! Ensure order! Safeguard the Masquerade!" completed = TRUE -/datum/objective/bloodsucker/prince +/datum/objective/vampire/prince name = "Camarilla Prince" explanation_text = "Rule your fellow kindred with an iron fist! Ensure the sanctity of the Masquerade, at ALL costs!" completed = TRUE diff --git a/tff_modular/modules/vampire/sound/VampireAlert.ogg b/tff_modular/modules/vampire/sound/VampireAlert.ogg new file mode 100644 index 0000000000000000000000000000000000000000..1113f1bcec63b2bcf7b5e400d659f94ccb4d7fcb GIT binary patch literal 213040 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
    b<@@FXf}X-^%Aesj;NpBQn-n5W-t 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 z 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

    rA)7dE9(xb?M9dWJQk`*!QW$34d?d+UL

    rq`m~2T1+!$ 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

    %+}+bCq!OMFPp` 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 literal 0 HcmV?d00001 diff --git a/tff_modular/modules/vampire/status_effects.dm b/tff_modular/modules/vampire/status_effects.dm new file mode 100644 index 00000000000..dcec4728bc8 --- /dev/null +++ b/tff_modular/modules/vampire/status_effects.dm @@ -0,0 +1,2 @@ +/datum/movespeed_modifier/status_effect/life_drain + multiplicative_slowdown = 1.25 diff --git a/tff_modular/modules/vampire/torpor_vampire.dm b/tff_modular/modules/vampire/torpor_vampire.dm new file mode 100644 index 00000000000..bcb3b527b69 --- /dev/null +++ b/tff_modular/modules/vampire/torpor_vampire.dm @@ -0,0 +1,103 @@ +/** + * # Torpor + * + * Torpor is what deals with the Vampire falling asleep, their healing, the effects, ect. + * This is basically what Sol is meant to do to them, but they can also trigger it manually if they wish to heal, as Burn is only healed through Torpor. + * You cannot manually exit Torpor, it is instead entered/exited by: + * + * Torpor is triggered by: + * - Entering a Coffin with more than 10 combined Brute/Burn damage, dealt with by /closet/crate/coffin/close() [coffins.dm] + * - Death, dealt with by /HandleDeath() + * Torpor is ended by: + * - Having less than 10 Burn damage while OUTSIDE of your Coffin while it isnt Sol. + * - Having less than 10 Brute & Burn Combined while INSIDE of your Coffin while it isnt Sol. + * - Sol being over, dealt with by /sunlight/process() [vampire_daylight.dm] +**/ +/datum/antagonist/vampire/proc/check_begin_torpor() + var/mob/living/carbon/carbon_owner = owner.current + if(QDELETED(carbon_owner)) + return + var/total_damage = carbon_owner.get_brute_loss() + carbon_owner.get_fire_loss() + if(total_damage >= 10 || length(carbon_owner.all_wounds)) + carbon_owner.apply_status_effect(/datum/status_effect/vampire_torpor) + +/datum/status_effect/vampire_torpor + id = "torpor" + alert_type = null + remove_on_fullheal = TRUE + heal_flag_necessary = HEAL_ADMIN // so admins can aheal in case stuff goes fucky wucky + /// Antag datum of the vampire. + var/datum/antagonist/vampire/vampire_datum + /// Cooldown twhere, if it finishes, we'll just force heal the vampire, to avoid eternal torpor. + COOLDOWN_DECLARE(force_heal_time) + /// List of traits applied while in torpor. + var/static/list/torpor_traits = list( + TRAIT_DEATHCOMA, + TRAIT_FAKEDEATH, + TRAIT_NODEATH, + TRAIT_RESISTHIGHPRESSURE, + TRAIT_RESISTLOWPRESSURE, + TRAIT_TORPOR, + ) + +/datum/status_effect/vampire_torpor/on_apply() + if(!iscarbon(owner) || QDELING(owner)) + return FALSE + vampire_datum = IS_VAMPIRE(owner) + if(!vampire_datum) + . = FALSE + CRASH("Attempted to apply [type] to a non-vampire!") + if(vampire_datum.final_death) + return FALSE + REMOVE_TRAIT(owner, TRAIT_SLEEPIMMUNE, TRAIT_VAMPIRE) + owner.add_traits(torpor_traits, TRAIT_STATUS_EFFECT(id)) + owner.remove_status_effect(/datum/status_effect/jitter) + vampire_datum.disable_all_powers() + to_chat(owner, span_notice("You enter the horrible slumber of deathless Torpor. You will heal until you are renewed.")) + COOLDOWN_START(src, force_heal_time, 5 MINUTES) + return TRUE + +/datum/status_effect/vampire_torpor/on_remove() + if(!iscarbon(owner) || vampire_datum.final_death) + return + + owner.grab_ghost() + owner.remove_traits(torpor_traits, TRAIT_STATUS_EFFECT(id)) + if(!HAS_TRAIT(owner, TRAIT_MASQUERADE)) + ADD_TRAIT(owner, TRAIT_SLEEPIMMUNE, TRAIT_VAMPIRE) + + vampire_datum.heal_vampire_organs() + vampire_datum.my_clan?.on_exit_torpor() + vampire_datum = null + + to_chat(owner, span_notice("You have recovered from Torpor.")) + +/datum/status_effect/vampire_torpor/tick(seconds_between_ticks) + if(should_end()) + qdel(src) + return + + if(COOLDOWN_FINISHED(src, force_heal_time) && !QDELETED(owner)) + log_game("[key_name(owner)] was in Torpor for 5 minutes, immediately reviving them to prevent a potential softlock.") + owner.revive(HEAL_ALL) + qdel(src) + +/datum/status_effect/vampire_torpor/proc/should_end() + if(HAS_TRAIT(owner, TRAIT_FRENZY)) + return TRUE + var/total_brute = owner.get_brute_loss() + var/total_burn = owner.get_fire_loss() + + if(total_burn >= 199) + return FALSE + + // You are in a coffin, so instead we'll check TOTAL damage. + if(istype(owner.loc, /obj/structure/closet/crate/coffin)) + if((total_brute + total_burn) <= 10) + owner.heal_overall_damage(brute = 10, burn = 10) // heal minor leftover damage + return TRUE + else if(total_brute <= 10) + owner.heal_overall_damage(brute = 10) // heal minor leftover damage + return TRUE + + return FALSE diff --git a/tff_modular/modules/vampire/tracking_vampire.dm b/tff_modular/modules/vampire/tracking_vampire.dm new file mode 100644 index 00000000000..99f4ee3ca87 --- /dev/null +++ b/tff_modular/modules/vampire/tracking_vampire.dm @@ -0,0 +1,34 @@ +/datum/antagonist/vampire/proc/setup_tracker(mob/living/body) + cleanup_tracker() + tracker = new(body, REF(src)) + + for(var/datum/antagonist/vassal/vassal in vassals) + vassal.monitor?.add_to_tracking_network(tracker.tracking_beacon) + tracker.tracking_beacon.toggle_visibility(TRUE) + +/datum/antagonist/vampire/proc/cleanup_tracker() + if(tracker) + QDEL_NULL(tracker) + +/** + * An abstract object contained within the vampire, used to host the team_monitor component. +**/ +/obj/effect/abstract/vampire_tracker_holder + name = "vampire tracker holder" + desc = span_danger("You REALLY shouldn't be seeing this!") + + var/datum/component/tracking_beacon/tracking_beacon + +/obj/effect/abstract/vampire_tracker_holder/Initialize(mapload, key) + . = ..() + tracking_beacon = AddComponent(/datum/component/tracking_beacon, \ + _frequency_key = key, \ + _colour = "#960000", \ + _global = TRUE, \ + _always_update = TRUE, \ + ) + +/obj/effect/abstract/vampire_tracker_holder/Destroy(force) + tracking_beacon.toggle_visibility(FALSE) + QDEL_NULL(tracking_beacon) + . = ..() diff --git a/tff_modular/modules/vampire/vassals/datum_vassal.dm b/tff_modular/modules/vampire/vassals/datum_vassal.dm new file mode 100644 index 00000000000..5e236a5f8d3 --- /dev/null +++ b/tff_modular/modules/vampire/vassals/datum_vassal.dm @@ -0,0 +1,240 @@ +/datum/antagonist/vassal + name = "\improper Vassal" + roundend_category = "Vassal" + antagpanel_category = "Vampire" + pref_flag = ROLE_VAMPIRE + show_in_roundend = FALSE + hud_icon = 'tff_modular/modules/vampire/icons/antag_hud.dmi' + antag_hud_name = "vassal" + stinger_sound = 'sound/effects/magic/mutate.ogg' + hijack_speed = 0 + + /// The Master Vampire's antag datum. + var/datum/antagonist/vampire/master + /// The Vampire's team + var/datum/team/vampire/vampire_team + /// List of Powers, like Vampires. + var/list/datum/action/powers = list() + /// A link to our team monitor, used to track our master. + var/datum/component/team_monitor/monitor + +/datum/antagonist/vassal/antag_panel_data() + return "Master : [master.owner.name]" + +/datum/antagonist/vassal/apply_innate_effects(mob/living/mob_override) + . = ..() + var/mob/living/current_mob = mob_override || owner.current + + RegisterSignal(current_mob, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) + RegisterSignals(current_mob, list(COMSIG_MOB_LOGIN, COMSIG_MOVABLE_Z_CHANGED), PROC_REF(on_login)) + RegisterSignal(current_mob, COMSIG_MOB_UPDATE_SIGHT, PROC_REF(on_update_sight)) + + current_mob.update_sight() + + // HUD + add_team_hud(current_mob) + + // Tracking + setup_monitor(current_mob) + current_mob.grant_language(/datum/language/vampiric, source = LANGUAGE_VASSAL) + + current_mob.faction += FACTION_VAMPIRE + + current_mob.clear_mood_event("vampcandle") + +/datum/antagonist/vassal/remove_innate_effects(mob/living/mob_override) + . = ..() + var/mob/living/current_mob = mob_override || owner.current + + UnregisterSignal(current_mob, list(COMSIG_ATOM_EXAMINE, COMSIG_MOB_LOGIN, COMSIG_MOVABLE_Z_CHANGED, COMSIG_MOB_UPDATE_SIGHT)) + current_mob.update_sight() + + // Tracking + QDEL_NULL(monitor) + current_mob.remove_language(/datum/language/vampiric, source = LANGUAGE_VASSAL) + + // Remove traits + REMOVE_TRAITS_IN(current_mob, TRAIT_VAMPIRE) + current_mob.faction -= FACTION_VAMPIRE + +/datum/antagonist/vassal/on_gain() + . = ..() + if(!master) + owner.remove_antag_datum(src) + CRASH("[owner.current] was vassilized without a master!") + + ADD_TRAIT(owner, TRAIT_VAMPIRE_ALIGNED, REF(src)) + + vampire_team = master.vampire_team + vampire_team.add_member(owner) + + // Enslave them to their Master + master.vassals |= src + owner.enslave_mind_to_creator(master.owner.current) + owner.current.log_message("has been vassalized by [master.owner.name]!", LOG_ATTACK, color="#960000") + + // Give powers + grant_power(new /datum/action/cooldown/vampire/recuperate) + grant_power(new /datum/action/cooldown/vampire/distress) + + // Give objectives + forge_objectives() + +/datum/antagonist/vassal/on_removal() + REMOVE_TRAIT(owner, TRAIT_VAMPIRE_ALIGNED, REF(src)) + + // Free them from their Master + if(master) + master.vassals -= src + owner.enslaved_to = null + + vampire_team.remove_member(owner) + vampire_team = null + + // Remove powers + for(var/datum/action/cooldown/vampire/power in powers) + powers -= power + power.Remove(owner.current) + + return ..() + +/datum/antagonist/vassal/on_body_transfer(mob/living/old_body, mob/living/new_body) + . = ..() + for(var/datum/action/cooldown/vampire/power in powers) + power.Remove(old_body) + power.Grant(new_body) + +/datum/antagonist/vassal/greet() + var/mob/living/living_vassal = owner.current + var/mob/living/living_master = master.owner.current + + // Alert vassal + var/list/msg = list() + msg += span_cult_large("You are now the mortal servant of [master.owner.name], a Vampire!") + msg += span_cult("You are not required to obey any other Vampire, for only [master.owner.name] is your master. The laws of Nanotrasen do not apply to you now; only your Master's word must be obeyed.") + to_chat(living_vassal, boxed_message(msg.Join("\n"))) + + play_stinger() + + antag_memory += "You are the mortal servant of [master.owner.name], a vampire!
    " + + // Alert master + to_chat(living_master, span_userdanger("[living_vassal] has become addicted to your immortal blood. [living_vassal.p_They()] [living_vassal.p_are()] now your undying servant")) + living_master.playsound_local(null, 'sound/effects/magic/mutate.ogg', 100, FALSE, pressure_affected = FALSE) + +/datum/antagonist/vassal/farewell() + if(silent) + return + + owner.current.visible_message( + span_deconversion_message("[owner.current]'s eyes dart feverishly from side to side, and then stop. [owner.current.p_They()] seem[owner.current.p_s()] calm, \ + like [owner.current.p_they()] [owner.current.p_have()] regained some lost part of [owner.current.p_them()]self."), + span_deconversion_message("With a snap, you are no longer enslaved to [master.owner]! You breathe in heavily, having regained your free will, albeit the memories of your time serving them feel like a vague fever dream...") + ) + owner.current.playsound_local(null, 'sound/effects/magic/mutate.ogg', 100, FALSE, pressure_affected = FALSE) + + // Alert master + if(master.owner) + to_chat(master.owner, span_cult_bold("You feel the bond with your vassal [owner.name] has somehow been broken!")) + +/datum/antagonist/vassal/on_mindshield(mob/implanter, mob/living/mob_override) + var/mob/living/target = mob_override || owner.current + target.log_message("has been deconverted from Vassalization by [key_name(implanter)]!", LOG_ATTACK, color="#960000") + owner.remove_antag_datum(/datum/antagonist/vassal) + return COMPONENT_MINDSHIELD_DECONVERTED + +/datum/antagonist/vassal/proc/on_login() + SIGNAL_HANDLER + var/mob/living/current = owner.current + if(!QDELETED(current)) + addtimer(CALLBACK(src, TYPE_PROC_REF(/datum/antagonist, add_team_hud), current), 0.5 SECONDS, TIMER_OVERRIDE | TIMER_UNIQUE) //i don't trust this to not act weird + +/datum/antagonist/vassal/admin_add(datum/mind/new_owner, mob/admin) + var/list/datum/mind/possible_vampires = list() + + // Get possible vampires + for(var/datum/antagonist/vampire/vampire in GLOB.antagonists) + var/datum/mind/vampire_mind = vampire.owner + if(QDELETED(vampire_mind?.current) || vampire_mind.current.stat == DEAD) + continue + + possible_vampires += vampire_mind + + if(!length(possible_vampires)) + return + + // CHOOSE A DAMN PERSON + var/datum/mind/choice = tgui_input_list(admin, "Which vampire should this vassal belong to?", "Vampire", possible_vampires) + if(!choice) + return + + log_admin("[key_name_admin(usr)] turned [key_name_admin(new_owner)] into a vassal of [key_name_admin(choice)]!") + var/datum/antagonist/vampire/vampire = IS_VAMPIRE(choice.current) + master = vampire + new_owner.add_antag_datum(src) + + to_chat(choice, span_notice("Through divine intervention, you've gained a new vassal!")) + +/datum/antagonist/vassal/forge_objectives() + var/datum/objective/vampire/vassal/vassal_objective = new + vassal_objective.owner = owner + objectives += vassal_objective + +/datum/antagonist/vassal/add_team_hud(mob/target) + QDEL_NULL(team_hud_ref) + + var/datum/atom_hud/alternate_appearance/basic/has_antagonist/hud = target.add_alt_appearance( + /datum/atom_hud/alternate_appearance/basic/has_antagonist, + "antag_team_hud_[REF(src)]", + hud_image_on(target), + ) + team_hud_ref = WEAKREF(hud) + + var/list/mob/living/mob_list = list() + for(var/datum/antagonist/antag as anything in GLOB.antagonists) + if(!istype(antag, /datum/antagonist/vampire) && !istype(antag, /datum/antagonist/vassal)) + continue + var/mob/living/current = antag.owner?.current + if(!QDELETED(current)) + mob_list |= current + + for (var/datum/atom_hud/alternate_appearance/basic/has_antagonist/antag_hud as anything in GLOB.has_antagonist_huds) + if(!(antag_hud.target in mob_list)) + continue + antag_hud.show_to(target) + hud.show_to(antag_hud.target) + +/datum/antagonist/vassal/proc/setup_monitor(mob/target) + QDEL_NULL(monitor) + if(QDELETED(master?.owner?.current) || QDELETED(master.tracker)) + return + + monitor = target.AddComponent(/datum/component/team_monitor, REF(master)) + monitor.add_to_tracking_network(master.tracker.tracking_beacon) + monitor.show_hud(target) + +/datum/antagonist/vassal/proc/on_examine(datum/source, mob/examiner, list/examine_text) + SIGNAL_HANDLER + + var/text = " " + + var/datum/antagonist/vampire/vampiredatum = IS_VAMPIRE(examiner) + if(src in vampiredatum?.vassals) + text += span_cult("This is your vassal!") + examine_text += text + else if(vampiredatum || (master?.broke_masquerade && IS_VAMPIRE_HUNTER(examiner)) || IS_VASSAL(examiner)) + text += span_cult("This is [master.return_full_name()]'s vassal") + examine_text += text + +// Vassals get night vision, so they can at least somewhat be useful to their masters in dark areas without revealing themselves with a flashlight or something. +// The night vision is weaker than true night vision like a vampire has, but it's still better than mesons. +/datum/antagonist/vassal/proc/on_update_sight(mob/user) + SIGNAL_HANDLER + user.lighting_cutoff = max(user.lighting_cutoff, round((LIGHTING_CUTOFF_HIGH + LIGHTING_CUTOFF_MEDIUM) / 2, 1)) + user.lighting_color_cutoffs = user.lighting_color_cutoffs ? blend_cutoff_colors(user.lighting_color_cutoffs, list(25, 8, 5)) : list(25, 8, 5) + +/// Used when your Master teaches you a new Power. +/datum/antagonist/vassal/proc/grant_power(datum/action/cooldown/vampire/power) + powers += power + power.Grant(owner.current) + log_vampire_power("[key_name(owner.current)] has received \"[power]\" as a vassal") diff --git a/tff_modular/modules/vampire/vassals/powers/distress.dm b/tff_modular/modules/vampire/vassals/powers/distress.dm new file mode 100644 index 00000000000..8eab51f991b --- /dev/null +++ b/tff_modular/modules/vampire/vassals/powers/distress.dm @@ -0,0 +1,21 @@ +/datum/action/cooldown/vampire/distress + name = "Distress" + desc = "Injure yourself, allowing you to make a desperate call for help to your Master." + button_icon_state = "power_distress" + power_explanation = "Use this Power anywhere and your Master will instantly be alerted to your location." + vampire_power_flags = NONE + vampire_check_flags = NONE + special_flags = NONE + vitaecost = 10 + cooldown_time = 10 SECONDS + +/datum/action/cooldown/vampire/distress/activate_power() + . = ..() + var/datum/antagonist/vassal/vassaldatum = IS_VASSAL(owner) + + owner.balloon_alert(owner, "you call out for your master!") + to_chat(vassaldatum.master.owner, span_userdanger("[owner.real_name], your loyal vassal, is desperately calling for aid at [get_area(owner)]!")) + + var/mob/living/living_owner = owner + living_owner.adjust_brute_loss(10) + deactivate_power() diff --git a/tff_modular/modules/vampire/vassals/powers/recuperate.dm b/tff_modular/modules/vampire/vassals/powers/recuperate.dm new file mode 100644 index 00000000000..34afe08522d --- /dev/null +++ b/tff_modular/modules/vampire/vassals/powers/recuperate.dm @@ -0,0 +1,79 @@ +/// Used by vassals +/datum/action/cooldown/vampire/recuperate + name = "Sanguine Recuperation" + desc = "Slowly heals you overtime using your master's blood, in exchange for some of your own blood and effort." + button_icon_state = "power_recup" + power_explanation = "Activating this Power will begin to heal your wounds.\n\ + You will heal Brute and Toxin damage at the cost of your Stamina and blood.\n\ + If you aren't a bloodless race, you will additionally heal Burn damage." + vampire_power_flags = BP_AM_TOGGLE + vampire_check_flags = BP_CANT_USE_WHILE_INCAPACITATED | BP_CANT_USE_WHILE_UNCONSCIOUS + special_flags = NONE + vitaecost = 1.5 + cooldown_time = 10 SECONDS + +/datum/action/cooldown/vampire/recuperate/can_use() + . = ..() + if(!.) + return FALSE + + if(owner.stat >= DEAD || owner.incapacitated(IGNORE_RESTRAINTS)) + owner.balloon_alert(owner, "you are incapacitated...") + return FALSE + + var/mob/living/living_owner = owner + if(!HAS_TRAIT(owner, TRAIT_NOBLOOD) && living_owner.blood_volume <= BLOOD_VOLUME_OKAY) + owner.balloon_alert(owner, "not enough blood!") + return FALSE + +/datum/action/cooldown/vampire/recuperate/activate_power() + . = ..() + to_chat(owner, span_notice("Your muscles clench as your master's immortal blood mixes with your own, knitting your wounds.")) + owner.balloon_alert(owner, "recuperate turned on.") + +/datum/action/cooldown/vampire/recuperate/use_power() + . = ..() + if(!. || !currently_active) + return + + var/mob/living/carbon/carbon_owner = owner + if(!istype(carbon_owner)) + return + + var/needs_update = FALSE + carbon_owner.set_jitter_if_lower(10 SECONDS) + carbon_owner.adjust_stamina_loss(vitaecost * 1.1, 5) // can't stamcrit you. barely. + needs_update += carbon_owner.adjust_brute_loss(-2.5, updating_health = FALSE) + needs_update += carbon_owner.adjust_tox_loss(-2, updating_health = FALSE, forced = TRUE) + // Plasmamen won't lose blood, they don't have any, so they don't heal from Burn. + if(!HAS_TRAIT(carbon_owner, TRAIT_NOBLOOD)) + carbon_owner.blood_volume -= vitaecost + needs_update += carbon_owner.adjust_fire_loss(-1.5, updating_health = FALSE) + + // Stop Bleeding + var/datum/wound/bloodiest_wound + for(var/datum/wound/iter_wound as anything in carbon_owner.all_wounds) + if(iter_wound.blood_flow && (!bloodiest_wound || (iter_wound.blood_flow > bloodiest_wound.blood_flow))) + bloodiest_wound = iter_wound + + bloodiest_wound?.adjust_blood_flow(-0.25) + + for(var/obj/item/bodypart/bodypart as anything in carbon_owner.bodyparts) + if(bodypart.generic_bleedstacks) + bodypart.adjustBleedStacks(-1, 0) + + if(needs_update) + carbon_owner.updatehealth() + +/datum/action/cooldown/vampire/recuperate/continue_active() + if(QDELETED(owner) || owner.stat == DEAD) + return FALSE + if(owner.incapacitated(IGNORE_RESTRAINTS)) + owner.balloon_alert(owner, "too exhausted...") + return FALSE + return TRUE + +/datum/action/cooldown/vampire/recuperate/deactivate_power() + if(!QDELETED(owner)) + owner.balloon_alert(owner, "recuperate turned off.") + return ..() diff --git a/tgstation.dme b/tgstation.dme index e70e42e2d38..ce3fee10666 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -9558,61 +9558,6 @@ #include "tff_modular\modules\autoaccent\code\autoaccent.dm" #include "tff_modular\modules\bar_jukebox\code\jukebox.dm" #include "tff_modular\modules\barsigns\code\barsigns.dm" -#include "tff_modular\modules\bloodsucker\controllers.dm" -#include "tff_modular\modules\bloodsucker\bloodsuckers\assets.dm" -#include "tff_modular\modules\bloodsucker\bloodsuckers\bloodsucker.dm" -#include "tff_modular\modules\bloodsucker\bloodsuckers\clans.dm" -#include "tff_modular\modules\bloodsucker\bloodsuckers\conversion.dm" -#include "tff_modular\modules\bloodsucker\bloodsuckers\crafts.dm" -#include "tff_modular\modules\bloodsucker\bloodsuckers\dynamic.dm" -#include "tff_modular\modules\bloodsucker\bloodsuckers\hud.dm" -#include "tff_modular\modules\bloodsucker\bloodsuckers\integration.dm" -#include "tff_modular\modules\bloodsucker\bloodsuckers\life.dm" -#include "tff_modular\modules\bloodsucker\bloodsuckers\movable_hud.dm" -#include "tff_modular\modules\bloodsucker\bloodsuckers\names.dm" -#include "tff_modular\modules\bloodsucker\bloodsuckers\objectives.dm" -#include "tff_modular\modules\bloodsucker\bloodsuckers\procs.dm" -#include "tff_modular\modules\bloodsucker\bloodsuckers\shaded_bloodsucker.dm" -#include "tff_modular\modules\bloodsucker\bloodsuckers\sol.dm" -#include "tff_modular\modules\bloodsucker\bloodsuckers\species.dm" -#include "tff_modular\modules\bloodsucker\bloodsuckers\trauma.dm" -#include "tff_modular\modules\bloodsucker\clans\clan.dm" -#include "tff_modular\modules\bloodsucker\clans\clan_flavortext.dm" -#include "tff_modular\modules\bloodsucker\clans\clan_malkavian.dm" -#include "tff_modular\modules\bloodsucker\clans\clan_nosferatu.dm" -#include "tff_modular\modules\bloodsucker\clans\clan_tremere.dm" -#include "tff_modular\modules\bloodsucker\clans\clan_ventrue.dm" -#include "tff_modular\modules\bloodsucker\powers\_powers.dm" -#include "tff_modular\modules\bloodsucker\powers\cloak.dm" -#include "tff_modular\modules\bloodsucker\powers\feed.dm" -#include "tff_modular\modules\bloodsucker\powers\fortitude.dm" -#include "tff_modular\modules\bloodsucker\powers\gohome.dm" -#include "tff_modular\modules\bloodsucker\powers\masquerade.dm" -#include "tff_modular\modules\bloodsucker\powers\veil.dm" -#include "tff_modular\modules\bloodsucker\powers\prince\scourgify.dm" -#include "tff_modular\modules\bloodsucker\powers\targeted\_powers_targeted.dm" -#include "tff_modular\modules\bloodsucker\powers\targeted\brawn.dm" -#include "tff_modular\modules\bloodsucker\powers\targeted\haste.dm" -#include "tff_modular\modules\bloodsucker\powers\targeted\lunge.dm" -#include "tff_modular\modules\bloodsucker\powers\targeted\mesmerize.dm" -#include "tff_modular\modules\bloodsucker\powers\targeted\trespass.dm" -#include "tff_modular\modules\bloodsucker\powers\tremere\_powers_tremere.dm" -#include "tff_modular\modules\bloodsucker\powers\tremere\auspex.dm" -#include "tff_modular\modules\bloodsucker\powers\tremere\dominate.dm" -#include "tff_modular\modules\bloodsucker\powers\tremere\thaumaturgy.dm" -#include "tff_modular\modules\bloodsucker\powers\vassal\distress.dm" -#include "tff_modular\modules\bloodsucker\powers\vassal\recuperate.dm" -#include "tff_modular\modules\bloodsucker\powers\vassal\vassal_fold.dm" -#include "tff_modular\modules\bloodsucker\structures\coffin.dm" -#include "tff_modular\modules\bloodsucker\structures\crypt.dm" -#include "tff_modular\modules\bloodsucker\structures\objects.dm" -#include "tff_modular\modules\bloodsucker\vassal\batform.dm" -#include "tff_modular\modules\bloodsucker\vassal\vassal_datum.dm" -#include "tff_modular\modules\bloodsucker\vassal\vassal_pinpointer.dm" -#include "tff_modular\modules\bloodsucker\vassal\vassal_procs.dm" -#include "tff_modular\modules\bloodsucker\vassal\vassal_types\ex_vassal.dm" -#include "tff_modular\modules\bloodsucker\vassal\vassal_types\favorite_vassal.dm" -#include "tff_modular\modules\bloodsucker\vassal\vassal_types\revenge_vassal.dm" #include "tff_modular\modules\blooper\atoms_movable.dm" #include "tff_modular\modules\blooper\bark.dm" #include "tff_modular\modules\blooper\bark_list.dm" @@ -9782,6 +9727,81 @@ #include "tff_modular\modules\toys\code\loadout_datum_toys.dm" #include "tff_modular\modules\toys\code\plushes.dm" #include "tff_modular\modules\toys\code\soulmate_plushes.dm" +#include "tff_modular\modules\vampire\component.dm" +#include "tff_modular\modules\vampire\config.dm" +#include "tff_modular\modules\vampire\conversion_vampire.dm" +#include "tff_modular\modules\vampire\crafts.dm" +#include "tff_modular\modules\vampire\datum_vampire.dm" +#include "tff_modular\modules\vampire\effects.dm" +#include "tff_modular\modules\vampire\frenzy_vampire.dm" +#include "tff_modular\modules\vampire\language.dm" +#include "tff_modular\modules\vampire\leveling_vampire.dm" +#include "tff_modular\modules\vampire\life_vampire.dm" +#include "tff_modular\modules\vampire\misc_procs_vampire.dm" +#include "tff_modular\modules\vampire\monitor.dm" +#include "tff_modular\modules\vampire\moodlets_vampire.dm" +#include "tff_modular\modules\vampire\names_vampire.dm" +#include "tff_modular\modules\vampire\objectives_vampire.dm" +#include "tff_modular\modules\vampire\oozeling_vampire.dm" +#include "tff_modular\modules\vampire\society.dm" +#include "tff_modular\modules\vampire\status_effects.dm" +#include "tff_modular\modules\vampire\torpor_vampire.dm" +#include "tff_modular\modules\vampire\tracking_vampire.dm" +#include "tff_modular\modules\vampire\clans\_clan.dm" +#include "tff_modular\modules\vampire\clans\assignclan.dm" +#include "tff_modular\modules\vampire\clans\brujah.dm" +#include "tff_modular\modules\vampire\clans\debug.dm" +#include "tff_modular\modules\vampire\clans\flavortext_clans.dm" +#include "tff_modular\modules\vampire\clans\malkavian.dm" +#include "tff_modular\modules\vampire\clans\toreador.dm" +#include "tff_modular\modules\vampire\clans\tremere.dm" +#include "tff_modular\modules\vampire\clans\ventrue.dm" +#include "tff_modular\modules\vampire\objects\_vampire_object.dm" +#include "tff_modular\modules\vampire\objects\blood_drinking.dm" +#include "tff_modular\modules\vampire\objects\blood_throne.dm" +#include "tff_modular\modules\vampire\objects\candelabrum.dm" +#include "tff_modular\modules\vampire\objects\coffin.dm" +#include "tff_modular\modules\vampire\objects\hunter_gear.dm" +#include "tff_modular\modules\vampire\objects\kindred.dm" +#include "tff_modular\modules\vampire\objects\umbrellas.dm" +#include "tff_modular\modules\vampire\objects\vassal_rack.dm" +#include "tff_modular\modules\vampire\powers\_power.dm" +#include "tff_modular\modules\vampire\powers\_targeted.dm" +#include "tff_modular\modules\vampire\powers\disciplines.dm" +#include "tff_modular\modules\vampire\powers\feed.dm" +#include "tff_modular\modules\vampire\powers\gohome.dm" +#include "tff_modular\modules\vampire\powers\levelspells.dm" +#include "tff_modular\modules\vampire\powers\masquerade.dm" +#include "tff_modular\modules\vampire\powers\auspex\astral_project.dm" +#include "tff_modular\modules\vampire\powers\auspex\auspex.dm" +#include "tff_modular\modules\vampire\powers\celerity\celerity.dm" +#include "tff_modular\modules\vampire\powers\celerity\haste.dm" +#include "tff_modular\modules\vampire\powers\celerity\quickness.dm" +#include "tff_modular\modules\vampire\powers\dominate\command.dm" +#include "tff_modular\modules\vampire\powers\dominate\dominate.dm" +#include "tff_modular\modules\vampire\powers\dominate\mesmerize.dm" +#include "tff_modular\modules\vampire\powers\fortitude\fortitude.dm" +#include "tff_modular\modules\vampire\powers\obfuscate\cloak.dm" +#include "tff_modular\modules\vampire\powers\obfuscate\obfuscate.dm" +#include "tff_modular\modules\vampire\powers\obfuscate\trespass.dm" +#include "tff_modular\modules\vampire\powers\obfuscate\veil.dm" +#include "tff_modular\modules\vampire\powers\potence\brash.dm" +#include "tff_modular\modules\vampire\powers\potence\brawn.dm" +#include "tff_modular\modules\vampire\powers\potence\lunge.dm" +#include "tff_modular\modules\vampire\powers\potence\potence.dm" +#include "tff_modular\modules\vampire\powers\presence\awe.dm" +#include "tff_modular\modules\vampire\powers\presence\entrance.dm" +#include "tff_modular\modules\vampire\powers\presence\force_of_personality.dm" +#include "tff_modular\modules\vampire\powers\presence\presence.dm" +#include "tff_modular\modules\vampire\powers\presence\summon.dm" +#include "tff_modular\modules\vampire\powers\thaumaturgy\bloodboil.dm" +#include "tff_modular\modules\vampire\powers\thaumaturgy\bloodbolt.dm" +#include "tff_modular\modules\vampire\powers\thaumaturgy\blooddrain.dm" +#include "tff_modular\modules\vampire\powers\thaumaturgy\bloodshield.dm" +#include "tff_modular\modules\vampire\powers\thaumaturgy\thaumaturgy.dm" +#include "tff_modular\modules\vampire\vassals\datum_vassal.dm" +#include "tff_modular\modules\vampire\vassals\powers\distress.dm" +#include "tff_modular\modules\vampire\vassals\powers\recuperate.dm" #include "tff_modular\modules\vending\vending.dm" #include "tff_modular\modules\vending\vends\autodrobe.dm" #include "tff_modular\modules\vending\vends\clothing.dm" diff --git a/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss b/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss index c61ba8944ad..4b7fe1adc71 100644 --- a/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss +++ b/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss @@ -1519,4 +1519,18 @@ $border-width-px: $border-width * 1px; color: #009c22; } +.awe { + color: hsl(227, 87.7%, 68%); + animation: awe_glow 2s ease-in-out infinite; +} + +@keyframes awe_glow { + 0%, + 100% { + text-shadow: 0 0 8px rgb(255, 131, 197); + } + 50% { + text-shadow: 0 0 16px rgb(255, 0, 136); + } +} // TFF EDIT ADDITION END diff --git a/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss b/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss index deab03d4a65..19ccd601491 100644 --- a/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss +++ b/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss @@ -1421,4 +1421,18 @@ $border-width-px: $border-width * 1px; color: #006616; } +.awe { + color: hsl(240, 100%, 30%); + animation: awe_glow 2s ease-in-out infinite; +} + +@keyframes awe_glow { + 0%, + 100% { + text-shadow: 0 0 8px rgb(255, 131, 197); + } + 50% { + text-shadow: 0 0 16px rgb(255, 0, 136); + } +} // TFF EDIT ADDITION END diff --git a/tgui/packages/tgui/interfaces/AntagInfoBloodsucker.tsx b/tgui/packages/tgui/interfaces/AntagInfoBloodsucker.tsx deleted file mode 100644 index e4cd5d5aee5..00000000000 --- a/tgui/packages/tgui/interfaces/AntagInfoBloodsucker.tsx +++ /dev/null @@ -1,229 +0,0 @@ -import { useState } from 'react'; -import { Box, Button, Image, Section, Stack, Tabs } from 'tgui-core/components'; -import type { BooleanLike } from 'tgui-core/react'; - -import { resolveAsset } from '../assets'; -import { useBackend } from '../backend'; -import { Window } from '../layouts'; -import type { Objective } from './common/Objectives'; -import { PowerDetails } from './common/PowerInfo'; - -export type ClanProps = { - clan: ClanInfo[]; - in_clan: BooleanLike; -}; - -export type ClanInfo = { - clan_name: string; - clan_description: string; - clan_icon: string; -}; - -export type PowerInfo = { - power_name: string; - power_explanation: string[]; - power_icon: string; -}; - -export type BloodsuckerProps = { - powers: PowerInfo[]; - objectives: Objective[]; -}; -export type GhoulProps = BloodsuckerProps & { - title: string; - description: string; -}; - -const ObjectivePrintout = (props: any) => { - const { data } = useBackend(); - const { objectives } = data; - return ( - - Your current objectives: - - {(!objectives && 'None!') || - objectives.map((objective) => ( - - #{objective.count}: {objective.explanation} - - ))} - - - ); -}; - -export const AntagInfoBloodsucker = (props: any) => { - const [tab, setTab] = useState(1); - return ( - - - - setTab(1)} - > - Introduction - - setTab(2)} - > - Clan & Powers - - - {tab === 1 && } - {tab === 2 && } - - - ); -}; - -const BloodsuckerIntro = () => { - return ( - - -

    - - - You are a Bloodsucker, an undead blood-seeking monster living - aboard Space Station 13 - - - - - -
    - - -
    - - - - You regenerate your health slowly, you're weak to fire, and - you depend on blood to survive. Don't allow your blood to - run too low, or you'll enter a - - Frenzy!
    - - Beware of your Humanity level! The more Humanity you lose, the - easier it is to fall into a{' '} - Frenzy! - -
    - - Avoid using your Feed ability while near others, or else you - will risk breaking the Masquerade! - - - Loosing your heart will render your powers useless, but going - into a coffin with a heart inside will allow you to regenerate - it. - -
    -
    -
    -
    - -
    - - - Rest in a Coffin to claim it, and that area, as your haven. -
    - Examine your new structures to see how they function! -
    - Medical analyzers and the book of kindred can sell you out, your - Masquerade ability will hide your identity to prevent this. -
    - You will learn how to make persuasion racks once you have enough - levels to support a ghoul, which you will learn during torpor - during daytime. Examine the ghoul rack to see how many ghouls you - can have! -
    - You cannot level up until you select a clan. To select a clan, - click the clan tab on the top right of this window. -
    - Ensure to read the descriptions of each ability in the Clan & - Powers tab, you may learn something new! -
    - After a certain level, Sol will no longer grant you levels, - instead, you will need to feed on the blood of others to gain - levels. -
    - -
    - Other Bloodsuckers are not necessarily your friends, but your - survival may depend on cooperation. Betray them at your own - discretion and peril. -
    -
    -
    -
    -
    - - ); -}; - -const BloodsuckerClan = (props: any) => { - const { act, data } = useBackend(); - const { clan, in_clan, powers } = data; - - if (!in_clan) { - return ( -
    - - You are not in a Clan. - - - - -
    - ); - } - - return ( - - -
    - - - {clan.map((ClanInfo) => ( - <> - - - You are part of the {ClanInfo.clan_name} - - - {ClanInfo.clan_description} - - - ))} - - -
    -
    - -
    - ); -}; diff --git a/tgui/packages/tgui/interfaces/AntagInfoGhoul.tsx b/tgui/packages/tgui/interfaces/AntagInfoGhoul.tsx deleted file mode 100644 index c12f1bf3233..00000000000 --- a/tgui/packages/tgui/interfaces/AntagInfoGhoul.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import { Section, Stack } from 'tgui-core/components'; - -import { useBackend } from '../backend'; -import { Window } from '../layouts'; -import type { GhoulProps } from './AntagInfoBloodsucker'; -import { ObjectivePrintout } from './common/Objectives'; -import { PowerDetails } from './common/PowerInfo'; - -export const AntagInfoGhoul = (props: any, context: any) => { - const { data } = useBackend(); - const { powers } = data; - return ( - - - - - - ); -}; - -const GhoulInfo = () => { - const { data } = useBackend(); - const { powers, objectives, title, description } = data; - return ( - - -
    - - - {title} - - - - - -
    -
    - {description ? ( - -
    - - - {description} - - -
    -
    - ) : null} - - -
    - ); -}; diff --git a/tgui/packages/tgui/interfaces/AntagInfoVampire.tsx b/tgui/packages/tgui/interfaces/AntagInfoVampire.tsx new file mode 100644 index 00000000000..79e7e05035e --- /dev/null +++ b/tgui/packages/tgui/interfaces/AntagInfoVampire.tsx @@ -0,0 +1,1137 @@ +import type { BooleanLike } from 'common/react'; +import { type SetStateAction, useState } from 'react'; +import { sanitizeText } from 'tgui/sanitize'; +import { + Box, + Button, + DmIcon, + Icon, + Section, + Stack, + Tabs, +} from 'tgui-core/components'; +import { useBackend } from '../backend'; +import { Window } from '../layouts'; +import { type Objective, ObjectivePrintout } from './common/Objectives'; + +type VampireInformation = { + clan: ClanInfo[]; + in_clan: BooleanLike; + powers: PowerInfo[]; +}; + +type ClanInfo = { + name: string; + description: string; + icon: string; + icon_state: string; +}; + +type PowerInfo = { + name: string; + explanation: string; + icon: string; + icon_state: string; + cost: string; + constant_cost: string; + cooldown: string; +}; + +type Info = { + objectives: Objective[]; +}; + +enum InfoTab { + General = 1, + Basics, + Powers, +} + +export const AntagInfoVampire = () => { + // Set default to 2 so Basics (now in the middle) opens by default + const [tab, setTab] = useState(InfoTab.Basics); + + // Styles for the top-level tabs: + const topTabsStyle = { + display: 'flex', + width: '100%', + fontFamily: + '"Cinzel Decorative", "Uncial Antiqua", "Old English Text MT", serif', + } as const; + const topTabStyle = { + flex: 1, + fontSize: '25px', + padding: '10px 12px', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + textAlign: 'center', + fontWeight: 900, + letterSpacing: '0.5px', + textShadow: '0 1px 0 rgba(0,0,0,0.6)', + fontFamily: + '"Cinzel Decorative", "Uncial Antiqua", "Old English Text MT", serif', + } as const; + + return ( + + + + + {/* Guide on the left */} + setTab(InfoTab.General)} + > + General Guide + + + {/* Basics in the middle (slightly larger/bold for emphasis) */} + setTab(InfoTab.Basics)} + > + Basics + + + {/* Powers on the right */} + setTab(InfoTab.Powers)} + > + Powers + + + + + {/* Re-map which component shows for each tab index to match the new ordering */} + {tab === InfoTab.General && } + {tab === InfoTab.Basics && } + {tab === InfoTab.Powers && } + + + ); +}; + +const VampireIntroduction = (props: { + setTab: React.Dispatch>; +}) => { + const { data } = useBackend(); + const { objectives } = data; + return ( + + + + + + + + + + + + ); +}; + +enum GuideTab { + Basics = 1, + Masquerade, + Humanity, + Society, + Leveling, + Vitae, + Combat, + Lair, + Structures, + Vassals, +} + +const VampireGuide = () => { + const [tab, setTab] = useState(GuideTab.Basics); + + // small vertical padding for each tab; tweak values as desired + const guideTabStyle = { paddingTop: '10px', paddingBottom: '10px' } as const; + + return ( +
    + + + + setTab(GuideTab.Basics)} + style={guideTabStyle} + > + The Basics + + setTab(GuideTab.Masquerade)} + style={guideTabStyle} + > + The Masquerade + + setTab(GuideTab.Humanity)} + style={guideTabStyle} + > + Humanity + + setTab(GuideTab.Society)} + style={guideTabStyle} + > + Princes & Society + + setTab(GuideTab.Leveling)} + style={guideTabStyle} + > + Leveling + + setTab(GuideTab.Vitae)} + style={guideTabStyle} + > + Vitae + + setTab(GuideTab.Combat)} + style={guideTabStyle} + > + Combat + + setTab(GuideTab.Lair)} + style={guideTabStyle} + > + Your Lair + + setTab(GuideTab.Structures)} + style={guideTabStyle} + > + Structures + + setTab(GuideTab.Vassals)} + style={guideTabStyle} + > + Vassals + + + + + + {tab === GuideTab.Basics && ( + // The Basics + + + So you're a big bad vampire. Congrats. + + + Now keep it to yourself. + + + - 'Smiling' Jack, Los Angeles, circa 2001-2008. + +
    + Vampires survive because mortals think they're myths. + That's the{' '} + + Masquerade + + . The wolf doesn't want the sheep to know they're there. + Except these sheep have guns. + + {' '} + You must stay hidden. + +
    +
    + + Blending In + + You're dead: no breath, heartbeat, or need for food. That + makes you stand out. Avoid doctors, health scans, and especially + the{' '} + + Curator + + . They know vampires exist and can expose you. + + Tip: You have incredible powers, but using them draws + attention. Wise kindred blend in by acting like mortals. Use a + gun instead of claws. Walk instead of leaping across rooms. + Reserve your powers for when you truly need them. + +
    + + First Steps + + Take a moment to look at your screen. See those icons on the left? + That's your vampire HUD. Each icon gives you important + information, so click through them and learn what they show. +
    +
    + Your next priority should be finding another kindred. They can + help you learn the ropes, and they might point you toward the + local{' '} + + Prince + + . +
    + + + #1 RULE OF SURVIVAL + + + Keep vitae above 300. + + + A starving vampire is a dead vampire. Panic leads to mistakes. + + + Feed often. Feed smart. Stay alive. + + +
    + )} + {tab === GuideTab.Masquerade && ( + // The Masquerade + + + The Masquerade + + + How to keep from getting us all killed. + +
    + The{' '} + + Masquerade + {' '} + is an organized disinformation campaign enforced by{' '} + + Kindred + {' '} + society (mainly the{' '} + + Camarilla + + ) to convince humans that vampires do not exist. +
    +
    + If a mortal witnesses anything suspicious, you receive a{' '} + + Masquerade Infraction + + . After three, you are exiled and{' '} + + ALL + {' '} + vampires turn against you. +
    +
    + The{' '} + + Curator + {' '} + possesses the{' '} + + Archive of the Kindred + + , which can instantly expose you. However, if your{' '} + + Masquerade Ability + {' '} + is active, even this ancient tome cannot see through your + disguise. +
    +
    + At{' '} + + humanity + {' '} + above 7, you gain the{' '} + + Masquerade Ability + + , which fools health analyzers and the{' '} + + Curator + + . However, you will not heal normally while it is active. + + Tip: Too many bloodloss patients in medbay is just as + suspicious as a bloodless corpse in the halls. + +
    + + I broke the Masquerade. Now what? + + + • Everyone hunts you, vampires more than mortals +
    • Your vassals are up for grabs +
    • Other vampires can feed on you +
    Draining another vampire grants you their powers +
    • It is too late for mercy +
    +
    + )} + {tab === GuideTab.Humanity && ( + // Humanity + + + Humanity + + + Are we human? Or are we dancer? + +
    + Most{' '} + + Kindred + {' '} + were human before their Embrace. Clinging to{' '} + + humanity + {' '} + is how they resist the{' '} + + Beast's + {' '} + feral nature. +
    +
    + Your{' '} + + humanity + {' '} + directly affects the vampiric curse. Lower{' '} + + humanity + {' '} + means: +
    + + • Harder to interact with mortals +
    • Difficult to stay active during daylight +
    • Longer{' '} + + torpor + {' '} + recovery +
    +
    + + Click the humanity counter on your HUD for detailed information. + +
    + Why call it{' '} + + Humanity + {' '} + when not all{' '} + + kindred + {' '} + were human? Simple: tradition. Centuries-old vampires are slow to + change their ways. +
    + )} + {tab === GuideTab.Society && ( + // Society + + + Princes & Scourges + +
    A{' '} + + Prince + {' '} + is an elder vampire entrusted by the{' '} + + Camarilla + {' '} + to rule a territory. They keep track of every{' '} + + kindred + {' '} + present and enforce the{' '} + + Masquerade + {' '} + with an iron fist. +
    +
    + Of course, they do not work alone. Many{' '} + + Princes + {' '} + employ a{' '} + + Scourge + + , a personal enforcer loyal only to them. Scourges are often + chosen from clans like the Tremere, though some rare{' '} + + Princes + {' '} + have been known to employ even Brujah. + + Important: Princes have higher expectations placed upon + them. They must protect the Masquerade at all costs and deliver + final death to misbehaving kindred without hesitation. + +
    + + The Camarilla + +
    + The{' '} + + Camarilla + {' '} + is the most organized vampiric sect: an elite club that favors + tradition and covert control of mortals from behind the scenes. + Most vampire clans are part of them, though the{' '} + + Brujah notably insist on remaining independent + + . +
    +
    + Every city, station, colony, or outpost with a{' '} + + kindred + {' '} + presence has a{' '} + + Prince + {' '} + assigned by the{' '} + + Camarilla + {' '} + to oversee it. They are the chief enforcers of the{' '} + + Masquerade + + . +
    + )} + {tab === GuideTab.Leveling && ( + // Leveling + + + Leveling + + + Growing in Power + + As a vampire, you grow stronger over time by meeting your feeding + requirements. Click your blood meter on the HUD to see your + current progress toward the next rank. +
    + If you have consumed enough vitae to meet your goal, you will gain + a Rank whenever you next sleep in a coffin. Each rank provides + significant benefits: + + • Increased physical strength +
    • Greater health pool +
    • Faster feeding rate +
    • Higher blood capacity +
    • Additional discipline points to unlock new powers +
    +
    + In addition, you also passively gain a few ranks over time, and + will gain one rank whenever you vassalize a mortal into your + servant. +
    + )} + {tab === GuideTab.Vitae && ( + // Vitae + + + Vitae + +
    + + Vitae + {' '} + is the lifeblood that sustains every vampire. The{' '} + + Beast + {' '} + within you demands constant feeding, and ignoring this need is not + an option. When your blood reserves reach zero, you will + experience blurred vision, impaired healing, and far worse + consequences. +
    +
    + Your current rank determines how much{' '} + + vitae + {' '} + you can store and utilize at any given time. +
    +
    + + Sources of{' '} + + vitae + + : + + + • Crewmembers +
    • Monkeys +
    • Mice +
    • Bloodbags +
    + + Tip: Feed from crew regularly. Mice and monkeys will not + sustain you in the long run. + +
    + + Frenzy + + When your{' '} + + vitae + {' '} + is completely depleted, you lose control and enter a state known + as{' '} + + frenzy + + . In this feral state, the{' '} + + Beast + {' '} + takes over and compels you to attack the nearest mortal without + hesitation. +
    +
    + While in{' '} + + frenzy + + , you gain the ability to grab victims instantly, making you + extremely dangerous but also highly conspicuous. The only way to + regain control of yourself is to feed until you have enough{' '} + + vitae + {' '} + to suppress the{' '} + + Beast + + . +
    +
    + + Powers & Vitae + + All of your vampiric powers require{' '} + + vitae + {' '} + to use. Some abilities drain blood continuously while they remain + active, while others have an upfront cost when activated. Check + the Powers tab for specific costs and details on each ability. +
    + )} + {tab === GuideTab.Combat && ( + // Combat + + + Combat + +
    + As a vampire, you have significant advantages in combat, but also + critical weaknesses that can be exploited. +
    +
    + + Strengths + + + Enhanced Senses: Night vision and thermal vision let you + track prey in complete darkness. +
    +
    + Undead Physiology: No need to breathe, sleep, or eat. You + are immune to disease. Fatal wounds put you into{' '} + + Torpor + {' '} + instead of killing you. You will rise again if you have{' '} + + vitae + {' '} + and are not staked. +
    +
    + Resilience: Immune to cold, radiation, and toxins. + Critical injuries do not knock you down. +
    +
    + Supernatural Strength: Your fists deal devastating + damage, scaling with your rank. +
    +
    + + Weaknesses + + + Stakes: Paralyze you, disable powers, halt healing, and + prevent revival from{' '} + + Torpor + + . +
    +
    + Fire and Lasers: Deal devastating damage. Fortitude + offers minimal protection. +
    +
    + The Masquerade: Break it and every vampire turns against + you. You will be hunted by kindred and mortals alike. +
    +
    + )} + {tab === GuideTab.Lair && ( + // Lairs + + + Your Lair + +
    A{' '} + + lair + {' '} + is a location you have claimed as your own, where you can rest in + your coffin and perform certain vampiric rituals. Some vampires + find them useful. Many more have been caught because of them. +
    +
    + + Do You Need a{' '} + + Lair + + ? + + + Honestly? Probably not. A{' '} + + lair + {' '} + is only necessary if you intend to create{' '} + + vassals + {' '} + or use certain structures. + +
    + + Claiming a{' '} + + Lair + + + + If you still want one: acquire a coffin from the Chapel or craft + one via the Furniture category. Find somewhere{' '} + truly hidden, place the coffin, and rest inside to claim + the area. Once claimed, you can anchor vampiric structures like + the{' '} + + Vassalization Rack + {' '} + or{' '} + + Blood Throne + + . + +
    + + Warning: Maintenance is the first place people look. If + someone finds your lair, they find everything: your coffin, your + structures, your vassals, and you. + +
    + )} + {tab === GuideTab.Structures && ( + // Structures + + + Structures + + + These can be built via the Vampire crafting tab. + +
    + + Vassalization Rack + + + The vassalization rack is your tool for converting captured + crewmembers into loyal{' '} + + vassals + {' '} + who will serve your every command. +
    +
    + Usage: Secure the rack in your{' '} + + lair + {' '} + → restrain your target → drag them onto the rack → click the + rack to begin the torture process. +
    +
    + You can speed up the conversion significantly by using{' '} + + sharp tools + {' '} + on the victim while they are restrained. +
    +
    + + Crewmembers with{' '} + + mindshields + {' '} + or strong loyalties require their mental defenses to be weakened + first.{' '} + + Eldritch servants + {' '} + are completely immune and can never be converted. + +
    + + Candelabrum + + + A vampiric candelabra that radiates an unsettling aura. Any + mortal who gazes upon its{' '} + + flame + {' '} + will find their sanity slowly draining away. + +
    + + Blood Throne + + + When you sit upon a Blood Throne, your words are broadcast + telepathically to all{' '} + + kindred + {' '} + on the station. Other vampires will need their own throne if + they wish to respond. + +
    + )} + {tab === GuideTab.Vassals && ( + // Vassals + + + Vassals + +
    + + Vassals + {' '} + are mortals who have been broken and bound to your will. They + serve as your eyes, ears, and hands among the living, carrying out + your commands while you remain hidden in the shadows. +
    +
    + Creating Vassals + + To create a vassal, you will need a{' '} + + Vassalization Rack + {' '} + secured within your{' '} + + lair + + . Capture your target and restrain them so they cannot escape, + then drag them onto the rack. Click the rack to begin the{' '} + + torture + {' '} + process that will break their will and bind them to you. +
    +
    + Using{' '} + + sharp implements + {' '} + on the victim while they are restrained will accelerate the + process considerably. +
    +
    + Limitations + + Crewmembers protected by{' '} + + mindshields + {' '} + or those with strong existing loyalties cannot be converted + until their mental defenses have been weakened. Those who serve{' '} + + eldritch powers + {' '} + are completely immune and can never be turned. +
    +
    + Once someone has become your vassal, the only way to free them + is through implantation of a{' '} + + mindshield + + . +
    +
    + )} +
    +
    +
    + ); +}; + +const PowerSection = () => { + const { data } = useBackend(); + const { powers } = data; + if (!powers) { + return
    ; + } + + const [tab, setTab] = useState(0); + return ( +
    + + + + {powers.map((power, index) => ( + setTab(index)} + > + + + + } + width="32px" + style={{ + imageRendering: 'pixelated', + }} + /> + + {power.name} + + + ))} + + + + + {powers.map( + (power, index) => + tab === index && ( + + + {power.cost !== '0' && <>BLOOD COST: {power.cost}} + {power.cost !== '0' && power.constant_cost !== '0' && ( +
    + )} + {power.constant_cost !== '0' && ( + <>BLOOD DRAIN: {power.constant_cost} + )} + {(power.cost !== '0' || power.constant_cost !== '0') && + power.cooldown !== '0' && ( + <> +
    +
    + + )} + {power.cooldown !== '0' && ( + <> + COOLDOWN: {power.cooldown} seconds +
    +
    + + )} +
    + + + ), + )} +
    +
    +
    + ); +}; + +const ClanSection = () => { + const { data } = useBackend(); + const { clan, in_clan } = data; + + if (!in_clan) { + return ( +
    + + + + You are not in a clan! + + + + To determine your clan, utilize the clan selection ability. + + +
    + ); + } + + return ( +
    + {clan.map((ClanInfo, index) => ( + + + } + width="128px" + style={{ + imageRendering: 'pixelated', + }} + /> + + + + + You are part of the {ClanInfo.name}! + + + + + + ))} +
    + ); +}; diff --git a/tgui/packages/tgui/interfaces/KindredBook.tsx b/tgui/packages/tgui/interfaces/KindredBook.tsx index d92ca61680a..f2159acdbfa 100644 --- a/tgui/packages/tgui/interfaces/KindredBook.tsx +++ b/tgui/packages/tgui/interfaces/KindredBook.tsx @@ -1,6 +1,5 @@ -import { Collapsible, Section, Table } from 'tgui-core/components'; - import { useBackend } from '../backend'; +import { Collapsible, Section, Table } from 'tgui-core/components'; import { Window } from '../layouts'; type Data = { @@ -8,8 +7,8 @@ type Data = { }; type ClanInfo = { - clan_name: string; - clan_desc: string; + name: string; + desc: string; }; export const KindredBook = (props) => { @@ -18,7 +17,7 @@ export const KindredBook = (props) => { return ( -
    +
    Written by generations of Curators, this holds all information we @@ -30,8 +29,8 @@ export const KindredBook = (props) => {
    {clans.map((clan) => ( - - {clan.clan_desc} + + {clan.desc} ))} diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/bloodsucker.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/vampire.ts similarity index 71% rename from tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/bloodsucker.ts rename to tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/vampire.ts index 3a5127ffa1f..9991698a092 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/bloodsucker.ts +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/vampire.ts @@ -1,5 +1,3 @@ -// THIS IS A TFF UI FILE - import { type Antagonist, Category } from '../base'; export const VAMPIRE_MECHANICAL_DESCRIPTION = ` @@ -8,11 +6,10 @@ Use your Vampiric abilities as best you can. Scrape by Space Station 13, or take over it, ghoulizing your way. `; -const bloodsuckers: Antagonist = { - key: 'bloodsucker', - name: 'Roundstart Bloodsucker', +const Vampire: Antagonist = { + name = 'Vampire', description: [VAMPIRE_MECHANICAL_DESCRIPTION], category: Category.Roundstart, }; -export default bloodsuckers; +export default Vampire; diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/midroundbloodsucker.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/vampiricaccident.ts similarity index 63% rename from tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/midroundbloodsucker.ts rename to tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/vampiricaccident.ts index d7046699940..234baacc335 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/midroundbloodsucker.ts +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/vampiricaccident.ts @@ -1,5 +1,3 @@ -// THIS IS A TFF UI FILE - import { type Antagonist, Category } from '../base'; export const VAMPIRE_MECHANICAL_DESCRIPTION = ` @@ -8,11 +6,11 @@ Use your Vampiric abilities as best you can. Scrape by Space Station 13, or take over it, ghoulizing your way. `; -const VampiricAccident: Antagonist = { - key: 'bloodsuckermidround', - name: 'Bloodsucker (Midround)', +const Vampire: Antagonist = { + key = 'vampiricaccident', + name = 'Vampiric Accident', description: [VAMPIRE_MECHANICAL_DESCRIPTION], - category: Category.Midround, + category: Category.Roundstart, }; -export default VampiricAccident; +export default Vampire; From 84031c8617164744189bc8301e60c0f21598b2f7 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sat, 14 Mar 2026 10:50:30 +0300 Subject: [PATCH 025/149] =?UTF-8?q?=D0=BF=D0=B0=D1=80=D1=83=20=D0=B8=D0=B7?= =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/__DEFINES/~ff_defines/bloodsucker.dm | 2 +- tff_modular/modules/vampire/clans/_clan.dm | 2 +- tff_modular/modules/vampire/crafts.dm | 21 ++++-- tff_modular/modules/vampire/datum_vampire.dm | 4 +- tff_modular/modules/vampire/effects.dm | 1 + tff_modular/modules/vampire/frenzy_vampire.dm | 8 +- tff_modular/modules/vampire/icons/blood.dmi | Bin 0 -> 765 bytes tff_modular/modules/vampire/powers/feed.dm | 8 +- .../vampire/powers/thaumaturgy/bloodbolt.dm | 5 +- .../vampire/powers/thaumaturgy/blooddrain.dm | 1 + .../tgui/interfaces/AntagInfoVampire.tsx | 2 +- .../antagonists/antagonists/vampire.ts | 1 + .../tgui/interfaces/common/PowerInfo.tsx | 70 ------------------ 13 files changed, 34 insertions(+), 91 deletions(-) create mode 100644 tff_modular/modules/vampire/icons/blood.dmi delete mode 100644 tgui/packages/tgui/interfaces/common/PowerInfo.tsx diff --git a/code/__DEFINES/~ff_defines/bloodsucker.dm b/code/__DEFINES/~ff_defines/bloodsucker.dm index 456a04fd98e..c5aabc5d279 100644 --- a/code/__DEFINES/~ff_defines/bloodsucker.dm +++ b/code/__DEFINES/~ff_defines/bloodsucker.dm @@ -56,7 +56,7 @@ #define VITAE_GOAL_STANDARD 250 /// Default amount of damage the vampire's punch/kick damage increases with each level. -#define VAMPIRE_UNARMED_DMG_INCREASE_ON_RANKUP 0.5 +#define VAMPIRE_UNARMED_DMG_INCREASE_ON_RANKUP 1.25 /// How many starting levels do we want each one to have? #define VAMPIRE_STARTING_LEVELS 3 diff --git a/tff_modular/modules/vampire/clans/_clan.dm b/tff_modular/modules/vampire/clans/_clan.dm index 543fce95b52..95032790ec5 100644 --- a/tff_modular/modules/vampire/clans/_clan.dm +++ b/tff_modular/modules/vampire/clans/_clan.dm @@ -199,7 +199,7 @@ /datum/vampire_clan/proc/finalize_spend_rank() // Level up the vampire - vampiredatum.vampire_regen_rate += 0.05 + vampiredatum.vampire_regen_rate += 0.15 vampiredatum.max_vitae += 100 /* if(ishuman(vampiredatum.owner.current)) diff --git a/tff_modular/modules/vampire/crafts.dm b/tff_modular/modules/vampire/crafts.dm index 2ed580d02cd..d1822fe1de8 100644 --- a/tff_modular/modules/vampire/crafts.dm +++ b/tff_modular/modules/vampire/crafts.dm @@ -5,6 +5,7 @@ reqs = list(/obj/item/stack/sheet/mineral/wood = 3) time = 8 SECONDS category = CAT_WEAPON_MELEE + crafting_flags = CRAFT_SKIP_MATERIALS_PARITY /datum/crafting_recipe/hardened_stake name = "Hardened Stake" @@ -13,6 +14,7 @@ reqs = list(/obj/item/stack/rods = 1) time = 6 SECONDS category = CAT_WEAPON_MELEE + crafting_flags = CRAFT_SKIP_MATERIALS_PARITY /datum/crafting_recipe/silver_stake name = "Silver Stake" @@ -24,7 +26,7 @@ ) time = 8 SECONDS category = CAT_WEAPON_MELEE - crafting_flags = CRAFT_MUST_BE_LEARNED + crafting_flags = CRAFT_MUST_BE_LEARNED | CRAFT_SKIP_MATERIALS_PARITY /datum/crafting_recipe/vassalrack name = "Vassalization Rack" @@ -37,7 +39,7 @@ ) category = CAT_VAMPIRE - crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND | CRAFT_MUST_BE_LEARNED + crafting_flags = CRAFT_SKIP_MATERIALS_PARITY | CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND | CRAFT_MUST_BE_LEARNED /datum/crafting_recipe/candelabrum name = "Candelabrum" @@ -51,7 +53,7 @@ ) category = CAT_VAMPIRE - crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND | CRAFT_MUST_BE_LEARNED + crafting_flags = CRAFT_SKIP_MATERIALS_PARITY | CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND | CRAFT_MUST_BE_LEARNED /datum/crafting_recipe/bloodthrone name = "Blood Throne" @@ -64,7 +66,7 @@ ) category = CAT_VAMPIRE - crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND | CRAFT_MUST_BE_LEARNED + crafting_flags = CRAFT_SKIP_MATERIALS_PARITY | RAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND | CRAFT_MUST_BE_LEARNED /datum/crafting_recipe/meatcoffin name = "Meat Coffin" @@ -76,7 +78,7 @@ ) time = 15 SECONDS category = CAT_STRUCTURE - crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND | CRAFT_MUST_BE_LEARNED + crafting_flags = CRAFT_SKIP_MATERIALS_PARITY | CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND | CRAFT_MUST_BE_LEARNED /datum/crafting_recipe/vassalrack name = "Vassalization Rack" @@ -89,7 +91,7 @@ ) category = CAT_VAMPIRE - crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND | CRAFT_MUST_BE_LEARNED + crafting_flags = CRAFT_SKIP_MATERIALS_PARITY | CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND | CRAFT_MUST_BE_LEARNED /datum/crafting_recipe/candelabrum name = "Candelabrum" @@ -103,7 +105,7 @@ ) category = CAT_VAMPIRE - crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND | CRAFT_MUST_BE_LEARNED + crafting_flags = CRAFT_SKIP_MATERIALS_PARITY | CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND | CRAFT_MUST_BE_LEARNED /datum/crafting_recipe/bloodthrone name = "Blood Throne" @@ -116,7 +118,7 @@ ) category = CAT_VAMPIRE - crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND | CRAFT_MUST_BE_LEARNED + crafting_flags = CRAFT_SKIP_MATERIALS_PARITY | CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND | CRAFT_MUST_BE_LEARNED /datum/crafting_recipe/blackcoffin name = "Black Coffin" @@ -129,6 +131,7 @@ ) time = 15 SECONDS category = CAT_STRUCTURE + crafting_flags = CRAFT_SKIP_MATERIALS_PARITY /datum/crafting_recipe/securecoffin name = "Secure Coffin" @@ -141,6 +144,7 @@ ) time = 15 SECONDS category = CAT_STRUCTURE + crafting_flags = CRAFT_SKIP_MATERIALS_PARITY /datum/crafting_recipe/metalcoffin name = "Metal Coffin" @@ -151,3 +155,4 @@ ) time = 10 SECONDS category = CAT_STRUCTURE + crafting_flags = CRAFT_SKIP_MATERIALS_PARITY diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index c4e46933296..466f31dc551 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -92,7 +92,7 @@ /// Additional regeneration when the vampire has a lot of blood var/additional_regen /// How much damage the vampire heals each life tick. Increases per rank up - var/vampire_regen_rate = 0.3 + var/vampire_regen_rate = 0.45 /// Minimum cooldown when reviving. COOLDOWN_DECLARE(revive_cooldown) @@ -806,7 +806,7 @@ lost_limb.burn_modifier *= initial(lost_limb.burn_modifier) if(lost_limb.body_zone in BODY_ZONES_LIMBS) - var/extra_damage = 1 + (vampire_level / extra_damage_per_rank) + var/extra_damage = 2 + (vampire_level / extra_damage_per_rank) // safety measure in case we ever accidentally fuck up the math or something lost_limb.unarmed_damage_low = max(lost_limb.unarmed_damage_low - extra_damage, initial(lost_limb.unarmed_damage_low)) lost_limb.unarmed_damage_high = max(lost_limb.unarmed_damage_high - extra_damage, initial(lost_limb.unarmed_damage_high)) diff --git a/tff_modular/modules/vampire/effects.dm b/tff_modular/modules/vampire/effects.dm index 49b0f8069c5..96ce051afed 100644 --- a/tff_modular/modules/vampire/effects.dm +++ b/tff_modular/modules/vampire/effects.dm @@ -166,6 +166,7 @@ /obj/effect/decal/cleanable/blood/line name = "blood line" desc = "Raining blood, from a lacerated sky, bleeding its horror!" + icon = 'tff_modular/modules/vampire/icons/blood.dmi' icon_state = "line" random_icon_states = null base_name = "dried blood line" diff --git a/tff_modular/modules/vampire/frenzy_vampire.dm b/tff_modular/modules/vampire/frenzy_vampire.dm index 771ca5b5159..9ad4e312a5d 100644 --- a/tff_modular/modules/vampire/frenzy_vampire.dm +++ b/tff_modular/modules/vampire/frenzy_vampire.dm @@ -1,3 +1,5 @@ +#define CLIENT_COLOR_SOURCE_VAMPIRE "vampire_source" + /** * # Status effect * @@ -47,7 +49,7 @@ // Basic stuff carbon_owner.add_movespeed_modifier(/datum/movespeed_modifier/frenzy_speed) - carbon_owner.add_client_colour(/datum/client_colour/bloodlust) + carbon_owner.add_client_colour(/datum/client_colour/bloodlust, CLIENT_COLOR_SOURCE_VAMPIRE) carbon_owner.uncuff() carbon_owner.pulledby?.stop_pulling() carbon_owner.adjust_stamina_loss(-200) @@ -81,7 +83,7 @@ // Basic stuff carbon_owner.remove_movespeed_modifier(/datum/movespeed_modifier/frenzy_speed) - carbon_owner.remove_client_colour(/datum/client_colour/bloodlust) + carbon_owner.remove_client_colour(CLIENT_COLOR_SOURCE_VAMPIRE) // Alert them carbon_owner.balloon_alert(carbon_owner, "you come back to your senses.") @@ -113,3 +115,5 @@ /atom/movable/screen/alert/status_effect/masquerade/MouseEntered(location,control,params) desc = initial(desc) return ..() + +#undef CLIENT_COLOR_SOURCE_VAMPIRE diff --git a/tff_modular/modules/vampire/icons/blood.dmi b/tff_modular/modules/vampire/icons/blood.dmi new file mode 100644 index 0000000000000000000000000000000000000000..5b8caa395c453098e0a8f60d34b0dfc104a117e9 GIT binary patch literal 765 zcmVr(�DGTPE!Ct=GbNc003%wR9JLGWpiV4X>fFDZ*Bkp zc$`yKaB_9`^iy#0_2eo`Eh^5;&r`5fFwryM;w;ZhDainGjE%TBGg33tGfE(w;*!LY zR3K9+Co?ZqiHkEOv#1!zwcz4RD@x2w1+fjeloee4T)?IR02n42y75}A7ytkQBS}O- zR9Jkg1)_rKHHCbI@5$UfemR`VVxRUmb)4iM&l0aV5s zAFKiucwysc6vW;rm`M=~OyD$uV@tqE6EMPJ^#H1XL5))3LE|G6(9>5s1RyZ@82uP~ zyvZQOY?gaWO9c!Vf(!lm<$9?xHussw(M?1J%eraMPA3PCk{;G^KkhU^M^+DPd>S;t znF**$%a*{RqzWP<`?{qB`y-*by#^e$PTLBDF~rh5sRnTCmY)r z#LlIagyMkYaX4MyX7J8?^3<;hY!2K(_8Vio*E1rBOQ7du5Ctwfq4e$fRu6Wo@_Oow zIVCjQVAye5I=cS33*gnG3QA^iYHJyj)wzj&FG93_d238sI82Yv)6ucp;dA{}44MD> zpuRWrH*ULwm2B;3jeK*%{4bz?rJKX}Aio*}4=!HY9jskr{AlGbtDqaGi4X2&6Y^GH zL~61c?{F#$eN${9>wxq`=N!vhEtxK_3B6PpGs-Sq1JBnbzWetLUUfm7;LkPM6Gd%? z!zzeStRNh|AOv6R5tr$}!BXkXN0Jp|9Lq_Z#K;QX { - const { powers } = props; - if (!powers?.length) { - return
    ; - } - - const [selectedPower, setSelectedPower] = useState(powers[0]); - - return ( -
    - } - > - - - powers.power_name)} - onSelected={(powerName: string) => - setSelectedPower( - powers.find((p) => p.power_name === powerName) || powers[0], - ) - } - /> - {selectedPower && ( - - )} - - - - - {selectedPower?.power_explanation} - - -
    - ); -}; From 00712ba328ce07ca917ff8fd26abd134134ee736 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sat, 14 Mar 2026 10:52:09 +0300 Subject: [PATCH 026/149] Update crafts.dm --- tff_modular/modules/vampire/crafts.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tff_modular/modules/vampire/crafts.dm b/tff_modular/modules/vampire/crafts.dm index d1822fe1de8..5bc0614fe84 100644 --- a/tff_modular/modules/vampire/crafts.dm +++ b/tff_modular/modules/vampire/crafts.dm @@ -66,7 +66,7 @@ ) category = CAT_VAMPIRE - crafting_flags = CRAFT_SKIP_MATERIALS_PARITY | RAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND | CRAFT_MUST_BE_LEARNED + crafting_flags = CRAFT_SKIP_MATERIALS_PARITY | CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND | CRAFT_MUST_BE_LEARNED /datum/crafting_recipe/meatcoffin name = "Meat Coffin" From 1af384d6ef1eb345232556fb9b6d68f7ade83fef Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sat, 14 Mar 2026 11:30:16 +0300 Subject: [PATCH 027/149] =?UTF-8?q?=D0=B3=D0=BE=D1=80=D1=8B,=20=D0=B0?= =?UTF-8?q?=D0=BB=D1=8C=D0=BF=D1=8B=20=D0=B8=20=D1=85=D0=BE=D0=BB=D0=BC?= =?UTF-8?q?=D1=8B...?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modules/vampire/objects/umbrellas.dm | 1 + .../vampire/powers/thaumaturgy/blooddrain.dm | 47 +++++-------------- 2 files changed, 12 insertions(+), 36 deletions(-) diff --git a/tff_modular/modules/vampire/objects/umbrellas.dm b/tff_modular/modules/vampire/objects/umbrellas.dm index 092892e943e..266470ba213 100644 --- a/tff_modular/modules/vampire/objects/umbrellas.dm +++ b/tff_modular/modules/vampire/objects/umbrellas.dm @@ -165,3 +165,4 @@ tool_behaviors = list(TOOL_CROWBAR) time = 5 SECONDS category = CAT_EQUIPMENT + crafting_flags = CRAFT_SKIP_MATERIALS_PARITY diff --git a/tff_modular/modules/vampire/powers/thaumaturgy/blooddrain.dm b/tff_modular/modules/vampire/powers/thaumaturgy/blooddrain.dm index 63a123b0548..c7d153569f7 100644 --- a/tff_modular/modules/vampire/powers/thaumaturgy/blooddrain.dm +++ b/tff_modular/modules/vampire/powers/thaumaturgy/blooddrain.dm @@ -8,7 +8,7 @@ You must maintain line of sight to the victim for the effect to continue." vampire_power_flags = BP_AM_TOGGLE vampire_check_flags = BP_CANT_USE_IN_TORPOR | BP_CANT_USE_WHILE_STAKED | BP_CANT_USE_IN_FRENZY | BP_CANT_USE_WHILE_INCAPACITATED | BP_CANT_USE_WHILE_UNCONSCIOUS - vitaecost = 75 + vitaecost = 50 cooldown_time = 10 SECONDS // Very unlikely to ever last past 10 seconds even if the actual duration is longer. Combat is a fuck. target_range = 7 power_activates_immediately = FALSE @@ -16,56 +16,31 @@ ranged_mousepointer = 'tff_modular/modules/vampire/icons/vampire_blooddrain.dmi' var/datum/status_effect/blood_drain/active_effect + var/datum/beam/drain_beam + +/datum/action/cooldown/vampire/targeted/blooddrain/check_valid_target(atom/target_atom) + if(!isliving(target_atom)) + return FALSE + ..() /datum/action/cooldown/vampire/targeted/blooddrain/fire_targeted_power(atom/target_atom) . = ..() var/mob/living/living_owner = owner - /* var/mob/living/living_target = target_atom - check_witnesses(living_target) */ living_owner.face_atom(target_atom) living_owner.changeNext_move(CLICK_CD_RANGE) living_owner.newtonian_move(get_dir(target_atom, living_owner)) - - var/obj/projectile/magic/blood_drain/drain = new(living_owner.loc) - drain.firer = living_owner - drain.fired_from = src - drain.aim_projectile(target_atom, living_owner) - if(isliving(target_atom)) - drain.original = target_atom - drain.def_zone = ran_zone(living_owner.zone_selected) - INVOKE_ASYNC(drain, TYPE_PROC_REF(/obj/projectile, fire)) - - playsound(living_owner, 'sound/effects/magic/wandodeath.ogg', 60, TRUE) + playsound(living_owner, 'tff_modular/modules/vampire/sound/bloodbolt.ogg', 60, TRUE) + blood_drain(target_atom, living_owner, src) /datum/action/cooldown/vampire/targeted/blooddrain/deactivate_power() . = ..() if(!isnull(active_effect)) active_effect.end_drain() -/obj/projectile/magic/blood_drain - name = "vitality draining stream" - icon_state = "nothing" - range = 7 - antimagic_flags = MAGIC_RESISTANCE_HOLY - hitsound = 'tff_modular/modules/vampire/sound/bloodbolt.ogg' - var/datum/beam/drain_beam - -/obj/projectile/magic/blood_drain/fire(angle, atom/direct_target) +/datum/action/cooldown/vampire/targeted/blooddrain/proc/blood_drain(mob/living/victim, mob/living/carbon/firer, fired_from) if(!firer) CRASH("Projectile [src] fired with no firer") //We don't even want any of the rest of this to play out if we don't have a firer - drain_beam = firer.Beam(src, icon = 'icons/effects/beam.dmi', icon_state = "lifedrain", time = 10 SECONDS, maxdistance = 7, beam_color = COLOR_RED) - return ..() - -/obj/projectile/magic/blood_drain/on_hit(mob/living/target, blocked, pierce_hit) - . = ..() - if(isliving(target)) - target.apply_status_effect(/datum/status_effect/blood_drain, firer, fired_from) - -/obj/projectile/magic/blood_drain/Destroy() - if(!QDELETED(drain_beam)) - qdel(drain_beam) - drain_beam = null - return ..() + victim.apply_status_effect(/datum/status_effect, firer, fired_from) /// /// Status Effect. Literally copied from life drain spell of wizards, but modified to work with vampires. From 4fad5665f7db9a9d06021b30ac58567acb76bada Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sat, 14 Mar 2026 11:34:58 +0300 Subject: [PATCH 028/149] =?UTF-8?q?=D1=87=D0=B8=D0=BD=D0=B8=D0=BC=20=D1=82?= =?UTF-8?q?=D0=B3=D1=83=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PreferencesMenu/antagonists/antagonists/vampire.ts | 4 ++-- .../antagonists/antagonists/vampiricaccident.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/vampire.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/vampire.ts index d21d7fe66e5..792218f7488 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/vampire.ts +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/vampire.ts @@ -7,8 +7,8 @@ Scrape by Space Station 13, or take over it, ghoulizing your way. `; const Vampire: Antagonist = { - key = "Vampire", - name = 'Vampire', + key: "Vampire", + name: 'Vampire', description: [VAMPIRE_MECHANICAL_DESCRIPTION], category: Category.Roundstart, }; diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/vampiricaccident.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/vampiricaccident.ts index 234baacc335..5238a239aa5 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/vampiricaccident.ts +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/vampiricaccident.ts @@ -7,8 +7,8 @@ Scrape by Space Station 13, or take over it, ghoulizing your way. `; const Vampire: Antagonist = { - key = 'vampiricaccident', - name = 'Vampiric Accident', + key: 'vampiricaccident', + name: 'Vampiric Accident', description: [VAMPIRE_MECHANICAL_DESCRIPTION], category: Category.Roundstart, }; From 02b4ab0565bb2bc26a1aaac993a1048de70d6be7 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sat, 14 Mar 2026 12:04:42 +0300 Subject: [PATCH 029/149] =?UTF-8?q?=D0=91=D0=BE=D0=BB=D1=8C=D1=88=D0=B5=20?= =?UTF-8?q?=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2=20=D0=B1=D0=BE=D0=B3=D1=83=20?= =?UTF-8?q?=D0=B2=D0=B0=D0=BC=D0=BF=D0=B8=D1=80=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tff_modular/modules/vampire/clans/brujah.dm | 2 ++ tff_modular/modules/vampire/clans/malkavian.dm | 3 ++- tff_modular/modules/vampire/clans/toreador.dm | 2 ++ tff_modular/modules/vampire/clans/tremere.dm | 2 ++ tff_modular/modules/vampire/clans/ventrue.dm | 2 ++ .../modules/vampire/powers/celerity/haste.dm | 2 +- .../modules/vampire/powers/celerity/quickness.dm | 4 ++-- .../modules/vampire/powers/dominate/command.dm | 14 +++++++------- .../modules/vampire/powers/dominate/mesmerize.dm | 6 +++--- .../modules/vampire/powers/fortitude/fortitude.dm | 12 ++++++------ .../modules/vampire/powers/obfuscate/cloak.dm | 12 ++++++------ tff_modular/modules/vending/vends/autodrobe.dm | 2 ++ 12 files changed, 37 insertions(+), 26 deletions(-) diff --git a/tff_modular/modules/vampire/clans/brujah.dm b/tff_modular/modules/vampire/clans/brujah.dm index 52823cce3a9..6615ba57f8f 100644 --- a/tff_modular/modules/vampire/clans/brujah.dm +++ b/tff_modular/modules/vampire/clans/brujah.dm @@ -14,3 +14,5 @@ vampiredatum.owned_disciplines += new /datum/discipline/celerity(vampiredatum) vampiredatum.owned_disciplines += new /datum/discipline/potence/brujah(vampiredatum) vampiredatum.owned_disciplines += new /datum/discipline/presence(vampiredatum) + vampiredatum.owned_disciplines += new /datum/discipline/dominate(vampiredatum) + vampiredatum.owned_disciplines += new /datum/discipline/fortitude(vampiredatum) diff --git a/tff_modular/modules/vampire/clans/malkavian.dm b/tff_modular/modules/vampire/clans/malkavian.dm index b6809c334a3..e53fe7baa34 100644 --- a/tff_modular/modules/vampire/clans/malkavian.dm +++ b/tff_modular/modules/vampire/clans/malkavian.dm @@ -19,7 +19,8 @@ vampiredatum.owned_disciplines += new /datum/discipline/auspex/malkavian(vampiredatum) vampiredatum.owned_disciplines += new /datum/discipline/obfuscate(vampiredatum) vampiredatum.owned_disciplines += new /datum/discipline/dominate(vampiredatum) - + vampiredatum.owned_disciplines += new /datum/discipline/fortitude(vampiredatum) + vampiredatum.owned_disciplines += new /datum/discipline/celerity(vampiredatum) vampiredatum.owner.current.playsound_local(get_turf(vampiredatum.owner.current), 'sound/music/antag/creepalert.ogg', 80, FALSE, pressure_affected = FALSE, use_reverb = FALSE) to_chat(vampiredatum.owner.current, span_hypnophrase("Welcome, childe of Malkav...")) diff --git a/tff_modular/modules/vampire/clans/toreador.dm b/tff_modular/modules/vampire/clans/toreador.dm index 5bb0f23f3ae..09d3cc8a55f 100644 --- a/tff_modular/modules/vampire/clans/toreador.dm +++ b/tff_modular/modules/vampire/clans/toreador.dm @@ -14,3 +14,5 @@ vampiredatum.owned_disciplines += new /datum/discipline/celerity(vampiredatum) vampiredatum.owned_disciplines += new /datum/discipline/auspex(vampiredatum) vampiredatum.owned_disciplines += new /datum/discipline/presence(vampiredatum) + vampiredatum.owned_disciplines += new /datum/discipline/dominate(vampiredatum) + vampiredatum.owned_disciplines += new /datum/discipline/obfuscate(vampiredatum) diff --git a/tff_modular/modules/vampire/clans/tremere.dm b/tff_modular/modules/vampire/clans/tremere.dm index fc663257dc5..ea67f486aff 100644 --- a/tff_modular/modules/vampire/clans/tremere.dm +++ b/tff_modular/modules/vampire/clans/tremere.dm @@ -13,3 +13,5 @@ vampiredatum.owned_disciplines += new /datum/discipline/dominate(vampiredatum) vampiredatum.owned_disciplines += new /datum/discipline/auspex(vampiredatum) vampiredatum.owned_disciplines += new /datum/discipline/thaumaturgy(vampiredatum) + vampiredatum.owned_disciplines += new /datum/discipline/celerity(vampiredatum) + vampiredatum.owned_disciplines += new /datum/discipline/potence(vampiredatum) diff --git a/tff_modular/modules/vampire/clans/ventrue.dm b/tff_modular/modules/vampire/clans/ventrue.dm index 71c280d1648..02409e2b613 100644 --- a/tff_modular/modules/vampire/clans/ventrue.dm +++ b/tff_modular/modules/vampire/clans/ventrue.dm @@ -15,3 +15,5 @@ vampiredatum.owned_disciplines += new /datum/discipline/presence(vampiredatum) vampiredatum.owned_disciplines += new /datum/discipline/dominate/ventrue(vampiredatum) vampiredatum.owned_disciplines += new /datum/discipline/fortitude(vampiredatum) + vampiredatum.owned_disciplines += new /datum/discipline/potence(vampiredatum) + vampiredatum.owned_disciplines += new /datum/discipline/obfuscate(vampiredatum) diff --git a/tff_modular/modules/vampire/powers/celerity/haste.dm b/tff_modular/modules/vampire/powers/celerity/haste.dm index 0cc08dfd33c..3781e978c29 100644 --- a/tff_modular/modules/vampire/powers/celerity/haste.dm +++ b/tff_modular/modules/vampire/powers/celerity/haste.dm @@ -13,7 +13,7 @@ vampire_power_flags = BP_AM_TOGGLE vampire_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 vitaecost = 15 - cooldown_time = 12 SECONDS + cooldown_time = 7 SECONDS target_range = 15 power_activates_immediately = TRUE ///List of all people hit by our power, so we don't hit them again. diff --git a/tff_modular/modules/vampire/powers/celerity/quickness.dm b/tff_modular/modules/vampire/powers/celerity/quickness.dm index 11b33073372..eb8f223705d 100644 --- a/tff_modular/modules/vampire/powers/celerity/quickness.dm +++ b/tff_modular/modules/vampire/powers/celerity/quickness.dm @@ -7,8 +7,8 @@ vampire_power_flags = BP_AM_TOGGLE vampire_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 cooldown_time = 30 SECONDS - vitaecost = 50 - constant_vitaecost = 5 + vitaecost = 25 + constant_vitaecost = 2 /datum/action/cooldown/vampire/exactitude/can_use() diff --git a/tff_modular/modules/vampire/powers/dominate/command.dm b/tff_modular/modules/vampire/powers/dominate/command.dm index 62e1a75003e..c8143230d8c 100644 --- a/tff_modular/modules/vampire/powers/dominate/command.dm +++ b/tff_modular/modules/vampire/powers/dominate/command.dm @@ -17,9 +17,9 @@ In addition, attacking your target will immediately snap them out of their compulsion." vampire_power_flags = NONE vampire_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 - vitaecost = 120 - cooldown_time = 80 SECONDS - target_range = 3 + vitaecost = 80 + cooldown_time = 40 SECONDS + target_range = 4 power_activates_immediately = FALSE prefire_message = "Whom will you subvert to your will?" ranged_mousepointer = 'tff_modular/modules/vampire/icons/vampire_command.dmi' @@ -27,7 +27,7 @@ /// How long the command is in effect. var/power_time = 60 SECONDS /// How long you have to channel in order to command someone. - var/channel_time = 8 SECONDS + var/channel_time = 7 SECONDS /// Reference to the target var/datum/weakref/target_ref @@ -35,10 +35,10 @@ /datum/action/cooldown/vampire/targeted/command/two name = "Command" power_time = 180 SECONDS - vitaecost = 240 - cooldown_time = 200 SECONDS + vitaecost = 120 + cooldown_time = 60 SECONDS target_range = 6 - channel_time = 5 SECONDS + channel_time = 4 SECONDS /datum/action/cooldown/vampire/targeted/command/can_use() . = ..() diff --git a/tff_modular/modules/vampire/powers/dominate/mesmerize.dm b/tff_modular/modules/vampire/powers/dominate/mesmerize.dm index 2a0101084d3..d41d47cc17f 100644 --- a/tff_modular/modules/vampire/powers/dominate/mesmerize.dm +++ b/tff_modular/modules/vampire/powers/dominate/mesmerize.dm @@ -19,9 +19,9 @@ At level 4, you will be able to mesmerize regardless of your target's direction." vampire_power_flags = NONE vampire_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 - vitaecost = 75 - cooldown_time = 20 SECONDS - target_range = 4 + vitaecost = 40 + cooldown_time = 10 SECONDS + target_range = 5 power_activates_immediately = FALSE prefire_message = "Whom will you submit to your will?" level_current = 1 diff --git a/tff_modular/modules/vampire/powers/fortitude/fortitude.dm b/tff_modular/modules/vampire/powers/fortitude/fortitude.dm index e93953b11fe..2068f07e721 100644 --- a/tff_modular/modules/vampire/powers/fortitude/fortitude.dm +++ b/tff_modular/modules/vampire/powers/fortitude/fortitude.dm @@ -30,7 +30,7 @@ At level 4: Gain complete stun immunity." vampire_power_flags = BP_AM_TOGGLE | BP_AM_COSTLESS_UNCONSCIOUS vampire_check_flags = BP_CANT_USE_IN_TORPOR | BP_CANT_USE_IN_FRENZY | BP_CANT_USE_WHILE_STAKED - vitaecost = 50 + vitaecost = 10 cooldown_time = 5 SECONDS constant_vitaecost = 1 @@ -45,15 +45,15 @@ var/calculated_burn_resist // do not touch /datum/action/cooldown/vampire/fortitude/two - vitaecost = 40 - constant_vitaecost = 2 + vitaecost = 20 + constant_vitaecost = 1.5 resistance = 0.6 pierce = TRUE push = TRUE /datum/action/cooldown/vampire/fortitude/three vitaecost = 30 - constant_vitaecost = 3 + constant_vitaecost = 2 resistance = 0.4 pierce = TRUE push = TRUE @@ -61,7 +61,7 @@ /datum/action/cooldown/vampire/fortitude/four vitaecost = 20 - constant_vitaecost = 4 + constant_vitaecost = 2.5 resistance = 0.3 pierce = TRUE push = TRUE @@ -74,7 +74,7 @@ to_chat(owner, span_notice("Your flesh has become as hard as steel!")) owner.playsound_local(null, 'tff_modular/modules/vampire/sound/fortitude_on.ogg', 100, FALSE, pressure_affected = FALSE) - calculated_burn_resist = min(1, resistance * 3) + calculated_burn_resist = min(1, resistance * 1.2) // Traits & Effects if(pierce) diff --git a/tff_modular/modules/vampire/powers/obfuscate/cloak.dm b/tff_modular/modules/vampire/powers/obfuscate/cloak.dm index b32f69fb541..77b75681bef 100644 --- a/tff_modular/modules/vampire/powers/obfuscate/cloak.dm +++ b/tff_modular/modules/vampire/powers/obfuscate/cloak.dm @@ -9,22 +9,22 @@ vitaecost = 50 constant_vitaecost = 1 cooldown_time = 5 SECONDS - var/cloaklevel = 20 + var/cloaklevel = 70 /datum/action/cooldown/vampire/cloak/two vitaecost = 40 constant_vitaecost = 2 - cloaklevel = 15 + cloaklevel = 50 /datum/action/cooldown/vampire/cloak/three vitaecost = 30 - constant_vitaecost = 3 - cloaklevel = 10 + constant_vitaecost = 2 + cloaklevel = 30 /datum/action/cooldown/vampire/cloak/four vitaecost = 20 - constant_vitaecost = 4 - cloaklevel = 5 + constant_vitaecost = 3 + cloaklevel = 20 /// Must have nobody around to see the cloak /datum/action/cooldown/vampire/cloak/can_use() diff --git a/tff_modular/modules/vending/vends/autodrobe.dm b/tff_modular/modules/vending/vends/autodrobe.dm index 1f2ef884151..48558d85bcb 100644 --- a/tff_modular/modules/vending/vends/autodrobe.dm +++ b/tff_modular/modules/vending/vends/autodrobe.dm @@ -13,6 +13,8 @@ /obj/item/clothing/head/playbunnyears/mime = 3, /obj/item/clothing/shoes/clown_shoes/heeled = 3, /obj/item/clothing/shoes/fancy_heels/white = 3, + /obj/item/umbrella = 3, + /obj/item/umbrella/parasol = 3, ), ), ) From d0a1a8272adcda581b2533a6093d0c4ca5b5afca Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sat, 14 Mar 2026 12:44:54 +0300 Subject: [PATCH 030/149] =?UTF-8?q?=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/dynamic.toml | 4 +-- tff_modular/modules/vampire/dynamic.dm | 32 +++++++++++++++++++ .../vampire/powers/dominate/command.dm | 6 +--- .../antagonists/vampiricaccident.ts | 4 +-- 4 files changed, 37 insertions(+), 9 deletions(-) create mode 100644 tff_modular/modules/vampire/dynamic.dm diff --git a/config/dynamic.toml b/config/dynamic.toml index 6e268e0e05f..2763f610b6e 100644 --- a/config/dynamic.toml +++ b/config/dynamic.toml @@ -680,7 +680,7 @@ repeatable_weight_decrease = 2 repeatable = 0 minimum_required_age = 0 -["Roundstart Bloodsucker"] +["Vampire"] weight = 10 min_pop = 15 blacklisted_roles = [] @@ -688,7 +688,7 @@ min_antag_cap = 1 max_antag_cap = 4 minimum_required_age = 0 -["Midround Bloodsucker"] +["Vampiric Accident"] weight = 10 min_pop = 15 blacklisted_roles = [] diff --git a/tff_modular/modules/vampire/dynamic.dm b/tff_modular/modules/vampire/dynamic.dm new file mode 100644 index 00000000000..70466cad3b3 --- /dev/null +++ b/tff_modular/modules/vampire/dynamic.dm @@ -0,0 +1,32 @@ +/datum/dynamic_ruleset/roundstart/vampire + name = "Vampire" + config_tag = "Vampire" + pref_flag = ROLE_VAMPIRE + preview_antag_datum = /datum/antagonist/vampire + jobban_flag = ROLE_VAMPIRE + weight = 10 + max_antag_cap = 4 + +/datum/dynamic_ruleset/roundstart/vampire/assign_role(datum/mind/candidate) + var/datum/antagonist/vampire/suck_datum = candidate.add_antag_datum(/datum/antagonist/vampire) + suck_datum.rank_up(rand(3, 4)) + +/datum/dynamic_ruleset/midround/from_living/vampire + name = "Vampiric Accident" + config_tag = "Vampiric Accident" + preview_antag_datum = /datum/antagonist/vampire + pref_flag = ROLE_VAMPIRICACCIDENT + jobban_flag = ROLE_BLOODSUCKER + midround_type = LIGHT_MIDROUND + weight = 10 + repeatable = TRUE + max_antag_cap = 4 + +/datum/dynamic_ruleset/midround/from_living/vampire/is_valid_candidate(mob/candidate, client/candidate_client) + if(!is_station_level(candidate.z)) + return FALSE + return ..() + +/datum/dynamic_ruleset/midround/from_living/vampire/assign_role(datum/mind/candidate) + var/datum/antagonist/vampire/suck_datum = candidate.add_antag_datum(/datum/antagonist/vampire) + suck_datum.rank_up(rand(3, 4)) diff --git a/tff_modular/modules/vampire/powers/dominate/command.dm b/tff_modular/modules/vampire/powers/dominate/command.dm index c8143230d8c..08ea37d9a9a 100644 --- a/tff_modular/modules/vampire/powers/dominate/command.dm +++ b/tff_modular/modules/vampire/powers/dominate/command.dm @@ -167,13 +167,9 @@ if(findtext_char(command, " ")) to_chat(owner, span_warning("Please only input a single word.")) return FALSE - if(length_char(command) > 7) + if(length_char(command) > 8) to_chat(owner, span_warning("Command too long!")) return FALSE - if(copytext(command, 1, 5) == "kill" || copytext(command, 1, 7) == "murder" || copytext(command, 1, 8) == "suicide" || copytext(command, 1, 4) == "die") - owner.balloon_alert(owner, "that won't work!") - to_chat(owner, span_warning(" * Remember, victims will be pacified for the duration of the command!")) - return FALSE return command diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/vampiricaccident.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/vampiricaccident.ts index 5238a239aa5..a762e93b65a 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/vampiricaccident.ts +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/vampiricaccident.ts @@ -6,11 +6,11 @@ Use your Vampiric abilities as best you can. Scrape by Space Station 13, or take over it, ghoulizing your way. `; -const Vampire: Antagonist = { +const VampiricAccident: Antagonist = { key: 'vampiricaccident', name: 'Vampiric Accident', description: [VAMPIRE_MECHANICAL_DESCRIPTION], category: Category.Roundstart, }; -export default Vampire; +export default VampiricAccident; From 2e38b7c24a80c631c6da185c5175d2bcd0a3a94b Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sat, 14 Mar 2026 13:01:00 +0300 Subject: [PATCH 031/149] Update datum_vampire.dm --- tff_modular/modules/vampire/datum_vampire.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index 466f31dc551..dc72ba4425b 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -791,7 +791,7 @@ new_limb.burn_modifier /= initial(new_limb.burn_modifier) if(new_limb.body_zone in BODY_ZONES_LIMBS) - var/extra_damage = 1 + (vampire_level * extra_damage_per_rank) + var/extra_damage = 2 + (vampire_level * extra_damage_per_rank) new_limb.unarmed_damage_low += extra_damage new_limb.unarmed_damage_high += extra_damage From 4e986fc24fd80da46740aed043c3e46620de4963 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sat, 14 Mar 2026 13:32:15 +0300 Subject: [PATCH 032/149] =?UTF-8?q?=D0=B0=D0=B1=D0=BD=D0=BE=D0=B2=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/__DEFINES/~ff_defines/bloodsucker.dm | 16 +--------------- .../objects/structures/crates_lockers/closets.dm | 6 +++--- .../structures/crates_lockers/closets/bodybag.dm | 4 ++-- .../ruins/lavalandruin_code/elephantgraveyard.dm | 2 +- code/modules/mining/mine_items.dm | 2 +- code/modules/mod/modules/module_pathfinder.dm | 2 +- .../xenobiology/crossbreeding/regenerative.dm | 2 +- tff_modular/modules/vampire/datum_vampire.dm | 2 +- tff_modular/modules/vampire/dynamic.dm | 4 +--- tff_modular/modules/vampire/life_vampire.dm | 6 +----- .../modules/vampire/objects/blood_drinking.dm | 4 ++-- tff_modular/modules/vampire/objects/coffin.dm | 2 +- tff_modular/modules/vampire/powers/_targeted.dm | 2 +- tff_modular/modules/vampire/powers/masquerade.dm | 2 +- tgstation.dme | 2 ++ .../antagonists/antagonists/vampiricaccident.ts | 2 +- 16 files changed, 21 insertions(+), 39 deletions(-) diff --git a/code/__DEFINES/~ff_defines/bloodsucker.dm b/code/__DEFINES/~ff_defines/bloodsucker.dm index c5aabc5d279..efcb522210b 100644 --- a/code/__DEFINES/~ff_defines/bloodsucker.dm +++ b/code/__DEFINES/~ff_defines/bloodsucker.dm @@ -20,13 +20,12 @@ #define IS_VASSAL(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/vassal)) #define CAT_VAMPIRE "Vampire" #define DOAFTER_SOURCE_ARCHIVE_OF_THE_KINDRED "doafter_archive_of_the_kindred" -#define DOAFTER_SOURCE_PERSUASION_RACK "doafter_persuasion_rack" /// This area can always be claimed as a vampire lair regardless of Z-level and such #define ALWAYS_VALID_VAMPIRE_LAIR (1<<21) #define LOG_CATEGORY_UPLINK_VAMPIRE "uplink-vampire" #define FACTION_VAMPIRE "Vampire" #define ROLE_VAMPIRE "Vampire" -#define ROLE_VAMPIRIC_ACCIDENT "Vampiric Accident" +#define ROLE_VAMPIRIC_ACCIDENT "VampiricAccident" #define span_awe(str) ("" + str + "") /// Uncomment this to enable testing of Vampire features (such as vassalizing people with a mind instead of a client). //#define VAMPIRE_TESTING @@ -210,9 +209,6 @@ #define IS_VAMPIRE_HUNTER(mob) (IS_CURATOR(mob)) -/// Basically just check for `HAS_MIND_TRAIT(user, TRAIT_VAMPIRE_ALIGNED)` instead of `IS_VAMPIRE(user) || IS_VASSAL(user)` -#define TRAIT_VAMPIRE_ALIGNED "vampire_aligned" - #define LANGUAGE_VAMPIRE "vampire" #define LANGUAGE_VASSAL "vassal" @@ -230,21 +226,11 @@ #define IGNORE_GRAB (1<<2) /// If the incapacited status effect will ignore a mob in softcrit #define IGNORE_SOFTCRIT (1<<3) - -#define IS_FINITE__UNSAFE(a) (!isinf(a) && !isnan(a)) -#define IS_FINITE(a) (isnum(a) && IS_FINITE__UNSAFE(a)) - #define IS_SAFE_NUM(a) IS_FINITE(a) #define BODY_ZONES_LIMBS list(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) ///from base of atom/expose_reagents(): (/list, /datum/reagents, methods, volume_modifier, show_message) -#define COMSIG_ATOM_EXPOSE_REAGENTS "atom_expose_reagents" - /// Prevents the atom from being exposed to reagents if returned on [COMSIG_ATOM_EXPOSE_REAGENTS] - #define COMPONENT_NO_EXPOSE_REAGENTS (1<<0) -///from base of atom/expose_reagents(): (/list, /datum/reagents, methods, volume_modifier, show_message) #define COMSIG_ATOM_AFTER_EXPOSE_REAGENTS "atom_after_expose_reagents" -///from base of [/datum/reagent/proc/expose_atom]: (/datum/reagent, reac_volume) -#define COMSIG_ATOM_EXPOSE_REAGENT "atom_expose_reagent" #define MOVABLE_PHYSICS_PRECISION 0.01 #define MOVABLE_PHYSICS_MINIMAL_VELOCITY 1 diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index e9d36687f90..068ac3c93dd 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -647,7 +647,7 @@ GLOBAL_LIST_EMPTY(roundstart_station_closets) /obj/structure/closet/atom_break(damage_flag) . = ..() if(!broken) - bust_open() + bust_open(FALSE) // TFF CHANGE - ORIGINAL: bust_open() /obj/structure/closet/on_craft_completion(list/components, datum/crafting_recipe/current_recipe, atom/crafter) var/obj/item/electronics/airlock/access_control = locate() in components @@ -1060,7 +1060,7 @@ GLOBAL_LIST_EMPTY(roundstart_station_closets) //we check after a while whether there is a point of resisting anymore and whether the user is capable of resisting user.visible_message(span_danger("[user] successfully broke out of [src]!"), span_notice("You successfully break out of [src]!")) - bust_open() + bust_open(FALSE) // TFF CHANGE - ORIGINAL: bust_open() else if(user.loc == src) //so we don't get the message if we resisted multiple times and succeeded. to_chat(user, span_warning("You fail to break out of [src]!")) @@ -1086,7 +1086,7 @@ GLOBAL_LIST_EMPTY(roundstart_station_closets) // If we reach here, nobody is resisting, so don't shake return FALSE -/obj/structure/closet/proc/bust_open(destructive = TRUE) +/obj/structure/closet/proc/bust_open(destructive = TRUE)// TFF CHANGE - ORIGINAL: proc/bust_open() SIGNAL_HANDLER welded = FALSE //applies to all lockers unlock() //applies to critter crates and secure lockers only diff --git a/code/game/objects/structures/crates_lockers/closets/bodybag.dm b/code/game/objects/structures/crates_lockers/closets/bodybag.dm index 12d9b7a3794..37e022c5986 100644 --- a/code/game/objects/structures/crates_lockers/closets/bodybag.dm +++ b/code/game/objects/structures/crates_lockers/closets/bodybag.dm @@ -306,13 +306,13 @@ span_notice("You successfully break out of [src]!")) if(istype(loc, /obj/machinery/disposal)) return ..() - bust_open() + bust_open(FALSE) // TFF CHANGE - ORIGINAL: bust_open() else if(user.loc == src) //so we don't get the message if we resisted multiple times and succeeded. to_chat(user, span_warning("You fail to break out of [src]!")) -/obj/structure/closet/body_bag/environmental/prisoner/bust_open() +/obj/structure/closet/body_bag/environmental/prisoner/bust_open(FALSE) // TFF CHANGE - ORIGINAL: bust_open() sinched = FALSE // We don't break the bag, because the buckles were backed out as opposed to fully broken. open() diff --git a/code/modules/mapfluff/ruins/lavalandruin_code/elephantgraveyard.dm b/code/modules/mapfluff/ruins/lavalandruin_code/elephantgraveyard.dm index 9e2c52e453f..2a19fde6bfc 100644 --- a/code/modules/mapfluff/ruins/lavalandruin_code/elephantgraveyard.dm +++ b/code/modules/mapfluff/ruins/lavalandruin_code/elephantgraveyard.dm @@ -305,7 +305,7 @@ span_danger("[user] emerges from [src], scattering dirt everywhere!"), span_notice("You triumphantly surface out of [src], scattering dirt all around the grave!"), ) - bust_open() + bust_open(FALSE) // TFF CHANGE - ORIGINAL: bust_open() else if(user.loc == src) to_chat(user, span_warning("You fail to dig yourself out of [src]!")) diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index babde4dbcb1..3e169262929 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -507,7 +507,7 @@ to_yeet += buckled_mobs unbuckle_all_mobs() - bust_open() + bust_open(FALSE) // TFF CHANGE - ORIGINAL: bust_open() if(!opened) return diff --git a/code/modules/mod/modules/module_pathfinder.dm b/code/modules/mod/modules/module_pathfinder.dm index 55263aa332d..76dc643ea25 100644 --- a/code/modules/mod/modules/module_pathfinder.dm +++ b/code/modules/mod/modules/module_pathfinder.dm @@ -152,7 +152,7 @@ if (!closet.opened) if (!closet.open()) playsound(closet, 'sound/effects/bang.ogg', vol = 50, vary = TRUE) - closet.bust_open() + closet.bust_open(FALSE) // TFF CHANGE - ORIGINAL: bust_open() mod.add_overlay(jet_icon) diff --git a/code/modules/research/xenobiology/crossbreeding/regenerative.dm b/code/modules/research/xenobiology/crossbreeding/regenerative.dm index 4cc1784b8d0..9748528a386 100644 --- a/code/modules/research/xenobiology/crossbreeding/regenerative.dm +++ b/code/modules/research/xenobiology/crossbreeding/regenerative.dm @@ -76,7 +76,7 @@ Regenerative extracts: C.name = "slimy closet" C.desc = "Looking closer, it seems to be made of a sort of solid, opaque, metal-like goo." if(target.mob_size > C.max_mob_size) //Prevents capturing megafauna or other large mobs in the closets - C.bust_open() + C.bust_open(FALSE) // TFF CHANGE - ORIGINAL: bust_open() C.visible_message(span_warning("[target] is too big, and immediately breaks \the [C.name] open!")) else //This can't be allowed to actually happen to the too-big mobs or it breaks some actions target.forceMove(C) diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index dc72ba4425b..34325719cea 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -571,7 +571,7 @@ // Heart var/obj/item/organ/heart/newheart = user.get_organ_slot(ORGAN_SLOT_HEART) - newheart?.beating = initial(newheart.beating) + newheart?.Restart() /datum/antagonist/vampire/proc/claim_coffin(obj/structure/closet/crate/claimed) var/static/list/banned_areas_typecache diff --git a/tff_modular/modules/vampire/dynamic.dm b/tff_modular/modules/vampire/dynamic.dm index 70466cad3b3..88261feacdc 100644 --- a/tff_modular/modules/vampire/dynamic.dm +++ b/tff_modular/modules/vampire/dynamic.dm @@ -3,7 +3,6 @@ config_tag = "Vampire" pref_flag = ROLE_VAMPIRE preview_antag_datum = /datum/antagonist/vampire - jobban_flag = ROLE_VAMPIRE weight = 10 max_antag_cap = 4 @@ -15,8 +14,7 @@ name = "Vampiric Accident" config_tag = "Vampiric Accident" preview_antag_datum = /datum/antagonist/vampire - pref_flag = ROLE_VAMPIRICACCIDENT - jobban_flag = ROLE_BLOODSUCKER + pref_flag = ROLE_VAMPIRIC_ACCIDENT midround_type = LIGHT_MIDROUND weight = 10 repeatable = TRUE diff --git a/tff_modular/modules/vampire/life_vampire.dm b/tff_modular/modules/vampire/life_vampire.dm index 9b470bb2278..4b799c764f1 100644 --- a/tff_modular/modules/vampire/life_vampire.dm +++ b/tff_modular/modules/vampire/life_vampire.dm @@ -78,7 +78,7 @@ var/healing_multiplier = 1 if(carbon_owner.on_fire) - healing_multiplier = 0 + healing_multiplier = 0.2 else if(HAS_TRAIT(carbon_owner, TRAIT_SLIME_HYDROPHOBIA)) healing_multiplier = 0.75 @@ -187,10 +187,6 @@ // Heal wounds for(var/datum/wound/iter_wound as anything in carbon_user.all_wounds) iter_wound.remove_wound() - for(var/obj/item/organ/organ as anything in carbon_user.organs) - - organ.Remove(carbon_user) - organ.forceMove(carbon_user.drop_location()) // Don't Revive if staked or being staked if(carbon_user.stat == DEAD && COOLDOWN_FINISHED(src, revive_cooldown) && !check_if_staked() && !HAS_TRAIT(carbon_user, TRAIT_BEINGSTAKED)) diff --git a/tff_modular/modules/vampire/objects/blood_drinking.dm b/tff_modular/modules/vampire/objects/blood_drinking.dm index cd88c2bb1e8..5175ec23749 100644 --- a/tff_modular/modules/vampire/objects/blood_drinking.dm +++ b/tff_modular/modules/vampire/objects/blood_drinking.dm @@ -10,7 +10,7 @@ span_notice("[attacker] forces [victim] to drink from \the [src]."), span_notice("You put \the [src] up to [victim]'s mouth.") ) - reagents.trans_to(victim, to_feed, transfered_by = attacker, methods = INGEST) + reagents.trans_to(victim, to_feed, transferred_by = attacker, methods = INGEST) playsound(victim, 'sound/items/drink.ogg', vol = 30, vary = TRUE) return TRUE @@ -26,7 +26,7 @@ span_notice("[victim] sucks the contents out of \the [src]!"), span_notice("You feed from \the [src].") ) - reagents.trans_to(victim, to_feed, transfered_by = attacker, methods = INGEST) + reagents.trans_to(victim, to_feed, transferred_by = attacker, methods = INGEST) playsound(victim, 'sound/items/drink.ogg', vol = 30, vary = TRUE) return TRUE diff --git a/tff_modular/modules/vampire/objects/coffin.dm b/tff_modular/modules/vampire/objects/coffin.dm index 754346fb6f2..e12dc433383 100644 --- a/tff_modular/modules/vampire/objects/coffin.dm +++ b/tff_modular/modules/vampire/objects/coffin.dm @@ -85,7 +85,7 @@ ) if(!tool.use_tool(src, user, pry_lid_timer)) return FALSE - bust_open() + bust_open(FALSE) // TFF CHANGE - ORIGINAL: bust_open() user.visible_message( span_notice("[user] snaps the door of [src] wide open."), span_notice("The door of [src] snaps open."), diff --git a/tff_modular/modules/vampire/powers/_targeted.dm b/tff_modular/modules/vampire/powers/_targeted.dm index 273d1813b56..22127b43279 100644 --- a/tff_modular/modules/vampire/powers/_targeted.dm +++ b/tff_modular/modules/vampire/powers/_targeted.dm @@ -72,7 +72,7 @@ return TRUE -/datum/action/cooldown/vampire/targeted/InterceptClickOn(mob/living/user, params, atom/target) +/datum/action/cooldown/vampire/targeted/InterceptClickOn(mob/living/clucker, params, atom/target) INVOKE_ASYNC(src, PROC_REF(click_with_power), target) return TRUE diff --git a/tff_modular/modules/vampire/powers/masquerade.dm b/tff_modular/modules/vampire/powers/masquerade.dm index 659af49ddae..bb72c817599 100644 --- a/tff_modular/modules/vampire/powers/masquerade.dm +++ b/tff_modular/modules/vampire/powers/masquerade.dm @@ -66,7 +66,7 @@ // Clear mutations and diseases carbon_owner.dna.remove_all_mutations() for(var/datum/disease/diseases in carbon_owner.diseases) - diseases.cure(target = carbon_owner, safe = TRUE) + diseases.cure() // Handle Traits carbon_owner.add_traits(vampiredatum.vampire_traits, TRAIT_VAMPIRE) diff --git a/tgstation.dme b/tgstation.dme index ce3fee10666..12d28d01f3e 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -759,6 +759,7 @@ #include "code\_onclick\hud\screen_objects.dm" #include "code\_onclick\hud\screentip.dm" #include "code\_onclick\hud\soulscythe.dm" +#include "code\_onclick\hud\vampire.dm" #include "code\_onclick\hud\voidwalkerhud.dm" #include "code\_onclick\hud\parallax\parallax.dm" #include "code\_onclick\hud\parallax\random_layer.dm" @@ -9732,6 +9733,7 @@ #include "tff_modular\modules\vampire\conversion_vampire.dm" #include "tff_modular\modules\vampire\crafts.dm" #include "tff_modular\modules\vampire\datum_vampire.dm" +#include "tff_modular\modules\vampire\dynamic.dm" #include "tff_modular\modules\vampire\effects.dm" #include "tff_modular\modules\vampire\frenzy_vampire.dm" #include "tff_modular\modules\vampire\language.dm" diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/vampiricaccident.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/vampiricaccident.ts index a762e93b65a..908581c9f6d 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/vampiricaccident.ts +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/vampiricaccident.ts @@ -10,7 +10,7 @@ const VampiricAccident: Antagonist = { key: 'vampiricaccident', name: 'Vampiric Accident', description: [VAMPIRE_MECHANICAL_DESCRIPTION], - category: Category.Roundstart, + category: Category.Midround, }; export default VampiricAccident; From e585fbe1fdd9e3ac5214533e26375384e1bc5c06 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sat, 14 Mar 2026 13:36:52 +0300 Subject: [PATCH 033/149] Update bodybag.dm --- code/game/objects/structures/crates_lockers/closets/bodybag.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/structures/crates_lockers/closets/bodybag.dm b/code/game/objects/structures/crates_lockers/closets/bodybag.dm index 37e022c5986..47042c8ade2 100644 --- a/code/game/objects/structures/crates_lockers/closets/bodybag.dm +++ b/code/game/objects/structures/crates_lockers/closets/bodybag.dm @@ -312,7 +312,7 @@ to_chat(user, span_warning("You fail to break out of [src]!")) -/obj/structure/closet/body_bag/environmental/prisoner/bust_open(FALSE) // TFF CHANGE - ORIGINAL: bust_open() +/obj/structure/closet/body_bag/environmental/prisoner/bust_open(destructive = FALSE) // TFF CHANGE - ORIGINAL: bust_open() sinched = FALSE // We don't break the bag, because the buckles were backed out as opposed to fully broken. open() From 132b1e35b126c6fccebd2e13bee41acc4ee7d2c7 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sat, 14 Mar 2026 13:46:05 +0300 Subject: [PATCH 034/149] Update monitor.dm --- tff_modular/modules/vampire/monitor.dm | 197 ------------------------- 1 file changed, 197 deletions(-) diff --git a/tff_modular/modules/vampire/monitor.dm b/tff_modular/modules/vampire/monitor.dm index 9f3764b9d13..e0c1fc71b77 100644 --- a/tff_modular/modules/vampire/monitor.dm +++ b/tff_modular/modules/vampire/monitor.dm @@ -621,200 +621,3 @@ GLOBAL_LIST_EMPTY(tracker_beacons) mouse_opacity = MOUSE_OPACITY_TRANSPARENT #undef ALT_APPEARENCE_ID - -/// 1 tile up -#define UI_HUMANITY_DISPLAY "WEST:6,CENTER+1:-8" -/// 1 tile down -#define UI_BLOOD_DISPLAY "WEST:6,CENTER:0" -/// 2 tiles down -#define UI_VAMPRANK_DISPLAY "WEST:6,CENTER-1:-2" - -///Maptext define for Vampire HUDs -#define FORMAT_VAMPIRE_HUD_TEXT(valuecolor, value) MAPTEXT("
    [round(value,1)]
    ") - -/atom/movable/screen/vampire - icon = 'tff_modular/modules/vampire/icons/actions_vampire.dmi' - mouse_over_pointer = MOUSE_HAND_POINTER - -/atom/movable/screen/vampire/blood_counter - name = "Vitae" - icon_state = "blood_display" - screen_loc = UI_BLOOD_DISPLAY - -/atom/movable/screen/vampire/blood_counter/Click() - . = ..() - var/list/msg = list() - var/mob/living/owner_mob = hud.mymob - var/datum/antagonist/vampire/owner_vamp = IS_VAMPIRE(owner_mob) - - if(!owner_vamp) - return - - msg += span_cult_large("This is your Vitae-Counter.") - msg += span_cult("Here you see your current level of blood-energy. This is used for all of your abilities, and sustains your very being.") - msg += span_cult("\nYou need to drink a certain amount from living, sentient beings in order to level up.") - msg += span_cult("Your healing also depends on it. You reach your maximum healing potential at [BS_BLOOD_VOLUME_MAX_REGEN].") - - var/bloodlevel - switch(owner_vamp.current_vitae) - if(0 to 200) - bloodlevel = "starved" - if(201 to 500) - bloodlevel = "thirsty" - if(501 to 700) - bloodlevel = "peckish" - if(701 to INFINITY) - bloodlevel = "content" - - msg += span_cult("Your current maximum is: [owner_vamp.max_vitae].") - msg += span_cult("This shift, you have drank [owner_vamp.total_blood_drank] units of blood.") - - msg += span_cult_large("\nRight now, you are feeling [bloodlevel].") - - if(owner_vamp.vitae_goal_progress <= owner_vamp.current_vitae_goal) - msg += span_cult_large("\nYour progress to the next level is: [owner_vamp.vitae_goal_progress]/[owner_vamp.current_vitae_goal].") - else - msg += span_cult_large("\nYou have drank deeply and greedily. Sleep in a coffin to level up.") - - to_chat(usr, boxed_message(msg.Join("\n"))) - -/atom/movable/screen/vampire/rank_counter - name = "Vampire Rank" - icon_state = "rank" - screen_loc = UI_VAMPRANK_DISPLAY - -/atom/movable/screen/vampire/rank_counter/Click() - . = ..() - var/list/msg = list() - var/mob/living/owner_mob = hud.mymob - var/datum/antagonist/vampire/owner_vamp = IS_VAMPIRE(owner_mob) - - if(!owner_vamp) - return - - /* var/mob/living/carbon/human/vampire_human = owner_mob */ - msg += span_cult_large("This is your Rank-Counter.") - msg += span_cult("Here you see your current progress in the mastery of your disciplines.") - msg += span_cult("This is a measure of your main progress as a vampire, and, should you feed on another vampire(that has broken the masquerade), you will absorb half of their levels.") - msg += span_cult("With your current rank, you are considered as [owner_vamp.get_rank_string()] of your craft.") - msg += span_cult("\nCurrently, your rank affords you the following benefits:") - msg += span_cult("Max Regeneration rate: +[owner_vamp.vampire_regen_rate]") - msg += span_cult("Max Vitae pool: +[owner_vamp.max_vitae - 600] ") - msg += span_cult("Unarmed damage: +[1 + (owner_vamp.vampire_level * owner_vamp.extra_damage_per_rank)]") - - var/list/disciplinestext - for(var/datum/discipline/discipline in owner_vamp.owned_disciplines) - disciplinestext += "\n[discipline.name] - " - disciplinestext += "Level:" - disciplinestext += "[discipline.level - 1]" - - if(disciplinestext) - msg += span_cult("\nYour disciplines and their levels are:[disciplinestext]") - - to_chat(usr, boxed_message(msg.Join("\n"))) - -/atom/movable/screen/vampire/humanity_counter - name = "Humanity" - icon_state = "humanity" - screen_loc = UI_HUMANITY_DISPLAY - -/atom/movable/screen/vampire/humanity_counter/Click() - . = ..() - var/list/msg = list() - var/mob/living/owner_mob = hud.mymob - var/datum/antagonist/vampire/owner_vamp = IS_VAMPIRE(owner_mob) - - msg += span_cult_large("This is your Humanity score.") - msg += span_cult("Humanity is a measure of how closely a vampire clings to the morality and values of mortal life, and consequently how well they are able to resist the urges of the Beast.") - msg += span_cult("This has an active effect on the curse of all cainites. Vampires with little humanity may find it harder to stay awake during the day, or to awaken from long periods of torpor. If your humanity is particularly low, you may even burst into flames in the presence of god's light.") - - var/humanitylevel - switch(owner_vamp.humanity) - if(0) - humanitylevel = "Monstrous" - if(1) - humanitylevel = "Horrific" - if(2) - humanitylevel = "Bestial" - if(3) - humanitylevel = "Cold" - if(4) - humanitylevel = "Unfeeling" - if(5) - humanitylevel = "Removed" - if(6) - humanitylevel = "Distant" - if(7) - humanitylevel = "Normal" - if(8) - humanitylevel = "Caring" - if(9) - humanitylevel = "Compassionate" - if(10) - humanitylevel = "Saintly" - - // Pardon me for my math, i was never good at this. - - var/normal_humanity_divisor = min(2, 1 + (owner_vamp.humanity / 10)) - var/divisor_turned_percentage = ((normal_humanity_divisor - 1) * 200) / 4 - - msg += span_cult("\nRight now, others would describe you as '[humanitylevel]', giving you a [divisor_turned_percentage]% resistance to the ravages of Sol.") - if(owner_vamp.humanity > 7) - msg += span_cult("Due to your connection to your own human soul, you have achieved the masquerade ability.") - - msg += span_cult("\nYou may gain humanity by engaging in human activities, such as:") - msg += span_cult("Hugging different mortals: [length(owner_vamp.humanity_trackgain_hugged)] of [owner_vamp.humanity_hugging_goal].") - msg += span_cult("Petting various animals: [length(owner_vamp.humanity_trackgain_petted)] of [owner_vamp.humanity_petting_goal].") - msg += span_cult("Looking at art: [length(owner_vamp.humanity_trackgain_art)] of [owner_vamp.humanity_art_goal].") - - to_chat(usr, boxed_message(msg.Join("\n"))) - -/// Update Blood Counter + Rank Counter -/datum/antagonist/vampire/proc/update_hud() - var/valuecolor - switch(current_vitae) - if(0 to 200) - valuecolor = "#560808" - if(201 to 300) - valuecolor = "#a32a2a" - if(301 to 500) - valuecolor = "#d55c5c" - if(501 to 700) // This isn't janky, a tiny bit lenience is baked in. - valuecolor = "#ffc2c2" - if(701 to INFINITY) - valuecolor = "#ffffff" - - blood_display?.maptext = FORMAT_VAMPIRE_HUD_TEXT(valuecolor, current_vitae) - - if(vamprank_display) - if(vampire_level_unspent > 0) - vamprank_display.icon_state = "[initial(vamprank_display.icon_state)]_up" - else - vamprank_display.icon_state = initial(vamprank_display.icon_state) - vamprank_display.maptext = FORMAT_VAMPIRE_HUD_TEXT("#ffd8d8", vampire_level) - - if(humanity_display) - var/humanityvaluecolor - switch(humanity) - if(0 to 2) - humanityvaluecolor = "#600000" - if(3 to 4) - humanityvaluecolor = "#a71c1c" - if(4 to 5) - humanityvaluecolor = "#db4646" - if(6 to 8) // same here - humanityvaluecolor = "#e8adad" - if(9 to 10) - humanityvaluecolor = "#ffffff" - - humanity_display.maptext = FORMAT_VAMPIRE_HUD_TEXT(humanityvaluecolor, humanity) - -/// 1 tile up -#undef UI_HUMANITY_DISPLAY -/// 1 tile down -#undef UI_BLOOD_DISPLAY -/// 2 tiles down -#undef UI_VAMPRANK_DISPLAY - -///Maptext define for Vampire HUDs -#undef FORMAT_VAMPIRE_HUD_TEXT From 3a57d764e4a6814bfe30892d7703dd1b522e2fa6 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sat, 14 Mar 2026 13:55:48 +0300 Subject: [PATCH 035/149] Update _targeted.dm --- tff_modular/modules/vampire/powers/_targeted.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tff_modular/modules/vampire/powers/_targeted.dm b/tff_modular/modules/vampire/powers/_targeted.dm index 22127b43279..bda0e222f63 100644 --- a/tff_modular/modules/vampire/powers/_targeted.dm +++ b/tff_modular/modules/vampire/powers/_targeted.dm @@ -72,7 +72,7 @@ return TRUE -/datum/action/cooldown/vampire/targeted/InterceptClickOn(mob/living/clucker, params, atom/target) +/datum/action/cooldown/vampire/targeted/InterceptClickOn(mob/living/clicker, params, atom/target) INVOKE_ASYNC(src, PROC_REF(click_with_power), target) return TRUE From 43d18bcb7b58853885e15dc93fe8ae16d1121522 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sat, 14 Mar 2026 14:05:57 +0300 Subject: [PATCH 036/149] Update vampire.ts --- .../PreferencesMenu/antagonists/antagonists/vampire.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/vampire.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/vampire.ts index 792218f7488..354293af8af 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/vampire.ts +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/vampire.ts @@ -7,7 +7,7 @@ Scrape by Space Station 13, or take over it, ghoulizing your way. `; const Vampire: Antagonist = { - key: "Vampire", + key: 'vampire', name: 'Vampire', description: [VAMPIRE_MECHANICAL_DESCRIPTION], category: Category.Roundstart, From 852245d21bfcfa23d6d86ca32ae99c040a7a9ce9 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sat, 14 Mar 2026 14:18:10 +0300 Subject: [PATCH 037/149] =?UTF-8?q?=D1=84=D0=B8=D0=BA=D1=81=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tff_modular/modules/vampire/datum_vampire.dm | 2 +- tff_modular/modules/vampire/life_vampire.dm | 24 ++++++++++--------- .../modules/vampire/objects/vassal_rack.dm | 2 +- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index 34325719cea..8593087d470 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -226,7 +226,7 @@ var/mob/living/carbon/human/current_human = current_mob current_human.physiology?.stamina_mod *= VAMPIRE_INHERENT_STAMINA_RESIST - current_mob.has_dna()?.remove_all_mutations() + current_mob.dna?.remove_all_mutations() current_mob.add_traits(vampire_traits + always_traits, TRAIT_VAMPIRE) current_mob.grant_language(/datum/language/vampiric, source = LANGUAGE_VAMPIRE) diff --git a/tff_modular/modules/vampire/life_vampire.dm b/tff_modular/modules/vampire/life_vampire.dm index 4b799c764f1..1eaa0aa3b84 100644 --- a/tff_modular/modules/vampire/life_vampire.dm +++ b/tff_modular/modules/vampire/life_vampire.dm @@ -2,30 +2,32 @@ /datum/antagonist/vampire/proc/life_tick(datum/source, seconds_per_tick, times_fired) SIGNAL_HANDLER + var/mob/living/vampire = source + if(!isliving(vampire)) // Weirdness shield - if(isbrain(owner?.current)) + if(isbrain(vampire?.current)) update_hud() return - if(QDELETED(owner)) + if(QDELETED(vampire)) INVOKE_ASYNC(src, PROC_REF(handle_death)) return // Deduct Blood - if(owner.current.stat == CONSCIOUS && !HAS_TRAIT(owner.current, TRAIT_IMMOBILIZED) && !HAS_TRAIT(owner.current, TRAIT_NODEATH)) + if(vampire.current.stat == CONSCIOUS && !HAS_TRAIT(vampire.current, TRAIT_IMMOBILIZED) && !HAS_TRAIT(vampire.current, TRAIT_NODEATH)) adjust_blood_volume(-VAMPIRE_PASSIVE_BLOOD_DRAIN) // Healing - if(handle_healing(seconds_per_tick) && !isanimal_or_basicmob(owner)) + if(handle_healing(seconds_per_tick) && !isanimal_or_basicmob(vampire)) if((COOLDOWN_FINISHED(src, vampire_spam_healing)) && current_vitae > 0) - to_chat(owner.current, span_notice("The power of your blood knits your wounds...")) + to_chat(vampire.current, span_notice("The power of your blood knits your wounds...")) COOLDOWN_START(src, vampire_spam_healing, VAMPIRE_SPAM_HEALING) - var/area/current_area = get_area(owner.current) - if(istype(current_area, /area/station/service/chapel) && !is_chaplain_job(owner.assigned_role) && humanity <= 2) - to_chat(owner, span_warning("Your inhuman nature is rejected by a holy presence!")) - owner.current.adjust_fire_loss(10) - owner.current.adjust_fire_stacks(4) - owner.current.ignite_mob() + var/area/current_area = get_area(vampire.current) + if(istype(current_area, /area/station/service/chapel) && !is_chaplain_job(vampire.assigned_role) && humanity <= 2) + to_chat(vampire, span_warning("Your inhuman nature is rejected by a holy presence!")) + vampire.current.adjust_fire_loss(10) + vampire.current.adjust_fire_stacks(4) + vampire.current.ignite_mob() // Standard Updates diff --git a/tff_modular/modules/vampire/objects/vassal_rack.dm b/tff_modular/modules/vampire/objects/vassal_rack.dm index 9434624f35c..2aad53d815e 100644 --- a/tff_modular/modules/vampire/objects/vassal_rack.dm +++ b/tff_modular/modules/vampire/objects/vassal_rack.dm @@ -37,7 +37,7 @@ else . += span_warning("You cannot create any more vassals at the moment!") -/obj/structure/vampire/vassalrack/deconstruct(disassembled = TRUE) +/obj/structure/vampire/vassalrack/atom_deconstruct(disassembled = TRUE) . = ..() new /obj/item/stack/sheet/iron(src.loc, 4) new /obj/item/stack/rods(loc, 4) From 6d3ebf783aa1c40a682fbe0b5fd5e54b590d11ef Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sat, 14 Mar 2026 14:23:50 +0300 Subject: [PATCH 038/149] Update life_vampire.dm --- tff_modular/modules/vampire/life_vampire.dm | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/tff_modular/modules/vampire/life_vampire.dm b/tff_modular/modules/vampire/life_vampire.dm index 1eaa0aa3b84..afb8bc437bb 100644 --- a/tff_modular/modules/vampire/life_vampire.dm +++ b/tff_modular/modules/vampire/life_vampire.dm @@ -3,31 +3,32 @@ SIGNAL_HANDLER var/mob/living/vampire = source + var/mob/living/vampiredatum = vampire.mind?.has_antag_datum(/datum/antagonist/vampire) if(!isliving(vampire)) // Weirdness shield if(isbrain(vampire?.current)) update_hud() return - if(QDELETED(vampire)) + if(QDELETED(vampire) || QDELETED(vampiredatum)) INVOKE_ASYNC(src, PROC_REF(handle_death)) return // Deduct Blood - if(vampire.current.stat == CONSCIOUS && !HAS_TRAIT(vampire.current, TRAIT_IMMOBILIZED) && !HAS_TRAIT(vampire.current, TRAIT_NODEATH)) + if(vampire.current.stat == CONSCIOUS && !HAS_TRAIT(vampire, TRAIT_IMMOBILIZED) && !HAS_TRAIT(vampire, TRAIT_NODEATH)) adjust_blood_volume(-VAMPIRE_PASSIVE_BLOOD_DRAIN) // Healing if(handle_healing(seconds_per_tick) && !isanimal_or_basicmob(vampire)) if((COOLDOWN_FINISHED(src, vampire_spam_healing)) && current_vitae > 0) - to_chat(vampire.current, span_notice("The power of your blood knits your wounds...")) + to_chat(vampire, span_notice("The power of your blood knits your wounds...")) COOLDOWN_START(src, vampire_spam_healing, VAMPIRE_SPAM_HEALING) - var/area/current_area = get_area(vampire.current) + var/area/current_area = get_area(vampire) if(istype(current_area, /area/station/service/chapel) && !is_chaplain_job(vampire.assigned_role) && humanity <= 2) to_chat(vampire, span_warning("Your inhuman nature is rejected by a holy presence!")) - vampire.current.adjust_fire_loss(10) - vampire.current.adjust_fire_stacks(4) - vampire.current.ignite_mob() + vampire.adjust_fire_loss(10) + vampire.adjust_fire_stacks(4) + vampire.ignite_mob() // Standard Updates From 82c01d5933b9fa60f69e055b6be64a1ca36b3cc5 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sat, 14 Mar 2026 14:24:18 +0300 Subject: [PATCH 039/149] Update datum_vampire.dm --- tff_modular/modules/vampire/datum_vampire.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index 8593087d470..6ac11f17180 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -190,7 +190,7 @@ */ /datum/antagonist/vampire/apply_innate_effects(mob/living/mob_override) . = ..() - var/mob/living/current_mob = mob_override || owner.current + var/mob/living/carbon/current_mob = mob_override || owner.current RegisterSignals(current_mob, list(COMSIG_MOB_LOGIN, COMSIG_MOVABLE_Z_CHANGED), PROC_REF(on_login)) RegisterSignal(current_mob, COMSIG_LIVING_LIFE, PROC_REF(life_tick)) RegisterSignal(current_mob, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) From c363334fd5477f0536e9cfde93a2081979502f45 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sat, 14 Mar 2026 14:27:30 +0300 Subject: [PATCH 040/149] Update life_vampire.dm --- tff_modular/modules/vampire/life_vampire.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tff_modular/modules/vampire/life_vampire.dm b/tff_modular/modules/vampire/life_vampire.dm index afb8bc437bb..eb94dbf594e 100644 --- a/tff_modular/modules/vampire/life_vampire.dm +++ b/tff_modular/modules/vampire/life_vampire.dm @@ -6,7 +6,7 @@ var/mob/living/vampiredatum = vampire.mind?.has_antag_datum(/datum/antagonist/vampire) if(!isliving(vampire)) // Weirdness shield - if(isbrain(vampire?.current)) + if(isbrain(vampire)) update_hud() return if(QDELETED(vampire) || QDELETED(vampiredatum)) @@ -14,7 +14,7 @@ return // Deduct Blood - if(vampire.current.stat == CONSCIOUS && !HAS_TRAIT(vampire, TRAIT_IMMOBILIZED) && !HAS_TRAIT(vampire, TRAIT_NODEATH)) + if(vampire.stat == CONSCIOUS && !HAS_TRAIT(vampire, TRAIT_IMMOBILIZED) && !HAS_TRAIT(vampire, TRAIT_NODEATH)) adjust_blood_volume(-VAMPIRE_PASSIVE_BLOOD_DRAIN) // Healing From fdfe69b327bbe781d9d7b296906008753680f393 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sat, 14 Mar 2026 14:31:53 +0300 Subject: [PATCH 041/149] Update life_vampire.dm --- tff_modular/modules/vampire/life_vampire.dm | 29 +++++++++++---------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/tff_modular/modules/vampire/life_vampire.dm b/tff_modular/modules/vampire/life_vampire.dm index eb94dbf594e..e4e20774cf9 100644 --- a/tff_modular/modules/vampire/life_vampire.dm +++ b/tff_modular/modules/vampire/life_vampire.dm @@ -2,33 +2,34 @@ /datum/antagonist/vampire/proc/life_tick(datum/source, seconds_per_tick, times_fired) SIGNAL_HANDLER - var/mob/living/vampire = source - var/mob/living/vampiredatum = vampire.mind?.has_antag_datum(/datum/antagonist/vampire) - if(!isliving(vampire)) + if(!isliving(owner.current)) // Weirdness shield - if(isbrain(vampire)) + if(isbrain(owner.current)) update_hud() return - if(QDELETED(vampire) || QDELETED(vampiredatum)) + if(QDELETED(owner.current)) INVOKE_ASYNC(src, PROC_REF(handle_death)) return + handle_life() + +/datum/antagonist/vampire/proc/handle_life() // Deduct Blood - if(vampire.stat == CONSCIOUS && !HAS_TRAIT(vampire, TRAIT_IMMOBILIZED) && !HAS_TRAIT(vampire, TRAIT_NODEATH)) + if(owner.current.stat == CONSCIOUS && !HAS_TRAIT(owner.current, TRAIT_IMMOBILIZED) && !HAS_TRAIT(owner.current, TRAIT_NODEATH)) adjust_blood_volume(-VAMPIRE_PASSIVE_BLOOD_DRAIN) // Healing - if(handle_healing(seconds_per_tick) && !isanimal_or_basicmob(vampire)) + if(handle_healing(seconds_per_tick) && !isanimal_or_basicmob(owner.current)) if((COOLDOWN_FINISHED(src, vampire_spam_healing)) && current_vitae > 0) - to_chat(vampire, span_notice("The power of your blood knits your wounds...")) + to_chat(owner.current, span_notice("The power of your blood knits your wounds...")) COOLDOWN_START(src, vampire_spam_healing, VAMPIRE_SPAM_HEALING) - var/area/current_area = get_area(vampire) - if(istype(current_area, /area/station/service/chapel) && !is_chaplain_job(vampire.assigned_role) && humanity <= 2) - to_chat(vampire, span_warning("Your inhuman nature is rejected by a holy presence!")) - vampire.adjust_fire_loss(10) - vampire.adjust_fire_stacks(4) - vampire.ignite_mob() + var/area/current_area = get_area(owner.current) + if(istype(current_area, /area/station/service/chapel) && !is_chaplain_job(owner.current.assigned_role) && humanity <= 2) + to_chat(owner.current, span_warning("Your inhuman nature is rejected by a holy presence!")) + owner.current.adjust_fire_loss(10) + owner.current.adjust_fire_stacks(4) + owner.current.ignite_mob() // Standard Updates From 9098352bd470ae83ff55f7b91640fbb1b93605c0 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sat, 14 Mar 2026 14:37:50 +0300 Subject: [PATCH 042/149] Update life_vampire.dm --- tff_modular/modules/vampire/life_vampire.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tff_modular/modules/vampire/life_vampire.dm b/tff_modular/modules/vampire/life_vampire.dm index e4e20774cf9..be33c1722a5 100644 --- a/tff_modular/modules/vampire/life_vampire.dm +++ b/tff_modular/modules/vampire/life_vampire.dm @@ -11,9 +11,9 @@ INVOKE_ASYNC(src, PROC_REF(handle_death)) return - handle_life() + handle_life(seconds_per_tick, times_fired) -/datum/antagonist/vampire/proc/handle_life() +/datum/antagonist/vampire/proc/handle_life(seconds_per_tick, times_fired) // Deduct Blood if(owner.current.stat == CONSCIOUS && !HAS_TRAIT(owner.current, TRAIT_IMMOBILIZED) && !HAS_TRAIT(owner.current, TRAIT_NODEATH)) adjust_blood_volume(-VAMPIRE_PASSIVE_BLOOD_DRAIN) @@ -25,7 +25,7 @@ COOLDOWN_START(src, vampire_spam_healing, VAMPIRE_SPAM_HEALING) var/area/current_area = get_area(owner.current) - if(istype(current_area, /area/station/service/chapel) && !is_chaplain_job(owner.current.assigned_role) && humanity <= 2) + if(istype(current_area, /area/station/service/chapel) && !is_chaplain_job(owner.current.mind?.assigned_role) && humanity <= 2) to_chat(owner.current, span_warning("Your inhuman nature is rejected by a holy presence!")) owner.current.adjust_fire_loss(10) owner.current.adjust_fire_stacks(4) From 2598306c1a184f5dceb02c5936d95af8ab8efc7b Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sat, 14 Mar 2026 14:46:12 +0300 Subject: [PATCH 043/149] Update life_vampire.dm --- tff_modular/modules/vampire/life_vampire.dm | 24 +++++++++------------ 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/tff_modular/modules/vampire/life_vampire.dm b/tff_modular/modules/vampire/life_vampire.dm index be33c1722a5..9fffaf22f5c 100644 --- a/tff_modular/modules/vampire/life_vampire.dm +++ b/tff_modular/modules/vampire/life_vampire.dm @@ -1,25 +1,21 @@ /// Runs from COMSIG_LIVING_LIFE, handles Vampire constant processes. /datum/antagonist/vampire/proc/life_tick(datum/source, seconds_per_tick, times_fired) SIGNAL_HANDLER - - if(!isliving(owner.current)) - // Weirdness shield + if(QDELETED(owner) || QDELETED(owner.current)) + INVOKE_ASYNC(src, PROC_REF(handle_death)) + return + handle_life() if(isbrain(owner.current)) update_hud() return - if(QDELETED(owner.current)) - INVOKE_ASYNC(src, PROC_REF(handle_death)) - return - - handle_life(seconds_per_tick, times_fired) -/datum/antagonist/vampire/proc/handle_life(seconds_per_tick, times_fired) +/datum/antagonist/vampire/proc/handle_life() // Deduct Blood if(owner.current.stat == CONSCIOUS && !HAS_TRAIT(owner.current, TRAIT_IMMOBILIZED) && !HAS_TRAIT(owner.current, TRAIT_NODEATH)) adjust_blood_volume(-VAMPIRE_PASSIVE_BLOOD_DRAIN) // Healing - if(handle_healing(seconds_per_tick) && !isanimal_or_basicmob(owner.current)) + if(handle_healing() && !isanimal_or_basicmob(owner.current)) if((COOLDOWN_FINISHED(src, vampire_spam_healing)) && current_vitae > 0) to_chat(owner.current, span_notice("The power of your blood knits your wounds...")) COOLDOWN_START(src, vampire_spam_healing, VAMPIRE_SPAM_HEALING) @@ -55,7 +51,7 @@ * By default, burn damage is healed 50% as effectively as brute * When undergoing torpor it's 80%, if you're in a coffin 100% **/ -/datum/antagonist/vampire/proc/handle_healing(seconds_per_tick) +/datum/antagonist/vampire/proc/handle_healing() var/mob/living/current = owner.current // Weirdness shield @@ -72,7 +68,7 @@ var/actual_regen = vampire_regen_rate + additional_regen - current.adjust_organ_loss(ORGAN_SLOT_BRAIN, -1 * (actual_regen * 4) * seconds_per_tick) + current.adjust_organ_loss(ORGAN_SLOT_BRAIN, -1 * (actual_regen * 4)) if(!iscarbon(current)) return FALSE @@ -95,7 +91,7 @@ if(wound.blood_flow && (!bloodiest_wound || wound.blood_flow > bloodiest_wound?.blood_flow)) bloodiest_wound = wound - bloodiest_wound?.adjust_blood_flow(-0.25 * seconds_per_tick) + bloodiest_wound?.adjust_blood_flow(-0.25) for(var/obj/item/bodypart/bodypart as anything in carbon_owner.bodyparts) if(bodypart.generic_bleedstacks) @@ -130,7 +126,7 @@ if(brute_heal > 0 || burn_heal > 0) // Just a check? Don't heal/spend, and return. var/vitaecost = (brute_heal * 0.5 + burn_heal) * vitaecost_multiplier * healing_multiplier - carbon_owner.heal_overall_damage(brute_heal * seconds_per_tick, burn_heal * seconds_per_tick) + carbon_owner.heal_overall_damage(brute_heal, burn_heal) adjust_blood_volume(-vitaecost) return TRUE From 1078fd4552a7982a1384d464a6852e4cec42b336 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sat, 14 Mar 2026 14:56:16 +0300 Subject: [PATCH 044/149] Update life_vampire.dm --- tff_modular/modules/vampire/life_vampire.dm | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/tff_modular/modules/vampire/life_vampire.dm b/tff_modular/modules/vampire/life_vampire.dm index 9fffaf22f5c..4c518090a11 100644 --- a/tff_modular/modules/vampire/life_vampire.dm +++ b/tff_modular/modules/vampire/life_vampire.dm @@ -1,9 +1,6 @@ /// Runs from COMSIG_LIVING_LIFE, handles Vampire constant processes. /datum/antagonist/vampire/proc/life_tick(datum/source, seconds_per_tick, times_fired) SIGNAL_HANDLER - if(QDELETED(owner) || QDELETED(owner.current)) - INVOKE_ASYNC(src, PROC_REF(handle_death)) - return handle_life() if(isbrain(owner.current)) update_hud() @@ -13,7 +10,9 @@ // Deduct Blood if(owner.current.stat == CONSCIOUS && !HAS_TRAIT(owner.current, TRAIT_IMMOBILIZED) && !HAS_TRAIT(owner.current, TRAIT_NODEATH)) adjust_blood_volume(-VAMPIRE_PASSIVE_BLOOD_DRAIN) - + if(QDELETED(owner) || QDELETED(owner.current)) + INVOKE_ASYNC(src, PROC_REF(handle_death)) + return // Healing if(handle_healing() && !isanimal_or_basicmob(owner.current)) if((COOLDOWN_FINISHED(src, vampire_spam_healing)) && current_vitae > 0) @@ -27,8 +26,6 @@ owner.current.adjust_fire_stacks(4) owner.current.ignite_mob() - // Standard Updates - // Clan specific stuff if(my_clan) my_clan.handle_clan_life() From 8c2c0151a04e9f7bdae4516000068ffe4cfc4f13 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sat, 14 Mar 2026 15:03:51 +0300 Subject: [PATCH 045/149] Update life_vampire.dm --- tff_modular/modules/vampire/life_vampire.dm | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/tff_modular/modules/vampire/life_vampire.dm b/tff_modular/modules/vampire/life_vampire.dm index 4c518090a11..db60a5eca37 100644 --- a/tff_modular/modules/vampire/life_vampire.dm +++ b/tff_modular/modules/vampire/life_vampire.dm @@ -1,15 +1,19 @@ /// Runs from COMSIG_LIVING_LIFE, handles Vampire constant processes. /datum/antagonist/vampire/proc/life_tick(datum/source, seconds_per_tick, times_fired) SIGNAL_HANDLER + if(!isliving(owner.current)) + return FALSE + handle_life() - if(isbrain(owner.current)) - update_hud() - return + var/area/current_area = get_area(owner.current) + if(istype(current_area, /area/station/service/chapel) && !is_chaplain_job(owner.current.mind?.assigned_role) && humanity <= 2) + to_chat(owner.current, span_warning("Your inhuman nature is rejected by a holy presence!")) + owner.current.adjust_fire_loss(10) + owner.current.adjust_fire_stacks(4) + owner.current.ignite_mob() /datum/antagonist/vampire/proc/handle_life() // Deduct Blood - if(owner.current.stat == CONSCIOUS && !HAS_TRAIT(owner.current, TRAIT_IMMOBILIZED) && !HAS_TRAIT(owner.current, TRAIT_NODEATH)) - adjust_blood_volume(-VAMPIRE_PASSIVE_BLOOD_DRAIN) if(QDELETED(owner) || QDELETED(owner.current)) INVOKE_ASYNC(src, PROC_REF(handle_death)) return @@ -19,13 +23,6 @@ to_chat(owner.current, span_notice("The power of your blood knits your wounds...")) COOLDOWN_START(src, vampire_spam_healing, VAMPIRE_SPAM_HEALING) - var/area/current_area = get_area(owner.current) - if(istype(current_area, /area/station/service/chapel) && !is_chaplain_job(owner.current.mind?.assigned_role) && humanity <= 2) - to_chat(owner.current, span_warning("Your inhuman nature is rejected by a holy presence!")) - owner.current.adjust_fire_loss(10) - owner.current.adjust_fire_stacks(4) - owner.current.ignite_mob() - // Clan specific stuff if(my_clan) my_clan.handle_clan_life() From e8c00e49cce03eeda1b32316da445264f891a5e3 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sat, 14 Mar 2026 15:06:18 +0300 Subject: [PATCH 046/149] =?UTF-8?q?=D0=B0=20=D1=87=D1=82=D0=BE=20=D0=B5?= =?UTF-8?q?=D1=81=D0=BB=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tff_modular/modules/vampire/life_vampire.dm | 39 ++++++++++++--------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/tff_modular/modules/vampire/life_vampire.dm b/tff_modular/modules/vampire/life_vampire.dm index db60a5eca37..dda4cc29c9c 100644 --- a/tff_modular/modules/vampire/life_vampire.dm +++ b/tff_modular/modules/vampire/life_vampire.dm @@ -1,28 +1,30 @@ /// Runs from COMSIG_LIVING_LIFE, handles Vampire constant processes. /datum/antagonist/vampire/proc/life_tick(datum/source, seconds_per_tick, times_fired) SIGNAL_HANDLER - if(!isliving(owner.current)) - return FALSE - - handle_life() - var/area/current_area = get_area(owner.current) - if(istype(current_area, /area/station/service/chapel) && !is_chaplain_job(owner.current.mind?.assigned_role) && humanity <= 2) - to_chat(owner.current, span_warning("Your inhuman nature is rejected by a holy presence!")) - owner.current.adjust_fire_loss(10) - owner.current.adjust_fire_stacks(4) - owner.current.ignite_mob() - -/datum/antagonist/vampire/proc/handle_life() - // Deduct Blood - if(QDELETED(owner) || QDELETED(owner.current)) - INVOKE_ASYNC(src, PROC_REF(handle_death)) + // Weirdness shield + if(isbrain(owner?.current)) + update_hud() return + handle_async() + // Deduct Blood + if(owner.current.stat == CONSCIOUS && !HAS_TRAIT(owner.current, TRAIT_IMMOBILIZED) && !HAS_TRAIT(owner.current, TRAIT_NODEATH)) + adjust_blood_volume(-VAMPIRE_PASSIVE_BLOOD_DRAIN) + // Healing - if(handle_healing() && !isanimal_or_basicmob(owner.current)) + if(handle_healing(seconds_per_tick) && !isanimal_or_basicmob(owner)) if((COOLDOWN_FINISHED(src, vampire_spam_healing)) && current_vitae > 0) to_chat(owner.current, span_notice("The power of your blood knits your wounds...")) COOLDOWN_START(src, vampire_spam_healing, VAMPIRE_SPAM_HEALING) + var/area/current_area = get_area(owner.current) + if(istype(current_area, /area/station/service/chapel) && !is_chaplain_job(owner.assigned_role) && humanity <= 2) + to_chat(owner, span_warning("Your inhuman nature is rejected by a holy presence!")) + owner.current.adjustFireLoss(10) + owner.current.adjust_fire_stacks(4) + owner.current.ignite_mob() + + // Standard Updates + // Clan specific stuff if(my_clan) my_clan.handle_clan_life() @@ -32,6 +34,11 @@ // Set our body's blood_volume to mimick our vampire one (if we aren't using the Masquerade power) update_hud() +/datum/antagonist/vampire/proc/handle_async() + if(QDELETED(owner)) + INVOKE_ASYNC(src, PROC_REF(handle_death)) + return + /** * Pretty simple, add a value to the vampire's blood volume **/ From e11b7ffee48fba478182b248df7e48bed028b835 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sat, 14 Mar 2026 15:11:37 +0300 Subject: [PATCH 047/149] Update life_vampire.dm --- tff_modular/modules/vampire/life_vampire.dm | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tff_modular/modules/vampire/life_vampire.dm b/tff_modular/modules/vampire/life_vampire.dm index dda4cc29c9c..f33a4e2738b 100644 --- a/tff_modular/modules/vampire/life_vampire.dm +++ b/tff_modular/modules/vampire/life_vampire.dm @@ -1,11 +1,7 @@ /// Runs from COMSIG_LIVING_LIFE, handles Vampire constant processes. /datum/antagonist/vampire/proc/life_tick(datum/source, seconds_per_tick, times_fired) SIGNAL_HANDLER - // Weirdness shield - if(isbrain(owner?.current)) - update_hud() - return - handle_async() + handle_life() // Deduct Blood if(owner.current.stat == CONSCIOUS && !HAS_TRAIT(owner.current, TRAIT_IMMOBILIZED) && !HAS_TRAIT(owner.current, TRAIT_NODEATH)) adjust_blood_volume(-VAMPIRE_PASSIVE_BLOOD_DRAIN) @@ -19,7 +15,7 @@ var/area/current_area = get_area(owner.current) if(istype(current_area, /area/station/service/chapel) && !is_chaplain_job(owner.assigned_role) && humanity <= 2) to_chat(owner, span_warning("Your inhuman nature is rejected by a holy presence!")) - owner.current.adjustFireLoss(10) + owner.current.adjust_fire_loss(10) owner.current.adjust_fire_stacks(4) owner.current.ignite_mob() @@ -34,7 +30,11 @@ // Set our body's blood_volume to mimick our vampire one (if we aren't using the Masquerade power) update_hud() -/datum/antagonist/vampire/proc/handle_async() +/datum/antagonist/vampire/proc/handle_life() + // Weirdness shield + if(isbrain(owner?.current)) + update_hud() + return if(QDELETED(owner)) INVOKE_ASYNC(src, PROC_REF(handle_death)) return From 20ed132437325ca80ce7a1d2a247018e66df2a34 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sat, 14 Mar 2026 15:22:23 +0300 Subject: [PATCH 048/149] Update life_vampire.dm --- tff_modular/modules/vampire/life_vampire.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tff_modular/modules/vampire/life_vampire.dm b/tff_modular/modules/vampire/life_vampire.dm index f33a4e2738b..99ae44dc629 100644 --- a/tff_modular/modules/vampire/life_vampire.dm +++ b/tff_modular/modules/vampire/life_vampire.dm @@ -113,7 +113,7 @@ // Extinguish and remove embedded objects carbon_owner.extinguish_mob() - carbon_owner.remove_all_embedded_objects() + INVOKE_ASYNC(carbon_owner, PROC_REF(remove_all_embedded_objects)) if(try_regenerate_limbs(vitaecost_multiplier)) return TRUE @@ -293,7 +293,7 @@ var/mob/living/carbon/carbon_body = body carbon_body.drop_all_held_items() carbon_body.unequip_everything() - carbon_body.remove_all_embedded_objects() + INVOKE_ASYNC(carbon_body, PROC_REF(remove_all_embedded_objects)) playsound(owner.current, 'tff_modular/modules/vampire/sound/burning_death.ogg', 100, TRUE) else body.dust(drop_items = TRUE) From a2b58c3dc4c2860a9fb8fe4b5fc8f19c1f911a71 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sat, 14 Mar 2026 15:27:36 +0300 Subject: [PATCH 049/149] Update life_vampire.dm --- tff_modular/modules/vampire/life_vampire.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tff_modular/modules/vampire/life_vampire.dm b/tff_modular/modules/vampire/life_vampire.dm index 99ae44dc629..259a8345ac6 100644 --- a/tff_modular/modules/vampire/life_vampire.dm +++ b/tff_modular/modules/vampire/life_vampire.dm @@ -113,7 +113,7 @@ // Extinguish and remove embedded objects carbon_owner.extinguish_mob() - INVOKE_ASYNC(carbon_owner, PROC_REF(remove_all_embedded_objects)) + INVOKE_ASYNC(carbon_owner, TYPE_PROC_REF(mob/living/carbon/human, remove_all_embedded_objects)) if(try_regenerate_limbs(vitaecost_multiplier)) return TRUE @@ -293,7 +293,7 @@ var/mob/living/carbon/carbon_body = body carbon_body.drop_all_held_items() carbon_body.unequip_everything() - INVOKE_ASYNC(carbon_body, PROC_REF(remove_all_embedded_objects)) + INVOKE_ASYNC(carbon_body, TYPE_PROC_REF(mob/living/carbon/human, remove_all_embedded_objects)) playsound(owner.current, 'tff_modular/modules/vampire/sound/burning_death.ogg', 100, TRUE) else body.dust(drop_items = TRUE) From e9395868dbb9768f5ab430b9d1ff285bf6994d60 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sat, 14 Mar 2026 15:31:16 +0300 Subject: [PATCH 050/149] Update life_vampire.dm --- tff_modular/modules/vampire/life_vampire.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tff_modular/modules/vampire/life_vampire.dm b/tff_modular/modules/vampire/life_vampire.dm index 259a8345ac6..99ae44dc629 100644 --- a/tff_modular/modules/vampire/life_vampire.dm +++ b/tff_modular/modules/vampire/life_vampire.dm @@ -113,7 +113,7 @@ // Extinguish and remove embedded objects carbon_owner.extinguish_mob() - INVOKE_ASYNC(carbon_owner, TYPE_PROC_REF(mob/living/carbon/human, remove_all_embedded_objects)) + INVOKE_ASYNC(carbon_owner, PROC_REF(remove_all_embedded_objects)) if(try_regenerate_limbs(vitaecost_multiplier)) return TRUE @@ -293,7 +293,7 @@ var/mob/living/carbon/carbon_body = body carbon_body.drop_all_held_items() carbon_body.unequip_everything() - INVOKE_ASYNC(carbon_body, TYPE_PROC_REF(mob/living/carbon/human, remove_all_embedded_objects)) + INVOKE_ASYNC(carbon_body, PROC_REF(remove_all_embedded_objects)) playsound(owner.current, 'tff_modular/modules/vampire/sound/burning_death.ogg', 100, TRUE) else body.dust(drop_items = TRUE) From 9d62b382d8b6020ad75d42c56731ff8982fa9971 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sat, 14 Mar 2026 15:38:28 +0300 Subject: [PATCH 051/149] Update life_vampire.dm --- tff_modular/modules/vampire/life_vampire.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tff_modular/modules/vampire/life_vampire.dm b/tff_modular/modules/vampire/life_vampire.dm index 99ae44dc629..017575a6de9 100644 --- a/tff_modular/modules/vampire/life_vampire.dm +++ b/tff_modular/modules/vampire/life_vampire.dm @@ -113,7 +113,7 @@ // Extinguish and remove embedded objects carbon_owner.extinguish_mob() - INVOKE_ASYNC(carbon_owner, PROC_REF(remove_all_embedded_objects)) + INVOKE_ASYNC(carbon_owner, TYPE_PROC_REF(/mob/living/carbon, remove_all_embedded_objects)) if(try_regenerate_limbs(vitaecost_multiplier)) return TRUE @@ -293,7 +293,7 @@ var/mob/living/carbon/carbon_body = body carbon_body.drop_all_held_items() carbon_body.unequip_everything() - INVOKE_ASYNC(carbon_body, PROC_REF(remove_all_embedded_objects)) + INVOKE_ASYNC(carbon_body, TYPE_PROC_REF(/mob/living/carbon, remove_all_embedded_objects)) playsound(owner.current, 'tff_modular/modules/vampire/sound/burning_death.ogg', 100, TRUE) else body.dust(drop_items = TRUE) From bfab748005815150265306e15a229b9a494da9f5 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sat, 14 Mar 2026 16:03:06 +0300 Subject: [PATCH 052/149] =?UTF-8?q?=D0=B2=D1=80=D0=B5=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D0=BD=D0=BE=20=D1=83=D0=B4=D0=B0=D0=BB=D1=8F=D0=B5=D0=BC=20?= =?UTF-8?q?=D0=B7=D0=BE=D0=BD=D1=82=D0=B8=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tff_modular/modules/vampire/objects/umbrellas.dm | 2 +- tff_modular/modules/vending/vends/autodrobe.dm | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/tff_modular/modules/vampire/objects/umbrellas.dm b/tff_modular/modules/vampire/objects/umbrellas.dm index 266470ba213..eae368cbab3 100644 --- a/tff_modular/modules/vampire/objects/umbrellas.dm +++ b/tff_modular/modules/vampire/objects/umbrellas.dm @@ -4,7 +4,6 @@ * Umbrellas you can hold, and open and close. * Currently not coding for protecting against rain as ???I dont think??? rain exists. * The rest don't and it just for looks. - */ /obj/item/umbrella name = "umbrella" desc = "A plain umbrella." @@ -166,3 +165,4 @@ time = 5 SECONDS category = CAT_EQUIPMENT crafting_flags = CRAFT_SKIP_MATERIALS_PARITY +*/ diff --git a/tff_modular/modules/vending/vends/autodrobe.dm b/tff_modular/modules/vending/vends/autodrobe.dm index 48558d85bcb..1f2ef884151 100644 --- a/tff_modular/modules/vending/vends/autodrobe.dm +++ b/tff_modular/modules/vending/vends/autodrobe.dm @@ -13,8 +13,6 @@ /obj/item/clothing/head/playbunnyears/mime = 3, /obj/item/clothing/shoes/clown_shoes/heeled = 3, /obj/item/clothing/shoes/fancy_heels/white = 3, - /obj/item/umbrella = 3, - /obj/item/umbrella/parasol = 3, ), ), ) From 38c540e9ac2789ad4e5ac0b5ccd51bc9d2ede9bc Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sat, 14 Mar 2026 16:08:59 +0300 Subject: [PATCH 053/149] Update malkavian_revelations.json --- tff_modular/strings/malkavian_revelations.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tff_modular/strings/malkavian_revelations.json b/tff_modular/strings/malkavian_revelations.json index 710e98f149e..7aa57375c7b 100644 --- a/tff_modular/strings/malkavian_revelations.json +++ b/tff_modular/strings/malkavian_revelations.json @@ -39,7 +39,7 @@ "#Ты думаешь меня это волнует? Спроси, волнует ли это меня, потому что мне плевать! Если бы я получал 1 кредит каждый раз когда они говорят что мне не плевать, я бы был бедным, потому что мне плевать!", "#Этот 357-й калибр заставил меня двигаться, как инвазивный вид.", "#Я делаю плохо прикосновение Мидаса.", - "#Я убью етбя!",, + "#Я убью тебя!", "#Подожди, дай мне сделать пару глотков.", "#Маскарад должен соблюдаться также, как хранят ядерный диск, это то что охраняет нас от того, кто снизу...", "#150, 149, 148... 147, 146, 145, 144... Какое мое число, напомни?", From 94920483c4fe45acad498b924843feddb6bb4a8c Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sun, 15 Mar 2026 13:11:47 +0300 Subject: [PATCH 054/149] =?UTF-8?q?=D0=B0=D0=B1=D0=BD=D0=BE=D0=B2=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/__DEFINES/~ff_defines/bloodsucker.dm | 3 +- .../deathmatch/deathmatch_controller.dm | 5 + code/modules/mob/dead/observer/observer.dm | 5 +- .../code/soulcatcher/soulcatcher_component.dm | 4 + tff_modular/modules/vampire/frenzy_vampire.dm | 4 - .../modules/vampire/powers/_targeted.dm | 4 +- .../vampire/powers/auspex/astral_project.dm | 2 +- .../modules/vampire/powers/auspex/auspex.dm | 91 ++++--------------- .../modules/vampire/powers/celerity/haste.dm | 8 +- .../vampire/powers/celerity/quickness.dm | 2 +- .../vampire/powers/dominate/command.dm | 6 +- .../vampire/powers/dominate/mesmerize.dm | 14 +-- tff_modular/modules/vampire/powers/feed.dm | 8 +- .../modules/vampire/powers/levelspells.dm | 2 +- .../vampire/powers/obfuscate/trespass.dm | 2 +- .../modules/vampire/powers/potence/brash.dm | 4 +- .../modules/vampire/powers/potence/brawn.dm | 8 +- .../modules/vampire/powers/potence/lunge.dm | 6 +- .../modules/vampire/powers/presence/awe.dm | 2 +- .../vampire/powers/presence/entrance.dm | 8 +- .../modules/vampire/powers/presence/summon.dm | 12 +-- .../vampire/powers/thaumaturgy/bloodboil.dm | 2 +- .../vampire/powers/thaumaturgy/bloodbolt.dm | 4 +- .../vampire/powers/thaumaturgy/blooddrain.dm | 10 +- .../modules/vampire/vassals/datum_vassal.dm | 6 -- .../strings/malkavian_revelations.json | 10 +- .../antagonists/vampiricaccident.ts | 2 +- 27 files changed, 90 insertions(+), 144 deletions(-) diff --git a/code/__DEFINES/~ff_defines/bloodsucker.dm b/code/__DEFINES/~ff_defines/bloodsucker.dm index efcb522210b..c2faf6fe5df 100644 --- a/code/__DEFINES/~ff_defines/bloodsucker.dm +++ b/code/__DEFINES/~ff_defines/bloodsucker.dm @@ -25,7 +25,7 @@ #define LOG_CATEGORY_UPLINK_VAMPIRE "uplink-vampire" #define FACTION_VAMPIRE "Vampire" #define ROLE_VAMPIRE "Vampire" -#define ROLE_VAMPIRIC_ACCIDENT "VampiricAccident" +#define ROLE_VAMPIRIC_ACCIDENT "Vampiric Accident" #define span_awe(str) ("" + str + "") /// Uncomment this to enable testing of Vampire features (such as vassalizing people with a mind instead of a client). //#define VAMPIRE_TESTING @@ -194,6 +194,7 @@ /// This vampire can tell if another vampire has committed diablere on examine. #define TRAIT_SEE_DIABLERIE "see_diablerie" +#define CLIENT_COLOR_SOURCE_VAMPIRE "client_color_source_vampire" // Trait sources /// Source trait for all vampire traits #define TRAIT_VAMPIRE "trait_vampire" diff --git a/code/modules/deathmatch/deathmatch_controller.dm b/code/modules/deathmatch/deathmatch_controller.dm index 3ae10ad51d2..e6081f43da0 100644 --- a/code/modules/deathmatch/deathmatch_controller.dm +++ b/code/modules/deathmatch/deathmatch_controller.dm @@ -40,6 +40,11 @@ return GLOB.observer_state /datum/deathmatch_controller/ui_interact(mob/user, datum/tgui/ui) + // TFF ADDITION START + if(HAS_TRAIT(user, TRAIT_NO_OBSERVE)) + to_chat(user, span_warning("You cannot play or host deathmatch in your current form!")) + return + // TFF ADDITION END ui = SStgui.try_update_ui(user, src, null) if(!ui) ui = new(user, src, "DeathmatchPanel") diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index d9f49d3d78f..9b871a01211 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -639,7 +639,10 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp /mob/dead/observer/verb/restore_ghost_appearance() set name = "Restore Ghost Character" - + // TFF ADDITION START + if(HAS_TRAIT(src, TRAIT_NO_OBSERVE)) + return + // TFF ADDITION END set_ghost_appearance() if(client?.prefs) var/real_name = client.prefs.read_preference(/datum/preference/name/real_name) diff --git a/modular_nova/modules/modular_implants/code/soulcatcher/soulcatcher_component.dm b/modular_nova/modules/modular_implants/code/soulcatcher/soulcatcher_component.dm index 38f8306b1a9..978961bc675 100644 --- a/modular_nova/modules/modular_implants/code/soulcatcher/soulcatcher_component.dm +++ b/modular_nova/modules/modular_implants/code/soulcatcher/soulcatcher_component.dm @@ -428,6 +428,10 @@ GLOBAL_LIST_EMPTY(soulcatchers) /mob/dead/observer/verb/join_soulcatcher() set name = "Enter Soulcatcher" + // TFF ADDIITON START + if(HAS_TRAIT(src, TRAIT_NO_OBSERVE)) + return FALSE + // TFF ADDITION END var/list/joinable_soulcatchers = list() for(var/datum/component/soulcatcher/soulcatcher in GLOB.soulcatchers) if(!soulcatcher.ghost_joinable || !isobj(soulcatcher.parent) || !soulcatcher.check_for_vacancy()) diff --git a/tff_modular/modules/vampire/frenzy_vampire.dm b/tff_modular/modules/vampire/frenzy_vampire.dm index 9ad4e312a5d..f4e09b14d26 100644 --- a/tff_modular/modules/vampire/frenzy_vampire.dm +++ b/tff_modular/modules/vampire/frenzy_vampire.dm @@ -1,5 +1,3 @@ -#define CLIENT_COLOR_SOURCE_VAMPIRE "vampire_source" - /** * # Status effect * @@ -115,5 +113,3 @@ /atom/movable/screen/alert/status_effect/masquerade/MouseEntered(location,control,params) desc = initial(desc) return ..() - -#undef CLIENT_COLOR_SOURCE_VAMPIRE diff --git a/tff_modular/modules/vampire/powers/_targeted.dm b/tff_modular/modules/vampire/powers/_targeted.dm index bda0e222f63..b3bf6c59402 100644 --- a/tff_modular/modules/vampire/powers/_targeted.dm +++ b/tff_modular/modules/vampire/powers/_targeted.dm @@ -77,7 +77,7 @@ return TRUE /// Click Target -/datum/action/cooldown/vampire/targeted/proc/click_with_power(atom/target_atom) +/datum/action/cooldown/vampire/targeted/proc/click_with_power(atom/target_atom, list/modifiers) // Already using? if(power_in_use) return @@ -100,7 +100,7 @@ power_activated_sucessfully() // Mesmerize pays only after success. power_in_use = FALSE -/datum/action/cooldown/vampire/targeted/proc/fire_targeted_power(atom/target_atom) +/datum/action/cooldown/vampire/targeted/proc/fire_targeted_power(atom/target_atom, list/modifiers) unset_click_ability(owner) log_combat(owner, target_atom, "used [name] on") diff --git a/tff_modular/modules/vampire/powers/auspex/astral_project.dm b/tff_modular/modules/vampire/powers/auspex/astral_project.dm index ba4dced2182..e759048784e 100644 --- a/tff_modular/modules/vampire/powers/auspex/astral_project.dm +++ b/tff_modular/modules/vampire/powers/auspex/astral_project.dm @@ -9,7 +9,7 @@ button_icon_state = "power_astral_projection" vampire_power_flags = BP_AM_TOGGLE vampire_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 - vitaecost = 400 + vitaecost = 200 cooldown_time = 60 SECONDS /datum/action/cooldown/vampire/astral_projection/activate_power() diff --git a/tff_modular/modules/vampire/powers/auspex/auspex.dm b/tff_modular/modules/vampire/powers/auspex/auspex.dm index 87f60efbea7..68948b67edc 100644 --- a/tff_modular/modules/vampire/powers/auspex/auspex.dm +++ b/tff_modular/modules/vampire/powers/auspex/auspex.dm @@ -8,69 +8,44 @@ level_1 = list(/datum/action/cooldown/vampire/auspex) level_2 = list(/datum/action/cooldown/vampire/auspex/two) level_3 = list(/datum/action/cooldown/vampire/auspex/three) - level_4 = list(/datum/action/cooldown/vampire/auspex/four) /datum/discipline/auspex/malkavian - level_5 = list(/datum/action/cooldown/vampire/auspex/four, /datum/action/cooldown/vampire/astral_projection) - -/** - * # Auspex - * - * Level 1 - Raise sightrange by 2, project sight 2 tiles ahead. - * Level 2 - Raise sightrange by 3, project sight 4 tiles ahead. Meson Vision - * Level 3 - Raise sightrange by 5, project sight 6 tiles ahead. - * Level 4 - Raise sightrange by 7, project sight 8 tiles ahead. Xray Vision - * Level 5 - For Malkavians: Gain ability to astral project like a wizard. - */ + level_4 = list(/datum/action/cooldown/vampire/astral_projection) + /datum/action/cooldown/vampire/auspex name = "Auspex" desc = "Sense the vitae of any creature directly, and use your keen senses to widen your perception." button_icon_state = "power_auspex" - power_explanation = "- Level 1: When Activated, you will see further. \n\ - - Level 2: When Activated, you will see further, be able to sense walls and the layout of rooms, and, upon examining a fellow Kindred, be able to tell if they have committed Diablerie. \n\ - - Level 3: When Activated, You still have meson vision, same as level 3, but even more range. \n\ - - Level 4: When Activated, you will see further, and be able to sense anything in sight, seeing through walls and barriers as if they were glass." + power_explanation = "- Level 1: When Activated, you will be able to sense walls and the layout of rooms, and, upon examining a fellow Kindred, be able to tell if they have committed Diablerie. \n\ + - Level 2: When Activated, You will be able to see health of your victims. \n\ + - Level 3: When Activated, you will be able to sense anything in sight, seeing and hearing through walls and barriers as if they were glass." vampire_power_flags = BP_AM_TOGGLE | BP_AM_STATIC_COOLDOWN vampire_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 - vitaecost = 50 + vitaecost = 10 constant_vitaecost = 1 cooldown_time = 10 SECONDS - var/add_meson = FALSE + var/add_medical = FALSE + var/add_meson = TRUE var/add_xray = FALSE - var/zoom_out_amt = 2 - var/zoom_amt = 6 - var/see_diablerie = FALSE - - + var/see_diablerie = TRUE var/looking = FALSE - var/mob/listening_to /datum/action/cooldown/vampire/auspex/two name = "Auspex" vitaecost = 40 constant_vitaecost = 2 - zoom_out_amt = 4 - zoom_amt = 7 add_meson = TRUE see_diablerie = TRUE + add_medical = TRUE /datum/action/cooldown/vampire/auspex/three name = "Auspex" vitaecost = 30 constant_vitaecost = 3 - zoom_out_amt = 6 - zoom_amt = 8 + add_medical = TRUE add_meson = TRUE see_diablerie = TRUE - -/datum/action/cooldown/vampire/auspex/four - name = "Auspex" - vitaecost = 20 - constant_vitaecost = 4 - zoom_out_amt = 10 - zoom_amt = 10 add_xray = TRUE - see_diablerie = TRUE /datum/action/cooldown/vampire/auspex/activate_power() . = ..() @@ -85,30 +60,11 @@ /datum/action/cooldown/vampire/auspex/proc/lookie() SIGNAL_HANDLER - if(!listening_to) - RegisterSignals(owner, list(COMSIG_MOVABLE_MOVED, COMSIG_MOB_LOGOUT), PROC_REF(deactivate_power)) - RegisterSignal(owner, COMSIG_ATOM_POST_DIR_CHANGE, PROC_REF(lookie)) - listening_to = owner - var/client/client = owner?.client - if(!client) - return - var/_x = 0 - var/_y = 0 - switch(owner.dir) - if(NORTH) - _y = zoom_amt - if(EAST) - _x = zoom_amt - if(SOUTH) - _y = -zoom_amt - if(WEST) - _x = -zoom_amt - - client?.change_view(get_zoomed_view(world.view, zoom_out_amt)) - client?.pixel_x = ICON_SIZE_X * _x - client?.pixel_y = ICON_SIZE_Y * _y looking = TRUE + if(add_medical) + ADD_TRAIT(owner, TRAIT_MEDICAL_HUD, REF(src)) + if(see_diablerie) ADD_TRAIT(owner, TRAIT_SEE_DIABLERIE, REF(src)) @@ -116,28 +72,13 @@ ADD_TRAIT(owner, TRAIT_MESON_VISION, REF(src)) if(add_xray) - ADD_TRAIT(owner, TRAIT_XRAY_VISION, REF(src)) + owner.add_traits(list(TRAIT_XRAY_VISION, TRAIT_XRAY_HEARING), REF(src)) owner.update_sight() /datum/action/cooldown/vampire/auspex/proc/unlooky() SIGNAL_HANDLER - if(listening_to) - UnregisterSignal(listening_to, list(COMSIG_MOVABLE_MOVED, COMSIG_MOB_LOGOUT, COMSIG_ATOM_POST_DIR_CHANGE)) - listening_to = null - looking = FALSE - owner.remove_traits(list(TRAIT_SEE_DIABLERIE, TRAIT_MESON_VISION, TRAIT_XRAY_VISION), REF(src)) + owner.remove_traits(list(TRAIT_SEE_DIABLERIE, TRAIT_MESON_VISION, TRAIT_XRAY_VISION, TRAIT_XRAY_HEARING, TRAIT_MEDICAL_HUD), REF(src)) owner.update_sight() - - // do this last in case weird client shit happens and runtimes - var/client/client = owner.client - if(client) - client?.change_view(CONFIG_GET(string/default_view)) - client?.pixel_x = 0 - client?.pixel_y = 0 - -/datum/action/cooldown/vampire/auspex/Destroy() - listening_to = null - return ..() diff --git a/tff_modular/modules/vampire/powers/celerity/haste.dm b/tff_modular/modules/vampire/powers/celerity/haste.dm index 3781e978c29..59bc6b4b292 100644 --- a/tff_modular/modules/vampire/powers/celerity/haste.dm +++ b/tff_modular/modules/vampire/powers/celerity/haste.dm @@ -42,7 +42,7 @@ owner.balloon_alert(owner, "you cannot dash while floating!") return FALSE var/mob/living/carbon/user = owner - if(user?.body_position == LYING_DOWN) + if(user?.body_position == LYING_DOWN && level_current < 3) owner.balloon_alert(owner, "you must be standing to tackle!") return FALSE return TRUE @@ -58,13 +58,14 @@ return FALSE /// This is a non-async proc to make sure the power is "locked" until this finishes. -/datum/action/cooldown/vampire/targeted/haste/fire_targeted_power(atom/target_atom) +/datum/action/cooldown/vampire/targeted/haste/fire_targeted_power(atom/target_atom, list/modifiers) . = ..() RegisterSignal(owner, COMSIG_MOVABLE_MOVED, PROC_REF(on_move)) var/mob/living/user = owner var/turf/targeted_turf = get_turf(target_atom) // Pulled? Not anymore. user.pulledby?.stop_pulling() + user.adjust_stamina_loss(-10 - level_current * 8) // Go to target turf // DO NOT USE WALK TO. // check_witnesses() @@ -82,7 +83,7 @@ break //just stop else consequetive_failures = 0 //reset so we can keep moving - if(user.resting || user.incapacitated(IGNORE_RESTRAINTS | IGNORE_GRAB)) //actually down? stop. + if(user.resting || user.incapacitated(IGNORE_RESTRAINTS | IGNORE_GRAB) && level_current < 3) //actually down? stop. break if(success) //don't sleep if we failed to move. sleep(world.tick_lag) @@ -98,5 +99,6 @@ continue hit += hit_living playsound(hit_living, SFX_PUNCH, 15, TRUE, -1) + hit_living.adjust_stamina_loss(20 + level_current * 8) hit_living.Knockdown(10 + level_current * 8) hit_living.spin(1 SECONDS, 1) diff --git a/tff_modular/modules/vampire/powers/celerity/quickness.dm b/tff_modular/modules/vampire/powers/celerity/quickness.dm index eb8f223705d..a3cbd073165 100644 --- a/tff_modular/modules/vampire/powers/celerity/quickness.dm +++ b/tff_modular/modules/vampire/powers/celerity/quickness.dm @@ -8,7 +8,7 @@ vampire_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 cooldown_time = 30 SECONDS vitaecost = 25 - constant_vitaecost = 2 + constant_vitaecost = 1.5 /datum/action/cooldown/vampire/exactitude/can_use() diff --git a/tff_modular/modules/vampire/powers/dominate/command.dm b/tff_modular/modules/vampire/powers/dominate/command.dm index 08ea37d9a9a..e30c955fa35 100644 --- a/tff_modular/modules/vampire/powers/dominate/command.dm +++ b/tff_modular/modules/vampire/powers/dominate/command.dm @@ -101,7 +101,7 @@ owner.balloon_alert(owner, "[living_target] is already compelled!") return FALSE -/datum/action/cooldown/vampire/targeted/command/fire_targeted_power(atom/target_atom) +/datum/action/cooldown/vampire/targeted/command/fire_targeted_power(atom/target_atom, list/modifiers) . = ..() var/mob/living/living_target = target_atom @@ -131,13 +131,13 @@ if(modified_delay > 0) living_target.balloon_alert(living_target, "your thoughts begin to blur!") - living_target.add_client_colour(/datum/client_colour/glass_colour/pink) + living_target.add_client_colour(/datum/client_colour/glass_colour/pink, CLIENT_COLOR_SOURCE_VAMPIRE) if(!do_after(owner, modified_delay, living_target, IGNORE_TARGET_LOC_CHANGE | IGNORE_HELD_ITEM, extra_checks = CALLBACK(src, PROC_REF(continue_active)), hidden = TRUE)) living_target.balloon_alert(living_target, "your thoughts come back into focus.") living_target.remove_client_colour(/datum/client_colour/glass_colour/pink) deactivate_power() return - living_target.remove_client_colour(/datum/client_colour/glass_colour/pink) + living_target.remove_client_colour(CLIENT_COLOR_SOURCE_VAMPIRE) // they're out of range once more if(!(living_target in hearers(target_range, owner))) diff --git a/tff_modular/modules/vampire/powers/dominate/mesmerize.dm b/tff_modular/modules/vampire/powers/dominate/mesmerize.dm index d41d47cc17f..7b1970d4bb9 100644 --- a/tff_modular/modules/vampire/powers/dominate/mesmerize.dm +++ b/tff_modular/modules/vampire/powers/dominate/mesmerize.dm @@ -37,15 +37,15 @@ return ..() /datum/action/cooldown/vampire/targeted/mesmerize/two - vitaecost = 45 + vitaecost = 30 level_current = 2 /datum/action/cooldown/vampire/targeted/mesmerize/three - vitaecost = 60 + vitaecost = 40 level_current = 3 /datum/action/cooldown/vampire/targeted/mesmerize/four - vitaecost = 85 + vitaecost = 60 level_current = 4 target_range = 6 @@ -85,7 +85,7 @@ return FALSE // Vampire/Curator check - if(IS_VAMPIRE(living_target) || IS_CURATOR(living_target) || HAS_MIND_TRAIT(living_target, TRAIT_UNCONVERTABLE)) + if(IS_VAMPIRE(living_target) || IS_CURATOR(living_target)) owner.balloon_alert(owner, "too powerful.") return FALSE @@ -104,7 +104,7 @@ owner.balloon_alert(owner, "[living_target] is already in a hypnotic gaze.") return FALSE -/datum/action/cooldown/vampire/targeted/mesmerize/fire_targeted_power(atom/target_atom) +/datum/action/cooldown/vampire/targeted/mesmerize/fire_targeted_power(atom/target_atom, list/modifiers) . = ..() var/mob/living/living_target = target_atom target_ref = WEAKREF(living_target) @@ -200,14 +200,14 @@ return ..() /datum/status_effect/mesmerized/on_apply() - owner.add_client_colour(/datum/client_colour/glass_colour/pink) + owner.add_client_colour(/datum/client_colour/glass_colour/pink, CLIENT_COLOR_SOURCE_VAMPIRE) owner.add_traits(mesmerized_traits, TRAIT_STATUS_EFFECT(id)) to_chat(owner, span_awe("[caster]'s eyes glitter so beautifully... You're mesmerized!"), type = MESSAGE_TYPE_COMBAT) owner.playsound_local(null, 'tff_modular/modules/vampire/sound/mesmerize.ogg', 100, FALSE, pressure_affected = FALSE) return TRUE /datum/status_effect/mesmerized/on_remove() - owner.remove_client_colour(/datum/client_colour/glass_colour/pink) + owner.remove_client_colour(CLIENT_COLOR_SOURCE_VAMPIRE) owner.remove_traits(mesmerized_traits, TRAIT_STATUS_EFFECT(id)) to_chat(owner, span_awe(span_big("With the spell waning, so does your memory of being mesmerized.")), type = MESSAGE_TYPE_COMBAT) if(CAN_THEY_SEE(owner, caster)) diff --git a/tff_modular/modules/vampire/powers/feed.dm b/tff_modular/modules/vampire/powers/feed.dm index 880a7d10786..72c03f725fb 100644 --- a/tff_modular/modules/vampire/powers/feed.dm +++ b/tff_modular/modules/vampire/powers/feed.dm @@ -154,7 +154,7 @@ silent_feed = TRUE -/datum/action/cooldown/vampire/targeted/feed/fire_targeted_power(atom/target_atom) +/datum/action/cooldown/vampire/targeted/feed/fire_targeted_power(atom/target_atom, list/modifiers) . = ..() var/mob/living/carbon/feed_target = target_atom var/mob/living/carbon/living_owner = owner @@ -175,7 +175,7 @@ currently_feeding = FALSE masquerade_breached = FALSE - if(!feed_target.grabbedby(living_owner)) + if(LAZYACCESS(modifiers, LEFT_CLICK)) // Don't allow normal feed on vamps. It's too easy and feels unfair. if(IS_VAMPIRE(feed_target)) @@ -219,7 +219,6 @@ // Just to make sure living_owner.stop_pulling() feed_target.stop_pulling() - /* // omega switch switch(get_dir(owner.loc, feed_target.loc)) if(NORTH) @@ -267,14 +266,13 @@ feed_target.dir = EAST animate(owner, 0.2 SECONDS, pixel_x = 8,) animate(feed_target, 0.2 SECONDS, pixel_x = -8) - */ owner.visible_message( span_notice("[owner] grabs [feed_target] tightly, biting into [feed_target.p_their()] neck!"), span_notice("You slip your fangs into [feed_target]'s neck."), vision_distance = FEED_SILENT_NOTICE_RANGE, ignored_mobs = feed_target ) - else if(feed_target.grabbedby(owner)) // COMBAT FEED BELOW HERE!!!!!!!!!! + else if(LAZYACCESS(modifiers, RIGHT_CLICK)) // COMBAT FEED BELOW HERE!!!!!!!!!! playsound(living_owner, 'tff_modular/modules/vampire/sound/drinkblood1.ogg', 50) diff --git a/tff_modular/modules/vampire/powers/levelspells.dm b/tff_modular/modules/vampire/powers/levelspells.dm index b9a247a48ed..804890d19d8 100644 --- a/tff_modular/modules/vampire/powers/levelspells.dm +++ b/tff_modular/modules/vampire/powers/levelspells.dm @@ -101,7 +101,7 @@ return TRUE -/datum/action/cooldown/vampire/targeted/scourgify/fire_targeted_power(atom/target_atom) +/datum/action/cooldown/vampire/targeted/scourgify/fire_targeted_power(atom/target_atom, list/modifiers) . = ..() var/mob/living/living_target = target_atom diff --git a/tff_modular/modules/vampire/powers/obfuscate/trespass.dm b/tff_modular/modules/vampire/powers/obfuscate/trespass.dm index 2a42b8ce996..3404cab6d98 100644 --- a/tff_modular/modules/vampire/powers/obfuscate/trespass.dm +++ b/tff_modular/modules/vampire/powers/obfuscate/trespass.dm @@ -58,7 +58,7 @@ target_turf = starting_turf -/datum/action/cooldown/vampire/targeted/trespass/fire_targeted_power(atom/target_atom) +/datum/action/cooldown/vampire/targeted/trespass/fire_targeted_power(atom/target_atom, list/modifiers) . = ..() // Find target turf, at or below Atom diff --git a/tff_modular/modules/vampire/powers/potence/brash.dm b/tff_modular/modules/vampire/powers/potence/brash.dm index cdd3065c9ed..949e13d1f86 100644 --- a/tff_modular/modules/vampire/powers/potence/brash.dm +++ b/tff_modular/modules/vampire/powers/potence/brash.dm @@ -20,7 +20,7 @@ vampire_power_flags = BP_AM_VERY_DYNAMIC_COOLDOWN vitaecost = 0 // Set on use cooldown_time = 1 SECONDS // Same as above - damage_coefficient = 1.625 + damage_coefficient = 1.75 brujah = TRUE level_current = 1 @@ -49,7 +49,7 @@ playsound(target_atom, sound, 75, TRUE) target_obj.deconstruct(FALSE) -/datum/action/cooldown/vampire/targeted/brawn/brash/fire_targeted_power(atom/target_atom) +/datum/action/cooldown/vampire/targeted/brawn/brash/fire_targeted_power(atom/target_atom, list/modifiers) . = ..() // People if(isliving(target_atom)) diff --git a/tff_modular/modules/vampire/powers/potence/brawn.dm b/tff_modular/modules/vampire/powers/potence/brawn.dm index f92645ab92d..1cf1058781d 100644 --- a/tff_modular/modules/vampire/powers/potence/brawn.dm +++ b/tff_modular/modules/vampire/powers/potence/brawn.dm @@ -8,7 +8,7 @@ Higher ranks will increase the damage when punching someone." vampire_power_flags = BP_AM_TOGGLE vampire_check_flags = BP_CANT_USE_IN_TORPOR | BP_CANT_USE_WHILE_STAKED | BP_CANT_USE_IN_FRENZY | BP_CANT_USE_WHILE_INCAPACITATED | BP_CANT_USE_WHILE_UNCONSCIOUS - vitaecost = 50 + vitaecost = 45 cooldown_time = 9 SECONDS target_range = 1 power_activates_immediately = TRUE @@ -17,7 +17,7 @@ ranged_mousepointer = 'tff_modular/modules/vampire/icons/vampire_strength.dmi' /// Only changed by the '/brawn/brash' subtype; acts as a general purpose damage multipler. - var/damage_coefficient = 1.25 + var/damage_coefficient = 1.5 /// Boolean indicating whether or not this version of '/brawn' is in the '/brash' subtype and should /// bypass typical ability level restrictions. (There is probably a better way to do this.) var/brujah = FALSE @@ -119,7 +119,7 @@ // check_witnesses() return TRUE -/datum/action/cooldown/vampire/targeted/brawn/fire_targeted_power(atom/target_atom) +/datum/action/cooldown/vampire/targeted/brawn/fire_targeted_power(atom/target_atom, list/modifiers) . = ..() var/mob/living/carbon/carbon_owner = owner @@ -189,7 +189,7 @@ // Adjust cost and cooldown if Brujah if(brujah) if(target_airlock.locked) - vitaecost = 100 + vitaecost = 80 cooldown_time = 10 SECONDS else vitaecost = 75 diff --git a/tff_modular/modules/vampire/powers/potence/lunge.dm b/tff_modular/modules/vampire/powers/potence/lunge.dm index 79480eaec06..028f310a699 100644 --- a/tff_modular/modules/vampire/powers/potence/lunge.dm +++ b/tff_modular/modules/vampire/powers/potence/lunge.dm @@ -21,12 +21,12 @@ /datum/action/cooldown/vampire/targeted/lunge/two vitaecost = 60 - cooldown_time = 10 SECONDS + cooldown_time = 8 SECONDS knockdown_bonus = 2 /datum/action/cooldown/vampire/targeted/lunge/three vitaecost = 75 - cooldown_time = 8 SECONDS + cooldown_time = 7 SECONDS knockdown_bonus = 3 /datum/action/cooldown/vampire/targeted/lunge/four @@ -72,7 +72,7 @@ owner.balloon_alert(owner, "too far away!") return FALSE -/datum/action/cooldown/vampire/targeted/lunge/fire_targeted_power(atom/target_atom) +/datum/action/cooldown/vampire/targeted/lunge/fire_targeted_power(atom/target_atom, list/modifiers) . = ..() owner.face_atom(target_atom) if(instant) diff --git a/tff_modular/modules/vampire/powers/presence/awe.dm b/tff_modular/modules/vampire/powers/presence/awe.dm index 4d796fd1be4..d9a7919df01 100644 --- a/tff_modular/modules/vampire/powers/presence/awe.dm +++ b/tff_modular/modules/vampire/powers/presence/awe.dm @@ -40,7 +40,7 @@ return FALSE if(victim.is_blind() || victim.is_nearsighted_currently()) return FALSE - if(HAS_MIND_TRAIT(victim, TRAIT_VAMPIRE_ALIGNED) || HAS_MIND_TRAIT(victim, TRAIT_UNCONVERTABLE) || IS_CURATOR(victim)) + if(HAS_MIND_TRAIT(victim, TRAIT_VAMPIRE_ALIGNED) || IS_CURATOR(victim)) return FALSE return TRUE diff --git a/tff_modular/modules/vampire/powers/presence/entrance.dm b/tff_modular/modules/vampire/powers/presence/entrance.dm index ac283d88acf..ae6a5fb480f 100644 --- a/tff_modular/modules/vampire/powers/presence/entrance.dm +++ b/tff_modular/modules/vampire/powers/presence/entrance.dm @@ -33,7 +33,7 @@ owner.balloon_alert(owner, "[carbon_target] is mindless.") return FALSE - if(HAS_MIND_TRAIT(carbon_target, TRAIT_VAMPIRE_ALIGNED) || HAS_MIND_TRAIT(carbon_target, TRAIT_UNCONVERTABLE) || IS_CURATOR(carbon_target)) + if(HAS_MIND_TRAIT(carbon_target, TRAIT_VAMPIRE_ALIGNED) || IS_CURATOR(carbon_target)) owner.balloon_alert(owner, "immune to your presence.") return FALSE @@ -51,7 +51,7 @@ return TRUE -/datum/action/cooldown/vampire/targeted/entrance/fire_targeted_power(atom/target_atom) +/datum/action/cooldown/vampire/targeted/entrance/fire_targeted_power(atom/target_atom, list/modifiers) . = ..() var/mob/living/carbon/carbon_target = target_atom @@ -83,7 +83,7 @@ owner.add_traits(list(TRAIT_MUTE, TRAIT_HANDS_BLOCKED, TRAIT_GRABWEAKNESS), TRAIT_STATUS_EFFECT(id)) owner.add_movespeed_modifier(/datum/movespeed_modifier/status_effect/entranced) owner.set_jitter_if_lower(duration) - owner.add_client_colour(/datum/client_colour/glass_colour/pink) + owner.add_client_colour(/datum/client_colour/glass_colour/pink, CLIENT_COLOR_SOURCE_VAMPIRE) owner.AddElement(/datum/element/relay_attackers) RegisterSignal(owner, COMSIG_ATOM_WAS_ATTACKED, PROC_REF(on_attacked)) return TRUE @@ -92,7 +92,7 @@ UnregisterSignal(owner, COMSIG_ATOM_WAS_ATTACKED) owner.remove_traits(list(TRAIT_MUTE, TRAIT_HANDS_BLOCKED, TRAIT_GRABWEAKNESS), TRAIT_STATUS_EFFECT(id)) owner.remove_movespeed_modifier(/datum/movespeed_modifier/status_effect/entranced) - owner.remove_client_colour(/datum/client_colour/glass_colour/pink) + owner.remove_client_colour(CLIENT_COLOR_SOURCE_VAMPIRE) to_chat(owner, span_awe("Your mind clears and you regain your focus.")) /datum/status_effect/entranced/get_examine_text() diff --git a/tff_modular/modules/vampire/powers/presence/summon.dm b/tff_modular/modules/vampire/powers/presence/summon.dm index ab5ea71bf0f..9a7c02366e6 100644 --- a/tff_modular/modules/vampire/powers/presence/summon.dm +++ b/tff_modular/modules/vampire/powers/presence/summon.dm @@ -13,8 +13,8 @@ They must be able to see you to be affected." vampire_power_flags = NONE vampire_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 - vitaecost = 100 - cooldown_time = 60 SECONDS + vitaecost = 60 + cooldown_time = 30 SECONDS target_range = 10 prefire_message = "Who will you summon to your presence?" ranged_mousepointer = 'tff_modular/modules/vampire/icons/vampire_summon.dmi' @@ -35,7 +35,7 @@ owner.balloon_alert(owner, "[carbon_target] is mindless.") return FALSE - if(HAS_MIND_TRAIT(carbon_target, TRAIT_VAMPIRE_ALIGNED) || IS_CURATOR(carbon_target) || HAS_MIND_TRAIT(carbon_target, TRAIT_UNCONVERTABLE)) + if(HAS_MIND_TRAIT(carbon_target, TRAIT_VAMPIRE_ALIGNED) || IS_CURATOR(carbon_target)) owner.balloon_alert(owner, "immune to your presence.") return FALSE @@ -57,7 +57,7 @@ return TRUE -/datum/action/cooldown/vampire/targeted/summon/fire_targeted_power(atom/target_atom) +/datum/action/cooldown/vampire/targeted/summon/fire_targeted_power(atom/target_atom, list/modifiers) . = ..() var/mob/living/carbon/carbon_target = target_atom @@ -100,7 +100,7 @@ return FALSE ADD_TRAIT(owner, TRAIT_MUTE, TRAIT_STATUS_EFFECT(id)) RegisterSignal(owner, COMSIG_MOB_CLIENT_PRE_MOVE, PROC_REF(block_player_move)) - owner.add_client_colour(/datum/client_colour/glass_colour/pink) + owner.add_client_colour(/datum/client_colour/glass_colour/pink, CLIENT_COLOR_SOURCE_VAMPIRE) start_movement() return TRUE @@ -108,7 +108,7 @@ REMOVE_TRAIT(owner, TRAIT_MUTE, TRAIT_STATUS_EFFECT(id)) UnregisterSignal(owner, COMSIG_MOB_CLIENT_PRE_MOVE) - owner.remove_client_colour(/datum/client_colour/glass_colour/pink) + owner.remove_client_colour(CLIENT_COLOR_SOURCE_VAMPIRE) if(move_loop) UnregisterSignal(move_loop, COMSIG_QDELETING) diff --git a/tff_modular/modules/vampire/powers/thaumaturgy/bloodboil.dm b/tff_modular/modules/vampire/powers/thaumaturgy/bloodboil.dm index 6803a7f56db..098c6041c16 100644 --- a/tff_modular/modules/vampire/powers/thaumaturgy/bloodboil.dm +++ b/tff_modular/modules/vampire/powers/thaumaturgy/bloodboil.dm @@ -57,7 +57,7 @@ owner.balloon_alert(owner, "[target.p_their()] blood is already boiling!") return FALSE -/datum/action/cooldown/vampire/targeted/bloodboil/fire_targeted_power(mob/living/carbon/target) +/datum/action/cooldown/vampire/targeted/bloodboil/fire_targeted_power(mob/living/carbon/target, list/modifiers) . = ..() // Just to make absolutely sure if(!iscarbon(target)) diff --git a/tff_modular/modules/vampire/powers/thaumaturgy/bloodbolt.dm b/tff_modular/modules/vampire/powers/thaumaturgy/bloodbolt.dm index e587aeabea0..64e0b52f89a 100644 --- a/tff_modular/modules/vampire/powers/thaumaturgy/bloodbolt.dm +++ b/tff_modular/modules/vampire/powers/thaumaturgy/bloodbolt.dm @@ -14,7 +14,7 @@ prefire_message = "Select your target." ranged_mousepointer = 'tff_modular/modules/vampire/icons/vampire_bloodbolt.dmi' -/datum/action/cooldown/vampire/targeted/bloodbolt/fire_targeted_power(atom/target_atom) +/datum/action/cooldown/vampire/targeted/bloodbolt/fire_targeted_power(atom/target_atom, list/modifiers) . = ..() var/mob/living/living_owner = owner // check_witnesses(target_atom) @@ -43,7 +43,7 @@ /obj/projectile/magic/arcane_barrage/vampire name = "blood bolt" icon_state = "mini_leaper" - damage = 40 + damage = 50 hitsound = 'tff_modular/modules/vampire/sound/bloodbolt.ogg' antimagic_flags = MAGIC_RESISTANCE_HOLY // var/datum/action/cooldown/vampire/targeted/bloodbolt/vampire_power diff --git a/tff_modular/modules/vampire/powers/thaumaturgy/blooddrain.dm b/tff_modular/modules/vampire/powers/thaumaturgy/blooddrain.dm index c7d153569f7..38ec2ae64ea 100644 --- a/tff_modular/modules/vampire/powers/thaumaturgy/blooddrain.dm +++ b/tff_modular/modules/vampire/powers/thaumaturgy/blooddrain.dm @@ -23,25 +23,21 @@ return FALSE ..() -/datum/action/cooldown/vampire/targeted/blooddrain/fire_targeted_power(atom/target_atom) +/datum/action/cooldown/vampire/targeted/blooddrain/fire_targeted_power(atom/target_atom, list/modifiers) . = ..() var/mob/living/living_owner = owner + var/mob/living/living_victim = target_atom living_owner.face_atom(target_atom) living_owner.changeNext_move(CLICK_CD_RANGE) living_owner.newtonian_move(get_dir(target_atom, living_owner)) playsound(living_owner, 'tff_modular/modules/vampire/sound/bloodbolt.ogg', 60, TRUE) - blood_drain(target_atom, living_owner, src) + living_victim.apply_status_effect(/datum/status_effect/blood_drain, living_owner, src) /datum/action/cooldown/vampire/targeted/blooddrain/deactivate_power() . = ..() if(!isnull(active_effect)) active_effect.end_drain() -/datum/action/cooldown/vampire/targeted/blooddrain/proc/blood_drain(mob/living/victim, mob/living/carbon/firer, fired_from) - if(!firer) - CRASH("Projectile [src] fired with no firer") //We don't even want any of the rest of this to play out if we don't have a firer - victim.apply_status_effect(/datum/status_effect, firer, fired_from) - /// /// Status Effect. Literally copied from life drain spell of wizards, but modified to work with vampires. /// diff --git a/tff_modular/modules/vampire/vassals/datum_vassal.dm b/tff_modular/modules/vampire/vassals/datum_vassal.dm index 5e236a5f8d3..933c4c81c9e 100644 --- a/tff_modular/modules/vampire/vassals/datum_vassal.dm +++ b/tff_modular/modules/vampire/vassals/datum_vassal.dm @@ -98,12 +98,6 @@ return ..() -/datum/antagonist/vassal/on_body_transfer(mob/living/old_body, mob/living/new_body) - . = ..() - for(var/datum/action/cooldown/vampire/power in powers) - power.Remove(old_body) - power.Grant(new_body) - /datum/antagonist/vassal/greet() var/mob/living/living_vassal = owner.current var/mob/living/living_master = master.owner.current diff --git a/tff_modular/strings/malkavian_revelations.json b/tff_modular/strings/malkavian_revelations.json index 7aa57375c7b..b31a3b2b4a3 100644 --- a/tff_modular/strings/malkavian_revelations.json +++ b/tff_modular/strings/malkavian_revelations.json @@ -38,7 +38,7 @@ "#Я видел Великую хартию вольностей. Я видел Око Горы.", "#Ты думаешь меня это волнует? Спроси, волнует ли это меня, потому что мне плевать! Если бы я получал 1 кредит каждый раз когда они говорят что мне не плевать, я бы был бедным, потому что мне плевать!", "#Этот 357-й калибр заставил меня двигаться, как инвазивный вид.", - "#Я делаю плохо прикосновение Мидаса.", + "#Я плох в прикосновении Мидаса.", "#Я убью тебя!", "#Подожди, дай мне сделать пару глотков.", "#Маскарад должен соблюдаться также, как хранят ядерный диск, это то что охраняет нас от того, кто снизу...", @@ -53,6 +53,12 @@ "#Если бог существует, как он позволил мне появиться?", "#...Я, кажется, потерял нить чего-то, не могу понять чего...", "#Личность которую все пытаются заткнуть, это та личность, которую все будут желать вернуть.", - "#Это твоя вина." + "#Это твоя вина.", + "#Сегодня ты нажил себе могущественного врага, чувак.", + "#Тебя любят личинки. Поверь мне.", + "#Мое величайшее оружие - знание. И глаза-лазеры.", + "#Я раскрашиваю мир красками своего безумия.", + "#Смейся, если хочешь... Но подумай вот о чем: ты такой же мертвец, как и я... Я помню, что я видел, когда был полностью и воистину мертв. Ты бы тоже сошел с ума.", + "#Я пытался превратить воду в вино. Какого хрена здесь кровь? А, ну да ладно - не пропадать же добру." ] } diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/vampiricaccident.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/vampiricaccident.ts index 908581c9f6d..7361231a9fd 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/vampiricaccident.ts +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/vampiricaccident.ts @@ -8,7 +8,7 @@ Scrape by Space Station 13, or take over it, ghoulizing your way. const VampiricAccident: Antagonist = { key: 'vampiricaccident', - name: 'Vampiric Accident', + name: 'Vampire (Midround)', description: [VAMPIRE_MECHANICAL_DESCRIPTION], category: Category.Midround, }; From d840a3b76402decde75ef55c922627314f011f02 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sun, 15 Mar 2026 20:00:10 +0300 Subject: [PATCH 055/149] gool --- tff_modular/modules/vampire/powers/feed.dm | 11 +++-------- .../vampire/powers/thaumaturgy/blooddrain.dm | 13 ++++++------- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/tff_modular/modules/vampire/powers/feed.dm b/tff_modular/modules/vampire/powers/feed.dm index 72c03f725fb..60f20703f03 100644 --- a/tff_modular/modules/vampire/powers/feed.dm +++ b/tff_modular/modules/vampire/powers/feed.dm @@ -48,7 +48,6 @@ . = ..() if(!.) return FALSE - // Already feeding if(target_ref) return FALSE @@ -175,7 +174,7 @@ currently_feeding = FALSE masquerade_breached = FALSE - if(LAZYACCESS(modifiers, LEFT_CLICK)) + if(living_owner.pulling == feed_target && !living_owner.grab_state >= GRAB_AGGRESSIVE) // Don't allow normal feed on vamps. It's too easy and feels unfair. if(IS_VAMPIRE(feed_target)) @@ -197,7 +196,7 @@ if(!IS_VASSAL(feed_target)) feed_time /= 4 - + feed_target.grabbedby(owner, FALSE) feed_target.playsound_local(null, 'tff_modular/modules/vampire/sound/mesmerize.ogg', 100, FALSE, pressure_affected = FALSE) feed_target.Stun(feed_time, TRUE) feed_target.become_blind(REF(src)) @@ -272,7 +271,7 @@ vision_distance = FEED_SILENT_NOTICE_RANGE, ignored_mobs = feed_target ) - else if(LAZYACCESS(modifiers, RIGHT_CLICK)) // COMBAT FEED BELOW HERE!!!!!!!!!! + else if(living_owner.pulling == feed_target && living_owner.grab_state >= GRAB_AGGRESSIVE) // COMBAT FEED BELOW HERE!!!!!!!!!! playsound(living_owner, 'tff_modular/modules/vampire/sound/drinkblood1.ogg', 50) @@ -316,10 +315,6 @@ // Normally removed traits are done. Now we give the victim a lil something to remember us by. feed_target.apply_status_effect(/datum/status_effect/feed_marked) - else - owner.balloon_alert(owner, "combat feed requires aggressive grab!") - deactivate_power() - return FALSE /datum/action/cooldown/vampire/targeted/feed/use_power() var/mob/living/user = owner diff --git a/tff_modular/modules/vampire/powers/thaumaturgy/blooddrain.dm b/tff_modular/modules/vampire/powers/thaumaturgy/blooddrain.dm index 38ec2ae64ea..51cf3837c68 100644 --- a/tff_modular/modules/vampire/powers/thaumaturgy/blooddrain.dm +++ b/tff_modular/modules/vampire/powers/thaumaturgy/blooddrain.dm @@ -16,7 +16,6 @@ ranged_mousepointer = 'tff_modular/modules/vampire/icons/vampire_blooddrain.dmi' var/datum/status_effect/blood_drain/active_effect - var/datum/beam/drain_beam /datum/action/cooldown/vampire/targeted/blooddrain/check_valid_target(atom/target_atom) if(!isliving(target_atom)) @@ -31,7 +30,10 @@ living_owner.changeNext_move(CLICK_CD_RANGE) living_owner.newtonian_move(get_dir(target_atom, living_owner)) playsound(living_owner, 'tff_modular/modules/vampire/sound/bloodbolt.ogg', 60, TRUE) - living_victim.apply_status_effect(/datum/status_effect/blood_drain, living_owner, src) + living_victim.apply_status_effect(/datum/status_effect/blood_drain) + active_effect = living_victim.has_status_effect(/datum/status_effect/blood_drain) + active_effect.vampire = living_owner + active_effect.spell = src /datum/action/cooldown/vampire/targeted/blooddrain/deactivate_power() . = ..() @@ -57,13 +59,10 @@ . = ..() vampire = null -/datum/status_effect/blood_drain/on_creation(mob/living/new_owner, mob/living/firer, fired_from, duration_override) - if(isnull(firer) || isnull(fired_from) || !iscarbon(firer) || !iscarbon(new_owner)) +/datum/status_effect/blood_drain/on_creation(mob/living/new_owner, duration_override) + if(isnull(vampire) || isnull(spell) || !iscarbon(vampire) || !iscarbon(new_owner)) qdel(src) return - vampire = firer - spell = fired_from - spell.active_effect = src drain_beam = vampire.Beam(new_owner, icon = 'icons/effects/beam.dmi', icon_state = "blood_drain", time = 22 SECONDS, maxdistance = 7, beam_color = COLOR_RED) RegisterSignal(drain_beam, COMSIG_QDELETING, PROC_REF(end_drain)) new_owner.visible_message(span_boldwarning("[vampire] begins draining the life force from [new_owner]!"), span_boldwarning("[vampire] is draining your life force! You need to get away from [vampire.p_them()] to stop it!")) From 5a593687f64f4c7a20aefb9c7374e1b0539a5328 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Tue, 17 Mar 2026 14:10:33 +0300 Subject: [PATCH 056/149] =?UTF-8?q?=D0=BD=D0=B5=D1=80=D1=84=20=D1=85=D0=B5?= =?UTF-8?q?=D0=B9=D1=81=D1=82=D0=B0,=20=D1=84=D0=B8=D0=BA=D1=81=20=D0=B1?= =?UTF-8?q?=D0=BB=D1=83=D0=B4=D0=B4=D1=80=D0=B5=D0=B9=D0=BD=D0=B0,=20?= =?UTF-8?q?=D1=87=D0=B8=D0=BD=D0=B8=D0=BC=20=D1=88=D0=B8=D0=B7=D1=83,=20?= =?UTF-8?q?=D0=B4=D0=B5=D0=BB=D0=B0=D0=B5=D0=BC=20=D0=B0=D1=83=D1=81=D0=BF?= =?UTF-8?q?=D0=B5=D0=BA=D1=81=20=D1=87=D1=83=D1=82=D1=8C=20=D0=B1=D0=BE?= =?UTF-8?q?=D0=BB=D0=B5=D0=B5=20=D0=BF=D0=BE=D0=BB=D0=B5=D0=B7=D0=BD=D1=8B?= =?UTF-8?q?=D0=BC,=20=D0=BD=D0=B5=D1=80=D1=84=D0=B8=D0=BC=20=D1=83=D0=B2?= =?UTF-8?q?=D0=B5=D0=BB=D0=B8=D1=87=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=80=D0=B5?= =?UTF-8?q?=D0=B3=D0=B5=D0=BD=D0=B0=20=D0=B8=20=D1=80=D0=B5=D0=B3=D0=B5?= =?UTF-8?q?=D0=BD=20=D0=B2=20=D1=86=D0=B5=D0=BB=D0=BE=D0=BC,=20=D0=BD?= =?UTF-8?q?=D0=BE=20=D0=B7=D0=B0=20=D1=82=D0=BE=20=D1=83=D0=B2=D0=B5=D0=BB?= =?UTF-8?q?=D0=B8=D1=87=D0=B8=D0=B2=D0=B0=D0=B5=D0=BC=20=D0=B1=D0=B0=D0=B7?= =?UTF-8?q?=D0=BE=D0=B2=D1=8B=D0=B9=20=D0=B8=20=D0=BC=D0=B5=D0=BD=D1=8F?= =?UTF-8?q?=D0=B5=D0=BC=20=D0=B0=D0=B1=D0=B8=D0=BB=D0=BA=D0=B8.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/__DEFINES/~ff_defines/bloodsucker.dm | 2 +- .../fluffy}/malkavian_revelations.json | 33 +++++++--- tff_modular/modules/vampire/clans/_clan.dm | 4 +- tff_modular/modules/vampire/clans/brujah.dm | 2 +- .../modules/vampire/clans/malkavian.dm | 4 +- tff_modular/modules/vampire/clans/toreador.dm | 2 +- tff_modular/modules/vampire/clans/tremere.dm | 4 +- tff_modular/modules/vampire/clans/ventrue.dm | 2 +- tff_modular/modules/vampire/datum_vampire.dm | 12 ++-- tff_modular/modules/vampire/frenzy_vampire.dm | 2 +- tff_modular/modules/vampire/life_vampire.dm | 15 ++--- .../modules/vampire/misc_procs_vampire.dm | 4 +- .../vampire/powers/auspex/astral_project.dm | 2 +- .../modules/vampire/powers/auspex/auspex.dm | 24 +++---- .../modules/vampire/powers/celerity/haste.dm | 4 +- .../vampire/powers/celerity/quickness.dm | 2 +- .../vampire/powers/dominate/dominate.dm | 6 +- tff_modular/modules/vampire/powers/feed.dm | 3 +- .../vampire/powers/thaumaturgy/blooddrain.dm | 63 ++++++++++++++----- tff_modular/modules/vampire/society.dm | 7 +-- .../modules/vampire/tracking_vampire.dm | 2 + .../modules/vampire/vassals/datum_vassal.dm | 21 +++---- 22 files changed, 129 insertions(+), 91 deletions(-) rename {tff_modular/strings => strings/fluffy}/malkavian_revelations.json (64%) diff --git a/code/__DEFINES/~ff_defines/bloodsucker.dm b/code/__DEFINES/~ff_defines/bloodsucker.dm index c2faf6fe5df..c4070d0c45e 100644 --- a/code/__DEFINES/~ff_defines/bloodsucker.dm +++ b/code/__DEFINES/~ff_defines/bloodsucker.dm @@ -52,7 +52,7 @@ /// The number that incoming levels are divided by when comitting the Amaranth. Example: 2 would divide the victims level by 2, and give that to the diablerist #define DIABLERIE_DIVISOR 1.5 /// Amount of vitae drunk from another player required to level up. -#define VITAE_GOAL_STANDARD 250 +#define VITAE_GOAL_STANDARD 150 /// Default amount of damage the vampire's punch/kick damage increases with each level. #define VAMPIRE_UNARMED_DMG_INCREASE_ON_RANKUP 1.25 diff --git a/tff_modular/strings/malkavian_revelations.json b/strings/fluffy/malkavian_revelations.json similarity index 64% rename from tff_modular/strings/malkavian_revelations.json rename to strings/fluffy/malkavian_revelations.json index b31a3b2b4a3..0bec91f7dea 100644 --- a/tff_modular/strings/malkavian_revelations.json +++ b/strings/fluffy/malkavian_revelations.json @@ -18,22 +18,22 @@ "#Что произойдет когда вся органика умрет? Вся неорганика просто останется?", "#Что бы случилось, если бы я убил члена командования?", "#Все думают что я дурак, но по крайней мере я не страшен, тогда бы они извинялись.", - "#Не забудь помолиться, чтобы получить помощь!", + "Не забудь помолиться, чтобы получить помощь!", "#Интересно, приняли бы меня таким какой я есть?", "#Здесь пришельцы, они существуют. Это не заговор. Настоящий вопрос это когда они будут атаковать нас.", "#Повреждение мозга реально, или это наш мозг адаптируется к новой реальности?", - "#Никогда не заключай сделку с дьяволом... Худшая ошибка в моей жизни.", + "Никогда не заключай сделку с дьяволом... Худшая ошибка в моей жизни.", "#Генокрады более чистая форма людей... Если бы люди были самыми нечистыми существами.", - "#Как там поживает дьявол? Давно его не видел.", + "Как там поживает дьявол? Давно его не видел.", "#Для меня это ничего не значит, парень.", - "#Я никому не лоялен, я демон.", + "Я никому не лоялен, я Демон, а мой покровитель Дьявол.", "#Я ни к кому не испытываю преданности, никогда не испытывал и не буду испытывать.", "#Коротышка решила быть с демоном, похоже это ее проблема!", "#Ты видишь, я действительно сделал это, я действительно он.", - "#Превратил кирпичик в империю, хватит играть со мной.", + "Превратил кирпичик в империю, хватит играть со мной.", "Я это он! Я был им!! Я продолжу быть им!!!", "#Они думают, что победили демона, но я вернулся!", - "#Ты не можешь верить мне, даже я не верю себе. Я даже не знаю кто я теперь.", + "Ты не можешь верить мне, даже я не верю себе. Я даже не знаю кто я теперь.", "#У них амнезия, они забыли что я был им.", "#Я видел Великую хартию вольностей. Я видел Око Горы.", "#Ты думаешь меня это волнует? Спроси, волнует ли это меня, потому что мне плевать! Если бы я получал 1 кредит каждый раз когда они говорят что мне не плевать, я бы был бедным, потому что мне плевать!", @@ -51,14 +51,27 @@ "#Если бы только все видели мир так, как вижу его я.", "#Что сделало человечество, чтобы заслужить мое существование?", "#Если бог существует, как он позволил мне появиться?", - "#...Я, кажется, потерял нить чего-то, не могу понять чего...", + "...Я, кажется, потерял нить чего-то, не могу понять чего...", "#Личность которую все пытаются заткнуть, это та личность, которую все будут желать вернуть.", - "#Это твоя вина.", + "Это твоя вина.", "#Сегодня ты нажил себе могущественного врага, чувак.", "#Тебя любят личинки. Поверь мне.", "#Мое величайшее оружие - знание. И глаза-лазеры.", "#Я раскрашиваю мир красками своего безумия.", - "#Смейся, если хочешь... Но подумай вот о чем: ты такой же мертвец, как и я... Я помню, что я видел, когда был полностью и воистину мертв. Ты бы тоже сошел с ума.", - "#Я пытался превратить воду в вино. Какого хрена здесь кровь? А, ну да ладно - не пропадать же добру." + "# Смейтесь, если хотите. Считайте, что вы намного умнее, чем несчастный сломленный сумасшедший. Неважно. Но подумайте над этим: вы — мёртвое существо, как и я. Вы умерли и возродились… вот этим. Что делает вас и меня разными? Очень просто — я помню, что видел, когда был полностью и воистину мёртв. Вы бы тоже сошли с ума.", + "#Я пытался превратить воду в вино. Какого хрена здесь кровь? А, ну да ладно - не пропадать же добру.", + "Потанцуем?", + "Должен ли я делать то, что мне назначено? Или я должен пойти в шестую дорму? Другой вопрос заключается в том, почему такое существо как я имеет столь высокое либидо.", + "Моли тебя окружают.", + "#Цимисхи - милые ребята, они так завидуют Носферату и подражают им. Что ж, если они думают, что безобразие приводит к просветлению, я с радостью помогу им. У них слишком много конечностей, на мой вкус...", + "Ты живешь на островке невезения... Смерть предъявит на тебя право...", + "Не обращайте внимания на этого человека в углу. Он просто выдуманный друг, которого я перестал выдумывать, но он обиделся и остался.", + "Не считай безумие проклятием, смертный. Для некоторых это величайшее из благ. Горькая милость, возможно, но все же милость.", + "Я видел большую лошадь. Она создала меня, а потом поскакала искать прекрасные поля, жуя морковку.", + "С концом света придут четыре всадника. Четыре коня в плащах на своих верных людях-скакунах.", + "А потом я придумаю себе хобби. Кто знает, может, воскрешение мертвых?", + "#Добро пожаловать в безумный мир, дом всех самых странных вещей...", + "#Вампиры-Социалисты хотят контролировать твой разум!", + "#Я запру тебя в мире, где ты будешь любить быть живым." ] } diff --git a/tff_modular/modules/vampire/clans/_clan.dm b/tff_modular/modules/vampire/clans/_clan.dm index 95032790ec5..84ad1fc28c0 100644 --- a/tff_modular/modules/vampire/clans/_clan.dm +++ b/tff_modular/modules/vampire/clans/_clan.dm @@ -199,7 +199,7 @@ /datum/vampire_clan/proc/finalize_spend_rank() // Level up the vampire - vampiredatum.vampire_regen_rate += 0.15 + vampiredatum.vampire_regen_rate += 0.05 vampiredatum.max_vitae += 100 /* if(ishuman(vampiredatum.owner.current)) @@ -212,7 +212,7 @@ // Flavor to_chat(vampiredatum.owner.current, span_notice("You are now a rank [vampiredatum.vampire_level] Vampire. \ - Your strength, health, feed rate, regen rate, and maximum blood capacity have all increased! \n\ + Your strength, feed rate, regen rate, and maximum blood capacity have all increased! \n\ * Your existing powers have all ranked up as well!")) vampiredatum.update_hud() diff --git a/tff_modular/modules/vampire/clans/brujah.dm b/tff_modular/modules/vampire/clans/brujah.dm index 6615ba57f8f..888b013d574 100644 --- a/tff_modular/modules/vampire/clans/brujah.dm +++ b/tff_modular/modules/vampire/clans/brujah.dm @@ -14,5 +14,5 @@ vampiredatum.owned_disciplines += new /datum/discipline/celerity(vampiredatum) vampiredatum.owned_disciplines += new /datum/discipline/potence/brujah(vampiredatum) vampiredatum.owned_disciplines += new /datum/discipline/presence(vampiredatum) - vampiredatum.owned_disciplines += new /datum/discipline/dominate(vampiredatum) + vampiredatum.owned_disciplines += new /datum/discipline/obfuscate(vampiredatum) vampiredatum.owned_disciplines += new /datum/discipline/fortitude(vampiredatum) diff --git a/tff_modular/modules/vampire/clans/malkavian.dm b/tff_modular/modules/vampire/clans/malkavian.dm index e53fe7baa34..f2195769499 100644 --- a/tff_modular/modules/vampire/clans/malkavian.dm +++ b/tff_modular/modules/vampire/clans/malkavian.dm @@ -16,7 +16,7 @@ /datum/vampire_clan/malkavian/New(datum/antagonist/vampire/owner_datum) . = ..() - vampiredatum.owned_disciplines += new /datum/discipline/auspex/malkavian(vampiredatum) + vampiredatum.owned_disciplines += new /datum/discipline/auspex(vampiredatum) vampiredatum.owned_disciplines += new /datum/discipline/obfuscate(vampiredatum) vampiredatum.owned_disciplines += new /datum/discipline/dominate(vampiredatum) vampiredatum.owned_disciplines += new /datum/discipline/fortitude(vampiredatum) @@ -49,7 +49,7 @@ return if(prob(15)) - var/message = pick(strings("antagonist_flavor/malkavian_revelations.json", "revelations", "strings")) + var/message = pick(strings("fluffy/malkavian_revelations.json", "revelations", "strings")) INVOKE_ASYNC(living_vampire, TYPE_PROC_REF(/atom/movable, say), message, , , , , , "Malkavian Revelation") COOLDOWN_START(src, revelation_cooldown, rand(REVELATION_MIN_COOLDOWN, REVELATION_MAX_COOLDOWN)) diff --git a/tff_modular/modules/vampire/clans/toreador.dm b/tff_modular/modules/vampire/clans/toreador.dm index 09d3cc8a55f..93aabcef71f 100644 --- a/tff_modular/modules/vampire/clans/toreador.dm +++ b/tff_modular/modules/vampire/clans/toreador.dm @@ -12,7 +12,7 @@ /datum/vampire_clan/toreador/New(datum/antagonist/vampire/owner_datum) . = ..() vampiredatum.owned_disciplines += new /datum/discipline/celerity(vampiredatum) - vampiredatum.owned_disciplines += new /datum/discipline/auspex(vampiredatum) + vampiredatum.owned_disciplines += new /datum/discipline/potence(vampiredatum) vampiredatum.owned_disciplines += new /datum/discipline/presence(vampiredatum) vampiredatum.owned_disciplines += new /datum/discipline/dominate(vampiredatum) vampiredatum.owned_disciplines += new /datum/discipline/obfuscate(vampiredatum) diff --git a/tff_modular/modules/vampire/clans/tremere.dm b/tff_modular/modules/vampire/clans/tremere.dm index ea67f486aff..065d5d06e2d 100644 --- a/tff_modular/modules/vampire/clans/tremere.dm +++ b/tff_modular/modules/vampire/clans/tremere.dm @@ -11,7 +11,7 @@ /datum/vampire_clan/tremere/New(datum/antagonist/vampire/owner_datum) . = ..() vampiredatum.owned_disciplines += new /datum/discipline/dominate(vampiredatum) - vampiredatum.owned_disciplines += new /datum/discipline/auspex(vampiredatum) + vampiredatum.owned_disciplines += new /datum/discipline/presence(vampiredatum) vampiredatum.owned_disciplines += new /datum/discipline/thaumaturgy(vampiredatum) - vampiredatum.owned_disciplines += new /datum/discipline/celerity(vampiredatum) + vampiredatum.owned_disciplines += new /datum/discipline/obfuscate(vampiredatum) vampiredatum.owned_disciplines += new /datum/discipline/potence(vampiredatum) diff --git a/tff_modular/modules/vampire/clans/ventrue.dm b/tff_modular/modules/vampire/clans/ventrue.dm index 02409e2b613..181205d1421 100644 --- a/tff_modular/modules/vampire/clans/ventrue.dm +++ b/tff_modular/modules/vampire/clans/ventrue.dm @@ -16,4 +16,4 @@ vampiredatum.owned_disciplines += new /datum/discipline/dominate/ventrue(vampiredatum) vampiredatum.owned_disciplines += new /datum/discipline/fortitude(vampiredatum) vampiredatum.owned_disciplines += new /datum/discipline/potence(vampiredatum) - vampiredatum.owned_disciplines += new /datum/discipline/obfuscate(vampiredatum) + vampiredatum.owned_disciplines += new /datum/discipline/celerity(vampiredatum) diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index 6ac11f17180..9fb2ffcdc72 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -92,7 +92,7 @@ /// Additional regeneration when the vampire has a lot of blood var/additional_regen /// How much damage the vampire heals each life tick. Increases per rank up - var/vampire_regen_rate = 0.45 + var/vampire_regen_rate = 0.6 /// Minimum cooldown when reviving. COOLDOWN_DECLARE(revive_cooldown) @@ -112,7 +112,7 @@ var/atom/movable/screen/vampire/humanity_counter/humanity_display /// Tracker so that vassals know where their master is - var/obj/effect/abstract/vampire_tracker_holder/tracker + // var/obj/effect/abstract/vampire_tracker_holder/tracker /// List of limbs we've applied modifications to. var/list/affected_limbs = list( @@ -196,7 +196,7 @@ RegisterSignal(current_mob, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) RegisterSignal(current_mob, COMSIG_ATOM_AFTER_EXPOSE_REAGENTS, PROC_REF(after_expose_reagents)) RegisterSignal(current_mob, COMSIG_LIVING_DEATH, PROC_REF(on_death)) - RegisterSignal(current_mob, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved)) + // RegisterSignal(current_mob, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved)) RegisterSignal(current_mob, COMSIG_HUMAN_ON_HANDLE_BLOOD, PROC_REF(handle_blood)) RegisterSignal(current_mob, COMSIG_MOB_UPDATE_SIGHT, PROC_REF(on_update_sight)) @@ -220,7 +220,7 @@ ensure_brain_nonvital(current_mob) setup_limbs(current_mob) - setup_tracker(current_mob) + // setup_tracker(current_mob) if(ishuman(current_mob)) var/mob/living/carbon/human/current_human = current_mob @@ -261,7 +261,7 @@ handle_clown_mutation(current_mob, removing = FALSE) cleanup_limbs(current_mob) - cleanup_tracker() + // cleanup_tracker() remove_hud_elements(current_mob) QDEL_NULL(blood_display) @@ -752,6 +752,7 @@ if(diablerie_count > 0 && HAS_TRAIT(examiner, TRAIT_SEE_DIABLERIE)) examine_text += span_cult_large("
    You can see the corrupted marks of a diablerist in [owner.current.p_their()] aura!") +/* /datum/antagonist/vampire/proc/on_moved(datum/source) SIGNAL_HANDLER @@ -760,6 +761,7 @@ return tracker?.tracking_beacon?.update_position() +*/ /datum/antagonist/vampire/proc/setup_limbs(mob/living/carbon/target) if(!iscarbon(target)) diff --git a/tff_modular/modules/vampire/frenzy_vampire.dm b/tff_modular/modules/vampire/frenzy_vampire.dm index f4e09b14d26..d5e2e91257d 100644 --- a/tff_modular/modules/vampire/frenzy_vampire.dm +++ b/tff_modular/modules/vampire/frenzy_vampire.dm @@ -100,7 +100,7 @@ if(vampiredatum.current_vitae >= FRENZY_THRESHOLD_EXIT) qdel(src) return - carbon_owner.adjust_fire_loss(0.75) + carbon_owner.adjust_fire_loss(0.75 + (vampiredatum.vampire_level * 0.05)) carbon_owner.set_jitter_if_lower(10 SECONDS) /datum/status_effect/frenzy/get_examine_text() diff --git a/tff_modular/modules/vampire/life_vampire.dm b/tff_modular/modules/vampire/life_vampire.dm index 017575a6de9..405646f0d57 100644 --- a/tff_modular/modules/vampire/life_vampire.dm +++ b/tff_modular/modules/vampire/life_vampire.dm @@ -70,7 +70,8 @@ var/actual_regen = vampire_regen_rate + additional_regen current.adjust_organ_loss(ORGAN_SLOT_BRAIN, -1 * (actual_regen * 4)) - + current.adjust_organ_loss(ORGAN_SLOT_EYES, -1 * (actual_regen * 4)) + current.adjust_organ_loss(ORGAN_SLOT_EARS, -1 * (actual_regen * 4)) if(!iscarbon(current)) return FALSE var/mob/living/carbon/carbon_owner = current @@ -79,7 +80,7 @@ var/healing_multiplier = 1 if(carbon_owner.on_fire) - healing_multiplier = 0.2 + healing_multiplier = 0 else if(HAS_TRAIT(carbon_owner, TRAIT_SLIME_HYDROPHOBIA)) healing_multiplier = 0.75 @@ -204,7 +205,7 @@ if(source.stat != DEAD) // weirdness shield return - COOLDOWN_START(src, revive_cooldown, 25 SECONDS) // ensure we take at minimum 25 seconds to revive. + COOLDOWN_START(src, revive_cooldown, 30 SECONDS) // ensure we take at minimum 25 seconds to revive. INVOKE_ASYNC(src, PROC_REF(handle_death)) /datum/antagonist/vampire/proc/handle_death() @@ -256,13 +257,13 @@ // The more blood, the better the regeneration if(current_vitae < BLOOD_VOLUME_BAD) - additional_regen = 0.1 + additional_regen = 0.05 else if(current_vitae < BLOOD_VOLUME_OKAY) - additional_regen = 0.2 + additional_regen = 0.1 else if(current_vitae < BLOOD_VOLUME_NORMAL) - additional_regen = 0.3 + additional_regen = 0.15 else if(current_vitae < BS_BLOOD_VOLUME_MAX_REGEN) - additional_regen = 0.4 + additional_regen = 0.2 else additional_regen = 0.5 diff --git a/tff_modular/modules/vampire/misc_procs_vampire.dm b/tff_modular/modules/vampire/misc_procs_vampire.dm index 1b4c8298e55..bf26b3a1ee3 100644 --- a/tff_modular/modules/vampire/misc_procs_vampire.dm +++ b/tff_modular/modules/vampire/misc_procs_vampire.dm @@ -328,9 +328,9 @@ /// All the descriptions: var/ventrue = "The Ventrue are the de-facto leaders of the Camarilla. They style themselves as kings and emperors, often inhabiting positions of power.\n\ IMPORTANT: Members of the Ventrue Clan are the most eligible for princedom. Please remember that princes are expected to behave in a manner befitting their office.\n\ - [disciplines]: [dominate], [fortitude], [presence]" + [disciplines]: [presence], [dominate], [fortitude], [potence], [celerity]" var/tremere = "With a powerful ancestry of wizards and magicians, the Tremere wield the secret art of blood magic, which they guard with utmost care.\n\ - [disciplines]: [thaumaturgy], [auspex], [dominate]" + [disciplines]: [dominate], [presence], [thaumaturgy], [obfuscate], [potence]" var/toreador = "Artists, Pleasure-workers, Celebrities. These are the people of the Toreador clan. They are by far the closest to humanity of all kindred, each a deeply sensitive individual.\n\ [disciplines]: [presence], [auspex], [celerity]" var/malkavian = "Completely insane. You gain constant hallucinations, become a prophet with unintelligable rambling, and gain insights better left unknown. You can also travel through Phobetor tears, rifts through spacetime only you can travel through.\n\ diff --git a/tff_modular/modules/vampire/powers/auspex/astral_project.dm b/tff_modular/modules/vampire/powers/auspex/astral_project.dm index e759048784e..1dc59437625 100644 --- a/tff_modular/modules/vampire/powers/auspex/astral_project.dm +++ b/tff_modular/modules/vampire/powers/auspex/astral_project.dm @@ -9,7 +9,7 @@ button_icon_state = "power_astral_projection" vampire_power_flags = BP_AM_TOGGLE vampire_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 - vitaecost = 200 + vitaecost = 150 cooldown_time = 60 SECONDS /datum/action/cooldown/vampire/astral_projection/activate_power() diff --git a/tff_modular/modules/vampire/powers/auspex/auspex.dm b/tff_modular/modules/vampire/powers/auspex/auspex.dm index 68948b67edc..4317b9125fd 100644 --- a/tff_modular/modules/vampire/powers/auspex/auspex.dm +++ b/tff_modular/modules/vampire/powers/auspex/auspex.dm @@ -7,25 +7,22 @@ // Lists of abilities granted per level level_1 = list(/datum/action/cooldown/vampire/auspex) level_2 = list(/datum/action/cooldown/vampire/auspex/two) - level_3 = list(/datum/action/cooldown/vampire/auspex/three) - -/datum/discipline/auspex/malkavian - level_4 = list(/datum/action/cooldown/vampire/astral_projection) + level_3 = list(/datum/action/cooldown/vampire/auspex/three, /datum/action/cooldown/vampire/astral_projection) /datum/action/cooldown/vampire/auspex name = "Auspex" desc = "Sense the vitae of any creature directly, and use your keen senses to widen your perception." button_icon_state = "power_auspex" - power_explanation = "- Level 1: When Activated, you will be able to sense walls and the layout of rooms, and, upon examining a fellow Kindred, be able to tell if they have committed Diablerie. \n\ + power_explanation = "- Level 1: When Activated, you will be able to see other peoples warrants and ID, and, upon examining a fellow Kindred, be able to tell if they have committed Diablerie. \n\ - Level 2: When Activated, You will be able to see health of your victims. \n\ - - Level 3: When Activated, you will be able to sense anything in sight, seeing and hearing through walls and barriers as if they were glass." + - Level 3: When Activated, you will be able to sense anything in sight, hearing through walls and barriers as if they were air. You also can enter a trance, and being able to talk to ghosts." vampire_power_flags = BP_AM_TOGGLE | BP_AM_STATIC_COOLDOWN vampire_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 vitaecost = 10 constant_vitaecost = 1 cooldown_time = 10 SECONDS var/add_medical = FALSE - var/add_meson = TRUE + var/add_security = TRUE var/add_xray = FALSE var/see_diablerie = TRUE var/looking = FALSE @@ -34,17 +31,12 @@ name = "Auspex" vitaecost = 40 constant_vitaecost = 2 - add_meson = TRUE - see_diablerie = TRUE add_medical = TRUE /datum/action/cooldown/vampire/auspex/three name = "Auspex" vitaecost = 30 constant_vitaecost = 3 - add_medical = TRUE - add_meson = TRUE - see_diablerie = TRUE add_xray = TRUE /datum/action/cooldown/vampire/auspex/activate_power() @@ -68,11 +60,11 @@ if(see_diablerie) ADD_TRAIT(owner, TRAIT_SEE_DIABLERIE, REF(src)) - if(add_meson) - ADD_TRAIT(owner, TRAIT_MESON_VISION, REF(src)) + if(add_security) + ADD_TRAIT(owner, TRAIT_SECURITY_HUD, REF(src)) if(add_xray) - owner.add_traits(list(TRAIT_XRAY_VISION, TRAIT_XRAY_HEARING), REF(src)) + ADD_TRAIT(owner, TRAIT_XRAY_HEARING, REF(src)) owner.update_sight() @@ -80,5 +72,5 @@ SIGNAL_HANDLER looking = FALSE - owner.remove_traits(list(TRAIT_SEE_DIABLERIE, TRAIT_MESON_VISION, TRAIT_XRAY_VISION, TRAIT_XRAY_HEARING, TRAIT_MEDICAL_HUD), REF(src)) + owner.remove_traits(list(TRAIT_SEE_DIABLERIE, TRAIT_SECURITY_HUD, TRAIT_XRAY_HEARING, TRAIT_MEDICAL_HUD), REF(src)) owner.update_sight() diff --git a/tff_modular/modules/vampire/powers/celerity/haste.dm b/tff_modular/modules/vampire/powers/celerity/haste.dm index 59bc6b4b292..d87b374232d 100644 --- a/tff_modular/modules/vampire/powers/celerity/haste.dm +++ b/tff_modular/modules/vampire/powers/celerity/haste.dm @@ -25,8 +25,8 @@ level_current = 2 /datum/action/cooldown/vampire/targeted/haste/three - vitaecost = 45 - cooldown_time = 2 SECONDS + vitaecost = 30 + cooldown_time = 4 SECONDS level_current = 3 /datum/action/cooldown/vampire/targeted/haste/can_use() diff --git a/tff_modular/modules/vampire/powers/celerity/quickness.dm b/tff_modular/modules/vampire/powers/celerity/quickness.dm index a3cbd073165..b0c6f1c468f 100644 --- a/tff_modular/modules/vampire/powers/celerity/quickness.dm +++ b/tff_modular/modules/vampire/powers/celerity/quickness.dm @@ -8,7 +8,7 @@ vampire_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 cooldown_time = 30 SECONDS vitaecost = 25 - constant_vitaecost = 1.5 + constant_vitaecost = 1 /datum/action/cooldown/vampire/exactitude/can_use() diff --git a/tff_modular/modules/vampire/powers/dominate/dominate.dm b/tff_modular/modules/vampire/powers/dominate/dominate.dm index 1e336aa484c..6f4a99518de 100644 --- a/tff_modular/modules/vampire/powers/dominate/dominate.dm +++ b/tff_modular/modules/vampire/powers/dominate/dominate.dm @@ -11,5 +11,7 @@ level_5 = null /datum/discipline/dominate/ventrue - level_3 = list(/datum/action/cooldown/vampire/targeted/mesmerize/three, /datum/action/cooldown/vampire/targeted/command) - level_4 = list(/datum/action/cooldown/vampire/targeted/mesmerize/four, /datum/action/cooldown/vampire/targeted/command/two) + level_1 = list(/datum/action/cooldown/vampire/targeted/mesmerize/two) + level_2 = list(/datum/action/cooldown/vampire/targeted/mesmerize/three) + level_3 = list(/datum/action/cooldown/vampire/targeted/mesmerize/four, /datum/action/cooldown/vampire/targeted/command/two) + level_4 = null diff --git a/tff_modular/modules/vampire/powers/feed.dm b/tff_modular/modules/vampire/powers/feed.dm index 60f20703f03..434c58121a4 100644 --- a/tff_modular/modules/vampire/powers/feed.dm +++ b/tff_modular/modules/vampire/powers/feed.dm @@ -173,7 +173,8 @@ currently_feeding = FALSE masquerade_breached = FALSE - + if(!living_owner.pulling) + return if(living_owner.pulling == feed_target && !living_owner.grab_state >= GRAB_AGGRESSIVE) // Don't allow normal feed on vamps. It's too easy and feels unfair. diff --git a/tff_modular/modules/vampire/powers/thaumaturgy/blooddrain.dm b/tff_modular/modules/vampire/powers/thaumaturgy/blooddrain.dm index 51cf3837c68..044c23dc174 100644 --- a/tff_modular/modules/vampire/powers/thaumaturgy/blooddrain.dm +++ b/tff_modular/modules/vampire/powers/thaumaturgy/blooddrain.dm @@ -8,7 +8,7 @@ You must maintain line of sight to the victim for the effect to continue." vampire_power_flags = BP_AM_TOGGLE vampire_check_flags = BP_CANT_USE_IN_TORPOR | BP_CANT_USE_WHILE_STAKED | BP_CANT_USE_IN_FRENZY | BP_CANT_USE_WHILE_INCAPACITATED | BP_CANT_USE_WHILE_UNCONSCIOUS - vitaecost = 50 + vitaecost = 75 cooldown_time = 10 SECONDS // Very unlikely to ever last past 10 seconds even if the actual duration is longer. Combat is a fuck. target_range = 7 power_activates_immediately = FALSE @@ -17,29 +17,57 @@ var/datum/status_effect/blood_drain/active_effect -/datum/action/cooldown/vampire/targeted/blooddrain/check_valid_target(atom/target_atom) - if(!isliving(target_atom)) - return FALSE - ..() - -/datum/action/cooldown/vampire/targeted/blooddrain/fire_targeted_power(atom/target_atom, list/modifiers) +/datum/action/cooldown/vampire/targeted/blooddrain/fire_targeted_power(atom/target_atom) . = ..() var/mob/living/living_owner = owner - var/mob/living/living_victim = target_atom + /* var/mob/living/living_target = target_atom + check_witnesses(living_target) */ living_owner.face_atom(target_atom) living_owner.changeNext_move(CLICK_CD_RANGE) living_owner.newtonian_move(get_dir(target_atom, living_owner)) - playsound(living_owner, 'tff_modular/modules/vampire/sound/bloodbolt.ogg', 60, TRUE) - living_victim.apply_status_effect(/datum/status_effect/blood_drain) - active_effect = living_victim.has_status_effect(/datum/status_effect/blood_drain) - active_effect.vampire = living_owner - active_effect.spell = src + + var/obj/projectile/magic/blood_drain/drain = new(living_owner.loc) + drain.firer = living_owner + drain.fired_from = src + drain.aim_projectile(target_atom, living_owner) + if(isliving(target_atom)) + drain.original = target_atom + drain.set_homing_target(target_atom) + drain.def_zone = ran_zone(living_owner.zone_selected) + INVOKE_ASYNC(drain, TYPE_PROC_REF(/obj/projectile, fire)) + + playsound(living_owner, 'sound/effects/magic/wandodeath.ogg', 60, TRUE) /datum/action/cooldown/vampire/targeted/blooddrain/deactivate_power() . = ..() if(!isnull(active_effect)) active_effect.end_drain() +/obj/projectile/magic/blood_drain + name = "vitality draining stream" + icon_state = "nothing" + range = 7 + antimagic_flags = MAGIC_RESISTANCE_HOLY + hitsound = 'tff_modular/modules/vampire/sound/bloodbolt.ogg' + var/datum/beam/drain_beam + +/obj/projectile/magic/blood_drain/fire(angle, atom/direct_target) + if(!firer) + CRASH("Projectile [src] fired with no firer") //We don't even want any of the rest of this to play out if we don't have a firer + drain_beam = Beam(firer, icon = 'icons/effects/beam.dmi', icon_state = "drain_life", time = 10 SECONDS, maxdistance = 7, beam_type = /obj/effect/ebeam/blood, beam_color = COLOR_RED) + return ..() + +/obj/projectile/magic/blood_drain/on_hit(mob/living/carbon/target, blocked, pierce_hit) + . = ..() + if(isliving(target)) + target.apply_status_effect(/datum/status_effect/blood_drain, firer, fired_from) + +/obj/projectile/magic/blood_drain/Destroy() + if(!QDELETED(drain_beam)) + qdel(drain_beam) + drain_beam = null + return ..() + /// /// Status Effect. Literally copied from life drain spell of wizards, but modified to work with vampires. /// @@ -59,11 +87,14 @@ . = ..() vampire = null -/datum/status_effect/blood_drain/on_creation(mob/living/new_owner, duration_override) - if(isnull(vampire) || isnull(spell) || !iscarbon(vampire) || !iscarbon(new_owner)) +/datum/status_effect/blood_drain/on_creation(mob/living/new_owner, mob/living/firer, fired_from, duration_override) + if(isnull(firer) || isnull(fired_from) || !iscarbon(firer) || !iscarbon(new_owner)) qdel(src) return - drain_beam = vampire.Beam(new_owner, icon = 'icons/effects/beam.dmi', icon_state = "blood_drain", time = 22 SECONDS, maxdistance = 7, beam_color = COLOR_RED) + vampire = firer + spell = fired_from + spell.active_effect = src + drain_beam = vampire.Beam(new_owner, icon = 'icons/effects/beam.dmi', icon_state = "drain_life", time = 22 SECONDS, maxdistance = 7, beam_type = /obj/effect/ebeam/blood, beam_color = COLOR_RED,) RegisterSignal(drain_beam, COMSIG_QDELETING, PROC_REF(end_drain)) new_owner.visible_message(span_boldwarning("[vampire] begins draining the life force from [new_owner]!"), span_boldwarning("[vampire] is draining your life force! You need to get away from [vampire.p_them()] to stop it!")) . = ..() diff --git a/tff_modular/modules/vampire/society.dm b/tff_modular/modules/vampire/society.dm index 6830952ac71..7a795d88669 100644 --- a/tff_modular/modules/vampire/society.dm +++ b/tff_modular/modules/vampire/society.dm @@ -47,8 +47,7 @@ SUBSYSTEM_DEF(vsociety) // Build a poll_config datum to match the new polling API currently_polling = TRUE - var/icon/prince_icon = icon('tff_modular/modules/vampire/icons/vampiric.dmi', "prince") - prince_icon.Scale(24, 24) + var/icon/prince_icon = icon('tff_modular/modules/vampire/icons/actions_vampire.dmi', "power_awe") var/list/pollers = SSpolling.poll_candidates( "You are eligible for princedom.", poll_time = 3 MINUTES, @@ -66,13 +65,13 @@ SUBSYSTEM_DEF(vsociety) currently_polling = FALSE var/datum/antagonist/vampire/chosen_datum - var/mob/living/chosen_candidate + var/mob/living/carbon/chosen_candidate // We have to do this shit because the polling proc doesn't always return a list. Sometimes it just returns a mob. var/list/candidates = list() candidates += pollers - for(var/mob/living/current_candidate in candidates) // Pick the ideal one from the list. + for(var/mob/living/carbon/current_candidate in candidates) // Pick the ideal one from the list. var/datum/antagonist/vampire/current_datum = IS_VAMPIRE(current_candidate) if(!chosen_candidate) // If we are the first in line, just be the prince by default diff --git a/tff_modular/modules/vampire/tracking_vampire.dm b/tff_modular/modules/vampire/tracking_vampire.dm index 99f4ee3ca87..7bb7c02bf74 100644 --- a/tff_modular/modules/vampire/tracking_vampire.dm +++ b/tff_modular/modules/vampire/tracking_vampire.dm @@ -1,3 +1,4 @@ +/* /datum/antagonist/vampire/proc/setup_tracker(mob/living/body) cleanup_tracker() tracker = new(body, REF(src)) @@ -32,3 +33,4 @@ tracking_beacon.toggle_visibility(FALSE) QDEL_NULL(tracking_beacon) . = ..() +*/ diff --git a/tff_modular/modules/vampire/vassals/datum_vassal.dm b/tff_modular/modules/vampire/vassals/datum_vassal.dm index 933c4c81c9e..d4d4bfd94fc 100644 --- a/tff_modular/modules/vampire/vassals/datum_vassal.dm +++ b/tff_modular/modules/vampire/vassals/datum_vassal.dm @@ -16,7 +16,7 @@ /// List of Powers, like Vampires. var/list/datum/action/powers = list() /// A link to our team monitor, used to track our master. - var/datum/component/team_monitor/monitor + // var/datum/component/team_monitor/monitor /datum/antagonist/vassal/antag_panel_data() return "Master : [master.owner.name]" @@ -27,7 +27,6 @@ RegisterSignal(current_mob, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) RegisterSignals(current_mob, list(COMSIG_MOB_LOGIN, COMSIG_MOVABLE_Z_CHANGED), PROC_REF(on_login)) - RegisterSignal(current_mob, COMSIG_MOB_UPDATE_SIGHT, PROC_REF(on_update_sight)) current_mob.update_sight() @@ -35,7 +34,7 @@ add_team_hud(current_mob) // Tracking - setup_monitor(current_mob) + // setup_monitor(current_mob) current_mob.grant_language(/datum/language/vampiric, source = LANGUAGE_VASSAL) current_mob.faction += FACTION_VAMPIRE @@ -46,11 +45,11 @@ . = ..() var/mob/living/current_mob = mob_override || owner.current - UnregisterSignal(current_mob, list(COMSIG_ATOM_EXAMINE, COMSIG_MOB_LOGIN, COMSIG_MOVABLE_Z_CHANGED, COMSIG_MOB_UPDATE_SIGHT)) + UnregisterSignal(current_mob, list(COMSIG_ATOM_EXAMINE, COMSIG_MOB_LOGIN, COMSIG_MOVABLE_Z_CHANGED)) current_mob.update_sight() // Tracking - QDEL_NULL(monitor) + // QDEL_NULL(monitor) current_mob.remove_language(/datum/language/vampiric, source = LANGUAGE_VASSAL) // Remove traits @@ -64,6 +63,7 @@ CRASH("[owner.current] was vassilized without a master!") ADD_TRAIT(owner, TRAIT_VAMPIRE_ALIGNED, REF(src)) + ADD_TRAIT(owner, TRAIT_NIGHT_VISION, REF(src)) vampire_team = master.vampire_team vampire_team.add_member(owner) @@ -82,7 +82,7 @@ /datum/antagonist/vassal/on_removal() REMOVE_TRAIT(owner, TRAIT_VAMPIRE_ALIGNED, REF(src)) - + REMOVE_TRAIT(owner, TRAIT_NIGHT_VISION, REF(src)) // Free them from their Master if(master) master.vassals -= src @@ -198,6 +198,7 @@ antag_hud.show_to(target) hud.show_to(antag_hud.target) +/* /datum/antagonist/vassal/proc/setup_monitor(mob/target) QDEL_NULL(monitor) if(QDELETED(master?.owner?.current) || QDELETED(master.tracker)) @@ -206,6 +207,7 @@ monitor = target.AddComponent(/datum/component/team_monitor, REF(master)) monitor.add_to_tracking_network(master.tracker.tracking_beacon) monitor.show_hud(target) +*/ /datum/antagonist/vassal/proc/on_examine(datum/source, mob/examiner, list/examine_text) SIGNAL_HANDLER @@ -220,13 +222,6 @@ text += span_cult("This is [master.return_full_name()]'s vassal") examine_text += text -// Vassals get night vision, so they can at least somewhat be useful to their masters in dark areas without revealing themselves with a flashlight or something. -// The night vision is weaker than true night vision like a vampire has, but it's still better than mesons. -/datum/antagonist/vassal/proc/on_update_sight(mob/user) - SIGNAL_HANDLER - user.lighting_cutoff = max(user.lighting_cutoff, round((LIGHTING_CUTOFF_HIGH + LIGHTING_CUTOFF_MEDIUM) / 2, 1)) - user.lighting_color_cutoffs = user.lighting_color_cutoffs ? blend_cutoff_colors(user.lighting_color_cutoffs, list(25, 8, 5)) : list(25, 8, 5) - /// Used when your Master teaches you a new Power. /datum/antagonist/vassal/proc/grant_power(datum/action/cooldown/vampire/power) powers += power From 943fbb7235f500a34afd7f8da62c5efcc9786cbb Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Tue, 17 Mar 2026 14:14:46 +0300 Subject: [PATCH 057/149] =?UTF-8?q?=D0=BF=D0=B0=D1=80=D1=83=20=D1=84=D0=B8?= =?UTF-8?q?=D0=BA=D1=81=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tff_modular/modules/vampire/clans/malkavian.dm | 2 +- tff_modular/modules/vampire/misc_procs_vampire.dm | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/tff_modular/modules/vampire/clans/malkavian.dm b/tff_modular/modules/vampire/clans/malkavian.dm index f2195769499..006204122fb 100644 --- a/tff_modular/modules/vampire/clans/malkavian.dm +++ b/tff_modular/modules/vampire/clans/malkavian.dm @@ -20,7 +20,7 @@ vampiredatum.owned_disciplines += new /datum/discipline/obfuscate(vampiredatum) vampiredatum.owned_disciplines += new /datum/discipline/dominate(vampiredatum) vampiredatum.owned_disciplines += new /datum/discipline/fortitude(vampiredatum) - vampiredatum.owned_disciplines += new /datum/discipline/celerity(vampiredatum) + vampiredatum.owned_disciplines += new /datum/discipline/presence(vampiredatum) vampiredatum.owner.current.playsound_local(get_turf(vampiredatum.owner.current), 'sound/music/antag/creepalert.ogg', 80, FALSE, pressure_affected = FALSE, use_reverb = FALSE) to_chat(vampiredatum.owner.current, span_hypnophrase("Welcome, childe of Malkav...")) diff --git a/tff_modular/modules/vampire/misc_procs_vampire.dm b/tff_modular/modules/vampire/misc_procs_vampire.dm index bf26b3a1ee3..cd9857495ed 100644 --- a/tff_modular/modules/vampire/misc_procs_vampire.dm +++ b/tff_modular/modules/vampire/misc_procs_vampire.dm @@ -332,13 +332,11 @@ var/tremere = "With a powerful ancestry of wizards and magicians, the Tremere wield the secret art of blood magic, which they guard with utmost care.\n\ [disciplines]: [dominate], [presence], [thaumaturgy], [obfuscate], [potence]" var/toreador = "Artists, Pleasure-workers, Celebrities. These are the people of the Toreador clan. They are by far the closest to humanity of all kindred, each a deeply sensitive individual.\n\ - [disciplines]: [presence], [auspex], [celerity]" + [disciplines]: [celerity], [potence], [presence], [dominate], [obfuscate]" var/malkavian = "Completely insane. You gain constant hallucinations, become a prophet with unintelligable rambling, and gain insights better left unknown. You can also travel through Phobetor tears, rifts through spacetime only you can travel through.\n\ - [disciplines]: [dominate], [auspex], [obfuscate]" - var/gangrel = "Often mistaken as werewolves, Gangrel carry the smell of wet dog wherever they go. Their unique bond with the beast within allows them to transform parts of their body into powerful claws, even becoming entirely different beings.\n\ - [disciplines]: [animalism], [protean], [fortitude]" + [disciplines]: [auspex], [obfuscate], [dominate], [fortitude], [presence]" var/brujah = "A clan now, of mostly rebels. Though some still show fragments of their lost lineage of warrior-poets. They are long split from the Camarilla, and often form their own groups.\n\ - [disciplines]: [potence], [celerity], [presence]" + [disciplines]: [celerity], [potence], [presence], [dominate], [fortitude]" // Now the logic switch(clan_name) From 9283418218044f1fb8cd80b2093d980e20eb7c3d Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Tue, 17 Mar 2026 14:17:05 +0300 Subject: [PATCH 058/149] Update misc_procs_vampire.dm --- tff_modular/modules/vampire/misc_procs_vampire.dm | 2 -- 1 file changed, 2 deletions(-) diff --git a/tff_modular/modules/vampire/misc_procs_vampire.dm b/tff_modular/modules/vampire/misc_procs_vampire.dm index cd9857495ed..d57266cf8a3 100644 --- a/tff_modular/modules/vampire/misc_procs_vampire.dm +++ b/tff_modular/modules/vampire/misc_procs_vampire.dm @@ -350,8 +350,6 @@ return malkavian if(CLAN_TREMERE) return tremere - if(CLAN_GANGREL) - return gangrel log_runtime("Unknown clan name passed to get_clan_description: [clan_name]") return "No description available." From 6c219e0e166e29c5431d3edefd1fa264c6d9db37 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Tue, 17 Mar 2026 14:21:53 +0300 Subject: [PATCH 059/149] Update misc_procs_vampire.dm --- tff_modular/modules/vampire/misc_procs_vampire.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tff_modular/modules/vampire/misc_procs_vampire.dm b/tff_modular/modules/vampire/misc_procs_vampire.dm index d57266cf8a3..a8280557de3 100644 --- a/tff_modular/modules/vampire/misc_procs_vampire.dm +++ b/tff_modular/modules/vampire/misc_procs_vampire.dm @@ -314,7 +314,7 @@ /datum/antagonist/vampire/proc/get_clan_description(clan_name) /// This makes descriptions about a billion times cleaner: Spans for discipline names and their individual descriptions: var/disciplines = "[span_tooltip("Disciplines are the aspects of the original curse bestowed upon caine, of which every kindred suffers/benefits. In terms of gameplay, they are groups of abilities that you level up.", "Disciplines")]" - var/animalism = "[span_tooltip("Animalism is a Discipline that brings the vampire closer to their animalistic nature. This typically allows them to communicate with and gain dominance over creatures of nature.", "Animalism")]" + // var/animalism = "[span_tooltip("Animalism is a Discipline that brings the vampire closer to their animalistic nature. This typically allows them to communicate with and gain dominance over creatures of nature.", "Animalism")]" var/auspex = "[span_tooltip("Auspex is a Discipline that grants vampires supernatural senses, letting them peer far further and deeper than any mortal. The malkavians especially have a strong bond with it.", "Auspex")]" var/celerity = "[span_tooltip("Celerity is a Discipline that grants vampires supernatural quickness and reflexes.", "Celerity")]" var/dominate = "[span_tooltip("Dominate is a Discipline that overwhelms another person's mind with the vampire's will.", "Dominate")]" @@ -322,7 +322,7 @@ var/obfuscate = "[span_tooltip("Obfuscate is a Discipline that allows vampires to conceal themselves, deceive the mind of others, or make them ignore what the user does not want to be seen.", "Obfuscate")]" var/potence = "[span_tooltip("Potence is the Discipline that endows vampires with physical vigor and preternatural strength.", "Potence")]" var/presence = "[span_tooltip("Presence is the Discipline of supernatural allure and emotional manipulation which allows Kindred to attract, sway, and control crowds.", "Presence")]" - var/protean = "[span_tooltip("Protean is a Discipline that gives vampires the ability to change form, from growing feral claws to turning into something entirely different.", "Protean")]" + // var/protean = "[span_tooltip("Protean is a Discipline that gives vampires the ability to change form, from growing feral claws to turning into something entirely different.", "Protean")]" var/thaumaturgy = "[span_tooltip("Thaumaturgy is the secret blood-art of the clan tremere. Allowing them all manners of blood-sorcery and pacts.", "Thaumaturgy")]" /// All the descriptions: From 03a914cb290815e31f588f74ab7da2be6ce90852 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Tue, 17 Mar 2026 14:47:09 +0300 Subject: [PATCH 060/149] =?UTF-8?q?=D1=83=D0=BB=D1=83=D1=87=D1=88=D0=B0?= =?UTF-8?q?=D0=B5=D0=BC=20=D0=BF=D1=80=D0=B8=D1=81=D1=83=D1=82=D1=81=D1=82?= =?UTF-8?q?=D0=B2=D0=B8=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tff_modular/modules/vampire/powers/obfuscate/cloak.dm | 4 ++-- tff_modular/modules/vampire/powers/obfuscate/trespass.dm | 2 +- tff_modular/modules/vampire/powers/obfuscate/veil.dm | 2 +- tff_modular/modules/vampire/powers/presence/awe.dm | 4 ++++ tff_modular/modules/vampire/powers/presence/entrance.dm | 5 ++++- .../modules/vampire/powers/presence/force_of_personality.dm | 3 +++ tff_modular/modules/vampire/powers/presence/presence.dm | 2 +- tff_modular/modules/vampire/powers/presence/summon.dm | 4 ++++ 8 files changed, 20 insertions(+), 6 deletions(-) diff --git a/tff_modular/modules/vampire/powers/obfuscate/cloak.dm b/tff_modular/modules/vampire/powers/obfuscate/cloak.dm index 77b75681bef..5a0e7922b05 100644 --- a/tff_modular/modules/vampire/powers/obfuscate/cloak.dm +++ b/tff_modular/modules/vampire/powers/obfuscate/cloak.dm @@ -6,8 +6,8 @@ Additionally, while Cloak is active, you are completely invisible to silicons." vampire_power_flags = BP_AM_TOGGLE vampire_check_flags = BP_CANT_USE_IN_TORPOR | BP_CANT_USE_WHILE_STAKED | BP_CANT_USE_IN_FRENZY | BP_CANT_USE_WHILE_UNCONSCIOUS - vitaecost = 50 - constant_vitaecost = 1 + vitaecost = 40 + constant_vitaecost = 2 cooldown_time = 5 SECONDS var/cloaklevel = 70 diff --git a/tff_modular/modules/vampire/powers/obfuscate/trespass.dm b/tff_modular/modules/vampire/powers/obfuscate/trespass.dm index 3404cab6d98..39c6e1c65b7 100644 --- a/tff_modular/modules/vampire/powers/obfuscate/trespass.dm +++ b/tff_modular/modules/vampire/powers/obfuscate/trespass.dm @@ -7,7 +7,7 @@ Higher levels decrease the sound played from using the Power, and increase the speed of the transition." vampire_power_flags = BP_AM_TOGGLE vampire_check_flags = BP_CANT_USE_IN_TORPOR | BP_CANT_USE_WHILE_STAKED | BP_CANT_USE_WHILE_INCAPACITATED | BP_CANT_USE_WHILE_UNCONSCIOUS - vitaecost = 30 + vitaecost = 40 cooldown_time = 8 SECONDS prefire_message = "Select a destination." ranged_mousepointer = 'tff_modular/modules/vampire/icons/vampire_trespass.dmi' diff --git a/tff_modular/modules/vampire/powers/obfuscate/veil.dm b/tff_modular/modules/vampire/powers/obfuscate/veil.dm index ed2b78417b1..694bab8b0ef 100644 --- a/tff_modular/modules/vampire/powers/obfuscate/veil.dm +++ b/tff_modular/modules/vampire/powers/obfuscate/veil.dm @@ -7,7 +7,7 @@ vampire_power_flags = BP_AM_TOGGLE vampire_check_flags = BP_CANT_USE_IN_FRENZY | BP_CANT_USE_WHILE_STAKED vitaecost = 100 - constant_vitaecost = 4 + constant_vitaecost = 0.5 cooldown_time = 10 SECONDS var/datum/dna/original_dna diff --git a/tff_modular/modules/vampire/powers/presence/awe.dm b/tff_modular/modules/vampire/powers/presence/awe.dm index d9a7919df01..ec5a4fbf3a2 100644 --- a/tff_modular/modules/vampire/powers/presence/awe.dm +++ b/tff_modular/modules/vampire/powers/presence/awe.dm @@ -16,6 +16,10 @@ /// The range of the aura in tiles var/aura = 5 +/datum/action/cooldown/vampire/awe/two + constant_vitaecost = 1 + aura = 6 + /datum/action/cooldown/vampire/awe/activate_power() . = ..() to_chat(owner, span_notice("You extend your supernatural presence."), type = MESSAGE_TYPE_INFO) diff --git a/tff_modular/modules/vampire/powers/presence/entrance.dm b/tff_modular/modules/vampire/powers/presence/entrance.dm index ae6a5fb480f..53bd9f7136a 100644 --- a/tff_modular/modules/vampire/powers/presence/entrance.dm +++ b/tff_modular/modules/vampire/powers/presence/entrance.dm @@ -19,6 +19,9 @@ target_range = 7 prefire_message = "Who will you entrance?" ranged_mousepointer = 'tff_modular/modules/vampire/icons/vampire_entrance.dmi' + var/ignore_shielding = FALSE + +/datum/action/cooldown/vampire/targeted/entrance/two /datum/action/cooldown/vampire/targeted/entrance/check_valid_target(atom/target_atom) . = ..() @@ -45,7 +48,7 @@ owner.balloon_alert(owner, "[carbon_target] is already entranced.") return FALSE - if(carbon_target.get_eye_protection() >= FLASH_PROTECTION_WELDER) + if(carbon_target.get_eye_protection() >= FLASH_PROTECTION_WELDER && !ignore_shielding) owner.balloon_alert(owner, "[carbon_target] has too much eye protection.") return FALSE diff --git a/tff_modular/modules/vampire/powers/presence/force_of_personality.dm b/tff_modular/modules/vampire/powers/presence/force_of_personality.dm index 1c1d0cbd505..5356ce85ce6 100644 --- a/tff_modular/modules/vampire/powers/presence/force_of_personality.dm +++ b/tff_modular/modules/vampire/powers/presence/force_of_personality.dm @@ -15,6 +15,9 @@ var/aura_range = 7 var/deactivate_timer +/datum/action/cooldown/vampire/force_of_personality/two + constant_vitaecost = 1 + /datum/action/cooldown/vampire/force_of_personality/activate_power() . = ..() to_chat(owner, span_notice("You project an overwhelming sense of authority."), type = MESSAGE_TYPE_INFO) diff --git a/tff_modular/modules/vampire/powers/presence/presence.dm b/tff_modular/modules/vampire/powers/presence/presence.dm index e6151021a73..9ba5948d72e 100644 --- a/tff_modular/modules/vampire/powers/presence/presence.dm +++ b/tff_modular/modules/vampire/powers/presence/presence.dm @@ -6,4 +6,4 @@ level_2 = list(/datum/action/cooldown/vampire/targeted/entrance, /datum/action/cooldown/vampire/targeted/summon) level_3 = list(/datum/action/cooldown/vampire/awe, /datum/action/cooldown/vampire/targeted/entrance, /datum/action/cooldown/vampire/targeted/summon) level_4 = list(/datum/action/cooldown/vampire/awe, /datum/action/cooldown/vampire/targeted/entrance, /datum/action/cooldown/vampire/targeted/summon, /datum/action/cooldown/vampire/force_of_personality) - level_5 = null + level_5 = list(/datum/action/cooldown/vampire/awe/two, /datum/action/cooldown/vampire/targeted/entrance, /datum/action/cooldown/vampire/targeted/summon/two, /datum/action/cooldown/vampire/force_of_personality/two) diff --git a/tff_modular/modules/vampire/powers/presence/summon.dm b/tff_modular/modules/vampire/powers/presence/summon.dm index 9a7c02366e6..af9d45db445 100644 --- a/tff_modular/modules/vampire/powers/presence/summon.dm +++ b/tff_modular/modules/vampire/powers/presence/summon.dm @@ -22,6 +22,10 @@ /// Maximum duration of the summon effect var/summon_duration = 30 SECONDS +/datum/action/cooldown/vampire/targeted/summon/two + vitaecost = 30 + cooldown_time = 20 SECONDS + /datum/action/cooldown/vampire/targeted/summon/check_valid_target(atom/target_atom) . = ..() if(!.) From 9a9367150e0fb3622c279620622e23b948e4a788 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Tue, 17 Mar 2026 17:31:52 +0300 Subject: [PATCH 061/149] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D1=8F=D0=B5=D0=BC=20=D0=B7=D0=BE=D0=BD=D1=82=D0=B8=D0=BA,=20?= =?UTF-8?q?=D1=83=D0=B4=D0=B0=D0=BB=D1=8F=D0=B5=D0=BC=20=D0=BB=D0=B8=D1=88?= =?UTF-8?q?=D0=BD=D0=B5=D0=B5,=20=D0=9C=D0=95=D0=97=D0=9C=D0=95=D0=A0?= =?UTF-8?q?=D0=90=D0=99=D0=97,=20=D0=9C=D0=95=D0=97=D0=9C=D0=95=D0=A0?= =?UTF-8?q?=D0=90=D0=99=D0=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../greyscale_configs/greyscale_items.dm | 19 +++++++++++ strings/fluffy/malkavian_revelations.json | 15 ++++++++- tff_modular/modules/vampire/datum_vampire.dm | 2 ++ tff_modular/modules/vampire/icons/hud.dmi | Bin 17150 -> 354 bytes .../modules/vampire/objects/umbrellas.dm | 31 ++++++++---------- .../vampire/powers/dominate/mesmerize.dm | 18 ---------- 6 files changed, 49 insertions(+), 36 deletions(-) diff --git a/code/datums/greyscale/config_types/greyscale_configs/greyscale_items.dm b/code/datums/greyscale/config_types/greyscale_configs/greyscale_items.dm index fa9440e8c1c..b1bce212302 100644 --- a/code/datums/greyscale/config_types/greyscale_configs/greyscale_items.dm +++ b/code/datums/greyscale/config_types/greyscale_configs/greyscale_items.dm @@ -360,3 +360,22 @@ name = "MOD Soul Core" icon_file = 'icons/obj/clothing/modsuit/mod_construction.dmi' json_config = 'code/datums/greyscale/json_configs/mod_core_soul.json' + +// TFF ADDITION START + +/datum/greyscale_config/umbrella + name = "Umbrella" + icon_file = 'tff_modular/modules/vampire/icons/umbrellas.dmi' + json_config = 'code/datums/greyscale/json_configs/_umbrella.json' + +/datum/greyscale_config/umbrella_inhand_left + name = "Held Umbrella, Left, Closed" + icon_file = 'tff_modular/modules/vampire/icons/umbrellas_inhand_lh.dmi' + json_config = 'code/datums/greyscale/json_configs/_umbrella_inhand.json' + +/datum/greyscale_config/umbrella_inhand_right + name = "Held Umbrella, Right, Closed" + icon_file = 'tff_modular/modules/vampire/icons/umbrellas_inhand_rh.dmi' + json_config = 'code/datums/greyscale/json_configs/_umbrella_inhand.json' + +// TFF ADDITION END diff --git a/strings/fluffy/malkavian_revelations.json b/strings/fluffy/malkavian_revelations.json index 0bec91f7dea..48a1785685b 100644 --- a/strings/fluffy/malkavian_revelations.json +++ b/strings/fluffy/malkavian_revelations.json @@ -72,6 +72,19 @@ "А потом я придумаю себе хобби. Кто знает, может, воскрешение мертвых?", "#Добро пожаловать в безумный мир, дом всех самых странных вещей...", "#Вампиры-Социалисты хотят контролировать твой разум!", - "#Я запру тебя в мире, где ты будешь любить быть живым." + "#Я запру тебя в мире, где ты будешь любить быть живым.", + "#Кто-то отправится на небеса, а кто-то просто умрет.", + "Всегда оставайся человеком. Даже если ты не человек.", + "Сострадание - не слабость. Это хорошая черта.", + "#Цикл вновь повторяется. Ты снова тут. Как и в прошлый раз.", + "Солнце для нас встаёт там, где скажут имеющие власть.", + "#Если бы в уравнении было лишнее звено, то тебя бы не было. Ты кому-то точно нужен.", + "Времена меняются. Например, почти никто больше не здоровается за руку. Её ведь так сложно вытянуть.", + "#Любви тут давно нет. Бог покинул это место.", + "#Тюрьма - не содержание. Это изысканная казнь скукой с вариантами для выхода.", + "#Не обращайся к Богу за помощью - он может тебе ответить не так, как хотелось бы.", + "#От Божьей Кары не убежать - она на божественных скоростях.", + "Маленький ствол - это не так уж и плохо. Конечно, было бы лучше, чтобы у офицера его вообще не было...", + "Умение правильно делать паузы - то, что отделяет одних от других." ] } diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index 9fb2ffcdc72..96e2cf389fc 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -332,6 +332,8 @@ /datum/crafting_recipe/candelabrum, /datum/crafting_recipe/bloodthrone, /datum/crafting_recipe/meatcoffin, + /datum/crafting_recipe/umbrella_parasol, + /datum/crafting_recipe/umbrella, )) // Set name and reputation diff --git a/tff_modular/modules/vampire/icons/hud.dmi b/tff_modular/modules/vampire/icons/hud.dmi index e38837333a62732cb7f8d4a8134c2aec7a05621e..da5a0fe7768876ceac10a3ae1bd2a95a8c22d98d 100644 GIT binary patch literal 354 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJf~t^+5|`BCk`dUf|#NQ2JV7 z7o!N!?zNsSjv*1PZ>JyRJ!HVcpx+a4levVg!boJXfr$T%h0I4@aXoC*4xOry`&onk zckC42hG~i6mho>)oF4Qt-zt_0>x;2B~%iu@qHCqp;FeapZ{&f0trB=s@w6m6;AO@!6isYyTn& zarY3jHL~mkVQ01bmQp}kBhI9AC-h=@YcngWNPX&9RaFPoJ~ z<-5ZXTbI#$ga#_<&b@~wpC>OYl*l&bl{_AqROXPO zVc(8?`K*88@+Nz3gfnRbVl0oZ3jr64Ix=@2^7woDJPa{0HtKC!R{ii%+-^F#P+|`? z{yXWg_fjKbd9^Vu`w*Ho{c&tWx>2`cKTY6}rV7Hp3H2ta*Y7Fd_kS+-?k+XPd*DJLCQ_-E=w##cW=c-dAm41gkc_X5__L<$n>bmXxXJ>2$yW+#@ z;%D}GYF++{z*#!ahmX2!)QjTfiV1Kz;zLWG+gBs1!3JhN z^<|F}IX+cqrSW~@jB`9!e@1A{o1^UN_3pke*J&_c#lEwti7A^R9N(Q$cr@q{qSi#m zd20p1nD4S{+93fB2tK171pe#%TJ=Mx4Cb}$kk8x8uWgHDuF-Jla;@{k1c&O z^FieB&3ZxXC4;8#JXiiQ?yi!f|He+ZiSrLpiS&eRDG zQ_67k2~*RtM#;Rq@|)>aU2W2pB&lw#s7xjGtgqs-?U&qGO0s#^zI(d;5R=k$935mP zL>v`m^V({;GBeCCXzMrl`<+vd8ZLuBtV9_q-<0^e#PLu^;?cE;jlH)%(puBXyG|7f zVHdM*h;^d&zbtxwV%8hxTaC+&X%y0Mmn&iD7D)}BZhe^iKnmMu(Z%3(w~CQPSNCJf7pe!7sp2jRA7^-$&eI`}1+I2tCsT!doP8~r znGoyW{wSh*!*UMga<12F-g1M9rl@ih9toDu-L(DX*M4tGR^t*OR3|CY@?ukPQgREO z;HOe^`ltSFCGH>QOah2zxZCMEJHz=FdnrS@Jvj98L7D)Kho@4!B0K1p(eF*OvKOz6P&^MET=59VWHefyZ#J%o|c>yiXfNG!?P~3poP#rpG5$^#E1>=-6Vz$YA4y$_-0-)pYUc<0}c zdYD+lWG-*C0re&$AC|_zvxMV@o;qH4hlk$svI)|DRb=1U(~(xlb=TBQ$#MAB_4-x5 zk=ClCjkr@bd6QuOw`8%(ajVYM#)saT(&f(d2C1DvH_g%l; zy2Wzl^QOU$?zK?)5xc53!?%TWLd{5sL-E86VlbT3AfIdz_v7;s_Fgu@;3cCi0{MPQ z`$f#nmuhcm)NDT;)wdi|$`X6mEyd6CeeAnSg39uczKQ*S_=5_PTgtM72gt(tvMcn~ny`j>rT6lTf%>#COnn11I=B4#hcA9`eo zWkX_ljSB)TCrbi@Vf|1CU8st%3?v-}{)oQGoo(S`X;i%!yTzUCG8NCh#qk}uDfW$} z0XJ$_xns}%>d@m7tm`fp_E8D;ksopY!wNmdLE<>lp=*G#1bZbh(OU+x#>^`#eZ8*P zJy{1)|CT+SBIAcI)N(%zUP;oKR%mkGsT8c7;t87sC|R28o@iN9{4-K-12o0J(06k zTn)$^zVYv$`7P3eKbT*D$NF)?BL!b;9@xAV%ekpEp8FqOMnwuf171GU$(i|kzF(5D zv;ArocV4=~zn3b>y*WOUA1P=Jm;r91AUaS0?b!z)5EDxi2=q)2L<^b$(Omj(Cl1s% ziay(IkWsUO9YGvPP5AXgqI%+=VkSo?#BXC zD9U2T`ot;`Lq4u>giw<{HA)&&yVbBBbrg*Yk`QVK_9NQAo<@3o+t{;ay8tUYY?A3Y zKD*VkpmH1Q@IEY;x?RR^Lw!#okS9de80e!m2Yk&(Q1x&Ap5$Th3N zshBm0o9z;nS^+zFn~d{Z`TGV5J@t*aF|yfBw7QW(eAZ_WPkzWO3AH9s#ib0;nN{`W z{;PRy^Loc~XwMZA)0AIsg$CSh@L(eezj4$rnZ=5W=?c&Jc#Qo+y!0Fpbbx?+T?iux zBpJ%{|9=GjZ$sUPC4EMBKTajjDt3CMl1*?=rQTAznMQGm=JqOz(J-s1GGT65$C^gc zJ5FWtHK77e;uf!5|A-@qnjZr`%2M}-)S*3gNl`1?{f7}*nHB5)ch~2gn9_|a)+xUS zcl!Iv>jwvSw!T>$hM4ifJ|4X)Uytf|U#311{VFq+C<{8yoC5XTMr2L#; z7%pHXaBeAkbf9o)!Px5@Q_4u2XT}dB3vQRIwXUu_NlJ~|>HxIl%Fy4SpimG!H<$B- z(cW9NDi2XXZRg|J39z9z&4ZcB+NBtA$eVOBv$peiWBC_Diu?`g0CRqr~ zn74$nnj+wY`e82Gnv<*9Q*0KGDn=5n%$jDRfGra2WHrNlZ|5)? zJVuMu#yy2L1t`=f#OCZ1eFLqg%&QnuLVI~ic|nvIMDcw8FP^*&;yBdzc$n7X3(td@ zuXvvCI9eWQe45VkO$S0ipiI+D_+>+xH`E;s7~h9N%8Y&}aWxuUOw_bx9$qd$QJ;o2d z7@S&696!@xN#37!>N)qih7f2^kBBb(LDO--;S!;g{<+LYDL>AJMRQJhWnb{M-vM~o zzz@@*K|U$zf5Hy}?Op<8{r|`A{YS0akIxF#ow9kf;cL4oF2faB<9{Ohcogk6a=7;s zh3`lwI^xC2ojrQ!Ee$o3Vf4xR&UHM*6LU|9uzYWC2XaU1v=_x&Y7J{lkF5u8Dh(P} z+*N}2nUu=IE6rMi2hxK|c&RFTahV+|aMTIj{EiZ=e%nTAkSbGgZ=dDT=%L>+ren>C zUDhF+(pI>s>U~1)Fe%?VA`t?s$nMDmavgjM4aN|X{THrBa^}mRt6stPn>R8IJW9NU z_gVJwq=S>uqBo0^P>UC+N@ED# zr>`E0zU_uo>*Ls;hTbnX#(|e+b~*bipeN1d3F{{mpOE9$`itNrzf(T{VUEgVVo}V< zDxe-4d+rm~1Y44u2JJR*sJV8jF&5-D#)Lf?h|AKl1b=hIAx$|ZO7NP*@PI`ooNyw2f!t51AYVFvjD z+F%@HilS0J{z}6cWKOqk9K0a&Z3EJ3*Vh=+?#HM${UpCG;}y|b)$465UZG- zLc1yBRr+Mi1VpSN6GduxJmM$8I}AQe$XZU1e!A7@`reL=>a2)H9(IjaCD0%KGVBWd zC_rS&8ZvR`_}G_W{apGt(e}iP<-W7KbaD@lh_N~X$kpn;2~(|{?W*hTC4n92mA^O| z#IUjbv-l)|>&rtAj5KInjd6r|4Zj?|+9E({)|T!3G`b`ActM~A*6H&XK_G^6rXUda z%>WvZa{!1Q)I@WJxh9p)*fp5;Ebf=FJN*bQB*^+zud7PNIWB}T-9T!mM zO#U5T^R(RW33&-Too4li4`N(DcD)3Q+6MTTD6Z>pPQ+o9any}m@7()qeyg035+3a< z<}}?9fj5&{37~Wl0ENjoRhkAgk#JaC)fzWVQU1NB`FYF|WJO{~F)|0A8}#8r+S2>* zP*^{2%xi4XVA*_cReGN^cgT9-a`xFlV%V?KBzL|>&c?$Ay8)inqEsT*VRz4 z?u41jc3FS5`Qc)>OFbvNcVBuYY~*sDw(>r-BiEtg-83@<>?U;Y9#CaQd3pJO9Z6hj=D$)GPCW;?qerlrx(~~=7}5p`@hxjU#}}d@LbY%uEk%nN>E-=51Zi{9F2$77}S+u_NV7 zA~_YJ1T4lG_Rpn-zPMGl09ScuU~o^VprmB<UFo)&)9hGyx=;E zzeTgj((gOz1#7kaZq8Glca%i0QFRtWwhDaurhsLFN4%(7aDu9*q>1(?^D8BbJH_)q zMIBduVLA9coUc{YFH5rS{K^N45M!EBXl2V1c1vJnT_W)#`YCXXPXcJJx! zR}lkW`4pbGt-Kk*U{sW)>FqEjRV*!`+xlW2Day9Cca)yq$#kC(5*6QKmO3l*v3YxI z)ew@JR8AhJcrvm*_qyG| z|6EA%X;*4)Nm{oH!?Q-h^44l=+%_F`*7}XhpNXPx|&7~$f zYdBfoeE$5^L~;!FcYX3ZL!+X)I%hjDv>iiOExH``T5@GumtUzcovW}WYl^LCWGuHj z7zpD)JVvkK5;r`&Hl3g&P(4K&v;}@3IpdjnHljsF+*P7t_>HR>_Nb$A-b`XHh&BavZjX$5+|5L4_Jcl_U`^^^QZi@T{@bm^(_mvTyDv)p>V% z<^Pet&52V#KMAipuft14<9tG&IG~hORJ4tai)*s@6oU0gH-=*))S18x)q)b2Zj?Cr zxfeLXo|MU2r*9cB;tp7vR(61Pv~@h{*zW7y6ujI?seNErQoF>-$nljU%+}g^I24lV zi17Mj+W77S8>=Sf(*)n2_Sv#9s-FF3u0FKXn;atw+Pp6QmP{mQ*{^B}5ildt`Jc3K zubEzoiHX?`rHAO}3*Vto@IpOLDr*^xAo@9gdI0zb_juPRo7qfVD+V_ommklIpAvM|b7L zGXS&^khl)#pQFxxex;WJCh-khh}*vYM?}%H@5{bNJnZGW1UjeC{ZenW(bO#;?& z`Ni3bpxK^8@22Jqt3GPoH-8Zh5DQNZU#QJ%RfRJklGkk}V5`#?dS@`6z#w5e?+KtnQxEesvZ?rQ5ZNsGBVOdIGvR4xvGgj0b$$hE%lDt zo&gQ86|$Sf#m5(vmHn~o;s^UCh(bz!{=5Z{Y=4DaQ=jWZiSi zVaAD!Wd^+NbB)ADFC!x(1slx_KhLT-)%XA(&cWw;@gi%A{4cpj7{1oOnz~tGsU0|4 zWIGTQR64?Ejmc3>oU1zz0=pM9^f^;KmZ$CS zl;F~$_sri@>iB|a7KCIYXhywEo>-g*9Y=tIudQaNoTKgZJo}(%J0!JYiXp%^=8(qs zS955-T%w~cH@82z<*|R3Xv%?B%&Lx8dvuFaz)Sy?D=1+RU`HGrJ~V;DXfGjmLQNeu z@b_~2@#$5s3`uoi;=Lb=|BRwacE?WEqg_rZ`1$nfg8c@W#eOm`ry)TjqtduN;bD#6 zd%fJ1R0GQl8lAR=HacDS)o;sj0@YG>noP&@?j6ae8_@ENjP7}YZ*eM-D>=}^bZ>9t zuIP?k?TETJ`RLCl%f47OLG03f-n@x~jbUE*K-DQ`gH3kotuo&YIw=B%%J*?#w75bG zN7#YzCZ*uY+E{sRC`?GI7uovEf+Q+GVQPc(1&E-NkzV0tnaH+&Tj6Al#yKr?V&6lBaC z;%64^r-jV0%4E1Cr`f|&DO3VQ$-+2BUv4p?eHIx<-u6D1xE} z$**?>!t1Cy9MDHrMeX9r%!0dwbgUPNhP3}+6d_~L(?by5y_&A=!Wqj)7 z_jjK@S**@WR;Yb`SJ=WqQ9K_KH%sbqs4@-{oG9=gp6dutDi|d+y7~}Wr71ilbv<^r{YU5t zRAVoqHt)yHHWp&&b@$e2>`B;D_o_kROoe=4kncMcp{qQdj4dMKST=ENyB z7CmgmMzxy%ymjWkA|Cc)g7VW#x{@WT>+y}hocMxdSi1(ldP$dTD|iXubuIk4=Uw#A z&wl@T_x*b~yTiEk`!JukLVWfGKVLmA%<`J4_;g!)u*Fq~FXb8KUY82ley*nOZjcX! zrSf61lUNF@E~||zB^L*G^lnl&j6F9wFq(5$ zO?G!?0ac0}sCI$~8@MI23D>E?;rK-PS|LB;YHrd4v(F_cqOGyppO+IB3C5K@BK0dj z!$k&1bRos(S?{h4X@D847{~8R{TXtp2-mZ`*Bj60{V?s82GwUhu`;wC{`X9Y&Sq=4g zeU5L^f<}6cKJk-6_9q2ayfNWpz3NRbG6_*&<`qz?n-{NMjf>_iMt10IiDQmt@nO8EV|yzT(2M!B_m^WD^tWh8 zt$mbUk8=z@D4F{~KKt4O&kcPJM@`aUjtEnO8aC>!jS~d0k-A~~*q%|`YOc#GkhpFo zdvs*(5L0>h-E89SYG5>Yl;lV3By~>5r5xLL<_{9V{7`g^=(k&sg)zL3UH}`+;4}e^ zwEO1Ov=fbST%sn6*F|OAgpKKLX#WoPw$Y_AtOKbi8*SJRBIKj6wICH+S;{`q#5>^z zEP-x2DSR=%cDa7({o(>^A#aP1AH}=pc&2o6Hz3yIS|x9bJJ@=YE*)0qrc%?}3BBfq zFwqJA2|hkV6J`~8SBErY|1j{vicIR);ggOET3T9#Xl}8I$z(S0?rZ{*;~i!mO7LRr(_# z5!)AjDS7DY-3S>uA&9pzWpI>EuVjg4x#dZgh3*}Z@A-xa$95uUakjN5S$?C{DTlou zwz^`3`{?LhHKG|!1=*+no)fr>Pj*g$L9IUq_-#g`Us6%Dy(G0{X_!r6iAuv|#gc~0 z3}2I>Zb0bmYvHcdX(&hnSRei?QG@?IDp%?#HwpsXm^#e`IEC$gcq*bg+kW2lOJ2}4U-Or7hV#4DeodK-y{w|$xa%pF-0)^u0|0Cee&HnhJYaLS&iZ$k4tsSDRIe2 zeFRmvs=-S}{s2;`p7buM2#EVs4J}tBev9vTZ#GFWf9^*jNDb3&GHoV3Rk9M*n=SIc z|Nd&^*3p*z*lfKreA;WXqQp@%q(T4CNokPstNvL&dM)k+dB=Qe7-qJy49`+ftU1>8 z%JEO;UtP&)Oc{pFX10Co%c!sKN&`O?)o|4`4*T^Uo@M=HEssvPpx_E(p{HkFeGN=S zwBcsVAY-rmRG@7VGp0w=Pwn7$)l;mi{2%z5U(USaXHsRr3mPE1omfy?c84vP)=C;p zL2{H;FJ>=G?X^cC{C&sB`{a+!$l>APtkVY&=);gB^H_L$L)#atx3AN5N@e7cR zl$r~~&HAl){u`cz)Ps`GBI48EmkNJ$SV!=8h5H!MF@mhMLV|yMyklQcCJ9V=M{ZREAnEFow!OjJ{6S4&j$Y{JJ$k`q!C4gw_ zWB)&ejyvro4=og8t#$XWG@n|IL&pC!-uEo5p%WtE*(#BCnT{ntCH(_U-RnAvr*{j+iSXA zFW!eHKfGI8a_@`3eKQfI3-KG_FfYPvt?%Tf(E3v#jr%8PXjdG&>?7#x?fD`~dXiH~ z+xxO*^Rlr$CcNVNGQBo4zhCbk>MpiE9eREFj^pDEN@Vi&w1$_$gvOVzEQ1@Fi`@@dHCZ(u zmb`cG2Jwb;ZAVs0gO<7k+#Ocpl8 zU4-!%nelA!1oIDo^Q^2k=(+Y=cki6_tYojNIGL`7O-i|*><4@*72ekjNuBS-M)|cU zA1|=D{Xiwo-VqJHFywztqw}|&zdW%);_r^}LSS9EA~T&OkRB_r$|*E5B7HX103viJ zmD7LKPD6O$nozY0^pQ*b$uk?!qv>hne_niSVGI7D1z;dIH(Q8{?RyK`_ZCda z=$d?9C)5Q=i?P~3g4PmEG}kEh^&ns)a=y5PC%A}{CQRsF!I`F}Dm+5{2d?#^J7f57 z@R2$odSg!6{4X>AwCWV)dAy~5T_UI#Sn_sUq75a;t0N1p(A)tv|`~PX=rzs`^F9rgA z^@MtMY2@!3(QG9>Rr=5Qsl&dcM_>c7*wF&?*YW=1gynF2|?*3+}TU>!8J86*A zxga}std{2(qG1Q?<6RqZadEwNvpleW!=jWl9gK~;QGb5@f)f)TC_K=ExlGN)`VEEW z8lGmyC6^;=yehN&b5sDl>~EW@{kf^R+FHYBhcOQYHDZyxIQYZm9LIAFEM4y3K7Wpw zHGEfDeT$Bc*yB;ZvD1o)fBnJomhaGu+X8|-kiTp!^9bfUHDYSXIkzf|+c|D;6#ol8 zw(lTqfdxSA?kU9(k8x(GZI9XU^TlS|Fk5^bR$UpO~a(5rh zPRMbrr$7lp_bW94p5JdsS>c8qKC;=l&VCRg;MZ)mwd3lF8ya+gv8=N`$C(lSGQ!r@ zmS0fff@xgn9ejdY%r@cLvCLF(@GyzaqvZL1NNV6LsYI~!(b*f(qVH5)99BnEzF?6` znyxZepv-!im3!CUkB~dtih&UMjC6F^pk$ng%v*?zW$Xc$tmaZH zGaTzwhkjSThR?t-2P4q?3SMi&`9PSk)pNg0(PUtt`Q+!h|)+UwC}uVG)^$vijn zrjjvo%i#^eq_J|g*B$CJF9pv^u+z0`#ct_2gz&aCXILi;(vBnd<&eG13nKV4N3$H3 zuZaqiec!*wlv8R6`x*Xr4c2pGdVPR%?F;eArM~Zh8wa~7w+%dd{4L*ZJ@G=7&T^=%{JUL%*bI*DymlK zPTh{nnuyWxFn}G4$4eDc$y)+_=eJH++-i5`dUaQGQWDk+E(Wzw07GzZ=?>xy(|$m) zalo+e38gGK@zu0^KV?Up*Qc%R>fz6+rF+&?TdVwR2BTQBbYZbp-Cdui(2q^{wK-0c zl!mNV;;#n2?o?{@Q`p+1o8@=k-`t?&dT$#q6S!I5hz3S$&V;z@(DJZx{ zxK*^f+cxXjD=|~r+B6rNteO&{HgnYI+I29w5j%g#pYKBmh}PVDl4a5h+oYpYZ^3-= z^35=Ltu8}UD$IXvmQKqQ_KJCAAVXo}nti-~a~zCk?29P}7XGhCHgM2TwM{F%5P{61 zj=L+h7{ix>a%iQW{+m`V?>j?^1MgnIRDY|xar!_0!SqGW|Mn33e~jg?-0=9+(&B#? zixM^z^BLY6Ctz&@i-~Zz(Kr2*#!in$xg`5~h#Vv6lw+R(zx^$#2gf8o03V3MS)DpQ z;NYR1xowAL`A*`vJ1 z_EnU*U-<+eQC15L7#2Lmd#|OK*Ir?DeH^Mf_(3UJX-!-II@AyB*3Y??NK3C|mA{DM zZCB{_OIM6Ttgf*`YQej>^5O=h(HHWC;$cWbjXG)5 zM|%QUn?%|nXo_AWoD4LI&n42{eT_iGs>`ZLdS_d$i6Mhr zwtZ}EvtHM_8N^ktTU?BMk@r~!7b#lu2Ne=wTP35~oaR*O?<}=zxI(iYvPIU)$+Azc z@U8W~?BP-sv?Z!YePrRI?GPt2Wbuzd>W*d5LW)BC9gy%iU9K?Ec4Ytg?Zt@l)i4R1)QQaSiVF;YU}FUg*L^-l|S5c z869|WB-?QRGRhOfwKeNCN1Jx2NN> z+8$l$M-V%0`pz72^(55a6ILSnZyctMLQoCAZ5y|;g&l-aWel;F{px8KnPR{vCq(5{ z0%PcQ+?5`TI6sp2LEfDp4X%VEl!d53aE6_&yyJ}eg6{=I87h=_L~3>~`t~GkxPVZ^inW*rG*ryd7!_Y=`=23XQ(789eZV zma&PZVWk%)-_N(#!s8Tgioes|m#hE!B*dPXQPueOm{f5k>XAEN9VkZZgbq#LZ=z`k6zI@I#05#xVWr zhwj#OQk_>(l!3=IDaNO&6ja8rqLEI~7TE9z(n0OkRn<1Vn*QQ*NS;Fs;sr#S9?e2N zg{H7WL9``V{j>)P)y3kAoi7u8P@%I{E!BRZ66mc07*5pSA|#!+#ow=m{rTAkyYikF zjUk4!LVrjbOc4zi$?gDIr;moVgpjiB@chVwIY^{@wv{7*JN6Q;L)3HX>OMYhqPCd&zp7L7%@|71QkmCFq*nYZ1a!U+C$!J9VI|C7!XNza!)Zzk( z_$(FCkw6S2{YndveZBC#Iq=YDm-n#h1j5EG;miPQ`5o&+p)-_ic?LU@fymq>&%hC@ z?0eL|Qbib1UZqIKse)1k>!WSj-UQVC9X}ElHwr9xdFADgrl9y@;?aC`@d$c%D#mS- zHj~hHb@ga*5I$sA<-C4zbPZhLm`ZN~&7Z?S5S`fxwnGGr-P&bEYy4<2;Ds$DnKFxU zv^|$%>lXg>dpP@qb)ANK+WMz_7ol0!BCzA+GyE)95p1YVr8vZ?l;VdUt-1h#Hpwyd zh+R$P>At~eK3#Jgb}VCND1%cabVPFH0+B1p!qWmzm;b)gw}z{BOcl8lglLmC{bAU3 zwfn~PlDobSeUConXr#-IwuTVL@qoC+<7JIf1q04QZi+u-=2&T;_9qq3Ph8MxVed2s z+&)JUtd!+tl$;|FfY}GFvY$S0-UjIRhhFLji4MqYtLw>$FNQd6&lQpnd=h5p>dpg9 zioZBIGsR1D$xRFRrV(&?-LxQ*tubxKCO_)mb6x>b;2)f2{9h8^2V_KA3U&?B^F+i) zW&hmDu`VRO{k87*lfI*WCl~*`gEulIg&-fRcQQK=9YY-U)P{x7j(v|WL`rLzARUZz zx`9pq`=@LV!`fNFvH+0Er6K?DrCJ->9EcpKIacrTPx_vey`JMM$H`^%Y0Nl6d<-8#O1uOL!l9G`6F1Magw?TG+HbS=mKF*qP)hqm((_4`o5 z=ut-sYW;mOtn6WIx(b(TJ>#)Q!}A-PGz_icSd3SiwE2gKZ>zg$rCA@r*H1AkwSCb1 z0a&Z{!|&PxZ+E3zK}kOHVlQYrINhBm1v_kaYW!9|v4(ThqpAB%=l6rk_D%%Q{@^j) z(-vxnTVjewHJk#~5+_Xej$)qDI(+@Y^8+HJ#bv||Q|7uqy!8g;$?xlD7UWD6g5mkD zdM!e3>BDx_z>Zcl3%u2fpbHdKVC%r>+31nyM>&Tlsob#bm#^7*VGq_d&kVc=W#K$8 z2NX{%+yohSjnVg@sX7j&Z_rbq=|sN8lFjqLxez*ubpn8=)%eg18lm}R{ucgt1@)W> zIPbBCRzKTE4eqsI$*OGra}mUD9hfZU=5-FL_<4AX&a*_xraN-EYfAga+g}aem$&bY z&FoO`xYtMSHqS@rI#j=fEVhS>L+DZl@zvfZ6z!%@+p|Z)CUi{uZyZq97W<5*xYy$T zfS?ifLvr@2&ofR(PT(KBb;zmhn{1nEClJbZks`d}PDHY{fk2f`A%d;JI_8yRuAcvhGKL~a+ zGNl7G^u-0G0lg9uyFL`z)v_w20lT>RQ3L zeC1;tEl5swVirj228!c>JUE~Wt9hAGeG{!d2jf=qyw}Ku(vRnZU$C+nr~Jj<01Hyh zbKn3X#yNEqKLHx)odT&CbZqXD{}6HD2_YZI60I*t7mbo!v;H`!Bv7?;O_7U>uVF_3 zNKjk8#%>4XqwP9gFJ|Nt3o;g4E&TEYp7p#sViZU}b2D)%6SE)t;kQ`IAPppf=w_d0 zRZ~Zos+=^_iNm?F^5t85{go5Qozl$W;WU@PZ~lWCf%J@nK-qWxt*r%hM+9_Tp96t@0I5vaA0~}Zo7QCf{z1DZzmh1XWHh)MSEh*rKs`8K_Io_y>B01jJ%t!pct^<-GE>6`8c^8qSQ^ z{%R%aIRt`F>VY~KZJ5Bx%K;T5o=_$Z(7@h?Ue$nIXgrAE zia_m;#eP_!3-oMfZ10wsNmorvDWlv17H^RKxch|u#E5GzFZkel)}^6<`ymTJ z;!w`*P>@FmpEF2C|9#jutap>0NW5nd)l#dsacZArCMn^FaSq79%cX~8HSE%5~Zpkd%R!yw1}@A=NA=QukR00uVy7oO-%Zvgen z01$Y}zv3}`)*x@7!wa7q7-xXCY8=miZbo}wNmmEXWI5-{FARjs9Yrul%W1M~ysG`c-X9v+lwM zSJBCihNq$%+Lkr2kIxmwFi}^tOdK!cP{#0m_Hc);q7LdYjYN+!D4pE>rqSEcZ?2E~ zcCXUO&=&ebUgU0)P2c|nx?GP5?Xa~&T7Rc(N>HYH!nY^(?UC>-aW+2<)+o4+EGYm; zsXA(wf^{*|0#pxz+15}+D`og#OJj6JMv@j zM9so&Lc(g}+=C+-oY`Z?VXkmgE>NlH^)`T*wlbkoGBW&89g}NL6i9HIt{5~Rx3tJR zOgBh)lMuI~tgm&N?fRf185!Z@X-4#iG@Tj;A}z|yQxdNX%F%IyFL79@GFS5nzn;&0 zlSA5xUo0uHylcOK3jM%_MQ4-_wFTl2t-pBG&(mmMPuzw!rztT{@b=n!cWLYCjZLy5 zhc1e6K9B?IzjtrKaQB=ENQd^>wsZn_Fpq6U%rXqs<8Y_uWIGYks>YO9 zlf9D!-Qd6sQW)g=IgV%B*c@*tQUi42By9_Lc7NwrQ^j6zd|}1iM1}c-@mp8OSeoI` zkMoLxi<1c67E0WJ%=p0|Uja9yBxC-{p-@KxKB6bbZuN$Ts2piL+CQuP5La!WWm`L; zZ}Pl+*)SHxEN4=FrD;5e^UDns>dVfTP?iJWc#(Y&!fCOBd1d=8?fz1KdtU8z!P$CO z3*wVRHrBf}X*q)ui_@xz?#>49e&wmmYm$3kmFkv%#V=m#f${8W542;;vkBfaR5BiN zM+tC5z7_AG6$MGaDVyVP@i}MvMdf~O4?TW7WjQ_C6U)*k#<&V!1Sfp(10oovf|8{P8rqLzXi)G?|^>f-uefP=37bm^Efz}26RK=AMN}e97_wGlQwl@Kk=q1 zVQG>xxg9{Gdun$7pN}iJzEe<`S4XR;>z-T!&E5?7#63DNFt*yCGnu$W$09o&cBRv- zS7uE7P9xYm+q=UF2@ppaFBs=4`ma<3=O$wXGlRPN8= z9UzfxCjlO1J3S47hlPb595zH{3DI1t0c_1wz{613aC>|E%#zpMqdBL)?%jj)yWjV{ zbB4n?1Vmq#u^(PI!E4(W45Bxhy>ypK$tzm97X7@Tc@r{Y8nq H>F56e2*>V= diff --git a/tff_modular/modules/vampire/objects/umbrellas.dm b/tff_modular/modules/vampire/objects/umbrellas.dm index eae368cbab3..a8419a23330 100644 --- a/tff_modular/modules/vampire/objects/umbrellas.dm +++ b/tff_modular/modules/vampire/objects/umbrellas.dm @@ -4,6 +4,7 @@ * Umbrellas you can hold, and open and close. * Currently not coding for protecting against rain as ???I dont think??? rain exists. * The rest don't and it just for looks. + */ /obj/item/umbrella name = "umbrella" desc = "A plain umbrella." @@ -139,21 +140,6 @@ greyscale_config_inhand_left = null greyscale_config_inhand_right = null -/datum/greyscale_config/umbrella - name = "Umbrella" - icon_file = 'tff_modular/modules/vampire/icons/umbrellas.dmi' - json_config = 'code/datums/greyscale/json_configs/_umbrella.json' - -/datum/greyscale_config/umbrella_inhand_left - name = "Held Umbrella, Left, Closed" - icon_file = 'tff_modular/modules/vampire/icons/umbrellas_inhand_lh.dmi' - json_config = 'code/datums/greyscale/json_configs/_umbrella_inhand.json' - -/datum/greyscale_config/umbrella_inhand_right - name = "Held Umbrella, Right, Closed" - icon_file = 'tff_modular/modules/vampire/icons/umbrellas_inhand_rh.dmi' - json_config = 'code/datums/greyscale/json_configs/_umbrella_inhand.json' - /datum/crafting_recipe/umbrella name = "Umbrella" result = /obj/item/umbrella @@ -164,5 +150,16 @@ tool_behaviors = list(TOOL_CROWBAR) time = 5 SECONDS category = CAT_EQUIPMENT - crafting_flags = CRAFT_SKIP_MATERIALS_PARITY -*/ + crafting_flags = CRAFT_SKIP_MATERIALS_PARITY | CRAFT_MUST_BE_LEARNED + +/datum/crafting_recipe/umbrella_parasol + name = "Umbrella Parasol" + result = /obj/item/umbrella/parasol + reqs = list( + /obj/item/stack/sheet/cloth = 3, + /obj/item/stack/rods = 1, + ) + tool_behaviors = list(TOOL_CROWBAR, TOOL_WRENCH) + time = 10 SECONDS + category = CAT_EQUIPMENT + crafting_flags = CRAFT_SKIP_MATERIALS_PARITY | CRAFT_MUST_BE_LEARNED diff --git a/tff_modular/modules/vampire/powers/dominate/mesmerize.dm b/tff_modular/modules/vampire/powers/dominate/mesmerize.dm index 7b1970d4bb9..1aefc065f37 100644 --- a/tff_modular/modules/vampire/powers/dominate/mesmerize.dm +++ b/tff_modular/modules/vampire/powers/dominate/mesmerize.dm @@ -129,8 +129,6 @@ else owner.balloon_alert(owner, "attempting to hypnotize [living_target]...") - perform_indicators(living_target, modified_delay) - if(!do_after(owner, modified_delay, living_target, IGNORE_USER_LOC_CHANGE | IGNORE_TARGET_LOC_CHANGE, extra_checks = CALLBACK(src, PROC_REF(continue_active)), hidden = TRUE)) deactivate_power() return @@ -159,22 +157,6 @@ . = ..() target_ref = null -/datum/action/cooldown/vampire/targeted/mesmerize/proc/perform_indicators(mob/target, duration) - // Display an animated overlay over our head to indicate what's going on - eldritch_eye(target, "eye_open", 1 SECONDS) - var/main_duration = max(duration - 2 SECONDS, 1 SECONDS) - addtimer(CALLBACK(src, PROC_REF(eldritch_eye), target, "eye_flash", main_duration), 1 SECONDS) - addtimer(CALLBACK(src, PROC_REF(eldritch_eye), target, "eye_close", 1 SECONDS), main_duration + 1 SECONDS) - -/// Display an animated overlay over our head to indicate what's going on -/datum/action/cooldown/vampire/targeted/mesmerize/proc/eldritch_eye(mob/target, icon_state = "eye_open", duration = 1 SECONDS) - var/image/image = image('icons/effects/eldritch.dmi', owner, icon_state, ABOVE_ALL_MOB_LAYER) - image.pixel_w = -(owner.pixel_x + owner.pixel_w) - image.pixel_z = 28 - image.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA - SET_PLANE_EXPLICIT(image, ABOVE_HUD_PLANE, owner) - flick_overlay_global(image, list(owner?.client, target?.client), duration) - /datum/status_effect/mesmerized id = "mesmerized" duration = 15 SECONDS From 1eae641d9c9f7d37a05072fc093895ae7743800e Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Tue, 17 Mar 2026 17:47:07 +0300 Subject: [PATCH 062/149] =?UTF-8?q?=D0=BF=D1=80=D0=BE=D0=B1=D1=83=D0=B5?= =?UTF-8?q?=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../greyscale_configs/greyscale_items.dm | 19 ------------------- .../modules/vampire/objects/umbrellas.dm | 2 +- 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/code/datums/greyscale/config_types/greyscale_configs/greyscale_items.dm b/code/datums/greyscale/config_types/greyscale_configs/greyscale_items.dm index b1bce212302..fa9440e8c1c 100644 --- a/code/datums/greyscale/config_types/greyscale_configs/greyscale_items.dm +++ b/code/datums/greyscale/config_types/greyscale_configs/greyscale_items.dm @@ -360,22 +360,3 @@ name = "MOD Soul Core" icon_file = 'icons/obj/clothing/modsuit/mod_construction.dmi' json_config = 'code/datums/greyscale/json_configs/mod_core_soul.json' - -// TFF ADDITION START - -/datum/greyscale_config/umbrella - name = "Umbrella" - icon_file = 'tff_modular/modules/vampire/icons/umbrellas.dmi' - json_config = 'code/datums/greyscale/json_configs/_umbrella.json' - -/datum/greyscale_config/umbrella_inhand_left - name = "Held Umbrella, Left, Closed" - icon_file = 'tff_modular/modules/vampire/icons/umbrellas_inhand_lh.dmi' - json_config = 'code/datums/greyscale/json_configs/_umbrella_inhand.json' - -/datum/greyscale_config/umbrella_inhand_right - name = "Held Umbrella, Right, Closed" - icon_file = 'tff_modular/modules/vampire/icons/umbrellas_inhand_rh.dmi' - json_config = 'code/datums/greyscale/json_configs/_umbrella_inhand.json' - -// TFF ADDITION END diff --git a/tff_modular/modules/vampire/objects/umbrellas.dm b/tff_modular/modules/vampire/objects/umbrellas.dm index a8419a23330..113f719315b 100644 --- a/tff_modular/modules/vampire/objects/umbrellas.dm +++ b/tff_modular/modules/vampire/objects/umbrellas.dm @@ -4,7 +4,6 @@ * Umbrellas you can hold, and open and close. * Currently not coding for protecting against rain as ???I dont think??? rain exists. * The rest don't and it just for looks. - */ /obj/item/umbrella name = "umbrella" desc = "A plain umbrella." @@ -163,3 +162,4 @@ time = 10 SECONDS category = CAT_EQUIPMENT crafting_flags = CRAFT_SKIP_MATERIALS_PARITY | CRAFT_MUST_BE_LEARNED +*/ From 9e1b04d0cb1607cc42d0925df249099dc60b8dc4 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Tue, 17 Mar 2026 17:52:07 +0300 Subject: [PATCH 063/149] Update datum_vampire.dm --- tff_modular/modules/vampire/datum_vampire.dm | 2 -- 1 file changed, 2 deletions(-) diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index 96e2cf389fc..9fb2ffcdc72 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -332,8 +332,6 @@ /datum/crafting_recipe/candelabrum, /datum/crafting_recipe/bloodthrone, /datum/crafting_recipe/meatcoffin, - /datum/crafting_recipe/umbrella_parasol, - /datum/crafting_recipe/umbrella, )) // Set name and reputation From f9a046d0bf3e67be800e4c04b0dc4e656cff4d62 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Thu, 19 Mar 2026 17:53:12 +0300 Subject: [PATCH 064/149] =?UTF-8?q?=D0=BD=D0=B5=D0=BA=D0=BE=D1=82=D0=BE?= =?UTF-8?q?=D1=80=D1=8B=D0=B5=20=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- strings/fluffy/malkavian_revelations.json | 36 ++--- tff_modular/modules/vampire/clans/_clan.dm | 10 +- tff_modular/modules/vampire/clans/brujah.dm | 1 - tff_modular/modules/vampire/clans/debug.dm | 1 - .../modules/vampire/clans/malkavian.dm | 1 - tff_modular/modules/vampire/clans/toreador.dm | 1 - tff_modular/modules/vampire/clans/tremere.dm | 1 - tff_modular/modules/vampire/clans/ventrue.dm | 1 - tff_modular/modules/vampire/datum_vampire.dm | 4 +- .../modules/vampire/powers/auspex/auspex.dm | 20 +-- .../vampire/powers/dominate/command.dm | 4 +- .../vampire/powers/dominate/mesmerize.dm | 3 +- tff_modular/modules/vampire/powers/feed.dm | 4 +- .../vampire/powers/fortitude/fortitude.dm | 15 +- .../vampire/powers/obfuscate/obfuscate.dm | 8 +- tff_modular/modules/vampire/society.dm | 129 +----------------- 16 files changed, 58 insertions(+), 181 deletions(-) diff --git a/strings/fluffy/malkavian_revelations.json b/strings/fluffy/malkavian_revelations.json index 48a1785685b..76bdcada9a9 100644 --- a/strings/fluffy/malkavian_revelations.json +++ b/strings/fluffy/malkavian_revelations.json @@ -26,7 +26,7 @@ "#Генокрады более чистая форма людей... Если бы люди были самыми нечистыми существами.", "Как там поживает дьявол? Давно его не видел.", "#Для меня это ничего не значит, парень.", - "Я никому не лоялен, я Демон, а мой покровитель Дьявол.", + "#Я никому не лоялен, я Демон, а мой покровитель Дьявол.", "#Я ни к кому не испытываю преданности, никогда не испытывал и не буду испытывать.", "#Коротышка решила быть с демоном, похоже это ее проблема!", "#Ты видишь, я действительно сделал это, я действительно он.", @@ -51,40 +51,42 @@ "#Если бы только все видели мир так, как вижу его я.", "#Что сделало человечество, чтобы заслужить мое существование?", "#Если бог существует, как он позволил мне появиться?", - "...Я, кажется, потерял нить чего-то, не могу понять чего...", + "#...Я, кажется, потерял нить чего-то, не могу понять чего...", "#Личность которую все пытаются заткнуть, это та личность, которую все будут желать вернуть.", "Это твоя вина.", "#Сегодня ты нажил себе могущественного врага, чувак.", "#Тебя любят личинки. Поверь мне.", "#Мое величайшее оружие - знание. И глаза-лазеры.", "#Я раскрашиваю мир красками своего безумия.", - "# Смейтесь, если хотите. Считайте, что вы намного умнее, чем несчастный сломленный сумасшедший. Неважно. Но подумайте над этим: вы — мёртвое существо, как и я. Вы умерли и возродились… вот этим. Что делает вас и меня разными? Очень просто — я помню, что видел, когда был полностью и воистину мёртв. Вы бы тоже сошли с ума.", - "#Я пытался превратить воду в вино. Какого хрена здесь кровь? А, ну да ладно - не пропадать же добру.", + "#Смейтесь, если хотите. Считайте, что вы намного умнее, чем несчастный сломленный сумасшедший. Неважно. Но подумайте над этим: вы — мёртвое существо, как и я. Вы умерли и возродились… вот этим. Что делает вас и меня разными? Очень просто — я помню, что видел, когда был полностью и воистину мёртв. Вы бы тоже сошли с ума.", + "Я пытался превратить воду в вино. Какого хрена здесь кровь? А, ну да ладно - не пропадать же добру.", "Потанцуем?", "Должен ли я делать то, что мне назначено? Или я должен пойти в шестую дорму? Другой вопрос заключается в том, почему такое существо как я имеет столь высокое либидо.", - "Моли тебя окружают.", "#Цимисхи - милые ребята, они так завидуют Носферату и подражают им. Что ж, если они думают, что безобразие приводит к просветлению, я с радостью помогу им. У них слишком много конечностей, на мой вкус...", - "Ты живешь на островке невезения... Смерть предъявит на тебя право...", - "Не обращайте внимания на этого человека в углу. Он просто выдуманный друг, которого я перестал выдумывать, но он обиделся и остался.", - "Не считай безумие проклятием, смертный. Для некоторых это величайшее из благ. Горькая милость, возможно, но все же милость.", - "Я видел большую лошадь. Она создала меня, а потом поскакала искать прекрасные поля, жуя морковку.", - "С концом света придут четыре всадника. Четыре коня в плащах на своих верных людях-скакунах.", - "А потом я придумаю себе хобби. Кто знает, может, воскрешение мертвых?", + "#Ты живешь на островке невезения... Смерть предъявит на тебя право...", + "#Не обращайте внимания на этого человека в углу. Он просто выдуманный друг, которого я перестал выдумывать, но он обиделся и остался.", + "#Не считай безумие проклятием, смертный. Для некоторых это величайшее из благ. Горькая милость, возможно, но все же милость.", + "#Я видел большую лошадь. Она создала меня, а потом поскакала искать прекрасные поля, жуя морковку.", + "#С концом света придут четыре всадника. Четыре коня в плащах на своих верных людях-скакунах.", + "#А потом я придумаю себе хобби. Кто знает, может, воскрешение мертвых?", "#Добро пожаловать в безумный мир, дом всех самых странных вещей...", "#Вампиры-Социалисты хотят контролировать твой разум!", "#Я запру тебя в мире, где ты будешь любить быть живым.", "#Кто-то отправится на небеса, а кто-то просто умрет.", - "Всегда оставайся человеком. Даже если ты не человек.", - "Сострадание - не слабость. Это хорошая черта.", + "#Всегда оставайся человеком. Даже если ты не человек.", "#Цикл вновь повторяется. Ты снова тут. Как и в прошлый раз.", - "Солнце для нас встаёт там, где скажут имеющие власть.", "#Если бы в уравнении было лишнее звено, то тебя бы не было. Ты кому-то точно нужен.", - "Времена меняются. Например, почти никто больше не здоровается за руку. Её ведь так сложно вытянуть.", + "#Времена меняются. Например, почти никто больше не здоровается за руку. Её ведь так сложно вытянуть.", "#Любви тут давно нет. Бог покинул это место.", "#Тюрьма - не содержание. Это изысканная казнь скукой с вариантами для выхода.", "#Не обращайся к Богу за помощью - он может тебе ответить не так, как хотелось бы.", "#От Божьей Кары не убежать - она на божественных скоростях.", - "Маленький ствол - это не так уж и плохо. Конечно, было бы лучше, чтобы у офицера его вообще не было...", - "Умение правильно делать паузы - то, что отделяет одних от других." + "#Глаза у меня добрые, но рубашка смерительная.", + "#Так заканчивается моя история. Официально это было самоубийство, и я так никогда и не узнаю, что случилось со мной в закусочной той ночью.", + "#Он безумный, мир безумный — ты тоже безумный, потому что в твоей голове сижу безумный я", + "#Я не из тех, кто жаждет крови, не из тех, кому не хватает насилия и не любитель проблем. Но и совесть меня не мучает.", + "#Жирафы - бессердечные создания", + "#Между годами серого существования и мигом надежды, я выбираю надежду", + "#Не пытки меня сломали. Не промывка мозгов. Не удар по голове. Не слуга Мансуса. Смерть..." ] } diff --git a/tff_modular/modules/vampire/clans/_clan.dm b/tff_modular/modules/vampire/clans/_clan.dm index 84ad1fc28c0..a7a94591fed 100644 --- a/tff_modular/modules/vampire/clans/_clan.dm +++ b/tff_modular/modules/vampire/clans/_clan.dm @@ -27,7 +27,6 @@ // Societee var/is_sabbat = FALSE // In case we want a bad guy clan that doesn't care about the masquerade. - var/princely_score_bonus = -10 // Will be added to playtime in get_princely_score() /// Unique antag HUD icon of this clan, if any. var/antag_hud_icon @@ -192,11 +191,20 @@ to_chat(living_vampire, span_notice("You have learned how to use [discipline_response]!")) finalize_spend_rank() + prince_check() // QoL if(vampiredatum.vampire_level_unspent > 0) spend_rank(carbon_vampire) +/datum/vampire_clan/proc/prince_check() + if(!vampiredatum.can_become_prince && !vampiredatum.vampire_level >= 10) + return FALSE + + var/tgui_answer = tgui_alert(vampiredatum.owner.current, "You grown enough to become a prince, do you want it?", "Princify", list("Yes", "No")) + if(tgui_answer == "Yes") + vampiredatum.princify() + /datum/vampire_clan/proc/finalize_spend_rank() // Level up the vampire vampiredatum.vampire_regen_rate += 0.05 diff --git a/tff_modular/modules/vampire/clans/brujah.dm b/tff_modular/modules/vampire/clans/brujah.dm index 888b013d574..78f087972b6 100644 --- a/tff_modular/modules/vampire/clans/brujah.dm +++ b/tff_modular/modules/vampire/clans/brujah.dm @@ -5,7 +5,6 @@ At the same time, many Brujah are pragmatic. They respect competence, reward power, and will accept arrangements that let them keep their autonomy while serving a purpose. For the right price, leverage, or chance to settle scores, princes were known recruit Brujah as scourges or enforcers, so long as those Brujah retain visible independence." join_icon_state = "brujah" default_humanity = 8 - princely_score_bonus = 2 joinable_clan = TRUE antag_hud_icon = "brujah" diff --git a/tff_modular/modules/vampire/clans/debug.dm b/tff_modular/modules/vampire/clans/debug.dm index 942ae3cd2bf..94649baaf2d 100644 --- a/tff_modular/modules/vampire/clans/debug.dm +++ b/tff_modular/modules/vampire/clans/debug.dm @@ -4,7 +4,6 @@ name = "Debug Clan" description = "wtf you shouldn't be seeing this outside of testing" default_humanity = 10 - princely_score_bonus = 99 joinable_clan = TRUE /datum/vampire_clan/debug/New(datum/antagonist/vampire/owner_datum) diff --git a/tff_modular/modules/vampire/clans/malkavian.dm b/tff_modular/modules/vampire/clans/malkavian.dm index 006204122fb..801f13b067e 100644 --- a/tff_modular/modules/vampire/clans/malkavian.dm +++ b/tff_modular/modules/vampire/clans/malkavian.dm @@ -9,7 +9,6 @@ join_icon_state = "malkavian" joinable_clan = TRUE default_humanity = 8 - princely_score_bonus = 6 COOLDOWN_DECLARE(revelation_cooldown) diff --git a/tff_modular/modules/vampire/clans/toreador.dm b/tff_modular/modules/vampire/clans/toreador.dm index 93aabcef71f..3797659a450 100644 --- a/tff_modular/modules/vampire/clans/toreador.dm +++ b/tff_modular/modules/vampire/clans/toreador.dm @@ -6,7 +6,6 @@ join_icon_state = "toreador" blood_drink_type = VAMPIRE_DRINK_SNOBBY default_humanity = 10 - princely_score_bonus = 10 joinable_clan = TRUE /datum/vampire_clan/toreador/New(datum/antagonist/vampire/owner_datum) diff --git a/tff_modular/modules/vampire/clans/tremere.dm b/tff_modular/modules/vampire/clans/tremere.dm index 065d5d06e2d..8f748948dcc 100644 --- a/tff_modular/modules/vampire/clans/tremere.dm +++ b/tff_modular/modules/vampire/clans/tremere.dm @@ -5,7 +5,6 @@ The Tremere stand as a pillar of the Camarilla and are one of its main defenders, despite the fact that they exist almost as a subsect." join_icon_state = "tremere" default_humanity = 7 - princely_score_bonus = 8 joinable_clan = TRUE /datum/vampire_clan/tremere/New(datum/antagonist/vampire/owner_datum) diff --git a/tff_modular/modules/vampire/clans/ventrue.dm b/tff_modular/modules/vampire/clans/ventrue.dm index 181205d1421..a5e8ce7bf6c 100644 --- a/tff_modular/modules/vampire/clans/ventrue.dm +++ b/tff_modular/modules/vampire/clans/ventrue.dm @@ -6,7 +6,6 @@ join_icon_state = "ventrue" blood_drink_type = VAMPIRE_DRINK_SNOBBY default_humanity = 9 - princely_score_bonus = 15 // IT'S OVER NIN- ten. It's over ten. joinable_clan = TRUE /datum/vampire_clan/ventrue/New(datum/antagonist/vampire/owner_datum) diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index 9fb2ffcdc72..c7cd64a48df 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -37,7 +37,8 @@ /// Flavor only var/vampire_name - + /// Can we become prince? + var/can_become_prince = FALSE /// Are we the prince? var/prince = FALSE /// Are we the scourge? Literally only used for the examine. Okay. @@ -374,7 +375,6 @@ clear_powers_and_stats() GLOB.all_vampires -= src SSvampire_leveling.check_enable() - check_cancel_society() if(iscarbon(owner.current)) var/mob/living/carbon/carbon_owner = owner.current diff --git a/tff_modular/modules/vampire/powers/auspex/auspex.dm b/tff_modular/modules/vampire/powers/auspex/auspex.dm index 4317b9125fd..8533acde3b2 100644 --- a/tff_modular/modules/vampire/powers/auspex/auspex.dm +++ b/tff_modular/modules/vampire/powers/auspex/auspex.dm @@ -7,7 +7,11 @@ // Lists of abilities granted per level level_1 = list(/datum/action/cooldown/vampire/auspex) level_2 = list(/datum/action/cooldown/vampire/auspex/two) - level_3 = list(/datum/action/cooldown/vampire/auspex/three, /datum/action/cooldown/vampire/astral_projection) + level_3 = list(/datum/action/cooldown/vampire/auspex/two, /datum/action/cooldown/vampire/astral_projection) + +/datum/discipline/auspex/apply_discipline_quirks(datum/antagonist/vampire/clan_owner) + . = ..() + owner.add_traits(clan_owner.vampire_traits, TRAIT_XRAY_HEARING, TRAIT_VAMPIRE) /datum/action/cooldown/vampire/auspex name = "Auspex" @@ -15,7 +19,7 @@ button_icon_state = "power_auspex" power_explanation = "- Level 1: When Activated, you will be able to see other peoples warrants and ID, and, upon examining a fellow Kindred, be able to tell if they have committed Diablerie. \n\ - Level 2: When Activated, You will be able to see health of your victims. \n\ - - Level 3: When Activated, you will be able to sense anything in sight, hearing through walls and barriers as if they were air. You also can enter a trance, and being able to talk to ghosts." + - Level 3: You gain ability to enter trance, that creates your astral projection." vampire_power_flags = BP_AM_TOGGLE | BP_AM_STATIC_COOLDOWN vampire_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 vitaecost = 10 @@ -23,7 +27,6 @@ cooldown_time = 10 SECONDS var/add_medical = FALSE var/add_security = TRUE - var/add_xray = FALSE var/see_diablerie = TRUE var/looking = FALSE @@ -33,12 +36,6 @@ constant_vitaecost = 2 add_medical = TRUE -/datum/action/cooldown/vampire/auspex/three - name = "Auspex" - vitaecost = 30 - constant_vitaecost = 3 - add_xray = TRUE - /datum/action/cooldown/vampire/auspex/activate_power() . = ..() if(!looking) @@ -63,14 +60,11 @@ if(add_security) ADD_TRAIT(owner, TRAIT_SECURITY_HUD, REF(src)) - if(add_xray) - ADD_TRAIT(owner, TRAIT_XRAY_HEARING, REF(src)) - owner.update_sight() /datum/action/cooldown/vampire/auspex/proc/unlooky() SIGNAL_HANDLER looking = FALSE - owner.remove_traits(list(TRAIT_SEE_DIABLERIE, TRAIT_SECURITY_HUD, TRAIT_XRAY_HEARING, TRAIT_MEDICAL_HUD), REF(src)) + owner.remove_traits(list(TRAIT_SEE_DIABLERIE, TRAIT_SECURITY_HUD, TRAIT_MEDICAL_HUD), REF(src)) owner.update_sight() diff --git a/tff_modular/modules/vampire/powers/dominate/command.dm b/tff_modular/modules/vampire/powers/dominate/command.dm index e30c955fa35..4c15760fc60 100644 --- a/tff_modular/modules/vampire/powers/dominate/command.dm +++ b/tff_modular/modules/vampire/powers/dominate/command.dm @@ -164,9 +164,7 @@ /* if(CHAT_FILTER_CHECK(command)) to_chat(owner, span_warning("The command '[span_bold("[command]")]' is forbidden!")) return FALSE */ - if(findtext_char(command, " ")) - to_chat(owner, span_warning("Please only input a single word.")) - return FALSE + if(length_char(command) > 8) to_chat(owner, span_warning("Command too long!")) return FALSE diff --git a/tff_modular/modules/vampire/powers/dominate/mesmerize.dm b/tff_modular/modules/vampire/powers/dominate/mesmerize.dm index 1aefc065f37..cf54f9d4c69 100644 --- a/tff_modular/modules/vampire/powers/dominate/mesmerize.dm +++ b/tff_modular/modules/vampire/powers/dominate/mesmerize.dm @@ -21,7 +21,7 @@ vampire_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 vitaecost = 40 cooldown_time = 10 SECONDS - target_range = 5 + target_range = 4 power_activates_immediately = FALSE prefire_message = "Whom will you submit to your will?" level_current = 1 @@ -47,7 +47,6 @@ /datum/action/cooldown/vampire/targeted/mesmerize/four vitaecost = 60 level_current = 4 - target_range = 6 /datum/action/cooldown/vampire/targeted/mesmerize/can_use() . = ..() diff --git a/tff_modular/modules/vampire/powers/feed.dm b/tff_modular/modules/vampire/powers/feed.dm index 434c58121a4..a3bd237b1b9 100644 --- a/tff_modular/modules/vampire/powers/feed.dm +++ b/tff_modular/modules/vampire/powers/feed.dm @@ -276,7 +276,7 @@ playsound(living_owner, 'tff_modular/modules/vampire/sound/drinkblood1.ogg', 50) - feed_target.Stun((5 + level_current) SECONDS) + feed_target.Stun((10 + level_current) SECONDS) feed_target.set_jitter_if_lower((5 + level_current) SECONDS) owner.visible_message( @@ -361,7 +361,7 @@ if(HAS_TRAIT(user, TRAIT_FRENZY)) feed_strength_mult = 2 else if(!silent_feed) - feed_strength_mult = 1 + feed_strength_mult = 1.2 handle_feeding(feed_target, feed_strength_mult) diff --git a/tff_modular/modules/vampire/powers/fortitude/fortitude.dm b/tff_modular/modules/vampire/powers/fortitude/fortitude.dm index 2068f07e721..650b7114862 100644 --- a/tff_modular/modules/vampire/powers/fortitude/fortitude.dm +++ b/tff_modular/modules/vampire/powers/fortitude/fortitude.dm @@ -42,12 +42,13 @@ var/dismember = FALSE var/stun = FALSE - var/calculated_burn_resist // do not touch + var/burn_resistance = 0.8 /datum/action/cooldown/vampire/fortitude/two vitaecost = 20 constant_vitaecost = 1.5 resistance = 0.6 + burn_resistance = 0.8 pierce = TRUE push = TRUE @@ -55,14 +56,16 @@ vitaecost = 30 constant_vitaecost = 2 resistance = 0.4 + burn_resistance = 0.7 pierce = TRUE push = TRUE dismember = TRUE /datum/action/cooldown/vampire/fortitude/four vitaecost = 20 - constant_vitaecost = 2.5 - resistance = 0.3 + constant_vitaecost = 2 + resistance = 0.4 + burn_resistance = 0.6 pierce = TRUE push = TRUE dismember = TRUE @@ -74,8 +77,6 @@ to_chat(owner, span_notice("Your flesh has become as hard as steel!")) owner.playsound_local(null, 'tff_modular/modules/vampire/sound/fortitude_on.ogg', 100, FALSE, pressure_affected = FALSE) - calculated_burn_resist = min(1, resistance * 1.2) - // Traits & Effects if(pierce) ADD_TRAIT(owner, TRAIT_PIERCEIMMUNE, REF(src)) @@ -89,7 +90,7 @@ var/mob/living/carbon/human/user = owner user.physiology.brute_mod *= resistance user.physiology.stamina_mod *= resistance * 2 // Stamina resistance is half as effective because they have it inherently. - user.physiology.burn_mod *= calculated_burn_resist // they get burn resistance, but way less + user.physiology.burn_mod *= burn_resistance // they get burn resistance, but way less /datum/action/cooldown/vampire/fortitude/use_power() . = ..() @@ -106,7 +107,7 @@ var/mob/living/carbon/human/vampire_user = owner vampire_user.physiology.brute_mod /= resistance - vampire_user.physiology.burn_mod /= calculated_burn_resist + vampire_user.physiology.burn_mod /= burn_resistance vampire_user.physiology.stamina_mod /= resistance * 2 // Remove Traits & Effects diff --git a/tff_modular/modules/vampire/powers/obfuscate/obfuscate.dm b/tff_modular/modules/vampire/powers/obfuscate/obfuscate.dm index 6e2d231d304..6bf6755a0e6 100644 --- a/tff_modular/modules/vampire/powers/obfuscate/obfuscate.dm +++ b/tff_modular/modules/vampire/powers/obfuscate/obfuscate.dm @@ -4,8 +4,8 @@ icon_state = "obfuscate" // Lists of abilities granted per level - level_1 = list(/datum/action/cooldown/vampire/cloak) - level_2 = list(/datum/action/cooldown/vampire/cloak/two, /datum/action/cooldown/vampire/targeted/trespass) - level_3 = list(/datum/action/cooldown/vampire/cloak/three, /datum/action/cooldown/vampire/targeted/trespass/two) - level_4 = list(/datum/action/cooldown/vampire/cloak/four, /datum/action/cooldown/vampire/targeted/trespass/three, /datum/action/cooldown/vampire/veil) + level_1 = list(/datum/action/cooldown/vampire/veil, /datum/action/cooldown/vampire/targeted/trespass) + level_2 = list(/datum/action/cooldown/vampire/cloak, /datum/action/cooldown/vampire/veil, /datum/action/cooldown/vampire/targeted/trespass/two) + level_3 = list(/datum/action/cooldown/vampire/cloak/two, /datum/action/cooldown/vampire/targeted/trespass/three, /datum/action/cooldown/vampire/veil) + level_4 = null level_5 = null diff --git a/tff_modular/modules/vampire/society.dm b/tff_modular/modules/vampire/society.dm index 7a795d88669..f34d18debf4 100644 --- a/tff_modular/modules/vampire/society.dm +++ b/tff_modular/modules/vampire/society.dm @@ -1,125 +1,19 @@ -SUBSYSTEM_DEF(vsociety) - name = "Vampire Society" - wait = 5 MINUTES - flags = SS_NO_INIT | SS_BACKGROUND - can_fire = FALSE - - // Are we currently polling? - var/currently_polling = FALSE - - // Ref to the prince datum - var/datum/weakref/princedatum - - var/start_time = 0 - -/datum/controller/subsystem/vsociety/fire(resumed = FALSE) - var/time_elapsed = world.time - start_time - - // Give them some breathing room - if(time_elapsed < 9 MINUTES) - return - - if(!princedatum && !currently_polling) - for(var/datum/antagonist/vampire as anything in GLOB.all_vampires) - to_chat(vampire.owner.current, span_announce("* Vampire Tip: A vote for Prince will occur soon. If you are interested in leading your fellow kindred, read up on princes in your info panel now!")) - addtimer(CALLBACK(src, PROC_REF(poll_for_prince)), 2 MINUTES) - message_admins("Vampire society has fired, and a prince poll will occur in 2 minutes.") - log_game("Vampire society has fired, and a prince poll will occur soon.") - -/datum/controller/subsystem/vsociety/proc/poll_for_prince() - message_admins("Vampire society is now polling for a new prince.") - log_game("Vampire society is now polling for a new prince.") - - //Build a list of mobs in GLOB.all_vampires - var/list/vampire_living_candidates = list() - - for(var/datum/antagonist/vampire as anything in GLOB.all_vampires) - var/currentmob = vampire.owner?.current - - if(!isliving(currentmob)) //Are we mob/living? - continue - - var/mob/living/livingmob = currentmob - if(livingmob.health <= HEALTH_THRESHOLD_DEAD) // we check health instead of stat to avoid skipping out on vamps that are in torpor or something - continue - - vampire_living_candidates += currentmob - - // Build a poll_config datum to match the new polling API - currently_polling = TRUE - var/icon/prince_icon = icon('tff_modular/modules/vampire/icons/actions_vampire.dmi', "power_awe") - var/list/pollers = SSpolling.poll_candidates( - "You are eligible for princedom.", - poll_time = 3 MINUTES, - flash_window = TRUE, - group = vampire_living_candidates, - alert_pic = prince_icon, - role_name_text = "Prince", - custom_response_messages = list( - POLL_RESPONSE_SIGNUP = "You have made your bid for princedom.
    * Note: Princedom has certain expectations placed upon you. If you are not in a position to enforce the masquerade, consider letting someone else take this burden.", - POLL_RESPONSE_UNREGISTERED = "You have removed your bid to princedom.", - ), - amount_to_pick = length(GLOB.all_vampires), - announce_chosen = FALSE, - ) - currently_polling = FALSE - - var/datum/antagonist/vampire/chosen_datum - var/mob/living/carbon/chosen_candidate - - // We have to do this shit because the polling proc doesn't always return a list. Sometimes it just returns a mob. - var/list/candidates = list() - candidates += pollers - - for(var/mob/living/carbon/current_candidate in candidates) // Pick the ideal one from the list. - var/datum/antagonist/vampire/current_datum = IS_VAMPIRE(current_candidate) - - if(!chosen_candidate) // If we are the first in line, just be the prince by default - chosen_candidate = current_candidate - chosen_datum = IS_VAMPIRE(current_candidate) - continue - - if(current_datum.get_princely_score() >= chosen_datum.get_princely_score()) - chosen_candidate = current_candidate - chosen_datum = IS_VAMPIRE(current_candidate) - - if(chosen_datum) - chosen_datum.princify() - /** * Resumes society, called when someone is assigned Vampire **/ /datum/antagonist/vampire/proc/check_start_society() - - if(SSvsociety.can_fire || !CONFIG_GET(flag/allow_vampire_prince)) + if(!CONFIG_GET(flag/allow_vampire_prince)) return - if(length(GLOB.all_vampires) >= 3) - SSvsociety.start_time = world.time - SSvsociety.can_fire = TRUE + can_become_prince = TRUE message_admins("Vampire Society has started, as there are [length(GLOB.all_vampires)] vampires active.") log_game("Vampire Society has started, as there are [length(GLOB.all_vampires)] vampires active.") -/** - * Pauses society, called when someone is unassigned Vampire -**/ -/datum/antagonist/vampire/proc/check_cancel_society() - - if(!SSvsociety.can_fire) - return - - if(length(GLOB.all_vampires) < 3 || !CONFIG_GET(flag/allow_vampire_prince)) - SSvsociety.can_fire = FALSE - message_admins("Vampire Society has paused, as there are only [length(GLOB.all_vampires)] vampires active.") - log_game("Vampire Society has paused, as there are only [length(GLOB.all_vampires)] vampires active.") - /** * Turns the player into a prince. **/ /datum/antagonist/vampire/proc/princify() - SSvsociety.princedatum = WEAKREF(src) - - rank_up(8, TRUE) // Rank up a lot. + rank_up(4, TRUE) // Rank up a lot. to_chat(owner.current, span_cult_bold("As a true prince, you find some of your old power returning to you!")) owner.current.playsound_local(null, 'tff_modular/modules/vampire/sound/prince.ogg', 100, FALSE, pressure_affected = FALSE) prince = TRUE @@ -136,8 +30,8 @@ SUBSYSTEM_DEF(vsociety) objectives += prince_objective owner.announce_objectives() - message_admins("[ADMIN_LOOKUP(owner.current)] has received the role of Vampire Prince. ([get_princely_score()] princely score, with [my_clan?.princely_score_bonus]/[min(50, owner.current?.client?.get_exp_living(TRUE) / 60) / 10] clan/hour bonus.)") - log_game("[key_name(owner.current)] has become the Vampire Prince. ([get_princely_score()] princely score, with [my_clan?.princely_score_bonus]/[min(50, owner.current?.client?.get_exp_living(TRUE) / 60) / 10] clan/hour bonus.)") + message_admins("[ADMIN_LOOKUP(owner.current)] has received the role of Vampire Prince.") + log_game("[key_name(owner.current)] has become the Vampire Prince.") notify_ghosts( "[owner.name] has become the Vampire Prince!", @@ -180,19 +74,6 @@ SUBSYSTEM_DEF(vsociety) update_static_data_for_all_viewers() -/** - * Returns the princyness of this vampire. - * get the players hours, convert it into a 10 point scale, 0-100 hours. - * get their clans default princely score. 0-10(mostly). - * Add those together. -**/ -/datum/antagonist/vampire/proc/get_princely_score() - var/calculated_hour_score = min(50, owner.current?.client?.get_exp_living(TRUE) / 60) / 10 - - var/clan_bonus = my_clan?.princely_score_bonus || -10 - - return clan_bonus + calculated_hour_score - // We could put this in objectives but like, it's just two tiny hardcoded things. It's fine here. /datum/objective/vampire/scourge name = "Camarilla Scourge" From b9d755a53214a8760a61c08c6de7fc2ac719e9c8 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Thu, 19 Mar 2026 18:12:13 +0300 Subject: [PATCH 065/149] Update _clan.dm --- tff_modular/modules/vampire/clans/_clan.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tff_modular/modules/vampire/clans/_clan.dm b/tff_modular/modules/vampire/clans/_clan.dm index a7a94591fed..cef09361766 100644 --- a/tff_modular/modules/vampire/clans/_clan.dm +++ b/tff_modular/modules/vampire/clans/_clan.dm @@ -191,14 +191,13 @@ to_chat(living_vampire, span_notice("You have learned how to use [discipline_response]!")) finalize_spend_rank() - prince_check() // QoL if(vampiredatum.vampire_level_unspent > 0) spend_rank(carbon_vampire) /datum/vampire_clan/proc/prince_check() - if(!vampiredatum.can_become_prince && !vampiredatum.vampire_level >= 10) + if(!vampiredatum.can_become_prince && !vampiredatum.vampire_level >= 10 && !vampiredatum.prince) return FALSE var/tgui_answer = tgui_alert(vampiredatum.owner.current, "You grown enough to become a prince, do you want it?", "Princify", list("Yes", "No")) @@ -223,6 +222,7 @@ Your strength, feed rate, regen rate, and maximum blood capacity have all increased! \n\ * Your existing powers have all ranked up as well!")) vampiredatum.update_hud() + prince_check() /datum/vampire_clan/proc/on_vampire_broke_masquerade(datum/source, datum/antagonist/vampire/masquerade_breaker) SIGNAL_HANDLER From 9a97e74e0af84871d8db1d86399a6f2655461d3e Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Thu, 19 Mar 2026 18:15:17 +0300 Subject: [PATCH 066/149] Update _clan.dm --- tff_modular/modules/vampire/clans/_clan.dm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tff_modular/modules/vampire/clans/_clan.dm b/tff_modular/modules/vampire/clans/_clan.dm index cef09361766..97651c52a8d 100644 --- a/tff_modular/modules/vampire/clans/_clan.dm +++ b/tff_modular/modules/vampire/clans/_clan.dm @@ -200,9 +200,11 @@ if(!vampiredatum.can_become_prince && !vampiredatum.vampire_level >= 10 && !vampiredatum.prince) return FALSE - var/tgui_answer = tgui_alert(vampiredatum.owner.current, "You grown enough to become a prince, do you want it?", "Princify", list("Yes", "No")) + var/tgui_answer = tgui_alert(vampiredatum.owner.current, "You grown enough to become a prince, do you want it? If you refuse, you won't be able to become a prince later!", "Princify", list("Yes", "No")) if(tgui_answer == "Yes") vampiredatum.princify() + else if(tgui_answer == "No") + vampiredatum.can_become_prince = FALSE /datum/vampire_clan/proc/finalize_spend_rank() // Level up the vampire From ee025c5cc747a349c790c29a55d4ba63ab885cc2 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Thu, 19 Mar 2026 18:17:29 +0300 Subject: [PATCH 067/149] Update society.dm --- tff_modular/modules/vampire/society.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tff_modular/modules/vampire/society.dm b/tff_modular/modules/vampire/society.dm index f34d18debf4..6e4fcee4342 100644 --- a/tff_modular/modules/vampire/society.dm +++ b/tff_modular/modules/vampire/society.dm @@ -13,7 +13,7 @@ * Turns the player into a prince. **/ /datum/antagonist/vampire/proc/princify() - rank_up(4, TRUE) // Rank up a lot. + rank_up(5, TRUE) // Rank up a lot. to_chat(owner.current, span_cult_bold("As a true prince, you find some of your old power returning to you!")) owner.current.playsound_local(null, 'tff_modular/modules/vampire/sound/prince.ogg', 100, FALSE, pressure_affected = FALSE) prince = TRUE @@ -22,7 +22,7 @@ var/full_name = return_full_name() for(var/datum/antagonist/vampire as anything in GLOB.all_vampires) to_chat(vampire.owner.current, span_narsiesmall("[full_name], also known as [owner.name || owner.current.real_name || owner.current.name], has claimed the role of Prince!")) - + vampire.can_become_prince = FALSE if(CONFIG_GET(flag/allow_vampire_scourge)) grant_power(new /datum/action/cooldown/vampire/targeted/scourgify) From 9920baa0bd2e2893fcc20a9d7e7d99eee1dc04c6 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Thu, 19 Mar 2026 18:18:18 +0300 Subject: [PATCH 068/149] Update society.dm --- tff_modular/modules/vampire/society.dm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tff_modular/modules/vampire/society.dm b/tff_modular/modules/vampire/society.dm index 6e4fcee4342..24281dc54f3 100644 --- a/tff_modular/modules/vampire/society.dm +++ b/tff_modular/modules/vampire/society.dm @@ -8,11 +8,15 @@ can_become_prince = TRUE message_admins("Vampire Society has started, as there are [length(GLOB.all_vampires)] vampires active.") log_game("Vampire Society has started, as there are [length(GLOB.all_vampires)] vampires active.") + else + can_become_prince = FALSE /** * Turns the player into a prince. **/ /datum/antagonist/vampire/proc/princify() + if(!can_become_prince) + return FALS rank_up(5, TRUE) // Rank up a lot. to_chat(owner.current, span_cult_bold("As a true prince, you find some of your old power returning to you!")) owner.current.playsound_local(null, 'tff_modular/modules/vampire/sound/prince.ogg', 100, FALSE, pressure_affected = FALSE) From 217770b7c8791e748a9cb20587364aab20ee3bbf Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Thu, 19 Mar 2026 18:50:55 +0300 Subject: [PATCH 069/149] Update society.dm --- tff_modular/modules/vampire/society.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tff_modular/modules/vampire/society.dm b/tff_modular/modules/vampire/society.dm index 24281dc54f3..6d5f76b1ce8 100644 --- a/tff_modular/modules/vampire/society.dm +++ b/tff_modular/modules/vampire/society.dm @@ -24,7 +24,7 @@ add_team_hud(owner.current) var/full_name = return_full_name() - for(var/datum/antagonist/vampire as anything in GLOB.all_vampires) + for(var/datum/antagonist/vampire/vampire as anything in GLOB.all_vampires) to_chat(vampire.owner.current, span_narsiesmall("[full_name], also known as [owner.name || owner.current.real_name || owner.current.name], has claimed the role of Prince!")) vampire.can_become_prince = FALSE if(CONFIG_GET(flag/allow_vampire_scourge)) From 969d02d98bc0f0a7e52a6d0d71f84c5bcb4129bc Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Thu, 19 Mar 2026 19:08:43 +0300 Subject: [PATCH 070/149] =?UTF-8?q?=D1=84=D0=B8=D0=BA=D1=81=D1=8B=20=D0=B8?= =?UTF-8?q?=20=D0=B1=D0=BE=D0=BB=D1=8C=D1=88=D0=B5=20=D1=81=D0=BB=D0=BE?= =?UTF-8?q?=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- strings/fluffy/malkavian_revelations.json | 8 +++++++- tff_modular/modules/vampire/society.dm | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/strings/fluffy/malkavian_revelations.json b/strings/fluffy/malkavian_revelations.json index 76bdcada9a9..e9af750247d 100644 --- a/strings/fluffy/malkavian_revelations.json +++ b/strings/fluffy/malkavian_revelations.json @@ -63,6 +63,7 @@ "Потанцуем?", "Должен ли я делать то, что мне назначено? Или я должен пойти в шестую дорму? Другой вопрос заключается в том, почему такое существо как я имеет столь высокое либидо.", "#Цимисхи - милые ребята, они так завидуют Носферату и подражают им. Что ж, если они думают, что безобразие приводит к просветлению, я с радостью помогу им. У них слишком много конечностей, на мой вкус...", + "#Цимисхи... Пингвины. Они решили, что любят воду, и обменяли свои крылья на ласты. И они были так близко...", "#Ты живешь на островке невезения... Смерть предъявит на тебя право...", "#Не обращайте внимания на этого человека в углу. Он просто выдуманный друг, которого я перестал выдумывать, но он обиделся и остался.", "#Не считай безумие проклятием, смертный. Для некоторых это величайшее из благ. Горькая милость, возможно, но все же милость.", @@ -87,6 +88,11 @@ "#Я не из тех, кто жаждет крови, не из тех, кому не хватает насилия и не любитель проблем. Но и совесть меня не мучает.", "#Жирафы - бессердечные создания", "#Между годами серого существования и мигом надежды, я выбираю надежду", - "#Не пытки меня сломали. Не промывка мозгов. Не удар по голове. Не слуга Мансуса. Смерть..." + "#Не пытки меня сломали. Не промывка мозгов. Не удар по голове. Не слуга Мансуса. Смерть...", + "#Тремеры... Они. Идут. За нами...", + "#Вентру никогда не примут этого, не важно, кто попытается им это передать. И не говорите, что я вас не предупреждал.", + "#Бруха. Я бы хотел полюбить вашего обычного Бруха, но у него такой толстый череп, что он просто не может расколоть его и вытащить наружу все то хорошее, о существовании чего он даже не подозревает. Так что забудьте о нем.", + "#Кто же знал, что в такой небольшой женщине будет так много крови? Кроме Бога, разумеется — Бог знает все. Можем ли мы как-нибудь прибраться здесь?", + "#Брат Малахи, почему у меня так тяжело на душе?" ] } diff --git a/tff_modular/modules/vampire/society.dm b/tff_modular/modules/vampire/society.dm index 6d5f76b1ce8..cc75a96cd68 100644 --- a/tff_modular/modules/vampire/society.dm +++ b/tff_modular/modules/vampire/society.dm @@ -16,7 +16,7 @@ **/ /datum/antagonist/vampire/proc/princify() if(!can_become_prince) - return FALS + return FALSE rank_up(5, TRUE) // Rank up a lot. to_chat(owner.current, span_cult_bold("As a true prince, you find some of your old power returning to you!")) owner.current.playsound_local(null, 'tff_modular/modules/vampire/sound/prince.ogg', 100, FALSE, pressure_affected = FALSE) From e0d5c00895156fb41e91856df5a2c7e503c0f08f Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Thu, 19 Mar 2026 19:12:01 +0300 Subject: [PATCH 071/149] =?UTF-8?q?=D0=B2=D1=80=D0=B5=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D0=BD=D0=BE=20=D1=83=D0=B1=D0=B8=D1=80=D0=B0=D0=B5=D0=BC=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BF?= =?UTF-8?q?=D1=80=D0=B8=D0=BD=D1=86=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tff_modular/modules/vampire/clans/_clan.dm | 3 ++- tff_modular/modules/vampire/datum_vampire.dm | 4 +++- tff_modular/modules/vampire/society.dm | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/tff_modular/modules/vampire/clans/_clan.dm b/tff_modular/modules/vampire/clans/_clan.dm index 97651c52a8d..e3f7e4b2cf3 100644 --- a/tff_modular/modules/vampire/clans/_clan.dm +++ b/tff_modular/modules/vampire/clans/_clan.dm @@ -196,6 +196,7 @@ if(vampiredatum.vampire_level_unspent > 0) spend_rank(carbon_vampire) +/* /datum/vampire_clan/proc/prince_check() if(!vampiredatum.can_become_prince && !vampiredatum.vampire_level >= 10 && !vampiredatum.prince) return FALSE @@ -205,6 +206,7 @@ vampiredatum.princify() else if(tgui_answer == "No") vampiredatum.can_become_prince = FALSE +*/ /datum/vampire_clan/proc/finalize_spend_rank() // Level up the vampire @@ -224,7 +226,6 @@ Your strength, feed rate, regen rate, and maximum blood capacity have all increased! \n\ * Your existing powers have all ranked up as well!")) vampiredatum.update_hud() - prince_check() /datum/vampire_clan/proc/on_vampire_broke_masquerade(datum/source, datum/antagonist/vampire/masquerade_breaker) SIGNAL_HANDLER diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index c7cd64a48df..02479d606b5 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -37,12 +37,14 @@ /// Flavor only var/vampire_name + /* /// Can we become prince? var/can_become_prince = FALSE /// Are we the prince? var/prince = FALSE /// Are we the scourge? Literally only used for the examine. Okay. var/scourge = FALSE + */ /// Have we been broken the Masquerade? var/broke_masquerade = FALSE /// How many Masquerade Infractions do we have? @@ -350,7 +352,7 @@ SSvampire_leveling.check_enable() // Start society if we're the first vampire - check_start_society() + // check_start_society() if(!QDELETED(owner.current)) for(var/quirk_type in typesof(/datum/quirk/item_quirk/addict/junkie) + /datum/quirk/skittish) diff --git a/tff_modular/modules/vampire/society.dm b/tff_modular/modules/vampire/society.dm index cc75a96cd68..5a533f73b1b 100644 --- a/tff_modular/modules/vampire/society.dm +++ b/tff_modular/modules/vampire/society.dm @@ -1,6 +1,6 @@ /** * Resumes society, called when someone is assigned Vampire -**/ + /datum/antagonist/vampire/proc/check_start_society() if(!CONFIG_GET(flag/allow_vampire_prince)) return @@ -10,7 +10,7 @@ log_game("Vampire Society has started, as there are [length(GLOB.all_vampires)] vampires active.") else can_become_prince = FALSE - +**/ /** * Turns the player into a prince. **/ From 6693b1570e965a1d5f5b2f70137384f5ad9452cd Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Thu, 19 Mar 2026 19:43:23 +0300 Subject: [PATCH 072/149] Update datum_vampire.dm --- tff_modular/modules/vampire/datum_vampire.dm | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index 02479d606b5..13f976c4d28 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -37,14 +37,10 @@ /// Flavor only var/vampire_name - /* - /// Can we become prince? - var/can_become_prince = FALSE /// Are we the prince? var/prince = FALSE /// Are we the scourge? Literally only used for the examine. Okay. var/scourge = FALSE - */ /// Have we been broken the Masquerade? var/broke_masquerade = FALSE /// How many Masquerade Infractions do we have? From 8391384de22bbc126ecfe3f1d7efad9a1f66d3bf Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Thu, 19 Mar 2026 19:44:11 +0300 Subject: [PATCH 073/149] Update society.dm --- tff_modular/modules/vampire/society.dm | 3 --- 1 file changed, 3 deletions(-) diff --git a/tff_modular/modules/vampire/society.dm b/tff_modular/modules/vampire/society.dm index 5a533f73b1b..da10575bda0 100644 --- a/tff_modular/modules/vampire/society.dm +++ b/tff_modular/modules/vampire/society.dm @@ -15,8 +15,6 @@ * Turns the player into a prince. **/ /datum/antagonist/vampire/proc/princify() - if(!can_become_prince) - return FALSE rank_up(5, TRUE) // Rank up a lot. to_chat(owner.current, span_cult_bold("As a true prince, you find some of your old power returning to you!")) owner.current.playsound_local(null, 'tff_modular/modules/vampire/sound/prince.ogg', 100, FALSE, pressure_affected = FALSE) @@ -26,7 +24,6 @@ var/full_name = return_full_name() for(var/datum/antagonist/vampire/vampire as anything in GLOB.all_vampires) to_chat(vampire.owner.current, span_narsiesmall("[full_name], also known as [owner.name || owner.current.real_name || owner.current.name], has claimed the role of Prince!")) - vampire.can_become_prince = FALSE if(CONFIG_GET(flag/allow_vampire_scourge)) grant_power(new /datum/action/cooldown/vampire/targeted/scourgify) From 093c8c138d076a0e7addd4ef6d65fe6f2262736a Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sun, 22 Mar 2026 15:51:07 +0300 Subject: [PATCH 074/149] =?UTF-8?q?=D1=87=D0=B8=D0=BD=D0=B8=D0=BC=20=D1=83?= =?UTF-8?q?=D1=80=D0=BE=D0=BD,=20=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D1=8F?= =?UTF-8?q?=D0=B5=D0=BC=20=D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D1=83=20?= =?UTF-8?q?=D1=84=D0=BE=D1=80=D1=82=D0=B8=D1=82=D1=83=D0=B4=D0=B0,=20?= =?UTF-8?q?=D1=87=D0=B8=D0=BD=D0=B8=D0=BC=20=D0=B2=D1=82=D0=BE=D1=80=D0=BE?= =?UTF-8?q?=D0=B9=20=D1=83=D1=80=D0=BE=D0=B2=D0=B5=D0=BD=D1=8C=20=D1=8D?= =?UTF-8?q?=D0=BD=D1=82=D1=80=D0=B5=D0=BD=D1=81,=20=D0=BD=D0=B5=D1=80?= =?UTF-8?q?=D1=84=D0=B8=D0=BC=20=D1=89=D0=B8=D1=82=20=D0=B8=20=D1=82.?= =?UTF-8?q?=D0=B4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/__DEFINES/~ff_defines/bloodsucker.dm | 2 +- tff_modular/modules/vampire/clans/_clan.dm | 10 +++++++++ .../modules/vampire/clans/malkavian.dm | 1 - tff_modular/modules/vampire/clans/ventrue.dm | 1 - tff_modular/modules/vampire/datum_vampire.dm | 16 ++++++++------ .../modules/vampire/misc_procs_vampire.dm | 7 ------- .../vampire/powers/dominate/command.dm | 16 +++++++++----- .../vampire/powers/dominate/dominate.dm | 10 ++++----- .../vampire/powers/fortitude/fortitude.dm | 12 +++++++---- .../modules/vampire/powers/potence/brawn.dm | 21 ++++++++++++++----- .../modules/vampire/powers/potence/potence.dm | 4 +--- .../vampire/powers/presence/entrance.dm | 3 ++- .../vampire/powers/thaumaturgy/bloodbolt.dm | 6 ++++++ .../vampire/powers/thaumaturgy/bloodshield.dm | 4 ++-- 14 files changed, 72 insertions(+), 41 deletions(-) diff --git a/code/__DEFINES/~ff_defines/bloodsucker.dm b/code/__DEFINES/~ff_defines/bloodsucker.dm index c4070d0c45e..da4eb21a277 100644 --- a/code/__DEFINES/~ff_defines/bloodsucker.dm +++ b/code/__DEFINES/~ff_defines/bloodsucker.dm @@ -55,7 +55,7 @@ #define VITAE_GOAL_STANDARD 150 /// Default amount of damage the vampire's punch/kick damage increases with each level. -#define VAMPIRE_UNARMED_DMG_INCREASE_ON_RANKUP 1.25 +#define VAMPIRE_UNARMED_DMG_INCREASE_ON_RANKUP 1 /// How many starting levels do we want each one to have? #define VAMPIRE_STARTING_LEVELS 3 diff --git a/tff_modular/modules/vampire/clans/_clan.dm b/tff_modular/modules/vampire/clans/_clan.dm index e3f7e4b2cf3..32957ab982b 100644 --- a/tff_modular/modules/vampire/clans/_clan.dm +++ b/tff_modular/modules/vampire/clans/_clan.dm @@ -210,6 +210,16 @@ /datum/vampire_clan/proc/finalize_spend_rank() // Level up the vampire + if(ishuman(vampiredatum.owner.current)) + var/mob/living/carbon/human/human_user = vampiredatum.owner.current + var/obj/item/bodypart/user_left_hand = human_user.get_bodypart(BODY_ZONE_L_ARM) + var/obj/item/bodypart/user_right_hand = human_user.get_bodypart(BODY_ZONE_R_ARM) + user_left_hand.unarmed_damage_low += vampiredatum.extra_damage_per_rank + user_right_hand.unarmed_damage_low += vampiredatum.extra_damage_per_rank + // This affects the hitting power of Brawn. + user_left_hand.unarmed_damage_high += vampiredatum.extra_damage_per_rank + user_right_hand.unarmed_damage_high += vampiredatum.extra_damage_per_rank + vampiredatum.current_damage_bonus += vampiredatum.extra_damage_per_rank vampiredatum.vampire_regen_rate += 0.05 vampiredatum.max_vitae += 100 diff --git a/tff_modular/modules/vampire/clans/malkavian.dm b/tff_modular/modules/vampire/clans/malkavian.dm index 801f13b067e..304c04dda52 100644 --- a/tff_modular/modules/vampire/clans/malkavian.dm +++ b/tff_modular/modules/vampire/clans/malkavian.dm @@ -14,7 +14,6 @@ /datum/vampire_clan/malkavian/New(datum/antagonist/vampire/owner_datum) . = ..() - vampiredatum.owned_disciplines += new /datum/discipline/auspex(vampiredatum) vampiredatum.owned_disciplines += new /datum/discipline/obfuscate(vampiredatum) vampiredatum.owned_disciplines += new /datum/discipline/dominate(vampiredatum) diff --git a/tff_modular/modules/vampire/clans/ventrue.dm b/tff_modular/modules/vampire/clans/ventrue.dm index a5e8ce7bf6c..799cd5a4fe7 100644 --- a/tff_modular/modules/vampire/clans/ventrue.dm +++ b/tff_modular/modules/vampire/clans/ventrue.dm @@ -10,7 +10,6 @@ /datum/vampire_clan/ventrue/New(datum/antagonist/vampire/owner_datum) . = ..() - vampiredatum.owned_disciplines += new /datum/discipline/presence(vampiredatum) vampiredatum.owned_disciplines += new /datum/discipline/dominate/ventrue(vampiredatum) vampiredatum.owned_disciplines += new /datum/discipline/fortitude(vampiredatum) diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index 13f976c4d28..0e142bc91b3 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -20,6 +20,7 @@ /// How much blood we can have at once, increases per level. var/max_vitae = 600 + var/current_damage_bonus = 0 /// The vampire team, used for vassals var/datum/team/vampire/vampire_team /// The vampire's clan @@ -791,9 +792,13 @@ new_limb.burn_modifier /= initial(new_limb.burn_modifier) if(new_limb.body_zone in BODY_ZONES_LIMBS) - var/extra_damage = 2 + (vampire_level * extra_damage_per_rank) - new_limb.unarmed_damage_low += extra_damage - new_limb.unarmed_damage_high += extra_damage + var/obj/item/bodypart/user_left_hand = owner.get_bodypart(BODY_ZONE_L_ARM) + var/obj/item/bodypart/user_right_hand = owner.get_bodypart(BODY_ZONE_R_ARM) + user_left_hand.unarmed_damage_low = 5 + current_damage_bonus + user_right_hand.unarmed_damage_low = 5 + current_damage_bonus + // This affects the hitting power of Brawn. + user_left_hand.unarmed_damage_high = 10 + current_damage_bonus + user_right_hand.unarmed_damage_high = 10 + current_damage_bonus /datum/antagonist/vampire/proc/unregister_limb(mob/living/carbon/owner, obj/item/bodypart/lost_limb, special) SIGNAL_HANDLER @@ -806,10 +811,9 @@ lost_limb.burn_modifier *= initial(lost_limb.burn_modifier) if(lost_limb.body_zone in BODY_ZONES_LIMBS) - var/extra_damage = 2 + (vampire_level / extra_damage_per_rank) // safety measure in case we ever accidentally fuck up the math or something - lost_limb.unarmed_damage_low = max(lost_limb.unarmed_damage_low - extra_damage, initial(lost_limb.unarmed_damage_low)) - lost_limb.unarmed_damage_high = max(lost_limb.unarmed_damage_high - extra_damage, initial(lost_limb.unarmed_damage_high)) + lost_limb.unarmed_damage_low = max(lost_limb.unarmed_damage_low - current_damage_bonus, initial(lost_limb.unarmed_damage_low)) + lost_limb.unarmed_damage_high = max(lost_limb.unarmed_damage_high - current_damage_bonus, initial(lost_limb.unarmed_damage_high)) /datum/antagonist/vampire/proc/limb_gone(obj/item/bodypart/deleted_limb) SIGNAL_HANDLER diff --git a/tff_modular/modules/vampire/misc_procs_vampire.dm b/tff_modular/modules/vampire/misc_procs_vampire.dm index a8280557de3..ab3aac9c314 100644 --- a/tff_modular/modules/vampire/misc_procs_vampire.dm +++ b/tff_modular/modules/vampire/misc_procs_vampire.dm @@ -80,13 +80,6 @@ return FALSE vampire_level_unspent += levels - for(var/limb_slot, current_limb in affected_limbs) - var/obj/item/bodypart/limb = current_limb - if(QDELETED(limb) || !(limb_slot in BODY_ZONES_LIMBS)) - continue - // This affects the hitting power of regular unarmed attacks and Brawn. - limb.unarmed_damage_low += extra_damage_per_rank - limb.unarmed_damage_high += extra_damage_per_rank if(!my_clan) to_chat(owner.current, span_notice("You have grown in power. Join a clan to spend it.")) diff --git a/tff_modular/modules/vampire/powers/dominate/command.dm b/tff_modular/modules/vampire/powers/dominate/command.dm index 4c15760fc60..abef4d043a5 100644 --- a/tff_modular/modules/vampire/powers/dominate/command.dm +++ b/tff_modular/modules/vampire/powers/dominate/command.dm @@ -33,13 +33,18 @@ var/datum/weakref/target_ref /datum/action/cooldown/vampire/targeted/command/two - name = "Command" - power_time = 180 SECONDS + power_time = 120 SECONDS vitaecost = 120 - cooldown_time = 60 SECONDS - target_range = 6 + cooldown_time = 45 SECONDS + target_range = 5 channel_time = 4 SECONDS +/datum/action/cooldown/vampire/targeted/command/three + power_time = 180 SECONDS + cooldown_time = 50 SECONDS + target_range = 6 + level_current = 3 + /datum/action/cooldown/vampire/targeted/command/can_use() . = ..() if(!.) @@ -165,7 +170,8 @@ to_chat(owner, span_warning("The command '[span_bold("[command]")]' is forbidden!")) return FALSE */ - if(length_char(command) > 8) + var/max_lenght = 8 * level_current + if(length_char(command) > max_lenght) to_chat(owner, span_warning("Command too long!")) return FALSE diff --git a/tff_modular/modules/vampire/powers/dominate/dominate.dm b/tff_modular/modules/vampire/powers/dominate/dominate.dm index 6f4a99518de..992912844fa 100644 --- a/tff_modular/modules/vampire/powers/dominate/dominate.dm +++ b/tff_modular/modules/vampire/powers/dominate/dominate.dm @@ -5,13 +5,13 @@ // Base only has mez, ventrue get command earlier and can upgrade it level_1 = list(/datum/action/cooldown/vampire/targeted/mesmerize) - level_2 = list(/datum/action/cooldown/vampire/targeted/mesmerize/two) - level_3 = list(/datum/action/cooldown/vampire/targeted/mesmerize/three) - level_4 = list(/datum/action/cooldown/vampire/targeted/mesmerize/four, /datum/action/cooldown/vampire/targeted/command) + level_2 = list(/datum/action/cooldown/vampire/targeted/mesmerize/two, /datum/action/cooldown/vampire/targeted/command) + level_3 = list(/datum/action/cooldown/vampire/targeted/mesmerize/three, /datum/action/cooldown/vampire/targeted/command/two) + level_4 = list(/datum/action/cooldown/vampire/targeted/mesmerize/four, /datum/action/cooldown/vampire/targeted/command/three) level_5 = null /datum/discipline/dominate/ventrue level_1 = list(/datum/action/cooldown/vampire/targeted/mesmerize/two) - level_2 = list(/datum/action/cooldown/vampire/targeted/mesmerize/three) - level_3 = list(/datum/action/cooldown/vampire/targeted/mesmerize/four, /datum/action/cooldown/vampire/targeted/command/two) + level_2 = list(/datum/action/cooldown/vampire/targeted/mesmerize/three, /datum/action/cooldown/vampire/targeted/command/two) + level_3 = list(/datum/action/cooldown/vampire/targeted/mesmerize/four, /datum/action/cooldown/vampire/targeted/command/three) level_4 = null diff --git a/tff_modular/modules/vampire/powers/fortitude/fortitude.dm b/tff_modular/modules/vampire/powers/fortitude/fortitude.dm index 650b7114862..737ea6286a5 100644 --- a/tff_modular/modules/vampire/powers/fortitude/fortitude.dm +++ b/tff_modular/modules/vampire/powers/fortitude/fortitude.dm @@ -30,9 +30,8 @@ At level 4: Gain complete stun immunity." vampire_power_flags = BP_AM_TOGGLE | BP_AM_COSTLESS_UNCONSCIOUS vampire_check_flags = BP_CANT_USE_IN_TORPOR | BP_CANT_USE_IN_FRENZY | BP_CANT_USE_WHILE_STAKED - vitaecost = 10 + vitaecost = 50 cooldown_time = 5 SECONDS - constant_vitaecost = 1 var/resistance = 0.8 @@ -76,7 +75,6 @@ owner.balloon_alert(owner, "fortitude turned on.") to_chat(owner, span_notice("Your flesh has become as hard as steel!")) owner.playsound_local(null, 'tff_modular/modules/vampire/sound/fortitude_on.ogg', 100, FALSE, pressure_affected = FALSE) - // Traits & Effects if(pierce) ADD_TRAIT(owner, TRAIT_PIERCEIMMUNE, REF(src)) @@ -86,12 +84,17 @@ ADD_TRAIT(owner, TRAIT_PUSHIMMUNE, REF(src)) if(stun) ADD_TRAIT(owner, TRAIT_STUNIMMUNE, REF(src)) // They'll get stun resistance + this, who cares. - var/mob/living/carbon/human/user = owner + RegisterSignal(user, COMSIG_MOB_APPLY_DAMAGE, PROC_REF(on_take_damage)) user.physiology.brute_mod *= resistance user.physiology.stamina_mod *= resistance * 2 // Stamina resistance is half as effective because they have it inherently. user.physiology.burn_mod *= burn_resistance // they get burn resistance, but way less +/datum/action/cooldown/vampire/fortitude/proc/on_take_damage(datum/source, damage_amount, damage_type, ...) + SIGNAL_HANDLER + var/blood_to_consume = damage_amount / resistance + vampiredatum_power.adjust_blood_volume(-blood_to_consume) + /datum/action/cooldown/vampire/fortitude/use_power() . = ..() if(!.) @@ -106,6 +109,7 @@ return var/mob/living/carbon/human/vampire_user = owner + UnregisterSignal(vampire_user, COMSIG_MOB_APPLY_DAMAGE) vampire_user.physiology.brute_mod /= resistance vampire_user.physiology.burn_mod /= burn_resistance vampire_user.physiology.stamina_mod /= resistance * 2 diff --git a/tff_modular/modules/vampire/powers/potence/brawn.dm b/tff_modular/modules/vampire/powers/potence/brawn.dm index 1cf1058781d..afbda23e47d 100644 --- a/tff_modular/modules/vampire/powers/potence/brawn.dm +++ b/tff_modular/modules/vampire/powers/potence/brawn.dm @@ -4,7 +4,7 @@ button_icon_state = "power_strength" power_explanation = "Use this power to deal a horrific blow. Punching a Cyborg will EMP it and deal high damage.\n\ At level 3, you can break closets open and break restraints.\n\ - At level 4, you can bash airlocks open, and you get the ability to break even silver handcuffs. Use wisely - security is unlikely to try and capture you alive again after the first time!\n\ + At level 4, you can bash airlocks open, and you get the ability to brawn even mecha. Use wisely - security is unlikely to try and capture you alive again after the first time!\n\ Higher ranks will increase the damage when punching someone." vampire_power_flags = BP_AM_TOGGLE vampire_check_flags = BP_CANT_USE_IN_TORPOR | BP_CANT_USE_WHILE_STAKED | BP_CANT_USE_IN_FRENZY | BP_CANT_USE_WHILE_INCAPACITATED | BP_CANT_USE_WHILE_UNCONSCIOUS @@ -122,15 +122,13 @@ /datum/action/cooldown/vampire/targeted/brawn/fire_targeted_power(atom/target_atom, list/modifiers) . = ..() var/mob/living/carbon/carbon_owner = owner - + var/obj/item/bodypart/user_active_arm = carbon_owner.get_active_hand() + var/hit_strength = user_active_arm.unarmed_damage_high * damage_coefficient + 2 // Living Targets if(isliving(target_atom)) var/mob/living/living_target = target_atom // Strength of the attack - var/obj/item/bodypart/user_active_arm = carbon_owner.get_active_hand() - var/hit_strength = user_active_arm.unarmed_damage_high * damage_coefficient + 2 - var/powerlevel = min(5, 1 + level_current) if(rand(5 + powerlevel) >= 5) @@ -203,6 +201,13 @@ if(brujah && level_current >= 3 && target_airlock.locked) target_airlock.unbolt() target_airlock.open(BYPASS_DOOR_CHECKS) + else if(istype(target_atom, /obj/vehicle)) + var/obj/vehicle/target_vehicle = target_atom + playsound(get_turf(carbon_owner), 'sound/effects/grillehit.ogg', 80, TRUE, -1) + if(target_vehicle.Adjacent(carbon_owner)) + target_vehicle.visible_message(span_danger("[target_vehicle] breaks apart as [carbon_owner] bashes it!")) + target_vehicle.emp_act(EMP_HEAVY) + target_vehicle.take_damage(hit_strength) /datum/action/cooldown/vampire/targeted/brawn/check_valid_target(atom/target_atom) . = ..() @@ -232,4 +237,10 @@ if(target_closet.welded || target_closet.locked) return TRUE + if(istype(target_atom, /obj/vehicle)) + if(level_current < 4) + owner.balloon_alert(owner, "level 4 required!") + return FALSE + return TRUE + return FALSE diff --git a/tff_modular/modules/vampire/powers/potence/potence.dm b/tff_modular/modules/vampire/powers/potence/potence.dm index 9e5b4b073b4..7b4081d2e62 100644 --- a/tff_modular/modules/vampire/powers/potence/potence.dm +++ b/tff_modular/modules/vampire/powers/potence/potence.dm @@ -20,6 +20,4 @@ /datum/discipline/potence/apply_discipline_quirks(datum/antagonist/vampire/clan_owner) . = ..() - clan_owner.cleanup_limbs(clan_owner.owner.current) - clan_owner.extra_damage_per_rank = VAMPIRE_UNARMED_DMG_INCREASE_ON_RANKUP * 2 - clan_owner.setup_limbs(clan_owner.owner.current) + clan_owner.extra_damage_per_rank = VAMPIRE_UNARMED_DMG_INCREASE_ON_RANKUP * 1.5 diff --git a/tff_modular/modules/vampire/powers/presence/entrance.dm b/tff_modular/modules/vampire/powers/presence/entrance.dm index 53bd9f7136a..0d54121cbde 100644 --- a/tff_modular/modules/vampire/powers/presence/entrance.dm +++ b/tff_modular/modules/vampire/powers/presence/entrance.dm @@ -21,7 +21,8 @@ ranged_mousepointer = 'tff_modular/modules/vampire/icons/vampire_entrance.dmi' var/ignore_shielding = FALSE -/datum/action/cooldown/vampire/targeted/entrance/two +/datum/action/cooldown/vampire/targeted/entrance + ignore_shielding = TRUE /datum/action/cooldown/vampire/targeted/entrance/check_valid_target(atom/target_atom) . = ..() diff --git a/tff_modular/modules/vampire/powers/thaumaturgy/bloodbolt.dm b/tff_modular/modules/vampire/powers/thaumaturgy/bloodbolt.dm index 64e0b52f89a..daa7f01565b 100644 --- a/tff_modular/modules/vampire/powers/thaumaturgy/bloodbolt.dm +++ b/tff_modular/modules/vampire/powers/thaumaturgy/bloodbolt.dm @@ -71,4 +71,10 @@ visible_message(span_danger("[living_target]'s wounds spray boiling hot blood!"), span_userdanger("Oh god it burns!")) qdel(src) return BULLET_ACT_HIT + if(istype(target, /obj/vehicle)) + var/obj/vehicle/mecha = target + mecha.emp_act(EMP_HEAVY) + mecha.take_damage(damage) + qdel(src) + return BULLET_ACT_HIT . = ..() diff --git a/tff_modular/modules/vampire/powers/thaumaturgy/bloodshield.dm b/tff_modular/modules/vampire/powers/thaumaturgy/bloodshield.dm index bdef3ee26fa..a2230525cd9 100644 --- a/tff_modular/modules/vampire/powers/thaumaturgy/bloodshield.dm +++ b/tff_modular/modules/vampire/powers/thaumaturgy/bloodshield.dm @@ -52,7 +52,7 @@ icon_state = "blood_shield" lefthand_file = 'tff_modular/modules/vampire/icons/bs_leftinhand.dmi' righthand_file = 'tff_modular/modules/vampire/icons/bs_rightinhand.dmi' - block_chance = 100 + block_chance = 75 /obj/item/shield/vampire/Initialize(mapload) . = ..() @@ -66,4 +66,4 @@ . = ..() if(. && damage > 0) var/datum/antagonist/vampire/vampire = IS_VAMPIRE(owner) - vampire?.adjust_blood_volume(-15) + vampire?.adjust_blood_volume(-7.5) From e2fa9d562fb217012c6a27fa98962f623bdfe6a6 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Wed, 25 Mar 2026 17:42:35 +0300 Subject: [PATCH 075/149] oinkball --- .../vampire/powers/dominate/command.dm | 30 ++++++++++++++----- .../vampire/powers/dominate/dominate.dm | 17 +++++------ .../vampire/powers/dominate/mesmerize.dm | 12 ++++---- .../vampire/powers/presence/entrance.dm | 8 ++++- .../modules/vampire/powers/presence/summon.dm | 8 ++++- 5 files changed, 50 insertions(+), 25 deletions(-) diff --git a/tff_modular/modules/vampire/powers/dominate/command.dm b/tff_modular/modules/vampire/powers/dominate/command.dm index abef4d043a5..84127c1e4af 100644 --- a/tff_modular/modules/vampire/powers/dominate/command.dm +++ b/tff_modular/modules/vampire/powers/dominate/command.dm @@ -25,7 +25,7 @@ ranged_mousepointer = 'tff_modular/modules/vampire/icons/vampire_command.dmi' /// How long the command is in effect. - var/power_time = 60 SECONDS + var/power_time = 120 SECONDS /// How long you have to channel in order to command someone. var/channel_time = 7 SECONDS @@ -33,17 +33,31 @@ var/datum/weakref/target_ref /datum/action/cooldown/vampire/targeted/command/two - power_time = 120 SECONDS - vitaecost = 120 - cooldown_time = 45 SECONDS - target_range = 5 + power_time = 240 SECONDS + vitaecost = 100 channel_time = 4 SECONDS + level_current = 2 /datum/action/cooldown/vampire/targeted/command/three - power_time = 180 SECONDS - cooldown_time = 50 SECONDS - target_range = 6 + power_time = 360 SECONDS level_current = 3 + target_range = 5 + channel_time = 4 SECONDS + vitaecost = 110 + +/datum/action/cooldown/vampire/targeted/command/four + power_time = 480 SECONDS + level_current = 4 + target_range = 5 + channel_time = 4 SECONDS + vitaecost = 120 + +/datum/action/cooldown/vampire/targeted/command/five + power_time = 600 SECONDS + level_current = 5 + target_range = 5 + channel_time = 4 SECONDS + vitaecost = 130 /datum/action/cooldown/vampire/targeted/command/can_use() . = ..() diff --git a/tff_modular/modules/vampire/powers/dominate/dominate.dm b/tff_modular/modules/vampire/powers/dominate/dominate.dm index 992912844fa..5063ad61b8a 100644 --- a/tff_modular/modules/vampire/powers/dominate/dominate.dm +++ b/tff_modular/modules/vampire/powers/dominate/dominate.dm @@ -4,14 +4,13 @@ icon_state = "dominate" // Base only has mez, ventrue get command earlier and can upgrade it - level_1 = list(/datum/action/cooldown/vampire/targeted/mesmerize) - level_2 = list(/datum/action/cooldown/vampire/targeted/mesmerize/two, /datum/action/cooldown/vampire/targeted/command) - level_3 = list(/datum/action/cooldown/vampire/targeted/mesmerize/three, /datum/action/cooldown/vampire/targeted/command/two) - level_4 = list(/datum/action/cooldown/vampire/targeted/mesmerize/four, /datum/action/cooldown/vampire/targeted/command/three) - level_5 = null + level_1 = list(/datum/action/cooldown/vampire/targeted/mesmerize, /datum/action/cooldown/vampire/targeted/command) + level_2 = list(/datum/action/cooldown/vampire/targeted/mesmerize/two, /datum/action/cooldown/vampire/targeted/command/two) + level_3 = list(/datum/action/cooldown/vampire/targeted/mesmerize/three, /datum/action/cooldown/vampire/targeted/command/three) + level_4 = list(/datum/action/cooldown/vampire/targeted/mesmerize/four, /datum/action/cooldown/vampire/targeted/command/four) + level_5 = list(/datum/action/cooldown/vampire/targeted/mesmerize/four, /datum/action/cooldown/vampire/targeted/command/five) /datum/discipline/dominate/ventrue - level_1 = list(/datum/action/cooldown/vampire/targeted/mesmerize/two) - level_2 = list(/datum/action/cooldown/vampire/targeted/mesmerize/three, /datum/action/cooldown/vampire/targeted/command/two) - level_3 = list(/datum/action/cooldown/vampire/targeted/mesmerize/four, /datum/action/cooldown/vampire/targeted/command/three) - level_4 = null + level_1 = list(/datum/action/cooldown/vampire/targeted/mesmerize/three, /datum/action/cooldown/vampire/targeted/command/three) + level_2 = list(/datum/action/cooldown/vampire/targeted/mesmerize/four, /datum/action/cooldown/vampire/targeted/command/four) + level_3 = list(/datum/action/cooldown/vampire/targeted/mesmerize/four, /datum/action/cooldown/vampire/targeted/command/five) diff --git a/tff_modular/modules/vampire/powers/dominate/mesmerize.dm b/tff_modular/modules/vampire/powers/dominate/mesmerize.dm index cf54f9d4c69..3652f8b23a7 100644 --- a/tff_modular/modules/vampire/powers/dominate/mesmerize.dm +++ b/tff_modular/modules/vampire/powers/dominate/mesmerize.dm @@ -19,9 +19,9 @@ At level 4, you will be able to mesmerize regardless of your target's direction." vampire_power_flags = NONE vampire_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 - vitaecost = 40 - cooldown_time = 10 SECONDS - target_range = 4 + vitaecost = 50 + cooldown_time = 16 SECONDS + target_range = 3 power_activates_immediately = FALSE prefire_message = "Whom will you submit to your will?" level_current = 1 @@ -30,23 +30,23 @@ /// Reference to the target var/datum/weakref/target_ref /// How long it takes us to mesmerize our target. - var/mesmerize_delay = 5 SECONDS + var/mesmerize_delay = 6 SECONDS /datum/action/cooldown/vampire/targeted/mesmerize/Destroy() target_ref = null return ..() /datum/action/cooldown/vampire/targeted/mesmerize/two - vitaecost = 30 level_current = 2 /datum/action/cooldown/vampire/targeted/mesmerize/three - vitaecost = 40 level_current = 3 + target_range = 4 /datum/action/cooldown/vampire/targeted/mesmerize/four vitaecost = 60 level_current = 4 + target_range = 4 /datum/action/cooldown/vampire/targeted/mesmerize/can_use() . = ..() diff --git a/tff_modular/modules/vampire/powers/presence/entrance.dm b/tff_modular/modules/vampire/powers/presence/entrance.dm index 0d54121cbde..fa6615b9d8c 100644 --- a/tff_modular/modules/vampire/powers/presence/entrance.dm +++ b/tff_modular/modules/vampire/powers/presence/entrance.dm @@ -37,10 +37,16 @@ owner.balloon_alert(owner, "[carbon_target] is mindless.") return FALSE - if(HAS_MIND_TRAIT(carbon_target, TRAIT_VAMPIRE_ALIGNED) || IS_CURATOR(carbon_target)) + if(IS_CURATOR(carbon_target)) owner.balloon_alert(owner, "immune to your presence.") return FALSE + if(IS_VAMPIRE(carbon_target)) + var/datum/antagonist/vampire/vampire_target = carbon_target + if(vampire_target.vampire_level >= vampiredatum_power.vampire_level) + to_chat(owner, span_danger("You can't influence a vampire above your level!")) + return FALSE + if(carbon_target.stat != CONSCIOUS) owner.balloon_alert(owner, "[carbon_target] is not [(carbon_target.stat == DEAD || HAS_TRAIT(carbon_target, TRAIT_FAKEDEATH)) ? "alive" : "conscious"].") return FALSE diff --git a/tff_modular/modules/vampire/powers/presence/summon.dm b/tff_modular/modules/vampire/powers/presence/summon.dm index af9d45db445..ea6e7ce93ad 100644 --- a/tff_modular/modules/vampire/powers/presence/summon.dm +++ b/tff_modular/modules/vampire/powers/presence/summon.dm @@ -39,10 +39,16 @@ owner.balloon_alert(owner, "[carbon_target] is mindless.") return FALSE - if(HAS_MIND_TRAIT(carbon_target, TRAIT_VAMPIRE_ALIGNED) || IS_CURATOR(carbon_target)) + if(IS_CURATOR(carbon_target)) owner.balloon_alert(owner, "immune to your presence.") return FALSE + if(IS_VAMPIRE(carbon_target)) + var/datum/antagonist/vampire/vampire_target = carbon_target + if(vampire_target.vampire_level >= vampiredatum_power.vampire_level) + to_chat(owner, span_danger("You can't influence a vampire above your level!")) + return FALSE + if(HAS_SILICON_ACCESS(carbon_target)) owner.balloon_alert(owner, "[carbon_target] is immune.") return FALSE From 32a6c28e1349e37a79182362bc81b71eacad1b03 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Wed, 25 Mar 2026 17:47:34 +0300 Subject: [PATCH 076/149] Update command.dm --- tff_modular/modules/vampire/powers/dominate/command.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/tff_modular/modules/vampire/powers/dominate/command.dm b/tff_modular/modules/vampire/powers/dominate/command.dm index 84127c1e4af..19bf0596a8a 100644 --- a/tff_modular/modules/vampire/powers/dominate/command.dm +++ b/tff_modular/modules/vampire/powers/dominate/command.dm @@ -10,7 +10,6 @@ power_explanation = "Click any player to attempt to compel them.\n\ If your target is already commanded, a Curator, or a vampire, you will fail.\n\ Once commanded, the target will do their best to fulfill it, with a duration scaling with level.\n\ - If your target is mindshielded, your command's duration will be halved, and commanding them will take longer.\n\ At level 1, your command will stay for 60 seconds.\n\ At level 2, it will remain for 3 minutes.\n\ Be smart with your wording. They will become pacified, and won't obey violent commands.\n\ From 9119f1355dac07fc9e63f2f9ff75fceb1e8a0bbf Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Wed, 25 Mar 2026 19:37:56 +0300 Subject: [PATCH 077/149] =?UTF-8?q?=D1=87=D0=B8=D0=BD=D0=B8=D0=BC=20=D0=B4?= =?UTF-8?q?=D0=BB=D1=8F=20=D0=B1=D0=B0=D1=82=D1=87=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tff_modular/modules/vampire/crafts.dm | 29 ++----------------- .../modules/vampire/objects/blood_throne.dm | 2 +- .../vampire/powers/dominate/command.dm | 2 ++ tff_modular/modules/vampire/powers/gohome.dm | 4 +-- .../vampire/powers/obfuscate/trespass.dm | 5 +++- .../modules/vampire/powers/obfuscate/veil.dm | 2 ++ 6 files changed, 13 insertions(+), 31 deletions(-) diff --git a/tff_modular/modules/vampire/crafts.dm b/tff_modular/modules/vampire/crafts.dm index 5bc0614fe84..9e6c066b8e9 100644 --- a/tff_modular/modules/vampire/crafts.dm +++ b/tff_modular/modules/vampire/crafts.dm @@ -55,6 +55,7 @@ category = CAT_VAMPIRE crafting_flags = CRAFT_SKIP_MATERIALS_PARITY | CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND | CRAFT_MUST_BE_LEARNED +/* /datum/crafting_recipe/bloodthrone name = "Blood Throne" result = /obj/structure/vampire/bloodthrone @@ -67,6 +68,7 @@ category = CAT_VAMPIRE crafting_flags = CRAFT_SKIP_MATERIALS_PARITY | CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND | CRAFT_MUST_BE_LEARNED +*/ /datum/crafting_recipe/meatcoffin name = "Meat Coffin" @@ -93,33 +95,6 @@ category = CAT_VAMPIRE crafting_flags = CRAFT_SKIP_MATERIALS_PARITY | CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND | CRAFT_MUST_BE_LEARNED -/datum/crafting_recipe/candelabrum - name = "Candelabrum" - result = /obj/structure/vampire/candelabrum - time = 5 SECONDS - - reqs = list( - /obj/item/stack/sheet/iron = 1, - /obj/item/stack/rods = 3, - /obj/item/flashlight/flare/candle = 2, - ) - - category = CAT_VAMPIRE - crafting_flags = CRAFT_SKIP_MATERIALS_PARITY | CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND | CRAFT_MUST_BE_LEARNED - -/datum/crafting_recipe/bloodthrone - name = "Blood Throne" - result = /obj/structure/vampire/bloodthrone - time = 5 SECONDS - - reqs = list( - /obj/item/stack/sheet/iron = 10, - /obj/item/stack/rods = 2, - ) - - category = CAT_VAMPIRE - crafting_flags = CRAFT_SKIP_MATERIALS_PARITY | CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND | CRAFT_MUST_BE_LEARNED - /datum/crafting_recipe/blackcoffin name = "Black Coffin" result = /obj/structure/closet/crate/coffin/blackcoffin diff --git a/tff_modular/modules/vampire/objects/blood_throne.dm b/tff_modular/modules/vampire/objects/blood_throne.dm index 6072c9bc13f..7d898a81489 100644 --- a/tff_modular/modules/vampire/objects/blood_throne.dm +++ b/tff_modular/modules/vampire/objects/blood_throne.dm @@ -16,7 +16,7 @@ // Add rotating and armrest /obj/structure/vampire/bloodthrone/Initialize(mapload) - AddComponent(/datum/component/simple_rotation) + // AddComponent(/datum/component/simple_rotation) return ..() // Rotating diff --git a/tff_modular/modules/vampire/powers/dominate/command.dm b/tff_modular/modules/vampire/powers/dominate/command.dm index 19bf0596a8a..794b571e9cd 100644 --- a/tff_modular/modules/vampire/powers/dominate/command.dm +++ b/tff_modular/modules/vampire/powers/dominate/command.dm @@ -104,10 +104,12 @@ owner.balloon_alert(owner, "[living_target] is not [(living_target.stat == DEAD || HAS_TRAIT(living_target, TRAIT_FAKEDEATH)) ? "alive" : "conscious"].") return FALSE + /* // Is our target deaf? if(!living_target.can_hear()) owner.balloon_alert(owner, "[living_target] cannot hear you!") return FALSE + */ // Is our target a silicon? if(issilicon(living_target)) diff --git a/tff_modular/modules/vampire/powers/gohome.dm b/tff_modular/modules/vampire/powers/gohome.dm index f710d22ec66..970d5d7f556 100644 --- a/tff_modular/modules/vampire/powers/gohome.dm +++ b/tff_modular/modules/vampire/powers/gohome.dm @@ -75,11 +75,11 @@ user.uncuff() playsound(current_turf, 'sound/effects/magic/summon_karp.ogg', 60, 1) - + /* var/datum/effect_system/steam_spread/vampire/puff = new /datum/effect_system/steam_spread/vampire() puff.set_up(3, 0, current_turf) puff.start() - + */ /// STEP FIVE: Create animal at prev location var/mob/living/simple_animal/new_mob = pick_weight(spawning_mobs) new new_mob(current_turf) diff --git a/tff_modular/modules/vampire/powers/obfuscate/trespass.dm b/tff_modular/modules/vampire/powers/obfuscate/trespass.dm index 39c6e1c65b7..4885c63f929 100644 --- a/tff_modular/modules/vampire/powers/obfuscate/trespass.dm +++ b/tff_modular/modules/vampire/powers/obfuscate/trespass.dm @@ -72,10 +72,11 @@ // Effect Origin var/sound_strength = max(40, 100 - level_current * 20) playsound(get_turf(owner), 'sound/effects/magic/summon_karp.ogg', vol = sound_strength, vary = TRUE) + /* var/datum/effect_system/steam_spread/vampire/puff = new /datum/effect_system/steam_spread() puff.set_up(3, FALSE, my_turf) puff.start() - + */ var/mist_delay = max(5, 20 - level_current * 2.5) // Level up and do this faster. // Freeze Me @@ -102,6 +103,8 @@ check_witnesses() // Effect Destination playsound(get_turf(owner), 'sound/effects/magic/summon_karp.ogg', vol = 60, vary = TRUE) + /* puff = new /datum/effect_system/steam_spread() puff.set_up(3, FALSE, target_turf) puff.start() + */ diff --git a/tff_modular/modules/vampire/powers/obfuscate/veil.dm b/tff_modular/modules/vampire/powers/obfuscate/veil.dm index 694bab8b0ef..e0e970374bc 100644 --- a/tff_modular/modules/vampire/powers/obfuscate/veil.dm +++ b/tff_modular/modules/vampire/powers/obfuscate/veil.dm @@ -61,10 +61,12 @@ /datum/action/cooldown/vampire/veil/proc/cast_effect() // Effect playsound(get_turf(owner), 'sound/effects/smoke.ogg', 20, 1) + /* var/datum/effect_system/steam_spread/vampire/puff = new /datum/effect_system/steam_spread/() puff.set_up(3, 0, get_turf(owner)) puff.attach(owner) //OPTIONAL puff.start() + */ owner.spin(0.8 SECONDS, 1) //Spin around like a loon. check_witnesses() From 4ed0ce144c501a8b86debac17443ac98a263cf1b Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Wed, 25 Mar 2026 19:42:54 +0300 Subject: [PATCH 078/149] =?UTF-8?q?=D1=87=D0=B8=D0=BD=D0=B8=D0=BC=20=D0=B4?= =?UTF-8?q?=D0=BB=D1=8F=20=D0=B1=D0=B0=D1=82=D1=87=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tff_modular/modules/vampire/datum_vampire.dm | 2 +- tff_modular/modules/vampire/powers/gohome.dm | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index 0e142bc91b3..1e22df0435c 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -367,7 +367,7 @@ owner.forget_crafting_recipe(list( /datum/crafting_recipe/vassalrack, /datum/crafting_recipe/candelabrum, - /datum/crafting_recipe/bloodthrone, + // /datum/crafting_recipe/bloodthrone, /datum/crafting_recipe/meatcoffin, )) diff --git a/tff_modular/modules/vampire/powers/gohome.dm b/tff_modular/modules/vampire/powers/gohome.dm index 970d5d7f556..91040ab8cff 100644 --- a/tff_modular/modules/vampire/powers/gohome.dm +++ b/tff_modular/modules/vampire/powers/gohome.dm @@ -92,8 +92,10 @@ deactivate_power() +/* /datum/effect_system/steam_spread/vampire effect_type = /obj/effect/particle_effect/fluid/smoke/vampsmoke +*/ #undef GOHOME_START #undef GOHOME_FLICKER_ONE From a6419b79fded5099293349706db2dabd950e576a Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Wed, 25 Mar 2026 19:43:23 +0300 Subject: [PATCH 079/149] Update datum_vampire.dm --- tff_modular/modules/vampire/datum_vampire.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index 1e22df0435c..6009e136381 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -330,7 +330,7 @@ owner.teach_crafting_recipe(list( /datum/crafting_recipe/vassalrack, /datum/crafting_recipe/candelabrum, - /datum/crafting_recipe/bloodthrone, + // /datum/crafting_recipe/bloodthrone, /datum/crafting_recipe/meatcoffin, )) From 212f11dc798b2b0e4c946a3644caeb7dae44b768 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Thu, 26 Mar 2026 00:38:38 +0300 Subject: [PATCH 080/149] Update command.dm --- tff_modular/modules/vampire/powers/dominate/command.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tff_modular/modules/vampire/powers/dominate/command.dm b/tff_modular/modules/vampire/powers/dominate/command.dm index 794b571e9cd..8a4babc607b 100644 --- a/tff_modular/modules/vampire/powers/dominate/command.dm +++ b/tff_modular/modules/vampire/powers/dominate/command.dm @@ -154,7 +154,7 @@ living_target.add_client_colour(/datum/client_colour/glass_colour/pink, CLIENT_COLOR_SOURCE_VAMPIRE) if(!do_after(owner, modified_delay, living_target, IGNORE_TARGET_LOC_CHANGE | IGNORE_HELD_ITEM, extra_checks = CALLBACK(src, PROC_REF(continue_active)), hidden = TRUE)) living_target.balloon_alert(living_target, "your thoughts come back into focus.") - living_target.remove_client_colour(/datum/client_colour/glass_colour/pink) + living_target.remove_client_colour(CLIENT_COLOR_SOURCE_VAMPIRE) deactivate_power() return living_target.remove_client_colour(CLIENT_COLOR_SOURCE_VAMPIRE) @@ -162,6 +162,7 @@ // they're out of range once more if(!(living_target in hearers(target_range, owner))) living_target.balloon_alert(living_target, "your thoughts come back into focus.") + living_target.remove_client_colour(CLIENT_COLOR_SOURCE_VAMPIRE) deactivate_power() return From 95b2aebfba249e74afc607aa5215cff4f1160cc7 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sat, 28 Mar 2026 03:51:28 +0300 Subject: [PATCH 081/149] Update command.dm --- .../modules/vampire/powers/dominate/command.dm | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/tff_modular/modules/vampire/powers/dominate/command.dm b/tff_modular/modules/vampire/powers/dominate/command.dm index 8a4babc607b..9e4bfbe88fe 100644 --- a/tff_modular/modules/vampire/powers/dominate/command.dm +++ b/tff_modular/modules/vampire/powers/dominate/command.dm @@ -17,14 +17,14 @@ vampire_power_flags = NONE vampire_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 vitaecost = 80 - cooldown_time = 40 SECONDS - target_range = 4 + cooldown_time = 90 SECONDS + target_range = 3 power_activates_immediately = FALSE prefire_message = "Whom will you subvert to your will?" ranged_mousepointer = 'tff_modular/modules/vampire/icons/vampire_command.dmi' /// How long the command is in effect. - var/power_time = 120 SECONDS + var/power_time = 60 SECONDS /// How long you have to channel in order to command someone. var/channel_time = 7 SECONDS @@ -32,31 +32,30 @@ var/datum/weakref/target_ref /datum/action/cooldown/vampire/targeted/command/two - power_time = 240 SECONDS + power_time = 80 SECONDS vitaecost = 100 channel_time = 4 SECONDS level_current = 2 /datum/action/cooldown/vampire/targeted/command/three - power_time = 360 SECONDS + power_time = 100 SECONDS level_current = 3 target_range = 5 channel_time = 4 SECONDS - vitaecost = 110 /datum/action/cooldown/vampire/targeted/command/four - power_time = 480 SECONDS + power_time = 120 SECONDS level_current = 4 target_range = 5 channel_time = 4 SECONDS vitaecost = 120 /datum/action/cooldown/vampire/targeted/command/five - power_time = 600 SECONDS + power_time = 120 SECONDS level_current = 5 target_range = 5 channel_time = 4 SECONDS - vitaecost = 130 + vitaecost = 120 /datum/action/cooldown/vampire/targeted/command/can_use() . = ..() From 31cc8694f7b043b2e5c024d16d6bdad3d6234057 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sun, 29 Mar 2026 16:36:50 +0300 Subject: [PATCH 082/149] =?UTF-8?q?=D1=87=D0=B8=D0=BD=D0=B8=D0=BC=20=D0=BE?= =?UTF-8?q?=D1=88=D0=B8=D0=B1=D0=BA=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tff_modular/modules/vampire/clans/debug.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tff_modular/modules/vampire/clans/debug.dm b/tff_modular/modules/vampire/clans/debug.dm index 94649baaf2d..7067889207c 100644 --- a/tff_modular/modules/vampire/clans/debug.dm +++ b/tff_modular/modules/vampire/clans/debug.dm @@ -9,7 +9,7 @@ /datum/vampire_clan/debug/New(datum/antagonist/vampire/owner_datum) . = ..() vampiredatum.vampire_level_unspent = 35 - vampiredatum.owned_disciplines += new /datum/discipline/auspex/malkavian(vampiredatum) + vampiredatum.owned_disciplines += new /datum/discipline/auspex(vampiredatum) vampiredatum.owned_disciplines += new /datum/discipline/celerity(vampiredatum) vampiredatum.owned_disciplines += new /datum/discipline/dominate/ventrue(vampiredatum) vampiredatum.owned_disciplines += new /datum/discipline/fortitude(vampiredatum) From f653da3588a3473a8fded31c8cf5c00568918dd4 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Tue, 31 Mar 2026 17:30:21 +0300 Subject: [PATCH 083/149] =?UTF-8?q?=D1=87=D0=B8=D0=BD=D0=B8=D0=BC=20=D1=81?= =?UTF-8?q?=D0=BC=D0=B5=D1=80=D1=82=D1=8C=20=D0=B2=D1=81=D0=B5=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=BD=D0=BE=D0=B9=20=D0=BF=D0=BE=D1=81=D0=BB=D0=B5=20?= =?UTF-8?q?=D1=81=D0=BC=D0=B5=D1=80=D1=82=D0=B8,=20=D1=83=D0=BB=D1=83?= =?UTF-8?q?=D1=87=D1=88=D0=B0=D0=B5=D0=BC/=D0=B1=D1=83=D0=B1=D0=BB=D0=B8?= =?UTF-8?q?=D0=BC=20=D1=84=D0=BE=D1=80=D1=82=D0=B8=D1=82=D1=83=D0=B4,=20?= =?UTF-8?q?=D1=83=D0=B1=D0=B8=D1=80=D0=B0=D0=B5=D0=BC=20=D0=BE=D0=B4=D0=BD?= =?UTF-8?q?=D1=83=20=D0=B0=D0=B1=D0=B8=D0=BB=D0=BE=D1=87=D0=BA=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tff_modular/modules/vampire/frenzy_vampire.dm | 5 +++-- tff_modular/modules/vampire/powers/fortitude/fortitude.dm | 6 +++--- tff_modular/modules/vampire/powers/obfuscate/obfuscate.dm | 6 +++--- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/tff_modular/modules/vampire/frenzy_vampire.dm b/tff_modular/modules/vampire/frenzy_vampire.dm index d5e2e91257d..ea824ef459c 100644 --- a/tff_modular/modules/vampire/frenzy_vampire.dm +++ b/tff_modular/modules/vampire/frenzy_vampire.dm @@ -100,8 +100,9 @@ if(vampiredatum.current_vitae >= FRENZY_THRESHOLD_EXIT) qdel(src) return - carbon_owner.adjust_fire_loss(0.75 + (vampiredatum.vampire_level * 0.05)) - carbon_owner.set_jitter_if_lower(10 SECONDS) + if(carbon_owner.stat != DEAD || !HAS_TRAIT(carbon_owner, TRAIT_TORPOR)) + carbon_owner.adjust_fire_loss(0.75 + (vampiredatum.vampire_level * 0.05)) + carbon_owner.set_jitter_if_lower(10 SECONDS) /datum/status_effect/frenzy/get_examine_text() return span_danger("[owner.p_They()] seem[owner.p_s()]... inhumane, and feral!") diff --git a/tff_modular/modules/vampire/powers/fortitude/fortitude.dm b/tff_modular/modules/vampire/powers/fortitude/fortitude.dm index 737ea6286a5..1d8611e12b6 100644 --- a/tff_modular/modules/vampire/powers/fortitude/fortitude.dm +++ b/tff_modular/modules/vampire/powers/fortitude/fortitude.dm @@ -41,7 +41,7 @@ var/dismember = FALSE var/stun = FALSE - var/burn_resistance = 0.8 + var/burn_resistance = 0.9 /datum/action/cooldown/vampire/fortitude/two vitaecost = 20 @@ -63,7 +63,7 @@ /datum/action/cooldown/vampire/fortitude/four vitaecost = 20 constant_vitaecost = 2 - resistance = 0.4 + resistance = 0.3 burn_resistance = 0.6 pierce = TRUE push = TRUE @@ -92,7 +92,7 @@ /datum/action/cooldown/vampire/fortitude/proc/on_take_damage(datum/source, damage_amount, damage_type, ...) SIGNAL_HANDLER - var/blood_to_consume = damage_amount / resistance + var/blood_to_consume = damage_amount / (resistance + 0.1) vampiredatum_power.adjust_blood_volume(-blood_to_consume) /datum/action/cooldown/vampire/fortitude/use_power() diff --git a/tff_modular/modules/vampire/powers/obfuscate/obfuscate.dm b/tff_modular/modules/vampire/powers/obfuscate/obfuscate.dm index 6bf6755a0e6..b989db5145c 100644 --- a/tff_modular/modules/vampire/powers/obfuscate/obfuscate.dm +++ b/tff_modular/modules/vampire/powers/obfuscate/obfuscate.dm @@ -4,8 +4,8 @@ icon_state = "obfuscate" // Lists of abilities granted per level - level_1 = list(/datum/action/cooldown/vampire/veil, /datum/action/cooldown/vampire/targeted/trespass) - level_2 = list(/datum/action/cooldown/vampire/cloak, /datum/action/cooldown/vampire/veil, /datum/action/cooldown/vampire/targeted/trespass/two) - level_3 = list(/datum/action/cooldown/vampire/cloak/two, /datum/action/cooldown/vampire/targeted/trespass/three, /datum/action/cooldown/vampire/veil) + level_1 = list(/datum/action/cooldown/vampire/targeted/trespass) + level_2 = list(/datum/action/cooldown/vampire/cloak, /datum/action/cooldown/vampire/targeted/trespass/two) + level_3 = list(/datum/action/cooldown/vampire/cloak/two, /datum/action/cooldown/vampire/targeted/trespass/three) level_4 = null level_5 = null From 06315b9f8385ab25040a6b18acb91747fb708668 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Wed, 1 Apr 2026 16:22:47 +0300 Subject: [PATCH 084/149] MM THATS SO GOOD --- tff_modular/modules/vampire/powers/feed.dm | 4 ++-- tff_modular/modules/vampire/sound/aaughmp3.ogg | Bin 0 -> 70486 bytes .../vampire/sound/nom-nom-nom_gPJiWn4.ogg | Bin 0 -> 27517 bytes .../modules/vampire/sound/peter-hehehe.ogg | Bin 0 -> 89789 bytes .../modules/vampire/sound/so-good-and-tasty.ogg | Bin 0 -> 75607 bytes 5 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 tff_modular/modules/vampire/sound/aaughmp3.ogg create mode 100644 tff_modular/modules/vampire/sound/nom-nom-nom_gPJiWn4.ogg create mode 100644 tff_modular/modules/vampire/sound/peter-hehehe.ogg create mode 100644 tff_modular/modules/vampire/sound/so-good-and-tasty.ogg diff --git a/tff_modular/modules/vampire/powers/feed.dm b/tff_modular/modules/vampire/powers/feed.dm index a3bd237b1b9..a676427fe2c 100644 --- a/tff_modular/modules/vampire/powers/feed.dm +++ b/tff_modular/modules/vampire/powers/feed.dm @@ -214,8 +214,8 @@ // It begins... currently_feeding = TRUE - living_owner.playsound_local(null, 'tff_modular/modules/vampire/sound/drinkblood1.ogg', 100, FALSE, pressure_affected = FALSE) - + var/sound_of_feeding = pick('tff_modular/modules/vampire/sound/aaughmp3.ogg', 'tff_modular/modules/vampire/sound/nom-nom-nom_gPJiWn4.ogg', 'tff_modular/modules/vampire/sound/so-good-and-tasty.ogg', 'tff_modular/modules/vampire/sound/peter-hehehe.ogg') + playsound(living_owner, sound_of_feeding, 100, FALSE, pressure_affected = FALSE) // Just to make sure living_owner.stop_pulling() feed_target.stop_pulling() diff --git a/tff_modular/modules/vampire/sound/aaughmp3.ogg b/tff_modular/modules/vampire/sound/aaughmp3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..83f11f3f6e74ccaae7cef91881c4c70bf4c24649 GIT binary patch literal 70486 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%0DusR14w>EX?MnfU(?c| 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 literal 0 HcmV?d00001 diff --git a/tff_modular/modules/vampire/sound/nom-nom-nom_gPJiWn4.ogg b/tff_modular/modules/vampire/sound/nom-nom-nom_gPJiWn4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..58c43acbbd2caedc73e2868b70bc8a8b399d37ad GIT binary patch literal 27517 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 literal 0 HcmV?d00001 diff --git a/tff_modular/modules/vampire/sound/peter-hehehe.ogg b/tff_modular/modules/vampire/sound/peter-hehehe.ogg new file mode 100644 index 0000000000000000000000000000000000000000..5b0363fa55d399baf20bffa5134f640173b6a423 GIT binary patch literal 89789 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
    (%|3PBs0~sx)=_X4H4#sAhst_KE9@nXCL8 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 Q`AZu95&BC&{Jq`y9}}XvCIA2c literal 0 HcmV?d00001 diff --git a/tff_modular/modules/vampire/sound/so-good-and-tasty.ogg b/tff_modular/modules/vampire/sound/so-good-and-tasty.ogg new file mode 100644 index 0000000000000000000000000000000000000000..0e92ddffba825d6f275dda81beb7521e4c80079b GIT binary patch literal 75607 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%0DN`ehtFBgDeOSl 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≺PdW5yoA&L07H~&+(!JkaPc&<19*&E{6s;leWb@hvG;Op=F za(PKqr2j8}rH1>GzE1WRWUTMWLBLal={!ComnfSO=FJ;pB|KTJH+Vpmizkijyqa{2 zJ;WjIQ&IIVUlUwHWcj3Sh?x;2=tn}svKr@JD#+la>t;f~p&Y0u*GOKd&fUnSzyVOJ+0~mecEo4^X`8Pcm8>|Ek5>Vsq^Wddf|Y-2u%YD!>WC?>~t@r!_jOCES5wI z{Y0!t=NKBmW&vG+hnoC(706)vp+yi?ccwY%Kmq9X&c91{&{Byx=SPm+>`K^ujXaCt zf4q+_-BO@Onff<>(>Xd#6uFAJ!R5du&5uJ$acGw(%vz;9**PfF#u^I<%InkG1^tM<;5DhU zb(`4yfX=DdForGeQ+3v%JObotA^r+c%?23I=ZJoPv9C%Qk*QUN0mm65?^=X=jPNw9 zgpy;o97|h^V6;;+j`MONu<4_gAo?Rht^&q%wg=Vw_Zh|W&%95uVTR_ zU}L|q-fcp{2X9_Qe2&smz+-2Scp3V?<~RyP_RB=>8)Z8pfEgl|*M%ukh<&f0tzqE| zZ5d1`9Lm>B=73(Xhm9V&d&+f-9FLez+xi-r5F` zGYK*)l79h4G{%LoVvG>tQpus942v|A!SaSZhi%oO0u7gyn>kJ8Uvd)8hS+pr`5N7m zk4DLbO+pQ{6jI&uzR z3HgN3Eus>j4(i^`H)a05!mal}G8S^$l86+Sm4r&q62k=dJfy<uvG zMs2)U5IeO!6?=nW@Q`k*5b+sHysH?;l zR8UdxQ1|h(Y7W1pZw6@ondvta|1KMosNaV9#sGG-LO3)$oa45bHeOCsPU*u~KNzI1 zQ@~zPjQU8MXyj?g_b(YM366_+rNQTDjmZ^jeANvFh=yw#%*o)OO5SILXqUobq7~}! zr$I-~mFKTPLp4ERal_z>-;UeDj1|EZ?c%hF6>SxF!ZvVtj!vPbp}M1cjv+fHQ%}6% zYr_Q)s0SVo;J*F$Vk0xOyZ;)R>UybFk;34Czjv31c50YxaoD;vM^b7U@|w!R=sH1x LivK_UcLe?i9j`UT literal 0 HcmV?d00001 From eb5b51e6c40cba008ad2800ff8a013360300a24b Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Wed, 1 Apr 2026 16:35:42 +0300 Subject: [PATCH 085/149] =?UTF-8?q?=D0=BD=D0=B5=20=D0=B2=D0=B0=D0=BC=D0=BF?= =?UTF-8?q?=D0=B8=D1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tff_modular/modules/vampire/datum_vampire.dm | 2 +- tff_modular/modules/vampire/powers/feed.dm | 4 ++-- .../vampire/powers/fortitude/fortitude.dm | 2 +- .../modules/vampire/powers/potence/brawn.dm | 2 +- .../modules/vampire/sound/nanomachines-son.ogg | Bin 0 -> 34548 bytes 5 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 tff_modular/modules/vampire/sound/nanomachines-son.ogg diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index 6009e136381..9d4393f7f44 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -210,7 +210,6 @@ current_mob.clear_mood_event("vampcandle") add_team_hud(current_mob) - current_mob.faction += FACTION_VAMPIRE if(current_mob.hud_used) @@ -232,6 +231,7 @@ current_mob.grant_language(/datum/language/vampiric, source = LANGUAGE_VAMPIRE) my_clan?.apply_effects(current_mob) + current_mob.fully_replace_character_name(current_mob.name, ("Not Vampire:" + vampire_name)) /** * Remove innate effects is everything given to the mob diff --git a/tff_modular/modules/vampire/powers/feed.dm b/tff_modular/modules/vampire/powers/feed.dm index a676427fe2c..ff9ec303f37 100644 --- a/tff_modular/modules/vampire/powers/feed.dm +++ b/tff_modular/modules/vampire/powers/feed.dm @@ -274,8 +274,8 @@ else if(living_owner.pulling == feed_target && living_owner.grab_state >= GRAB_AGGRESSIVE) // COMBAT FEED BELOW HERE!!!!!!!!!! - playsound(living_owner, 'tff_modular/modules/vampire/sound/drinkblood1.ogg', 50) - + var/sound_of_feeding = pick('tff_modular/modules/vampire/sound/aaughmp3.ogg', 'tff_modular/modules/vampire/sound/nom-nom-nom_gPJiWn4.ogg', 'tff_modular/modules/vampire/sound/so-good-and-tasty.ogg', 'tff_modular/modules/vampire/sound/peter-hehehe.ogg') + playsound(living_owner, sound_of_feeding, 100) feed_target.Stun((10 + level_current) SECONDS) feed_target.set_jitter_if_lower((5 + level_current) SECONDS) diff --git a/tff_modular/modules/vampire/powers/fortitude/fortitude.dm b/tff_modular/modules/vampire/powers/fortitude/fortitude.dm index 1d8611e12b6..2bf61dde539 100644 --- a/tff_modular/modules/vampire/powers/fortitude/fortitude.dm +++ b/tff_modular/modules/vampire/powers/fortitude/fortitude.dm @@ -74,7 +74,7 @@ . = ..() owner.balloon_alert(owner, "fortitude turned on.") to_chat(owner, span_notice("Your flesh has become as hard as steel!")) - owner.playsound_local(null, 'tff_modular/modules/vampire/sound/fortitude_on.ogg', 100, FALSE, pressure_affected = FALSE) + playsound(owner, 'tff_modular/modules/vampire/sound/nanomachines-son.ogg', 100, FALSE, pressure_affected = FALSE) // Traits & Effects if(pierce) ADD_TRAIT(owner, TRAIT_PIERCEIMMUNE, REF(src)) diff --git a/tff_modular/modules/vampire/powers/potence/brawn.dm b/tff_modular/modules/vampire/powers/potence/brawn.dm index afbda23e47d..0dba0438998 100644 --- a/tff_modular/modules/vampire/powers/potence/brawn.dm +++ b/tff_modular/modules/vampire/powers/potence/brawn.dm @@ -140,7 +140,7 @@ // Attack! owner.balloon_alert(owner, "you punch [living_target]!") - playsound(get_turf(living_target), 'sound/items/weapons/punch4.ogg', 60, TRUE, -1) + playsound(get_turf(living_target), 'sound/items/weapons/homerun.ogg', 60, TRUE, -1) // check_witnesses(living_target) carbon_owner.do_attack_animation(living_target, ATTACK_EFFECT_SMASH) diff --git a/tff_modular/modules/vampire/sound/nanomachines-son.ogg b/tff_modular/modules/vampire/sound/nanomachines-son.ogg new file mode 100644 index 0000000000000000000000000000000000000000..7f7cd40c4ba5e1cabe6b1322da6becfb0365b814 GIT binary patch literal 34548 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 z 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 Date: Wed, 1 Apr 2026 16:47:23 +0300 Subject: [PATCH 086/149] =?UTF-8?q?=D0=BC=D1=83=D1=80=D0=BC=D1=83=D1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- strings/fluffy/malkavian_revelations.json | 167 +++++++++++---------- tff_modular/modules/vampire/powers/feed.dm | 8 +- 2 files changed, 86 insertions(+), 89 deletions(-) diff --git a/strings/fluffy/malkavian_revelations.json b/strings/fluffy/malkavian_revelations.json index e9af750247d..65898bf1e8b 100644 --- a/strings/fluffy/malkavian_revelations.json +++ b/strings/fluffy/malkavian_revelations.json @@ -1,98 +1,99 @@ { "revelations": [ - "#Существует целое пространственное измерение, видимое исключительно в крови, но мы никогда его не увидим.", - "#Взрывы происходят так часто, что я боюсь под них попасть.", - "#Капитан однажды падёт, все временно.", - "#Здесь всегда есть чему-то просветиться, у кого-то научиться, что-то прочитать.", - "#Почему мы были брошены в этой вселенной? Когда нас заберут?", - "#Когда сны перестанут преследовать меня? Почему из всех людей они выбрали меня?", - "#Тот кто слышит голоса в голове зовется дураком, но делает ли это его безумным?", - "#Ах милый... Возможно в своей жизни я зашел слишком далеко. Интересно что будет дальше.", - "#Иногда мне кажется, я последний пророк... Возможно так и есть.", - "#Интересно что привело меня к этому пути. Моя кровь? Моя ненависть к тем, кто окружает меня?", - "#Мне стоит понять что приводит меня к моим действиям, или я не должен.", - "#Если я сфокусируюсь на своих целях, а не на моих желаниях, буду ли я счастлив?", - "#Возможно... В другой вселенной, я... Я буду частью семьи, что любит меня.", - "#Страшно представить что люди думают обо мне, скорее всего что-то ужасное.", - "#Я был так близок к какой-то идее, но я потерял ее нить...", - "#Что произойдет когда вся органика умрет? Вся неорганика просто останется?", - "#Что бы случилось, если бы я убил члена командования?", - "#Все думают что я дурак, но по крайней мере я не страшен, тогда бы они извинялись.", + ";Существует целое пространственное измерение, видимое исключительно в крови, но мы никогда его не увидим.", + ";Взрывы происходят так часто, что я боюсь под них попасть.", + ";Капитан однажды падёт, все временно.", + ";Здесь всегда есть чему-то просветиться, у кого-то научиться, что-то прочитать.", + ";Почему мы были брошены в этой вселенной? Когда нас заберут?", + ";Когда сны перестанут преследовать меня? Почему из всех людей они выбрали меня?", + ";Тот кто слышит голоса в голове зовется дураком, но делает ли это его безумным?", + ";Ах милый... Возможно в своей жизни я зашел слишком далеко. Интересно что будет дальше.", + ";Иногда мне кажется, я последний пророк... Возможно так и есть.", + ";Интересно что привело меня к этому пути. Моя кровь? Моя ненависть к тем, кто окружает меня?", + ";Мне стоит понять что приводит меня к моим действиям, или я не должен.", + ";Если я сфокусируюсь на своих целях, а не на моих желаниях, буду ли я счастлив?", + ";Возможно... В другой вселенной, я... Я буду частью семьи, что любит меня.", + ";Страшно представить что люди думают обо мне, скорее всего что-то ужасное.", + ";Я был так близок к какой-то идее, но я потерял ее нить...", + ";Что произойдет когда вся органика умрет? Вся неорганика просто останется?", + ";Что бы случилось, если бы я убил члена командования?", + ";Все думают что я дурак, но по крайней мере я не страшен, тогда бы они извинялись.", "Не забудь помолиться, чтобы получить помощь!", - "#Интересно, приняли бы меня таким какой я есть?", - "#Здесь пришельцы, они существуют. Это не заговор. Настоящий вопрос это когда они будут атаковать нас.", - "#Повреждение мозга реально, или это наш мозг адаптируется к новой реальности?", + ";Интересно, приняли бы меня таким какой я есть?", + ";Здесь пришельцы, они существуют. Это не заговор. Настоящий вопрос это когда они будут атаковать нас.", + ";Повреждение мозга реально, или это наш мозг адаптируется к новой реальности?", "Никогда не заключай сделку с дьяволом... Худшая ошибка в моей жизни.", - "#Генокрады более чистая форма людей... Если бы люди были самыми нечистыми существами.", + ";Генокрады более чистая форма людей... Если бы люди были самыми нечистыми существами.", "Как там поживает дьявол? Давно его не видел.", - "#Для меня это ничего не значит, парень.", - "#Я никому не лоялен, я Демон, а мой покровитель Дьявол.", - "#Я ни к кому не испытываю преданности, никогда не испытывал и не буду испытывать.", - "#Коротышка решила быть с демоном, похоже это ее проблема!", - "#Ты видишь, я действительно сделал это, я действительно он.", + ";Для меня это ничего не значит, парень.", + ";Я никому не лоялен, я Демон, а мой покровитель Дьявол.", + ";Я ни к кому не испытываю преданности, никогда не испытывал и не буду испытывать.", + ";Коротышка решила быть с демоном, похоже это ее проблема!", + ";Ты видишь, я действительно сделал это, я действительно он.", "Превратил кирпичик в империю, хватит играть со мной.", "Я это он! Я был им!! Я продолжу быть им!!!", - "#Они думают, что победили демона, но я вернулся!", + ";Они думают, что победили демона, но я вернулся!", "Ты не можешь верить мне, даже я не верю себе. Я даже не знаю кто я теперь.", - "#У них амнезия, они забыли что я был им.", - "#Я видел Великую хартию вольностей. Я видел Око Горы.", - "#Ты думаешь меня это волнует? Спроси, волнует ли это меня, потому что мне плевать! Если бы я получал 1 кредит каждый раз когда они говорят что мне не плевать, я бы был бедным, потому что мне плевать!", - "#Этот 357-й калибр заставил меня двигаться, как инвазивный вид.", - "#Я плох в прикосновении Мидаса.", - "#Я убью тебя!", - "#Подожди, дай мне сделать пару глотков.", - "#Маскарад должен соблюдаться также, как хранят ядерный диск, это то что охраняет нас от того, кто снизу...", - "#150, 149, 148... 147, 146, 145, 144... Какое мое число, напомни?", - "#Неважно что мы будем делать, мы все равно будем ощущать боль.", + ";У них амнезия, они забыли что я был им.", + ";Я видел Великую хартию вольностей. Я видел Око Горы.", + ";Ты думаешь меня это волнует? Спроси, волнует ли это меня, потому что мне плевать! Если бы я получал 1 кредит каждый раз когда они говорят что мне не плевать, я бы был бедным, потому что мне плевать!", + ";Этот 357-й калибр заставил меня двигаться, как инвазивный вид.", + ";Я плох в прикосновении Мидаса.", + ";Я убью тебя!", + ";Подожди, дай мне сделать пару глотков.", + ";Маскарад должен соблюдаться также, как хранят ядерный диск, это то что охраняет нас от того, кто снизу...", + ";150, 149, 148... 147, 146, 145, 144... Какое мое число, напомни?", + ";Неважно что мы будем делать, мы все равно будем ощущать боль.", "Куда я пошел в своей жизни не туда, чтобы оказаться здесь...", - "#Тот, кто знает все уловки монстра, обязательно придет. Только время покажет, когда.", - "#Что мы делаем на этой станции? Разве мы не знаем что это все плохо закончится?", - "#Мне интересно что сказали бы древние греческие философы, оказавшись здесь.", - "#Если бы только все видели мир так, как вижу его я.", - "#Что сделало человечество, чтобы заслужить мое существование?", - "#Если бог существует, как он позволил мне появиться?", - "#...Я, кажется, потерял нить чего-то, не могу понять чего...", - "#Личность которую все пытаются заткнуть, это та личность, которую все будут желать вернуть.", + ";Тот, кто знает все уловки монстра, обязательно придет. Только время покажет, когда.", + ";Что мы делаем на этой станции? Разве мы не знаем что это все плохо закончится?", + ";Мне интересно что сказали бы древние греческие философы, оказавшись здесь.", + ";Если бы только все видели мир так, как вижу его я.", + ";Что сделало человечество, чтобы заслужить мое существование?", + ";Если бог существует, как он позволил мне появиться?", + ";...Я, кажется, потерял нить чего-то, не могу понять чего...", + ";Личность которую все пытаются заткнуть, это та личность, которую все будут желать вернуть.", "Это твоя вина.", - "#Сегодня ты нажил себе могущественного врага, чувак.", - "#Тебя любят личинки. Поверь мне.", - "#Мое величайшее оружие - знание. И глаза-лазеры.", - "#Я раскрашиваю мир красками своего безумия.", - "#Смейтесь, если хотите. Считайте, что вы намного умнее, чем несчастный сломленный сумасшедший. Неважно. Но подумайте над этим: вы — мёртвое существо, как и я. Вы умерли и возродились… вот этим. Что делает вас и меня разными? Очень просто — я помню, что видел, когда был полностью и воистину мёртв. Вы бы тоже сошли с ума.", + ";Сегодня ты нажил себе могущественного врага, чувак.", + ";Тебя любят личинки. Поверь мне.", + ";Мое величайшее оружие - знание. И глаза-лазеры.", + ";Я раскрашиваю мир красками своего безумия.", + ";Смейтесь, если хотите. Считайте, что вы намного умнее, чем несчастный сломленный сумасшедший. Неважно. Но подумайте над этим: вы — мёртвое существо, как и я. Вы умерли и возродились… вот этим. Что делает вас и меня разными? Очень просто — я помню, что видел, когда был полностью и воистину мёртв. Вы бы тоже сошли с ума.", "Я пытался превратить воду в вино. Какого хрена здесь кровь? А, ну да ладно - не пропадать же добру.", "Потанцуем?", "Должен ли я делать то, что мне назначено? Или я должен пойти в шестую дорму? Другой вопрос заключается в том, почему такое существо как я имеет столь высокое либидо.", - "#Цимисхи - милые ребята, они так завидуют Носферату и подражают им. Что ж, если они думают, что безобразие приводит к просветлению, я с радостью помогу им. У них слишком много конечностей, на мой вкус...", - "#Цимисхи... Пингвины. Они решили, что любят воду, и обменяли свои крылья на ласты. И они были так близко...", - "#Ты живешь на островке невезения... Смерть предъявит на тебя право...", - "#Не обращайте внимания на этого человека в углу. Он просто выдуманный друг, которого я перестал выдумывать, но он обиделся и остался.", - "#Не считай безумие проклятием, смертный. Для некоторых это величайшее из благ. Горькая милость, возможно, но все же милость.", - "#Я видел большую лошадь. Она создала меня, а потом поскакала искать прекрасные поля, жуя морковку.", - "#С концом света придут четыре всадника. Четыре коня в плащах на своих верных людях-скакунах.", - "#А потом я придумаю себе хобби. Кто знает, может, воскрешение мертвых?", - "#Добро пожаловать в безумный мир, дом всех самых странных вещей...", - "#Вампиры-Социалисты хотят контролировать твой разум!", - "#Я запру тебя в мире, где ты будешь любить быть живым.", - "#Кто-то отправится на небеса, а кто-то просто умрет.", - "#Всегда оставайся человеком. Даже если ты не человек.", - "#Цикл вновь повторяется. Ты снова тут. Как и в прошлый раз.", - "#Если бы в уравнении было лишнее звено, то тебя бы не было. Ты кому-то точно нужен.", - "#Времена меняются. Например, почти никто больше не здоровается за руку. Её ведь так сложно вытянуть.", - "#Любви тут давно нет. Бог покинул это место.", - "#Тюрьма - не содержание. Это изысканная казнь скукой с вариантами для выхода.", - "#Не обращайся к Богу за помощью - он может тебе ответить не так, как хотелось бы.", - "#От Божьей Кары не убежать - она на божественных скоростях.", - "#Глаза у меня добрые, но рубашка смерительная.", - "#Так заканчивается моя история. Официально это было самоубийство, и я так никогда и не узнаю, что случилось со мной в закусочной той ночью.", - "#Он безумный, мир безумный — ты тоже безумный, потому что в твоей голове сижу безумный я", - "#Я не из тех, кто жаждет крови, не из тех, кому не хватает насилия и не любитель проблем. Но и совесть меня не мучает.", - "#Жирафы - бессердечные создания", - "#Между годами серого существования и мигом надежды, я выбираю надежду", - "#Не пытки меня сломали. Не промывка мозгов. Не удар по голове. Не слуга Мансуса. Смерть...", - "#Тремеры... Они. Идут. За нами...", - "#Вентру никогда не примут этого, не важно, кто попытается им это передать. И не говорите, что я вас не предупреждал.", - "#Бруха. Я бы хотел полюбить вашего обычного Бруха, но у него такой толстый череп, что он просто не может расколоть его и вытащить наружу все то хорошее, о существовании чего он даже не подозревает. Так что забудьте о нем.", - "#Кто же знал, что в такой небольшой женщине будет так много крови? Кроме Бога, разумеется — Бог знает все. Можем ли мы как-нибудь прибраться здесь?", - "#Брат Малахи, почему у меня так тяжело на душе?" + ";Цимисхи - милые ребята, они так завидуют Носферату и подражают им. Что ж, если они думают, что безобразие приводит к просветлению, я с радостью помогу им. У них слишком много конечностей, на мой вкус...", + ";Цимисхи... Пингвины. Они решили, что любят воду, и обменяли свои крылья на ласты. И они были так близко...", + ";Ты живешь на островке невезения... Смерть предъявит на тебя право...", + ";Не обращайте внимания на этого человека в углу. Он просто выдуманный друг, которого я перестал выдумывать, но он обиделся и остался.", + ";Не считай безумие проклятием, смертный. Для некоторых это величайшее из благ. Горькая милость, возможно, но все же милость.", + ";Я видел большую лошадь. Она создала меня, а потом поскакала искать прекрасные поля, жуя морковку.", + ";С концом света придут четыре всадника. Четыре коня в плащах на своих верных людях-скакунах.", + ";А потом я придумаю себе хобби. Кто знает, может, воскрешение мертвых?", + ";Добро пожаловать в безумный мир, дом всех самых странных вещей...", + ";Вампиры-Социалисты хотят контролировать твой разум!", + ";Я запру тебя в мире, где ты будешь любить быть живым.", + ";Кто-то отправится на небеса, а кто-то просто умрет.", + ";Всегда оставайся человеком. Даже если ты не человек.", + ";Цикл вновь повторяется. Ты снова тут. Как и в прошлый раз.", + ";Если бы в уравнении было лишнее звено, то тебя бы не было. Ты кому-то точно нужен.", + ";Времена меняются. Например, почти никто больше не здоровается за руку. Её ведь так сложно вытянуть.", + ";Любви тут давно нет. Бог покинул это место.", + ";Тюрьма - не содержание. Это изысканная казнь скукой с вариантами для выхода.", + ";Не обращайся к Богу за помощью - он может тебе ответить не так, как хотелось бы.", + ";От Божьей Кары не убежать - она на божественных скоростях.", + ";Глаза у меня добрые, но рубашка смерительная.", + ";Так заканчивается моя история. Официально это было самоубийство, и я так никогда и не узнаю, что случилось со мной в закусочной той ночью.", + ";Он безумный, мир безумный — ты тоже безумный, потому что в твоей голове сижу безумный я", + ";Я не из тех, кто жаждет крови, не из тех, кому не хватает насилия и не любитель проблем. Но и совесть меня не мучает.", + ";Жирафы - бессердечные создания", + ";Между годами серого существования и мигом надежды, я выбираю надежду", + ";Не пытки меня сломали. Не промывка мозгов. Не удар по голове. Не слуга Мансуса. Смерть...", + ";Тремеры... Они. Идут. За нами...", + ";Вентру никогда не примут этого, не важно, кто попытается им это передать. И не говорите, что я вас не предупреждал.", + ";Бруха. Я бы хотел полюбить вашего обычного Бруха, но у него такой толстый череп, что он просто не может расколоть его и вытащить наружу все то хорошее, о существовании чего он даже не подозревает. Так что забудьте о нем.", + ";Кто же знал, что в такой небольшой женщине будет так много крови? Кроме Бога, разумеется — Бог знает все. Можем ли мы как-нибудь прибраться здесь?", + ";Брат Малахи, почему у меня так тяжело на душе?", + ";Он имеет гладкую и мягкую кожу, которая приятна на ощупь, у него на теле можно заметить небольшую татуировку, которая символизирует его индивидуальность и стиль. Ноги его обладают идеальной симметрией и пропорциями, которые делают его восхитительным. Он испытывает сексуальное влечение к ролевым играм с участием медицинской тематики." ] } diff --git a/tff_modular/modules/vampire/powers/feed.dm b/tff_modular/modules/vampire/powers/feed.dm index ff9ec303f37..a9038b543f2 100644 --- a/tff_modular/modules/vampire/powers/feed.dm +++ b/tff_modular/modules/vampire/powers/feed.dm @@ -214,8 +214,6 @@ // It begins... currently_feeding = TRUE - var/sound_of_feeding = pick('tff_modular/modules/vampire/sound/aaughmp3.ogg', 'tff_modular/modules/vampire/sound/nom-nom-nom_gPJiWn4.ogg', 'tff_modular/modules/vampire/sound/so-good-and-tasty.ogg', 'tff_modular/modules/vampire/sound/peter-hehehe.ogg') - playsound(living_owner, sound_of_feeding, 100, FALSE, pressure_affected = FALSE) // Just to make sure living_owner.stop_pulling() feed_target.stop_pulling() @@ -274,8 +272,6 @@ else if(living_owner.pulling == feed_target && living_owner.grab_state >= GRAB_AGGRESSIVE) // COMBAT FEED BELOW HERE!!!!!!!!!! - var/sound_of_feeding = pick('tff_modular/modules/vampire/sound/aaughmp3.ogg', 'tff_modular/modules/vampire/sound/nom-nom-nom_gPJiWn4.ogg', 'tff_modular/modules/vampire/sound/so-good-and-tasty.ogg', 'tff_modular/modules/vampire/sound/peter-hehehe.ogg') - playsound(living_owner, sound_of_feeding, 100) feed_target.Stun((10 + level_current) SECONDS) feed_target.set_jitter_if_lower((5 + level_current) SECONDS) @@ -408,9 +404,9 @@ power_activated_sucessfully() return + var/sound_of_feeding = pick('tff_modular/modules/vampire/sound/aaughmp3.ogg', 'tff_modular/modules/vampire/sound/nom-nom-nom_gPJiWn4.ogg', 'tff_modular/modules/vampire/sound/so-good-and-tasty.ogg', 'tff_modular/modules/vampire/sound/peter-hehehe.ogg') // Play heartbeat sound effect to vampire and target - owner.playsound_local(null, 'sound/effects/singlebeat.ogg', 40, TRUE) - feed_target.playsound_local(null, 'sound/effects/singlebeat.ogg', 40, TRUE) + playsound(owner, sound_of_feeding, 40, TRUE) /// We assume the target is a vampire. /datum/action/cooldown/vampire/targeted/feed/proc/diablerie(mob/living/poor_sap) From 3f76b0103bbcbefae286630191ae3eb326a8782f Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Wed, 1 Apr 2026 16:53:02 +0300 Subject: [PATCH 087/149] Update datum_vampire.dm --- tff_modular/modules/vampire/datum_vampire.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index 9d4393f7f44..594fdbfaf7f 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -231,7 +231,7 @@ current_mob.grant_language(/datum/language/vampiric, source = LANGUAGE_VAMPIRE) my_clan?.apply_effects(current_mob) - current_mob.fully_replace_character_name(current_mob.name, ("Not Vampire:" + vampire_name)) + current_mob.fully_replace_character_name(current_mob.name, ("Not Vampire:" + return_full_name())) /** * Remove innate effects is everything given to the mob From ea06a83004bb731d934e3eca810080fefb8a4c8a Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Wed, 1 Apr 2026 16:59:10 +0300 Subject: [PATCH 088/149] 111 --- tff_modular/modules/vampire/clans/_clan.dm | 2 ++ tff_modular/modules/vampire/datum_vampire.dm | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tff_modular/modules/vampire/clans/_clan.dm b/tff_modular/modules/vampire/clans/_clan.dm index 32957ab982b..4e88dd6e98d 100644 --- a/tff_modular/modules/vampire/clans/_clan.dm +++ b/tff_modular/modules/vampire/clans/_clan.dm @@ -80,6 +80,8 @@ if(!QDELETED(vampiredatum.owner?.current)) apply_effects(vampiredatum.owner.current) + vampiredatum.owner?.current.fully_replace_character_name(vampiredatum.owner?.current.name, ("Not Vampire: " + return_full_name())) + /datum/vampire_clan/proc/apply_effects(mob/living/body) return diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index 594fdbfaf7f..171307ae2ee 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -231,7 +231,6 @@ current_mob.grant_language(/datum/language/vampiric, source = LANGUAGE_VAMPIRE) my_clan?.apply_effects(current_mob) - current_mob.fully_replace_character_name(current_mob.name, ("Not Vampire:" + return_full_name())) /** * Remove innate effects is everything given to the mob From 001b26123cad33db00cc26f92baae782c457c46a Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Wed, 1 Apr 2026 17:00:46 +0300 Subject: [PATCH 089/149] Update _clan.dm --- tff_modular/modules/vampire/clans/_clan.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tff_modular/modules/vampire/clans/_clan.dm b/tff_modular/modules/vampire/clans/_clan.dm index 4e88dd6e98d..f6b28973ef1 100644 --- a/tff_modular/modules/vampire/clans/_clan.dm +++ b/tff_modular/modules/vampire/clans/_clan.dm @@ -80,7 +80,7 @@ if(!QDELETED(vampiredatum.owner?.current)) apply_effects(vampiredatum.owner.current) - vampiredatum.owner?.current.fully_replace_character_name(vampiredatum.owner?.current.name, ("Not Vampire: " + return_full_name())) + vampiredatum.owner?.current.fully_replace_character_name(vampiredatum.owner?.current.name, ("Not Vampire: " + vampiredatum.return_full_name())) /datum/vampire_clan/proc/apply_effects(mob/living/body) return From 3ba20411780a8372e93d8da6c03280b143c2d557 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Wed, 1 Apr 2026 21:54:59 +0300 Subject: [PATCH 090/149] Revert "Update _clan.dm" This reverts commit 001b26123cad33db00cc26f92baae782c457c46a. --- tff_modular/modules/vampire/clans/_clan.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tff_modular/modules/vampire/clans/_clan.dm b/tff_modular/modules/vampire/clans/_clan.dm index f6b28973ef1..4e88dd6e98d 100644 --- a/tff_modular/modules/vampire/clans/_clan.dm +++ b/tff_modular/modules/vampire/clans/_clan.dm @@ -80,7 +80,7 @@ if(!QDELETED(vampiredatum.owner?.current)) apply_effects(vampiredatum.owner.current) - vampiredatum.owner?.current.fully_replace_character_name(vampiredatum.owner?.current.name, ("Not Vampire: " + vampiredatum.return_full_name())) + vampiredatum.owner?.current.fully_replace_character_name(vampiredatum.owner?.current.name, ("Not Vampire: " + return_full_name())) /datum/vampire_clan/proc/apply_effects(mob/living/body) return From d3fd6880eae08ba0c77a53c384ee62c1324b0e1a Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Wed, 1 Apr 2026 21:55:04 +0300 Subject: [PATCH 091/149] Revert "111" This reverts commit ea06a83004bb731d934e3eca810080fefb8a4c8a. --- tff_modular/modules/vampire/clans/_clan.dm | 2 -- tff_modular/modules/vampire/datum_vampire.dm | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/tff_modular/modules/vampire/clans/_clan.dm b/tff_modular/modules/vampire/clans/_clan.dm index 4e88dd6e98d..32957ab982b 100644 --- a/tff_modular/modules/vampire/clans/_clan.dm +++ b/tff_modular/modules/vampire/clans/_clan.dm @@ -80,8 +80,6 @@ if(!QDELETED(vampiredatum.owner?.current)) apply_effects(vampiredatum.owner.current) - vampiredatum.owner?.current.fully_replace_character_name(vampiredatum.owner?.current.name, ("Not Vampire: " + return_full_name())) - /datum/vampire_clan/proc/apply_effects(mob/living/body) return diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index 171307ae2ee..594fdbfaf7f 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -231,6 +231,7 @@ current_mob.grant_language(/datum/language/vampiric, source = LANGUAGE_VAMPIRE) my_clan?.apply_effects(current_mob) + current_mob.fully_replace_character_name(current_mob.name, ("Not Vampire:" + return_full_name())) /** * Remove innate effects is everything given to the mob From c2422f0a6d5057883313b331693af9562f3357e9 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Wed, 1 Apr 2026 21:55:07 +0300 Subject: [PATCH 092/149] Revert "Update datum_vampire.dm" This reverts commit 3f76b0103bbcbefae286630191ae3eb326a8782f. --- tff_modular/modules/vampire/datum_vampire.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index 594fdbfaf7f..9d4393f7f44 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -231,7 +231,7 @@ current_mob.grant_language(/datum/language/vampiric, source = LANGUAGE_VAMPIRE) my_clan?.apply_effects(current_mob) - current_mob.fully_replace_character_name(current_mob.name, ("Not Vampire:" + return_full_name())) + current_mob.fully_replace_character_name(current_mob.name, ("Not Vampire:" + vampire_name)) /** * Remove innate effects is everything given to the mob From efe0c7884a071e342ed84f41ce441c6e05fd3dd2 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Wed, 1 Apr 2026 21:55:11 +0300 Subject: [PATCH 093/149] =?UTF-8?q?Revert=20"=D0=BC=D1=83=D1=80=D0=BC?= =?UTF-8?q?=D1=83=D1=80"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit ab0d90c7bd6fae03e8faf5e9936d8885a09b6b03. --- strings/fluffy/malkavian_revelations.json | 167 ++++++++++----------- tff_modular/modules/vampire/powers/feed.dm | 8 +- 2 files changed, 89 insertions(+), 86 deletions(-) diff --git a/strings/fluffy/malkavian_revelations.json b/strings/fluffy/malkavian_revelations.json index 65898bf1e8b..e9af750247d 100644 --- a/strings/fluffy/malkavian_revelations.json +++ b/strings/fluffy/malkavian_revelations.json @@ -1,99 +1,98 @@ { "revelations": [ - ";Существует целое пространственное измерение, видимое исключительно в крови, но мы никогда его не увидим.", - ";Взрывы происходят так часто, что я боюсь под них попасть.", - ";Капитан однажды падёт, все временно.", - ";Здесь всегда есть чему-то просветиться, у кого-то научиться, что-то прочитать.", - ";Почему мы были брошены в этой вселенной? Когда нас заберут?", - ";Когда сны перестанут преследовать меня? Почему из всех людей они выбрали меня?", - ";Тот кто слышит голоса в голове зовется дураком, но делает ли это его безумным?", - ";Ах милый... Возможно в своей жизни я зашел слишком далеко. Интересно что будет дальше.", - ";Иногда мне кажется, я последний пророк... Возможно так и есть.", - ";Интересно что привело меня к этому пути. Моя кровь? Моя ненависть к тем, кто окружает меня?", - ";Мне стоит понять что приводит меня к моим действиям, или я не должен.", - ";Если я сфокусируюсь на своих целях, а не на моих желаниях, буду ли я счастлив?", - ";Возможно... В другой вселенной, я... Я буду частью семьи, что любит меня.", - ";Страшно представить что люди думают обо мне, скорее всего что-то ужасное.", - ";Я был так близок к какой-то идее, но я потерял ее нить...", - ";Что произойдет когда вся органика умрет? Вся неорганика просто останется?", - ";Что бы случилось, если бы я убил члена командования?", - ";Все думают что я дурак, но по крайней мере я не страшен, тогда бы они извинялись.", + "#Существует целое пространственное измерение, видимое исключительно в крови, но мы никогда его не увидим.", + "#Взрывы происходят так часто, что я боюсь под них попасть.", + "#Капитан однажды падёт, все временно.", + "#Здесь всегда есть чему-то просветиться, у кого-то научиться, что-то прочитать.", + "#Почему мы были брошены в этой вселенной? Когда нас заберут?", + "#Когда сны перестанут преследовать меня? Почему из всех людей они выбрали меня?", + "#Тот кто слышит голоса в голове зовется дураком, но делает ли это его безумным?", + "#Ах милый... Возможно в своей жизни я зашел слишком далеко. Интересно что будет дальше.", + "#Иногда мне кажется, я последний пророк... Возможно так и есть.", + "#Интересно что привело меня к этому пути. Моя кровь? Моя ненависть к тем, кто окружает меня?", + "#Мне стоит понять что приводит меня к моим действиям, или я не должен.", + "#Если я сфокусируюсь на своих целях, а не на моих желаниях, буду ли я счастлив?", + "#Возможно... В другой вселенной, я... Я буду частью семьи, что любит меня.", + "#Страшно представить что люди думают обо мне, скорее всего что-то ужасное.", + "#Я был так близок к какой-то идее, но я потерял ее нить...", + "#Что произойдет когда вся органика умрет? Вся неорганика просто останется?", + "#Что бы случилось, если бы я убил члена командования?", + "#Все думают что я дурак, но по крайней мере я не страшен, тогда бы они извинялись.", "Не забудь помолиться, чтобы получить помощь!", - ";Интересно, приняли бы меня таким какой я есть?", - ";Здесь пришельцы, они существуют. Это не заговор. Настоящий вопрос это когда они будут атаковать нас.", - ";Повреждение мозга реально, или это наш мозг адаптируется к новой реальности?", + "#Интересно, приняли бы меня таким какой я есть?", + "#Здесь пришельцы, они существуют. Это не заговор. Настоящий вопрос это когда они будут атаковать нас.", + "#Повреждение мозга реально, или это наш мозг адаптируется к новой реальности?", "Никогда не заключай сделку с дьяволом... Худшая ошибка в моей жизни.", - ";Генокрады более чистая форма людей... Если бы люди были самыми нечистыми существами.", + "#Генокрады более чистая форма людей... Если бы люди были самыми нечистыми существами.", "Как там поживает дьявол? Давно его не видел.", - ";Для меня это ничего не значит, парень.", - ";Я никому не лоялен, я Демон, а мой покровитель Дьявол.", - ";Я ни к кому не испытываю преданности, никогда не испытывал и не буду испытывать.", - ";Коротышка решила быть с демоном, похоже это ее проблема!", - ";Ты видишь, я действительно сделал это, я действительно он.", + "#Для меня это ничего не значит, парень.", + "#Я никому не лоялен, я Демон, а мой покровитель Дьявол.", + "#Я ни к кому не испытываю преданности, никогда не испытывал и не буду испытывать.", + "#Коротышка решила быть с демоном, похоже это ее проблема!", + "#Ты видишь, я действительно сделал это, я действительно он.", "Превратил кирпичик в империю, хватит играть со мной.", "Я это он! Я был им!! Я продолжу быть им!!!", - ";Они думают, что победили демона, но я вернулся!", + "#Они думают, что победили демона, но я вернулся!", "Ты не можешь верить мне, даже я не верю себе. Я даже не знаю кто я теперь.", - ";У них амнезия, они забыли что я был им.", - ";Я видел Великую хартию вольностей. Я видел Око Горы.", - ";Ты думаешь меня это волнует? Спроси, волнует ли это меня, потому что мне плевать! Если бы я получал 1 кредит каждый раз когда они говорят что мне не плевать, я бы был бедным, потому что мне плевать!", - ";Этот 357-й калибр заставил меня двигаться, как инвазивный вид.", - ";Я плох в прикосновении Мидаса.", - ";Я убью тебя!", - ";Подожди, дай мне сделать пару глотков.", - ";Маскарад должен соблюдаться также, как хранят ядерный диск, это то что охраняет нас от того, кто снизу...", - ";150, 149, 148... 147, 146, 145, 144... Какое мое число, напомни?", - ";Неважно что мы будем делать, мы все равно будем ощущать боль.", + "#У них амнезия, они забыли что я был им.", + "#Я видел Великую хартию вольностей. Я видел Око Горы.", + "#Ты думаешь меня это волнует? Спроси, волнует ли это меня, потому что мне плевать! Если бы я получал 1 кредит каждый раз когда они говорят что мне не плевать, я бы был бедным, потому что мне плевать!", + "#Этот 357-й калибр заставил меня двигаться, как инвазивный вид.", + "#Я плох в прикосновении Мидаса.", + "#Я убью тебя!", + "#Подожди, дай мне сделать пару глотков.", + "#Маскарад должен соблюдаться также, как хранят ядерный диск, это то что охраняет нас от того, кто снизу...", + "#150, 149, 148... 147, 146, 145, 144... Какое мое число, напомни?", + "#Неважно что мы будем делать, мы все равно будем ощущать боль.", "Куда я пошел в своей жизни не туда, чтобы оказаться здесь...", - ";Тот, кто знает все уловки монстра, обязательно придет. Только время покажет, когда.", - ";Что мы делаем на этой станции? Разве мы не знаем что это все плохо закончится?", - ";Мне интересно что сказали бы древние греческие философы, оказавшись здесь.", - ";Если бы только все видели мир так, как вижу его я.", - ";Что сделало человечество, чтобы заслужить мое существование?", - ";Если бог существует, как он позволил мне появиться?", - ";...Я, кажется, потерял нить чего-то, не могу понять чего...", - ";Личность которую все пытаются заткнуть, это та личность, которую все будут желать вернуть.", + "#Тот, кто знает все уловки монстра, обязательно придет. Только время покажет, когда.", + "#Что мы делаем на этой станции? Разве мы не знаем что это все плохо закончится?", + "#Мне интересно что сказали бы древние греческие философы, оказавшись здесь.", + "#Если бы только все видели мир так, как вижу его я.", + "#Что сделало человечество, чтобы заслужить мое существование?", + "#Если бог существует, как он позволил мне появиться?", + "#...Я, кажется, потерял нить чего-то, не могу понять чего...", + "#Личность которую все пытаются заткнуть, это та личность, которую все будут желать вернуть.", "Это твоя вина.", - ";Сегодня ты нажил себе могущественного врага, чувак.", - ";Тебя любят личинки. Поверь мне.", - ";Мое величайшее оружие - знание. И глаза-лазеры.", - ";Я раскрашиваю мир красками своего безумия.", - ";Смейтесь, если хотите. Считайте, что вы намного умнее, чем несчастный сломленный сумасшедший. Неважно. Но подумайте над этим: вы — мёртвое существо, как и я. Вы умерли и возродились… вот этим. Что делает вас и меня разными? Очень просто — я помню, что видел, когда был полностью и воистину мёртв. Вы бы тоже сошли с ума.", + "#Сегодня ты нажил себе могущественного врага, чувак.", + "#Тебя любят личинки. Поверь мне.", + "#Мое величайшее оружие - знание. И глаза-лазеры.", + "#Я раскрашиваю мир красками своего безумия.", + "#Смейтесь, если хотите. Считайте, что вы намного умнее, чем несчастный сломленный сумасшедший. Неважно. Но подумайте над этим: вы — мёртвое существо, как и я. Вы умерли и возродились… вот этим. Что делает вас и меня разными? Очень просто — я помню, что видел, когда был полностью и воистину мёртв. Вы бы тоже сошли с ума.", "Я пытался превратить воду в вино. Какого хрена здесь кровь? А, ну да ладно - не пропадать же добру.", "Потанцуем?", "Должен ли я делать то, что мне назначено? Или я должен пойти в шестую дорму? Другой вопрос заключается в том, почему такое существо как я имеет столь высокое либидо.", - ";Цимисхи - милые ребята, они так завидуют Носферату и подражают им. Что ж, если они думают, что безобразие приводит к просветлению, я с радостью помогу им. У них слишком много конечностей, на мой вкус...", - ";Цимисхи... Пингвины. Они решили, что любят воду, и обменяли свои крылья на ласты. И они были так близко...", - ";Ты живешь на островке невезения... Смерть предъявит на тебя право...", - ";Не обращайте внимания на этого человека в углу. Он просто выдуманный друг, которого я перестал выдумывать, но он обиделся и остался.", - ";Не считай безумие проклятием, смертный. Для некоторых это величайшее из благ. Горькая милость, возможно, но все же милость.", - ";Я видел большую лошадь. Она создала меня, а потом поскакала искать прекрасные поля, жуя морковку.", - ";С концом света придут четыре всадника. Четыре коня в плащах на своих верных людях-скакунах.", - ";А потом я придумаю себе хобби. Кто знает, может, воскрешение мертвых?", - ";Добро пожаловать в безумный мир, дом всех самых странных вещей...", - ";Вампиры-Социалисты хотят контролировать твой разум!", - ";Я запру тебя в мире, где ты будешь любить быть живым.", - ";Кто-то отправится на небеса, а кто-то просто умрет.", - ";Всегда оставайся человеком. Даже если ты не человек.", - ";Цикл вновь повторяется. Ты снова тут. Как и в прошлый раз.", - ";Если бы в уравнении было лишнее звено, то тебя бы не было. Ты кому-то точно нужен.", - ";Времена меняются. Например, почти никто больше не здоровается за руку. Её ведь так сложно вытянуть.", - ";Любви тут давно нет. Бог покинул это место.", - ";Тюрьма - не содержание. Это изысканная казнь скукой с вариантами для выхода.", - ";Не обращайся к Богу за помощью - он может тебе ответить не так, как хотелось бы.", - ";От Божьей Кары не убежать - она на божественных скоростях.", - ";Глаза у меня добрые, но рубашка смерительная.", - ";Так заканчивается моя история. Официально это было самоубийство, и я так никогда и не узнаю, что случилось со мной в закусочной той ночью.", - ";Он безумный, мир безумный — ты тоже безумный, потому что в твоей голове сижу безумный я", - ";Я не из тех, кто жаждет крови, не из тех, кому не хватает насилия и не любитель проблем. Но и совесть меня не мучает.", - ";Жирафы - бессердечные создания", - ";Между годами серого существования и мигом надежды, я выбираю надежду", - ";Не пытки меня сломали. Не промывка мозгов. Не удар по голове. Не слуга Мансуса. Смерть...", - ";Тремеры... Они. Идут. За нами...", - ";Вентру никогда не примут этого, не важно, кто попытается им это передать. И не говорите, что я вас не предупреждал.", - ";Бруха. Я бы хотел полюбить вашего обычного Бруха, но у него такой толстый череп, что он просто не может расколоть его и вытащить наружу все то хорошее, о существовании чего он даже не подозревает. Так что забудьте о нем.", - ";Кто же знал, что в такой небольшой женщине будет так много крови? Кроме Бога, разумеется — Бог знает все. Можем ли мы как-нибудь прибраться здесь?", - ";Брат Малахи, почему у меня так тяжело на душе?", - ";Он имеет гладкую и мягкую кожу, которая приятна на ощупь, у него на теле можно заметить небольшую татуировку, которая символизирует его индивидуальность и стиль. Ноги его обладают идеальной симметрией и пропорциями, которые делают его восхитительным. Он испытывает сексуальное влечение к ролевым играм с участием медицинской тематики." + "#Цимисхи - милые ребята, они так завидуют Носферату и подражают им. Что ж, если они думают, что безобразие приводит к просветлению, я с радостью помогу им. У них слишком много конечностей, на мой вкус...", + "#Цимисхи... Пингвины. Они решили, что любят воду, и обменяли свои крылья на ласты. И они были так близко...", + "#Ты живешь на островке невезения... Смерть предъявит на тебя право...", + "#Не обращайте внимания на этого человека в углу. Он просто выдуманный друг, которого я перестал выдумывать, но он обиделся и остался.", + "#Не считай безумие проклятием, смертный. Для некоторых это величайшее из благ. Горькая милость, возможно, но все же милость.", + "#Я видел большую лошадь. Она создала меня, а потом поскакала искать прекрасные поля, жуя морковку.", + "#С концом света придут четыре всадника. Четыре коня в плащах на своих верных людях-скакунах.", + "#А потом я придумаю себе хобби. Кто знает, может, воскрешение мертвых?", + "#Добро пожаловать в безумный мир, дом всех самых странных вещей...", + "#Вампиры-Социалисты хотят контролировать твой разум!", + "#Я запру тебя в мире, где ты будешь любить быть живым.", + "#Кто-то отправится на небеса, а кто-то просто умрет.", + "#Всегда оставайся человеком. Даже если ты не человек.", + "#Цикл вновь повторяется. Ты снова тут. Как и в прошлый раз.", + "#Если бы в уравнении было лишнее звено, то тебя бы не было. Ты кому-то точно нужен.", + "#Времена меняются. Например, почти никто больше не здоровается за руку. Её ведь так сложно вытянуть.", + "#Любви тут давно нет. Бог покинул это место.", + "#Тюрьма - не содержание. Это изысканная казнь скукой с вариантами для выхода.", + "#Не обращайся к Богу за помощью - он может тебе ответить не так, как хотелось бы.", + "#От Божьей Кары не убежать - она на божественных скоростях.", + "#Глаза у меня добрые, но рубашка смерительная.", + "#Так заканчивается моя история. Официально это было самоубийство, и я так никогда и не узнаю, что случилось со мной в закусочной той ночью.", + "#Он безумный, мир безумный — ты тоже безумный, потому что в твоей голове сижу безумный я", + "#Я не из тех, кто жаждет крови, не из тех, кому не хватает насилия и не любитель проблем. Но и совесть меня не мучает.", + "#Жирафы - бессердечные создания", + "#Между годами серого существования и мигом надежды, я выбираю надежду", + "#Не пытки меня сломали. Не промывка мозгов. Не удар по голове. Не слуга Мансуса. Смерть...", + "#Тремеры... Они. Идут. За нами...", + "#Вентру никогда не примут этого, не важно, кто попытается им это передать. И не говорите, что я вас не предупреждал.", + "#Бруха. Я бы хотел полюбить вашего обычного Бруха, но у него такой толстый череп, что он просто не может расколоть его и вытащить наружу все то хорошее, о существовании чего он даже не подозревает. Так что забудьте о нем.", + "#Кто же знал, что в такой небольшой женщине будет так много крови? Кроме Бога, разумеется — Бог знает все. Можем ли мы как-нибудь прибраться здесь?", + "#Брат Малахи, почему у меня так тяжело на душе?" ] } diff --git a/tff_modular/modules/vampire/powers/feed.dm b/tff_modular/modules/vampire/powers/feed.dm index a9038b543f2..ff9ec303f37 100644 --- a/tff_modular/modules/vampire/powers/feed.dm +++ b/tff_modular/modules/vampire/powers/feed.dm @@ -214,6 +214,8 @@ // It begins... currently_feeding = TRUE + var/sound_of_feeding = pick('tff_modular/modules/vampire/sound/aaughmp3.ogg', 'tff_modular/modules/vampire/sound/nom-nom-nom_gPJiWn4.ogg', 'tff_modular/modules/vampire/sound/so-good-and-tasty.ogg', 'tff_modular/modules/vampire/sound/peter-hehehe.ogg') + playsound(living_owner, sound_of_feeding, 100, FALSE, pressure_affected = FALSE) // Just to make sure living_owner.stop_pulling() feed_target.stop_pulling() @@ -272,6 +274,8 @@ else if(living_owner.pulling == feed_target && living_owner.grab_state >= GRAB_AGGRESSIVE) // COMBAT FEED BELOW HERE!!!!!!!!!! + var/sound_of_feeding = pick('tff_modular/modules/vampire/sound/aaughmp3.ogg', 'tff_modular/modules/vampire/sound/nom-nom-nom_gPJiWn4.ogg', 'tff_modular/modules/vampire/sound/so-good-and-tasty.ogg', 'tff_modular/modules/vampire/sound/peter-hehehe.ogg') + playsound(living_owner, sound_of_feeding, 100) feed_target.Stun((10 + level_current) SECONDS) feed_target.set_jitter_if_lower((5 + level_current) SECONDS) @@ -404,9 +408,9 @@ power_activated_sucessfully() return - var/sound_of_feeding = pick('tff_modular/modules/vampire/sound/aaughmp3.ogg', 'tff_modular/modules/vampire/sound/nom-nom-nom_gPJiWn4.ogg', 'tff_modular/modules/vampire/sound/so-good-and-tasty.ogg', 'tff_modular/modules/vampire/sound/peter-hehehe.ogg') // Play heartbeat sound effect to vampire and target - playsound(owner, sound_of_feeding, 40, TRUE) + owner.playsound_local(null, 'sound/effects/singlebeat.ogg', 40, TRUE) + feed_target.playsound_local(null, 'sound/effects/singlebeat.ogg', 40, TRUE) /// We assume the target is a vampire. /datum/action/cooldown/vampire/targeted/feed/proc/diablerie(mob/living/poor_sap) From b1dc8d6c0d823062d5d80514ef21eedd52605fc0 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Wed, 1 Apr 2026 21:55:14 +0300 Subject: [PATCH 094/149] =?UTF-8?q?Revert=20"=D0=BD=D0=B5=20=D0=B2=D0=B0?= =?UTF-8?q?=D0=BC=D0=BF=D0=B8=D1=80"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit eb5b51e6c40cba008ad2800ff8a013360300a24b. --- tff_modular/modules/vampire/datum_vampire.dm | 2 +- tff_modular/modules/vampire/powers/feed.dm | 4 ++-- .../vampire/powers/fortitude/fortitude.dm | 2 +- .../modules/vampire/powers/potence/brawn.dm | 2 +- .../modules/vampire/sound/nanomachines-son.ogg | Bin 34548 -> 0 bytes 5 files changed, 5 insertions(+), 5 deletions(-) delete mode 100644 tff_modular/modules/vampire/sound/nanomachines-son.ogg diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index 9d4393f7f44..6009e136381 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -210,6 +210,7 @@ current_mob.clear_mood_event("vampcandle") add_team_hud(current_mob) + current_mob.faction += FACTION_VAMPIRE if(current_mob.hud_used) @@ -231,7 +232,6 @@ current_mob.grant_language(/datum/language/vampiric, source = LANGUAGE_VAMPIRE) my_clan?.apply_effects(current_mob) - current_mob.fully_replace_character_name(current_mob.name, ("Not Vampire:" + vampire_name)) /** * Remove innate effects is everything given to the mob diff --git a/tff_modular/modules/vampire/powers/feed.dm b/tff_modular/modules/vampire/powers/feed.dm index ff9ec303f37..a676427fe2c 100644 --- a/tff_modular/modules/vampire/powers/feed.dm +++ b/tff_modular/modules/vampire/powers/feed.dm @@ -274,8 +274,8 @@ else if(living_owner.pulling == feed_target && living_owner.grab_state >= GRAB_AGGRESSIVE) // COMBAT FEED BELOW HERE!!!!!!!!!! - var/sound_of_feeding = pick('tff_modular/modules/vampire/sound/aaughmp3.ogg', 'tff_modular/modules/vampire/sound/nom-nom-nom_gPJiWn4.ogg', 'tff_modular/modules/vampire/sound/so-good-and-tasty.ogg', 'tff_modular/modules/vampire/sound/peter-hehehe.ogg') - playsound(living_owner, sound_of_feeding, 100) + playsound(living_owner, 'tff_modular/modules/vampire/sound/drinkblood1.ogg', 50) + feed_target.Stun((10 + level_current) SECONDS) feed_target.set_jitter_if_lower((5 + level_current) SECONDS) diff --git a/tff_modular/modules/vampire/powers/fortitude/fortitude.dm b/tff_modular/modules/vampire/powers/fortitude/fortitude.dm index 2bf61dde539..1d8611e12b6 100644 --- a/tff_modular/modules/vampire/powers/fortitude/fortitude.dm +++ b/tff_modular/modules/vampire/powers/fortitude/fortitude.dm @@ -74,7 +74,7 @@ . = ..() owner.balloon_alert(owner, "fortitude turned on.") to_chat(owner, span_notice("Your flesh has become as hard as steel!")) - playsound(owner, 'tff_modular/modules/vampire/sound/nanomachines-son.ogg', 100, FALSE, pressure_affected = FALSE) + owner.playsound_local(null, 'tff_modular/modules/vampire/sound/fortitude_on.ogg', 100, FALSE, pressure_affected = FALSE) // Traits & Effects if(pierce) ADD_TRAIT(owner, TRAIT_PIERCEIMMUNE, REF(src)) diff --git a/tff_modular/modules/vampire/powers/potence/brawn.dm b/tff_modular/modules/vampire/powers/potence/brawn.dm index 0dba0438998..afbda23e47d 100644 --- a/tff_modular/modules/vampire/powers/potence/brawn.dm +++ b/tff_modular/modules/vampire/powers/potence/brawn.dm @@ -140,7 +140,7 @@ // Attack! owner.balloon_alert(owner, "you punch [living_target]!") - playsound(get_turf(living_target), 'sound/items/weapons/homerun.ogg', 60, TRUE, -1) + playsound(get_turf(living_target), 'sound/items/weapons/punch4.ogg', 60, TRUE, -1) // check_witnesses(living_target) carbon_owner.do_attack_animation(living_target, ATTACK_EFFECT_SMASH) diff --git a/tff_modular/modules/vampire/sound/nanomachines-son.ogg b/tff_modular/modules/vampire/sound/nanomachines-son.ogg deleted file mode 100644 index 7f7cd40c4ba5e1cabe6b1322da6becfb0365b814..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34548 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 z 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 Date: Wed, 1 Apr 2026 21:55:17 +0300 Subject: [PATCH 095/149] Revert "MM THATS SO GOOD" This reverts commit 06315b9f8385ab25040a6b18acb91747fb708668. --- tff_modular/modules/vampire/powers/feed.dm | 4 ++-- tff_modular/modules/vampire/sound/aaughmp3.ogg | Bin 70486 -> 0 bytes .../vampire/sound/nom-nom-nom_gPJiWn4.ogg | Bin 27517 -> 0 bytes .../modules/vampire/sound/peter-hehehe.ogg | Bin 89789 -> 0 bytes .../modules/vampire/sound/so-good-and-tasty.ogg | Bin 75607 -> 0 bytes 5 files changed, 2 insertions(+), 2 deletions(-) delete mode 100644 tff_modular/modules/vampire/sound/aaughmp3.ogg delete mode 100644 tff_modular/modules/vampire/sound/nom-nom-nom_gPJiWn4.ogg delete mode 100644 tff_modular/modules/vampire/sound/peter-hehehe.ogg delete mode 100644 tff_modular/modules/vampire/sound/so-good-and-tasty.ogg diff --git a/tff_modular/modules/vampire/powers/feed.dm b/tff_modular/modules/vampire/powers/feed.dm index a676427fe2c..a3bd237b1b9 100644 --- a/tff_modular/modules/vampire/powers/feed.dm +++ b/tff_modular/modules/vampire/powers/feed.dm @@ -214,8 +214,8 @@ // It begins... currently_feeding = TRUE - var/sound_of_feeding = pick('tff_modular/modules/vampire/sound/aaughmp3.ogg', 'tff_modular/modules/vampire/sound/nom-nom-nom_gPJiWn4.ogg', 'tff_modular/modules/vampire/sound/so-good-and-tasty.ogg', 'tff_modular/modules/vampire/sound/peter-hehehe.ogg') - playsound(living_owner, sound_of_feeding, 100, FALSE, pressure_affected = FALSE) + living_owner.playsound_local(null, 'tff_modular/modules/vampire/sound/drinkblood1.ogg', 100, FALSE, pressure_affected = FALSE) + // Just to make sure living_owner.stop_pulling() feed_target.stop_pulling() diff --git a/tff_modular/modules/vampire/sound/aaughmp3.ogg b/tff_modular/modules/vampire/sound/aaughmp3.ogg deleted file mode 100644 index 83f11f3f6e74ccaae7cef91881c4c70bf4c24649..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 70486 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%0DusR14w>EX?MnfU(?c| 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 diff --git a/tff_modular/modules/vampire/sound/nom-nom-nom_gPJiWn4.ogg b/tff_modular/modules/vampire/sound/nom-nom-nom_gPJiWn4.ogg deleted file mode 100644 index 58c43acbbd2caedc73e2868b70bc8a8b399d37ad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27517 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 diff --git a/tff_modular/modules/vampire/sound/peter-hehehe.ogg b/tff_modular/modules/vampire/sound/peter-hehehe.ogg deleted file mode 100644 index 5b0363fa55d399baf20bffa5134f640173b6a423..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 89789 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 Q`AZu95&BC&{Jq`y9}}XvCIA2c diff --git a/tff_modular/modules/vampire/sound/so-good-and-tasty.ogg b/tff_modular/modules/vampire/sound/so-good-and-tasty.ogg deleted file mode 100644 index 0e92ddffba825d6f275dda81beb7521e4c80079b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 75607 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%0DN`ehtFBgDeOSl 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≺PdW5yoA&L07H~&+(!JkaPc&<19*&E{6s;leWb@hvG;Op=F za(PKqr2j8}rH1>GzE1WRWUTMWLBLal={!ComnfSO=FJ;pB|KTJH+Vpmizkijyqa{2 zJ;WjIQ&IIVUlUwHWcj3Sh?x;2=tn}svKr@JD#+la>t;f~p&Y0u*GOKd&fUnSzyVOJ+0~mecEo4^X`8Pcm8>|Ek5>Vsq^Wddf|Y-2u%YD!>WC?>~t@r!_jOCES5wI z{Y0!t=NKBmW&vG+hnoC(706)vp+yi?ccwY%Kmq9X&c91{&{Byx=SPm+>`K^ujXaCt zf4q+_-BO@Onff<>(>Xd#6uFAJ!R5du&5uJ$acGw(%vz;9**PfF#u^I<%InkG1^tM<;5DhU zb(`4yfX=DdForGeQ+3v%JObotA^r+c%?23I=ZJoPv9C%Qk*QUN0mm65?^=X=jPNw9 zgpy;o97|h^V6;;+j`MONu<4_gAo?Rht^&q%wg=Vw_Zh|W&%95uVTR_ zU}L|q-fcp{2X9_Qe2&smz+-2Scp3V?<~RyP_RB=>8)Z8pfEgl|*M%ukh<&f0tzqE| zZ5d1`9Lm>B=73(Xhm9V&d&+f-9FLez+xi-r5F` zGYK*)l79h4G{%LoVvG>tQpus942v|A!SaSZhi%oO0u7gyn>kJ8Uvd)8hS+pr`5N7m zk4DLbO+pQ{6jI&uzR z3HgN3Eus>j4(i^`H)a05!mal}G8S^$l86+Sm4r&q62k=dJfy<uvG zMs2)U5IeO!6?=nW@Q`k*5b+sHysH?;l zR8UdxQ1|h(Y7W1pZw6@ondvta|1KMosNaV9#sGG-LO3)$oa45bHeOCsPU*u~KNzI1 zQ@~zPjQU8MXyj?g_b(YM366_+rNQTDjmZ^jeANvFh=yw#%*o)OO5SILXqUobq7~}! zr$I-~mFKTPLp4ERal_z>-;UeDj1|EZ?c%hF6>SxF!ZvVtj!vPbp}M1cjv+fHQ%}6% zYr_Q)s0SVo;J*F$Vk0xOyZ;)R>UybFk;34Czjv31c50YxaoD;vM^b7U@|w!R=sH1x LivK_UcLe?i9j`UT From 69fb9c766b42c23c4fc47599d3c10c05ec2b9332 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Thu, 2 Apr 2026 20:25:41 +0300 Subject: [PATCH 096/149] Update dynamic.dm --- tff_modular/modules/vampire/dynamic.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tff_modular/modules/vampire/dynamic.dm b/tff_modular/modules/vampire/dynamic.dm index 88261feacdc..59fb78a0ff7 100644 --- a/tff_modular/modules/vampire/dynamic.dm +++ b/tff_modular/modules/vampire/dynamic.dm @@ -5,6 +5,7 @@ preview_antag_datum = /datum/antagonist/vampire weight = 10 max_antag_cap = 4 + min_pop = 15 /datum/dynamic_ruleset/roundstart/vampire/assign_role(datum/mind/candidate) var/datum/antagonist/vampire/suck_datum = candidate.add_antag_datum(/datum/antagonist/vampire) @@ -19,6 +20,7 @@ weight = 10 repeatable = TRUE max_antag_cap = 4 + min_pop = 15 /datum/dynamic_ruleset/midround/from_living/vampire/is_valid_candidate(mob/candidate, client/candidate_client) if(!is_station_level(candidate.z)) From 185529b3a34b0fedeb9370cb7d36bf474aa43c76 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Thu, 2 Apr 2026 20:31:27 +0300 Subject: [PATCH 097/149] =?UTF-8?q?=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB?= =?UTF-8?q?=D1=8F=D0=B5=D0=BC=20=D0=B2=D1=81=D1=8F=D0=BA=D0=BE=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/__DEFINES/~ff_defines/bloodsucker.dm | 1 + config/dynamic.toml | 14 ++++++++++++-- tff_modular/modules/vampire/dynamic.dm | 11 +++++++++++ .../antagonists/antagonists/vampirelatejoin.ts | 16 ++++++++++++++++ 4 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/vampirelatejoin.ts diff --git a/code/__DEFINES/~ff_defines/bloodsucker.dm b/code/__DEFINES/~ff_defines/bloodsucker.dm index da4eb21a277..a9340d003c7 100644 --- a/code/__DEFINES/~ff_defines/bloodsucker.dm +++ b/code/__DEFINES/~ff_defines/bloodsucker.dm @@ -26,6 +26,7 @@ #define FACTION_VAMPIRE "Vampire" #define ROLE_VAMPIRE "Vampire" #define ROLE_VAMPIRIC_ACCIDENT "Vampiric Accident" +#define ROLE_VAMPIRE_LATEJOIN "Vampire LateJoin" #define span_awe(str) ("" + str + "") /// Uncomment this to enable testing of Vampire features (such as vassalizing people with a mind instead of a client). //#define VAMPIRE_TESTING diff --git a/config/dynamic.toml b/config/dynamic.toml index 2763f610b6e..836cd4cc974 100644 --- a/config/dynamic.toml +++ b/config/dynamic.toml @@ -685,7 +685,7 @@ weight = 10 min_pop = 15 blacklisted_roles = [] min_antag_cap = 1 -max_antag_cap = 4 +max_antag_cap.denominator = 24 minimum_required_age = 0 ["Vampiric Accident"] @@ -693,7 +693,17 @@ weight = 10 min_pop = 15 blacklisted_roles = [] min_antag_cap = 1 -max_antag_cap = 4 +max_antag_cap.denominator = 24 repeatable_weight_decrease = 2 repeatable = 1 minimum_required_age = 0 + +["Vampire LateJoin] +weight = 10 +min_pop = 15 +blacklisted_roles = [] +repeatable_weight_decrease = 2 +repeatable = 1 +minimum_required_age = 0 +min_antag_cap = 1 +max_antag_cap.denominator = 24 diff --git a/tff_modular/modules/vampire/dynamic.dm b/tff_modular/modules/vampire/dynamic.dm index 59fb78a0ff7..5f7b4149827 100644 --- a/tff_modular/modules/vampire/dynamic.dm +++ b/tff_modular/modules/vampire/dynamic.dm @@ -30,3 +30,14 @@ /datum/dynamic_ruleset/midround/from_living/vampire/assign_role(datum/mind/candidate) var/datum/antagonist/vampire/suck_datum = candidate.add_antag_datum(/datum/antagonist/vampire) suck_datum.rank_up(rand(3, 4)) + +/datum/dynamic_ruleset/latejoin/vampire + name = "Vampiric Accident" + config_tag = "Vampiric LateJoin" + preview_antag_datum = /datum/antagonist/vampire + pref_flag = ROLE_VAMPIRE_LATEJOIN + midround_type = LIGHT_MIDROUND + weight = 10 + repeatable = TRUE + max_antag_cap = 4 + min_pop = 15 diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/vampirelatejoin.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/vampirelatejoin.ts new file mode 100644 index 00000000000..0787636672b --- /dev/null +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/vampirelatejoin.ts @@ -0,0 +1,16 @@ +import { type Antagonist, Category } from '../base'; + +export const VAMPIRE_MECHANICAL_DESCRIPTION = ` +After your death, you awaken to see yourself as an undead monster. +Use your Vampiric abilities as best you can. +Scrape by Space Station 13, or take over it, ghoulizing your way. +`; + +const VampireLatejoin: Antagonist = { + key: 'vampirelatejoin', + name: 'Vampire (LateJoin)', + description: [VAMPIRE_MECHANICAL_DESCRIPTION], + category: Category.Latejoin, +}; + +export default VampireLatejoin; From 9c741df62da7160321040320a1c78e2ff0db82ee Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sat, 4 Apr 2026 15:18:58 +0300 Subject: [PATCH 098/149] Update dynamic.dm --- tff_modular/modules/vampire/dynamic.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/tff_modular/modules/vampire/dynamic.dm b/tff_modular/modules/vampire/dynamic.dm index 5f7b4149827..a4d21aad241 100644 --- a/tff_modular/modules/vampire/dynamic.dm +++ b/tff_modular/modules/vampire/dynamic.dm @@ -36,7 +36,6 @@ config_tag = "Vampiric LateJoin" preview_antag_datum = /datum/antagonist/vampire pref_flag = ROLE_VAMPIRE_LATEJOIN - midround_type = LIGHT_MIDROUND weight = 10 repeatable = TRUE max_antag_cap = 4 From fec4a80f681d162b9f6038a0113c7f70c8bdefa6 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sat, 4 Apr 2026 15:21:33 +0300 Subject: [PATCH 099/149] =?UTF-8?q?=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D1=8F=D0=B5=D0=BC=20=D0=B2=D1=81=D1=8F=D0=BA=D0=BE=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/__DEFINES/~ff_defines/bloodsucker.dm | 14 ++++++++++++++ tff_modular/modules/vampire/datum_vampire.dm | 2 +- tff_modular/modules/vampire/dynamic.dm | 12 +++++++++++- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/code/__DEFINES/~ff_defines/bloodsucker.dm b/code/__DEFINES/~ff_defines/bloodsucker.dm index a9340d003c7..899160d27f5 100644 --- a/code/__DEFINES/~ff_defines/bloodsucker.dm +++ b/code/__DEFINES/~ff_defines/bloodsucker.dm @@ -27,6 +27,20 @@ #define ROLE_VAMPIRE "Vampire" #define ROLE_VAMPIRIC_ACCIDENT "Vampiric Accident" #define ROLE_VAMPIRE_LATEJOIN "Vampire LateJoin" +#define BLOODSUCKER_RESTRICTED_SPECIES list( \ + /datum/species/synthetic, \ + /datum/species/plasmaman, \ + /datum/species/shadow/nightmare, \ + /datum/species/abductor, \ + /datum/species/android, \ + /datum/species/golem, \ + /datum/species/shadow, \ + /datum/species/skeleton, \ + /datum/species/zombie, \ + /datum/species/mutant, \ + /datum/species/dullahan, \ + /datum/species/hemophage \ +) #define span_awe(str) ("" + str + "") /// Uncomment this to enable testing of Vampire features (such as vassalizing people with a mind instead of a client). //#define VAMPIRE_TESTING diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index 6009e136381..fb76c24911b 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -12,7 +12,7 @@ hijack_speed = 0 - show_to_ghosts = TRUE + show_to_ghosts = FALSE /// How much blood we have, starting off at default blood levels. /// We don't use our actual body's temperature because some species don't have blood and we don't want to exclude them diff --git a/tff_modular/modules/vampire/dynamic.dm b/tff_modular/modules/vampire/dynamic.dm index a4d21aad241..de59fcfd557 100644 --- a/tff_modular/modules/vampire/dynamic.dm +++ b/tff_modular/modules/vampire/dynamic.dm @@ -7,6 +7,11 @@ max_antag_cap = 4 min_pop = 15 +/datum/dynamic_ruleset/roundstart/vampire/is_valid_candidate(mob/candidate, client/candidate_client) + if(is_species(candidate, BLOODSUCKER_RESTRICTED_SPECIES)) + return FALSE + return ..() + /datum/dynamic_ruleset/roundstart/vampire/assign_role(datum/mind/candidate) var/datum/antagonist/vampire/suck_datum = candidate.add_antag_datum(/datum/antagonist/vampire) suck_datum.rank_up(rand(3, 4)) @@ -23,7 +28,7 @@ min_pop = 15 /datum/dynamic_ruleset/midround/from_living/vampire/is_valid_candidate(mob/candidate, client/candidate_client) - if(!is_station_level(candidate.z)) + if(is_species(candidate, BLOODSUCKER_RESTRICTED_SPECIES)) return FALSE return ..() @@ -40,3 +45,8 @@ repeatable = TRUE max_antag_cap = 4 min_pop = 15 + +/datum/dynamic_ruleset/latejoin/vampire/is_valid_candidate(mob/candidate, client/candidate_client) + if(is_species(candidate, BLOODSUCKER_RESTRICTED_SPECIES)) + return FALSE + return ..() From 95206ed430a05226e25885f9984dc4113508ea1c Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sun, 5 Apr 2026 15:57:15 +0300 Subject: [PATCH 100/149] =?UTF-8?q?=D0=BE=D1=87=D0=B5=D0=BD=D1=8C=20=D0=B2?= =?UTF-8?q?=D0=B0=D0=B6=D0=BD=D0=BE=D0=B5=20=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/__DEFINES/~ff_defines/_globalvars/traits/declarations.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/__DEFINES/~ff_defines/_globalvars/traits/declarations.dm b/code/__DEFINES/~ff_defines/_globalvars/traits/declarations.dm index 656a681350c..9b3ae25f1ff 100644 --- a/code/__DEFINES/~ff_defines/_globalvars/traits/declarations.dm +++ b/code/__DEFINES/~ff_defines/_globalvars/traits/declarations.dm @@ -4,4 +4,3 @@ #define TRAIT_XENO_ABILITY_GIVEN "xeno_ability_given" /// Determines if something can receive healing from a xeno #define TRAIT_XENO_HEAL_AURA "trait_xeno_heal_aura" - From ff145e88af6ddaf80cd7fd008fd65ecbe09b7320 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sun, 5 Apr 2026 21:52:01 +0300 Subject: [PATCH 101/149] =?UTF-8?q?=D0=B2=D0=BE=D0=B7=D0=B2=D1=80=D0=B0?= =?UTF-8?q?=D1=89=D0=B0=D0=B5=D0=BC=20=D1=82=D1=80=D0=BE=D0=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tff_modular/modules/vampire/crafts.dm | 2 -- tff_modular/modules/vampire/datum_vampire.dm | 4 ++-- tff_modular/modules/vampire/objects/blood_throne.dm | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/tff_modular/modules/vampire/crafts.dm b/tff_modular/modules/vampire/crafts.dm index 9e6c066b8e9..45e9e786037 100644 --- a/tff_modular/modules/vampire/crafts.dm +++ b/tff_modular/modules/vampire/crafts.dm @@ -55,7 +55,6 @@ category = CAT_VAMPIRE crafting_flags = CRAFT_SKIP_MATERIALS_PARITY | CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND | CRAFT_MUST_BE_LEARNED -/* /datum/crafting_recipe/bloodthrone name = "Blood Throne" result = /obj/structure/vampire/bloodthrone @@ -68,7 +67,6 @@ category = CAT_VAMPIRE crafting_flags = CRAFT_SKIP_MATERIALS_PARITY | CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND | CRAFT_MUST_BE_LEARNED -*/ /datum/crafting_recipe/meatcoffin name = "Meat Coffin" diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index fb76c24911b..fc40b05c81a 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -330,7 +330,7 @@ owner.teach_crafting_recipe(list( /datum/crafting_recipe/vassalrack, /datum/crafting_recipe/candelabrum, - // /datum/crafting_recipe/bloodthrone, + /datum/crafting_recipe/bloodthrone, /datum/crafting_recipe/meatcoffin, )) @@ -367,7 +367,7 @@ owner.forget_crafting_recipe(list( /datum/crafting_recipe/vassalrack, /datum/crafting_recipe/candelabrum, - // /datum/crafting_recipe/bloodthrone, + /datum/crafting_recipe/bloodthrone, /datum/crafting_recipe/meatcoffin, )) diff --git a/tff_modular/modules/vampire/objects/blood_throne.dm b/tff_modular/modules/vampire/objects/blood_throne.dm index 7d898a81489..f00ff11c275 100644 --- a/tff_modular/modules/vampire/objects/blood_throne.dm +++ b/tff_modular/modules/vampire/objects/blood_throne.dm @@ -16,7 +16,7 @@ // Add rotating and armrest /obj/structure/vampire/bloodthrone/Initialize(mapload) - // AddComponent(/datum/component/simple_rotation) + AddElement(/datum/element/simple_rotation) return ..() // Rotating From 1fa51a10885fbd21ac1665b33dcda39126d17177 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Tue, 14 Apr 2026 18:47:29 +0300 Subject: [PATCH 102/149] =?UTF-8?q?=D0=BF=D0=B0=D1=80=D1=83=20=D0=B8=D0=B7?= =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/__DEFINES/~ff_defines/bloodsucker.dm | 4 ++-- tff_modular/modules/vampire/datum_vampire.dm | 2 +- tff_modular/modules/vampire/dynamic.dm | 4 ++-- tff_modular/modules/vampire/frenzy_vampire.dm | 4 +++- tff_modular/modules/vampire/life_vampire.dm | 1 + tff_modular/modules/vampire/powers/celerity/haste.dm | 2 +- tff_modular/modules/vampire/powers/potence/brash.dm | 2 +- tff_modular/modules/vampire/powers/potence/brawn.dm | 2 +- tff_modular/modules/vampire/powers/thaumaturgy/bloodbolt.dm | 2 +- tff_modular/modules/vampire/torpor_vampire.dm | 3 +++ 10 files changed, 16 insertions(+), 10 deletions(-) diff --git a/code/__DEFINES/~ff_defines/bloodsucker.dm b/code/__DEFINES/~ff_defines/bloodsucker.dm index 899160d27f5..9c18450d64b 100644 --- a/code/__DEFINES/~ff_defines/bloodsucker.dm +++ b/code/__DEFINES/~ff_defines/bloodsucker.dm @@ -67,10 +67,10 @@ /// The number that incoming levels are divided by when comitting the Amaranth. Example: 2 would divide the victims level by 2, and give that to the diablerist #define DIABLERIE_DIVISOR 1.5 /// Amount of vitae drunk from another player required to level up. -#define VITAE_GOAL_STANDARD 150 +#define VITAE_GOAL_STANDARD 200 /// Default amount of damage the vampire's punch/kick damage increases with each level. -#define VAMPIRE_UNARMED_DMG_INCREASE_ON_RANKUP 1 +#define VAMPIRE_UNARMED_DMG_INCREASE_ON_RANKUP 0.5 /// How many starting levels do we want each one to have? #define VAMPIRE_STARTING_LEVELS 3 diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index fc40b05c81a..46d9f604803 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -92,7 +92,7 @@ /// Additional regeneration when the vampire has a lot of blood var/additional_regen /// How much damage the vampire heals each life tick. Increases per rank up - var/vampire_regen_rate = 0.6 + var/vampire_regen_rate = 0.3 /// Minimum cooldown when reviving. COOLDOWN_DECLARE(revive_cooldown) diff --git a/tff_modular/modules/vampire/dynamic.dm b/tff_modular/modules/vampire/dynamic.dm index de59fcfd557..171e3da27ec 100644 --- a/tff_modular/modules/vampire/dynamic.dm +++ b/tff_modular/modules/vampire/dynamic.dm @@ -14,7 +14,7 @@ /datum/dynamic_ruleset/roundstart/vampire/assign_role(datum/mind/candidate) var/datum/antagonist/vampire/suck_datum = candidate.add_antag_datum(/datum/antagonist/vampire) - suck_datum.rank_up(rand(3, 4)) + suck_datum.rank_up(VAMPIRE_STARTING_LEVELS) /datum/dynamic_ruleset/midround/from_living/vampire name = "Vampiric Accident" @@ -34,7 +34,7 @@ /datum/dynamic_ruleset/midround/from_living/vampire/assign_role(datum/mind/candidate) var/datum/antagonist/vampire/suck_datum = candidate.add_antag_datum(/datum/antagonist/vampire) - suck_datum.rank_up(rand(3, 4)) + suck_datum.rank_up(VAMPIRE_STARTING_LEVELS) /datum/dynamic_ruleset/latejoin/vampire name = "Vampiric Accident" diff --git a/tff_modular/modules/vampire/frenzy_vampire.dm b/tff_modular/modules/vampire/frenzy_vampire.dm index ea824ef459c..329592d96e5 100644 --- a/tff_modular/modules/vampire/frenzy_vampire.dm +++ b/tff_modular/modules/vampire/frenzy_vampire.dm @@ -100,7 +100,9 @@ if(vampiredatum.current_vitae >= FRENZY_THRESHOLD_EXIT) qdel(src) return - if(carbon_owner.stat != DEAD || !HAS_TRAIT(carbon_owner, TRAIT_TORPOR)) + if(carbon_owner.stat == DEAD || HAS_TRAIT(carbon_owner, TRAIT_TORPOR)) + return FALSE + else carbon_owner.adjust_fire_loss(0.75 + (vampiredatum.vampire_level * 0.05)) carbon_owner.set_jitter_if_lower(10 SECONDS) diff --git a/tff_modular/modules/vampire/life_vampire.dm b/tff_modular/modules/vampire/life_vampire.dm index 405646f0d57..8a79c4240e8 100644 --- a/tff_modular/modules/vampire/life_vampire.dm +++ b/tff_modular/modules/vampire/life_vampire.dm @@ -72,6 +72,7 @@ current.adjust_organ_loss(ORGAN_SLOT_BRAIN, -1 * (actual_regen * 4)) current.adjust_organ_loss(ORGAN_SLOT_EYES, -1 * (actual_regen * 4)) current.adjust_organ_loss(ORGAN_SLOT_EARS, -1 * (actual_regen * 4)) + current.adjust_organ_loss(ORGAN_SLOT_EARS, -1 * (actual_regen * 4)) if(!iscarbon(current)) return FALSE var/mob/living/carbon/carbon_owner = current diff --git a/tff_modular/modules/vampire/powers/celerity/haste.dm b/tff_modular/modules/vampire/powers/celerity/haste.dm index d87b374232d..98d67bf4bea 100644 --- a/tff_modular/modules/vampire/powers/celerity/haste.dm +++ b/tff_modular/modules/vampire/powers/celerity/haste.dm @@ -99,6 +99,6 @@ continue hit += hit_living playsound(hit_living, SFX_PUNCH, 15, TRUE, -1) - hit_living.adjust_stamina_loss(20 + level_current * 8) + hit_living.adjust_stamina_loss(10 + level_current * 8) hit_living.Knockdown(10 + level_current * 8) hit_living.spin(1 SECONDS, 1) diff --git a/tff_modular/modules/vampire/powers/potence/brash.dm b/tff_modular/modules/vampire/powers/potence/brash.dm index 949e13d1f86..20586c9c826 100644 --- a/tff_modular/modules/vampire/powers/potence/brash.dm +++ b/tff_modular/modules/vampire/powers/potence/brash.dm @@ -20,7 +20,7 @@ vampire_power_flags = BP_AM_VERY_DYNAMIC_COOLDOWN vitaecost = 0 // Set on use cooldown_time = 1 SECONDS // Same as above - damage_coefficient = 1.75 + damage_coefficient = 1.625 brujah = TRUE level_current = 1 diff --git a/tff_modular/modules/vampire/powers/potence/brawn.dm b/tff_modular/modules/vampire/powers/potence/brawn.dm index afbda23e47d..ed96bdd71b8 100644 --- a/tff_modular/modules/vampire/powers/potence/brawn.dm +++ b/tff_modular/modules/vampire/powers/potence/brawn.dm @@ -17,7 +17,7 @@ ranged_mousepointer = 'tff_modular/modules/vampire/icons/vampire_strength.dmi' /// Only changed by the '/brawn/brash' subtype; acts as a general purpose damage multipler. - var/damage_coefficient = 1.5 + var/damage_coefficient = 1.25 /// Boolean indicating whether or not this version of '/brawn' is in the '/brash' subtype and should /// bypass typical ability level restrictions. (There is probably a better way to do this.) var/brujah = FALSE diff --git a/tff_modular/modules/vampire/powers/thaumaturgy/bloodbolt.dm b/tff_modular/modules/vampire/powers/thaumaturgy/bloodbolt.dm index daa7f01565b..01e0a190bde 100644 --- a/tff_modular/modules/vampire/powers/thaumaturgy/bloodbolt.dm +++ b/tff_modular/modules/vampire/powers/thaumaturgy/bloodbolt.dm @@ -8,7 +8,7 @@ vampire_power_flags = NONE vampire_check_flags = BP_CANT_USE_IN_TORPOR | BP_CANT_USE_WHILE_STAKED | BP_CANT_USE_IN_FRENZY | BP_CANT_USE_WHILE_INCAPACITATED | BP_CANT_USE_WHILE_UNCONSCIOUS vitaecost = 60 - cooldown_time = 40 SECONDS + cooldown_time = 60 SECONDS target_range = 80 // Sniper :) power_activates_immediately = FALSE prefire_message = "Select your target." diff --git a/tff_modular/modules/vampire/torpor_vampire.dm b/tff_modular/modules/vampire/torpor_vampire.dm index bcb3b527b69..1e0b13b4014 100644 --- a/tff_modular/modules/vampire/torpor_vampire.dm +++ b/tff_modular/modules/vampire/torpor_vampire.dm @@ -15,6 +15,9 @@ **/ /datum/antagonist/vampire/proc/check_begin_torpor() var/mob/living/carbon/carbon_owner = owner.current + var/datum/antagonist/vampire/antag_datum = IS_VAMPIRE(carbon_owner) + antag_datum.try_regenerate_limbs() + antag_datum.heal_vampire_organs() if(QDELETED(carbon_owner)) return var/total_damage = carbon_owner.get_brute_loss() + carbon_owner.get_fire_loss() From 66a19319905feccc23fbfd13d2c6076912a0788c Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Tue, 14 Apr 2026 18:52:49 +0300 Subject: [PATCH 103/149] Update leveling_vampire.dm --- tff_modular/modules/vampire/leveling_vampire.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tff_modular/modules/vampire/leveling_vampire.dm b/tff_modular/modules/vampire/leveling_vampire.dm index 52e515ab258..c984f918ee3 100644 --- a/tff_modular/modules/vampire/leveling_vampire.dm +++ b/tff_modular/modules/vampire/leveling_vampire.dm @@ -11,7 +11,7 @@ SUBSYSTEM_DEF(vampire_leveling) name = "Vampire Leveling" wait = 15 MINUTES - flags = SS_NO_INIT | SS_KEEP_TIMING + ss_flags = SS_NO_INIT | SS_KEEP_TIMING can_fire = FALSE /datum/controller/subsystem/vampire_leveling/fire(resumed = FALSE) From 4cfcf9bd79171f13be8dee902939483a8f42bbc1 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Wed, 15 Apr 2026 20:36:25 +0300 Subject: [PATCH 104/149] Update datum_vampire.dm --- tff_modular/modules/vampire/datum_vampire.dm | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index 46d9f604803..785879d1594 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -460,11 +460,8 @@ .["powers"] += list(power_data) /datum/antagonist/vampire/get_preview_icon() - var/icon/final_icon = render_preview_outfit(/datum/outfit/vampire_outfit) - var/icon/blood_icon = icon('icons/effects/blood.dmi', "suitblood") - blood_icon.Blend(BLOOD_COLOR_RED, ICON_MULTIPLY) - final_icon.Blend(blood_icon, ICON_OVERLAY) - + var/datum/universal_icon/final_icon = render_preview_outfit(/datum/outfit/vampire_outfit) + final_icon.scale(64, 64) return finish_preview_icon(final_icon) /datum/antagonist/vampire/roundend_report() From 8d82d2a5170f796cd2f530e06d0e404b3c86bc74 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Wed, 15 Apr 2026 20:41:11 +0300 Subject: [PATCH 105/149] =?UTF-8?q?=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D1=8F=D0=B5=D0=BC=20=D1=84=D0=B0=D0=BA=D1=88=D0=B8=D0=BE?= =?UTF-8?q?=D0=BD=20=D1=80=D0=B0=D0=BD=D1=82=D0=B0=D0=B9=D0=BC=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tff_modular/modules/vampire/datum_vampire.dm | 5 ++--- tff_modular/modules/vampire/vassals/datum_vassal.dm | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index 785879d1594..a99f8ed4ea1 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -210,8 +210,7 @@ current_mob.clear_mood_event("vampcandle") add_team_hud(current_mob) - - current_mob.faction += FACTION_VAMPIRE + current_mob.add_faction(FACTION_VAMPIRE) if(current_mob.hud_used) on_hud_created() @@ -268,7 +267,7 @@ QDEL_NULL(vamprank_display) QDEL_NULL(humanity_display) - current_mob.faction -= FACTION_VAMPIRE + current_mob.remove_faction(FACTION_VAMPIRE) if(ishuman(current_mob)) var/mob/living/carbon/human/current_human = current_mob diff --git a/tff_modular/modules/vampire/vassals/datum_vassal.dm b/tff_modular/modules/vampire/vassals/datum_vassal.dm index d4d4bfd94fc..ecdcf995b19 100644 --- a/tff_modular/modules/vampire/vassals/datum_vassal.dm +++ b/tff_modular/modules/vampire/vassals/datum_vassal.dm @@ -37,7 +37,7 @@ // setup_monitor(current_mob) current_mob.grant_language(/datum/language/vampiric, source = LANGUAGE_VASSAL) - current_mob.faction += FACTION_VAMPIRE + current_mob.add_faction(FACTION_VAMPIRE) current_mob.clear_mood_event("vampcandle") @@ -54,7 +54,7 @@ // Remove traits REMOVE_TRAITS_IN(current_mob, TRAIT_VAMPIRE) - current_mob.faction -= FACTION_VAMPIRE + current_mob.remove_faction(FACTION_VAMPIRE) /datum/antagonist/vassal/on_gain() . = ..() From 77db098d92ab1a6fc9d40ae3f971f489f6b97005 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Wed, 15 Apr 2026 20:45:49 +0300 Subject: [PATCH 106/149] =?UTF-8?q?=D0=BD=D0=B5=20=D0=BF=D0=BE=20=D1=82?= =?UTF-8?q?=D0=B3=D1=88=D0=BD=D0=BE=D0=BC=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tff_modular/modules/vampire/clans/_clan.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tff_modular/modules/vampire/clans/_clan.dm b/tff_modular/modules/vampire/clans/_clan.dm index 32957ab982b..01405310c59 100644 --- a/tff_modular/modules/vampire/clans/_clan.dm +++ b/tff_modular/modules/vampire/clans/_clan.dm @@ -220,7 +220,7 @@ user_left_hand.unarmed_damage_high += vampiredatum.extra_damage_per_rank user_right_hand.unarmed_damage_high += vampiredatum.extra_damage_per_rank vampiredatum.current_damage_bonus += vampiredatum.extra_damage_per_rank - vampiredatum.vampire_regen_rate += 0.05 + vampiredatum.vampire_regen_rate += 0.1 vampiredatum.max_vitae += 100 /* if(ishuman(vampiredatum.owner.current)) From 24c823a2c43df3b9c67ba6b0c857eb0433f8326e Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Wed, 15 Apr 2026 21:03:06 +0300 Subject: [PATCH 107/149] =?UTF-8?q?=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=B1=D0=B0=D0=B3=D0=BE=D0=B2?= =?UTF-8?q?=20=D0=B8=20=D0=BE=D0=B3=D1=80=D0=B0=D0=BD=D0=B8=D1=87=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=20=D1=80=D0=B0=D1=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/__DEFINES/~ff_defines/bloodsucker.dm | 6 +++++- tff_modular/modules/vampire/misc_procs_vampire.dm | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/code/__DEFINES/~ff_defines/bloodsucker.dm b/code/__DEFINES/~ff_defines/bloodsucker.dm index 9c18450d64b..c5b2337ba30 100644 --- a/code/__DEFINES/~ff_defines/bloodsucker.dm +++ b/code/__DEFINES/~ff_defines/bloodsucker.dm @@ -39,7 +39,11 @@ /datum/species/zombie, \ /datum/species/mutant, \ /datum/species/dullahan, \ - /datum/species/hemophage \ + /datum/species/hemophage, \ + /datum/species/jelly/slime, \ + /datum/species/jelly, \ + /datum/species/ethereal, \ + /datum/species/abductor/abductorweak \ ) #define span_awe(str) ("" + str + "") /// Uncomment this to enable testing of Vampire features (such as vassalizing people with a mind instead of a client). diff --git a/tff_modular/modules/vampire/misc_procs_vampire.dm b/tff_modular/modules/vampire/misc_procs_vampire.dm index ab3aac9c314..72279ba689c 100644 --- a/tff_modular/modules/vampire/misc_procs_vampire.dm +++ b/tff_modular/modules/vampire/misc_procs_vampire.dm @@ -364,7 +364,7 @@ return FALSE if(HAS_MIND_TRAIT(watcher, TRAIT_VAMPIRE_ALIGNED)) return FALSE - if((FACTION_VAMPIRE in watcher.faction) || (REF(owner.current) in watcher.faction)) + if(watcher.has_faction(FACTION_VAMPIRE)) return FALSE if(watcher.mind.has_antag_datum_in_list(weirdo_antags)) return FALSE From 0e0536f4697ffe769cb9fff0dc12aa67e5fb8a5d Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Wed, 15 Apr 2026 21:24:43 +0300 Subject: [PATCH 108/149] =?UTF-8?q?=D0=B8=D0=BA=D0=BE=D0=BD=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../screenshot_antag_icons_vampire.png | Bin 0 -> 1607 bytes .../screenshot_antag_icons_vampirelatejoin.png | Bin 0 -> 1607 bytes .../screenshot_antag_icons_vampiricaccident.png | Bin 0 -> 1607 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 code/modules/unit_tests/screenshots/screenshot_antag_icons_vampire.png create mode 100644 code/modules/unit_tests/screenshots/screenshot_antag_icons_vampirelatejoin.png create mode 100644 code/modules/unit_tests/screenshots/screenshot_antag_icons_vampiricaccident.png diff --git a/code/modules/unit_tests/screenshots/screenshot_antag_icons_vampire.png b/code/modules/unit_tests/screenshots/screenshot_antag_icons_vampire.png new file mode 100644 index 0000000000000000000000000000000000000000..e6b63d768e31f3f49ba46281b1e50248ed856c46 GIT binary patch literal 1607 zcmY*ZdpHwn7@tm(4v~^1CzmV~qKirH^B|+lCC_0}+t@;Ga~V@qiqX$;liPNf!lETLW+5$X&E3rGCeq|@S zzARRxnMppY@iR4gE3>;U>2PrEDtGDx6EdUe&Ri{yn@M8rk~aJQGpVjUEkB}o7mA)Z z+w6Pr`f>3}x6S=)_4_}STm|SK{tJEF#)gGJ#>WqFDl04RWuN-m(a|Bd5U2A~jvZhP z>Y%Xl59I?`JcT#AFl=Y&aa*QK3(y6YSiMDzd=!akEu!>#lO&Oh(6McFm3HKHSO`tj zRS9E_CA88WXDXcDB(sKl`$Li`4EKGadEJRO=LdUzx;ao`hFo6N^6UOfJPi$T28^__ zhYzBWxL+78%L`ckjNohXk7$!c8R(*c8u#)o80`y3plNd;hRdCB!Roi)Eg)EEQ}rf} zpAmo%T3YL6^Si^$ja-#xbrQ_s=n%_vkdR*Xh9u|>a-w`W6B5Hqtn=W5R&-XMScSWN zi;y7^_1Ja!dA9LgD;_kZHSqoV=N>`bOJ)s_SXP+|Q%i5{VdF8Uak6 z^(~cXEY4miZh#QCR+=*W^_r0?gE886N-CR^&7?@`vwR>)wNDWjSI)(b8}&m$Nec&s z$c02rR#a0DZa6d#7H)jdS2Fsu8rh^}+{nTEk)WZWfl-s#3j9x5osAui8rXBFG+1~x zhpUb^jftPw~>MqL4O)Vu-Vhge1wwv^&^JQ?Fk;-q1uIf=l472i;PJo`I3$5B?=o#Ac4rqbbn?Sljtls z!nghf1LH}^&ID7&9?nx1$JpgEJhK9L!sWP`4}uyVB(e%kd2t3vf>T*}r0OL95xs6p zVJPE39PNQukirC2Z_j$t^}Hdr`IER`b8f{v7R)=Q?j%do^*b3VbMq@Y6!K1(ne)fb)k2ev{1G`^Y>&K3rY|j%8$BMb)t92)j#p0CaN4I}t za6@*9gI|D!c^!!cOtyYlKg2`+j*c*L5$7ZnfV(N z>2gZzT^z|2=MKr6?iGicNsQE~0c2H+wr071m{$ScrO#oT&zUi9WCn?a8_M1X?zE{0 zhZN;x_km1;;iU?9%j(*V2Lt-YAbB733yst7;nYPbim8yHe-{~ zOUl)0!76VKR9?(5y-yr;OgvZBtK_u|`Ir~KH7pea+OL6gf;0f{&#<|>cKo|lpOYD$ zVKuoS2sZi{BkqsS*vQ0F?o2DAm6>BrPN+1^S_)Wl)lhPOsFR}uXW}nDuk$V2f*@OL zKk=Pct+{&@HC()&fl8CeSwt{zg+9?C(1E|TD8Tl!<QP#vA{fu%>pu@AiRH%6HSNB{r; literal 0 HcmV?d00001 diff --git a/code/modules/unit_tests/screenshots/screenshot_antag_icons_vampirelatejoin.png b/code/modules/unit_tests/screenshots/screenshot_antag_icons_vampirelatejoin.png new file mode 100644 index 0000000000000000000000000000000000000000..e6b63d768e31f3f49ba46281b1e50248ed856c46 GIT binary patch literal 1607 zcmY*ZdpHwn7@tm(4v~^1CzmV~qKirH^B|+lCC_0}+t@;Ga~V@qiqX$;liPNf!lETLW+5$X&E3rGCeq|@S zzARRxnMppY@iR4gE3>;U>2PrEDtGDx6EdUe&Ri{yn@M8rk~aJQGpVjUEkB}o7mA)Z z+w6Pr`f>3}x6S=)_4_}STm|SK{tJEF#)gGJ#>WqFDl04RWuN-m(a|Bd5U2A~jvZhP z>Y%Xl59I?`JcT#AFl=Y&aa*QK3(y6YSiMDzd=!akEu!>#lO&Oh(6McFm3HKHSO`tj zRS9E_CA88WXDXcDB(sKl`$Li`4EKGadEJRO=LdUzx;ao`hFo6N^6UOfJPi$T28^__ zhYzBWxL+78%L`ckjNohXk7$!c8R(*c8u#)o80`y3plNd;hRdCB!Roi)Eg)EEQ}rf} zpAmo%T3YL6^Si^$ja-#xbrQ_s=n%_vkdR*Xh9u|>a-w`W6B5Hqtn=W5R&-XMScSWN zi;y7^_1Ja!dA9LgD;_kZHSqoV=N>`bOJ)s_SXP+|Q%i5{VdF8Uak6 z^(~cXEY4miZh#QCR+=*W^_r0?gE886N-CR^&7?@`vwR>)wNDWjSI)(b8}&m$Nec&s z$c02rR#a0DZa6d#7H)jdS2Fsu8rh^}+{nTEk)WZWfl-s#3j9x5osAui8rXBFG+1~x zhpUb^jftPw~>MqL4O)Vu-Vhge1wwv^&^JQ?Fk;-q1uIf=l472i;PJo`I3$5B?=o#Ac4rqbbn?Sljtls z!nghf1LH}^&ID7&9?nx1$JpgEJhK9L!sWP`4}uyVB(e%kd2t3vf>T*}r0OL95xs6p zVJPE39PNQukirC2Z_j$t^}Hdr`IER`b8f{v7R)=Q?j%do^*b3VbMq@Y6!K1(ne)fb)k2ev{1G`^Y>&K3rY|j%8$BMb)t92)j#p0CaN4I}t za6@*9gI|D!c^!!cOtyYlKg2`+j*c*L5$7ZnfV(N z>2gZzT^z|2=MKr6?iGicNsQE~0c2H+wr071m{$ScrO#oT&zUi9WCn?a8_M1X?zE{0 zhZN;x_km1;;iU?9%j(*V2Lt-YAbB733yst7;nYPbim8yHe-{~ zOUl)0!76VKR9?(5y-yr;OgvZBtK_u|`Ir~KH7pea+OL6gf;0f{&#<|>cKo|lpOYD$ zVKuoS2sZi{BkqsS*vQ0F?o2DAm6>BrPN+1^S_)Wl)lhPOsFR}uXW}nDuk$V2f*@OL zKk=Pct+{&@HC()&fl8CeSwt{zg+9?C(1E|TD8Tl!<QP#vA{fu%>pu@AiRH%6HSNB{r; literal 0 HcmV?d00001 diff --git a/code/modules/unit_tests/screenshots/screenshot_antag_icons_vampiricaccident.png b/code/modules/unit_tests/screenshots/screenshot_antag_icons_vampiricaccident.png new file mode 100644 index 0000000000000000000000000000000000000000..e6b63d768e31f3f49ba46281b1e50248ed856c46 GIT binary patch literal 1607 zcmY*ZdpHwn7@tm(4v~^1CzmV~qKirH^B|+lCC_0}+t@;Ga~V@qiqX$;liPNf!lETLW+5$X&E3rGCeq|@S zzARRxnMppY@iR4gE3>;U>2PrEDtGDx6EdUe&Ri{yn@M8rk~aJQGpVjUEkB}o7mA)Z z+w6Pr`f>3}x6S=)_4_}STm|SK{tJEF#)gGJ#>WqFDl04RWuN-m(a|Bd5U2A~jvZhP z>Y%Xl59I?`JcT#AFl=Y&aa*QK3(y6YSiMDzd=!akEu!>#lO&Oh(6McFm3HKHSO`tj zRS9E_CA88WXDXcDB(sKl`$Li`4EKGadEJRO=LdUzx;ao`hFo6N^6UOfJPi$T28^__ zhYzBWxL+78%L`ckjNohXk7$!c8R(*c8u#)o80`y3plNd;hRdCB!Roi)Eg)EEQ}rf} zpAmo%T3YL6^Si^$ja-#xbrQ_s=n%_vkdR*Xh9u|>a-w`W6B5Hqtn=W5R&-XMScSWN zi;y7^_1Ja!dA9LgD;_kZHSqoV=N>`bOJ)s_SXP+|Q%i5{VdF8Uak6 z^(~cXEY4miZh#QCR+=*W^_r0?gE886N-CR^&7?@`vwR>)wNDWjSI)(b8}&m$Nec&s z$c02rR#a0DZa6d#7H)jdS2Fsu8rh^}+{nTEk)WZWfl-s#3j9x5osAui8rXBFG+1~x zhpUb^jftPw~>MqL4O)Vu-Vhge1wwv^&^JQ?Fk;-q1uIf=l472i;PJo`I3$5B?=o#Ac4rqbbn?Sljtls z!nghf1LH}^&ID7&9?nx1$JpgEJhK9L!sWP`4}uyVB(e%kd2t3vf>T*}r0OL95xs6p zVJPE39PNQukirC2Z_j$t^}Hdr`IER`b8f{v7R)=Q?j%do^*b3VbMq@Y6!K1(ne)fb)k2ev{1G`^Y>&K3rY|j%8$BMb)t92)j#p0CaN4I}t za6@*9gI|D!c^!!cOtyYlKg2`+j*c*L5$7ZnfV(N z>2gZzT^z|2=MKr6?iGicNsQE~0c2H+wr071m{$ScrO#oT&zUi9WCn?a8_M1X?zE{0 zhZN;x_km1;;iU?9%j(*V2Lt-YAbB733yst7;nYPbim8yHe-{~ zOUl)0!76VKR9?(5y-yr;OgvZBtK_u|`Ir~KH7pea+OL6gf;0f{&#<|>cKo|lpOYD$ zVKuoS2sZi{BkqsS*vQ0F?o2DAm6>BrPN+1^S_)Wl)lhPOsFR}uXW}nDuk$V2f*@OL zKk=Pct+{&@HC()&fl8CeSwt{zg+9?C(1E|TD8Tl!<QP#vA{fu%>pu@AiRH%6HSNB{r; literal 0 HcmV?d00001 From 220d58be02ab9e58da645e12925ee3b9409cb16a Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Thu, 16 Apr 2026 18:09:02 +0300 Subject: [PATCH 109/149] Update datum_vampire.dm --- tff_modular/modules/vampire/datum_vampire.dm | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index a99f8ed4ea1..e89465496b1 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -459,9 +459,14 @@ .["powers"] += list(power_data) /datum/antagonist/vampire/get_preview_icon() - var/datum/universal_icon/final_icon = render_preview_outfit(/datum/outfit/vampire_outfit) - final_icon.scale(64, 64) - return finish_preview_icon(final_icon) + var/datum/universal_icon/vampire_icon = render_preview_outfit(/datum/outfit/vampire_outfit) + var/datum/universal_icon/blood_icon = uni_icon('icons/effects/blood.dmi', "suitblood") + blood_icon.blend_color(BLOOD_COLOR_RED, ICON_MULTIPLY) + vampire_icon.blend_icon(blood_icon, ICON_OVERLAY) + + var/datum/universal_icon/final_icon = finish_preview_icon(vampire_icon) + + return final_icon /datum/antagonist/vampire/roundend_report() var/list/report = list() From 9dae1dc3c4bb5bac7c60b97e204d4bf65ed89627 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Thu, 16 Apr 2026 18:10:56 +0300 Subject: [PATCH 110/149] Revert "Update datum_vampire.dm" This reverts commit 220d58be02ab9e58da645e12925ee3b9409cb16a. --- tff_modular/modules/vampire/datum_vampire.dm | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index e89465496b1..a99f8ed4ea1 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -459,14 +459,9 @@ .["powers"] += list(power_data) /datum/antagonist/vampire/get_preview_icon() - var/datum/universal_icon/vampire_icon = render_preview_outfit(/datum/outfit/vampire_outfit) - var/datum/universal_icon/blood_icon = uni_icon('icons/effects/blood.dmi', "suitblood") - blood_icon.blend_color(BLOOD_COLOR_RED, ICON_MULTIPLY) - vampire_icon.blend_icon(blood_icon, ICON_OVERLAY) - - var/datum/universal_icon/final_icon = finish_preview_icon(vampire_icon) - - return final_icon + var/datum/universal_icon/final_icon = render_preview_outfit(/datum/outfit/vampire_outfit) + final_icon.scale(64, 64) + return finish_preview_icon(final_icon) /datum/antagonist/vampire/roundend_report() var/list/report = list() From e1d9f45165daa841177064757742f92f6bd8d530 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Thu, 16 Apr 2026 18:12:53 +0300 Subject: [PATCH 111/149] =?UTF-8?q?=D1=84=D0=B8=D0=BA=D1=81=20=D1=81=D0=BF?= =?UTF-8?q?=D1=80=D0=B0=D0=B9=D1=82=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../screenshot_antag_icons_vampire.png | Bin 1607 -> 745 bytes .../screenshot_antag_icons_vampirelatejoin.png | Bin 1607 -> 745 bytes ...screenshot_antag_icons_vampiricaccident.png | Bin 1607 -> 745 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/code/modules/unit_tests/screenshots/screenshot_antag_icons_vampire.png b/code/modules/unit_tests/screenshots/screenshot_antag_icons_vampire.png index e6b63d768e31f3f49ba46281b1e50248ed856c46..6c1894057665a42bb53bec90aadc92afdc13a253 100644 GIT binary patch delta 685 zcmV;e0#g0Q4Cw`s8Gi!+007lShYA1y0Ao;0R7C&)0N>x=%*@O^1^||UfJYn{at#2Q zg@c!Zfkhe?W-|ah6A)ku06`ZNJ{1!-5Dp3o3J(tt92^{$mX@WZr6D09BO@cBo}2ab z^u@xyARr*YzPsSw+_|~A$;QGTA0Hkb9`47nApigX0d!JMQwab-=GbNc003l>B{P2j zaxBfbI5Sc+(=$pSoZ^zil2jm5Nr{UyC9|j)$TZ~QOe;#vO@*+P6(B|5tj>JGPDNxRe(H4=i#RT?xj4>AI^lyTYuZ*U4Is#~1V0-HUbhfg7?G^? zt8>8sV;BLlgVs?P{nYvY0PLd<&^8LAWYGXO0^q?q>IFI;k218$;&l)Mj0Jz3Am`jG z)HKZ-1k+%INr$zi0`}hfyQCPjZTkViv|ZQLaf2WRm>b}O>+~?sA~^qq2+<*gHO2b0 zC;(h30m6SAubBWiXATg85nq0iD-+Ve0Am1(ZunOAeNUqTn`Mii?DgfWeXtEMCqQ|` z(vY5qVW3Gm96!lf?wMG@{C$4_%H_51HP~Yud|I3XYCp?8YD>lz+6K6&*ypK^4uGTy zi~!Cg9pW+oXz(`PJKwMKQVhbCg^m*_!~jpQQ8d6T0Q{SGUg0c?K@N&R4qZAlA<+zQ z5x`40IcIgE?}1WE>BsMZ>KQ_GySWU&>ieQ708~}rAJ0V{;;bqX!1Nh=)0qHY%M{E3 Tnrp=?00000NkvXXu0mjf_;ex! delta 1553 zcmY*ZdpHwn9G*@%Ix9j+a&pO%LL`RV=RuY-l;<$fHYOx@V~k3`2BeR0~^kInt?f&iA~}^ZovLf6x1Szu)`uB)frG%0MXq0Puzs1KzwY zXWu)4JJ;aRU^MmSrDGqIshxZ^-C5olwkLQ`Zf-N!%`hWH&&h>^lgJ1ULc!k|ZaHjeBh2eBl|iw})c)A~t{9eS^%nO6#TDqSiY?3Z(}d6mTsGt@6& zHh-i<>|*pbCY%Up*x<~aVn7#ET^Jk1F$)RIeVg+Ce`b}{=ViurR=@&hF1C3dyJ;p` z@3pGB@#OIPlIsBN6MqJpSy?fWsMy#Mc1=x9WzN~p-QC^N%eWYgA98H~U!V*QDW5JM zz@(G8i_4=nI`4By&+YbXLEFTk~mg7~K z;Vmz*qrv&`P`zWG;_;u9Nc!zlx^^B9`AtntbXxt6==lsqoMoHb*(# zfHUwSXK4My(8|k|tX?n1aDIoIJfhS?RdYpBdTuqI99@VBwU*M}d}Ee^3}OBzq8zen zK}Su8x=K~19&*P>|1l|27Ad~Z7_~M1zSjbe8<8H z6=GRxz``TuX^I?FL|2?EXQW}d!11l(Qjs1}zd*cQxdgba1nP^LP4i~-FbIx(BcA2Y zk#Me<3oc#O(h=`yt^NDo{-eX$5=7M1Q z(HQD|cYojvMeD#;*R94u)&;ZJUvlq6J>oCfryL~2oySJ!MLOelBiaqtu06S>;hkuA zCb2(xZ%$a)j!UFWjNQB1A~`bL1yq-S>zgs6bzJ+leV~SuzG)-#d3(4jnoM+&;i{$Y z(0dk80jWEA+Yb>AS@yEU*SJnxbsX3~WT_oJdAciKFd8l5h^{xDHjc*1E{!XE^>ABG ziJg~^sYxS|3QDqk@MMIG`YrIPu9GM??k=R~%`+l80#mXRPr$`OqjE5nZWHaIvP`ffh>par~BIvy-eFkHb-^`!?7k%BxMwRoUF<2 zaY*f38Os#qjmQ`r6a^cKb(JYTq&=pcZPNdkFAu4peZaK&8PacM`ilhH%HI0!wWej_5wgwqSZ*4l)-pXG>9G?>0}QTp>gkUs z%GIR?$WI)txsqW}MHse^_p9xbbzg(N%a7d^k`f6%tb%obHi4=ZSe$)||8CaDB)VHj zeO?ff6=+P4iTnK{CM^D}3&TQpeZjcJ0iCMaK!%8~>xipHUa&O~jPxtd8a>N)AW5bQ zr@mRM_Mx)6o|CS1M7~AnD8!p|z#ePhX`o-*f$+mDnKT!ka=4nX2+p;;IF?R~*^m`U YPZ?x4)NU&p{PJfy*}FjMZGEr(4WGO6_y7O^ diff --git a/code/modules/unit_tests/screenshots/screenshot_antag_icons_vampirelatejoin.png b/code/modules/unit_tests/screenshots/screenshot_antag_icons_vampirelatejoin.png index e6b63d768e31f3f49ba46281b1e50248ed856c46..6c1894057665a42bb53bec90aadc92afdc13a253 100644 GIT binary patch delta 685 zcmV;e0#g0Q4Cw`s8Gi!+007lShYA1y0Ao;0R7C&)0N>x=%*@O^1^||UfJYn{at#2Q zg@c!Zfkhe?W-|ah6A)ku06`ZNJ{1!-5Dp3o3J(tt92^{$mX@WZr6D09BO@cBo}2ab z^u@xyARr*YzPsSw+_|~A$;QGTA0Hkb9`47nApigX0d!JMQwab-=GbNc003l>B{P2j zaxBfbI5Sc+(=$pSoZ^zil2jm5Nr{UyC9|j)$TZ~QOe;#vO@*+P6(B|5tj>JGPDNxRe(H4=i#RT?xj4>AI^lyTYuZ*U4Is#~1V0-HUbhfg7?G^? zt8>8sV;BLlgVs?P{nYvY0PLd<&^8LAWYGXO0^q?q>IFI;k218$;&l)Mj0Jz3Am`jG z)HKZ-1k+%INr$zi0`}hfyQCPjZTkViv|ZQLaf2WRm>b}O>+~?sA~^qq2+<*gHO2b0 zC;(h30m6SAubBWiXATg85nq0iD-+Ve0Am1(ZunOAeNUqTn`Mii?DgfWeXtEMCqQ|` z(vY5qVW3Gm96!lf?wMG@{C$4_%H_51HP~Yud|I3XYCp?8YD>lz+6K6&*ypK^4uGTy zi~!Cg9pW+oXz(`PJKwMKQVhbCg^m*_!~jpQQ8d6T0Q{SGUg0c?K@N&R4qZAlA<+zQ z5x`40IcIgE?}1WE>BsMZ>KQ_GySWU&>ieQ708~}rAJ0V{;;bqX!1Nh=)0qHY%M{E3 Tnrp=?00000NkvXXu0mjf_;ex! delta 1553 zcmY*ZdpHwn9G*@%Ix9j+a&pO%LL`RV=RuY-l;<$fHYOx@V~k3`2BeR0~^kInt?f&iA~}^ZovLf6x1Szu)`uB)frG%0MXq0Puzs1KzwY zXWu)4JJ;aRU^MmSrDGqIshxZ^-C5olwkLQ`Zf-N!%`hWH&&h>^lgJ1ULc!k|ZaHjeBh2eBl|iw})c)A~t{9eS^%nO6#TDqSiY?3Z(}d6mTsGt@6& zHh-i<>|*pbCY%Up*x<~aVn7#ET^Jk1F$)RIeVg+Ce`b}{=ViurR=@&hF1C3dyJ;p` z@3pGB@#OIPlIsBN6MqJpSy?fWsMy#Mc1=x9WzN~p-QC^N%eWYgA98H~U!V*QDW5JM zz@(G8i_4=nI`4By&+YbXLEFTk~mg7~K z;Vmz*qrv&`P`zWG;_;u9Nc!zlx^^B9`AtntbXxt6==lsqoMoHb*(# zfHUwSXK4My(8|k|tX?n1aDIoIJfhS?RdYpBdTuqI99@VBwU*M}d}Ee^3}OBzq8zen zK}Su8x=K~19&*P>|1l|27Ad~Z7_~M1zSjbe8<8H z6=GRxz``TuX^I?FL|2?EXQW}d!11l(Qjs1}zd*cQxdgba1nP^LP4i~-FbIx(BcA2Y zk#Me<3oc#O(h=`yt^NDo{-eX$5=7M1Q z(HQD|cYojvMeD#;*R94u)&;ZJUvlq6J>oCfryL~2oySJ!MLOelBiaqtu06S>;hkuA zCb2(xZ%$a)j!UFWjNQB1A~`bL1yq-S>zgs6bzJ+leV~SuzG)-#d3(4jnoM+&;i{$Y z(0dk80jWEA+Yb>AS@yEU*SJnxbsX3~WT_oJdAciKFd8l5h^{xDHjc*1E{!XE^>ABG ziJg~^sYxS|3QDqk@MMIG`YrIPu9GM??k=R~%`+l80#mXRPr$`OqjE5nZWHaIvP`ffh>par~BIvy-eFkHb-^`!?7k%BxMwRoUF<2 zaY*f38Os#qjmQ`r6a^cKb(JYTq&=pcZPNdkFAu4peZaK&8PacM`ilhH%HI0!wWej_5wgwqSZ*4l)-pXG>9G?>0}QTp>gkUs z%GIR?$WI)txsqW}MHse^_p9xbbzg(N%a7d^k`f6%tb%obHi4=ZSe$)||8CaDB)VHj zeO?ff6=+P4iTnK{CM^D}3&TQpeZjcJ0iCMaK!%8~>xipHUa&O~jPxtd8a>N)AW5bQ zr@mRM_Mx)6o|CS1M7~AnD8!p|z#ePhX`o-*f$+mDnKT!ka=4nX2+p;;IF?R~*^m`U YPZ?x4)NU&p{PJfy*}FjMZGEr(4WGO6_y7O^ diff --git a/code/modules/unit_tests/screenshots/screenshot_antag_icons_vampiricaccident.png b/code/modules/unit_tests/screenshots/screenshot_antag_icons_vampiricaccident.png index e6b63d768e31f3f49ba46281b1e50248ed856c46..6c1894057665a42bb53bec90aadc92afdc13a253 100644 GIT binary patch delta 685 zcmV;e0#g0Q4Cw`s8Gi!+007lShYA1y0Ao;0R7C&)0N>x=%*@O^1^||UfJYn{at#2Q zg@c!Zfkhe?W-|ah6A)ku06`ZNJ{1!-5Dp3o3J(tt92^{$mX@WZr6D09BO@cBo}2ab z^u@xyARr*YzPsSw+_|~A$;QGTA0Hkb9`47nApigX0d!JMQwab-=GbNc003l>B{P2j zaxBfbI5Sc+(=$pSoZ^zil2jm5Nr{UyC9|j)$TZ~QOe;#vO@*+P6(B|5tj>JGPDNxRe(H4=i#RT?xj4>AI^lyTYuZ*U4Is#~1V0-HUbhfg7?G^? zt8>8sV;BLlgVs?P{nYvY0PLd<&^8LAWYGXO0^q?q>IFI;k218$;&l)Mj0Jz3Am`jG z)HKZ-1k+%INr$zi0`}hfyQCPjZTkViv|ZQLaf2WRm>b}O>+~?sA~^qq2+<*gHO2b0 zC;(h30m6SAubBWiXATg85nq0iD-+Ve0Am1(ZunOAeNUqTn`Mii?DgfWeXtEMCqQ|` z(vY5qVW3Gm96!lf?wMG@{C$4_%H_51HP~Yud|I3XYCp?8YD>lz+6K6&*ypK^4uGTy zi~!Cg9pW+oXz(`PJKwMKQVhbCg^m*_!~jpQQ8d6T0Q{SGUg0c?K@N&R4qZAlA<+zQ z5x`40IcIgE?}1WE>BsMZ>KQ_GySWU&>ieQ708~}rAJ0V{;;bqX!1Nh=)0qHY%M{E3 Tnrp=?00000NkvXXu0mjf_;ex! delta 1553 zcmY*ZdpHwn9G*@%Ix9j+a&pO%LL`RV=RuY-l;<$fHYOx@V~k3`2BeR0~^kInt?f&iA~}^ZovLf6x1Szu)`uB)frG%0MXq0Puzs1KzwY zXWu)4JJ;aRU^MmSrDGqIshxZ^-C5olwkLQ`Zf-N!%`hWH&&h>^lgJ1ULc!k|ZaHjeBh2eBl|iw})c)A~t{9eS^%nO6#TDqSiY?3Z(}d6mTsGt@6& zHh-i<>|*pbCY%Up*x<~aVn7#ET^Jk1F$)RIeVg+Ce`b}{=ViurR=@&hF1C3dyJ;p` z@3pGB@#OIPlIsBN6MqJpSy?fWsMy#Mc1=x9WzN~p-QC^N%eWYgA98H~U!V*QDW5JM zz@(G8i_4=nI`4By&+YbXLEFTk~mg7~K z;Vmz*qrv&`P`zWG;_;u9Nc!zlx^^B9`AtntbXxt6==lsqoMoHb*(# zfHUwSXK4My(8|k|tX?n1aDIoIJfhS?RdYpBdTuqI99@VBwU*M}d}Ee^3}OBzq8zen zK}Su8x=K~19&*P>|1l|27Ad~Z7_~M1zSjbe8<8H z6=GRxz``TuX^I?FL|2?EXQW}d!11l(Qjs1}zd*cQxdgba1nP^LP4i~-FbIx(BcA2Y zk#Me<3oc#O(h=`yt^NDo{-eX$5=7M1Q z(HQD|cYojvMeD#;*R94u)&;ZJUvlq6J>oCfryL~2oySJ!MLOelBiaqtu06S>;hkuA zCb2(xZ%$a)j!UFWjNQB1A~`bL1yq-S>zgs6bzJ+leV~SuzG)-#d3(4jnoM+&;i{$Y z(0dk80jWEA+Yb>AS@yEU*SJnxbsX3~WT_oJdAciKFd8l5h^{xDHjc*1E{!XE^>ABG ziJg~^sYxS|3QDqk@MMIG`YrIPu9GM??k=R~%`+l80#mXRPr$`OqjE5nZWHaIvP`ffh>par~BIvy-eFkHb-^`!?7k%BxMwRoUF<2 zaY*f38Os#qjmQ`r6a^cKb(JYTq&=pcZPNdkFAu4peZaK&8PacM`ilhH%HI0!wWej_5wgwqSZ*4l)-pXG>9G?>0}QTp>gkUs z%GIR?$WI)txsqW}MHse^_p9xbbzg(N%a7d^k`f6%tb%obHi4=ZSe$)||8CaDB)VHj zeO?ff6=+P4iTnK{CM^D}3&TQpeZjcJ0iCMaK!%8~>xipHUa&O~jPxtd8a>N)AW5bQ zr@mRM_Mx)6o|CS1M7~AnD8!p|z#ePhX`o-*f$+mDnKT!ka=4nX2+p;;IF?R~*^m`U YPZ?x4)NU&p{PJfy*}FjMZGEr(4WGO6_y7O^ From b76c45cbb3fc407109e02484ea50a572478e6723 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Thu, 16 Apr 2026 21:43:43 +0300 Subject: [PATCH 112/149] =?UTF-8?q?=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/__DEFINES/~ff_defines/bloodsucker.dm | 4 ---- .../configuration/entries/game_options.dm | 8 ------- code/game/machinery/computer/crew.dm | 6 ----- .../structures/crates_lockers/closets.dm | 6 ++--- .../crates_lockers/closets/bodybag.dm | 4 ++-- .../antagonists/_common/antag_datum.dm | 21 ++---------------- code/modules/client/client_colour.dm | 6 ----- .../deathmatch/deathmatch_controller.dm | 5 ----- .../lavalandruin_code/elephantgraveyard.dm | 2 +- code/modules/mining/mine_items.dm | 2 +- code/modules/mob/dead/observer/observer.dm | 4 ---- .../mob/living/carbon/carbon_defense.dm | 1 - code/modules/mod/modules/module_pathfinder.dm | 2 +- .../xenobiology/crossbreeding/regenerative.dm | 2 +- code/modules/surgery/organs/organ_movement.dm | 1 + .../code/soulcatcher/soulcatcher_component.dm | 4 ---- tff_modular/modules/vampire/config.dm | 7 ++++++ tff_modular/modules/vampire/datum_vampire.dm | 4 ++-- .../modules/vampire/modular_changes.dm | 22 +++++++++++++++++++ tff_modular/modules/vampire/objects/coffin.dm | 2 +- .../modules/vampire/powers/potence/brawn.dm | 4 ++-- .../vampire/powers/thaumaturgy/bloodbolt.dm | 2 +- tgstation.dme | 1 + 23 files changed, 48 insertions(+), 72 deletions(-) create mode 100644 tff_modular/modules/vampire/modular_changes.dm diff --git a/code/__DEFINES/~ff_defines/bloodsucker.dm b/code/__DEFINES/~ff_defines/bloodsucker.dm index c5b2337ba30..3c4e7d5da21 100644 --- a/code/__DEFINES/~ff_defines/bloodsucker.dm +++ b/code/__DEFINES/~ff_defines/bloodsucker.dm @@ -1,7 +1,5 @@ /// From base of /mob/living/simple_animal/attack_hand() and /mob/living/basic/attack_hand() when petting (non-combat): (mob/living/pet) #define COMSIG_LIVING_PET_ANIMAL "living_pet_animal" -/// From base of carbon_defense.dm when hugging: (mob/living/carbon/hugged) -#define COMSIG_LIVING_HUG_CARBON "living_hug_carbon" /// From base of /datum/element/art when appraising art: (atom/art_piece) #define COMSIG_LIVING_APPRAISE_ART "living_appraise_art" /// Source trait while Feeding @@ -264,7 +262,5 @@ ///from base of atom/movable/newtonian_move(): (inertia_direction, start_delay) #define COMSIG_MOVABLE_NEWTONIAN_MOVE "movable_newtonian_move" #define COMPONENT_MOVABLE_NEWTONIAN_BLOCK (1<<0) -///from base of [/atom/proc/expose_reagents]: (/atom, /list, methods, volume_modifier, show_message) -#define COMSIG_REAGENTS_EXPOSE_ATOM "reagents_expose_atom" #define COMSIG_LIVING_TRACKER_REMOVED "tracker_removed" #define ui_team_finder "CENTER,CENTER" diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm index e5850fc41ed..9e7265cae05 100644 --- a/code/controllers/configuration/entries/game_options.dm +++ b/code/controllers/configuration/entries/game_options.dm @@ -519,11 +519,3 @@ /datum/config_entry/number/max_shuttle_size default = 250 -// TFF ADDITION START -/datum/config_entry/flag/allow_vampire_prince - default = TRUE - -/datum/config_entry/flag/allow_vampire_scourge - default = TRUE - -// TFF ADDITION END diff --git a/code/game/machinery/computer/crew.dm b/code/game/machinery/computer/crew.dm index ca8423b5792..fb10033b283 100644 --- a/code/game/machinery/computer/crew.dm +++ b/code/game/machinery/computer/crew.dm @@ -294,12 +294,6 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new) if (sensor_mode >= SENSOR_VITALS) entry["life_status"] = tracked_living_mob.stat else if (sensor_mode == SENSOR_LIVING) - // TFF ADDITION - if(tracked_living_mob.stat == UNCONSCIOUS && tracked_living_mob.health > tracked_living_mob.crit_threshold) - entry["life_status"] = CONSCIOUS - else - entry["life_status"] = tracked_living_mob.stat - // TFF ADDITION END // binary sensors should only report alive or dead entry["life_status"] = (tracked_living_mob.stat == DEAD) ? DEAD : CONSCIOUS diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 82616c7e01e..b1036c5fd2e 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -659,7 +659,7 @@ GLOBAL_LIST_EMPTY(roundstart_station_closets) /obj/structure/closet/atom_break(damage_flag) . = ..() if(!broken) - bust_open(FALSE) // TFF CHANGE - ORIGINAL: bust_open() + bust_open() /obj/structure/closet/on_craft_completion(list/components, datum/crafting_recipe/current_recipe, atom/crafter) var/obj/item/electronics/airlock/access_control = locate() in components @@ -1078,7 +1078,7 @@ GLOBAL_LIST_EMPTY(roundstart_station_closets) //we check after a while whether there is a point of resisting anymore and whether the user is capable of resisting user.visible_message(span_danger("[user] successfully broke out of [src]!"), span_notice("You successfully break out of [src]!")) - bust_open(FALSE) // TFF CHANGE - ORIGINAL: bust_open() + bust_open() else if(user.loc == src) //so we don't get the message if we resisted multiple times and succeeded. to_chat(user, span_warning("You fail to break out of [src]!")) @@ -1104,7 +1104,7 @@ GLOBAL_LIST_EMPTY(roundstart_station_closets) // If we reach here, nobody is resisting, so don't shake return FALSE -/obj/structure/closet/proc/bust_open(destructive = TRUE)// TFF CHANGE - ORIGINAL: proc/bust_open() +/obj/structure/closet/proc/bust_open() SIGNAL_HANDLER welded = FALSE //applies to all lockers unlock() //applies to critter crates and secure lockers only diff --git a/code/game/objects/structures/crates_lockers/closets/bodybag.dm b/code/game/objects/structures/crates_lockers/closets/bodybag.dm index 708a43c58f4..28c2b6030b3 100644 --- a/code/game/objects/structures/crates_lockers/closets/bodybag.dm +++ b/code/game/objects/structures/crates_lockers/closets/bodybag.dm @@ -369,13 +369,13 @@ span_notice("You successfully break out of [src]!")) if(istype(loc, /obj/machinery/disposal)) return ..() - bust_open(FALSE) // TFF CHANGE - ORIGINAL: bust_open() + bust_open() else if(user.loc == src) //so we don't get the message if we resisted multiple times and succeeded. to_chat(user, span_warning("You fail to break out of [src]!")) -/obj/structure/closet/body_bag/environmental/prisoner/bust_open(destructive = FALSE) // TFF CHANGE - ORIGINAL: bust_open() +/obj/structure/closet/body_bag/environmental/prisoner/bust_open() sinched = FALSE // We don't break the bag, because the buckles were backed out as opposed to fully broken. open() diff --git a/code/modules/antagonists/_common/antag_datum.dm b/code/modules/antagonists/_common/antag_datum.dm index 9162da6484d..2695b4973b6 100644 --- a/code/modules/antagonists/_common/antag_datum.dm +++ b/code/modules/antagonists/_common/antag_datum.dm @@ -240,17 +240,6 @@ GLOBAL_LIST_EMPTY(antagonists) /datum/antagonist/proc/create_team(datum/team/team) return -// TFF ADDITION START -/datum/antagonist/proc/make_info_button() as /datum/action/antag_info - if(!ui_name) - return - var/datum/action/antag_info/info_button = new(src) - info_button.Grant(owner.current) - info_button_ref = WEAKREF(info_button) - return info_button - -// TFF ADDITION END - ///Called by the add_antag_datum() mind proc after the instanced datum is added to the mind's antag_datums list. /datum/antagonist/proc/on_gain() SHOULD_CALL_PARENT(TRUE) @@ -258,14 +247,11 @@ GLOBAL_LIST_EMPTY(antagonists) if(!skip_custom_objectives_addition) add_custom_objectives() // FLUFFY FRONTIER CHANGE END - // TFF REMOVAL: var/datum/action/antag_info/info_button + var/datum/action/antag_info/info_button if(!owner) CRASH("[src] ran on_gain() without a mind") if(!owner.current) CRASH("[src] ran on_gain() on a mind without a mob") - - // TFF EDIT START - ORIGINAL: - /* if(ui_name)//in the future, this should entirely replace greet. info_button = new(src) if(antag_flags & ANTAG_OBSERVER_VISIBLE_PANEL) @@ -273,12 +259,9 @@ GLOBAL_LIST_EMPTY(antagonists) info_button.allow_observer_click = TRUE info_button.Grant(owner.current) info_button_ref = WEAKREF(info_button) - */ - var/datum/action/antag_info/info_button = make_info_button() - // TFF EDIT END if(!silent) greet() - if(info_button) // TFF EDIT - ORIGINAL: if(ui_name) + if(ui_name) to_chat(owner.current, span_boldnotice("For more info, read the panel. \ You can always come back to it using the button in the top left.")) info_button.Trigger() diff --git a/code/modules/client/client_colour.dm b/code/modules/client/client_colour.dm index e8e2b1f899a..bb4ad106f73 100644 --- a/code/modules/client/client_colour.dm +++ b/code/modules/client/client_colour.dm @@ -205,12 +205,6 @@ fade_in = 2 SECONDS fade_out = 2 SECONDS -// TFF ADDITION START -/datum/client_colour/glass_colour/pink - color = "#ffcfe9" - -// TFF ADDITION END - /datum/client_colour/monochrome/New(mob/owner) . = ..() if (owner) diff --git a/code/modules/deathmatch/deathmatch_controller.dm b/code/modules/deathmatch/deathmatch_controller.dm index e6081f43da0..3ae10ad51d2 100644 --- a/code/modules/deathmatch/deathmatch_controller.dm +++ b/code/modules/deathmatch/deathmatch_controller.dm @@ -40,11 +40,6 @@ return GLOB.observer_state /datum/deathmatch_controller/ui_interact(mob/user, datum/tgui/ui) - // TFF ADDITION START - if(HAS_TRAIT(user, TRAIT_NO_OBSERVE)) - to_chat(user, span_warning("You cannot play or host deathmatch in your current form!")) - return - // TFF ADDITION END ui = SStgui.try_update_ui(user, src, null) if(!ui) ui = new(user, src, "DeathmatchPanel") diff --git a/code/modules/mapfluff/ruins/lavalandruin_code/elephantgraveyard.dm b/code/modules/mapfluff/ruins/lavalandruin_code/elephantgraveyard.dm index 9462454ed4a..0674ff97cb8 100644 --- a/code/modules/mapfluff/ruins/lavalandruin_code/elephantgraveyard.dm +++ b/code/modules/mapfluff/ruins/lavalandruin_code/elephantgraveyard.dm @@ -299,7 +299,7 @@ span_danger("[user] emerges from [src], scattering dirt everywhere!"), span_notice("You triumphantly surface out of [src], scattering dirt all around the grave!"), ) - bust_open(FALSE) // TFF CHANGE - ORIGINAL: bust_open() + bust_open() else if(user.loc == src) to_chat(user, span_warning("You fail to dig yourself out of [src]!")) diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index 95a987ff67d..59b6afcc51a 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -508,7 +508,7 @@ to_yeet += buckled_mobs unbuckle_all_mobs() - bust_open(FALSE) // TFF CHANGE - ORIGINAL: bust_open() + bust_open() if(!opened) return diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 02336e63c69..a7f0edccbcf 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -639,10 +639,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp /mob/dead/observer/verb/restore_ghost_appearance() set name = "Restore Ghost Character" - // TFF ADDITION START - if(HAS_TRAIT(src, TRAIT_NO_OBSERVE)) - return - // TFF ADDITION END set_ghost_appearance() if(client?.prefs) var/real_name = client.prefs.read_preference(/datum/preference/name/real_name) diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index f21a607fbc9..e2d26f732df 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -463,7 +463,6 @@ SEND_SIGNAL(src, COMSIG_CARBON_HELP_ACT, helper) SEND_SIGNAL(helper, COMSIG_CARBON_HELPED, src) - SEND_SIGNAL(helper, COMSIG_LIVING_HUG_CARBON, src) adjust_status_effects_on_shake_up() set_resting(FALSE) diff --git a/code/modules/mod/modules/module_pathfinder.dm b/code/modules/mod/modules/module_pathfinder.dm index 263950e38d8..657aa42b084 100644 --- a/code/modules/mod/modules/module_pathfinder.dm +++ b/code/modules/mod/modules/module_pathfinder.dm @@ -152,7 +152,7 @@ if (!closet.opened) if (!closet.open()) playsound(closet, 'sound/effects/bang.ogg', vol = 50, vary = TRUE) - closet.bust_open(FALSE) // TFF CHANGE - ORIGINAL: bust_open() + closet.bust_open() mod.add_overlay(jet_icon) diff --git a/code/modules/research/xenobiology/crossbreeding/regenerative.dm b/code/modules/research/xenobiology/crossbreeding/regenerative.dm index 9748528a386..4cc1784b8d0 100644 --- a/code/modules/research/xenobiology/crossbreeding/regenerative.dm +++ b/code/modules/research/xenobiology/crossbreeding/regenerative.dm @@ -76,7 +76,7 @@ Regenerative extracts: C.name = "slimy closet" C.desc = "Looking closer, it seems to be made of a sort of solid, opaque, metal-like goo." if(target.mob_size > C.max_mob_size) //Prevents capturing megafauna or other large mobs in the closets - C.bust_open(FALSE) // TFF CHANGE - ORIGINAL: bust_open() + C.bust_open() C.visible_message(span_warning("[target] is too big, and immediately breaks \the [C.name] open!")) else //This can't be allowed to actually happen to the too-big mobs or it breaks some actions target.forceMove(C) diff --git a/code/modules/surgery/organs/organ_movement.dm b/code/modules/surgery/organs/organ_movement.dm index dfe1b65b916..fc06b26c0ca 100644 --- a/code/modules/surgery/organs/organ_movement.dm +++ b/code/modules/surgery/organs/organ_movement.dm @@ -272,6 +272,7 @@ item_flags &= ~ABSTRACT REMOVE_TRAIT(src, TRAIT_NODROP, ORGAN_INSIDE_BODY_TRAIT) + limb.owner?.synchronize_bodytypes() limb.owner?.synchronize_bodyshapes() diff --git a/modular_nova/modules/modular_implants/code/soulcatcher/soulcatcher_component.dm b/modular_nova/modules/modular_implants/code/soulcatcher/soulcatcher_component.dm index 978961bc675..38f8306b1a9 100644 --- a/modular_nova/modules/modular_implants/code/soulcatcher/soulcatcher_component.dm +++ b/modular_nova/modules/modular_implants/code/soulcatcher/soulcatcher_component.dm @@ -428,10 +428,6 @@ GLOBAL_LIST_EMPTY(soulcatchers) /mob/dead/observer/verb/join_soulcatcher() set name = "Enter Soulcatcher" - // TFF ADDIITON START - if(HAS_TRAIT(src, TRAIT_NO_OBSERVE)) - return FALSE - // TFF ADDITION END var/list/joinable_soulcatchers = list() for(var/datum/component/soulcatcher/soulcatcher in GLOB.soulcatchers) if(!soulcatcher.ghost_joinable || !isobj(soulcatcher.parent) || !soulcatcher.check_for_vacancy()) diff --git a/tff_modular/modules/vampire/config.dm b/tff_modular/modules/vampire/config.dm index 685c9f6cf57..75bb7659227 100644 --- a/tff_modular/modules/vampire/config.dm +++ b/tff_modular/modules/vampire/config.dm @@ -3,3 +3,10 @@ /datum/config_entry/string/default_view_square default = "15x15" + +/datum/config_entry/flag/allow_vampire_prince + default = TRUE + +/datum/config_entry/flag/allow_vampire_scourge + default = TRUE + diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index a99f8ed4ea1..dd41bc95ce4 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -201,7 +201,7 @@ RegisterSignal(current_mob, COMSIG_MOB_UPDATE_SIGHT, PROC_REF(on_update_sight)) RegisterSignal(current_mob, COMSIG_LIVING_PET_ANIMAL, PROC_REF(on_pet_animal)) - RegisterSignal(current_mob, COMSIG_LIVING_HUG_CARBON, PROC_REF(on_hug_carbon)) + RegisterSignal(current_mob, COMSIG_CARBON_HELPED, PROC_REF(on_hug_carbon)) RegisterSignal(current_mob, COMSIG_LIVING_APPRAISE_ART, PROC_REF(on_appraise_art)) handle_clown_mutation(current_mob, "Your clownish nature has been subdued by your thirst for blood.") @@ -251,7 +251,7 @@ COMSIG_HUMAN_ON_HANDLE_BLOOD, COMSIG_MOB_UPDATE_SIGHT, COMSIG_LIVING_PET_ANIMAL, - COMSIG_LIVING_HUG_CARBON, + COMSIG_CARBON_HELPED, COMSIG_LIVING_APPRAISE_ART, )) current_mob.update_sight() diff --git a/tff_modular/modules/vampire/modular_changes.dm b/tff_modular/modules/vampire/modular_changes.dm new file mode 100644 index 00000000000..f46d398ce51 --- /dev/null +++ b/tff_modular/modules/vampire/modular_changes.dm @@ -0,0 +1,22 @@ +/datum/deathmatch_controller/ui_interact(mob/user, datum/tgui/ui) + if(HAS_TRAIT(user, TRAIT_NO_OBSERVE)) + to_chat(user, span_warning("You cannot play or host deathmatch in your current form!")) + return + ..() + +/mob/dead/observer/restore_ghost_appearance() + if(HAS_TRAIT(src, TRAIT_NO_OBSERVE)) + return + ..() + +/mob/dead/observer/join_soulcatcher() + if(HAS_TRAIT(src, TRAIT_NO_OBSERVE)) + return FALSE + ..() + +/datum/client_colour/glass_colour/pink + color = "#ffcfe9" + +/datum/element/art/apply_moodlet(atom/source, mob/living/user, impress) + . = ..() + SEND_SIGNAL(user, COMSIG_LIVING_APPRAISE_ART, source) diff --git a/tff_modular/modules/vampire/objects/coffin.dm b/tff_modular/modules/vampire/objects/coffin.dm index e12dc433383..754346fb6f2 100644 --- a/tff_modular/modules/vampire/objects/coffin.dm +++ b/tff_modular/modules/vampire/objects/coffin.dm @@ -85,7 +85,7 @@ ) if(!tool.use_tool(src, user, pry_lid_timer)) return FALSE - bust_open(FALSE) // TFF CHANGE - ORIGINAL: bust_open() + bust_open() user.visible_message( span_notice("[user] snaps the door of [src] wide open."), span_notice("The door of [src] snaps open."), diff --git a/tff_modular/modules/vampire/powers/potence/brawn.dm b/tff_modular/modules/vampire/powers/potence/brawn.dm index ed96bdd71b8..434fb1b00a3 100644 --- a/tff_modular/modules/vampire/powers/potence/brawn.dm +++ b/tff_modular/modules/vampire/powers/potence/brawn.dm @@ -55,7 +55,7 @@ // Lockers if(istype(human_owner.loc, /obj/structure/closet)) var/obj/structure/closet/closet = human_owner.loc - addtimer(CALLBACK(closet, TYPE_PROC_REF(/obj/structure/closet, bust_open), FALSE), 0.1 SECONDS) + addtimer(CALLBACK(closet, TYPE_PROC_REF(/obj/structure/closet, bust_open)), 0.1 SECONDS) closet.visible_message( span_warning("[closet] tears apart as [human_owner] bashes it open from within!"), span_warning("[closet] tears apart as you bash it open from within!") @@ -167,7 +167,7 @@ return FALSE target_closet.visible_message(span_danger("[target_closet] breaks open as [carbon_owner] bashes it!")) - INVOKE_ASYNC(target_closet, TYPE_PROC_REF(/obj/structure/closet, bust_open), FALSE) + INVOKE_ASYNC(target_closet, TYPE_PROC_REF(/obj/structure/closet, bust_open)) playsound(get_turf(carbon_owner), 'sound/effects/grillehit.ogg', 80, TRUE, -1) // check_witnesses() // Airlocks diff --git a/tff_modular/modules/vampire/powers/thaumaturgy/bloodbolt.dm b/tff_modular/modules/vampire/powers/thaumaturgy/bloodbolt.dm index 01e0a190bde..40b8be90c39 100644 --- a/tff_modular/modules/vampire/powers/thaumaturgy/bloodbolt.dm +++ b/tff_modular/modules/vampire/powers/thaumaturgy/bloodbolt.dm @@ -51,7 +51,7 @@ /obj/projectile/magic/arcane_barrage/vampire/on_hit(atom/target, blocked = 0, pierce_hit) if(istype(target, /obj/structure/closet)) var/obj/structure/closet/hit_closet = target - hit_closet.bust_open(destructive = FALSE) + hit_closet.bust_open() qdel(src) return BULLET_ACT_HIT diff --git a/tgstation.dme b/tgstation.dme index f5586d69e28..a27967949e6 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -9875,6 +9875,7 @@ #include "tff_modular\modules\vampire\leveling_vampire.dm" #include "tff_modular\modules\vampire\life_vampire.dm" #include "tff_modular\modules\vampire\misc_procs_vampire.dm" +#include "tff_modular\modules\vampire\modular_changes.dm" #include "tff_modular\modules\vampire\monitor.dm" #include "tff_modular\modules\vampire\moodlets_vampire.dm" #include "tff_modular\modules\vampire\names_vampire.dm" From 8e8dd97d7ad58523b205e3033210b3865dd44e32 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Thu, 16 Apr 2026 21:48:37 +0300 Subject: [PATCH 113/149] Update _atom.dm --- code/game/atom/_atom.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/atom/_atom.dm b/code/game/atom/_atom.dm index 66219100228..640cc611ba4 100644 --- a/code/game/atom/_atom.dm +++ b/code/game/atom/_atom.dm @@ -435,7 +435,7 @@ . = SEND_SIGNAL(src, COMSIG_ATOM_EXPOSE_REAGENTS, reagents, source, methods, show_message) if(. & COMPONENT_NO_EXPOSE_REAGENTS) return - SEND_SIGNAL(source, COMSIG_REAGENTS_EXPOSE_ATOM, src, reagents, methods, show_message) // TFF ADDITION + SEND_SIGNAL(source, COMSIG_REAGENT_EXPOSE_ATOM, src, reagents, methods, show_message) // TFF ADDITION for(var/datum/reagent/current_reagent as anything in reagents) . |= current_reagent.expose_atom(src, reagents[current_reagent], methods) SEND_SIGNAL(src, COMSIG_ATOM_AFTER_EXPOSE_REAGENTS, reagents, source, methods, show_message) // TFF ADDITION From 5f5bbb7406fd57cf3e18bedd69907d27009098da Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Thu, 16 Apr 2026 21:49:33 +0300 Subject: [PATCH 114/149] Update _atom.dm --- code/game/atom/_atom.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/game/atom/_atom.dm b/code/game/atom/_atom.dm index 640cc611ba4..36a4587eb4a 100644 --- a/code/game/atom/_atom.dm +++ b/code/game/atom/_atom.dm @@ -435,7 +435,6 @@ . = SEND_SIGNAL(src, COMSIG_ATOM_EXPOSE_REAGENTS, reagents, source, methods, show_message) if(. & COMPONENT_NO_EXPOSE_REAGENTS) return - SEND_SIGNAL(source, COMSIG_REAGENT_EXPOSE_ATOM, src, reagents, methods, show_message) // TFF ADDITION for(var/datum/reagent/current_reagent as anything in reagents) . |= current_reagent.expose_atom(src, reagents[current_reagent], methods) SEND_SIGNAL(src, COMSIG_ATOM_AFTER_EXPOSE_REAGENTS, reagents, source, methods, show_message) // TFF ADDITION From f64c6b1c8af2083980193d8327f376d5e0de1783 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Thu, 16 Apr 2026 21:57:11 +0300 Subject: [PATCH 115/149] Update closets.dm --- code/game/objects/structures/crates_lockers/closets.dm | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index b1036c5fd2e..e8fa4a030ff 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -21,7 +21,6 @@ GLOBAL_LIST_EMPTY(roundstart_station_closets) contents_thermal_insulation = 0 pass_flags_self = PASSSTRUCTURE | LETPASSCLICKS custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 2) - var/ash_chance = 10 // TFF ADDITION /// The overlay for the closet's door var/obj/effect/overlay/closet_door/door_obj /// Whether or not this door is being animated @@ -1109,15 +1108,6 @@ GLOBAL_LIST_EMPTY(roundstart_station_closets) welded = FALSE //applies to all lockers unlock() //applies to critter crates and secure lockers only broken = TRUE //applies to secure lockers only - if(destructive) - for(var/obj/item/broken in src.contents) - if(!prob(ash_chance)) - continue - new /obj/effect/decal/cleanable/ash(loc) - - if(istype(broken, /obj/item/ammo_box)) - explosion(src, 0, 0, 2, 0, 2) - qdel(broken) open(force = TRUE, special_effects = FALSE) /obj/structure/closet/attack_hand_secondary(mob/user, modifiers) From 6bc4c0c4933facf326e8e9a2b9204b76c90ac0b5 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Thu, 16 Apr 2026 22:06:05 +0300 Subject: [PATCH 116/149] Update datum_vampire.dm --- tff_modular/modules/vampire/datum_vampire.dm | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index dd41bc95ce4..1e0af21b52f 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -617,14 +617,6 @@ background_icon = 'tff_modular/modules/vampire/icons/actions_vampire.dmi' background_icon_state = "vamp_power_off" -/datum/antagonist/vampire/make_info_button() - if(!ui_name) - return - var/datum/action/antag_info/vampire/info_button = new(src) - info_button.Grant(owner.current) - info_button_ref = WEAKREF(info_button) - return info_button - /datum/antagonist/vampire/add_team_hud(mob/target, antag_to_check, passed_hud_keys) if(broke_masquerade) antag_hud_name = "masquerade_broken" From 580fdcaf4dba9729e4748b60097be90e24a9dfc3 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Fri, 17 Apr 2026 20:47:09 +0300 Subject: [PATCH 117/149] =?UTF-8?q?=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=BC=D0=BE=D0=B4=D1=83=D0=BB?= =?UTF-8?q?=D1=8C=D0=BD=D1=8B=D1=85=20=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/datums/elements/art.dm | 2 -- tff_modular/modules/vampire/datum_vampire.dm | 6 +++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/code/datums/elements/art.dm b/code/datums/elements/art.dm index a58f7e38bc8..93e156081d9 100644 --- a/code/datums/elements/art.dm +++ b/code/datums/elements/art.dm @@ -35,8 +35,6 @@ user.visible_message(span_notice("[user] stops and looks intently at [source]."), \ span_notice("You appraise [source]... [msg]")) - SEND_SIGNAL(user, COMSIG_LIVING_APPRAISE_ART, source) // TFF ADDITION - /datum/element/art/proc/on_examine(atom/source, mob/user, list/examine_texts) SIGNAL_HANDLER if(!isliving(user)) diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index 1e0af21b52f..416cbbce21f 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -194,7 +194,7 @@ RegisterSignals(current_mob, list(COMSIG_MOB_LOGIN, COMSIG_MOVABLE_Z_CHANGED), PROC_REF(on_login)) RegisterSignal(current_mob, COMSIG_LIVING_LIFE, PROC_REF(life_tick)) RegisterSignal(current_mob, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) - RegisterSignal(current_mob, COMSIG_ATOM_AFTER_EXPOSE_REAGENTS, PROC_REF(after_expose_reagents)) + RegisterSignal(current_mob, COMSIG_ATOM_EXPOSE_REAGENTS, PROC_REF(after_expose_reagents)) RegisterSignal(current_mob, COMSIG_LIVING_DEATH, PROC_REF(on_death)) // RegisterSignal(current_mob, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved)) RegisterSignal(current_mob, COMSIG_HUMAN_ON_HANDLE_BLOOD, PROC_REF(handle_blood)) @@ -245,7 +245,7 @@ COMSIG_MOVABLE_Z_CHANGED, COMSIG_LIVING_LIFE, COMSIG_ATOM_EXAMINE, - COMSIG_ATOM_AFTER_EXPOSE_REAGENTS, + COMSIG_ATOM_EXPOSE_REAGENTS, COMSIG_LIVING_DEATH, COMSIG_MOVABLE_MOVED, COMSIG_HUMAN_ON_HANDLE_BLOOD, @@ -809,7 +809,7 @@ affected_limbs[deleted_limb.body_zone] = null UnregisterSignal(deleted_limb, COMSIG_QDELETING) -/datum/antagonist/vampire/proc/after_expose_reagents(mob/source_mob, list/reagents, datum/reagents/source, methods = TOUCH, volume_modifier = 1, show_message = TRUE) +/datum/antagonist/vampire/proc/after_expose_reagents(atom/target, list/reagents, datum/reagents/source, methods) SIGNAL_HANDLER var/datum/reagent/blood/blood_reagent = locate() in reagents if(!blood_reagent) From adde54b76766b336e692867eb98f33ca1fa7813d Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sat, 18 Apr 2026 15:39:29 +0300 Subject: [PATCH 118/149] =?UTF-8?q?=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=B2=D1=81=D1=8F=D0=BA=D0=B8?= =?UTF-8?q?=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/__DEFINES/~ff_defines/bloodsucker.dm | 9 +- code/_onclick/hud/hud.dm | 15 - .../configuration/entries/game_options.dm | 1 - code/game/atom/_atom.dm | 1 + strings/fluffy/malkavian_revelations.json | 67 +- tff_modular/modules/vampire/monitor.dm | 623 ------------------ .../modules/vampire/movable_physics.dm | 354 ++++++++++ .../vampire/objects/_vampire_object.dm | 2 +- .../modules/vampire/objects/candelabrum.dm | 2 +- .../modules/vampire/objects/kindred.dm | 4 +- tff_modular/modules/vampire/powers/feed.dm | 2 +- .../modules/vampire/powers/potence/lunge.dm | 2 +- .../modules/vampire/vassals/datum_vassal.dm | 2 +- tgstation.dme | 3 +- 14 files changed, 401 insertions(+), 686 deletions(-) delete mode 100644 tff_modular/modules/vampire/monitor.dm create mode 100644 tff_modular/modules/vampire/movable_physics.dm diff --git a/code/__DEFINES/~ff_defines/bloodsucker.dm b/code/__DEFINES/~ff_defines/bloodsucker.dm index 3c4e7d5da21..d735c6edcd4 100644 --- a/code/__DEFINES/~ff_defines/bloodsucker.dm +++ b/code/__DEFINES/~ff_defines/bloodsucker.dm @@ -225,15 +225,11 @@ /// Trait that says you're shaded by something (ie partially in the dark) #define TRAIT_SHADED "shaded" -#define IS_VAMPIRE_HUNTER(mob) (IS_CURATOR(mob)) - #define LANGUAGE_VAMPIRE "vampire" #define LANGUAGE_VASSAL "vassal" -/// /turf/proc/is_softly_lit() but inlined -#define IS_SOFTLY_LIT(turf) (turf.lighting_object && !(turf.luminosity || turf.dynamic_lumcount)) /// Similar to turf.get_lumcount(), but it checks for soft lighting first, and just assumes the lumcount is 0 if it is. -#define GET_SIMPLE_LUMCOUNT(turf) (IS_SOFTLY_LIT(turf) ? 0 : turf.get_lumcount()) +#define GET_SIMPLE_LUMCOUNT(turf) (turf.is_softly_lit() ? 0 : turf.get_lumcount()) //Incapacitated status effect flags /// If the incapacitated status effect will ignore a mob in restraints (handcuffs) @@ -259,8 +255,5 @@ #define MPHYSICS_MOVING (1<<1) /// The component has been "paused" and will not process #define MPHYSICS_PAUSED (1<<2) -///from base of atom/movable/newtonian_move(): (inertia_direction, start_delay) -#define COMSIG_MOVABLE_NEWTONIAN_MOVE "movable_newtonian_move" - #define COMPONENT_MOVABLE_NEWTONIAN_BLOCK (1<<0) #define COMSIG_LIVING_TRACKER_REMOVED "tracker_removed" #define ui_team_finder "CENTER,CENTER" diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index cf74f6a0926..56bbd94f741 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -127,8 +127,6 @@ GLOBAL_LIST_INIT(available_erp_ui_styles, list( /// and avoid needing to make changes to all idk 300 consumers if we want to change the appearance var/list/asset_refs_for_reuse = list() - var/list/team_finder_arrows = list() // TFF ADDITION - /datum/hud/New(mob/owner) mymob = owner @@ -248,7 +246,6 @@ GLOBAL_LIST_INIT(available_erp_ui_styles, list( QDEL_NULL(palette_actions) QDEL_NULL(listed_actions) QDEL_LIST(floating_actions) - QDEL_LIST(team_finder_arrows) // TFF ADDITION QDEL_LIST(static_inventory) // all already deleted by static inventory clear @@ -372,10 +369,6 @@ GLOBAL_LIST_INIT(available_erp_ui_styles, list( screenmob.client.screen += hotkeybuttons if(infodisplay.len) screenmob.client.screen += infodisplay - // TFF ADDITION START - if(team_finder_arrows.len) - screenmob.client.screen += team_finder_arrows - // TFF ADDITION END if(always_visible_inventory.len) screenmob.client.screen += always_visible_inventory if(open_containers.len && screenmob == mymob) // Don't show open inventories to ghosts @@ -387,20 +380,12 @@ GLOBAL_LIST_INIT(available_erp_ui_styles, list( hud_shown = FALSE //Governs behavior of other procs if(static_inventory.len) screenmob.client.screen -= static_inventory - // TFF ADDITION START - if(team_finder_arrows.len) - screenmob.client.screen += team_finder_arrows - // TFF ADDITION END if(toggleable_inventory.len) screenmob.client.screen -= toggleable_inventory if(hotkeybuttons.len) screenmob.client.screen -= hotkeybuttons if(infodisplay.len) screenmob.client.screen += infodisplay - // TFF ADDITION START - if(team_finder_arrows.len) - screenmob.client.screen -= team_finder_arrows - // TFF ADDITION END if(always_visible_inventory.len) screenmob.client.screen += always_visible_inventory diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm index 9e7265cae05..2d024691738 100644 --- a/code/controllers/configuration/entries/game_options.dm +++ b/code/controllers/configuration/entries/game_options.dm @@ -518,4 +518,3 @@ /datum/config_entry/number/max_shuttle_size default = 250 - diff --git a/code/game/atom/_atom.dm b/code/game/atom/_atom.dm index 36a4587eb4a..2c51beb782c 100644 --- a/code/game/atom/_atom.dm +++ b/code/game/atom/_atom.dm @@ -435,6 +435,7 @@ . = SEND_SIGNAL(src, COMSIG_ATOM_EXPOSE_REAGENTS, reagents, source, methods, show_message) if(. & COMPONENT_NO_EXPOSE_REAGENTS) return + for(var/datum/reagent/current_reagent as anything in reagents) . |= current_reagent.expose_atom(src, reagents[current_reagent], methods) SEND_SIGNAL(src, COMSIG_ATOM_AFTER_EXPOSE_REAGENTS, reagents, source, methods, show_message) // TFF ADDITION diff --git a/strings/fluffy/malkavian_revelations.json b/strings/fluffy/malkavian_revelations.json index e9af750247d..6ce3f2634f9 100644 --- a/strings/fluffy/malkavian_revelations.json +++ b/strings/fluffy/malkavian_revelations.json @@ -3,16 +3,16 @@ "#Существует целое пространственное измерение, видимое исключительно в крови, но мы никогда его не увидим.", "#Взрывы происходят так часто, что я боюсь под них попасть.", "#Капитан однажды падёт, все временно.", - "#Здесь всегда есть чему-то просветиться, у кого-то научиться, что-то прочитать.", + "Здесь всегда есть чему-то просветиться, у кого-то научиться, что-то прочитать.", "#Почему мы были брошены в этой вселенной? Когда нас заберут?", - "#Когда сны перестанут преследовать меня? Почему из всех людей они выбрали меня?", + "Когда сны перестанут преследовать меня? Почему из всех людей они выбрали меня?", "#Тот кто слышит голоса в голове зовется дураком, но делает ли это его безумным?", "#Ах милый... Возможно в своей жизни я зашел слишком далеко. Интересно что будет дальше.", "#Иногда мне кажется, я последний пророк... Возможно так и есть.", "#Интересно что привело меня к этому пути. Моя кровь? Моя ненависть к тем, кто окружает меня?", - "#Мне стоит понять что приводит меня к моим действиям, или я не должен.", - "#Если я сфокусируюсь на своих целях, а не на моих желаниях, буду ли я счастлив?", - "#Возможно... В другой вселенной, я... Я буду частью семьи, что любит меня.", + "Мне стоит понять что приводит меня к моим действиям, или я не должен.", + "Если я сфокусируюсь на своих целях, а не на моих желаниях, буду ли я счастлив?", + "Возможно... В другой вселенной, я... Я буду частью семьи, что любит меня.", "#Страшно представить что люди думают обо мне, скорее всего что-то ужасное.", "#Я был так близок к какой-то идее, но я потерял ее нить...", "#Что произойдет когда вся органика умрет? Вся неорганика просто останется?", @@ -40,59 +40,66 @@ "#Этот 357-й калибр заставил меня двигаться, как инвазивный вид.", "#Я плох в прикосновении Мидаса.", "#Я убью тебя!", - "#Подожди, дай мне сделать пару глотков.", + "Подожди, дай мне сделать пару глотков.", "#Маскарад должен соблюдаться также, как хранят ядерный диск, это то что охраняет нас от того, кто снизу...", - "#150, 149, 148... 147, 146, 145, 144... Какое мое число, напомни?", - "#Неважно что мы будем делать, мы все равно будем ощущать боль.", + "150, 149, 148... 147, 146, 145, 144... Какое мое число, напомни?", + "Неважно что мы будем делать, мы все равно будем ощущать боль.", "Куда я пошел в своей жизни не туда, чтобы оказаться здесь...", - "#Тот, кто знает все уловки монстра, обязательно придет. Только время покажет, когда.", - "#Что мы делаем на этой станции? Разве мы не знаем что это все плохо закончится?", + "Тот, кто знает все уловки монстра, обязательно придет. Только время покажет, когда.", + "Что мы делаем на этой станции? Разве мы не знаем что это все плохо закончится?", "#Мне интересно что сказали бы древние греческие философы, оказавшись здесь.", "#Если бы только все видели мир так, как вижу его я.", - "#Что сделало человечество, чтобы заслужить мое существование?", - "#Если бог существует, как он позволил мне появиться?", + "Что сделало человечество, чтобы заслужить мое существование?", + "Если бог существует, как он позволил мне появиться?", "#...Я, кажется, потерял нить чего-то, не могу понять чего...", "#Личность которую все пытаются заткнуть, это та личность, которую все будут желать вернуть.", "Это твоя вина.", + "Я не могу мыслить...", "#Сегодня ты нажил себе могущественного врага, чувак.", "#Тебя любят личинки. Поверь мне.", - "#Мое величайшее оружие - знание. И глаза-лазеры.", + "Мое величайшее оружие - знание. И глаза-лазеры.", "#Я раскрашиваю мир красками своего безумия.", "#Смейтесь, если хотите. Считайте, что вы намного умнее, чем несчастный сломленный сумасшедший. Неважно. Но подумайте над этим: вы — мёртвое существо, как и я. Вы умерли и возродились… вот этим. Что делает вас и меня разными? Очень просто — я помню, что видел, когда был полностью и воистину мёртв. Вы бы тоже сошли с ума.", "Я пытался превратить воду в вино. Какого хрена здесь кровь? А, ну да ладно - не пропадать же добру.", - "Потанцуем?", "Должен ли я делать то, что мне назначено? Или я должен пойти в шестую дорму? Другой вопрос заключается в том, почему такое существо как я имеет столь высокое либидо.", "#Цимисхи - милые ребята, они так завидуют Носферату и подражают им. Что ж, если они думают, что безобразие приводит к просветлению, я с радостью помогу им. У них слишком много конечностей, на мой вкус...", - "#Цимисхи... Пингвины. Они решили, что любят воду, и обменяли свои крылья на ласты. И они были так близко...", - "#Ты живешь на островке невезения... Смерть предъявит на тебя право...", - "#Не обращайте внимания на этого человека в углу. Он просто выдуманный друг, которого я перестал выдумывать, но он обиделся и остался.", - "#Не считай безумие проклятием, смертный. Для некоторых это величайшее из благ. Горькая милость, возможно, но все же милость.", + "Ты живешь на островке невезения... Смерть предъявит на тебя право...", + "Не обращайте внимания на этого человека в углу. Он просто выдуманный друг, которого я перестал выдумывать, но он обиделся и остался.", + "Не считай безумие проклятием, смертный. Для некоторых это величайшее из благ. Горькая милость, возможно, но все же милость.", "#Я видел большую лошадь. Она создала меня, а потом поскакала искать прекрасные поля, жуя морковку.", "#С концом света придут четыре всадника. Четыре коня в плащах на своих верных людях-скакунах.", - "#А потом я придумаю себе хобби. Кто знает, может, воскрешение мертвых?", + "А потом я придумаю себе хобби. Кто знает, может, воскрешение мертвых?", "#Добро пожаловать в безумный мир, дом всех самых странных вещей...", - "#Вампиры-Социалисты хотят контролировать твой разум!", + "Вампиры-Социалисты хотят контролировать твой разум и улучшать условия жизни, чтобы твоя кровь стала вкуснее!", "#Я запру тебя в мире, где ты будешь любить быть живым.", "#Кто-то отправится на небеса, а кто-то просто умрет.", - "#Всегда оставайся человеком. Даже если ты не человек.", - "#Цикл вновь повторяется. Ты снова тут. Как и в прошлый раз.", + "Всегда оставайся человеком. Даже если ты не человек.", + "Цикл вновь повторяется. Ты снова тут. Как и в прошлый раз.", "#Если бы в уравнении было лишнее звено, то тебя бы не было. Ты кому-то точно нужен.", - "#Времена меняются. Например, почти никто больше не здоровается за руку. Её ведь так сложно вытянуть.", - "#Любви тут давно нет. Бог покинул это место.", + "Времена меняются. Например, почти никто больше не здоровается за руку. Её ведь так сложно вытянуть.", + "Любви тут давно нет. Бог покинул это место.", "#Тюрьма - не содержание. Это изысканная казнь скукой с вариантами для выхода.", "#Не обращайся к Богу за помощью - он может тебе ответить не так, как хотелось бы.", "#От Божьей Кары не убежать - она на божественных скоростях.", - "#Глаза у меня добрые, но рубашка смерительная.", "#Так заканчивается моя история. Официально это было самоубийство, и я так никогда и не узнаю, что случилось со мной в закусочной той ночью.", "#Он безумный, мир безумный — ты тоже безумный, потому что в твоей голове сижу безумный я", - "#Я не из тех, кто жаждет крови, не из тех, кому не хватает насилия и не любитель проблем. Но и совесть меня не мучает.", + "Я не из тех, кто жаждет крови, не из тех, кому не хватает насилия и не любитель проблем. Но и совесть меня не мучает.", "#Жирафы - бессердечные создания", - "#Между годами серого существования и мигом надежды, я выбираю надежду", + "#Руки дрожат...", + "#Мои алмазы добыты в самых ужасных местах, которые только возможны.", + "Между годами серого существования и мигом надежды, я выбираю надежду", "#Не пытки меня сломали. Не промывка мозгов. Не удар по голове. Не слуга Мансуса. Смерть...", "#Тремеры... Они. Идут. За нами...", - "#Вентру никогда не примут этого, не важно, кто попытается им это передать. И не говорите, что я вас не предупреждал.", - "#Бруха. Я бы хотел полюбить вашего обычного Бруха, но у него такой толстый череп, что он просто не может расколоть его и вытащить наружу все то хорошее, о существовании чего он даже не подозревает. Так что забудьте о нем.", + "#Вентру никогда не примут этого, не важно, кто попытается им это объяснить. И не говорите, что я вас не предупреждал.", "#Кто же знал, что в такой небольшой женщине будет так много крови? Кроме Бога, разумеется — Бог знает все. Можем ли мы как-нибудь прибраться здесь?", - "#Брат Малахи, почему у меня так тяжело на душе?" + "Почему у меня так тяжело на душе?", + "#Никто здесь не знает, что я вампир. Кроме тех, кого я высосал и убил, но они теперь мертвы, так что эта проблема в значительной степени решилась сама собой", + "В конце концов, Дьявол приходит за каждым", + "Ваша людская алчность, как всегда разбушевалась. Мы же, вампиры с присущей нам надменностью, все недооценили.", + ";Не знаю, спрашивали ли вы меня или нет, но я не вампир.", + "Быть вампиром фигово. Так что не верьте рекламе, ребят.", + "У меня очень давно не было смертных друзей. Проблема у них такая - любят умирать.", + "Я как-то тащил труп по дому и заметил, что после этого пыли не осталось. Я ведь, получается, пол подмел?", + "Да, некоторую одежду мы снимаем с жертв. Бывает, укусишь кого нибудь, а потом думаешь: Ммм, классные штаны какие!" ] } diff --git a/tff_modular/modules/vampire/monitor.dm b/tff_modular/modules/vampire/monitor.dm deleted file mode 100644 index e0c1fc71b77..00000000000 --- a/tff_modular/modules/vampire/monitor.dm +++ /dev/null @@ -1,623 +0,0 @@ -#define ALT_APPEARENCE_ID "team_monitor" - -//================== -// Helpers -//================== - -//A list that tracks everything that should be tracked by team monitors -//Assoc list: -// Key = Frequency -// Value = Components -GLOBAL_LIST_EMPTY(tracker_huds) -GLOBAL_LIST_EMPTY(tracker_beacons) - -//Gets the first free team element, useful for creating new teams -//Special key is for what kind of team frequency it should be -//Everything that has a team monitor can be configured to change what frequency it tracks on -//The special key can be used to make keys like synd5 or synd83 to prevent centcom tracking syndies. -/proc/get_free_team_frequency(special_key = "") - var/sanity = 5 - //5 attempts to find a free team element, should never get that far - while(sanity > 0) - sanity -- - var/random_id = rand(1, 999) - var/key = "[random_id]" - if(!GLOB.tracker_beacons.Find("[special_key][key]")) - return key - //Return something anyways - var/random_id = rand(1, 999) - var/key = "[random_id]" - return key - -//Adds a new tracking hud -/proc/add_tracker_hud(frequency_added, datum/component/component_added) - if(!frequency_added) - return - if(islist(GLOB.tracker_huds[frequency_added])) - GLOB.tracker_huds[frequency_added] |= component_added - else - GLOB.tracker_huds[frequency_added] = list(component_added) - -//Adds a new tracking beacon -/proc/add_tracker_beacon(frequency_added, datum/component/component_added) - if(!frequency_added) - return - if(islist(GLOB.tracker_beacons[frequency_added])) - GLOB.tracker_beacons[frequency_added] |= component_added - else - GLOB.tracker_beacons[frequency_added] = list(component_added) - -/proc/get_all_beacons_on_frequency(frequency, base_frequency) - if(!frequency) - return GLOB.tracker_beacons["[base_frequency]-GLOB"] - var/list/found_beacons = list() - if(islist(GLOB.tracker_beacons[frequency])) - found_beacons.Add(GLOB.tracker_beacons[frequency]) - if(islist(GLOB.tracker_beacons["[base_frequency]-GLOB"])) - found_beacons.Add(GLOB.tracker_beacons["[base_frequency]-GLOB"]) - return found_beacons - -/proc/get_all_watchers_on_frequency(frequency, team_key = "", global_freq = FALSE) - if(global_freq) - . = list() - for(var/tracker_freq in GLOB.tracker_huds) - for(var/datum/component/team_monitor/TM as() in GLOB.tracker_huds[tracker_freq]) - if(TM.team_freq_key == team_key) - . += TM - else - return GLOB.tracker_huds[frequency] - -//================== -// Component -// - HUD COMPONENT -// - HANDLES POINTING TOWARDS TRACKED BEACONS -//================== - -//The component that handles tracking atoms -/datum/component/team_monitor - /// The frequency of the team signals we are trackings - /// Key <-- cannot be changed - var/team_freq_key = "debug" - /// Final compiled: Consists of key then numbers between 1 and 999 - var/team_frequency = "" - /// The atoms we are actually tracking - /// Key = Beacon component - /// Value = image - var/list/tracking = list() - /// Who are we updating for - var/mob/updating = null - /// Distance from center - /// Probably in pixels or something idk - var/distance = 20 - /// Should we display the hud in the firstplace - var/hud_visible = TRUE - /// The attached beacon: Ignore this one - var/datum/component/tracking_beacon/attached_beacon - /// If we can track beacons within the same zgroup (e.g. on a multiz station) - var/multiz = TRUE - -/datum/component/team_monitor/Initialize(frequency_key, frequency, _attached_beacon, _multiz = TRUE) - multiz = _multiz - team_freq_key = frequency_key - if(frequency) - team_frequency = "[frequency_key][frequency]" - else - team_frequency = team_freq_key - - - attached_beacon = _attached_beacon - - get_matching_beacons() - add_tracker_hud(team_frequency, src) - -/datum/component/team_monitor/Destroy(force) - if(team_frequency) - GLOB.tracker_huds[team_frequency] -= src - - SEND_SIGNAL(parent, COMSIG_LIVING_TRACKER_REMOVED, team_frequency) - - //Stop processing - STOP_PROCESSING(SSprocessing, src) - - //Remove the HUD from the equipped mob - if(updating) - hide_hud(updating) - - //Dispose - if(attached_beacon) - if(attached_beacon.attached_monitor == src) - attached_beacon.attached_monitor = null - attached_beacon = null - - . = ..() - -//Gets the active trackers for when the team_monitor component -//is initialized while other trackers are already active. -/datum/component/team_monitor/proc/get_matching_beacons() - for(var/datum/component/tracking_beacon/beacon as() in get_all_beacons_on_frequency(team_frequency, team_freq_key)) - if(beacon != attached_beacon && (beacon.updating || beacon.always_update)) - add_to_tracking_network(beacon) - -//=========== -// Handles the parent being moved and updates the direction of the arrows. -//=========== - -/datum/component/team_monitor/process() - update_all_directions() - -//When the parent is removed, we need to update our arrows -//Also if we are visible update the arrows of anything tracking us -/datum/component/team_monitor/proc/parent_moved() - SIGNAL_HANDLER - - //Update our alt appearances - update_all_directions() - -//Updates the direction of the arrows for all atoms we are tracking -/datum/component/team_monitor/proc/update_all_directions() - if(!updating) - return - for(var/datum/component/tracking_beacon/beacon as() in tracking) - update_atom_dir(beacon) - -//Update the arrow towards another atom -/datum/component/team_monitor/proc/update_atom_dir(datum/component/tracking_beacon/beacon) - if(!updating?.hud_used || !beacon?.visible) - return - var/atom/movable/screen/arrow/screen = tracking[beacon] - var/turf/target_turf = get_turf(beacon.parent) - var/turf/parent_turf = get_turf(parent) - if(!target_turf || !parent_turf) - return - var/share_z = target_turf.z == parent_turf.z - if((!share_z && (!multiz)) || target_turf == parent_turf) - if(screen) - //Remove the screen - updating.hud_used.team_finder_arrows -= screen - qdel(screen) - tracking[beacon] = null - //Update their hud - updating.hud_used.show_hud(updating.hud_used.hud_version, updating) - return - if(!screen) - //Create the screen - screen = new(null, updating.hud_used) - screen.alpha = 240 - if(multiz && !share_z) - if(screen.color != beacon.z_diff_colour) - screen.color = beacon.z_diff_colour - else if(screen.color != beacon.colour) - screen.color = beacon.colour - updating.hud_used.team_finder_arrows += screen - tracking[beacon] = screen - //Update their hud - updating.hud_used.show_hud(updating.hud_used.hud_version, updating) - if(multiz && !share_z) - if(screen.color != beacon.z_diff_colour) - screen.color = beacon.z_diff_colour - else if(screen.color != beacon.colour) - screen.color = beacon.colour - var/matrix/rotationMatrix = matrix() - rotationMatrix.Scale(1.5) - rotationMatrix.Translate(0, -distance) - rotationMatrix.Turn(get_angle(target_turf, parent_turf)) - var/new_alpha = 240 - if(share_z) - switch(get_dist(target_turf, parent_turf)) - if(0) - new_alpha = 0 - if(1) - new_alpha = 60 - if(2) - new_alpha = 100 - if(3) - new_alpha = 150 - else - new_alpha = 240 - animate(screen, alpha = new_alpha, transform = rotationMatrix, time = 0.2 SECONDS) - -//=========== -// Handles hiding / showing the hud when equipped -//=========== - -/datum/component/team_monitor/proc/show_hud(mob/target) - //Our hud is disabled - if(!hud_visible || !target) - return - updating = target - //Start processing to update in weird situations - START_PROCESSING(SSprocessing, src) - //Register parent signal - RegisterSignal(target, COMSIG_MOVABLE_MOVED, PROC_REF(parent_moved)) - //Mob doesnt have a hud, dont add hud arrows - if(!target.hud_used) - return - for(var/datum/component/tracking_beacon/key in tracking) - if(!key.visible) // calling show_hud should not show hidden beacons - continue - var/atom/movable/screen/arrow/arrow = new(null, target.hud_used) - arrow.alpha = 240 - var/turf/target_turf = get_turf(key.parent) - var/turf/parent_turf = get_turf(parent) - if(multiz && target_turf.z != parent_turf.z) - if(arrow.color != key.z_diff_colour) - arrow.color = key.z_diff_colour - else if(arrow.color != key.colour) - arrow.color = key.colour - target.hud_used.team_finder_arrows += arrow - tracking[key] = arrow - //Update their hud - target.hud_used.show_hud(target.hud_used.hud_version, target) - update_all_directions() - -/datum/component/team_monitor/proc/hide_hud(mob/target) - updating = null - //Stop processing - STOP_PROCESSING(SSprocessing, src) - if(!target) - return - //UnRegister parent signal - UnregisterSignal(target, COMSIG_MOVABLE_MOVED) - //Remove our arrows - for(var/key in tracking) - var/atom/movable/screen/arrow = tracking[key] - if(!arrow) - continue - if(target.hud_used) - target.hud_used.team_finder_arrows -= arrow - qdel(arrow) - tracking[key] = null - //Update their hud - if(target.hud_used) - target.hud_used.show_hud(target.hud_used.hud_version, target) - -//=========== -// Handles user interaction -// - Disabling hud transmission -// - Disabling hud view -// - Changing transmission frequency -//=========== - -/datum/component/team_monitor/proc/toggle_hud(new_hud_status, mob/user) - hud_visible = new_hud_status - if(hud_visible && !updating) - show_hud(user) - else if(!hud_visible) - hide_hud(user) - -/datum/component/team_monitor/proc/change_frequency(mob/user) - //Get new frequency - var/new_freq = input(user, "Enter a new frequency (1 - 999):", "Frequency Change", 1) as num|null - if(!new_freq) - to_chat(user, "Invalid frequency. Encrypted tracking HUD disabled.") - return - if(new_freq < 1 || new_freq > 999) - to_chat(user, "Frequency is out of range. Must be between 1 and 999.") - return - set_frequency(new_freq) - to_chat(user, "Tracking HUD now scanning on frequency [team_frequency].") - //Set frequency of the linked beacon - if(attached_beacon) - attached_beacon.set_frequency(new_freq) - -/datum/component/team_monitor/proc/set_frequency(new_frequency) - var/hud_on = hud_visible - var/mob/user = updating - //Remove tracking from old frequency - if(team_frequency) - if(updating) - toggle_hud(FALSE, updating) - //Remove from the global frequency - GLOB.tracker_huds[team_frequency] -= src - //Clear tracking - tracking.Cut() - team_frequency = "[team_freq_key][new_frequency]" - //Add tracking to new frequency - if(!team_frequency) - return - //Adds our tracking component to the global list of trackers - add_tracker_hud(team_frequency, src) - //Gets the other trackers on our frequency - get_matching_beacons() - //Show hud if needed - if(user) - toggle_hud(hud_on, user) - -//Adds a new atom to the tracking monitor, will create a hud element that tracks them -//TODO: Add the screen if already equipped -//Should be the only way atoms are added to the tracking list -/datum/component/team_monitor/proc/add_to_tracking_network(datum/component/tracking_beacon/beacon) - if(beacon != attached_beacon) - if(updating?.hud_used) - var/atom/movable/screen/arrow/arrow = new(null, updating.hud_used) - arrow.alpha = 240 - var/turf/target_turf = get_turf(beacon.parent) - var/turf/parent_turf = get_turf(parent) - if(multiz && target_turf.z != parent_turf.z) - if(arrow.color != beacon.z_diff_colour) - arrow.color = beacon.z_diff_colour - else if(arrow.color != beacon.colour) - arrow.color = beacon.colour - updating.hud_used.team_finder_arrows += arrow - tracking[beacon] = arrow - //Update arrow direction - update_atom_dir(beacon) - //Update their hud - updating.hud_used.show_hud(updating.hud_used.hud_version, updating) - else - tracking[beacon] = null - -// ============ -// Worn version, hides when dequipped -// ============ - -/datum/component/team_monitor/worn/Initialize(frequency_key, frequency, _attached_beacon) - var/obj/item/clothing/item = parent - if(!istype(item)) - return COMPONENT_INCOMPATIBLE - RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, PROC_REF(parent_equipped)) - RegisterSignal(parent, COMSIG_ITEM_DROPPED, PROC_REF(parent_dequpped)) - ..() - -//=========== -// Handles being equipped / dequipped -//=========== - -//The parent equipped an item with a team_monitor, check if its in the right slot and apply the hud -//Also needs to enable other trackers pointers towards us -/datum/component/team_monitor/worn/proc/parent_equipped(datum/source, mob/equipper, slot) - SIGNAL_HANDLER - - var/obj/item/clothing/item = parent - if(!istype(item)) - return - if(item.slot_flags & slot) //Was equipped to a valid slot for this item? - show_hud(equipper) - else - hide_hud(equipper) - -//Disable our hud -//Disable the pointers to us -/datum/component/team_monitor/worn/proc/parent_dequpped(datum/source, mob/user) - SIGNAL_HANDLER - - hide_hud(user) - -/datum/component/team_monitor/worn/Destroy(force) - //Unregister signals - if(parent) - UnregisterSignal(parent, COMSIG_ITEM_EQUIPPED) - UnregisterSignal(parent, COMSIG_ITEM_DROPPED) - return ..() - -//================== -// Component -// - TRACKER COMPONENT -// - HANDLES UPDATING TRACKERS WHEN MOVED -//================== - -/datum/component/tracking_beacon - /// The frequency of the team signals we are trackings - /// Key <-- cannot be changed - var/team_freq_key = "debug" - /// Final compiled: Consists of key then numbers between 1 and 999 - var/team_frequency = "" - /// Are we visible to other trackers? - var/visible = TRUE - /// Our colour - var/colour = "#FFFFFF" - /// Colour when on a different z level - var/z_diff_colour = "#808080" - /// Who are we updating for - var/mob/updating = null - /// Do we have an attached monitor? - var/datum/component/team_monitor/attached_monitor - /// Should we update when not equipped? - var/always_update = FALSE - /// Global signal? - var/global_signal = FALSE - -/datum/component/tracking_beacon/Initialize(_frequency_key, _frequency, _attached_monitor, _visible = TRUE, _colour = "#ffffff", _global = FALSE, _always_update = FALSE, _z_diff_colour = "#808080") - . = ..() - - //Set vars - colour = _colour - z_diff_colour = _z_diff_colour - attached_monitor = _attached_monitor - always_update = _always_update - global_signal = _global - - //Set the frequency we are transmitting on - team_freq_key = _frequency_key - if(_global) - team_frequency = "[_frequency_key]-GLOB" - else if(_frequency) - team_frequency = "[_frequency_key][_frequency]" - else - team_frequency = team_freq_key - - //Add ourselves to the tracking network - add_tracker_beacon(team_frequency, src) - - //Register tracking signal - if(always_update) - RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(update_position)) - else - //Reigster equipping signals - RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, PROC_REF(parent_equipped)) - RegisterSignal(parent, COMSIG_ITEM_DROPPED, PROC_REF(parent_dequpped)) - - //Set our visibility on the tracking network - toggle_visibility(_visible) - -/datum/component/tracking_beacon/Destroy(force) - //Unregister signals - if(parent) - //Register tracking signal - if(always_update) - UnregisterSignal(parent, COMSIG_MOVABLE_MOVED) - else - UnregisterSignal(parent, COMSIG_ITEM_EQUIPPED) - UnregisterSignal(parent, COMSIG_ITEM_DROPPED) - - //Unregister movement signal - if(updating) - UnregisterSignal(updating, COMSIG_MOVABLE_MOVED) - - //Goodbye, it was a good life - remove_from_huds() - - //Remove from the global network - if(team_frequency) - GLOB.tracker_beacons[team_frequency] -= src - - if(attached_monitor?.attached_beacon == src) - attached_monitor.attached_beacon = null - attached_monitor = null - - . = ..() - -//=========== -// Equip/Dequip transmission handling -//=========== - -//The parent equipped an item with a team_monitor, check if its in the right slot and apply the hud -//Also needs to enable other trackers pointers towards us -/datum/component/tracking_beacon/proc/parent_equipped(datum/source, mob/equipper, slot) - SIGNAL_HANDLER - - var/obj/item/clothing/item = parent - if(!istype(item)) - return - if(item.slot_flags & slot) //Was equipped to a valid slot for this item? - updating = equipper - toggle_visibility(TRUE) - RegisterSignal(updating, COMSIG_MOVABLE_MOVED, PROC_REF(update_position)) - else - toggle_visibility(FALSE) - if(updating) - UnregisterSignal(updating, COMSIG_MOVABLE_MOVED) - updating = null - -//Disable our hud -//Disable the pointers to us -/datum/component/tracking_beacon/proc/parent_dequpped(datum/source, mob/user) - SIGNAL_HANDLER - - toggle_visibility(FALSE) - if(updating) - UnregisterSignal(updating, COMSIG_MOVABLE_MOVED) - updating = null - -//=========== -// Visibility Handling -//=========== - -//Toggle visibility -//If visibility is disabled we will hide ourselves from others -/datum/component/tracking_beacon/proc/toggle_visibility(new_vis) - visible = new_vis - //If we are updating toggle our visibility - if((updating || always_update) && visible) - add_to_huds() - else - remove_from_huds() - -//=========== -// Position Updating -//=========== - -/datum/component/tracking_beacon/proc/update_position() - SIGNAL_HANDLER - - //Update everyone tracking us - if(!visible) - return - if(!team_frequency) - return - for(var/datum/component/team_monitor/TM as() in get_all_watchers_on_frequency(team_frequency, team_freq_key, global_signal)) - if(TM != attached_monitor) - TM.update_atom_dir(src) - -//=========== -// Showing on huds -//=========== - -//Remove ourselves from other tracking components -/datum/component/tracking_beacon/proc/remove_from_huds() - if(!team_frequency) - return - for(var/datum/component/team_monitor/team_monitor as() in get_all_watchers_on_frequency(team_frequency, team_freq_key, global_signal)) - //Remove ourselves from the tracking list - var/atom/movable/screen/arrow = team_monitor.tracking[src] - team_monitor.tracking.Remove(src) - //Delete the arrow pointing to use - if(!arrow) - continue - if(team_monitor.updating?.hud_used) - team_monitor.updating.hud_used.team_finder_arrows -= arrow - //Update their hud - team_monitor.updating.hud_used.show_hud(team_monitor.updating.hud_used.hud_version, team_monitor.updating) - qdel(arrow) - -//Add ourselves to other tracking components -/datum/component/tracking_beacon/proc/add_to_huds() - //If we are invisibile, dont bother - if(!visible) - return - //Find other trackers and add ourselves to their tracking network - if(!team_frequency) - return - for(var/datum/component/team_monitor/team_monitor as() in get_all_watchers_on_frequency(team_frequency, team_freq_key, global_signal)) - if(team_monitor != attached_monitor) - team_monitor.add_to_tracking_network(src) - -//=========== -// Handles user interaction -// - Disabling hud transmission -// - Disabling hud view -// - Changing transmission frequency -//=========== - -/datum/component/tracking_beacon/proc/change_frequency(mob/user) - //Get new frequency - var/new_freq = input(user, "Enter a new frequency (1 - 999):", "Frequency Change", 1) as num|null - if(!new_freq) - to_chat(user, "Invalid frequency. Encrypted tracking beacon disabled.") - return - if(new_freq < 1 || new_freq > 999) - to_chat(user, "Frequency is out of range. Must be between 1 and 999.") - return - set_frequency(new_freq) - to_chat(user, "Tracking HUD now transmitting on frequency [team_frequency].") - //Set frequency of the linked tracker - if(attached_monitor) - attached_monitor.set_frequency(new_freq) - -/datum/component/tracking_beacon/proc/set_frequency(new_frequency) - //Remove tracking from old frequency - if(team_frequency) - //Disable the beacon on other trackers - toggle_visibility(FALSE) - //Remove from the global frequency - GLOB.tracker_beacons[team_frequency] -= src - team_frequency = "[team_freq_key][new_frequency]" - //Add tracking to new frequency - if(!team_frequency) - return - //Adds our tracking component to the global list of trackers - add_tracker_beacon(team_frequency, src) - //Set our visibility on the tracking network - toggle_visibility(visible) - -//======= -// Generic Arrow, No special effects -//======= - -/atom/movable/screen/arrow - icon = 'tff_modular/modules/vampire/icons/hud.dmi' - icon_state = "hud_arrow" - screen_loc = ui_team_finder - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - -#undef ALT_APPEARENCE_ID diff --git a/tff_modular/modules/vampire/movable_physics.dm b/tff_modular/modules/vampire/movable_physics.dm new file mode 100644 index 00000000000..cd05ecd9506 --- /dev/null +++ b/tff_modular/modules/vampire/movable_physics.dm @@ -0,0 +1,354 @@ +PROCESSING_SUBSYSTEM_DEF(movable_physics) + name = "Movable Physics" + priority = 24 + wait = 0.05 SECONDS + stat_tag = "MPhys" + runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME + +/** + * MOVABLE PHYSICS COMPONENT - By ma44, bob joga and pyroshark (https://github.com/DaedalusDock/daedalusdock/pull/96/) + * + * Essentially, this component adds a very dodgy, very barebones simulation of pixel movement and physics for the movable. + * Using animate here would be very expensive, so instead this processes every 1/20 seconds and adjusts pixel_x, pixel_y and pixel_z. + * Whenever the movable crosses a tile's boundary, it will attempt to move into the appropriate tile. + * Collisions are accounted for, but they are very simple and tile based. No complex hitboxes or anythin'. + * All of this, of course, only works while the movable is located a turf. + */ +/datum/component/movable_physics + /// Flags for turning on certain physic properties, see the top of the file for more information on flags + var/physics_flags + /// The angle of the path the object takes on the x/y plane + var/angle + /** + * Modifies the pixel_x/pixel_y of an object every process() + * Movables aren't Move()'d into another turf if pixel_z exceeds 16, so try not to supply a super high vertical value + * if you don't want the movable to clip through multiple turfs (looks dumb) + */ + var/horizontal_velocity + /// Modifies the pixel_z of an object every process() + var/vertical_velocity + /** + * The horizontal_velocity is reduced by this every process() + * this doesn't take into account the object being in the air vs gravity pushing it against the ground + */ + var/horizontal_friction + /// The vertical_velocity is reduced by this every process() + var/vertical_friction + /** + * Conservation of momentum for x/y plane + * horizontal_velocity gets multiplied by this when bumping on a wall + */ + var/horizontal_conservation_of_momentum + /** + * Conservation of momentum for z plane + * vertical_velocity gets multiplied by this when bumping on the floor + */ + var/vertical_conservation_of_momentum + /** + * The pixel_z that the object will no longer be influenced by gravity for a 32x32 turf + * Keep this value between -16 to 0 so it's visuals matches up with it physically being in the turf + */ + var/z_floor + /// Visual angle velocity of the object + var/visual_angle_velocity + /// Visual angle friction of the object + var/visual_angle_friction + /// For calling spinanimation at the start of movement + var/spin_speed + /// For calling spinanimation at the start of movement + var/spin_loops + /// For calling spinanimation at the start of movement + var/spin_clockwise + /// For calling spinanimation when bouncing + var/bounce_spin_speed + /// For calling spinanimation when bouncing + var/bounce_spin_loops + /// For calling spinanimation when bouncing + var/bounce_spin_clockwise + /// The sound effect to play when bouncing off of something + var/bounce_sound + /// If we have this callback, it gets invoked when bouncing on the floor + var/datum/callback/bounce_callback + /// If we have this callback, it gets invoked when stopping movement + var/datum/callback/stop_callback + /// If we have this callback, it gets invoked when bumping on another atom + var/datum/callback/bump_callback + + /** + * The cached animate_movement of the parent + * Any kind of gliding when doing Move() makes the physics look derpy, so we'll just make Move() be instant + */ + var/cached_animate_movement + /// Cached transform of the parent, in case some fucking idiot decides its a good idea to make the damn movable spin forever + var/cached_transform + +// It's a BAD IDEA to use this on something that is not an item, even though you can +/datum/component/movable_physics/Initialize( + physics_flags = NONE, + angle = 0, + horizontal_velocity = 0, + vertical_velocity = 0, + horizontal_friction = 0, + vertical_friction = 0, + horizontal_conservation_of_momentum = 0.8, + vertical_conservation_of_momentum = 0.8, + z_floor = 0, + visual_angle_velocity = 0, + visual_angle_friction = 0, + spin_speed = 2 SECONDS, + spin_loops = 0, + spin_clockwise = TRUE, + bounce_spin_speed = 0, + bounce_spin_loops = 0, + bounce_spin_clockwise = 0, + bounce_sound, + bounce_callback, + bump_callback, + stop_callback, +) + if(!ismovable(parent)) + return COMPONENT_INCOMPATIBLE + + src.horizontal_velocity = horizontal_velocity + src.vertical_velocity = vertical_velocity + src.horizontal_friction = horizontal_friction + src.vertical_friction = vertical_friction + src.z_floor = z_floor + src.physics_flags = physics_flags + src.angle = angle + src.horizontal_conservation_of_momentum = horizontal_conservation_of_momentum + src.vertical_conservation_of_momentum = vertical_conservation_of_momentum + src.visual_angle_velocity = visual_angle_velocity + src.visual_angle_friction = visual_angle_friction + src.spin_speed = spin_speed + src.spin_loops = spin_loops + src.spin_clockwise = spin_clockwise + src.bounce_spin_speed = bounce_spin_speed + src.bounce_spin_loops = bounce_spin_loops + src.bounce_spin_clockwise = bounce_spin_clockwise + src.bounce_sound = bounce_sound + src.bounce_callback = bounce_callback + src.bump_callback = bump_callback + src.stop_callback = stop_callback + set_angle(angle) + +/datum/component/movable_physics/Destroy(force) + STOP_PROCESSING(SSmovable_physics, src) + bounce_callback = null + stop_callback = null + cached_transform = null + return ..() + +/datum/component/movable_physics/RegisterWithParent() + RegisterSignal(parent, COMSIG_MOVABLE_BUMP, PROC_REF(on_bump)) + if(isitem(parent)) + RegisterSignal(parent, COMSIG_ITEM_PICKUP, PROC_REF(on_item_pickup)) + if(has_movement()) + start_movement() + else if(physics_flags & MPHYSICS_QDEL_WHEN_NO_MOVEMENT) + qdel(src) + +/datum/component/movable_physics/UnregisterFromParent() + UnregisterSignal(parent, COMSIG_MOVABLE_IMPACT) + if(isitem(parent)) + UnregisterSignal(parent, COMSIG_ITEM_PICKUP) + stop_movement() + +// NOTE: This component will work very poorly at anything less than ticking 10 times per second +/datum/component/movable_physics/process(seconds_per_tick) + var/atom/movable/moving_atom = parent + if(!isturf(moving_atom.loc) || QDELING(moving_atom.loc) || !has_movement()) + stop_movement() + return PROCESS_KILL + + // We will not process when paused + if(physics_flags & MPHYSICS_PAUSED) + return + + // this component was designed to tick every 1/20 seconds, so we have to always account for that + var/tick_amount = 20 * seconds_per_tick + //this code basically only makes sense if we only move at most a single tile per tick, it is absolutely fucked otherwise + while(tick_amount > 0) + tick_amount-- + //we need to know if we have gravity right now to apply friction and such, yeah + var/has_gravity = moving_atom.has_gravity() + + moving_atom.pixel_x = round(moving_atom.pixel_x + (horizontal_velocity * sin(angle)), MOVABLE_PHYSICS_PRECISION) + moving_atom.pixel_y = round(moving_atom.pixel_y + (horizontal_velocity * cos(angle)), MOVABLE_PHYSICS_PRECISION) + + moving_atom.pixel_z = round(clamp(moving_atom.pixel_z + vertical_velocity, z_floor, world.icon_size), MOVABLE_PHYSICS_PRECISION) + + moving_atom.adjust_visual_angle(round(visual_angle_velocity, 1)) + + if(has_gravity) + visual_angle_velocity = max(0, visual_angle_velocity - visual_angle_friction) + horizontal_velocity = max(0, horizontal_velocity - horizontal_friction) + // we are not on the floor, apply friction + if(moving_atom.pixel_z > z_floor) + vertical_velocity -= vertical_friction + // we are on the floor, try to bounce if we have any vertical velocity + else if(moving_atom.pixel_z <= z_floor && vertical_velocity) + z_floor_bounce(moving_atom) + // z_floor_bounce could have deleted us + if(QDELETED(src)) + return + + var/move_direction = NONE + var/effective_pixel_x = moving_atom.pixel_x - moving_atom.base_pixel_x + var/effective_pixel_y = moving_atom.pixel_y - moving_atom.base_pixel_y + //crossed east boundary + if(effective_pixel_x > world.icon_size/2) + move_direction |= EAST + //crossed west boundary + else if(effective_pixel_x < -world.icon_size/2) + move_direction |= WEST + + //crossed north boundary + if(effective_pixel_y > world.icon_size/2) + move_direction |= NORTH + //crossed south boundary + else if(effective_pixel_y < -world.icon_size/2) + move_direction |= SOUTH + + //check if we need to move, continue otherwise + if(!move_direction) + continue + //get the tile we should move towards + var/step = get_step(moving_atom, move_direction) + //attempt to move to that tile, if successful we reset the pixel_x and pixel_y to be on the edge of appropriate boundaries + //if unsuccessful, bump signal will be called and newton's third law comes into play + if(moving_atom.Move(step, move_direction, world.icon_size)) + if(move_direction & EAST) + moving_atom.pixel_x -= world.icon_size + else if(move_direction & WEST) + moving_atom.pixel_x += world.icon_size + + if(move_direction & NORTH) + moving_atom.pixel_y -= world.icon_size + else if(move_direction & SOUTH) + moving_atom.pixel_y += world.icon_size + +/// Checks if we still have any movement going on +/datum/component/movable_physics/proc/has_movement() + var/atom/movable/moving_atom = parent + // horizontal velocity and visual_angle_velocity should NEVER be negative + if(horizontal_velocity < MOVABLE_PHYSICS_MINIMAL_VELOCITY && \ + abs(vertical_velocity) < MOVABLE_PHYSICS_MINIMAL_VELOCITY && \ + moving_atom.pixel_z <= z_floor && \ + visual_angle_velocity < MOVABLE_PHYSICS_MINIMAL_VELOCITY) + return FALSE + return TRUE + +/// Does a bunch of setup, then starts the movement sequence +/datum/component/movable_physics/proc/start_movement() + if(physics_flags & MPHYSICS_MOVING) + stack_trace("[type] attempted to start_movement() while already moving") + return + START_PROCESSING(SSmovable_physics, src) + physics_flags |= MPHYSICS_MOVING + var/atom/movable/moving_atom = parent + cached_animate_movement = moving_atom.animate_movement + moving_atom.animate_movement = NO_STEPS + if(!spin_speed || visual_angle_velocity || visual_angle_friction) + return + moving_atom.SpinAnimation(speed = spin_speed, loops = spin_loops) + if(spin_loops == INFINITY) + cached_transform = matrix(moving_atom.transform) + +/// Stops movement sequence, and deletes component if we have the MPHYSICS_QDEL_WHEN_NO_MOVEMENT flag +/datum/component/movable_physics/proc/stop_movement() + STOP_PROCESSING(SSmovable_physics, src) + physics_flags &= ~MPHYSICS_MOVING + var/atom/movable/moving_atom = parent + if(cached_animate_movement) + moving_atom.animate_movement = cached_animate_movement + // this will probably bite my ass later + moving_atom.pixel_z = z_floor + if(cached_transform) + animate(moving_atom, transform = cached_transform, time = 0, loop = 0) + stop_callback?.Invoke() + if((physics_flags & MPHYSICS_QDEL_WHEN_NO_MOVEMENT) && !QDELING(src)) + qdel(src) + +/// Helper to set angle, futureproofing in case new behavior like altering the transform of the movable based on angle is needed +/datum/component/movable_physics/proc/set_angle(new_angle) + if(!isnull(new_angle)) + angle = SIMPLIFY_DEGREES(new_angle) + +/// Proc for bouncing, aka object reached z_floor on pixel_z and needs a dose of Newton's third law +/datum/component/movable_physics/proc/z_floor_bounce(atom/movable/moving_atom) + moving_atom.pixel_z = round(z_floor, MOVABLE_PHYSICS_PRECISION) + if(bounce_spin_speed && !visual_angle_velocity && !visual_angle_friction) + moving_atom.SpinAnimation(speed = bounce_spin_speed, loops = max(0, bounce_spin_loops)) + vertical_velocity = abs(vertical_velocity * vertical_conservation_of_momentum) + bounce_callback?.Invoke() + +/// Basically handles bumping on a solid object and ricocheting away according to a dose of Newton's third law +/datum/component/movable_physics/proc/on_bump(atom/movable/source, atom/bumped_atom) + SIGNAL_HANDLER + + horizontal_velocity = horizontal_velocity * horizontal_conservation_of_momentum + var/face_direction = get_dir(bumped_atom, source) + var/face_angle = dir2angle(face_direction) + var/incidence = GET_ANGLE_OF_INCIDENCE(face_angle, angle + 180) + var/new_angle = SIMPLIFY_DEGREES(face_angle + incidence) + set_angle(new_angle) + bump_callback?.Invoke(bumped_atom) + if(!visual_angle_velocity) + return + incidence = GET_ANGLE_OF_INCIDENCE(face_angle, source.visual_angle + 180) + new_angle = SIMPLIFY_DEGREES(face_angle + incidence) + source.set_visual_angle(new_angle) + bumped_atom.hitby(source, FALSE) + +/// Stops movement for pesky items when they get picked up, as that essentially invalidates this component +/datum/component/movable_physics/proc/on_item_pickup(obj/item/source) + SIGNAL_HANDLER + + stop_movement() + +/** + * DEBUG PROC + * + * Basically, loosely throws src towards target. For simple, no-nonsense testing of the component. + * Deviation is just the amount of degrees the angle can deviate. + */ +/atom/movable/proc/physics_chungus_deluxe(atom/movable/target, deviation = rand(-10, 10)) + var/angle_to_target = get_angle(src, target) + var/angle_of_movement = angle_to_target + if(deviation) + angle_of_movement += SIMPLIFY_DEGREES(rand(-deviation * 100, deviation * 100) * 0.01) + AddComponent(/datum/component/movable_physics, \ + angle = angle_of_movement, \ + horizontal_velocity = rand(4.5 * 100, 5.5 * 100) * 0.01, \ + vertical_velocity = rand(4 * 100, 4.5 * 100) * 0.01, \ + horizontal_friction = rand(0.2 * 100, 0.24 * 100) * 0.01, \ + vertical_friction = 10 * 0.05, \ + z_floor = 0, \ + visual_angle_velocity = rand(1 * 100, 3 * 100) * 0.01, \ + visual_angle_friction = 0.1, \ + ) + +/atom/movable + /** + * Current visual angle in degrees + * Generally if you want to make an atom rotate visually, you should use this var + * and it's setter procs + */ + var/visual_angle = 0 + +/// Adjusts the visual angle of the atom by angle_amount in degrees, based on it's current transform +/atom/movable/proc/adjust_visual_angle(angle_amount, animate_time = 0, animate_loop = 0, animate_easing = LINEAR_EASING, animate_flags = NONE) + angle_amount = SIMPLIFY_DEGREES(angle_amount) + if(!angle_amount) + return + animate(src, transform = transform.Turn(angle_amount), time = animate_time, loop = animate_loop, easing = animate_easing, flags = animate_flags) + visual_angle += angle_amount + visual_angle = SIMPLIFY_DEGREES(visual_angle) + +/// Sets the angle of the transform to exactly new_angle in degrees +/atom/movable/proc/set_visual_angle(new_angle = 0) + if(isnull(new_angle)) + return + var/difference = SIMPLIFY_DEGREES(new_angle - visual_angle) + return adjust_visual_angle(difference) diff --git a/tff_modular/modules/vampire/objects/_vampire_object.dm b/tff_modular/modules/vampire/objects/_vampire_object.dm index 4a5e0af1a7d..2e129fba422 100644 --- a/tff_modular/modules/vampire/objects/_vampire_object.dm +++ b/tff_modular/modules/vampire/objects/_vampire_object.dm @@ -27,7 +27,7 @@ . += span_cult(vampire_desc) if(IS_VASSAL(user) && vassal_desc) . += span_cult(vassal_desc) - if(IS_VAMPIRE_HUNTER(user) && curator_desc) + if(IS_CURATOR(user) && curator_desc) . += span_cult(curator_desc) /// This handles bolting down the structure. diff --git a/tff_modular/modules/vampire/objects/candelabrum.dm b/tff_modular/modules/vampire/objects/candelabrum.dm index b4daf5924a2..621ceb488cb 100644 --- a/tff_modular/modules/vampire/objects/candelabrum.dm +++ b/tff_modular/modules/vampire/objects/candelabrum.dm @@ -153,7 +153,7 @@ return PROCESS_KILL for(var/mob/living/carbon/nearby_people in viewers(7, src)) /// We don't want vampires or vassals affected by this - if(HAS_MIND_TRAIT(nearby_people, TRAIT_VAMPIRE_ALIGNED) || IS_VAMPIRE_HUNTER(nearby_people)) + if(HAS_MIND_TRAIT(nearby_people, TRAIT_VAMPIRE_ALIGNED) || IS_CURATOR(nearby_people)) continue nearby_people.set_hallucinations_if_lower(10 SECONDS) nearby_people.add_mood_event("vampcandle", /datum/mood_event/vampcandle) diff --git a/tff_modular/modules/vampire/objects/kindred.dm b/tff_modular/modules/vampire/objects/kindred.dm index 0da73006081..1bcd184ba58 100644 --- a/tff_modular/modules/vampire/objects/kindred.dm +++ b/tff_modular/modules/vampire/objects/kindred.dm @@ -34,7 +34,7 @@ return NONE if(DOING_INTERACTION(user, DOAFTER_SOURCE_ARCHIVE_OF_THE_KINDRED)) return ITEM_INTERACT_BLOCKING - if(!IS_VAMPIRE_HUNTER(user)) + if(!IS_CURATOR(user)) if(!IS_VAMPIRE(user)) to_chat(user, span_warning("[src] burns your hands as you try to use it!")) user.apply_damage(3, BURN, pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM)) @@ -66,7 +66,7 @@ return interact_with_atom(interacting_with, user, modifiers) /obj/item/book/kindred/attack_self(mob/living/user) - if(!IS_VAMPIRE_HUNTER(user)) + if(!IS_CURATOR(user)) if(IS_VAMPIRE(user)) to_chat(user, span_notice("[src] seems to be too complicated for you. It would be best to leave this for someone else to take.")) else diff --git a/tff_modular/modules/vampire/powers/feed.dm b/tff_modular/modules/vampire/powers/feed.dm index a3bd237b1b9..70318826148 100644 --- a/tff_modular/modules/vampire/powers/feed.dm +++ b/tff_modular/modules/vampire/powers/feed.dm @@ -120,7 +120,7 @@ owner.balloon_alert(owner, "ew, no!") return FALSE // Cannot be a curator - if(IS_VAMPIRE_HUNTER(target)) + if(IS_CURATOR(target)) owner.balloon_alert(owner, "[target] is too powerful!") return FALSE var/datum/antagonist/vampire/target_vampire = IS_VAMPIRE(target) diff --git a/tff_modular/modules/vampire/powers/potence/lunge.dm b/tff_modular/modules/vampire/powers/potence/lunge.dm index 028f310a699..58734e8403f 100644 --- a/tff_modular/modules/vampire/powers/potence/lunge.dm +++ b/tff_modular/modules/vampire/powers/potence/lunge.dm @@ -151,7 +151,7 @@ user.spin(1 SECONDS) return - if(IS_VAMPIRE_HUNTER(target)) + if(IS_CURATOR(target)) owner.balloon_alert(owner, "pushed away!") target.grabbedby(owner) return diff --git a/tff_modular/modules/vampire/vassals/datum_vassal.dm b/tff_modular/modules/vampire/vassals/datum_vassal.dm index ecdcf995b19..47d77dd2a08 100644 --- a/tff_modular/modules/vampire/vassals/datum_vassal.dm +++ b/tff_modular/modules/vampire/vassals/datum_vassal.dm @@ -218,7 +218,7 @@ if(src in vampiredatum?.vassals) text += span_cult("This is your vassal!") examine_text += text - else if(vampiredatum || (master?.broke_masquerade && IS_VAMPIRE_HUNTER(examiner)) || IS_VASSAL(examiner)) + else if(vampiredatum || (master?.broke_masquerade && IS_CURATOR(examiner)) || IS_VASSAL(examiner)) text += span_cult("This is [master.return_full_name()]'s vassal") examine_text += text diff --git a/tgstation.dme b/tgstation.dme index a27967949e6..6e5e1293081 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -9863,7 +9863,7 @@ #include "tff_modular\modules\toys\code\loadout_datum_toys.dm" #include "tff_modular\modules\toys\code\plushes.dm" #include "tff_modular\modules\toys\code\soulmate_plushes.dm" -#include "tff_modular\modules\vampire\component.dm" +#include "tff_modular\modules\vampire\movable_physics.dm" #include "tff_modular\modules\vampire\config.dm" #include "tff_modular\modules\vampire\conversion_vampire.dm" #include "tff_modular\modules\vampire\crafts.dm" @@ -9876,7 +9876,6 @@ #include "tff_modular\modules\vampire\life_vampire.dm" #include "tff_modular\modules\vampire\misc_procs_vampire.dm" #include "tff_modular\modules\vampire\modular_changes.dm" -#include "tff_modular\modules\vampire\monitor.dm" #include "tff_modular\modules\vampire\moodlets_vampire.dm" #include "tff_modular\modules\vampire\names_vampire.dm" #include "tff_modular\modules\vampire\objectives_vampire.dm" From e62ad22c9c4343d108f96904b414e50594564808 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sat, 18 Apr 2026 15:49:19 +0300 Subject: [PATCH 119/149] =?UTF-8?q?=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D1=8F=D0=B5=D0=BC=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tff_modular/modules/vampire/component.dm | 361 ----------------------- tgstation.dme | 2 +- 2 files changed, 1 insertion(+), 362 deletions(-) delete mode 100644 tff_modular/modules/vampire/component.dm diff --git a/tff_modular/modules/vampire/component.dm b/tff_modular/modules/vampire/component.dm deleted file mode 100644 index db4c18ba50f..00000000000 --- a/tff_modular/modules/vampire/component.dm +++ /dev/null @@ -1,361 +0,0 @@ -PROCESSING_SUBSYSTEM_DEF(movable_physics) - name = "Movable Physics" - priority = 24 - wait = 0.05 SECONDS - stat_tag = "MPhys" - runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME - -/** - * MOVABLE PHYSICS COMPONENT - By ma44, bob joga and pyroshark (https://github.com/DaedalusDock/daedalusdock/pull/96/) - * - * Essentially, this component adds a very dodgy, very barebones simulation of pixel movement and physics for the movable. - * Using animate here would be very expensive, so instead this processes every 1/20 seconds and adjusts pixel_x, pixel_y and pixel_z. - * Whenever the movable crosses a tile's boundary, it will attempt to move into the appropriate tile. - * Collisions are accounted for, but they are very simple and tile based. No complex hitboxes or anythin'. - * All of this, of course, only works while the movable is located a turf. - */ -/datum/component/movable_physics - /// Flags for turning on certain physic properties, see the top of the file for more information on flags - var/physics_flags - /// The angle of the path the object takes on the x/y plane - var/angle - /** - * Modifies the pixel_x/pixel_y of an object every process() - * Movables aren't Move()'d into another turf if pixel_z exceeds 16, so try not to supply a super high vertical value - * if you don't want the movable to clip through multiple turfs (looks dumb) - */ - var/horizontal_velocity - /// Modifies the pixel_z of an object every process() - var/vertical_velocity - /** - * The horizontal_velocity is reduced by this every process() - * this doesn't take into account the object being in the air vs gravity pushing it against the ground - */ - var/horizontal_friction - /// The vertical_velocity is reduced by this every process() - var/vertical_friction - /** - * Conservation of momentum for x/y plane - * horizontal_velocity gets multiplied by this when bumping on a wall - */ - var/horizontal_conservation_of_momentum - /** - * Conservation of momentum for z plane - * vertical_velocity gets multiplied by this when bumping on the floor - */ - var/vertical_conservation_of_momentum - /** - * The pixel_z that the object will no longer be influenced by gravity for a 32x32 turf - * Keep this value between -16 to 0 so it's visuals matches up with it physically being in the turf - */ - var/z_floor - /// Visual angle velocity of the object - var/visual_angle_velocity - /// Visual angle friction of the object - var/visual_angle_friction - /// For calling spinanimation at the start of movement - var/spin_speed - /// For calling spinanimation at the start of movement - var/spin_loops - /// For calling spinanimation at the start of movement - var/spin_clockwise - /// For calling spinanimation when bouncing - var/bounce_spin_speed - /// For calling spinanimation when bouncing - var/bounce_spin_loops - /// For calling spinanimation when bouncing - var/bounce_spin_clockwise - /// The sound effect to play when bouncing off of something - var/bounce_sound - /// If we have this callback, it gets invoked when bouncing on the floor - var/datum/callback/bounce_callback - /// If we have this callback, it gets invoked when stopping movement - var/datum/callback/stop_callback - /// If we have this callback, it gets invoked when bumping on another atom - var/datum/callback/bump_callback - - /** - * The cached animate_movement of the parent - * Any kind of gliding when doing Move() makes the physics look derpy, so we'll just make Move() be instant - */ - var/cached_animate_movement - /// Cached transform of the parent, in case some fucking idiot decides its a good idea to make the damn movable spin forever - var/cached_transform - -// It's a BAD IDEA to use this on something that is not an item, even though you can -/datum/component/movable_physics/Initialize( - physics_flags = NONE, - angle = 0, - horizontal_velocity = 0, - vertical_velocity = 0, - horizontal_friction = 0, - vertical_friction = 0, - horizontal_conservation_of_momentum = 0.8, - vertical_conservation_of_momentum = 0.8, - z_floor = 0, - visual_angle_velocity = 0, - visual_angle_friction = 0, - spin_speed = 2 SECONDS, - spin_loops = 0, - spin_clockwise = TRUE, - bounce_spin_speed = 0, - bounce_spin_loops = 0, - bounce_spin_clockwise = 0, - bounce_sound, - bounce_callback, - bump_callback, - stop_callback, -) - if(!ismovable(parent)) - return COMPONENT_INCOMPATIBLE - - src.horizontal_velocity = horizontal_velocity - src.vertical_velocity = vertical_velocity - src.horizontal_friction = horizontal_friction - src.vertical_friction = vertical_friction - src.z_floor = z_floor - src.physics_flags = physics_flags - src.angle = angle - src.horizontal_conservation_of_momentum = horizontal_conservation_of_momentum - src.vertical_conservation_of_momentum = vertical_conservation_of_momentum - src.visual_angle_velocity = visual_angle_velocity - src.visual_angle_friction = visual_angle_friction - src.spin_speed = spin_speed - src.spin_loops = spin_loops - src.spin_clockwise = spin_clockwise - src.bounce_spin_speed = bounce_spin_speed - src.bounce_spin_loops = bounce_spin_loops - src.bounce_spin_clockwise = bounce_spin_clockwise - src.bounce_sound = bounce_sound - src.bounce_callback = bounce_callback - src.bump_callback = bump_callback - src.stop_callback = stop_callback - set_angle(angle) - -/datum/component/movable_physics/Destroy(force) - STOP_PROCESSING(SSmovable_physics, src) - bounce_callback = null - stop_callback = null - cached_transform = null - return ..() - -/datum/component/movable_physics/RegisterWithParent() - RegisterSignal(parent, COMSIG_MOVABLE_NEWTONIAN_MOVE, PROC_REF(on_newtonian_move)) - RegisterSignal(parent, COMSIG_MOVABLE_BUMP, PROC_REF(on_bump)) - if(isitem(parent)) - RegisterSignal(parent, COMSIG_ITEM_PICKUP, PROC_REF(on_item_pickup)) - if(has_movement()) - start_movement() - else if(physics_flags & MPHYSICS_QDEL_WHEN_NO_MOVEMENT) - qdel(src) - -/datum/component/movable_physics/UnregisterFromParent() - UnregisterSignal(parent, COMSIG_MOVABLE_IMPACT) - if(isitem(parent)) - UnregisterSignal(parent, COMSIG_ITEM_PICKUP) - stop_movement() - -// NOTE: This component will work very poorly at anything less than ticking 10 times per second -/datum/component/movable_physics/process(seconds_per_tick) - var/atom/movable/moving_atom = parent - if(!isturf(moving_atom.loc) || QDELING(moving_atom.loc) || !has_movement()) - stop_movement() - return PROCESS_KILL - - // We will not process when paused - if(physics_flags & MPHYSICS_PAUSED) - return - - // this component was designed to tick every 1/20 seconds, so we have to always account for that - var/tick_amount = 20 * seconds_per_tick - //this code basically only makes sense if we only move at most a single tile per tick, it is absolutely fucked otherwise - while(tick_amount > 0) - tick_amount-- - //we need to know if we have gravity right now to apply friction and such, yeah - var/has_gravity = moving_atom.has_gravity() - - moving_atom.pixel_x = round(moving_atom.pixel_x + (horizontal_velocity * sin(angle)), MOVABLE_PHYSICS_PRECISION) - moving_atom.pixel_y = round(moving_atom.pixel_y + (horizontal_velocity * cos(angle)), MOVABLE_PHYSICS_PRECISION) - - moving_atom.pixel_z = round(clamp(moving_atom.pixel_z + vertical_velocity, z_floor, world.icon_size), MOVABLE_PHYSICS_PRECISION) - - moving_atom.adjust_visual_angle(round(visual_angle_velocity, 1)) - - if(has_gravity) - visual_angle_velocity = max(0, visual_angle_velocity - visual_angle_friction) - horizontal_velocity = max(0, horizontal_velocity - horizontal_friction) - // we are not on the floor, apply friction - if(moving_atom.pixel_z > z_floor) - vertical_velocity -= vertical_friction - // we are on the floor, try to bounce if we have any vertical velocity - else if(moving_atom.pixel_z <= z_floor && vertical_velocity) - z_floor_bounce(moving_atom) - // z_floor_bounce could have deleted us - if(QDELETED(src)) - return - - var/move_direction = NONE - var/effective_pixel_x = moving_atom.pixel_x - moving_atom.base_pixel_x - var/effective_pixel_y = moving_atom.pixel_y - moving_atom.base_pixel_y - //crossed east boundary - if(effective_pixel_x > world.icon_size/2) - move_direction |= EAST - //crossed west boundary - else if(effective_pixel_x < -world.icon_size/2) - move_direction |= WEST - - //crossed north boundary - if(effective_pixel_y > world.icon_size/2) - move_direction |= NORTH - //crossed south boundary - else if(effective_pixel_y < -world.icon_size/2) - move_direction |= SOUTH - - //check if we need to move, continue otherwise - if(!move_direction) - continue - //get the tile we should move towards - var/step = get_step(moving_atom, move_direction) - //attempt to move to that tile, if successful we reset the pixel_x and pixel_y to be on the edge of appropriate boundaries - //if unsuccessful, bump signal will be called and newton's third law comes into play - if(moving_atom.Move(step, move_direction, world.icon_size)) - if(move_direction & EAST) - moving_atom.pixel_x -= world.icon_size - else if(move_direction & WEST) - moving_atom.pixel_x += world.icon_size - - if(move_direction & NORTH) - moving_atom.pixel_y -= world.icon_size - else if(move_direction & SOUTH) - moving_atom.pixel_y += world.icon_size - -/// Checks if we still have any movement going on -/datum/component/movable_physics/proc/has_movement() - var/atom/movable/moving_atom = parent - // horizontal velocity and visual_angle_velocity should NEVER be negative - if(horizontal_velocity < MOVABLE_PHYSICS_MINIMAL_VELOCITY && \ - abs(vertical_velocity) < MOVABLE_PHYSICS_MINIMAL_VELOCITY && \ - moving_atom.pixel_z <= z_floor && \ - visual_angle_velocity < MOVABLE_PHYSICS_MINIMAL_VELOCITY) - return FALSE - return TRUE - -/// Does a bunch of setup, then starts the movement sequence -/datum/component/movable_physics/proc/start_movement() - if(physics_flags & MPHYSICS_MOVING) - stack_trace("[type] attempted to start_movement() while already moving") - return - START_PROCESSING(SSmovable_physics, src) - physics_flags |= MPHYSICS_MOVING - var/atom/movable/moving_atom = parent - cached_animate_movement = moving_atom.animate_movement - moving_atom.animate_movement = NO_STEPS - if(!spin_speed || visual_angle_velocity || visual_angle_friction) - return - moving_atom.SpinAnimation(speed = spin_speed, loops = spin_loops) - if(spin_loops == INFINITY) - cached_transform = matrix(moving_atom.transform) - -/// Stops movement sequence, and deletes component if we have the MPHYSICS_QDEL_WHEN_NO_MOVEMENT flag -/datum/component/movable_physics/proc/stop_movement() - STOP_PROCESSING(SSmovable_physics, src) - physics_flags &= ~MPHYSICS_MOVING - var/atom/movable/moving_atom = parent - if(cached_animate_movement) - moving_atom.animate_movement = cached_animate_movement - // this will probably bite my ass later - moving_atom.pixel_z = z_floor - if(cached_transform) - animate(moving_atom, transform = cached_transform, time = 0, loop = 0) - stop_callback?.Invoke() - if((physics_flags & MPHYSICS_QDEL_WHEN_NO_MOVEMENT) && !QDELING(src)) - qdel(src) - -/// Helper to set angle, futureproofing in case new behavior like altering the transform of the movable based on angle is needed -/datum/component/movable_physics/proc/set_angle(new_angle) - if(!isnull(new_angle)) - angle = SIMPLIFY_DEGREES(new_angle) - -/// We do not EVER want newtonian movement while handling movement ourselves, so block it! -/datum/component/movable_physics/proc/on_newtonian_move(atom/movable/source, direction, start_delay) - SIGNAL_HANDLER - - return COMPONENT_MOVABLE_NEWTONIAN_BLOCK - -/// Proc for bouncing, aka object reached z_floor on pixel_z and needs a dose of Newton's third law -/datum/component/movable_physics/proc/z_floor_bounce(atom/movable/moving_atom) - moving_atom.pixel_z = round(z_floor, MOVABLE_PHYSICS_PRECISION) - if(bounce_spin_speed && !visual_angle_velocity && !visual_angle_friction) - moving_atom.SpinAnimation(speed = bounce_spin_speed, loops = max(0, bounce_spin_loops)) - vertical_velocity = abs(vertical_velocity * vertical_conservation_of_momentum) - bounce_callback?.Invoke() - -/// Basically handles bumping on a solid object and ricocheting away according to a dose of Newton's third law -/datum/component/movable_physics/proc/on_bump(atom/movable/source, atom/bumped_atom) - SIGNAL_HANDLER - - horizontal_velocity = horizontal_velocity * horizontal_conservation_of_momentum - var/face_direction = get_dir(bumped_atom, source) - var/face_angle = dir2angle(face_direction) - var/incidence = GET_ANGLE_OF_INCIDENCE(face_angle, angle + 180) - var/new_angle = SIMPLIFY_DEGREES(face_angle + incidence) - set_angle(new_angle) - bump_callback?.Invoke(bumped_atom) - if(!visual_angle_velocity) - return - incidence = GET_ANGLE_OF_INCIDENCE(face_angle, source.visual_angle + 180) - new_angle = SIMPLIFY_DEGREES(face_angle + incidence) - source.set_visual_angle(new_angle) - bumped_atom.hitby(source, FALSE) - -/// Stops movement for pesky items when they get picked up, as that essentially invalidates this component -/datum/component/movable_physics/proc/on_item_pickup(obj/item/source) - SIGNAL_HANDLER - - stop_movement() - -/** - * DEBUG PROC - * - * Basically, loosely throws src towards target. For simple, no-nonsense testing of the component. - * Deviation is just the amount of degrees the angle can deviate. - */ -/atom/movable/proc/physics_chungus_deluxe(atom/movable/target, deviation = rand(-10, 10)) - var/angle_to_target = get_angle(src, target) - var/angle_of_movement = angle_to_target - if(deviation) - angle_of_movement += SIMPLIFY_DEGREES(rand(-deviation * 100, deviation * 100) * 0.01) - AddComponent(/datum/component/movable_physics, \ - angle = angle_of_movement, \ - horizontal_velocity = rand(4.5 * 100, 5.5 * 100) * 0.01, \ - vertical_velocity = rand(4 * 100, 4.5 * 100) * 0.01, \ - horizontal_friction = rand(0.2 * 100, 0.24 * 100) * 0.01, \ - vertical_friction = 10 * 0.05, \ - z_floor = 0, \ - visual_angle_velocity = rand(1 * 100, 3 * 100) * 0.01, \ - visual_angle_friction = 0.1, \ - ) - -/atom/movable - /** - * Current visual angle in degrees - * Generally if you want to make an atom rotate visually, you should use this var - * and it's setter procs - */ - var/visual_angle = 0 - -/// Adjusts the visual angle of the atom by angle_amount in degrees, based on it's current transform -/atom/movable/proc/adjust_visual_angle(angle_amount, animate_time = 0, animate_loop = 0, animate_easing = LINEAR_EASING, animate_flags = NONE) - angle_amount = SIMPLIFY_DEGREES(angle_amount) - if(!angle_amount) - return - animate(src, transform = transform.Turn(angle_amount), time = animate_time, loop = animate_loop, easing = animate_easing, flags = animate_flags) - visual_angle += angle_amount - visual_angle = SIMPLIFY_DEGREES(visual_angle) - -/// Sets the angle of the transform to exactly new_angle in degrees -/atom/movable/proc/set_visual_angle(new_angle = 0) - if(isnull(new_angle)) - return - var/difference = SIMPLIFY_DEGREES(new_angle - visual_angle) - return adjust_visual_angle(difference) diff --git a/tgstation.dme b/tgstation.dme index 6e5e1293081..5485532b8b9 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -9863,7 +9863,6 @@ #include "tff_modular\modules\toys\code\loadout_datum_toys.dm" #include "tff_modular\modules\toys\code\plushes.dm" #include "tff_modular\modules\toys\code\soulmate_plushes.dm" -#include "tff_modular\modules\vampire\movable_physics.dm" #include "tff_modular\modules\vampire\config.dm" #include "tff_modular\modules\vampire\conversion_vampire.dm" #include "tff_modular\modules\vampire\crafts.dm" @@ -9877,6 +9876,7 @@ #include "tff_modular\modules\vampire\misc_procs_vampire.dm" #include "tff_modular\modules\vampire\modular_changes.dm" #include "tff_modular\modules\vampire\moodlets_vampire.dm" +#include "tff_modular\modules\vampire\movable_physics.dm" #include "tff_modular\modules\vampire\names_vampire.dm" #include "tff_modular\modules\vampire\objectives_vampire.dm" #include "tff_modular\modules\vampire\oozeling_vampire.dm" From 707111c3a0c369b5f84684fe5a1ddf6ab1befc63 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Tue, 21 Apr 2026 16:15:36 +0300 Subject: [PATCH 120/149] =?UTF-8?q?=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BC=D1=83=D1=81=D0=BE=D1=80?= =?UTF-8?q?=D0=B0=20=D0=B8=20=D0=B1=D0=BE=D0=BB=D0=B5=D0=B5=20=D0=BC=D0=BE?= =?UTF-8?q?=D0=B4=D1=83=D0=BB=D1=8C=D0=BD=D1=8B=D0=B5=20=D0=B8=D0=B7=D0=BC?= =?UTF-8?q?=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/__DEFINES/~ff_defines/bloodsucker.dm | 2 -- code/_onclick/hud/hud.dm | 1 + code/game/atom/_atom.dm | 1 - .../logging/categories/log_category_uplink.dm | 9 -------- code/modules/mob/dead/observer/observer.dm | 1 + .../master_files/code/datum/elements/art.dm | 3 +++ .../deathmatch/deathmatch_controller.dm | 5 +++++ .../logging/categories/log_category_uplink.dm | 4 ++++ .../modules/mob/dead/observer/observer.dm | 4 ++++ .../code/soulcatcher/soulcatcher_component.dm | 4 ++++ tff_modular/modules/vampire/client_colour.dm | 7 ++++++ tff_modular/modules/vampire/frenzy_vampire.dm | 2 +- .../modules/vampire/modular_changes.dm | 22 ------------------- tgstation.dme | 7 +++++- 14 files changed, 36 insertions(+), 36 deletions(-) create mode 100644 tff_modular/master_files/code/datum/elements/art.dm create mode 100644 tff_modular/master_files/code/modules/deathmatch/deathmatch_controller.dm create mode 100644 tff_modular/master_files/code/modules/logging/categories/log_category_uplink.dm create mode 100644 tff_modular/master_files/code/modules/mob/dead/observer/observer.dm create mode 100644 tff_modular/master_files/code/modules/modular_implants/code/soulcatcher/soulcatcher_component.dm create mode 100644 tff_modular/modules/vampire/client_colour.dm delete mode 100644 tff_modular/modules/vampire/modular_changes.dm diff --git a/code/__DEFINES/~ff_defines/bloodsucker.dm b/code/__DEFINES/~ff_defines/bloodsucker.dm index d735c6edcd4..887d390fa17 100644 --- a/code/__DEFINES/~ff_defines/bloodsucker.dm +++ b/code/__DEFINES/~ff_defines/bloodsucker.dm @@ -243,8 +243,6 @@ #define IS_SAFE_NUM(a) IS_FINITE(a) #define BODY_ZONES_LIMBS list(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) -///from base of atom/expose_reagents(): (/list, /datum/reagents, methods, volume_modifier, show_message) -#define COMSIG_ATOM_AFTER_EXPOSE_REAGENTS "atom_after_expose_reagents" #define MOVABLE_PHYSICS_PRECISION 0.01 #define MOVABLE_PHYSICS_MINIMAL_VELOCITY 1 diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index 56bbd94f741..ddd47ca17ed 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -246,6 +246,7 @@ GLOBAL_LIST_INIT(available_erp_ui_styles, list( QDEL_NULL(palette_actions) QDEL_NULL(listed_actions) QDEL_LIST(floating_actions) + QDEL_LIST(static_inventory) // all already deleted by static inventory clear diff --git a/code/game/atom/_atom.dm b/code/game/atom/_atom.dm index 2c51beb782c..757b1aa65f0 100644 --- a/code/game/atom/_atom.dm +++ b/code/game/atom/_atom.dm @@ -438,7 +438,6 @@ for(var/datum/reagent/current_reagent as anything in reagents) . |= current_reagent.expose_atom(src, reagents[current_reagent], methods) - SEND_SIGNAL(src, COMSIG_ATOM_AFTER_EXPOSE_REAGENTS, reagents, source, methods, show_message) // TFF ADDITION /// Are you allowed to drop stuff inside this atom /atom/proc/AllowDrop() diff --git a/code/modules/logging/categories/log_category_uplink.dm b/code/modules/logging/categories/log_category_uplink.dm index 847fed4dd94..4ef0f1af0c0 100644 --- a/code/modules/logging/categories/log_category_uplink.dm +++ b/code/modules/logging/categories/log_category_uplink.dm @@ -26,12 +26,3 @@ category = LOG_CATEGORY_UPLINK_SPY config_flag = /datum/config_entry/flag/log_uplink master_category = /datum/log_category/uplink - -// TFF ADDITION START - -/datum/log_category/uplink_vampire - category = LOG_CATEGORY_UPLINK_VAMPIRE - config_flag = /datum/config_entry/flag/log_uplink - master_category = /datum/log_category/uplink - -// TFF ADDITION END diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index a7f0edccbcf..c52461d16cf 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -639,6 +639,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp /mob/dead/observer/verb/restore_ghost_appearance() set name = "Restore Ghost Character" + set_ghost_appearance() if(client?.prefs) var/real_name = client.prefs.read_preference(/datum/preference/name/real_name) diff --git a/tff_modular/master_files/code/datum/elements/art.dm b/tff_modular/master_files/code/datum/elements/art.dm new file mode 100644 index 00000000000..f7b8595dcc8 --- /dev/null +++ b/tff_modular/master_files/code/datum/elements/art.dm @@ -0,0 +1,3 @@ +/datum/element/art/apply_moodlet(atom/source, mob/living/user, impress) + . = ..() + SEND_SIGNAL(user, COMSIG_LIVING_APPRAISE_ART, source) diff --git a/tff_modular/master_files/code/modules/deathmatch/deathmatch_controller.dm b/tff_modular/master_files/code/modules/deathmatch/deathmatch_controller.dm new file mode 100644 index 00000000000..e9b2fbdb046 --- /dev/null +++ b/tff_modular/master_files/code/modules/deathmatch/deathmatch_controller.dm @@ -0,0 +1,5 @@ +/datum/deathmatch_controller/ui_interact(mob/user, datum/tgui/ui) + if(HAS_TRAIT(user, TRAIT_NO_OBSERVE)) + to_chat(user, span_warning("You cannot play or host deathmatch in your current form!")) + return + ..() diff --git a/tff_modular/master_files/code/modules/logging/categories/log_category_uplink.dm b/tff_modular/master_files/code/modules/logging/categories/log_category_uplink.dm new file mode 100644 index 00000000000..2b15206f741 --- /dev/null +++ b/tff_modular/master_files/code/modules/logging/categories/log_category_uplink.dm @@ -0,0 +1,4 @@ +/datum/log_category/uplink_vampire + category = LOG_CATEGORY_UPLINK_VAMPIRE + config_flag = /datum/config_entry/flag/log_uplink + master_category = /datum/log_category/uplink diff --git a/tff_modular/master_files/code/modules/mob/dead/observer/observer.dm b/tff_modular/master_files/code/modules/mob/dead/observer/observer.dm new file mode 100644 index 00000000000..5d302f4cf13 --- /dev/null +++ b/tff_modular/master_files/code/modules/mob/dead/observer/observer.dm @@ -0,0 +1,4 @@ +/mob/dead/observer/restore_ghost_appearance() + if(HAS_TRAIT(src, TRAIT_NO_OBSERVE)) + return + ..() diff --git a/tff_modular/master_files/code/modules/modular_implants/code/soulcatcher/soulcatcher_component.dm b/tff_modular/master_files/code/modules/modular_implants/code/soulcatcher/soulcatcher_component.dm new file mode 100644 index 00000000000..9d61aef3b87 --- /dev/null +++ b/tff_modular/master_files/code/modules/modular_implants/code/soulcatcher/soulcatcher_component.dm @@ -0,0 +1,4 @@ +/mob/dead/observer/join_soulcatcher() + if(HAS_TRAIT(src, TRAIT_NO_OBSERVE)) + return FALSE + ..() diff --git a/tff_modular/modules/vampire/client_colour.dm b/tff_modular/modules/vampire/client_colour.dm new file mode 100644 index 00000000000..8a22179e5d6 --- /dev/null +++ b/tff_modular/modules/vampire/client_colour.dm @@ -0,0 +1,7 @@ +/datum/client_colour/glass_colour/pink + color = "#ffcfe9" + +/datum/client_colour/frenzy + priority = CLIENT_COLOR_IMPORTANT_PRIORITY + color = COLOR_CULT_RED + fade_out = 1 SECONDS diff --git a/tff_modular/modules/vampire/frenzy_vampire.dm b/tff_modular/modules/vampire/frenzy_vampire.dm index 329592d96e5..be724859498 100644 --- a/tff_modular/modules/vampire/frenzy_vampire.dm +++ b/tff_modular/modules/vampire/frenzy_vampire.dm @@ -47,7 +47,7 @@ // Basic stuff carbon_owner.add_movespeed_modifier(/datum/movespeed_modifier/frenzy_speed) - carbon_owner.add_client_colour(/datum/client_colour/bloodlust, CLIENT_COLOR_SOURCE_VAMPIRE) + carbon_owner.add_client_colour(/datum/client_colour/frenzy, CLIENT_COLOR_SOURCE_VAMPIRE) carbon_owner.uncuff() carbon_owner.pulledby?.stop_pulling() carbon_owner.adjust_stamina_loss(-200) diff --git a/tff_modular/modules/vampire/modular_changes.dm b/tff_modular/modules/vampire/modular_changes.dm deleted file mode 100644 index f46d398ce51..00000000000 --- a/tff_modular/modules/vampire/modular_changes.dm +++ /dev/null @@ -1,22 +0,0 @@ -/datum/deathmatch_controller/ui_interact(mob/user, datum/tgui/ui) - if(HAS_TRAIT(user, TRAIT_NO_OBSERVE)) - to_chat(user, span_warning("You cannot play or host deathmatch in your current form!")) - return - ..() - -/mob/dead/observer/restore_ghost_appearance() - if(HAS_TRAIT(src, TRAIT_NO_OBSERVE)) - return - ..() - -/mob/dead/observer/join_soulcatcher() - if(HAS_TRAIT(src, TRAIT_NO_OBSERVE)) - return FALSE - ..() - -/datum/client_colour/glass_colour/pink - color = "#ffcfe9" - -/datum/element/art/apply_moodlet(atom/source, mob/living/user, impress) - . = ..() - SEND_SIGNAL(user, COMSIG_LIVING_APPRAISE_ART, source) diff --git a/tgstation.dme b/tgstation.dme index 5485532b8b9..3a5e08e412e 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -9644,6 +9644,7 @@ #include "modular_nova\modules\xenoarchartifacts\obj\particle_battery.dm" #include "modular_nova\modules\xenoarchartifacts\obj\wave_scanner.dm" #include "tff_modular\master_files\code\_HELPERS\global_lists.dm" +#include "tff_modular\master_files\code\datum\elements\art.dm" #include "tff_modular\master_files\code\datum\id_trim\jobs.dm" #include "tff_modular\master_files\code\datum\quirks\neutral_quirks\burr.dm" #include "tff_modular\master_files\code\game\objects\items\ammo\shotammo.dm" @@ -9653,11 +9654,15 @@ #include "tff_modular\master_files\code\modules\cargo\markets\market_items\weapons.dm" #include "tff_modular\master_files\code\modules\cargo\packs\_packs.dm" #include "tff_modular\master_files\code\modules\client\preferences\clothing.dm" +#include "tff_modular\master_files\code\modules\deathmatch\deathmatch_controller.dm" #include "tff_modular\master_files\code\modules\job\job_blacklist.dm" #include "tff_modular\master_files\code\modules\job\job_outfit.dm" +#include "tff_modular\master_files\code\modules\logging\categories\log_category_uplink.dm" #include "tff_modular\master_files\code\modules\mapping\interdyne_ds2_improved_spawn.dm" #include "tff_modular\master_files\code\modules\mapping\space_ruins.dm" +#include "tff_modular\master_files\code\modules\mob\dead\observer\observer.dm" #include "tff_modular\master_files\code\modules\modular_computers\file_system\programs\dept_order.dm" +#include "tff_modular\master_files\code\modules\modular_implants\code\soulcatcher\soulcatcher_component.dm" #include "tff_modular\master_files\code\modules\power\cable.dm" #include "tff_modular\master_files\code\modules\quirks_balance\quirks.dm" #include "tff_modular\master_files\code\modules\reagents\recipe\coagulant_recipe.dm" @@ -9863,6 +9868,7 @@ #include "tff_modular\modules\toys\code\loadout_datum_toys.dm" #include "tff_modular\modules\toys\code\plushes.dm" #include "tff_modular\modules\toys\code\soulmate_plushes.dm" +#include "tff_modular\modules\vampire\client_colour.dm" #include "tff_modular\modules\vampire\config.dm" #include "tff_modular\modules\vampire\conversion_vampire.dm" #include "tff_modular\modules\vampire\crafts.dm" @@ -9874,7 +9880,6 @@ #include "tff_modular\modules\vampire\leveling_vampire.dm" #include "tff_modular\modules\vampire\life_vampire.dm" #include "tff_modular\modules\vampire\misc_procs_vampire.dm" -#include "tff_modular\modules\vampire\modular_changes.dm" #include "tff_modular\modules\vampire\moodlets_vampire.dm" #include "tff_modular\modules\vampire\movable_physics.dm" #include "tff_modular\modules\vampire\names_vampire.dm" From 8c796e65e3b8220acbe0d096d3b2c9aa3b0c17b0 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Tue, 21 Apr 2026 16:22:28 +0300 Subject: [PATCH 121/149] =?UTF-8?q?=D0=9C=D0=BE=D0=B4=D1=83=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D1=8B=D0=B5=20=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../antagonists/brainwashing/brainwashing.dm | 37 ---------- code/modules/antagonists/cult/blood_magic.dm | 69 ------------------- .../antagonists/brainwashing/brainwashing.dm | 37 ++++++++++ .../modules/antagonists/cult/blood_magic.dm | 66 ++++++++++++++++++ tgstation.dme | 2 + 5 files changed, 105 insertions(+), 106 deletions(-) create mode 100644 tff_modular/master_files/code/modules/antagonists/brainwashing/brainwashing.dm create mode 100644 tff_modular/master_files/code/modules/antagonists/cult/blood_magic.dm diff --git a/code/modules/antagonists/brainwashing/brainwashing.dm b/code/modules/antagonists/brainwashing/brainwashing.dm index 019d045d497..716e2cb494f 100644 --- a/code/modules/antagonists/brainwashing/brainwashing.dm +++ b/code/modules/antagonists/brainwashing/brainwashing.dm @@ -84,40 +84,3 @@ /datum/objective/brainwashing completed = TRUE - -// TFF ADDITION START -/// Removes objectives from someone's brainwash. -/proc/unbrainwash(mob/living/victim, list/directives) - var/datum/antagonist/brainwashed/brainwash = victim?.mind?.has_antag_datum(/datum/antagonist/brainwashed) - if(!brainwash) - return FALSE - if(directives) - if(!isnull(directives) && !islist(directives)) - directives = list(directives) - var/list/removed_objectives = list() - var/list/objective_texts = list() - for(var/datum/objective/directive as anything in directives) - if(istype(directive, /datum/weakref)) - var/datum/weakref/directive_weakref = directive - directive = directive_weakref.resolve() - if(!istype(directive)) - continue - brainwash.objectives -= directive - removed_objectives += directive - objective_texts += "\"[directive.explanation_text]\"" - log_admin("[key_name(victim)] had the following brainwashing objective[length(removed_objectives) > 1 ? "s" : ""] removed: [english_list(objective_texts)].") - if(LAZYLEN(brainwash.objectives)) - to_chat(victim, span_userdanger("[length(removed_objectives) > 1 ? "Some" : "One"] of your Directives fade away! You only have to obey the remaining Directives now.")) - victim.mind.announce_objectives() - else - victim.mind.remove_antag_datum(/datum/antagonist/brainwashed) - QDEL_LIST(removed_objectives) - else - var/list/objective_texts = list() - for(var/datum/objective/directive as anything in brainwash.objectives) - objective_texts += "\"[directive.explanation_text]\"" - log_admin("[key_name(victim)] had all of their brainwashing objectives removed: [english_list(objective_texts)].") - QDEL_LIST(brainwash.objectives) - victim.mind.remove_antag_datum(/datum/antagonist/brainwashed) - -// TFF ADDITION END diff --git a/code/modules/antagonists/cult/blood_magic.dm b/code/modules/antagonists/cult/blood_magic.dm index 2d9967ee1c9..9666e025f9a 100644 --- a/code/modules/antagonists/cult/blood_magic.dm +++ b/code/modules/antagonists/cult/blood_magic.dm @@ -504,75 +504,6 @@ carbon_target.set_jitter_if_lower(30 SECONDS * effect_coef) return ..() -// TFF ADDITION START -/obj/item/melee/blood_magic/stun/proc/effect_vampire(mob/living/target, mob/living/carbon/user) - to_chat(user, span_userdanger("The spell violently reacts with [target], releasing a large burst of sanguine energy!"), type = MESSAGE_TYPE_COMBAT) - to_chat(target, span_userdanger("You're flung back by a violent burst of sanguine energy, as [user] attempts to hit you with ") + span_cult_large("the blood of the Traitor!"), type = MESSAGE_TYPE_COMBAT) - target.visible_message( - span_warning("[user] and [target] are violently flung back by a burst of sanguine energy!"), - ignored_mobs = list(user, target), - ) - - var/obj/effect/temp_visual/sanguine_boom/boom = new(user.loc) - - if(user.loc == target.loc) - boom.pixel_x = -32 - boom.pixel_y = -32 - else - var/dir = get_dir(user, target) - if(dir & NORTH) - boom.pixel_y = 32 - else if(dir & SOUTH) - boom.pixel_y = -32 - - if(dir & WEST) - boom.pixel_x = -32 - else if(dir & EAST) - boom.pixel_x = 32 - - // deactivate any active powers, to ensure the vampire can experience the full force of being flung away at mach fuck - var/datum/antagonist/vampire/vampire_datum = IS_VAMPIRE(target) - vampire_datum.disable_all_powers(forced = TRUE) - // they lose 25% of their current vitae too - vampire_datum.adjust_blood_volume(-vampire_datum.current_vitae * 0.25) - - // ensure they're not buckled to anything, you are NOT escaping this bullshit - user.buckled?.unbuckle_mob(user, force = TRUE) - target.buckled?.unbuckle_mob(target, force = TRUE) - - playsound(user, 'tff_modular/modules/vampire/sound/rage_increase.ogg', vol = 100, vary = FALSE, pressure_affected = FALSE) - - flash_color(user.client, LIGHT_COLOR_BLOOD_MAGIC, 2 SECONDS) - flash_color(target.client, LIGHT_COLOR_BLOOD_MAGIC, 2 SECONDS) - - // cultist gets a little bit of mercy to make it slightly more fair (they won't break an arm or something from the knockback) - ADD_TRAIT(user, TRAIT_NEVER_WOUNDED, REF(src)) - addtimer(TRAIT_CALLBACK_REMOVE(user, TRAIT_NEVER_WOUNDED, REF(src)), 2 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE) - - - var/turf/user_turf = get_turf(user) - var/turf/target_turf = get_turf(target) - - // CLASH! - user.blood_particles(10, get_angle(target, user)) - target.blood_particles(10, get_angle(user, target)) - - // this is gonna hurt for the both of them. - user.throw_at(get_edge_target_turf(user_turf, get_dir(target_turf, user_turf)), range = 200, speed = 5) - target.throw_at(get_edge_target_turf(target_turf, get_dir(user_turf, target_turf)), range = 200, speed = 5) - - // they're both a bit disoriented for a moment - target.set_confusion_if_lower(8 SECONDS) - target.set_eye_blur_if_lower(8 SECONDS) - user.set_confusion_if_lower(8 SECONDS) - user.set_eye_blur_if_lower(8 SECONDS) - -/obj/effect/temp_visual/sanguine_boom - icon = 'tff_modular/modules/vampire/icons/64x64.dmi' - icon_state = "sanguine_boom" - duration = 0.41 SECONDS - -// TFF ADDITION END //Teleportation /obj/item/melee/blood_magic/teleport name = "Teleporting Aura" diff --git a/tff_modular/master_files/code/modules/antagonists/brainwashing/brainwashing.dm b/tff_modular/master_files/code/modules/antagonists/brainwashing/brainwashing.dm new file mode 100644 index 00000000000..09d1b06efa0 --- /dev/null +++ b/tff_modular/master_files/code/modules/antagonists/brainwashing/brainwashing.dm @@ -0,0 +1,37 @@ + +// TFF ADDITION START +/// Removes objectives from someone's brainwash. +/proc/unbrainwash(mob/living/victim, list/directives) + var/datum/antagonist/brainwashed/brainwash = victim?.mind?.has_antag_datum(/datum/antagonist/brainwashed) + if(!brainwash) + return FALSE + if(directives) + if(!isnull(directives) && !islist(directives)) + directives = list(directives) + var/list/removed_objectives = list() + var/list/objective_texts = list() + for(var/datum/objective/directive as anything in directives) + if(istype(directive, /datum/weakref)) + var/datum/weakref/directive_weakref = directive + directive = directive_weakref.resolve() + if(!istype(directive)) + continue + brainwash.objectives -= directive + removed_objectives += directive + objective_texts += "\"[directive.explanation_text]\"" + log_admin("[key_name(victim)] had the following brainwashing objective[length(removed_objectives) > 1 ? "s" : ""] removed: [english_list(objective_texts)].") + if(LAZYLEN(brainwash.objectives)) + to_chat(victim, span_userdanger("[length(removed_objectives) > 1 ? "Some" : "One"] of your Directives fade away! You only have to obey the remaining Directives now.")) + victim.mind.announce_objectives() + else + victim.mind.remove_antag_datum(/datum/antagonist/brainwashed) + QDEL_LIST(removed_objectives) + else + var/list/objective_texts = list() + for(var/datum/objective/directive as anything in brainwash.objectives) + objective_texts += "\"[directive.explanation_text]\"" + log_admin("[key_name(victim)] had all of their brainwashing objectives removed: [english_list(objective_texts)].") + QDEL_LIST(brainwash.objectives) + victim.mind.remove_antag_datum(/datum/antagonist/brainwashed) + +// TFF ADDITION END diff --git a/tff_modular/master_files/code/modules/antagonists/cult/blood_magic.dm b/tff_modular/master_files/code/modules/antagonists/cult/blood_magic.dm new file mode 100644 index 00000000000..b8f4db29118 --- /dev/null +++ b/tff_modular/master_files/code/modules/antagonists/cult/blood_magic.dm @@ -0,0 +1,66 @@ +/obj/item/melee/blood_magic/stun/proc/effect_vampire(mob/living/target, mob/living/carbon/user) + to_chat(user, span_userdanger("The spell violently reacts with [target], releasing a large burst of sanguine energy!"), type = MESSAGE_TYPE_COMBAT) + to_chat(target, span_userdanger("You're flung back by a violent burst of sanguine energy, as [user] attempts to hit you with ") + span_cult_large("the blood of the Traitor!"), type = MESSAGE_TYPE_COMBAT) + target.visible_message( + span_warning("[user] and [target] are violently flung back by a burst of sanguine energy!"), + ignored_mobs = list(user, target), + ) + + var/obj/effect/temp_visual/sanguine_boom/boom = new(user.loc) + + if(user.loc == target.loc) + boom.pixel_x = -32 + boom.pixel_y = -32 + else + var/dir = get_dir(user, target) + if(dir & NORTH) + boom.pixel_y = 32 + else if(dir & SOUTH) + boom.pixel_y = -32 + + if(dir & WEST) + boom.pixel_x = -32 + else if(dir & EAST) + boom.pixel_x = 32 + + // deactivate any active powers, to ensure the vampire can experience the full force of being flung away at mach fuck + var/datum/antagonist/vampire/vampire_datum = IS_VAMPIRE(target) + vampire_datum.disable_all_powers(forced = TRUE) + // they lose 25% of their current vitae too + vampire_datum.adjust_blood_volume(-vampire_datum.current_vitae * 0.25) + + // ensure they're not buckled to anything, you are NOT escaping this bullshit + user.buckled?.unbuckle_mob(user, force = TRUE) + target.buckled?.unbuckle_mob(target, force = TRUE) + + playsound(user, 'tff_modular/modules/vampire/sound/rage_increase.ogg', vol = 100, vary = FALSE, pressure_affected = FALSE) + + flash_color(user.client, LIGHT_COLOR_BLOOD_MAGIC, 2 SECONDS) + flash_color(target.client, LIGHT_COLOR_BLOOD_MAGIC, 2 SECONDS) + + // cultist gets a little bit of mercy to make it slightly more fair (they won't break an arm or something from the knockback) + ADD_TRAIT(user, TRAIT_NEVER_WOUNDED, REF(src)) + addtimer(TRAIT_CALLBACK_REMOVE(user, TRAIT_NEVER_WOUNDED, REF(src)), 2 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE) + + + var/turf/user_turf = get_turf(user) + var/turf/target_turf = get_turf(target) + + // CLASH! + user.blood_particles(10, get_angle(target, user)) + target.blood_particles(10, get_angle(user, target)) + + // this is gonna hurt for the both of them. + user.throw_at(get_edge_target_turf(user_turf, get_dir(target_turf, user_turf)), range = 200, speed = 5) + target.throw_at(get_edge_target_turf(target_turf, get_dir(user_turf, target_turf)), range = 200, speed = 5) + + // they're both a bit disoriented for a moment + target.set_confusion_if_lower(8 SECONDS) + target.set_eye_blur_if_lower(8 SECONDS) + user.set_confusion_if_lower(8 SECONDS) + user.set_eye_blur_if_lower(8 SECONDS) + +/obj/effect/temp_visual/sanguine_boom + icon = 'tff_modular/modules/vampire/icons/64x64.dmi' + icon_state = "sanguine_boom" + duration = 0.41 SECONDS diff --git a/tgstation.dme b/tgstation.dme index 3a5e08e412e..6bb03fb90a0 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -9649,6 +9649,8 @@ #include "tff_modular\master_files\code\datum\quirks\neutral_quirks\burr.dm" #include "tff_modular\master_files\code\game\objects\items\ammo\shotammo.dm" #include "tff_modular\master_files\code\game\objects\items\tools\weldingtool.dm" +#include "tff_modular\master_files\code\modules\antagonists\brainwashing\brainwashing.dm" +#include "tff_modular\master_files\code\modules\antagonists\cult\blood_magic.dm" #include "tff_modular\master_files\code\modules\cargo\markets\market_items\consumable.dm" #include "tff_modular\master_files\code\modules\cargo\markets\market_items\misc.dm" #include "tff_modular\master_files\code\modules\cargo\markets\market_items\weapons.dm" From 7457717b981e34a6de2dd8877774f41b2ad361a7 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Fri, 24 Apr 2026 11:35:37 +0300 Subject: [PATCH 122/149] =?UTF-8?q?=D1=83=D0=B4=D0=B0=D0=BB=D1=8F=D0=B5?= =?UTF-8?q?=D0=BC=20=D0=BE=D1=81=D1=82=D0=B0=D1=82=D0=BA=D0=B8=20=D0=B7?= =?UTF-8?q?=D0=BE=D0=BD=D1=82=D0=B8=D0=BA=D0=BE=D0=B2=20=D0=B8=20=D1=83?= =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D1=8C=D1=88=D0=B0=D0=B5=D0=BC=20=D1=88=D0=B0?= =?UTF-8?q?=D0=BD=D1=81=20=D1=81=D0=BF=D0=B0=D1=83=D0=BD=D0=B0=20=D0=BE?= =?UTF-8?q?=D1=82=D1=81=D0=BE=D1=81=D0=BD=D0=B8=D0=BA=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../greyscale/json_configs/_umbrella.json | 28 --- .../json_configs/_umbrella_inhand.json | 31 ---- config/dynamic.toml | 4 +- tff_modular/modules/vampire/dynamic.dm | 4 +- .../modules/vampire/objects/umbrellas.dm | 165 ------------------ tgstation.dme | 1 - 6 files changed, 4 insertions(+), 229 deletions(-) delete mode 100644 code/datums/greyscale/json_configs/_umbrella.json delete mode 100644 code/datums/greyscale/json_configs/_umbrella_inhand.json delete mode 100644 tff_modular/modules/vampire/objects/umbrellas.dm diff --git a/code/datums/greyscale/json_configs/_umbrella.json b/code/datums/greyscale/json_configs/_umbrella.json deleted file mode 100644 index 224aac4e6dd..00000000000 --- a/code/datums/greyscale/json_configs/_umbrella.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "umbrella_on": [ - { - "type": "icon_state", - "icon_state": "umbrella_on_handle", - "blend_mode": "overlay" - }, - { - "type": "icon_state", - "icon_state": "umbrella_on", - "blend_mode": "overlay", - "color_ids": [1] - } - ], - "umbrella": [ - { - "type": "icon_state", - "icon_state": "umbrella_handle", - "blend_mode": "overlay" - }, - { - "type": "icon_state", - "icon_state": "umbrella", - "blend_mode": "overlay", - "color_ids": [1] - } - ] -} diff --git a/code/datums/greyscale/json_configs/_umbrella_inhand.json b/code/datums/greyscale/json_configs/_umbrella_inhand.json deleted file mode 100644 index e8a0b8c4ccb..00000000000 --- a/code/datums/greyscale/json_configs/_umbrella_inhand.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "umbrella_closed": [ - { - "type": "icon_state", - "icon_state": "umbrella_closed", - "blend_mode": "overlay", - "color_ids": [1] - } - ], - "umbrella_on": [ - { - "type": "icon_state", - "icon_state": "umbrella_handle", - "blend_mode": "overlay" - }, - { - "type": "icon_state", - "icon_state": "umbrella_on", - "blend_mode": "overlay", - "color_ids": [1] - } - ], - "umbrella_on_BACK": [ - { - "type": "icon_state", - "icon_state": "umbrella_on_BACK", - "blend_mode": "overlay", - "color_ids": [1] - } - ] -} diff --git a/config/dynamic.toml b/config/dynamic.toml index 8f7e552c1b0..2eb46fa2853 100644 --- a/config/dynamic.toml +++ b/config/dynamic.toml @@ -701,7 +701,7 @@ repeatable = 0 minimum_required_age = 0 ["Vampire"] -weight = 10 +weight = 8 min_pop = 15 blacklisted_roles = [] min_antag_cap = 1 @@ -709,7 +709,7 @@ max_antag_cap.denominator = 24 minimum_required_age = 0 ["Vampiric Accident"] -weight = 10 +weight = 8 min_pop = 15 blacklisted_roles = [] min_antag_cap = 1 diff --git a/tff_modular/modules/vampire/dynamic.dm b/tff_modular/modules/vampire/dynamic.dm index 171e3da27ec..e7c78f5f5db 100644 --- a/tff_modular/modules/vampire/dynamic.dm +++ b/tff_modular/modules/vampire/dynamic.dm @@ -3,7 +3,7 @@ config_tag = "Vampire" pref_flag = ROLE_VAMPIRE preview_antag_datum = /datum/antagonist/vampire - weight = 10 + weight = 6 max_antag_cap = 4 min_pop = 15 @@ -22,7 +22,7 @@ preview_antag_datum = /datum/antagonist/vampire pref_flag = ROLE_VAMPIRIC_ACCIDENT midround_type = LIGHT_MIDROUND - weight = 10 + weight = 6 repeatable = TRUE max_antag_cap = 4 min_pop = 15 diff --git a/tff_modular/modules/vampire/objects/umbrellas.dm b/tff_modular/modules/vampire/objects/umbrellas.dm deleted file mode 100644 index 113f719315b..00000000000 --- a/tff_modular/modules/vampire/objects/umbrellas.dm +++ /dev/null @@ -1,165 +0,0 @@ -/* - * # Umbrellas! - * This file has code for umbrellas! - * Umbrellas you can hold, and open and close. - * Currently not coding for protecting against rain as ???I dont think??? rain exists. - * The rest don't and it just for looks. -/obj/item/umbrella - name = "umbrella" - desc = "A plain umbrella." - icon = 'tff_modular/modules/vampire/icons/umbrellas.dmi' - icon_state = "umbrella" - inhand_icon_state = "umbrella_closed" - lefthand_file = 'tff_modular/modules/vampire/icons/umbrellas_inhand_lh.dmi' - righthand_file = 'tff_modular/modules/vampire/icons/umbrellas_inhand_rh.dmi' - force = 5 - throwforce = 5 - w_class = WEIGHT_CLASS_SMALL - custom_materials = list(/datum/material/iron= SMALL_MATERIAL_AMOUNT * 0.5) - attack_verb_continuous = list("bludgeons", "whacks", "disciplines", "pummels") - attack_verb_simple = list("bludgeon", "whack", "discipline", "pummel") - drop_sound = 'tff_modular/modules/vampire/sound/wooden_drop.ogg' - pickup_sound = 'tff_modular/modules/vampire/sound/wooden_pickup.ogg' - hitsound = 'sound/items/weapons/genhit1.ogg' - - //open umbrella offsets for the inhands - var/open_x_offset = 2 - var/open_y_offset = 2 - - //Whether it's open or not - var/open = FALSE - - /// The sound effect played when our umbrella is opened - var/on_sound = 'sound/items/weapons/batonextend.ogg' - /// The inhand icon state used when our umbrella is opened. - var/on_inhand_icon_state = "umbrella_on" - - //greyscale stuff - greyscale_config = /datum/greyscale_config/umbrella - greyscale_config_inhand_left = /datum/greyscale_config/umbrella_inhand_left - greyscale_config_inhand_right = /datum/greyscale_config/umbrella_inhand_right - greyscale_colors = "#dddddd" - /// If the item should be assigned a random color - var/random_color = TRUE - /// List of possible random colors - var/static/list/umbrella_colors = list( - COLOR_BLUE, - COLOR_RED, - COLOR_PINK, - COLOR_BROWN, - COLOR_GREEN, - COLOR_CYAN, - COLOR_YELLOW, - COLOR_WHITE - ) - flags_1 = IS_PLAYER_COLORABLE_1 - -/obj/item/umbrella/Initialize(mapload) - . = ..() - if(random_color) - set_greyscale(colors = list(pick(umbrella_colors))) - AddComponent( \ - /datum/component/transforming, \ - force_on = 7, \ - hitsound_on = "sound/items/weapons/genhit1.ogg", \ - w_class_on = WEIGHT_CLASS_BULKY, \ - clumsy_check = FALSE, \ - attack_verb_continuous_on = list("swooshes", "whacks", "fwumps"), \ - attack_verb_simple_on = list("swoosh", "whack", "fwump"), \ - ) - RegisterSignal(src, COMSIG_TRANSFORMING_ON_TRANSFORM, PROC_REF(on_transform)) - -/obj/item/umbrella/worn_overlays(mutable_appearance/standing, isinhands) - . = ..() - if(!isinhands) - return - var/mob/holder = loc - if(open) - if(ISODD(holder.get_held_index_of_item(src))) //left hand or right hand? - . += mutable_appearance(lefthand_file, inhand_icon_state + "_BACK", BELOW_MOB_LAYER) - else - . += mutable_appearance(righthand_file, inhand_icon_state + "_BACK", BELOW_MOB_LAYER) - - -/obj/item/umbrella/proc/on_transform(obj/item/source, mob/user, active) - SIGNAL_HANDLER - inhand_icon_state = active ? on_inhand_icon_state : inhand_icon_state - open = active - if(user) - balloon_alert(user, active ? "opened" : "closed") - if(active) - ADD_TRAIT(user, TRAIT_SHADED, REF(src)) - else - REMOVE_TRAIT(user, TRAIT_SHADED, REF(src)) - playsound(src, on_sound, 50, TRUE) - return COMPONENT_NO_DEFAULT_MESSAGE - -/obj/item/umbrella/pickup(mob/user) - . = ..() - RegisterSignal(user, COMSIG_ATOM_DIR_CHANGE, PROC_REF(on_dir_change)) - if(open) - ADD_TRAIT(user, TRAIT_SHADED, REF(src)) - -/obj/item/umbrella/dropped(mob/user, silent) - . = ..() - REMOVE_TRAIT(user, TRAIT_SHADED, REF(src)) - UnregisterSignal(user, COMSIG_ATOM_DIR_CHANGE) - -/obj/item/umbrella/proc/on_dir_change(mob/living/carbon/owner, olddir, newdir) - SIGNAL_HANDLER - owner.update_held_items() - -/obj/item/umbrella/get_worn_offsets(isinhands) - . = ..() - var/mob/holder = loc - if(open) - .[2] += open_y_offset - switch(loc.dir) - if(NORTH) - .[1] += ISODD(holder.get_held_index_of_item(src)) ? -open_x_offset : open_x_offset - if(SOUTH) - .[1] += ISODD(holder.get_held_index_of_item(src)) ? open_x_offset : -open_x_offset - if(EAST) - .[1] -= open_x_offset - if(WEST) - .[1] += open_x_offset - - - -//other umbrellas - -/obj/item/umbrella/parasol - name = "parasol" - desc = "A black laced parsol, how intricate." - icon_state = "parasol" - inhand_icon_state = "parasol_closed" - on_inhand_icon_state = "parasol_on" - random_color = FALSE - greyscale_config = null - greyscale_config_inhand_left = null - greyscale_config_inhand_right = null - -/datum/crafting_recipe/umbrella - name = "Umbrella" - result = /obj/item/umbrella - reqs = list( - /obj/item/stack/sheet/cloth = 3, - /obj/item/stack/rods = 1, - ) - tool_behaviors = list(TOOL_CROWBAR) - time = 5 SECONDS - category = CAT_EQUIPMENT - crafting_flags = CRAFT_SKIP_MATERIALS_PARITY | CRAFT_MUST_BE_LEARNED - -/datum/crafting_recipe/umbrella_parasol - name = "Umbrella Parasol" - result = /obj/item/umbrella/parasol - reqs = list( - /obj/item/stack/sheet/cloth = 3, - /obj/item/stack/rods = 1, - ) - tool_behaviors = list(TOOL_CROWBAR, TOOL_WRENCH) - time = 10 SECONDS - category = CAT_EQUIPMENT - crafting_flags = CRAFT_SKIP_MATERIALS_PARITY | CRAFT_MUST_BE_LEARNED -*/ diff --git a/tgstation.dme b/tgstation.dme index 6bb03fb90a0..e180774b5df 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -9907,7 +9907,6 @@ #include "tff_modular\modules\vampire\objects\coffin.dm" #include "tff_modular\modules\vampire\objects\hunter_gear.dm" #include "tff_modular\modules\vampire\objects\kindred.dm" -#include "tff_modular\modules\vampire\objects\umbrellas.dm" #include "tff_modular\modules\vampire\objects\vassal_rack.dm" #include "tff_modular\modules\vampire\powers\_power.dm" #include "tff_modular\modules\vampire\powers\_targeted.dm" From ef729772dab7fd8081d42c57235a623d03834c26 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Fri, 24 Apr 2026 11:38:33 +0300 Subject: [PATCH 123/149] =?UTF-8?q?=D0=BA=D0=BE=D0=BC=D1=83=20=D1=82=D1=8B?= =?UTF-8?q?=20=D0=BD=D1=83=D0=B6=D0=B5=D0=BD,=20=D0=B2=D0=BE=D1=82=20?= =?UTF-8?q?=D1=82=D1=8B,=20=D0=B2=D0=B0=D0=BC=D0=BF=D0=B0=D0=B9=D1=80=20?= =?UTF-8?q?=D1=85=D0=B0=D0=BD=D1=82=D0=B5=D1=80=20=D0=B3=D0=B0=D1=80=D0=B1?= =?UTF-8?q?,=20=D0=BA=D0=BE=D0=BC=D1=83=20=D1=82=D1=8B=20=D0=BD=D1=83?= =?UTF-8?q?=D0=B6=D0=B5=D0=BD...?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modules/vampire/objects/hunter_gear.dm | 44 +------------------ 1 file changed, 1 insertion(+), 43 deletions(-) diff --git a/tff_modular/modules/vampire/objects/hunter_gear.dm b/tff_modular/modules/vampire/objects/hunter_gear.dm index 7039e84bd43..48a2dbda36b 100644 --- a/tff_modular/modules/vampire/objects/hunter_gear.dm +++ b/tff_modular/modules/vampire/objects/hunter_gear.dm @@ -1,45 +1,3 @@ -/obj/item/clothing/suit/armor/vamphunter - name = "vampire hunter garb" - desc = "This worn outfit saw much use back in the day. Internal reinforcements help protect against bites and scratches." - allowed = list( - /obj/item/book/bible, - /obj/item/book/kindred, - /obj/item/food/garlic_kimchi, - /obj/item/food/garlicbread, - /obj/item/food/grown/garlic, - /obj/item/reagent_containers/cup/glass/bottle/holywater, - /obj/item/stake, - ) - icon = 'tff_modular/modules/vampire/icons/vamp_obj.dmi' - worn_icon = 'tff_modular/modules/vampire/icons/worn.dmi' - icon_state = "monsterhunter" - inhand_icon_state = null - body_parts_covered = CHEST|GROIN|LEGS|ARMS - armor_type = /datum/armor/jacket_curator - strip_delay = 8 SECONDS - equip_delay_other = 6 SECONDS - -/datum/armor/jacket_curator - melee = 25 - bullet = 10 - laser = 25 - energy = 10 - acid = 45 - wound = 10 - -/obj/item/clothing/head/helmet/vamphunter_hat - name = "vampire hunter hat" - desc = "This hat saw much use back in the day." - icon = 'tff_modular/modules/vampire/icons/vamp_obj.dmi' - worn_icon = 'tff_modular/modules/vampire/icons/worn.dmi' - icon_state = "monsterhunterhat" - inhand_icon_state = null - flags_cover = HEADCOVERSEYES - flags_inv = HIDEEYES - armor_type = /datum/armor/jacket_curator - strip_delay = 8 SECONDS - dog_fashion = null - /obj/item/stake name = "wooden stake" desc = "A simple wooden stake carved to a sharp point." @@ -64,7 +22,7 @@ /datum/embedding/stake embed_chance = 100 fall_chance = 0 - rip_time = 2.5 SECONDS + rip_time = 5 SECONDS /obj/item/stake/attack(mob/living/target, mob/living/user, params) . = ..() From c742bd7c4066ad7ac60cd8a6770f6ff319264da0 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sun, 26 Apr 2026 00:20:47 +0300 Subject: [PATCH 124/149] =?UTF-8?q?=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D1=8F?= =?UTF-8?q?=D0=B5=D0=BC=20=D0=BD=D0=B0=D0=B7=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=20=D0=B4=D0=B0=D0=B1=D1=8B=20=D0=B8=D0=B7=D0=B1=D0=B5=D0=B6?= =?UTF-8?q?=D0=B0=D1=82=D1=8C=20=D0=BC=D0=B5=D1=80=D0=B4=D0=B6=D0=BA=D0=BE?= =?UTF-8?q?=D0=BD=D1=84=D0=BB=D0=B8=D0=BA=D1=82=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/__DEFINES/~ff_defines/{bloodsucker.dm => vampire.dm} | 0 tgstation.dme | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename code/__DEFINES/~ff_defines/{bloodsucker.dm => vampire.dm} (100%) diff --git a/code/__DEFINES/~ff_defines/bloodsucker.dm b/code/__DEFINES/~ff_defines/vampire.dm similarity index 100% rename from code/__DEFINES/~ff_defines/bloodsucker.dm rename to code/__DEFINES/~ff_defines/vampire.dm diff --git a/tgstation.dme b/tgstation.dme index e180774b5df..8ffad63b833 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -424,7 +424,6 @@ #include "code\__DEFINES\traits\macros.dm" #include "code\__DEFINES\traits\sources.dm" #include "code\__DEFINES\~ff_defines\barsigns.dm" -#include "code\__DEFINES\~ff_defines\bloodsucker.dm" #include "code\__DEFINES\~ff_defines\DNA.dm" #include "code\__DEFINES\~ff_defines\dynamic.dm" #include "code\__DEFINES\~ff_defines\flavor_misc.dm" @@ -435,6 +434,7 @@ #include "code\__DEFINES\~ff_defines\span.dm" #include "code\__DEFINES\~ff_defines\techweb_nodes.dm" #include "code\__DEFINES\~ff_defines\text.dm" +#include "code\__DEFINES\~ff_defines\vampire.dm" #include "code\__DEFINES\~ff_defines\vv.dm" #include "code\__DEFINES\~ff_defines\_globalvars\logging.dm" #include "code\__DEFINES\~ff_defines\_globalvars\lists\blooper.dm" From 683f7260c90791516a1117a7642acee11547431c Mon Sep 17 00:00:00 2001 From: Ruslanllll <86971528+Ruslanllll@users.noreply.github.com> Date: Mon, 27 Apr 2026 14:52:52 +0300 Subject: [PATCH 125/149] =?UTF-8?q?=D0=9E=D1=87=D0=B5=D0=BD=D1=8C=20=D0=BC?= =?UTF-8?q?=D0=B0=D0=BB=D0=B5=D0=BD=D1=8C=D0=BA=D0=B0=D1=8F=20=D1=87=D0=B8?= =?UTF-8?q?=D1=81=D1=82=D0=BA=D0=B0=20=D0=BA=D0=BE=D0=B4=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Copilot --- code/__DEFINES/~ff_defines/vampire.dm | 15 ------------- code/modules/admin/sql_ban_system.dm | 3 +++ .../modules/vampire/clans/malkavian.dm | 2 +- tff_modular/modules/vampire/datum_vampire.dm | 4 ++-- tff_modular/modules/vampire/dynamic.dm | 2 ++ .../modules/vampire/misc_procs_vampire.dm | 21 +------------------ .../modules/vampire/objects/candelabrum.dm | 2 +- .../modules/vampire/objects/vassal_rack.dm | 2 +- tff_modular/modules/vampire/powers/_power.dm | 4 ++-- .../modules/vampire/powers/celerity/haste.dm | 2 +- tff_modular/modules/vampire/powers/feed.dm | 4 ++-- tff_modular/modules/vampire/powers/gohome.dm | 2 +- .../modules/vampire/powers/potence/lunge.dm | 2 +- .../vampire/powers/presence/entrance.dm | 2 +- .../powers/presence/force_of_personality.dm | 2 +- .../modules/vampire/powers/presence/summon.dm | 2 +- .../vampire/vassals/powers/recuperate.dm | 4 ++-- 17 files changed, 23 insertions(+), 52 deletions(-) diff --git a/code/__DEFINES/~ff_defines/vampire.dm b/code/__DEFINES/~ff_defines/vampire.dm index 887d390fa17..3da63f50d24 100644 --- a/code/__DEFINES/~ff_defines/vampire.dm +++ b/code/__DEFINES/~ff_defines/vampire.dm @@ -228,21 +228,6 @@ #define LANGUAGE_VAMPIRE "vampire" #define LANGUAGE_VASSAL "vassal" -/// Similar to turf.get_lumcount(), but it checks for soft lighting first, and just assumes the lumcount is 0 if it is. -#define GET_SIMPLE_LUMCOUNT(turf) (turf.is_softly_lit() ? 0 : turf.get_lumcount()) - -//Incapacitated status effect flags -/// If the incapacitated status effect will ignore a mob in restraints (handcuffs) -#define IGNORE_RESTRAINTS (1<<0) -/// If the incapacitated status effect will ignore a mob in stasis (stasis beds) -#define IGNORE_STASIS (1<<1) -/// If the incapacitated status effect will ignore a mob being agressively grabbed -#define IGNORE_GRAB (1<<2) -/// If the incapacited status effect will ignore a mob in softcrit -#define IGNORE_SOFTCRIT (1<<3) -#define IS_SAFE_NUM(a) IS_FINITE(a) - -#define BODY_ZONES_LIMBS list(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) #define MOVABLE_PHYSICS_PRECISION 0.01 #define MOVABLE_PHYSICS_MINIMAL_VELOCITY 1 diff --git a/code/modules/admin/sql_ban_system.dm b/code/modules/admin/sql_ban_system.dm index 010bfdea7b0..cc7f34ffbb2 100644 --- a/code/modules/admin/sql_ban_system.dm +++ b/code/modules/admin/sql_ban_system.dm @@ -407,6 +407,9 @@ ROLE_BORER, ROLE_ASSAULT_OPERATIVE, // NOVA EDIT ADDITION END + // FLUFFY FRONTIER ADDITION START + ROLE_VAMPIRE, + // FLUFFY FRONTIER ADDITION END ), // NOVA EDIT ADDITION START - EXTRA_BANS "Nova Ban Options" = list( diff --git a/tff_modular/modules/vampire/clans/malkavian.dm b/tff_modular/modules/vampire/clans/malkavian.dm index 304c04dda52..4f25c382386 100644 --- a/tff_modular/modules/vampire/clans/malkavian.dm +++ b/tff_modular/modules/vampire/clans/malkavian.dm @@ -203,7 +203,7 @@ /obj/effect/client_image_holder/phobetor/proc/check_location_seen(atom/subject, turf/target_turf) if(!isturf(target_turf)) return FALSE - if(GET_SIMPLE_LUMCOUNT(target_turf) <= 0.2) + if(target_turf.get_lumcount() <= 0.2) return FALSE for(var/mob/living/nearby_viewers in viewers(target_turf) - subject) if(!nearby_viewers.mind || !nearby_viewers.client || nearby_viewers.client?.is_afk()) diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index 416cbbce21f..8e77fc320ba 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -779,7 +779,7 @@ if(initial(new_limb.burn_modifier) < 1) new_limb.burn_modifier /= initial(new_limb.burn_modifier) - if(new_limb.body_zone in BODY_ZONES_LIMBS) + if(new_limb.body_zone in GLOB.limb_zones) var/obj/item/bodypart/user_left_hand = owner.get_bodypart(BODY_ZONE_L_ARM) var/obj/item/bodypart/user_right_hand = owner.get_bodypart(BODY_ZONE_R_ARM) user_left_hand.unarmed_damage_low = 5 + current_damage_bonus @@ -798,7 +798,7 @@ if(initial(lost_limb.burn_modifier) < 1) lost_limb.burn_modifier *= initial(lost_limb.burn_modifier) - if(lost_limb.body_zone in BODY_ZONES_LIMBS) + if(lost_limb.body_zone in GLOB.limb_zones) // safety measure in case we ever accidentally fuck up the math or something lost_limb.unarmed_damage_low = max(lost_limb.unarmed_damage_low - current_damage_bonus, initial(lost_limb.unarmed_damage_low)) lost_limb.unarmed_damage_high = max(lost_limb.unarmed_damage_high - current_damage_bonus, initial(lost_limb.unarmed_damage_high)) diff --git a/tff_modular/modules/vampire/dynamic.dm b/tff_modular/modules/vampire/dynamic.dm index e7c78f5f5db..15e97837c7d 100644 --- a/tff_modular/modules/vampire/dynamic.dm +++ b/tff_modular/modules/vampire/dynamic.dm @@ -21,6 +21,7 @@ config_tag = "Vampiric Accident" preview_antag_datum = /datum/antagonist/vampire pref_flag = ROLE_VAMPIRIC_ACCIDENT + jobban_flag = ROLE_VAMPIRE midround_type = LIGHT_MIDROUND weight = 6 repeatable = TRUE @@ -41,6 +42,7 @@ config_tag = "Vampiric LateJoin" preview_antag_datum = /datum/antagonist/vampire pref_flag = ROLE_VAMPIRE_LATEJOIN + jobban_flag = ROLE_VAMPIRE weight = 10 repeatable = TRUE max_antag_cap = 4 diff --git a/tff_modular/modules/vampire/misc_procs_vampire.dm b/tff_modular/modules/vampire/misc_procs_vampire.dm index 72279ba689c..55c0fef6a39 100644 --- a/tff_modular/modules/vampire/misc_procs_vampire.dm +++ b/tff_modular/modules/vampire/misc_procs_vampire.dm @@ -398,7 +398,7 @@ /proc/get_zoomed_view(view, zoom_amt) var/view_x var/view_y - if(IS_SAFE_NUM(view)) + if(IS_FINITE(view)) return view + zoom_amt else var/list/viewrangelist = splittext(view, "x") @@ -420,25 +420,6 @@ "jumpsuit_style" = jumpsuit_style, ) -/mob/proc/incapacitated(flags) - return - -/mob/living/incapacitated(flags) - if(!(flags & IGNORE_RESTRAINTS) && HAS_TRAIT(src, TRAIT_RESTRAINED)) - return TRUE - if(!(flags & IGNORE_GRAB) && pulledby?.grab_state >= GRAB_AGGRESSIVE) - return TRUE - if(!(flags & IGNORE_STASIS) && HAS_TRAIT(src, TRAIT_STASIS)) - return TRUE - - if(flags & IGNORE_SOFTCRIT) - if((stat <= SOFT_CRIT) && !(HAS_TRAIT_NOT_FROM(src, TRAIT_INCAPACITATED, STAT_TRAIT))) - return FALSE - - if(HAS_TRAIT(src, TRAIT_INCAPACITATED)) - return TRUE - - return FALSE /mob/living/proc/blood_particles(amount = rand(1, 3), angle = rand(0,360), min_deviation = -30, max_deviation = 30, min_pixel_z = 0, max_pixel_z = 6) if(QDELETED(src) || !isturf(loc) || !blood_volume || HAS_TRAIT(src, TRAIT_NOBLOOD)) diff --git a/tff_modular/modules/vampire/objects/candelabrum.dm b/tff_modular/modules/vampire/objects/candelabrum.dm index 621ceb488cb..ec63f5a2ceb 100644 --- a/tff_modular/modules/vampire/objects/candelabrum.dm +++ b/tff_modular/modules/vampire/objects/candelabrum.dm @@ -121,7 +121,7 @@ /obj/structure/vampire/candelabrum/proc/distance_toggle(datum/source, atom/location, control, params, mob/user) SIGNAL_HANDLER - if(!anchored || user.incapacitated() || user.get_active_held_item() || !IS_VAMPIRE(user) || user.Adjacent(src)) + if(!anchored || user.incapacitated || user.get_active_held_item() || !IS_VAMPIRE(user) || user.Adjacent(src)) return var/list/modifiers = params2list(params) user.balloon_alert_to_viewers("gestures dramatically") diff --git a/tff_modular/modules/vampire/objects/vassal_rack.dm b/tff_modular/modules/vampire/objects/vassal_rack.dm index 2aad53d815e..c0f12163745 100644 --- a/tff_modular/modules/vampire/objects/vassal_rack.dm +++ b/tff_modular/modules/vampire/objects/vassal_rack.dm @@ -52,7 +52,7 @@ to_chat(user, span_announce("* Vampire Tip: Examine the vassal rack to understand how it functions!")) return // Default checks - if(!isliving(living_target) || !living_target.Adjacent(src) || living_target == user || !isliving(user) || has_buckled_mobs() || user.incapacitated() || living_target.buckled) + if(!isliving(living_target) || !living_target.Adjacent(src) || living_target == user || !isliving(user) || has_buckled_mobs() || user.incapacitated || living_target.buckled) return // Don't buckle Silicon to it please. if(issilicon(living_target)) diff --git a/tff_modular/modules/vampire/powers/_power.dm b/tff_modular/modules/vampire/powers/_power.dm index 7cb3994579e..2b12c218344 100644 --- a/tff_modular/modules/vampire/powers/_power.dm +++ b/tff_modular/modules/vampire/powers/_power.dm @@ -228,14 +228,14 @@ /datum/action/cooldown/vampire/proc/check_witnesses(mob/living/target) var/turf/our_turf = get_turf(owner) var/turf/target_turf = get_turf(target) - var/min_darkness = target_turf ? min(GET_SIMPLE_LUMCOUNT(our_turf), GET_SIMPLE_LUMCOUNT(target_turf)) : GET_SIMPLE_LUMCOUNT(our_turf) + var/min_darkness = target_turf ? min(our_turf.get_lumcount(), target_turf.get_lumcount()) : our_turf.get_lumcount() var/is_dark = min_darkness <= 0.2 for(var/mob/living/watcher in oviewers(6, owner) - target) if(!vampiredatum_power.is_masq_watcher(watcher)) continue if(is_dark && !watcher.Adjacent(owner) && (!target || !watcher.Adjacent(target))) continue - if(!watcher.incapacitated(IGNORE_RESTRAINTS)) + if(!INCAPACITATED_IGNORING(watcher, INCAPABLE_RESTRAINTS)) watcher.face_atom(owner) watcher.do_alert_animation(watcher) diff --git a/tff_modular/modules/vampire/powers/celerity/haste.dm b/tff_modular/modules/vampire/powers/celerity/haste.dm index 98d67bf4bea..2d4aab86bfd 100644 --- a/tff_modular/modules/vampire/powers/celerity/haste.dm +++ b/tff_modular/modules/vampire/powers/celerity/haste.dm @@ -83,7 +83,7 @@ break //just stop else consequetive_failures = 0 //reset so we can keep moving - if(user.resting || user.incapacitated(IGNORE_RESTRAINTS | IGNORE_GRAB) && level_current < 3) //actually down? stop. + if(user.resting || INCAPACITATED_IGNORING(user, INCAPABLE_RESTRAINTS | INCAPABLE_GRAB) && level_current < 3) //actually down? stop. break if(success) //don't sleep if we failed to move. sleep(world.tick_lag) diff --git a/tff_modular/modules/vampire/powers/feed.dm b/tff_modular/modules/vampire/powers/feed.dm index 70318826148..6d10d425585 100644 --- a/tff_modular/modules/vampire/powers/feed.dm +++ b/tff_modular/modules/vampire/powers/feed.dm @@ -72,7 +72,7 @@ if(currently_feeding) var/turf/our_turf = get_turf(owner) var/turf/target_turf = get_turf(target) - var/is_dark = min(GET_SIMPLE_LUMCOUNT(our_turf), GET_SIMPLE_LUMCOUNT(target_turf)) <= 0.2 + var/is_dark = min(our_turf.get_lumcount(), target_turf.get_lumcount()) <= 0.2 var/notice_range = silent_feed ? FEED_SILENT_NOTICE_RANGE : FEED_LOUD_NOTICE_RANGE var/list/potential_watchers = oviewers(notice_range, target) | oviewers(notice_range, owner) @@ -82,7 +82,7 @@ if(is_dark && !watcher.Adjacent(owner) && !watcher.Adjacent(target)) continue - if(!watcher.incapacitated(IGNORE_RESTRAINTS)) + if(!INCAPACITATED_IGNORING(watcher, INCAPABLE_RESTRAINTS)) watcher.face_atom(owner) watcher.do_alert_animation(watcher) to_chat(watcher, span_warning("[owner] is biting [target]'s neck!"), type = MESSAGE_TYPE_WARNING) diff --git a/tff_modular/modules/vampire/powers/gohome.dm b/tff_modular/modules/vampire/powers/gohome.dm index 91040ab8cff..4066f349a4e 100644 --- a/tff_modular/modules/vampire/powers/gohome.dm +++ b/tff_modular/modules/vampire/powers/gohome.dm @@ -67,7 +67,7 @@ /datum/action/cooldown/vampire/gohome/proc/teleport_to_coffin(mob/living/carbon/user) var/turf/current_turf = get_turf(owner) // If we aren't in the dark, anyone watching us will cause us to drop out stuff - if(GET_SIMPLE_LUMCOUNT(current_turf) >= 0.2) + if(current_turf.get_lumcount() >= 0.2) for(var/mob/living/watcher in oviewers(world.view, get_turf(owner)) - owner) if(vampiredatum_power.is_masq_watcher(watcher)) user.unequip_everything() diff --git a/tff_modular/modules/vampire/powers/potence/lunge.dm b/tff_modular/modules/vampire/powers/potence/lunge.dm index 58734e8403f..f99884ed74f 100644 --- a/tff_modular/modules/vampire/powers/potence/lunge.dm +++ b/tff_modular/modules/vampire/powers/potence/lunge.dm @@ -145,7 +145,7 @@ // check_witnesses(target) // Did I slip or get knocked unconscious? - if(user.body_position != STANDING_UP || user.incapacitated()) + if(user.body_position != STANDING_UP || user.incapacitated) var/send_dir = get_dir(user, target_turf) new /datum/forced_movement(user, get_ranged_target_turf(user, send_dir, 1), 1, FALSE) user.spin(1 SECONDS) diff --git a/tff_modular/modules/vampire/powers/presence/entrance.dm b/tff_modular/modules/vampire/powers/presence/entrance.dm index fa6615b9d8c..7c9de01740f 100644 --- a/tff_modular/modules/vampire/powers/presence/entrance.dm +++ b/tff_modular/modules/vampire/powers/presence/entrance.dm @@ -81,7 +81,7 @@ alert_type = /atom/movable/screen/alert/status_effect/entranced /datum/status_effect/entranced/on_creation(mob/living/new_owner, set_duration) - if(IS_SAFE_NUM(set_duration)) + if(IS_FINITE(set_duration)) duration = set_duration if(HAS_MIND_TRAIT(new_owner, TRAIT_MINDSHIELD)) duration /= 2 diff --git a/tff_modular/modules/vampire/powers/presence/force_of_personality.dm b/tff_modular/modules/vampire/powers/presence/force_of_personality.dm index 5356ce85ce6..b80ecbc83b7 100644 --- a/tff_modular/modules/vampire/powers/presence/force_of_personality.dm +++ b/tff_modular/modules/vampire/powers/presence/force_of_personality.dm @@ -82,7 +82,7 @@ qdel(src) return - if(owner.incapacitated(IGNORE_RESTRAINTS)) + if(INCAPACITATED_IGNORING(owner, INCAPABLE_RESTRAINTS)) return // Only check if we're within range of the vampire diff --git a/tff_modular/modules/vampire/powers/presence/summon.dm b/tff_modular/modules/vampire/powers/presence/summon.dm index ea6e7ce93ad..e6262bc7678 100644 --- a/tff_modular/modules/vampire/powers/presence/summon.dm +++ b/tff_modular/modules/vampire/powers/presence/summon.dm @@ -95,7 +95,7 @@ var/step_delay = 1.5 SECONDS /datum/status_effect/summoned/on_creation(mob/living/new_owner, set_duration, mob/living/vampire) - if(IS_SAFE_NUM(set_duration)) + if(IS_FINITE(set_duration)) duration = set_duration source_vampire = vampire return ..() diff --git a/tff_modular/modules/vampire/vassals/powers/recuperate.dm b/tff_modular/modules/vampire/vassals/powers/recuperate.dm index 34afe08522d..53f02aeb296 100644 --- a/tff_modular/modules/vampire/vassals/powers/recuperate.dm +++ b/tff_modular/modules/vampire/vassals/powers/recuperate.dm @@ -17,7 +17,7 @@ if(!.) return FALSE - if(owner.stat >= DEAD || owner.incapacitated(IGNORE_RESTRAINTS)) + if(owner.stat >= DEAD || INCAPACITATED_IGNORING(owner, INCAPABLE_RESTRAINTS)) owner.balloon_alert(owner, "you are incapacitated...") return FALSE @@ -68,7 +68,7 @@ /datum/action/cooldown/vampire/recuperate/continue_active() if(QDELETED(owner) || owner.stat == DEAD) return FALSE - if(owner.incapacitated(IGNORE_RESTRAINTS)) + if(INCAPACITATED_IGNORING(owner, INCAPABLE_RESTRAINTS)) owner.balloon_alert(owner, "too exhausted...") return FALSE return TRUE From d9f0bf3d158ac028f5d77f764c1a7b61a78cd1f9 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Mon, 27 Apr 2026 18:17:36 +0300 Subject: [PATCH 126/149] =?UTF-8?q?=D0=A7=D0=B8=D1=81=D1=82=D0=B8=D0=BC=20?= =?UTF-8?q?=D0=B4=D0=B5=D1=84=D0=B0=D0=B9=D0=BD=D1=8B,=20=D0=B4=D0=B5?= =?UTF-8?q?=D0=BB=D0=B0=D0=B5=D0=BC=20=D0=BD=D0=B5=D0=BA=D0=BE=D1=82=D0=BE?= =?UTF-8?q?=D1=80=D1=8B=D0=B5=20=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8=20?= =?UTF-8?q?=D0=B1=D0=B0=D0=BB=D0=B0=D0=BD=D1=81=D0=B0,=20=D0=B4=D0=B0?= =?UTF-8?q?=D0=B5=D0=BC=20=D0=BF=D0=BE=D0=B4=D1=81=D0=BA=D0=B0=D0=B7=D0=BA?= =?UTF-8?q?=D1=83=20=D0=BF=D0=BE=20=D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D1=8C?= =?UTF-8?q?=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8E=20=D0=BA=D0=BD=D0=B8?= =?UTF-8?q?=D0=B3=D0=B8=20=D0=B8=20=D1=83=D0=B1=D0=B8=D1=80=D0=B0=D0=B5?= =?UTF-8?q?=D0=BC=20=D0=BA=D0=BE=D0=BC=D0=BF=D0=BE=D0=BD=D0=B5=D0=BD=D1=82?= =?UTF-8?q?=20stationloving?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/__DEFINES/~ff_defines/vampire.dm | 176 +++++++++--------- .../modules/vampire/clans/malkavian.dm | 2 +- tff_modular/modules/vampire/life_vampire.dm | 1 + .../modules/vampire/objects/kindred.dm | 5 +- .../vampire/powers/presence/entrance.dm | 8 +- .../vampire/powers/presence/presence.dm | 6 +- .../modules/vampire/vassals/datum_vassal.dm | 14 +- 7 files changed, 107 insertions(+), 105 deletions(-) diff --git a/code/__DEFINES/~ff_defines/vampire.dm b/code/__DEFINES/~ff_defines/vampire.dm index 3da63f50d24..d9bc99129cb 100644 --- a/code/__DEFINES/~ff_defines/vampire.dm +++ b/code/__DEFINES/~ff_defines/vampire.dm @@ -1,30 +1,49 @@ -/// From base of /mob/living/simple_animal/attack_hand() and /mob/living/basic/attack_hand() when petting (non-combat): (mob/living/pet) -#define COMSIG_LIVING_PET_ANIMAL "living_pet_animal" -/// From base of /datum/element/art when appraising art: (atom/art_piece) -#define COMSIG_LIVING_APPRAISE_ART "living_appraise_art" -/// Source trait while Feeding -#define FEED_TRAIT "feed_trait" +/// Traits /// Hides TRAIT_GENELESS if it's only from the same sources as TRAIT_FAKEGENES. #define TRAIT_FAKEGENES "fakegenes" -/// You have special interactions with vampires and the occult. -#define TRAIT_OCCULTIST "occultist" /// The user is "vampire aligned" - i.e a vampire or vassal. /// Basically just check for `HAS_MIND_TRAIT(user, TRAIT_VAMPIRE_ALIGNED)` instead of `IS_VAMPIRE(user) || IS_VASSAL(user)` #define TRAIT_VAMPIRE_ALIGNED "vampire_aligned" +/// Falsifies Health analyzer blood levels +#define TRAIT_MASQUERADE "masquerade" +/// For people in the middle of being staked +#define TRAIT_BEINGSTAKED "beingstaked" +/// This vampire is currently in a frenzy, +#define TRAIT_FRENZY "frenzy" +/// This vampire is currently in torpor. +#define TRAIT_TORPOR "torpor" +/// This vampire can tell if another vampire has committed diablere on examine. +#define TRAIT_SEE_DIABLERIE "see_diablerie" + +/// Sources +/// Source trait while Feeding +#define FEED_TRAIT "feed_trait" +/// Source trait for all vampire traits +#define TRAIT_VAMPIRE "trait_vampire" + +/// Roles +#define ROLE_VAMPIRE "Vampire" +#define ROLE_VAMPIRIC_ACCIDENT "Vampiric Accident" +#define ROLE_VAMPIRE_LATEJOIN "Vampire LateJoin" + +/// Do After #define DOAFTER_SOURCE_PERSUASION_RACK "doafter_persuasion_rack" -/// Checks if the given mob is a vampire -#define IS_VAMPIRE(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/vampire)) -/// Checks if the given mob is a vassal -#define IS_VASSAL(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/vassal)) -#define CAT_VAMPIRE "Vampire" #define DOAFTER_SOURCE_ARCHIVE_OF_THE_KINDRED "doafter_archive_of_the_kindred" -/// This area can always be claimed as a vampire lair regardless of Z-level and such -#define ALWAYS_VALID_VAMPIRE_LAIR (1<<21) + +/// Log Category +/// Logging for vampire powers unlocked. +/proc/log_vampire_power(text, list/data) + logger.Log(LOG_CATEGORY_UPLINK_VAMPIRE, text, data) + #define LOG_CATEGORY_UPLINK_VAMPIRE "uplink-vampire" + +/// Misc +#define CAT_VAMPIRE "Vampire" #define FACTION_VAMPIRE "Vampire" -#define ROLE_VAMPIRE "Vampire" -#define ROLE_VAMPIRIC_ACCIDENT "Vampiric Accident" -#define ROLE_VAMPIRE_LATEJOIN "Vampire LateJoin" +#define LANGUAGE_VAMPIRE "vampire" +#define LANGUAGE_VASSAL "vassal" +#define CLIENT_COLOR_SOURCE_VAMPIRE "client_color_source_vampire" +#define ui_team_finder "CENTER,CENTER" #define BLOODSUCKER_RESTRICTED_SPECIES list( \ /datum/species/synthetic, \ /datum/species/plasmaman, \ @@ -43,7 +62,6 @@ /datum/species/ethereal, \ /datum/species/abductor/abductorweak \ ) -#define span_awe(str) ("" + str + "") /// Uncomment this to enable testing of Vampire features (such as vassalizing people with a mind instead of a client). //#define VAMPIRE_TESTING #if defined(VAMPIRE_TESTING) && defined(CIBUILDING) @@ -70,10 +88,12 @@ #define DIABLERIE_DIVISOR 1.5 /// Amount of vitae drunk from another player required to level up. #define VITAE_GOAL_STANDARD 200 +/// When do we warn them about their low blood? +#define VAMPIRE_LOW_BLOOD_WARNING 300 +/// Stats Defines /// Default amount of damage the vampire's punch/kick damage increases with each level. -#define VAMPIRE_UNARMED_DMG_INCREASE_ON_RANKUP 0.5 - +#define VAMPIRE_UNARMED_DMG_INCREASE_ON_RANKUP 0.75 /// How many starting levels do we want each one to have? #define VAMPIRE_STARTING_LEVELS 3 /// How many free levels the vampire gets gradually. @@ -81,9 +101,13 @@ /// Vampire's default stamina resist. #define VAMPIRE_INHERENT_STAMINA_RESIST 0.75 -/// When do we warn them about their low blood? -#define VAMPIRE_LOW_BLOOD_WARNING 300 +/// Humanity defines +/// Default Humanity +#define VAMPIRE_DEFAULT_HUMANITY 7 +// Masquerade ability given at this point or above +#define VAMPIRE_HUMANITY_MASQUERADE_POWER 7 +/// Oozeling Defines, currently not used /// Minimum blood required for vampires oozelings to auto-revive. #define OOZELING_MIN_REVIVE_BLOOD_THRESHOLD (FRENZY_THRESHOLD_ENTER * 5) /// How long it takes for an vampire oozeling to auto-revive, when left alone. @@ -107,25 +131,18 @@ // These are supposed to be somewhat nontrivial, to the point of sometimes not being viable. /// Hugging of separate people #define HUMANITY_HUGGING_TYPE "hug" - /// Petting of separate animals #define HUMANITY_PETTING_TYPE "pet" - /// Watching of art #define HUMANITY_ART_TYPE "art" - #define HUMANITY_GAIN_TYPES list(HUMANITY_HUGGING_TYPE, HUMANITY_PETTING_TYPE, HUMANITY_ART_TYPE) -/// Default Humanity -#define VAMPIRE_DEFAULT_HUMANITY 7 - // Cooldown defines // Used to prevent spamming vampires /// Spam prevention for healing messages. #define VAMPIRE_SPAM_HEALING 15 SECONDS /// Spam prevention for Sol Masquerade messages. #define VAMPIRE_SPAM_MASQUERADE 60 SECONDS - /// Spam prevention for Sol messages. #define VAMPIRE_SPAM_SOL 30 SECONDS @@ -141,6 +158,12 @@ #define CLAN_HECATA "Hecata Clan" #define CLAN_LASOMBRA "Lasombra Clan" +/// This area can always be claimed as a vampire lair regardless of Z-level and such +#define ALWAYS_VALID_VAMPIRE_LAIR (1<<21) + +/// This is a Default Power that all Vampires get. +#define VAMPIRE_DEFAULT_POWER (1<<1) + // Power defines /// This Power can't be used in Torpor #define BP_CANT_USE_IN_TORPOR (1<<0) @@ -152,10 +175,6 @@ #define BP_CANT_USE_WHILE_INCAPACITATED (1<<3) /// This Power can't be used while unconscious #define BP_CANT_USE_WHILE_UNCONSCIOUS (1<<4) - -/// This is a Default Power that all Vampires get. -#define VAMPIRE_DEFAULT_POWER (1<<1) - /// This Power is a Toggled Power #define BP_AM_TOGGLE (1<<0) /// This Power is a Single-Use Power @@ -167,76 +186,49 @@ /// This Power has a cooldown that is more dynamic than a typical power #define BP_AM_VERY_DYNAMIC_COOLDOWN (1<<4) -///Called when a Vampire reaches Final Death. -#define COMSIG_VAMPIRE_FINAL_DEATH "vampire_final_death" - ///Whether the vampire should not be dusted when arriving Final Death - #define DONT_DUST (1<<0) - -// Vampire Signals -/// Called when a Vampire breaks the Masquerade -#define COMSIG_VAMPIRE_BROKE_MASQUERADE "comsig_vampire_broke_masquerade" - -// Signals & Defines -/// Sent whenever vampires get a "natural" rank up. -#define COMSIG_SOL_RANKUP_VAMPIRES "sol_rankup_vampires" -/// Sent when tracking humanity gain progress: (type, subject) -#define COMSIG_VAMPIRE_TRACK_HUMANITY_GAIN "comsig_vampire_track_humanity_gain" - -/// Called on the mind when a Vampire chooses a clan: (datum/antagonist/vampire, datum/vampire_clan) -#define COMSIG_VAMPIRE_CLAN_CHOSEN "vampire_clan_chosen" - -#define DANGER_LEVEL_FIRST_WARNING 1 -#define DANGER_LEVEL_SECOND_WARNING 2 -#define DANGER_LEVEL_THIRD_WARNING 3 -#define DANGER_LEVEL_SOL_ROSE 4 -#define DANGER_LEVEL_SOL_ENDED 5 - // Clan defines /// Drinks blood the normal Vampire way. #define VAMPIRE_DRINK_NORMAL "vampire_drink_normal" /// Drinks blood but is snobby, refusing to drink from mindless #define VAMPIRE_DRINK_SNOBBY "vampire_drink_snobby" -// Masquerade ability given at this point or above -#define VAMPIRE_HUMANITY_MASQUERADE_POWER 7 - -// Traits -/// Falsifies Health analyzer blood levels -#define TRAIT_MASQUERADE "masquerade" -/// For people in the middle of being staked -#define TRAIT_BEINGSTAKED "beingstaked" -/// This vampire is currently in a frenzy, -#define TRAIT_FRENZY "frenzy" -/// This vampire is currently in torpor. -#define TRAIT_TORPOR "torpor" -/// This vampire can tell if another vampire has committed diablere on examine. -#define TRAIT_SEE_DIABLERIE "see_diablerie" - -#define CLIENT_COLOR_SOURCE_VAMPIRE "client_color_source_vampire" -// Trait sources -/// Source trait for all vampire traits -#define TRAIT_VAMPIRE "trait_vampire" - -// Macros -#define IS_CURATOR(mob) istype(mob?.mind?.assigned_role, /datum/job/curator) -/// Logging for vampire powers unlocked. -/proc/log_vampire_power(text, list/data) - logger.Log(LOG_CATEGORY_UPLINK_VAMPIRE, text, data) - -/// Trait that says you're shaded by something (ie partially in the dark) -#define TRAIT_SHADED "shaded" - -#define LANGUAGE_VAMPIRE "vampire" -#define LANGUAGE_VASSAL "vassal" +// movable physics component flags #define MOVABLE_PHYSICS_PRECISION 0.01 #define MOVABLE_PHYSICS_MINIMAL_VELOCITY 1 - -// movable physics component flags /// Remove the component as soon as there's zero velocity, useful for movables that will no longer move after being initially moved (blood splatters) #define MPHYSICS_QDEL_WHEN_NO_MOVEMENT (1<<0) /// Movement has started, don't call start_movement() again #define MPHYSICS_MOVING (1<<1) /// The component has been "paused" and will not process #define MPHYSICS_PAUSED (1<<2) + +/// Checks if the given mob is a vampire +#define IS_VAMPIRE(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/vampire)) +/// Checks if the given mob is a vassal +#define IS_VASSAL(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/vassal)) +/// Checks if the given mob is a curator +#define IS_CURATOR(mob) istype(mob?.mind?.assigned_role, /datum/job/curator) +/// Checks if the given mos is a chaplain +#define IS_CHAPLAIN(mob) istype(mob?.mind?.assigned_role, /datum/job/chaplain) + +/// Span Awe +#define span_awe(str) ("" + str + "") + +// Vampire Signals +///Called when a Vampire reaches Final Death. +#define COMSIG_VAMPIRE_FINAL_DEATH "vampire_final_death" + ///Whether the vampire should not be dusted when arriving Final Death + #define DONT_DUST (1<<0) #define COMSIG_LIVING_TRACKER_REMOVED "tracker_removed" -#define ui_team_finder "CENTER,CENTER" +/// From base of /mob/living/simple_animal/attack_hand() and /mob/living/basic/attack_hand() when petting (non-combat): (mob/living/pet) +#define COMSIG_LIVING_PET_ANIMAL "living_pet_animal" +/// From base of /datum/element/art when appraising art: (atom/art_piece) +#define COMSIG_LIVING_APPRAISE_ART "living_appraise_art" +/// Called when a Vampire breaks the Masquerade +#define COMSIG_VAMPIRE_BROKE_MASQUERADE "comsig_vampire_broke_masquerade" +/// Sent whenever vampires get a "natural" rank up. +#define COMSIG_SOL_RANKUP_VAMPIRES "sol_rankup_vampires" +/// Sent when tracking humanity gain progress: (type, subject) +#define COMSIG_VAMPIRE_TRACK_HUMANITY_GAIN "comsig_vampire_track_humanity_gain" +/// Called on the mind when a Vampire chooses a clan: (datum/antagonist/vampire, datum/vampire_clan) +#define COMSIG_VAMPIRE_CLAN_CHOSEN "vampire_clan_chosen" diff --git a/tff_modular/modules/vampire/clans/malkavian.dm b/tff_modular/modules/vampire/clans/malkavian.dm index 4f25c382386..47d122a6249 100644 --- a/tff_modular/modules/vampire/clans/malkavian.dm +++ b/tff_modular/modules/vampire/clans/malkavian.dm @@ -210,7 +210,7 @@ continue if(isanimal_or_basicmob(nearby_viewers)) continue - if(HAS_MIND_TRAIT(nearby_viewers, TRAIT_VAMPIRE_ALIGNED) || HAS_MIND_TRAIT(nearby_viewers, TRAIT_OCCULTIST)) + if(HAS_MIND_TRAIT(nearby_viewers, TRAIT_VAMPIRE_ALIGNED)) continue if(nearby_viewers.is_blind() || nearby_viewers.is_nearsighted_currently()) continue diff --git a/tff_modular/modules/vampire/life_vampire.dm b/tff_modular/modules/vampire/life_vampire.dm index 8a79c4240e8..a37b131342c 100644 --- a/tff_modular/modules/vampire/life_vampire.dm +++ b/tff_modular/modules/vampire/life_vampire.dm @@ -176,6 +176,7 @@ // Clear husk and regenerate organs carbon_user.cure_husk() carbon_user.regenerate_organs() + carbon_user.cure_all_traumas(TRAUMA_RESILIENCE_LOBOTOMY) ensure_brain_nonvital(carbon_user) // Heal organs diff --git a/tff_modular/modules/vampire/objects/kindred.dm b/tff_modular/modules/vampire/objects/kindred.dm index 1bcd184ba58..3de0286eae1 100644 --- a/tff_modular/modules/vampire/objects/kindred.dm +++ b/tff_modular/modules/vampire/objects/kindred.dm @@ -24,9 +24,10 @@ throw_range = 10 resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF -/obj/item/book/kindred/Initialize(mapload) +/obj/item/book/kindred/examine(mob/user) . = ..() - AddComponent(/datum/component/stationloving) + if(IS_CURATOR(user)) + . += span_awe("[src] can be used by curators to identify vampires. Use this on the suspect...") ///Attacking someone with the book. /obj/item/book/kindred/interact_with_atom(mob/target, mob/living/user, list/modifiers) diff --git a/tff_modular/modules/vampire/powers/presence/entrance.dm b/tff_modular/modules/vampire/powers/presence/entrance.dm index 7c9de01740f..e328e093ccd 100644 --- a/tff_modular/modules/vampire/powers/presence/entrance.dm +++ b/tff_modular/modules/vampire/powers/presence/entrance.dm @@ -16,14 +16,18 @@ vampire_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 vitaecost = 80 cooldown_time = 60 SECONDS - target_range = 7 + target_range = 5 prefire_message = "Who will you entrance?" ranged_mousepointer = 'tff_modular/modules/vampire/icons/vampire_entrance.dmi' var/ignore_shielding = FALSE -/datum/action/cooldown/vampire/targeted/entrance +/datum/action/cooldown/vampire/targeted/entrance/two ignore_shielding = TRUE +/datum/action/cooldown/vampire/targeted/entrance/three + ignore_shielding = TRUE + target_range = 7 + /datum/action/cooldown/vampire/targeted/entrance/check_valid_target(atom/target_atom) . = ..() if(!.) diff --git a/tff_modular/modules/vampire/powers/presence/presence.dm b/tff_modular/modules/vampire/powers/presence/presence.dm index 9ba5948d72e..2eef1df50de 100644 --- a/tff_modular/modules/vampire/powers/presence/presence.dm +++ b/tff_modular/modules/vampire/powers/presence/presence.dm @@ -4,6 +4,6 @@ icon_state = "presence" level_1 = list(/datum/action/cooldown/vampire/targeted/entrance) level_2 = list(/datum/action/cooldown/vampire/targeted/entrance, /datum/action/cooldown/vampire/targeted/summon) - level_3 = list(/datum/action/cooldown/vampire/awe, /datum/action/cooldown/vampire/targeted/entrance, /datum/action/cooldown/vampire/targeted/summon) - level_4 = list(/datum/action/cooldown/vampire/awe, /datum/action/cooldown/vampire/targeted/entrance, /datum/action/cooldown/vampire/targeted/summon, /datum/action/cooldown/vampire/force_of_personality) - level_5 = list(/datum/action/cooldown/vampire/awe/two, /datum/action/cooldown/vampire/targeted/entrance, /datum/action/cooldown/vampire/targeted/summon/two, /datum/action/cooldown/vampire/force_of_personality/two) + level_3 = list(/datum/action/cooldown/vampire/awe, /datum/action/cooldown/vampire/targeted/entrance/two, /datum/action/cooldown/vampire/targeted/summon) + level_4 = list(/datum/action/cooldown/vampire/awe, /datum/action/cooldown/vampire/targeted/entrance/two, /datum/action/cooldown/vampire/targeted/summon, /datum/action/cooldown/vampire/force_of_personality) + level_5 = list(/datum/action/cooldown/vampire/awe/two, /datum/action/cooldown/vampire/targeted/entrance/three, /datum/action/cooldown/vampire/targeted/summon/two, /datum/action/cooldown/vampire/force_of_personality/two) diff --git a/tff_modular/modules/vampire/vassals/datum_vassal.dm b/tff_modular/modules/vampire/vassals/datum_vassal.dm index 47d77dd2a08..d2cd383daa0 100644 --- a/tff_modular/modules/vampire/vassals/datum_vassal.dm +++ b/tff_modular/modules/vampire/vassals/datum_vassal.dm @@ -15,8 +15,13 @@ var/datum/team/vampire/vampire_team /// List of Powers, like Vampires. var/list/datum/action/powers = list() - /// A link to our team monitor, used to track our master. - // var/datum/component/team_monitor/monitor + /// Vassal Traits + var/list/traits_to_add = list( + TRAIT_VAMPIRE_ALIGNED, + TRAIT_NIGHT_VISION, + TRAIT_NOBREATH, + TRAIT_HARDLY_WOUNDED, + ) /datum/antagonist/vassal/antag_panel_data() return "Master : [master.owner.name]" @@ -29,6 +34,7 @@ RegisterSignals(current_mob, list(COMSIG_MOB_LOGIN, COMSIG_MOVABLE_Z_CHANGED), PROC_REF(on_login)) current_mob.update_sight() + current_mob.add_traits(traits_to_add, TRAIT_VAMPIRE) // HUD add_team_hud(current_mob) @@ -47,6 +53,7 @@ UnregisterSignal(current_mob, list(COMSIG_ATOM_EXAMINE, COMSIG_MOB_LOGIN, COMSIG_MOVABLE_Z_CHANGED)) current_mob.update_sight() + current_mob.remove_traits(traits_to_add, TRAIT_VAMPIRE) // Tracking // QDEL_NULL(monitor) @@ -62,9 +69,6 @@ owner.remove_antag_datum(src) CRASH("[owner.current] was vassilized without a master!") - ADD_TRAIT(owner, TRAIT_VAMPIRE_ALIGNED, REF(src)) - ADD_TRAIT(owner, TRAIT_NIGHT_VISION, REF(src)) - vampire_team = master.vampire_team vampire_team.add_member(owner) From 10ee9474e67401b2c9af1a4b639d52392105e1d4 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Mon, 27 Apr 2026 18:30:17 +0300 Subject: [PATCH 127/149] =?UTF-8?q?=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B4=D0=B5=D1=84=D0=B0=D0=B9?= =?UTF-8?q?=D0=BD=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/__DEFINES/~ff_defines/vampire.dm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/code/__DEFINES/~ff_defines/vampire.dm b/code/__DEFINES/~ff_defines/vampire.dm index d9bc99129cb..993ad016f09 100644 --- a/code/__DEFINES/~ff_defines/vampire.dm +++ b/code/__DEFINES/~ff_defines/vampire.dm @@ -31,12 +31,11 @@ #define DOAFTER_SOURCE_ARCHIVE_OF_THE_KINDRED "doafter_archive_of_the_kindred" /// Log Category +#define LOG_CATEGORY_UPLINK_VAMPIRE "uplink-vampire" /// Logging for vampire powers unlocked. /proc/log_vampire_power(text, list/data) logger.Log(LOG_CATEGORY_UPLINK_VAMPIRE, text, data) -#define LOG_CATEGORY_UPLINK_VAMPIRE "uplink-vampire" - /// Misc #define CAT_VAMPIRE "Vampire" #define FACTION_VAMPIRE "Vampire" From 15e96d495f4b82f0f66c062205c5a345c95135bd Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Tue, 28 Apr 2026 21:23:11 +0300 Subject: [PATCH 128/149] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D1=8F=D0=B5=D0=BC=20=D0=B0=D0=BD=D1=82=D0=B8=D0=BC=D0=B0=D0=B3?= =?UTF-8?q?=D0=B8=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tff_modular/modules/vampire/powers/dominate/mesmerize.dm | 3 +++ tff_modular/modules/vampire/powers/presence/entrance.dm | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/tff_modular/modules/vampire/powers/dominate/mesmerize.dm b/tff_modular/modules/vampire/powers/dominate/mesmerize.dm index 3652f8b23a7..369486a0f99 100644 --- a/tff_modular/modules/vampire/powers/dominate/mesmerize.dm +++ b/tff_modular/modules/vampire/powers/dominate/mesmerize.dm @@ -83,6 +83,9 @@ owner.balloon_alert(owner, "[living_target] is mindless.") return FALSE + if(living_target.can_block_magic(MAGIC_RESISTANCE_MIND, charge_cost = 1)) + return FALSE + // Vampire/Curator check if(IS_VAMPIRE(living_target) || IS_CURATOR(living_target)) owner.balloon_alert(owner, "too powerful.") diff --git a/tff_modular/modules/vampire/powers/presence/entrance.dm b/tff_modular/modules/vampire/powers/presence/entrance.dm index e328e093ccd..3007fb84e80 100644 --- a/tff_modular/modules/vampire/powers/presence/entrance.dm +++ b/tff_modular/modules/vampire/powers/presence/entrance.dm @@ -44,7 +44,8 @@ if(IS_CURATOR(carbon_target)) owner.balloon_alert(owner, "immune to your presence.") return FALSE - + if(carbot_target.can_block_magic(MAGIC_RESISTANCE_MIND, charge_cost = 1)) + return FALSE if(IS_VAMPIRE(carbon_target)) var/datum/antagonist/vampire/vampire_target = carbon_target if(vampire_target.vampire_level >= vampiredatum_power.vampire_level) From f7e542669aa6518e12c4f47bf8e3c605c9b7722d Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Wed, 29 Apr 2026 17:49:13 +0300 Subject: [PATCH 129/149] Update entrance.dm --- tff_modular/modules/vampire/powers/presence/entrance.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tff_modular/modules/vampire/powers/presence/entrance.dm b/tff_modular/modules/vampire/powers/presence/entrance.dm index 3007fb84e80..6def5929b81 100644 --- a/tff_modular/modules/vampire/powers/presence/entrance.dm +++ b/tff_modular/modules/vampire/powers/presence/entrance.dm @@ -44,7 +44,7 @@ if(IS_CURATOR(carbon_target)) owner.balloon_alert(owner, "immune to your presence.") return FALSE - if(carbot_target.can_block_magic(MAGIC_RESISTANCE_MIND, charge_cost = 1)) + if(carbon_target.can_block_magic(MAGIC_RESISTANCE_MIND, charge_cost = 1)) return FALSE if(IS_VAMPIRE(carbon_target)) var/datum/antagonist/vampire/vampire_target = carbon_target From 6bbe9dee7147b9a355bf0d6112dbed97a859503f Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Wed, 29 Apr 2026 17:56:41 +0300 Subject: [PATCH 130/149] =?UTF-8?q?=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BC=D0=B5=D1=80=D0=B4=D0=B6?= =?UTF-8?q?=D0=BA=D0=BE=D0=BD=D1=84=D0=BB=D0=B8=D0=BA=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hud/vampire.dm => tff_modular/modules/vampire/hud.dm | 0 tgstation.dme | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename code/_onclick/hud/vampire.dm => tff_modular/modules/vampire/hud.dm (100%) diff --git a/code/_onclick/hud/vampire.dm b/tff_modular/modules/vampire/hud.dm similarity index 100% rename from code/_onclick/hud/vampire.dm rename to tff_modular/modules/vampire/hud.dm diff --git a/tgstation.dme b/tgstation.dme index 754a5d6007d..0933d3ca397 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -773,7 +773,6 @@ #include "code\_onclick\hud\screen_objects.dm" #include "code\_onclick\hud\screentip.dm" #include "code\_onclick\hud\soulscythe.dm" -#include "code\_onclick\hud\vampire.dm" #include "code\_onclick\hud\voidwalkerhud.dm" #include "code\_onclick\hud\parallax\parallax.dm" #include "code\_onclick\hud\parallax\random_layer.dm" @@ -9882,6 +9881,7 @@ #include "tff_modular\modules\vampire\dynamic.dm" #include "tff_modular\modules\vampire\effects.dm" #include "tff_modular\modules\vampire\frenzy_vampire.dm" +#include "tff_modular\modules\vampire\hud.dm" #include "tff_modular\modules\vampire\language.dm" #include "tff_modular\modules\vampire\leveling_vampire.dm" #include "tff_modular\modules\vampire\life_vampire.dm" From ce8b36e7a43bbc0f4c4bc830061175c7c748d8e1 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Wed, 29 Apr 2026 18:24:28 +0300 Subject: [PATCH 131/149] =?UTF-8?q?=D0=BF=D1=80=D0=BE=D0=B1=D1=83=D0=B5?= =?UTF-8?q?=D0=BC=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D1=8F=D1=82?= =?UTF-8?q?=D1=8C=20=D1=85=D1=83=D0=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/__DEFINES/~ff_defines/vampire.dm | 5 +++ tff_modular/modules/vampire/datum_vampire.dm | 46 ++++++++------------ 2 files changed, 22 insertions(+), 29 deletions(-) diff --git a/code/__DEFINES/~ff_defines/vampire.dm b/code/__DEFINES/~ff_defines/vampire.dm index 993ad016f09..976ab6fda42 100644 --- a/code/__DEFINES/~ff_defines/vampire.dm +++ b/code/__DEFINES/~ff_defines/vampire.dm @@ -90,6 +90,11 @@ /// When do we warn them about their low blood? #define VAMPIRE_LOW_BLOOD_WARNING 300 +/// Hud Defines +#define HUD_VAMPIRE_RANK "hud_vampire_rank" +#define HUD_VAMPIRE_BLOOD "hud_vampire_blood" +#define HUD_VAMPIRE_HUMANITY "hud_vampire_humanity" + /// Stats Defines /// Default amount of damage the vampire's punch/kick damage increases with each level. #define VAMPIRE_UNARMED_DMG_INCREASE_ON_RANKUP 0.75 diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index 8e77fc320ba..d1172cb981e 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -104,13 +104,6 @@ var/area/vampire_lair_area var/obj/structure/closet/crate/coffin - /// Blood display HUD - var/atom/movable/screen/vampire/blood_counter/blood_display - /// Vampire level display HUD - var/atom/movable/screen/vampire/rank_counter/vamprank_display - /// Vampire humanity display HUD - var/atom/movable/screen/vampire/humanity_counter/humanity_display - /// Tracker so that vassals know where their master is // var/obj/effect/abstract/vampire_tracker_holder/tracker @@ -199,7 +192,7 @@ // RegisterSignal(current_mob, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved)) RegisterSignal(current_mob, COMSIG_HUMAN_ON_HANDLE_BLOOD, PROC_REF(handle_blood)) RegisterSignal(current_mob, COMSIG_MOB_UPDATE_SIGHT, PROC_REF(on_update_sight)) - + RegisterSignal(current_mob, COMSIG_MOB_HUD_CREATED, PROC_REF(on_hud_created)) RegisterSignal(current_mob, COMSIG_LIVING_PET_ANIMAL, PROC_REF(on_pet_animal)) RegisterSignal(current_mob, COMSIG_CARBON_HELPED, PROC_REF(on_hug_carbon)) RegisterSignal(current_mob, COMSIG_LIVING_APPRAISE_ART, PROC_REF(on_appraise_art)) @@ -214,8 +207,6 @@ if(current_mob.hud_used) on_hud_created() - else - RegisterSignal(current_mob, COMSIG_MOB_HUD_CREATED, PROC_REF(on_hud_created)) ensure_brain_nonvital(current_mob) setup_limbs(current_mob) @@ -262,7 +253,6 @@ cleanup_limbs(current_mob) // cleanup_tracker() - remove_hud_elements(current_mob) QDEL_NULL(blood_display) QDEL_NULL(vamprank_display) QDEL_NULL(humanity_display) @@ -276,30 +266,28 @@ if(!QDELETED(current_mob)) my_clan?.remove_effects(current_mob) -/datum/antagonist/vampire/proc/remove_hud_elements(mob/living/current_mob) - var/datum/hud/hud_used = current_mob?.hud_used - if(hud_used) - hud_used.infodisplay -= blood_display - hud_used.infodisplay -= vamprank_display - hud_used.infodisplay -= humanity_display - var/client/current_client = current_mob?.client - if(current_client) - current_client?.screen -= blood_display - current_client?.screen -= vamprank_display - current_client?.screen -= humanity_display + if(!current_mob.hud_used) + return + + var/datum/hud/vampire_hud = current_mob.hud_used + vampire_hud.remove_screen_object(HUD_VAMPIRE_BLOOD) + vampire_hud.remove_screen_object(HUD_VAMPIRE_RANK) + vampire_hud.remove_screen_object(HUD_VAMPIRE_HUMANITY) /datum/antagonist/vampire/proc/on_hud_created(datum/source) SIGNAL_HANDLER var/datum/hud/vampire_hud = owner.current.hud_used - blood_display = new /atom/movable/screen/vampire/blood_counter(null, vampire_hud) - vampire_hud.infodisplay += blood_display - - vamprank_display = new /atom/movable/screen/vampire/rank_counter(null, vampire_hud) - vampire_hud.infodisplay += vamprank_display + /// Blood display HUD + var/atom/movable/screen/vampire/blood_counter/blood_display + /// Vampire level display HUD + var/atom/movable/screen/vampire/rank_counter/vamprank_display + /// Vampire humanity display HUD + var/atom/movable/screen/vampire/humanity_counter/humanity_display - humanity_display = new /atom/movable/screen/vampire/humanity_counter(null, vampire_hud) - vampire_hud.infodisplay += humanity_display + vampire_hud.add_screen_object(/atom/movable/screen/vampire/blood_counter, HUD_VAMPIRE_BLOOD, HUD_GROUP_INFO) + vampire_hud.add_screen_object(/atom/movable/screen/vampire/rank_counter, HUD_VAMPIRE_RANK, HUD_GROUP_INFO) + vampire_hud.add_screen_object(/atom/movable/screen/vampire/humanity_counter, HUD_VAMPIRE_HUMANITY, HUD_GROUP_INFO) vampire_hud.show_hud(vampire_hud.hud_version) UnregisterSignal(owner.current, COMSIG_MOB_HUD_CREATED) From fbcb65f6df72007f07261484e5caf060da5d009b Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Wed, 29 Apr 2026 18:25:10 +0300 Subject: [PATCH 132/149] Update datum_vampire.dm --- tff_modular/modules/vampire/datum_vampire.dm | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index d1172cb981e..8a86dd249d5 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -253,10 +253,6 @@ cleanup_limbs(current_mob) // cleanup_tracker() - QDEL_NULL(blood_display) - QDEL_NULL(vamprank_display) - QDEL_NULL(humanity_display) - current_mob.remove_faction(FACTION_VAMPIRE) if(ishuman(current_mob)) @@ -277,14 +273,6 @@ /datum/antagonist/vampire/proc/on_hud_created(datum/source) SIGNAL_HANDLER var/datum/hud/vampire_hud = owner.current.hud_used - - /// Blood display HUD - var/atom/movable/screen/vampire/blood_counter/blood_display - /// Vampire level display HUD - var/atom/movable/screen/vampire/rank_counter/vamprank_display - /// Vampire humanity display HUD - var/atom/movable/screen/vampire/humanity_counter/humanity_display - vampire_hud.add_screen_object(/atom/movable/screen/vampire/blood_counter, HUD_VAMPIRE_BLOOD, HUD_GROUP_INFO) vampire_hud.add_screen_object(/atom/movable/screen/vampire/rank_counter, HUD_VAMPIRE_RANK, HUD_GROUP_INFO) vampire_hud.add_screen_object(/atom/movable/screen/vampire/humanity_counter, HUD_VAMPIRE_HUMANITY, HUD_GROUP_INFO) From 9ba4ed580d0261126bad8573c91d6d155f496db8 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Wed, 29 Apr 2026 18:28:45 +0300 Subject: [PATCH 133/149] Update hud.dm --- tff_modular/modules/vampire/hud.dm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tff_modular/modules/vampire/hud.dm b/tff_modular/modules/vampire/hud.dm index f3f30acb892..5472b1c7200 100644 --- a/tff_modular/modules/vampire/hud.dm +++ b/tff_modular/modules/vampire/hud.dm @@ -160,6 +160,9 @@ if(701 to INFINITY) valuecolor = "#ffffff" + var/atom/movable/screen/vampire/blood_counter/blood_display = owner.current?.hud_used?.screen_objects[HUD_VAMPIRE_BLOOD] + var/atom/movable/screen/vampire/rank_counter/vamprank_display = owner.current?.hud_used?.screen_objects[HUD_VAMPIRE_RANK] + var/atom/movable/screen/vampire/humanity_counter/humanity_display = owner.current?.hud_used?.screen_objects[HUD_VAMPIRE_HUMANITY] blood_display?.maptext = FORMAT_VAMPIRE_HUD_TEXT(valuecolor, current_vitae) if(vamprank_display) From 613e0da3bf53f6fe3a76ef86bf27180c1927790f Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Thu, 30 Apr 2026 02:46:19 +0300 Subject: [PATCH 134/149] =?UTF-8?q?=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D1=8F=D0=B5=D0=BC=20=D0=BC=D0=B0=D1=81=D0=BA=D0=B0=D1=80?= =?UTF-8?q?=D0=B0=D0=B4,=20=D0=BD=D0=B5=D0=BA=D0=BE=D1=82=D0=BE=D1=80?= =?UTF-8?q?=D1=8B=D0=B5=20=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8=20=D0=B1?= =?UTF-8?q?=D0=B0=D0=BB=D0=B0=D0=BD=D1=81=D0=B0,=20=D0=B8=D1=81=D0=BF?= =?UTF-8?q?=D1=80=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B1=D0=B0?= =?UTF-8?q?=D0=B3=D0=BE=D0=B2,=20=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D1=81=D0=BF=D0=BE=D1=81=D0=BE=D0=B1=D0=BD?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D0=B5=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/__DEFINES/~ff_defines/vampire.dm | 2 +- tff_modular/modules/vampire/clans/_clan.dm | 36 ++------ tff_modular/modules/vampire/datum_vampire.dm | 6 +- tff_modular/modules/vampire/dynamic.dm | 8 +- tff_modular/modules/vampire/hud.dm | 3 +- tff_modular/modules/vampire/life_vampire.dm | 5 +- .../modules/vampire/misc_procs_vampire.dm | 24 ++--- tff_modular/modules/vampire/powers/_power.dm | 16 +++- .../modules/vampire/powers/auspex/auspex.dm | 3 +- .../modules/vampire/powers/celerity/haste.dm | 4 +- .../vampire/powers/celerity/quickness.dm | 3 +- tff_modular/modules/vampire/powers/feed.dm | 33 +------ .../vampire/powers/fortitude/fortitude.dm | 2 +- .../vampire/powers/obfuscate/trespass.dm | 14 +-- .../modules/vampire/powers/potence/brawn.dm | 15 ++- .../modules/vampire/powers/potence/lunge.dm | 4 +- .../modules/vampire/powers/presence/awe.dm | 14 +-- .../vampire/powers/presence/entrance.dm | 2 +- .../powers/presence/force_of_personality.dm | 91 ++++--------------- .../vampire/powers/presence/presence.dm | 2 +- .../modules/vampire/powers/presence/summon.dm | 2 +- .../vampire/powers/thaumaturgy/bloodbolt.dm | 2 +- .../vampire/powers/thaumaturgy/blooddrain.dm | 5 +- tff_modular/modules/vampire/society.dm | 18 ++-- .../modules/vampire/tracking_vampire.dm | 36 -------- tff_modular/modules/vampire/vamp_society.dm | 74 +++++++++++++++ tgstation.dme | 2 +- 27 files changed, 167 insertions(+), 259 deletions(-) delete mode 100644 tff_modular/modules/vampire/tracking_vampire.dm create mode 100644 tff_modular/modules/vampire/vamp_society.dm diff --git a/code/__DEFINES/~ff_defines/vampire.dm b/code/__DEFINES/~ff_defines/vampire.dm index 976ab6fda42..332e69bf534 100644 --- a/code/__DEFINES/~ff_defines/vampire.dm +++ b/code/__DEFINES/~ff_defines/vampire.dm @@ -97,7 +97,7 @@ /// Stats Defines /// Default amount of damage the vampire's punch/kick damage increases with each level. -#define VAMPIRE_UNARMED_DMG_INCREASE_ON_RANKUP 0.75 +#define VAMPIRE_UNARMED_DMG_INCREASE_ON_RANKUP 1 /// How many starting levels do we want each one to have? #define VAMPIRE_STARTING_LEVELS 3 /// How many free levels the vampire gets gradually. diff --git a/tff_modular/modules/vampire/clans/_clan.dm b/tff_modular/modules/vampire/clans/_clan.dm index 01405310c59..453c0215b4a 100644 --- a/tff_modular/modules/vampire/clans/_clan.dm +++ b/tff_modular/modules/vampire/clans/_clan.dm @@ -196,40 +196,22 @@ if(vampiredatum.vampire_level_unspent > 0) spend_rank(carbon_vampire) -/* -/datum/vampire_clan/proc/prince_check() - if(!vampiredatum.can_become_prince && !vampiredatum.vampire_level >= 10 && !vampiredatum.prince) - return FALSE - - var/tgui_answer = tgui_alert(vampiredatum.owner.current, "You grown enough to become a prince, do you want it? If you refuse, you won't be able to become a prince later!", "Princify", list("Yes", "No")) - if(tgui_answer == "Yes") - vampiredatum.princify() - else if(tgui_answer == "No") - vampiredatum.can_become_prince = FALSE -*/ - /datum/vampire_clan/proc/finalize_spend_rank() // Level up the vampire - if(ishuman(vampiredatum.owner.current)) - var/mob/living/carbon/human/human_user = vampiredatum.owner.current - var/obj/item/bodypart/user_left_hand = human_user.get_bodypart(BODY_ZONE_L_ARM) - var/obj/item/bodypart/user_right_hand = human_user.get_bodypart(BODY_ZONE_R_ARM) - user_left_hand.unarmed_damage_low += vampiredatum.extra_damage_per_rank - user_right_hand.unarmed_damage_low += vampiredatum.extra_damage_per_rank - // This affects the hitting power of Brawn. - user_left_hand.unarmed_damage_high += vampiredatum.extra_damage_per_rank - user_right_hand.unarmed_damage_high += vampiredatum.extra_damage_per_rank - vampiredatum.current_damage_bonus += vampiredatum.extra_damage_per_rank vampiredatum.vampire_regen_rate += 0.1 vampiredatum.max_vitae += 100 - - /* if(ishuman(vampiredatum.owner.current)) - var/mob/living/carbon/human/vampire_human = vampiredatum.owner.current - vampire_human.dna.species.punchdamage += 0.5 */ - // We're almost done - Spend your Rank now. vampiredatum.vampire_level++ vampiredatum.vampire_level_unspent-- + vampiredatum.current_damage_bonus = vampiredatum.extra_damage_per_rank * vampiredatum.vampire_level + if(ishuman(vampiredatum.owner.current)) + var/mob/living/carbon/human/human_user = vampiredatum.owner.current + var/obj/item/bodypart/user_left_hand = human_user.get_bodypart(BODY_ZONE_L_ARM) + var/obj/item/bodypart/user_right_hand = human_user.get_bodypart(BODY_ZONE_R_ARM) + user_left_hand.unarmed_damage_low = 5 + vampiredatum.current_damage_bonus + user_right_hand.unarmed_damage_low = 5 + vampiredatum.current_damage_bonus + user_left_hand.unarmed_damage_high = 10 + vampiredatum.current_damage_bonus + user_right_hand.unarmed_damage_high = 10 + vampiredatum.current_damage_bonus // Flavor to_chat(vampiredatum.owner.current, span_notice("You are now a rank [vampiredatum.vampire_level] Vampire. \ diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index 8a86dd249d5..8c1023a629e 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -282,7 +282,7 @@ /datum/antagonist/vampire/get_admin_commands() . = ..() - .["Level Add"] = CALLBACK(src, PROC_REF(rank_up), 1) + .["Level Add"] = CALLBACK(src, PROC_REF(rank_up), 1, TRUE) if(vampire_level_unspent > 0) .["Level Deduct"] = CALLBACK(src, PROC_REF(rank_down)) @@ -323,8 +323,7 @@ GLOB.all_vampires += src SSvampire_leveling.check_enable() - // Start society if we're the first vampire - // check_start_society() + check_start_society() if(!QDELETED(owner.current)) for(var/quirk_type in typesof(/datum/quirk/item_quirk/addict/junkie) + /datum/quirk/skittish) @@ -760,7 +759,6 @@ var/obj/item/bodypart/user_right_hand = owner.get_bodypart(BODY_ZONE_R_ARM) user_left_hand.unarmed_damage_low = 5 + current_damage_bonus user_right_hand.unarmed_damage_low = 5 + current_damage_bonus - // This affects the hitting power of Brawn. user_left_hand.unarmed_damage_high = 10 + current_damage_bonus user_right_hand.unarmed_damage_high = 10 + current_damage_bonus diff --git a/tff_modular/modules/vampire/dynamic.dm b/tff_modular/modules/vampire/dynamic.dm index 15e97837c7d..31dad96f91f 100644 --- a/tff_modular/modules/vampire/dynamic.dm +++ b/tff_modular/modules/vampire/dynamic.dm @@ -14,7 +14,7 @@ /datum/dynamic_ruleset/roundstart/vampire/assign_role(datum/mind/candidate) var/datum/antagonist/vampire/suck_datum = candidate.add_antag_datum(/datum/antagonist/vampire) - suck_datum.rank_up(VAMPIRE_STARTING_LEVELS) + suck_datum.rank_up(VAMPIRE_STARTING_LEVELS, TRUE) /datum/dynamic_ruleset/midround/from_living/vampire name = "Vampiric Accident" @@ -35,7 +35,7 @@ /datum/dynamic_ruleset/midround/from_living/vampire/assign_role(datum/mind/candidate) var/datum/antagonist/vampire/suck_datum = candidate.add_antag_datum(/datum/antagonist/vampire) - suck_datum.rank_up(VAMPIRE_STARTING_LEVELS) + suck_datum.rank_up(VAMPIRE_STARTING_LEVELS, TRUE) /datum/dynamic_ruleset/latejoin/vampire name = "Vampiric Accident" @@ -52,3 +52,7 @@ if(is_species(candidate, BLOODSUCKER_RESTRICTED_SPECIES)) return FALSE return ..() + +/datum/dynamic_ruleset/latejoin/vampire/assign_role(datum/mind/candidate) + var/datum/antagonist/vampire/suck_datum = candidate.add_antag_datum(/datum/antagonist/vampire) + suck_datum.rank_up(VAMPIRE_STARTING_LEVELS, TRUE) diff --git a/tff_modular/modules/vampire/hud.dm b/tff_modular/modules/vampire/hud.dm index 5472b1c7200..63b7a7f3f72 100644 --- a/tff_modular/modules/vampire/hud.dm +++ b/tff_modular/modules/vampire/hud.dm @@ -68,7 +68,6 @@ if(!owner_vamp) return - /* var/mob/living/carbon/human/vampire_human = owner_mob */ msg += span_cult_large("This is your Rank-Counter.") msg += span_cult("Here you see your current progress in the mastery of your disciplines.") msg += span_cult("This is a measure of your main progress as a vampire, and, should you feed on another vampire(that has broken the masquerade), you will absorb half of their levels.") @@ -76,7 +75,7 @@ msg += span_cult("\nCurrently, your rank affords you the following benefits:") msg += span_cult("Max Regeneration rate: +[owner_vamp.vampire_regen_rate]") msg += span_cult("Max Vitae pool: +[owner_vamp.max_vitae - 600] ") - msg += span_cult("Unarmed damage: +[1 + (owner_vamp.vampire_level * owner_vamp.extra_damage_per_rank)]") + msg += span_cult("Unarmed damage: +[owner_vamp.current_damage_bonus]") var/list/disciplinestext for(var/datum/discipline/discipline in owner_vamp.owned_disciplines) diff --git a/tff_modular/modules/vampire/life_vampire.dm b/tff_modular/modules/vampire/life_vampire.dm index a37b131342c..16e10ac84b0 100644 --- a/tff_modular/modules/vampire/life_vampire.dm +++ b/tff_modular/modules/vampire/life_vampire.dm @@ -66,9 +66,7 @@ // oh god why if(HAS_TRAIT_FROM(current, TRAIT_DEATHCOMA, CHANGELING_TRAIT)) return FALSE - var/actual_regen = vampire_regen_rate + additional_regen - current.adjust_organ_loss(ORGAN_SLOT_BRAIN, -1 * (actual_regen * 4)) current.adjust_organ_loss(ORGAN_SLOT_EYES, -1 * (actual_regen * 4)) current.adjust_organ_loss(ORGAN_SLOT_EARS, -1 * (actual_regen * 4)) @@ -139,6 +137,9 @@ heal_vampire_organs() return TRUE + var/datum/status_effect/incapacitating/sleeping/sleeping_effect = current.has_status_effect(/datum/status_effect/incapacitating/sleeping) + if(sleeping_effect) + current.remove_status_effect(sleeping_effect) return FALSE /datum/antagonist/vampire/proc/try_regenerate_limbs(cost_muliplier = 1) diff --git a/tff_modular/modules/vampire/misc_procs_vampire.dm b/tff_modular/modules/vampire/misc_procs_vampire.dm index 55c0fef6a39..875bb6ae74d 100644 --- a/tff_modular/modules/vampire/misc_procs_vampire.dm +++ b/tff_modular/modules/vampire/misc_procs_vampire.dm @@ -296,9 +296,9 @@ return "'Expert'" if(10 to 11) return "'Master'" - if(12 to 24) + if(12 to 19) return "'Grand Master'" - if(25 to INFINITY) + if(20 to INFINITY) return "[span_narsiesmall("'Methuselah'")]" /// This is where we store clan descriptions. @@ -356,6 +356,10 @@ /datum/antagonist/heretic_monster, /datum/antagonist/nightmare, /datum/antagonist/wizard, + /datum/antagonist/cult, + /datum/antagonist/clock_cultist, + /datum/antagonist/voidwalker, + /datum/antagonist/nukeop/clownop, // THIS IS SO FUCKING SUPERNATURAL ) if(!isliving(watcher) || QDELING(watcher)) @@ -394,22 +398,6 @@ for(var/datum/antagonist/vassal/all_vassals in vassals) all_vassals.owner.remove_antag_datum(/datum/antagonist/vassal) -//Returns an in proportion scaled out view, with zoom_amt extra tiles on the y axis. -/proc/get_zoomed_view(view, zoom_amt) - var/view_x - var/view_y - if(IS_FINITE(view)) - return view + zoom_amt - else - var/list/viewrangelist = splittext(view, "x") - view_x = text2num(viewrangelist[1]) - view_y = text2num(viewrangelist[2]) - var/proportion = view_x / view_x - view_x += zoom_amt * proportion - view_y += zoom_amt - //God, I hate that we have to round this. - return "[round(view_x, 1)]x[round(view_y, 1)]" - /mob/living/carbon/human/proc/backup_clothing_prefs() as /alist return alist( "underwear" = underwear, diff --git a/tff_modular/modules/vampire/powers/_power.dm b/tff_modular/modules/vampire/powers/_power.dm index 2b12c218344..40999129786 100644 --- a/tff_modular/modules/vampire/powers/_power.dm +++ b/tff_modular/modules/vampire/powers/_power.dm @@ -225,19 +225,25 @@ Remove(owner) // If there's a mortal in line of sight, we get a masq infraction -/datum/action/cooldown/vampire/proc/check_witnesses(mob/living/target) +/datum/action/cooldown/vampire/proc/check_witnesses() var/turf/our_turf = get_turf(owner) - var/turf/target_turf = get_turf(target) - var/min_darkness = target_turf ? min(our_turf.get_lumcount(), target_turf.get_lumcount()) : our_turf.get_lumcount() + var/min_darkness = our_turf.get_lumcount() var/is_dark = min_darkness <= 0.2 - for(var/mob/living/watcher in oviewers(6, owner) - target) + var/datum/antagonist/vampire/antag_datum = IS_VAMPIRE(owner) + // Malkavians can't not show themselves as masquerade violators to others, because their task is to kill violators. + if(istype(antag_datum?.my_clan, /datum/vampire_clan/malkavian)) + return + for(var/mob/living/watcher in oviewers(6, owner)) if(!vampiredatum_power.is_masq_watcher(watcher)) continue if(is_dark && !watcher.Adjacent(owner) && (!target || !watcher.Adjacent(target))) continue if(!INCAPACITATED_IGNORING(watcher, INCAPABLE_RESTRAINTS)) watcher.face_atom(owner) - + if(watcher == owner) + continue + if(length(watcher) < 2) + return FALSE watcher.do_alert_animation(watcher) playsound(watcher, 'sound/machines/chime.ogg', 50, FALSE, -5) vampiredatum_power.give_masquerade_infraction() diff --git a/tff_modular/modules/vampire/powers/auspex/auspex.dm b/tff_modular/modules/vampire/powers/auspex/auspex.dm index 8533acde3b2..8093fe610ba 100644 --- a/tff_modular/modules/vampire/powers/auspex/auspex.dm +++ b/tff_modular/modules/vampire/powers/auspex/auspex.dm @@ -6,8 +6,7 @@ // Lists of abilities granted per level level_1 = list(/datum/action/cooldown/vampire/auspex) - level_2 = list(/datum/action/cooldown/vampire/auspex/two) - level_3 = list(/datum/action/cooldown/vampire/auspex/two, /datum/action/cooldown/vampire/astral_projection) + level_2 = list(/datum/action/cooldown/vampire/auspex/two, /datum/action/cooldown/vampire/astral_projection) /datum/discipline/auspex/apply_discipline_quirks(datum/antagonist/vampire/clan_owner) . = ..() diff --git a/tff_modular/modules/vampire/powers/celerity/haste.dm b/tff_modular/modules/vampire/powers/celerity/haste.dm index 2d4aab86bfd..150f268c465 100644 --- a/tff_modular/modules/vampire/powers/celerity/haste.dm +++ b/tff_modular/modules/vampire/powers/celerity/haste.dm @@ -65,7 +65,7 @@ var/turf/targeted_turf = get_turf(target_atom) // Pulled? Not anymore. user.pulledby?.stop_pulling() - user.adjust_stamina_loss(-10 - level_current * 8) + user.adjust_stamina_loss(-10 - level_current * 7) // Go to target turf // DO NOT USE WALK TO. // check_witnesses() @@ -99,6 +99,6 @@ continue hit += hit_living playsound(hit_living, SFX_PUNCH, 15, TRUE, -1) - hit_living.adjust_stamina_loss(10 + level_current * 8) + hit_living.adjust_stamina_loss(10 + level_current * 7) hit_living.Knockdown(10 + level_current * 8) hit_living.spin(1 SECONDS, 1) diff --git a/tff_modular/modules/vampire/powers/celerity/quickness.dm b/tff_modular/modules/vampire/powers/celerity/quickness.dm index b0c6f1c468f..87b62300b7c 100644 --- a/tff_modular/modules/vampire/powers/celerity/quickness.dm +++ b/tff_modular/modules/vampire/powers/celerity/quickness.dm @@ -8,8 +8,7 @@ vampire_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 cooldown_time = 30 SECONDS vitaecost = 25 - constant_vitaecost = 1 - + constant_vitaecost = 0.2 /datum/action/cooldown/vampire/exactitude/can_use() . = ..() diff --git a/tff_modular/modules/vampire/powers/feed.dm b/tff_modular/modules/vampire/powers/feed.dm index 6d10d425585..f3f76aa6091 100644 --- a/tff_modular/modules/vampire/powers/feed.dm +++ b/tff_modular/modules/vampire/powers/feed.dm @@ -123,10 +123,6 @@ if(IS_CURATOR(target)) owner.balloon_alert(owner, "[target] is too powerful!") return FALSE - var/datum/antagonist/vampire/target_vampire = IS_VAMPIRE(target) - if(target_vampire && (vampiredatum_power.scourge || vampiredatum_power.prince) && !target_vampire.broke_masquerade) - owner.balloon_alert(owner, "cannot diablerize non-masquerade breakers as royalty!") - return FALSE // Human checks if(ishuman(target)) // Cannot drink from inorganics @@ -467,23 +463,6 @@ to_chat(owner, span_userdanger("No way will [feed_target.p_they()] survive that...")) vampiredatum_power.adjust_humanity(-1) -/* - if(iscarbon(feed_target)) - var/mob/living/carbon/carbon_target = feed_target - // More/less humanity adds/deducts bleedy. - switch(vampiredatum_power.humanity) - if(0 to 2) - carbon_target.bleed(BLEED_CRITICAL) - if(3 to 4) - carbon_target.bleed(BLEED_DEEP_WOUND) - if(5 to 6) - carbon_target.bleed(BLEED_CUT) - if(7 to 8) - carbon_target.bleed(BLEED_SURFACE) - if(9 to 10) - carbon_target.bleed(BLEED_SCRATCH) -*/ - feed_fatal = FALSE humanity_deducted = FALSE completing_thirster = FALSE @@ -501,19 +480,11 @@ if(feed_fatal) feed_amount *= 1.5 - // But, if we are in combat we want to get them some time to react. - if(!silent_feed) - feed_amount *= 0.3 - var/blood_to_take = min(feed_amount * mult, target.blood_volume) // Remove target's blood target.blood_volume -= blood_to_take - // Shift body temperature (toward target's temp, by volume taken) - // ((vamp_blood_volume * vamp_temp) + (target_blood_volume * target_temp)) / (vamp_blood_volume + blood_to_take) - // owner.bodytemperature = ((vampiredatum_power.current_vitae * owner.bodytemperature) + (blood_to_take * target.bodytemperature)) / (vampiredatum_power.current_vitae + blood_to_take) - // Penalty for dead blood(at least it's still human, right?) if(target.stat == DEAD) blood_to_take /= 3 @@ -524,7 +495,7 @@ if(HAS_TRAIT(living_owner, TRAIT_FRENZY)) blood_to_take /= 2 - // Give vampire the blood^ + // Give vampire the blood var/vitae_absorbed = blood_to_take * 4 /// Tracking of the vitae goal @@ -549,7 +520,7 @@ blood_taken += blood_to_take // If we are on combat feed, we only want it to take a bit and then stop. Except if they are not conscious or if they're restrained. - if(!silent_feed && blood_taken >= 60 && target.stat <= SOFT_CRIT && !HAS_TRAIT(target, TRAIT_RESTRAINED)) + if(!silent_feed && blood_taken >= 200 && target.stat <= SOFT_CRIT && !HAS_TRAIT(target, TRAIT_RESTRAINED)) playsound(target, 'sound/items/weapons/cqchit2.ogg', 80) diff --git a/tff_modular/modules/vampire/powers/fortitude/fortitude.dm b/tff_modular/modules/vampire/powers/fortitude/fortitude.dm index 1d8611e12b6..1fb3ea3f86d 100644 --- a/tff_modular/modules/vampire/powers/fortitude/fortitude.dm +++ b/tff_modular/modules/vampire/powers/fortitude/fortitude.dm @@ -29,7 +29,7 @@ At level 3: Gain dismember resistance.\n\ At level 4: Gain complete stun immunity." vampire_power_flags = BP_AM_TOGGLE | BP_AM_COSTLESS_UNCONSCIOUS - vampire_check_flags = BP_CANT_USE_IN_TORPOR | BP_CANT_USE_IN_FRENZY | BP_CANT_USE_WHILE_STAKED + vampire_check_flags = BP_CANT_USE_IN_TORPOR | BP_CANT_USE_WHILE_STAKED vitaecost = 50 cooldown_time = 5 SECONDS diff --git a/tff_modular/modules/vampire/powers/obfuscate/trespass.dm b/tff_modular/modules/vampire/powers/obfuscate/trespass.dm index 4885c63f929..b55d0af5d67 100644 --- a/tff_modular/modules/vampire/powers/obfuscate/trespass.dm +++ b/tff_modular/modules/vampire/powers/obfuscate/trespass.dm @@ -64,19 +64,16 @@ // Find target turf, at or below Atom var/mob/living/carbon/user = owner var/turf/my_turf = get_turf(owner) - + check_witnesses() user.visible_message( span_warning("[user]'s form dissipates into a cloud of mist!"), span_notice("You disspiate into formless mist."), ) // Effect Origin - var/sound_strength = max(40, 100 - level_current * 20) + var/sound_strength = max(40, 100 - level_current * 30) playsound(get_turf(owner), 'sound/effects/magic/summon_karp.ogg', vol = sound_strength, vary = TRUE) - /* - var/datum/effect_system/steam_spread/vampire/puff = new /datum/effect_system/steam_spread() - puff.set_up(3, FALSE, my_turf) + var/datum/effect_system/basic/steam_spread/puff = new /datum/effect_system/basic/steam_spread(user.loc, 1) puff.start() - */ var/mist_delay = max(5, 20 - level_current * 2.5) // Level up and do this faster. // Freeze Me @@ -103,8 +100,5 @@ check_witnesses() // Effect Destination playsound(get_turf(owner), 'sound/effects/magic/summon_karp.ogg', vol = 60, vary = TRUE) - /* - puff = new /datum/effect_system/steam_spread() - puff.set_up(3, FALSE, target_turf) + puff = new /datum/effect_system/basic/steam_spread(user.loc, 1) puff.start() - */ diff --git a/tff_modular/modules/vampire/powers/potence/brawn.dm b/tff_modular/modules/vampire/powers/potence/brawn.dm index 434fb1b00a3..c20a635b2ab 100644 --- a/tff_modular/modules/vampire/powers/potence/brawn.dm +++ b/tff_modular/modules/vampire/powers/potence/brawn.dm @@ -7,7 +7,7 @@ At level 4, you can bash airlocks open, and you get the ability to brawn even mecha. Use wisely - security is unlikely to try and capture you alive again after the first time!\n\ Higher ranks will increase the damage when punching someone." vampire_power_flags = BP_AM_TOGGLE - vampire_check_flags = BP_CANT_USE_IN_TORPOR | BP_CANT_USE_WHILE_STAKED | BP_CANT_USE_IN_FRENZY | BP_CANT_USE_WHILE_INCAPACITATED | BP_CANT_USE_WHILE_UNCONSCIOUS + vampire_check_flags = BP_CANT_USE_IN_TORPOR | BP_CANT_USE_WHILE_STAKED | BP_CANT_USE_WHILE_INCAPACITATED | BP_CANT_USE_WHILE_UNCONSCIOUS vitaecost = 45 cooldown_time = 9 SECONDS target_range = 1 @@ -85,9 +85,7 @@ if(used) playsound(get_turf(human_owner), 'sound/effects/grillehit.ogg', 80, TRUE, -1) - - /* if(used) - check_witnesses() */ + check_witnesses() return used /datum/action/cooldown/vampire/targeted/brawn/proc/escape_puller() @@ -116,7 +114,7 @@ ) owner.pulledby?.stop_pulling() // It's already done, but JUST IN CASE. - // check_witnesses() + check_witnesses() return TRUE /datum/action/cooldown/vampire/targeted/brawn/fire_targeted_power(atom/target_atom, list/modifiers) @@ -141,7 +139,7 @@ // Attack! owner.balloon_alert(owner, "you punch [living_target]!") playsound(get_turf(living_target), 'sound/items/weapons/punch4.ogg', 60, TRUE, -1) - // check_witnesses(living_target) + check_witnesses() carbon_owner.do_attack_animation(living_target, ATTACK_EFFECT_SMASH) var/obj/item/bodypart/affecting = living_target.get_bodypart(ran_zone(living_target.zone_selected)) @@ -169,13 +167,13 @@ INVOKE_ASYNC(target_closet, TYPE_PROC_REF(/obj/structure/closet, bust_open)) playsound(get_turf(carbon_owner), 'sound/effects/grillehit.ogg', 80, TRUE, -1) - // check_witnesses() + check_witnesses() // Airlocks else if(istype(target_atom, /obj/machinery/door/airlock)) var/obj/machinery/door/airlock/target_airlock = target_atom playsound(get_turf(carbon_owner), 'sound/machines/airlock/airlock_alien_prying.ogg', 40, TRUE, -1) - // check_witnesses() + check_witnesses() owner.balloon_alert(owner, "you prepare to tear open [target_airlock]...") if(!do_after(carbon_owner, 2.5 SECONDS, target_airlock)) carbon_owner.balloon_alert(carbon_owner, "interrupted!") @@ -208,6 +206,7 @@ target_vehicle.visible_message(span_danger("[target_vehicle] breaks apart as [carbon_owner] bashes it!")) target_vehicle.emp_act(EMP_HEAVY) target_vehicle.take_damage(hit_strength) + check_witnesses() /datum/action/cooldown/vampire/targeted/brawn/check_valid_target(atom/target_atom) . = ..() diff --git a/tff_modular/modules/vampire/powers/potence/lunge.dm b/tff_modular/modules/vampire/powers/potence/lunge.dm index f99884ed74f..43d36d575d9 100644 --- a/tff_modular/modules/vampire/powers/potence/lunge.dm +++ b/tff_modular/modules/vampire/powers/potence/lunge.dm @@ -137,13 +137,13 @@ power_activated_sucessfully() // Am I next to my target to start giving the effects? if(!owner.Adjacent(hit_atom)) - // check_witnesses() + check_witnesses() return var/mob/living/user = owner var/mob/living/carbon/target = hit_atom - // check_witnesses(target) + check_witnesses() // Did I slip or get knocked unconscious? if(user.body_position != STANDING_UP || user.incapacitated) var/send_dir = get_dir(user, target_turf) diff --git a/tff_modular/modules/vampire/powers/presence/awe.dm b/tff_modular/modules/vampire/powers/presence/awe.dm index ec5a4fbf3a2..3ab44e4927f 100644 --- a/tff_modular/modules/vampire/powers/presence/awe.dm +++ b/tff_modular/modules/vampire/powers/presence/awe.dm @@ -2,7 +2,7 @@ name = "Awe" desc = "Project an aura of supernatural presence that subtly influences those around you." button_icon_state = "power_awe" - power_explanation = "Project an aura around yourself that subtly affects everyone nearby.\n\ + power_explanation = "Project an aura around yourself that subtly affects everyone in your room.\n\ Effects on those in your aura:\n\ - They can only whisper, unable to speak loudly.\n\ - They are slightly slowed.\n\ @@ -11,14 +11,8 @@ vampire_power_flags = BP_AM_TOGGLE | BP_AM_STATIC_COOLDOWN vampire_check_flags = BP_CANT_USE_IN_TORPOR | BP_CANT_USE_WHILE_STAKED | BP_CANT_USE_IN_FRENZY vitaecost = 30 - constant_vitaecost = 2 - cooldown_time = 10 SECONDS - /// The range of the aura in tiles - var/aura = 5 - -/datum/action/cooldown/vampire/awe/two constant_vitaecost = 1 - aura = 6 + cooldown_time = 10 SECONDS /datum/action/cooldown/vampire/awe/activate_power() . = ..() @@ -30,7 +24,9 @@ /datum/action/cooldown/vampire/awe/use_power() . = ..() - for(var/mob/living/victim in oviewers(aura, owner)) + var/area/vampire_loc = get_area(owner) + var/list/turfs = get_area_turfs(vampire_loc) + for(var/mob/living/victim as anything in turfs) if(can_affect(victim)) victim.apply_status_effect(/datum/status_effect/awed, owner) diff --git a/tff_modular/modules/vampire/powers/presence/entrance.dm b/tff_modular/modules/vampire/powers/presence/entrance.dm index 6def5929b81..2e17178bbe2 100644 --- a/tff_modular/modules/vampire/powers/presence/entrance.dm +++ b/tff_modular/modules/vampire/powers/presence/entrance.dm @@ -122,7 +122,7 @@ /// Alert for entranced status /atom/movable/screen/alert/status_effect/entranced name = "Entranced" - desc = "Your mind has been captured by a supernatural presence. You cannot speak or use items." + desc = "Your mind has been captured by a supernatural presence. You cannot speak or use items. Click to try to resist!" icon_state = "hypnosis" /// Movespeed modifier for the entranced status effect diff --git a/tff_modular/modules/vampire/powers/presence/force_of_personality.dm b/tff_modular/modules/vampire/powers/presence/force_of_personality.dm index b80ecbc83b7..e6238a4390f 100644 --- a/tff_modular/modules/vampire/powers/presence/force_of_personality.dm +++ b/tff_modular/modules/vampire/powers/presence/force_of_personality.dm @@ -1,19 +1,17 @@ /datum/action/cooldown/vampire/force_of_personality name = "Force of Personality" - desc = "Project an overwhelming aura of authority that causes those around you to involuntarily step back." + desc = "Project an overwhelming aura of authority that causes those around you to fall down." button_icon_state = "power_fop" - power_explanation = "Project an aura around yourself that subtly pushes people away.\n\ - Effects on those in 3 tile range. No one will be able to voluntarily approach you.\n\ - Targets must be able to see you to be affected.\n\ - Lasts 1 minute." - vampire_power_flags = BP_AM_TOGGLE | BP_AM_STATIC_COOLDOWN + power_explanation = "Project an aura around yourself that subtly pushes people to fall down.\n\ + Effects on those in 3 tile range.\n\ + Targets must be able to see you to be affected." + vampire_power_flags = BP_AM_TOGGLE vampire_check_flags = BP_CANT_USE_IN_TORPOR | BP_CANT_USE_WHILE_STAKED | BP_CANT_USE_IN_FRENZY vitaecost = 30 constant_vitaecost = 2 cooldown_time = 30 SECONDS /// The range of the aura in tiles, this is further than the actual effect just so we can hit them with the status effect before they even get close enough. - var/aura_range = 7 - var/deactivate_timer + var/aura_range = 3 /datum/action/cooldown/vampire/force_of_personality/two constant_vitaecost = 1 @@ -21,20 +19,14 @@ /datum/action/cooldown/vampire/force_of_personality/activate_power() . = ..() to_chat(owner, span_notice("You project an overwhelming sense of authority."), type = MESSAGE_TYPE_INFO) - deactivate_timer = addtimer(CALLBACK(src, PROC_REF(deactivate_power)), 1 MINUTES, TIMER_STOPPABLE) + for(var/mob/living/carbon/victims as anything in oviewers(aura_range, owner)) + if(!can_affect(victims)) + continue + victims.Knockdown(2 SECONDS) + victims.Stun(1) + to_chat(victims, span_awe("Bend Down!")) -/datum/action/cooldown/vampire/force_of_personality/deactivate_power() - . = ..() - to_chat(owner, span_notice("You withdraw your authoritative presence."), type = MESSAGE_TYPE_INFO) - if(deactivate_timer) - deltimer(deactivate_timer) - deactivate_timer = null - -/datum/action/cooldown/vampire/force_of_personality/use_power() - . = ..() - for(var/mob/living/victim in oviewers(aura_range, owner)) - if(can_affect(victim)) - victim.apply_status_effect(/datum/status_effect/intimidated, owner) + deactivate_power() /// Checks if this victim can be affected by the force of personality aura /datum/action/cooldown/vampire/force_of_personality/proc/can_affect(mob/living/victim) @@ -44,61 +36,10 @@ return FALSE if(victim.stat != CONSCIOUS) return FALSE + if(!iscarbon(victim)) + return FALSE if(victim.is_blind() || victim.is_nearsighted_currently()) return FALSE - if(HAS_MIND_TRAIT(victim, TRAIT_VAMPIRE_ALIGNED) || IS_CURATOR(victim) || HAS_MIND_TRAIT(victim, TRAIT_UNCONVERTABLE)) + if(HAS_MIND_TRAIT(victim, TRAIT_VAMPIRE_ALIGNED) || IS_CURATOR(victim)) return FALSE return TRUE - -/// Status effect for being affected by Force of Personality -/datum/status_effect/intimidated - id = "intimidated" - status_type = STATUS_EFFECT_REFRESH - duration = 10 SECONDS - tick_interval = 0.2 SECONDS - processing_speed = STATUS_EFFECT_PRIORITY - alert_type = null - /// The vampire projecting the aura - var/mob/living/source_vampire - /// The range at which the effect triggers - var/trigger_range = 3 - COOLDOWN_DECLARE(message_cooldown) - -/datum/status_effect/intimidated/on_creation(mob/living/new_owner, mob/living/vampire) - source_vampire = vampire - return ..() - -/datum/status_effect/intimidated/Destroy() - source_vampire = null - return ..() - -/datum/status_effect/intimidated/on_apply() - if(!iscarbon(owner)) - return FALSE - return TRUE - -/datum/status_effect/intimidated/tick(seconds_between_ticks) - if(QDELETED(source_vampire) || source_vampire.stat == DEAD) - qdel(src) - return - - if(INCAPACITATED_IGNORING(owner, INCAPABLE_RESTRAINTS)) - return - - // Only check if we're within range of the vampire - if(get_dist(owner, source_vampire) > trigger_range) - return - - // Step away from the vampire - if(owner.body_position == STANDING_UP) - var/away_dir = get_dir(source_vampire.loc, owner.loc) - var/turf/retreat_turf = get_step(owner.loc, away_dir) - // Make sure we're not stepping into the vampire or into a wall - if(retreat_turf && !retreat_turf.is_blocked_turf()) - if(COOLDOWN_FINISHED(src, message_cooldown)) - COOLDOWN_START(src, message_cooldown, 3 SECONDS) - owner.visible_message(span_warning("[owner] takes a hurried step back."), span_awe("You don't dare approach [source_vampire.p_them()]...")) - owner.Move(retreat_turf, away_dir) - -/datum/status_effect/intimidated/get_examine_text() - return span_warning("[owner.p_They()] seem[owner.p_s()] intimidated.") diff --git a/tff_modular/modules/vampire/powers/presence/presence.dm b/tff_modular/modules/vampire/powers/presence/presence.dm index 2eef1df50de..b257b0bd7d9 100644 --- a/tff_modular/modules/vampire/powers/presence/presence.dm +++ b/tff_modular/modules/vampire/powers/presence/presence.dm @@ -6,4 +6,4 @@ level_2 = list(/datum/action/cooldown/vampire/targeted/entrance, /datum/action/cooldown/vampire/targeted/summon) level_3 = list(/datum/action/cooldown/vampire/awe, /datum/action/cooldown/vampire/targeted/entrance/two, /datum/action/cooldown/vampire/targeted/summon) level_4 = list(/datum/action/cooldown/vampire/awe, /datum/action/cooldown/vampire/targeted/entrance/two, /datum/action/cooldown/vampire/targeted/summon, /datum/action/cooldown/vampire/force_of_personality) - level_5 = list(/datum/action/cooldown/vampire/awe/two, /datum/action/cooldown/vampire/targeted/entrance/three, /datum/action/cooldown/vampire/targeted/summon/two, /datum/action/cooldown/vampire/force_of_personality/two) + level_5 = list(/datum/action/cooldown/vampire/awe, /datum/action/cooldown/vampire/targeted/entrance/three, /datum/action/cooldown/vampire/targeted/summon/two, /datum/action/cooldown/vampire/force_of_personality/two) diff --git a/tff_modular/modules/vampire/powers/presence/summon.dm b/tff_modular/modules/vampire/powers/presence/summon.dm index e6262bc7678..e3ed31b4e56 100644 --- a/tff_modular/modules/vampire/powers/presence/summon.dm +++ b/tff_modular/modules/vampire/powers/presence/summon.dm @@ -20,7 +20,7 @@ ranged_mousepointer = 'tff_modular/modules/vampire/icons/vampire_summon.dmi' /// Maximum duration of the summon effect - var/summon_duration = 30 SECONDS + var/summon_duration = 10 SECONDS /datum/action/cooldown/vampire/targeted/summon/two vitaecost = 30 diff --git a/tff_modular/modules/vampire/powers/thaumaturgy/bloodbolt.dm b/tff_modular/modules/vampire/powers/thaumaturgy/bloodbolt.dm index 40b8be90c39..653b847c97f 100644 --- a/tff_modular/modules/vampire/powers/thaumaturgy/bloodbolt.dm +++ b/tff_modular/modules/vampire/powers/thaumaturgy/bloodbolt.dm @@ -17,7 +17,7 @@ /datum/action/cooldown/vampire/targeted/bloodbolt/fire_targeted_power(atom/target_atom, list/modifiers) . = ..() var/mob/living/living_owner = owner - // check_witnesses(target_atom) + check_witnesses() living_owner.balloon_alert(living_owner, "you fire a blood bolt!") living_owner.face_atom(target_atom) living_owner.changeNext_move(CLICK_CD_RANGE) diff --git a/tff_modular/modules/vampire/powers/thaumaturgy/blooddrain.dm b/tff_modular/modules/vampire/powers/thaumaturgy/blooddrain.dm index 044c23dc174..90bf8056f27 100644 --- a/tff_modular/modules/vampire/powers/thaumaturgy/blooddrain.dm +++ b/tff_modular/modules/vampire/powers/thaumaturgy/blooddrain.dm @@ -20,8 +20,7 @@ /datum/action/cooldown/vampire/targeted/blooddrain/fire_targeted_power(atom/target_atom) . = ..() var/mob/living/living_owner = owner - /* var/mob/living/living_target = target_atom - check_witnesses(living_target) */ + check_witnesses() living_owner.face_atom(target_atom) living_owner.changeNext_move(CLICK_CD_RANGE) living_owner.newtonian_move(get_dir(target_atom, living_owner)) @@ -54,7 +53,7 @@ /obj/projectile/magic/blood_drain/fire(angle, atom/direct_target) if(!firer) CRASH("Projectile [src] fired with no firer") //We don't even want any of the rest of this to play out if we don't have a firer - drain_beam = Beam(firer, icon = 'icons/effects/beam.dmi', icon_state = "drain_life", time = 10 SECONDS, maxdistance = 7, beam_type = /obj/effect/ebeam/blood, beam_color = COLOR_RED) + drain_beam = Beam(firer, icon = 'icons/effects/beam.dmi', icon_state = "drain_life", time = 10 SECONDS, maxdistance = 7, beam_type = /obj/effect/ebeam/blood, beam_color = COLOR_DARK_RED) return ..() /obj/projectile/magic/blood_drain/on_hit(mob/living/carbon/target, blocked, pierce_hit) diff --git a/tff_modular/modules/vampire/society.dm b/tff_modular/modules/vampire/society.dm index da10575bda0..bc8bb2bd051 100644 --- a/tff_modular/modules/vampire/society.dm +++ b/tff_modular/modules/vampire/society.dm @@ -1,21 +1,15 @@ -/** - * Resumes society, called when someone is assigned Vampire - /datum/antagonist/vampire/proc/check_start_society() - if(!CONFIG_GET(flag/allow_vampire_prince)) + if(SSvsociety.can_fire || !CONFIG_GET(flag/allow_vampire_prince)) return + if(length(GLOB.all_vampires) >= 3) - can_become_prince = TRUE + SSvsociety.start_time = world.time + SSvsociety.can_fire = TRUE message_admins("Vampire Society has started, as there are [length(GLOB.all_vampires)] vampires active.") log_game("Vampire Society has started, as there are [length(GLOB.all_vampires)] vampires active.") - else - can_become_prince = FALSE -**/ -/** - * Turns the player into a prince. -**/ + /datum/antagonist/vampire/proc/princify() - rank_up(5, TRUE) // Rank up a lot. + rank_up(8, TRUE) // Rank up a lot. to_chat(owner.current, span_cult_bold("As a true prince, you find some of your old power returning to you!")) owner.current.playsound_local(null, 'tff_modular/modules/vampire/sound/prince.ogg', 100, FALSE, pressure_affected = FALSE) prince = TRUE diff --git a/tff_modular/modules/vampire/tracking_vampire.dm b/tff_modular/modules/vampire/tracking_vampire.dm deleted file mode 100644 index 7bb7c02bf74..00000000000 --- a/tff_modular/modules/vampire/tracking_vampire.dm +++ /dev/null @@ -1,36 +0,0 @@ -/* -/datum/antagonist/vampire/proc/setup_tracker(mob/living/body) - cleanup_tracker() - tracker = new(body, REF(src)) - - for(var/datum/antagonist/vassal/vassal in vassals) - vassal.monitor?.add_to_tracking_network(tracker.tracking_beacon) - tracker.tracking_beacon.toggle_visibility(TRUE) - -/datum/antagonist/vampire/proc/cleanup_tracker() - if(tracker) - QDEL_NULL(tracker) - -/** - * An abstract object contained within the vampire, used to host the team_monitor component. -**/ -/obj/effect/abstract/vampire_tracker_holder - name = "vampire tracker holder" - desc = span_danger("You REALLY shouldn't be seeing this!") - - var/datum/component/tracking_beacon/tracking_beacon - -/obj/effect/abstract/vampire_tracker_holder/Initialize(mapload, key) - . = ..() - tracking_beacon = AddComponent(/datum/component/tracking_beacon, \ - _frequency_key = key, \ - _colour = "#960000", \ - _global = TRUE, \ - _always_update = TRUE, \ - ) - -/obj/effect/abstract/vampire_tracker_holder/Destroy(force) - tracking_beacon.toggle_visibility(FALSE) - QDEL_NULL(tracking_beacon) - . = ..() -*/ diff --git a/tff_modular/modules/vampire/vamp_society.dm b/tff_modular/modules/vampire/vamp_society.dm new file mode 100644 index 00000000000..62fdb76d7ff --- /dev/null +++ b/tff_modular/modules/vampire/vamp_society.dm @@ -0,0 +1,74 @@ +SUBSYSTEM_DEF(vsociety) + name = "Vampire Society" + wait = 5 MINUTES + ss_flags = SS_NO_INIT | SS_BACKGROUND + can_fire = FALSE + + // Are we currently polling? + var/currently_polling = FALSE + + // Ref to the prince datum + var/datum/weakref/princedatum + + var/start_time = 0 + + var/time_to_wait = 9 MINUTES + +/datum/controller/subsystem/vsociety/fire(resumed = FALSE) + var/time_elapsed = world.time - start_time + + // Give them some breathing room + if(time_elapsed < time_to_wait) + return + + if(!princedatum && !currently_polling) + for(var/datum/antagonist/vampire as anything in GLOB.all_vampires) + to_chat(vampire.owner.current, span_announce("* Vampire Tip: A vote for Prince will occur soon. If you are interested in leading your fellow kindred, read up on princes in your info panel now!")) + addtimer(CALLBACK(src, PROC_REF(poll_for_prince)), 2 MINUTES) + message_admins("Vampire society has fired, and a prince poll will occur in 2 minutes.") + log_game("Vampire society has fired, and a prince poll will occur soon.") + +/datum/controller/subsystem/vsociety/proc/poll_for_prince() + message_admins("Vampire society is now polling for a new prince.") + log_game("Vampire society is now polling for a new prince.") + + //Build a list of mobs in GLOB.all_vampires + var/list/vampire_living_candidates = list() + var/list/yes_candidate = list() + for(var/datum/antagonist/vampire as anything in GLOB.all_vampires) + var/currentmob = vampire.owner?.current + + if(!isliving(currentmob)) //Are we mob/living? + continue + + var/mob/living/livingmob = currentmob + if(livingmob.health <= HEALTH_THRESHOLD_DEAD) // we check health instead of stat to avoid skipping out on vamps that are in torpor or something + continue + + vampire_living_candidates += currentmob + currently_polling = TRUE + var/icon/prince_icon = icon('tff_modular/modules/vampire/icons/vampiric.dmi', "prince") + for(var/mob/living/candidate in vampire_living_candidates) + yes_candidate = SSpolling.poll_candidates( + question = "You are eligible for princedom.", + group = list(candidate), + poll_time = 3 MINUTES, + flash_window = TRUE, + alert_pic = prince_icon, + role_name_text = "Prince", + start_signed_up = FALSE, + announce_chosen = FALSE, + custom_response_messages = list( + POLL_RESPONSE_SIGNUP = "You have made your bid for princedom.
    * Note: Princedom has certain expectations placed upon you. If you are not in a position to enforce the masquerade, consider letting someone else take this burden.", + POLL_RESPONSE_UNREGISTERED = "You have removed your bid to princedom.", + ), + ) + prince_icon.Scale(24, 24) + currently_polling = FALSE + var/mob/living/chosen_candidate + if(length(yes_candidate)) + chosen_candidate = pick(yes_candidate) + var/datum/antagonist/vampire/antag_datum = IS_VAMPIRE(chosen_candidate) + antag_datum.princify() + else + time_to_wait = 30 MINUTES diff --git a/tgstation.dme b/tgstation.dme index ae126d52fda..3363d1f95e3 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -9942,7 +9942,7 @@ #include "tff_modular\modules\vampire\society.dm" #include "tff_modular\modules\vampire\status_effects.dm" #include "tff_modular\modules\vampire\torpor_vampire.dm" -#include "tff_modular\modules\vampire\tracking_vampire.dm" +#include "tff_modular\modules\vampire\vamp_society.dm" #include "tff_modular\modules\vampire\clans\_clan.dm" #include "tff_modular\modules\vampire\clans\assignclan.dm" #include "tff_modular\modules\vampire\clans\brujah.dm" From d920de038a5a84dcc7bd4404a86845c5ca1689c2 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Thu, 30 Apr 2026 02:51:44 +0300 Subject: [PATCH 135/149] Update awe.dm --- tff_modular/modules/vampire/powers/presence/awe.dm | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/tff_modular/modules/vampire/powers/presence/awe.dm b/tff_modular/modules/vampire/powers/presence/awe.dm index 3ab44e4927f..ec5a4fbf3a2 100644 --- a/tff_modular/modules/vampire/powers/presence/awe.dm +++ b/tff_modular/modules/vampire/powers/presence/awe.dm @@ -2,7 +2,7 @@ name = "Awe" desc = "Project an aura of supernatural presence that subtly influences those around you." button_icon_state = "power_awe" - power_explanation = "Project an aura around yourself that subtly affects everyone in your room.\n\ + power_explanation = "Project an aura around yourself that subtly affects everyone nearby.\n\ Effects on those in your aura:\n\ - They can only whisper, unable to speak loudly.\n\ - They are slightly slowed.\n\ @@ -11,8 +11,14 @@ vampire_power_flags = BP_AM_TOGGLE | BP_AM_STATIC_COOLDOWN vampire_check_flags = BP_CANT_USE_IN_TORPOR | BP_CANT_USE_WHILE_STAKED | BP_CANT_USE_IN_FRENZY vitaecost = 30 - constant_vitaecost = 1 + constant_vitaecost = 2 cooldown_time = 10 SECONDS + /// The range of the aura in tiles + var/aura = 5 + +/datum/action/cooldown/vampire/awe/two + constant_vitaecost = 1 + aura = 6 /datum/action/cooldown/vampire/awe/activate_power() . = ..() @@ -24,9 +30,7 @@ /datum/action/cooldown/vampire/awe/use_power() . = ..() - var/area/vampire_loc = get_area(owner) - var/list/turfs = get_area_turfs(vampire_loc) - for(var/mob/living/victim as anything in turfs) + for(var/mob/living/victim in oviewers(aura, owner)) if(can_affect(victim)) victim.apply_status_effect(/datum/status_effect/awed, owner) From b12a365f0da577f08f91be5ffb307fe216b7349a Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Thu, 30 Apr 2026 09:10:55 +0300 Subject: [PATCH 136/149] =?UTF-8?q?=D0=B5=D1=89=D0=B5=20=D0=BF=D0=B0=D1=80?= =?UTF-8?q?=D1=83=20=D0=BF=D1=80=D0=B0=D0=B2=D0=BE=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tff_modular/modules/vampire/powers/dominate/dominate.dm | 4 ++-- tff_modular/modules/vampire/powers/dominate/mesmerize.dm | 6 ++++++ tff_modular/modules/vampire/powers/presence/awe.dm | 4 ++++ .../modules/vampire/powers/presence/force_of_personality.dm | 6 ++++-- tff_modular/modules/vampire/powers/presence/presence.dm | 4 ++-- 5 files changed, 18 insertions(+), 6 deletions(-) diff --git a/tff_modular/modules/vampire/powers/dominate/dominate.dm b/tff_modular/modules/vampire/powers/dominate/dominate.dm index 5063ad61b8a..f0556320d2d 100644 --- a/tff_modular/modules/vampire/powers/dominate/dominate.dm +++ b/tff_modular/modules/vampire/powers/dominate/dominate.dm @@ -8,9 +8,9 @@ level_2 = list(/datum/action/cooldown/vampire/targeted/mesmerize/two, /datum/action/cooldown/vampire/targeted/command/two) level_3 = list(/datum/action/cooldown/vampire/targeted/mesmerize/three, /datum/action/cooldown/vampire/targeted/command/three) level_4 = list(/datum/action/cooldown/vampire/targeted/mesmerize/four, /datum/action/cooldown/vampire/targeted/command/four) - level_5 = list(/datum/action/cooldown/vampire/targeted/mesmerize/four, /datum/action/cooldown/vampire/targeted/command/five) + level_5 = list(/datum/action/cooldown/vampire/targeted/mesmerize/five, /datum/action/cooldown/vampire/targeted/command/five) /datum/discipline/dominate/ventrue level_1 = list(/datum/action/cooldown/vampire/targeted/mesmerize/three, /datum/action/cooldown/vampire/targeted/command/three) level_2 = list(/datum/action/cooldown/vampire/targeted/mesmerize/four, /datum/action/cooldown/vampire/targeted/command/four) - level_3 = list(/datum/action/cooldown/vampire/targeted/mesmerize/four, /datum/action/cooldown/vampire/targeted/command/five) + level_3 = list(/datum/action/cooldown/vampire/targeted/mesmerize/five, /datum/action/cooldown/vampire/targeted/command/five) diff --git a/tff_modular/modules/vampire/powers/dominate/mesmerize.dm b/tff_modular/modules/vampire/powers/dominate/mesmerize.dm index 369486a0f99..0911bab2f04 100644 --- a/tff_modular/modules/vampire/powers/dominate/mesmerize.dm +++ b/tff_modular/modules/vampire/powers/dominate/mesmerize.dm @@ -48,6 +48,12 @@ level_current = 4 target_range = 4 +/datum/action/cooldown/vampire/targeted/mesmerize/five + vitaecost = 60 + level_current = 5 + target_range = 5 + mesmerize_delay = 5 SECONDS + /datum/action/cooldown/vampire/targeted/mesmerize/can_use() . = ..() if(!.) diff --git a/tff_modular/modules/vampire/powers/presence/awe.dm b/tff_modular/modules/vampire/powers/presence/awe.dm index ec5a4fbf3a2..3ae0cbbe6d9 100644 --- a/tff_modular/modules/vampire/powers/presence/awe.dm +++ b/tff_modular/modules/vampire/powers/presence/awe.dm @@ -20,6 +20,10 @@ constant_vitaecost = 1 aura = 6 +/datum/action/cooldown/vampire/awe/three + constant_vitaecost = 0.8 + aura = 7 + /datum/action/cooldown/vampire/awe/activate_power() . = ..() to_chat(owner, span_notice("You extend your supernatural presence."), type = MESSAGE_TYPE_INFO) diff --git a/tff_modular/modules/vampire/powers/presence/force_of_personality.dm b/tff_modular/modules/vampire/powers/presence/force_of_personality.dm index e6238a4390f..44aaeec63b8 100644 --- a/tff_modular/modules/vampire/powers/presence/force_of_personality.dm +++ b/tff_modular/modules/vampire/powers/presence/force_of_personality.dm @@ -8,13 +8,12 @@ vampire_power_flags = BP_AM_TOGGLE vampire_check_flags = BP_CANT_USE_IN_TORPOR | BP_CANT_USE_WHILE_STAKED | BP_CANT_USE_IN_FRENZY vitaecost = 30 - constant_vitaecost = 2 cooldown_time = 30 SECONDS /// The range of the aura in tiles, this is further than the actual effect just so we can hit them with the status effect before they even get close enough. var/aura_range = 3 /datum/action/cooldown/vampire/force_of_personality/two - constant_vitaecost = 1 + aura_range = 4 /datum/action/cooldown/vampire/force_of_personality/activate_power() . = ..() @@ -24,6 +23,7 @@ continue victims.Knockdown(2 SECONDS) victims.Stun(1) + victims.set_resting(TRUE, instant = TRUE) to_chat(victims, span_awe("Bend Down!")) deactivate_power() @@ -40,6 +40,8 @@ return FALSE if(victim.is_blind() || victim.is_nearsighted_currently()) return FALSE + if(victim.can_block_magic(MAGIC_RESISTANCE_MIND, charge_cost = 1)) + return FALSE if(HAS_MIND_TRAIT(victim, TRAIT_VAMPIRE_ALIGNED) || IS_CURATOR(victim)) return FALSE return TRUE diff --git a/tff_modular/modules/vampire/powers/presence/presence.dm b/tff_modular/modules/vampire/powers/presence/presence.dm index b257b0bd7d9..95696bba03a 100644 --- a/tff_modular/modules/vampire/powers/presence/presence.dm +++ b/tff_modular/modules/vampire/powers/presence/presence.dm @@ -5,5 +5,5 @@ level_1 = list(/datum/action/cooldown/vampire/targeted/entrance) level_2 = list(/datum/action/cooldown/vampire/targeted/entrance, /datum/action/cooldown/vampire/targeted/summon) level_3 = list(/datum/action/cooldown/vampire/awe, /datum/action/cooldown/vampire/targeted/entrance/two, /datum/action/cooldown/vampire/targeted/summon) - level_4 = list(/datum/action/cooldown/vampire/awe, /datum/action/cooldown/vampire/targeted/entrance/two, /datum/action/cooldown/vampire/targeted/summon, /datum/action/cooldown/vampire/force_of_personality) - level_5 = list(/datum/action/cooldown/vampire/awe, /datum/action/cooldown/vampire/targeted/entrance/three, /datum/action/cooldown/vampire/targeted/summon/two, /datum/action/cooldown/vampire/force_of_personality/two) + level_4 = list(/datum/action/cooldown/vampire/awe/two, /datum/action/cooldown/vampire/targeted/entrance/two, /datum/action/cooldown/vampire/targeted/summon, /datum/action/cooldown/vampire/force_of_personality) + level_5 = list(/datum/action/cooldown/vampire/awe/three, /datum/action/cooldown/vampire/targeted/entrance/three, /datum/action/cooldown/vampire/targeted/summon/two, /datum/action/cooldown/vampire/force_of_personality/two) From 29570bfda75d162be7aa209ad8cd5da0ce5d4878 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Thu, 30 Apr 2026 09:16:11 +0300 Subject: [PATCH 137/149] =?UTF-8?q?=D0=B5=D1=89=D0=B5=20=D1=87=D1=83=D1=82?= =?UTF-8?q?=D1=8C=20=D1=87=D1=83=D1=82=D1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modules/vampire/powers/celerity/celerity.dm | 9 +++++++-- tff_modular/modules/vampire/powers/celerity/haste.dm | 12 +++++++++++- .../modules/vampire/powers/celerity/quickness.dm | 4 +--- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/tff_modular/modules/vampire/powers/celerity/celerity.dm b/tff_modular/modules/vampire/powers/celerity/celerity.dm index bdd33096c36..a18526ae698 100644 --- a/tff_modular/modules/vampire/powers/celerity/celerity.dm +++ b/tff_modular/modules/vampire/powers/celerity/celerity.dm @@ -7,5 +7,10 @@ level_1 = list(/datum/action/cooldown/vampire/targeted/haste) level_2 = list(/datum/action/cooldown/vampire/targeted/haste/two) level_3 = list(/datum/action/cooldown/vampire/targeted/haste/three) - level_4 = list(/datum/action/cooldown/vampire/targeted/haste/three, /datum/action/cooldown/vampire/exactitude) - level_5 = null + level_4 = list(/datum/action/cooldown/vampire/targeted/haste/four, /datum/action/cooldown/vampire/exactitude) + level_4 = list(/datum/action/cooldown/vampire/targeted/haste/five, /datum/action/cooldown/vampire/exactitude) + +/datum/discipline/celerity/apply_discipline_quirks(datum/antagonist/vampire/clan_owner) + . = ..() + owner.add_traits(clan_owner.vampire_traits, TRAIT_PERFECT_ATTACKER, TRAIT_VAMPIRE) + owner.next_move_modifier *= 0.9 diff --git a/tff_modular/modules/vampire/powers/celerity/haste.dm b/tff_modular/modules/vampire/powers/celerity/haste.dm index 150f268c465..40f43ab02dd 100644 --- a/tff_modular/modules/vampire/powers/celerity/haste.dm +++ b/tff_modular/modules/vampire/powers/celerity/haste.dm @@ -26,9 +26,19 @@ /datum/action/cooldown/vampire/targeted/haste/three vitaecost = 30 - cooldown_time = 4 SECONDS + cooldown_time = 5 SECONDS level_current = 3 +/datum/action/cooldown/vampire/targeted/haste/four + vitaecost = 30 + cooldown_time = 5 SECONDS + level_current = 4 + +/datum/action/cooldown/vampire/targeted/haste/five + vitaecost = 25 + cooldown_time = 4.5 SECONDS + level_current = 5 + /datum/action/cooldown/vampire/targeted/haste/can_use() . = ..() if(!.) diff --git a/tff_modular/modules/vampire/powers/celerity/quickness.dm b/tff_modular/modules/vampire/powers/celerity/quickness.dm index 87b62300b7c..bbda4fa48a4 100644 --- a/tff_modular/modules/vampire/powers/celerity/quickness.dm +++ b/tff_modular/modules/vampire/powers/celerity/quickness.dm @@ -21,12 +21,10 @@ /datum/action/cooldown/vampire/exactitude/activate_power() . = ..() RegisterSignal(owner, COMSIG_LIVING_EARLY_UNARMED_ATTACK, PROC_REF(on_unarmed_attack)) - ADD_TRAIT(owner, TRAIT_PERFECT_ATTACKER, REF(src)) /datum/action/cooldown/vampire/exactitude/deactivate_power() . = ..() UnregisterSignal(owner, COMSIG_LIVING_EARLY_UNARMED_ATTACK) - REMOVE_TRAIT(owner, TRAIT_PERFECT_ATTACKER, REF(src)) /datum/action/cooldown/vampire/exactitude/continue_active() . = ..() @@ -42,7 +40,7 @@ if(living_target.stat != DEAD) // don't focus on dead targets return NONE - for(var/mob/living/to_attack in oview(1, source)) + for(var/mob/living/to_attack in oview(2, source)) if(to_attack.stat == DEAD || to_attack.invisibility > source.see_invisible) continue source.face_atom(to_attack) From 1efaf058541a9083b9b1b3b650ffeb16ee2f6c18 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Thu, 30 Apr 2026 19:54:24 +0300 Subject: [PATCH 138/149] Update fortitude.dm --- .../vampire/powers/fortitude/fortitude.dm | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/tff_modular/modules/vampire/powers/fortitude/fortitude.dm b/tff_modular/modules/vampire/powers/fortitude/fortitude.dm index 1fb3ea3f86d..e5cbb999753 100644 --- a/tff_modular/modules/vampire/powers/fortitude/fortitude.dm +++ b/tff_modular/modules/vampire/powers/fortitude/fortitude.dm @@ -8,7 +8,7 @@ level_2 = list(/datum/action/cooldown/vampire/fortitude/two) level_3 = list(/datum/action/cooldown/vampire/fortitude/three) level_4 = list(/datum/action/cooldown/vampire/fortitude/four) - level_5 = null + level_5 = list(/datum/action/cooldown/vampire/fortitude/five) /** * FORTITUDE @@ -17,6 +17,7 @@ * Level 2: Push immunity * Level 3: Dismember resistance * Level 4: Complete stun immunity + * Level 5: Grab Resistance */ /datum/action/cooldown/vampire/fortitude @@ -40,20 +41,16 @@ var/push = FALSE var/dismember = FALSE var/stun = FALSE - + var/grab = FALSE var/burn_resistance = 0.9 /datum/action/cooldown/vampire/fortitude/two - vitaecost = 20 - constant_vitaecost = 1.5 resistance = 0.6 burn_resistance = 0.8 pierce = TRUE push = TRUE /datum/action/cooldown/vampire/fortitude/three - vitaecost = 30 - constant_vitaecost = 2 resistance = 0.4 burn_resistance = 0.7 pierce = TRUE @@ -61,8 +58,6 @@ dismember = TRUE /datum/action/cooldown/vampire/fortitude/four - vitaecost = 20 - constant_vitaecost = 2 resistance = 0.3 burn_resistance = 0.6 pierce = TRUE @@ -70,6 +65,15 @@ dismember = TRUE stun = TRUE +/datum/action/cooldown/vampire/fortitude/five + resistance = 0.3 + burn_resistance = 0.5 + pierce = TRUE + push = TRUE + dismember = TRUE + stun = TRUE + grab = TRUE + /datum/action/cooldown/vampire/fortitude/activate_power() . = ..() owner.balloon_alert(owner, "fortitude turned on.") @@ -84,6 +88,9 @@ ADD_TRAIT(owner, TRAIT_PUSHIMMUNE, REF(src)) if(stun) ADD_TRAIT(owner, TRAIT_STUNIMMUNE, REF(src)) // They'll get stun resistance + this, who cares. + if(grab) + ADD_TRAIT(owner, TRAIT_GRABRESISTANCE, REF(src)) + var/mob/living/carbon/human/user = owner RegisterSignal(user, COMSIG_MOB_APPLY_DAMAGE, PROC_REF(on_take_damage)) user.physiology.brute_mod *= resistance From ca31521b88dd48019697d56fa6da3fd3ce72e0c9 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Mon, 4 May 2026 02:32:15 +0300 Subject: [PATCH 139/149] Update malkavian_revelations.json --- strings/fluffy/malkavian_revelations.json | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/strings/fluffy/malkavian_revelations.json b/strings/fluffy/malkavian_revelations.json index 6ce3f2634f9..8d29444dad0 100644 --- a/strings/fluffy/malkavian_revelations.json +++ b/strings/fluffy/malkavian_revelations.json @@ -99,7 +99,24 @@ ";Не знаю, спрашивали ли вы меня или нет, но я не вампир.", "Быть вампиром фигово. Так что не верьте рекламе, ребят.", "У меня очень давно не было смертных друзей. Проблема у них такая - любят умирать.", - "Я как-то тащил труп по дому и заметил, что после этого пыли не осталось. Я ведь, получается, пол подмел?", - "Да, некоторую одежду мы снимаем с жертв. Бывает, укусишь кого нибудь, а потом думаешь: Ммм, классные штаны какие!" + "#Я как-то тащил труп по дому и заметил, что после этого пыли не осталось. Я ведь, получается, пол подмел?", + "#Да, некоторую одежду мы снимаем с жертв. Бывает, укусишь кого нибудь, а потом думаешь: Ммм, классные штаны какие!", + "#Он укусил меня в шею, разрушив нашу дружбу", + "#М-м-м... Вкус социального обеспечения.", + "#Трудно быть убийцей, когда у тебя рассеянный склероз.", + "Если бы динозавры дожили до наших времен, то я бы взял себе в качестве питомца Микрораптора. Милые, хищные куропатки.", + "Кто ты такой?", + "продукты однажды купить сходил магазин в я, мне нужных было там но не продуктов, с чем и я ушел ни.", + "Я был рожден солдатом, но кем я стал? Крутым солдатом.", + "#Я должен пытаться пользоваться тактикой, представить себя хищником, который ждет свою жертву.", + "#Кого я обманываю? Я никому не нужен и никогда не буду.", + "Все ваши обвинения мусор, все ваши слова мусор, все ваши мысли мусор, вы мусор.", + "Было бы лучше, если бы ты перестал дышать. Было бы лучше, если бы я перестал дышать", + "Голоса в моей голове говорят быть один, но с ними я уже не один.", + "Змеи вежливы, они сначала предупреждают, а затем кусают. Нужно поучиться у них.", + "Что если я марионетка и мной управляет какой-то странный священник любящий червей? Да нет, бред...", + "#Мир был бы лучше без меня.", + "Люди доставляют мне так много боли, я устал...", + "Бесполезно мечтать." ] } From c826d2de19051b314005482ad02a6fa7ac243f19 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Mon, 4 May 2026 02:32:26 +0300 Subject: [PATCH 140/149] Update malkavian_revelations.json --- strings/fluffy/malkavian_revelations.json | 1 + 1 file changed, 1 insertion(+) diff --git a/strings/fluffy/malkavian_revelations.json b/strings/fluffy/malkavian_revelations.json index 8d29444dad0..13a72d72e85 100644 --- a/strings/fluffy/malkavian_revelations.json +++ b/strings/fluffy/malkavian_revelations.json @@ -102,6 +102,7 @@ "#Я как-то тащил труп по дому и заметил, что после этого пыли не осталось. Я ведь, получается, пол подмел?", "#Да, некоторую одежду мы снимаем с жертв. Бывает, укусишь кого нибудь, а потом думаешь: Ммм, классные штаны какие!", "#Он укусил меня в шею, разрушив нашу дружбу", + "#Здесь нет места другим, мне лишь нужна причина разорвать их глотку.", "#М-м-м... Вкус социального обеспечения.", "#Трудно быть убийцей, когда у тебя рассеянный склероз.", "Если бы динозавры дожили до наших времен, то я бы взял себе в качестве питомца Микрораптора. Милые, хищные куропатки.", From 9a5f611cd6d9c1b0c3ec541ba857d0e52ac944c0 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Fri, 8 May 2026 00:06:19 +0300 Subject: [PATCH 141/149] =?UTF-8?q?=D0=B4=D0=B5=D0=BB=D0=B0=D0=B5=D0=BC=20?= =?UTF-8?q?=D1=88=D1=82=D1=83=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tff_modular/modules/vampire/config.dm | 2 +- tff_modular/modules/vampire/datum_vampire.dm | 7 +++++++ tff_modular/modules/vampire/misc_procs_vampire.dm | 12 ++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/tff_modular/modules/vampire/config.dm b/tff_modular/modules/vampire/config.dm index 75bb7659227..15860d84c64 100644 --- a/tff_modular/modules/vampire/config.dm +++ b/tff_modular/modules/vampire/config.dm @@ -5,7 +5,7 @@ default = "15x15" /datum/config_entry/flag/allow_vampire_prince - default = TRUE + default = FALSE /datum/config_entry/flag/allow_vampire_scourge default = TRUE diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index 8c1023a629e..1bb2b8d300e 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -291,11 +291,18 @@ .["Break Masq"] = CALLBACK(src, PROC_REF(break_masquerade)) .["Add Infraction"] = CALLBACK(src, PROC_REF(give_masquerade_infraction), TRUE) + else if(broke_masquerade) + .["Fix Masq"] = CALLBACK(src, PROC_REF(fix_masquerade)) + if(humanity > 0) .["Humanity Deduct"] = CALLBACK(src, PROC_REF(adjust_humanity), -1, FALSE) + else if(humanity < 10) .["Humanity Add"] = CALLBACK(src, PROC_REF(adjust_humanity), 1, FALSE) + if(!prince) + .["Princify"] = CALLBACK(src, PROC_REF(princify)) + /datum/antagonist/vampire/on_gain() . = ..() ADD_TRAIT(owner, TRAIT_VAMPIRE_ALIGNED, REF(src)) diff --git a/tff_modular/modules/vampire/misc_procs_vampire.dm b/tff_modular/modules/vampire/misc_procs_vampire.dm index 875bb6ae74d..3a44f8f471c 100644 --- a/tff_modular/modules/vampire/misc_procs_vampire.dm +++ b/tff_modular/modules/vampire/misc_procs_vampire.dm @@ -39,6 +39,18 @@ SEND_GLOBAL_SIGNAL(COMSIG_VAMPIRE_BROKE_MASQUERADE, src) GLOB.masquerade_breakers += src +/datum/antagonist/vampire/proc/fix_masquerade(mob/admin) + if(!broke_masquerade) + return + broke_masquerade = FALSE + + owner.current.playsound_local(null, 'tff_modular/modules/vampire/sound/masquerade_violation.ogg', 100, FALSE, pressure_affected = FALSE) + to_chat(owner.current, span_userdanger("Your Masquerade have been restored!")) + + add_team_hud(owner.current) + + GLOB.masquerade_breakers -= src + /** * Increment the masquerade infraction counter and warn the vampire accordingly **/ From 56ab674932c328fa9cdb21840ed7ff9700778a19 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Sun, 10 May 2026 18:38:48 +0300 Subject: [PATCH 142/149] =?UTF-8?q?=D0=B2=D1=80=D0=B5=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D0=BD=D0=BE=20=D1=83=D0=B4=D0=B0=D0=BB=D1=8F=D0=B5=D0=BC=20?= =?UTF-8?q?=D0=BF=D1=80=D0=B8=D0=BD=D1=86=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tff_modular/modules/vampire/powers/auspex/auspex.dm | 3 ++- tff_modular/modules/vampire/society.dm | 9 +-------- tff_modular/modules/vampire/vamp_society.dm | 3 ++- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/tff_modular/modules/vampire/powers/auspex/auspex.dm b/tff_modular/modules/vampire/powers/auspex/auspex.dm index 8093fe610ba..35a24e11e78 100644 --- a/tff_modular/modules/vampire/powers/auspex/auspex.dm +++ b/tff_modular/modules/vampire/powers/auspex/auspex.dm @@ -10,7 +10,8 @@ /datum/discipline/auspex/apply_discipline_quirks(datum/antagonist/vampire/clan_owner) . = ..() - owner.add_traits(clan_owner.vampire_traits, TRAIT_XRAY_HEARING, TRAIT_VAMPIRE) + ADD_TRAIT(owner, TRAIT_XRAY_HEARING, TRAIT_VAMPIRE) + clan_owner.vampire_traits += TRAIT_XRAY_HEARING /datum/action/cooldown/vampire/auspex name = "Auspex" diff --git a/tff_modular/modules/vampire/society.dm b/tff_modular/modules/vampire/society.dm index bc8bb2bd051..7a386071b67 100644 --- a/tff_modular/modules/vampire/society.dm +++ b/tff_modular/modules/vampire/society.dm @@ -1,12 +1,5 @@ /datum/antagonist/vampire/proc/check_start_society() - if(SSvsociety.can_fire || !CONFIG_GET(flag/allow_vampire_prince)) - return - - if(length(GLOB.all_vampires) >= 3) - SSvsociety.start_time = world.time - SSvsociety.can_fire = TRUE - message_admins("Vampire Society has started, as there are [length(GLOB.all_vampires)] vampires active.") - log_game("Vampire Society has started, as there are [length(GLOB.all_vampires)] vampires active.") + return FALSE /datum/antagonist/vampire/proc/princify() rank_up(8, TRUE) // Rank up a lot. diff --git a/tff_modular/modules/vampire/vamp_society.dm b/tff_modular/modules/vampire/vamp_society.dm index 62fdb76d7ff..8b8d97f5320 100644 --- a/tff_modular/modules/vampire/vamp_society.dm +++ b/tff_modular/modules/vampire/vamp_society.dm @@ -1,4 +1,4 @@ -SUBSYSTEM_DEF(vsociety) +/*SUBSYSTEM_DEF(vsociety) name = "Vampire Society" wait = 5 MINUTES ss_flags = SS_NO_INIT | SS_BACKGROUND @@ -72,3 +72,4 @@ SUBSYSTEM_DEF(vsociety) antag_datum.princify() else time_to_wait = 30 MINUTES +*/ From 2e50620832fb982a44892d056f47614ec79930dc Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Mon, 11 May 2026 20:12:18 +0300 Subject: [PATCH 143/149] =?UTF-8?q?=D0=92=D0=B0=D0=BC=D0=BF=D0=B8=D1=80?= =?UTF-8?q?=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modules/vampire/conversion_vampire.dm | 2 +- tff_modular/modules/vampire/datum_vampire.dm | 72 +++++++++++++++---- tff_modular/modules/vampire/dynamic.dm | 5 +- .../modules/vampire/objects/vassal_rack.dm | 32 ++++++++- .../modules/vampire/powers/levelspells.dm | 5 +- .../modules/vampire/vassals/datum_vassal.dm | 64 ++++++++++------- 6 files changed, 135 insertions(+), 45 deletions(-) diff --git a/tff_modular/modules/vampire/conversion_vampire.dm b/tff_modular/modules/vampire/conversion_vampire.dm index e73fe7b6d46..a85181aa702 100644 --- a/tff_modular/modules/vampire/conversion_vampire.dm +++ b/tff_modular/modules/vampire/conversion_vampire.dm @@ -22,7 +22,7 @@ living_vampire.balloon_alert(living_vampire, "enter a clan first.") return FALSE - if(count_vassals() >= 4) + if(count_vassals() >= vassal_limit) living_vampire.balloon_alert(living_vampire, "too many vassals.") return FALSE diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index 1bb2b8d300e..0200a1b6f6f 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -79,6 +79,10 @@ /// Vassals under my control. Periodically remove the dead ones. var/list/datum/antagonist/vassal/vassals = list() + /// How much vassals we can have? + var/vassal_limit = 2 + /// Vampires under my control. Periodically remove the dead ones. + var/list/datum/antagonist/vampire/fledgling/fledglings = list() /// The rank this vampire is at, used to level abilities and strength up var/vampire_level = 0 @@ -104,9 +108,6 @@ var/area/vampire_lair_area var/obj/structure/closet/crate/coffin - /// Tracker so that vassals know where their master is - // var/obj/effect/abstract/vampire_tracker_holder/tracker - /// List of limbs we've applied modifications to. var/list/affected_limbs = list( BODY_ZONE_L_ARM = null, @@ -477,6 +478,19 @@ vassal_report += " the [vassal.owner.assigned_role.title]" report += vassal_report.Join() + if(length(fledglings)) + report += span_header("
    Their fledglings were...") + for(var/datum/antagonist/vampire/fledgling in fledglings) + if(!fledgling.owner) + continue + + var/list/fledgling_report = list() + fledgling_report += "[fledgling.owner.name]" + + if(fledgling.owner.assigned_role) + fledgling_report += " the [fledgling.owner.assigned_role.title]" + report += fledgling_report.Join() + if(objectives_complete) report += span_greentext(span_big("
    The [name] was successful!")) else @@ -686,6 +700,24 @@ continue .++ + for(var/datum/antagonist/vampire/fledgling/fledgling as anything in fledglings) + var/mob/living/fledgling_body = fledgling.owner.current + if(QDELETED(fledgling_body)) + continue + if(only_living && !considered_alive(fledgling.owner)) + continue + if(!HAS_TRAIT(fledgling_body, TRAIT_MIND_TEMPORARILY_GONE)) + if(fledgling_body.stat == DEAD) + if(HAS_TRAIT(fledgling_body, TRAIT_DEFIB_BLACKLISTED)) + continue + if(!fledgling_body.key) + var/mob/dead/observer/fledgling_ghost = fledgling_body.get_ghost(TRUE, TRUE) + if(isnull(fledgling_ghost) || (istype(fledgling_ghost) && !fledgling_ghost.can_reenter_corpse)) + continue + else if(!fledgling_body.key) + continue + .++ + /datum/antagonist/vampire/proc/on_examine(datum/source, mob/examiner, list/examine_text) SIGNAL_HANDLER var/text @@ -701,6 +733,11 @@ examine_text += text return + if(IS_VAMPIRE(examiner) in fledglings) + text += span_cult("This is, [return_full_name()] your Master!") + examine_text += text + return + if(HAS_MIND_TRAIT(examiner, TRAIT_VAMPIRE_ALIGNED)) if(my_clan) @@ -721,17 +758,6 @@ if(diablerie_count > 0 && HAS_TRAIT(examiner, TRAIT_SEE_DIABLERIE)) examine_text += span_cult_large("
    You can see the corrupted marks of a diablerist in [owner.current.p_their()] aura!") -/* -/datum/antagonist/vampire/proc/on_moved(datum/source) - SIGNAL_HANDLER - - var/mob/living/current = owner?.current - if(QDELETED(current)) - return - - tracker?.tracking_beacon?.update_position() -*/ - /datum/antagonist/vampire/proc/setup_limbs(mob/living/carbon/target) if(!iscarbon(target)) return @@ -823,3 +849,21 @@ enrico.eye_color_right = "#663300" enrico.update_body(is_creating = TRUE) + +/datum/antagonist/vampire/fledgling + name = "Fledgling" + vassal_limit = 0 // Cant have vassals because it's a vassal. + vampire_level_unspent = 1 // Very bad start + free_levels_remaining = 0 + humanity = 7 // always 7 because it's fledgling... Yk + +/datum/antagonist/vampire/fledgling/forge_objectives() + // Vassal Objective + var/datum/objective/vampire/serve_objective = new /datum/objective/vampire/vassal + serve_objective.owner = owner + objectives += serve_objective + + // Survive Objective + var/datum/objective/survive/vampire/survive_objective = new + survive_objective.owner = owner + objectives += survive_objective diff --git a/tff_modular/modules/vampire/dynamic.dm b/tff_modular/modules/vampire/dynamic.dm index 31dad96f91f..234e799d0e8 100644 --- a/tff_modular/modules/vampire/dynamic.dm +++ b/tff_modular/modules/vampire/dynamic.dm @@ -4,7 +4,7 @@ pref_flag = ROLE_VAMPIRE preview_antag_datum = /datum/antagonist/vampire weight = 6 - max_antag_cap = 4 + max_antag_cap = list("denominator" = 10) min_pop = 15 /datum/dynamic_ruleset/roundstart/vampire/is_valid_candidate(mob/candidate, client/candidate_client) @@ -25,7 +25,7 @@ midround_type = LIGHT_MIDROUND weight = 6 repeatable = TRUE - max_antag_cap = 4 + max_antag_cap = list("denominator" = 10) min_pop = 15 /datum/dynamic_ruleset/midround/from_living/vampire/is_valid_candidate(mob/candidate, client/candidate_client) @@ -45,7 +45,6 @@ jobban_flag = ROLE_VAMPIRE weight = 10 repeatable = TRUE - max_antag_cap = 4 min_pop = 15 /datum/dynamic_ruleset/latejoin/vampire/is_valid_candidate(mob/candidate, client/candidate_client) diff --git a/tff_modular/modules/vampire/objects/vassal_rack.dm b/tff_modular/modules/vampire/objects/vassal_rack.dm index c0f12163745..744bda49d1a 100644 --- a/tff_modular/modules/vampire/objects/vassal_rack.dm +++ b/tff_modular/modules/vampire/objects/vassal_rack.dm @@ -31,7 +31,7 @@ . = ..() var/datum/antagonist/vampire/vampiredatum = IS_VAMPIRE(user) if(vampiredatum) - var/remaining_vassals = 4 - vampiredatum.count_vassals() + var/remaining_vassals = vampiredatum.vassal_limit - vampiredatum.count_vassals() if(remaining_vassals > 0) . += span_info("You are currently capable of creating [remaining_vassals] more vassal[remaining_vassals == 1 ? "" : "s"].") else @@ -116,15 +116,43 @@ var/datum/antagonist/vampire/vampiredatum = IS_VAMPIRE(user) var/mob/living/carbon/buckled_person = pick(buckled_mobs) - + var/datum/antagonist/vassal/vassaldatum = IS_VASSAL(buckled_person) // oh no let me free this poor soul if(!vampiredatum) user_unbuckle_mob(buckled_person, user) return TRUE + if(IS_VASSAL(buckled_person) && IS_VASSAL(buckled_person) in vampiredatum.vassals) + var/alert_response = tgui_alert( + user = user, \ + message = "What are you willing to do?", + title = "Vassal Management", + buttons = list("Raise Vassal Rank", "Refuse"), + timeout = 15 SECONDS, \ + autofocus = TRUE + ) + if(alert_response == "Raise Vassal Rank") + check_vassal_leveling(buckled_person, vampiredatum) + return TRUE var/obj/item/held_item = user.get_inactive_held_item() try_to_torture(user, buckled_person, held_item) +/obj/structure/vampire/vassalrack/proc/check_vassal_leveling(mob/living/target, datum/antagonist/vampire/master) + if(!IS_VASSAL(target)) + return FALSE + if(master.vampire_level_unspent < 1) + to_chat(master.owner.current, span_bolddanger("You need at least one unspent rank to spent it on vassal.")) + return FALSE + if(length(master.fledglings)) + to_chat(master.owner.current, span_bolddanger("You cant create one more vampire.")) + return FALSE + if(master.current_vitae < 300) + to_chat(master.owner.current, span_bolddanger("You need more vitae.")) + return FALSE + var/datum/antagonist/vassal/fledgling = IS_VASSAL(target) + fledgling.add_vassal_leveling(master) + return TRUE + /obj/structure/vampire/vassalrack/attack_hand_secondary(mob/user, list/modifiers) . = ..() if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN) diff --git a/tff_modular/modules/vampire/powers/levelspells.dm b/tff_modular/modules/vampire/powers/levelspells.dm index 804890d19d8..2843b4f7b7b 100644 --- a/tff_modular/modules/vampire/powers/levelspells.dm +++ b/tff_modular/modules/vampire/powers/levelspells.dm @@ -99,6 +99,9 @@ owner.balloon_alert(owner, "already offering!") return FALSE + if(IS_VASSAL(living_target) && (IS_VASSAL(living_target) in vampiredatum_power.vassals) && length(vampiredatum_power.fledglings)) + owner.balloon_alert(owner, "cannot create one more vampire!") + return FALSE return TRUE /datum/action/cooldown/vampire/targeted/scourgify/fire_targeted_power(atom/target_atom, list/modifiers) @@ -122,7 +125,7 @@ living_target.mind.remove_antag_datum(/datum/antagonist/vassal) // Make, then give the datum - var/datum/antagonist/vampire/scourgedatum = new(living_target.mind) + var/datum/antagonist/vampire/fledgling/scourgedatum = new(living_target.mind) scourgedatum.should_forge_objectives = FALSE // their one objective is to enforce their prince's authority scourgedatum.stinger_sound = null // to avoid several sounds stacking on top of each other living_target.mind.add_antag_datum(scourgedatum) diff --git a/tff_modular/modules/vampire/vassals/datum_vassal.dm b/tff_modular/modules/vampire/vassals/datum_vassal.dm index d2cd383daa0..3775901b171 100644 --- a/tff_modular/modules/vampire/vassals/datum_vassal.dm +++ b/tff_modular/modules/vampire/vassals/datum_vassal.dm @@ -16,12 +16,15 @@ /// List of Powers, like Vampires. var/list/datum/action/powers = list() /// Vassal Traits - var/list/traits_to_add = list( + var/list/vassal_traits = list( TRAIT_VAMPIRE_ALIGNED, TRAIT_NIGHT_VISION, - TRAIT_NOBREATH, - TRAIT_HARDLY_WOUNDED, ) + /// Vassal Type + var/datum/vassal_type/my_type + /// Fledgling rank + var/fledgling_rank = 0 + var/fledgling_final_rank = 4 /datum/antagonist/vassal/antag_panel_data() return "Master : [master.owner.name]" @@ -34,7 +37,7 @@ RegisterSignals(current_mob, list(COMSIG_MOB_LOGIN, COMSIG_MOVABLE_Z_CHANGED), PROC_REF(on_login)) current_mob.update_sight() - current_mob.add_traits(traits_to_add, TRAIT_VAMPIRE) + current_mob.add_traits(vassal_traits, TRAIT_VAMPIRE) // HUD add_team_hud(current_mob) @@ -53,14 +56,8 @@ UnregisterSignal(current_mob, list(COMSIG_ATOM_EXAMINE, COMSIG_MOB_LOGIN, COMSIG_MOVABLE_Z_CHANGED)) current_mob.update_sight() - current_mob.remove_traits(traits_to_add, TRAIT_VAMPIRE) - - // Tracking - // QDEL_NULL(monitor) + current_mob.remove_traits(vassal_traits, TRAIT_VAMPIRE) current_mob.remove_language(/datum/language/vampiric, source = LANGUAGE_VASSAL) - - // Remove traits - REMOVE_TRAITS_IN(current_mob, TRAIT_VAMPIRE) current_mob.remove_faction(FACTION_VAMPIRE) /datum/antagonist/vassal/on_gain() @@ -85,8 +82,6 @@ forge_objectives() /datum/antagonist/vassal/on_removal() - REMOVE_TRAIT(owner, TRAIT_VAMPIRE_ALIGNED, REF(src)) - REMOVE_TRAIT(owner, TRAIT_NIGHT_VISION, REF(src)) // Free them from their Master if(master) master.vassals -= src @@ -100,6 +95,8 @@ powers -= power power.Remove(owner.current) + if(my_type) + my_type.on_remove() return ..() /datum/antagonist/vassal/greet() @@ -141,6 +138,36 @@ owner.remove_antag_datum(/datum/antagonist/vassal) return COMPONENT_MINDSHIELD_DECONVERTED +/datum/antagonist/vassal/proc/add_vassal_leveling(datum/antagonist/vampire/master) + var/mob/living/carbon/fledgling = owner.curren + fledgling_rank += 1 + if(fledgling_rank < fledgling_final_rank) + if(fledgling_rank == 1) + fledgling.add_traits(list(TRAIT_NOBREATH, TRAIT_AGEUSIA), TRAIT_VAMPIRE) + vassal_traits += list(TRAIT_NOBREATH, TRAIT_AGEUSIA) + if(fledgling_rank == 2) + fledgling.add_traits(list(TRAIT_RADIMMUNE, TRAIT_VIRUSIMMUNE), TRAIT_VAMPIRE) + vassal_traits += list(TRAIT_RADIMMUNE, TRAIT_VIRUSIMMUNE) + if(fledgling_rank == 3) + fledgling.add_traits(list(TRAIT_HARDLY_WOUNDED, TRAIT_NOBLOOD), TRAIT_VAMPIRE) + vassal_traits += list(TRAIT_HARDLY_WOUNDED, TRAIT_NOBLOOD) + var/fledgling_rank_remain = 4 - fledgling_rank + to_chat(fledgling, span_awe("You feel you've become stronger, you need [fledgling_rank_remain] ranks to become vampire...")) + to_chat(master.owner.current, span_awe("You feel your vassal becomes stronger, you need [fledgling_rank_remain] ranks to make him vampire...")) + + else if(fledgling_rank >= fledgling_final_rank) + silent = TRUE + fledgling.mind?.remove_antag_datum(/datum/antagonist/vassal) + var/datum/antagonist/vampire/fledgling/new_vampire = fledgling.mind?.add_antag_datum(/datum/antagonist/vampire/fledgling) + var/datum/vampire_clan/masterclan_type = master.my_clan?.type + new_vampire.my_clan = new masterclan_type(new_vampire) + new_vampire.my_clan.on_apply() + master.fledglings += new_vampire + to_chat(fledgling, span_cult_italic("You've become a Fledgling, a Vampire, but your blood is weak now. [master.owner.current.name] is your creator, and you can gain information from him!")) + to_chat(master.owner.current, span_cult_italic("Your vassal becomes a Fledgling, he is very weak right now and needs your help to become stronger.")) + master.rank_down() + master.adjust_blood_volume(-150) + /datum/antagonist/vassal/proc/on_login() SIGNAL_HANDLER var/mob/living/current = owner.current @@ -202,17 +229,6 @@ antag_hud.show_to(target) hud.show_to(antag_hud.target) -/* -/datum/antagonist/vassal/proc/setup_monitor(mob/target) - QDEL_NULL(monitor) - if(QDELETED(master?.owner?.current) || QDELETED(master.tracker)) - return - - monitor = target.AddComponent(/datum/component/team_monitor, REF(master)) - monitor.add_to_tracking_network(master.tracker.tracking_beacon) - monitor.show_hud(target) -*/ - /datum/antagonist/vassal/proc/on_examine(datum/source, mob/examiner, list/examine_text) SIGNAL_HANDLER From 04721c8fda01639bbfc06c359d56548af5b8a790 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Mon, 11 May 2026 20:25:47 +0300 Subject: [PATCH 144/149] =?UTF-8?q?=D1=83=D0=B1=D0=B8=D1=80=D0=B0=D0=B5?= =?UTF-8?q?=D0=BC=20=D0=BB=D0=B8=D1=88=D0=BD=D0=B5=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tff_modular/modules/vampire/objects/vassal_rack.dm | 1 - tff_modular/modules/vampire/powers/fortitude/fortitude.dm | 4 ++-- tff_modular/modules/vampire/vassals/datum_vassal.dm | 6 +----- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/tff_modular/modules/vampire/objects/vassal_rack.dm b/tff_modular/modules/vampire/objects/vassal_rack.dm index 744bda49d1a..c93331e574e 100644 --- a/tff_modular/modules/vampire/objects/vassal_rack.dm +++ b/tff_modular/modules/vampire/objects/vassal_rack.dm @@ -116,7 +116,6 @@ var/datum/antagonist/vampire/vampiredatum = IS_VAMPIRE(user) var/mob/living/carbon/buckled_person = pick(buckled_mobs) - var/datum/antagonist/vassal/vassaldatum = IS_VASSAL(buckled_person) // oh no let me free this poor soul if(!vampiredatum) user_unbuckle_mob(buckled_person, user) diff --git a/tff_modular/modules/vampire/powers/fortitude/fortitude.dm b/tff_modular/modules/vampire/powers/fortitude/fortitude.dm index e5cbb999753..e542cdb8c21 100644 --- a/tff_modular/modules/vampire/powers/fortitude/fortitude.dm +++ b/tff_modular/modules/vampire/powers/fortitude/fortitude.dm @@ -99,8 +99,8 @@ /datum/action/cooldown/vampire/fortitude/proc/on_take_damage(datum/source, damage_amount, damage_type, ...) SIGNAL_HANDLER - var/blood_to_consume = damage_amount / (resistance + 0.1) - vampiredatum_power.adjust_blood_volume(-blood_to_consume) + + vampiredatum_power.adjust_blood_volume(-damage_amount) /datum/action/cooldown/vampire/fortitude/use_power() . = ..() diff --git a/tff_modular/modules/vampire/vassals/datum_vassal.dm b/tff_modular/modules/vampire/vassals/datum_vassal.dm index 3775901b171..898d40a8a85 100644 --- a/tff_modular/modules/vampire/vassals/datum_vassal.dm +++ b/tff_modular/modules/vampire/vassals/datum_vassal.dm @@ -20,8 +20,6 @@ TRAIT_VAMPIRE_ALIGNED, TRAIT_NIGHT_VISION, ) - /// Vassal Type - var/datum/vassal_type/my_type /// Fledgling rank var/fledgling_rank = 0 var/fledgling_final_rank = 4 @@ -95,8 +93,6 @@ powers -= power power.Remove(owner.current) - if(my_type) - my_type.on_remove() return ..() /datum/antagonist/vassal/greet() @@ -139,7 +135,7 @@ return COMPONENT_MINDSHIELD_DECONVERTED /datum/antagonist/vassal/proc/add_vassal_leveling(datum/antagonist/vampire/master) - var/mob/living/carbon/fledgling = owner.curren + var/mob/living/carbon/fledgling = owner.current fledgling_rank += 1 if(fledgling_rank < fledgling_final_rank) if(fledgling_rank == 1) From 4a305e967ff9c90b1a04d6bc7c21dc76797cab55 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Thu, 14 May 2026 17:06:09 +0300 Subject: [PATCH 145/149] =?UTF-8?q?=D1=80=D0=B5=D0=B1=D0=B0=D0=BB=D0=B0?= =?UTF-8?q?=D0=BD=D1=81=D1=8B=20=D0=B8=20=D0=B1=D0=BE=D0=BB=D1=8C=D1=88?= =?UTF-8?q?=D0=B5=20=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D1=8B=20=D0=BE=D1=82=20?= =?UTF-8?q?=D1=87=D0=B5=D0=BB=D0=BE=D0=B2=D0=B5=D1=87=D0=BD=D0=BE=D1=81?= =?UTF-8?q?=D1=82=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/__DEFINES/~ff_defines/vampire.dm | 7 ++- .../species/hemophage/corrupted_tongue.dm | 2 + tff_modular/modules/vampire/clans/toreador.dm | 2 +- tff_modular/modules/vampire/datum_vampire.dm | 12 ++--- .../modules/vampire/misc_procs_vampire.dm | 1 + .../vampire/powers/dominate/command.dm | 7 --- tff_modular/modules/vampire/powers/feed.dm | 53 ++++++++++++++++++- .../vampire/powers/fortitude/fortitude.dm | 22 ++++---- tff_modular/modules/vampire/society.dm | 3 -- 9 files changed, 74 insertions(+), 35 deletions(-) diff --git a/code/__DEFINES/~ff_defines/vampire.dm b/code/__DEFINES/~ff_defines/vampire.dm index 332e69bf534..40ce34a3925 100644 --- a/code/__DEFINES/~ff_defines/vampire.dm +++ b/code/__DEFINES/~ff_defines/vampire.dm @@ -78,7 +78,7 @@ /// Cost to convert someone after successful torture, in blood #define TORTURE_CONVERSION_COST 50 /// Once blood is this low, will enter a Frenzy -#define FRENZY_THRESHOLD_ENTER 25 +#define FRENZY_THRESHOLD_ENTER 175 /// Once blood is this high, will exit the Frenzy. Intentionally high, we want to kill the person we feed off of #define FRENZY_THRESHOLD_EXIT 500 /// How much blood drained from the vampire each lifetick @@ -104,7 +104,10 @@ #define VAMPIRE_FREE_LEVELS 3 /// Vampire's default stamina resist. #define VAMPIRE_INHERENT_STAMINA_RESIST 0.75 - +/// Vampire's default brute resist. +#define VAMPIRE_INHERENT_BRUTE_RESIST 0.75 +/// Vampire's default burn resist. +#define VAMPIRE_INHERENT_BURN_RESIST 0.85 /// Humanity defines /// Default Humanity #define VAMPIRE_DEFAULT_HUMANITY 7 diff --git a/modular_nova/modules/customization/modules/mob/living/carbon/human/species/hemophage/corrupted_tongue.dm b/modular_nova/modules/customization/modules/mob/living/carbon/human/species/hemophage/corrupted_tongue.dm index 62da523393c..01d01df0320 100644 --- a/modular_nova/modules/customization/modules/mob/living/carbon/human/species/hemophage/corrupted_tongue.dm +++ b/modular_nova/modules/customization/modules/mob/living/carbon/human/species/hemophage/corrupted_tongue.dm @@ -174,6 +174,8 @@ // Жертва будет уязвима к урону в течение 5 минут if(!victim.has_status_effect(/datum/status_effect/vulnerable_to_damage)) victim.apply_status_effect(/datum/status_effect/vulnerable_to_damage) + if(!victim.has_status_effect(/datum/status_effect/feed_marked) && !victim.has_status_effect(/datum/status_effect/feed_marked/fake)) + victim.apply_status_effect(/datum/status_effect/feed_marked/fake) // FLUFFY FRONTIER EDIT ADDITION END #undef HEMOPHAGE_DRAIN_AMOUNT diff --git a/tff_modular/modules/vampire/clans/toreador.dm b/tff_modular/modules/vampire/clans/toreador.dm index 3797659a450..f26081be6c6 100644 --- a/tff_modular/modules/vampire/clans/toreador.dm +++ b/tff_modular/modules/vampire/clans/toreador.dm @@ -2,7 +2,7 @@ name = CLAN_TOREADOR description = "The Toreador are a clan of vampires known for being some of the most beautiful, sensual, seductive, emotional and glamorous of the Kindred.

    \ Responsible for the legends of vampires who seduce and entice their prey with beauty, love and sensuality. Famous and infamous as a clan of artists and innovators, they are one of the bastions of the Camarilla, as their very survival depends on the facades of civility and grace on which the sect prides itself.

    \ - They are inherently divas by blood, and their humanity and sense of morality may plummit as fast as it rises." + They are inherently divas by blood, and their humanity and sense of morality may plummit as fast as it rises. Due to their grace and gentleness of action, Toreadors do not leave bite marks on the victim's body." join_icon_state = "toreador" blood_drink_type = VAMPIRE_DRINK_SNOBBY default_humanity = 10 diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index 0200a1b6f6f..8b0aa855e68 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -216,6 +216,8 @@ if(ishuman(current_mob)) var/mob/living/carbon/human/current_human = current_mob current_human.physiology?.stamina_mod *= VAMPIRE_INHERENT_STAMINA_RESIST + current_human.physiology?.brute_mod *= VAMPIRE_INHERENT_BRUTE_RESIST + current_human.physiology?.burn_mod *= VAMPIRE_INHERENT_BURN_RESIST current_mob.dna?.remove_all_mutations() current_mob.add_traits(vampire_traits + always_traits, TRAIT_VAMPIRE) @@ -252,13 +254,14 @@ handle_clown_mutation(current_mob, removing = FALSE) cleanup_limbs(current_mob) - // cleanup_tracker() current_mob.remove_faction(FACTION_VAMPIRE) if(ishuman(current_mob)) var/mob/living/carbon/human/current_human = current_mob current_human.physiology?.stamina_mod /= VAMPIRE_INHERENT_STAMINA_RESIST + current_human.physiology?.brute_mod /= VAMPIRE_INHERENT_BRUTE_RESIST + current_human.physiology?.burn_mod /= VAMPIRE_INHERENT_BURN_RESIST if(!QDELETED(current_mob)) my_clan?.remove_effects(current_mob) @@ -331,8 +334,6 @@ GLOB.all_vampires += src SSvampire_leveling.check_enable() - check_start_society() - if(!QDELETED(owner.current)) for(var/quirk_type in typesof(/datum/quirk/item_quirk/addict/junkie) + /datum/quirk/skittish) owner.current.remove_quirk(quirk_type) @@ -546,11 +547,6 @@ for(var/datum/action/cooldown/vampire/all_powers as anything in powers) remove_power(all_powers) - /// Stats - if(ishuman(owner.current)) - var/mob/living/carbon/human/human_user = user - human_user.physiology.stamina_mod /= VAMPIRE_INHERENT_STAMINA_RESIST - // Remove all vampire traits user.remove_traits(vampire_traits + always_traits, TRAIT_VAMPIRE) diff --git a/tff_modular/modules/vampire/misc_procs_vampire.dm b/tff_modular/modules/vampire/misc_procs_vampire.dm index 3a44f8f471c..3659fb1d610 100644 --- a/tff_modular/modules/vampire/misc_procs_vampire.dm +++ b/tff_modular/modules/vampire/misc_procs_vampire.dm @@ -206,6 +206,7 @@ temp_humanity = 0 humanity = temp_humanity + frenzy_threshold = FRENZY_THRESHOLD_ENTER - (15 * humanity) return TRUE /// Bacon wanted a signal diff --git a/tff_modular/modules/vampire/powers/dominate/command.dm b/tff_modular/modules/vampire/powers/dominate/command.dm index 9e4bfbe88fe..4b637ab4c37 100644 --- a/tff_modular/modules/vampire/powers/dominate/command.dm +++ b/tff_modular/modules/vampire/powers/dominate/command.dm @@ -103,13 +103,6 @@ owner.balloon_alert(owner, "[living_target] is not [(living_target.stat == DEAD || HAS_TRAIT(living_target, TRAIT_FAKEDEATH)) ? "alive" : "conscious"].") return FALSE - /* - // Is our target deaf? - if(!living_target.can_hear()) - owner.balloon_alert(owner, "[living_target] cannot hear you!") - return FALSE - */ - // Is our target a silicon? if(issilicon(living_target)) owner.balloon_alert(owner, "[living_target] cannot be compelled!") diff --git a/tff_modular/modules/vampire/powers/feed.dm b/tff_modular/modules/vampire/powers/feed.dm index f3f76aa6091..2af7b968bf2 100644 --- a/tff_modular/modules/vampire/powers/feed.dm +++ b/tff_modular/modules/vampire/powers/feed.dm @@ -311,7 +311,8 @@ feed_target.add_traits(list(TRAIT_IMMOBILIZED, TRAIT_MUTE, TRAIT_HANDS_BLOCKED), REF(src)) // Normally removed traits are done. Now we give the victim a lil something to remember us by. - feed_target.apply_status_effect(/datum/status_effect/feed_marked) + if(!istype(vampiredatum_power.my_clan, /datum/vampire_clan/toreador)) + feed_target.apply_status_effect(/datum/status_effect/feed_marked) /datum/action/cooldown/vampire/targeted/feed/use_power() var/mob/living/user = owner @@ -563,11 +564,16 @@ /datum/status_effect/feed_marked/on_apply() if(!iscarbon(owner)) return FALSE + owner.add_movespeed_modifier(/datum/movespeed_modifier/feed_marked) + owner.add_actionspeed_modifier(/datum/actionspeed_modifier/feed_marked) + owner.add_mood_event("feed_marked", /datum/mood_event/feed_marked) RegisterSignal(owner, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) return TRUE /datum/status_effect/feed_marked/on_remove() UnregisterSignal(owner, COMSIG_ATOM_EXAMINE) + owner.remove_movespeed_modifier(/datum/movespeed_modifier/feed_marked) + owner.remove_actionspeed_modifier(/datum/actionspeed_modifier/feed_marked) /datum/status_effect/feed_marked/on_creation(mob/living/new_owner, ...) duration = rand(5 MINUTES, 10 MINUTES) @@ -580,3 +586,48 @@ SIGNAL_HANDLER if(isobserver(user) || (get_dist(user, owner) <= 3 && !user.is_nearsighted_currently())) examine_list += span_warning("There are two strange punctures on [owner.p_their()] neck.") + if(IS_CURATOR(user)) + examine_list += span_cult_italic("It doesn't look like it's a hemophage bite...") + +/datum/movespeed_modifier/feed_marked + multiplicative_slowdown = 0.1 + blacklisted_movetypes = (FLYING|FLOATING) + +/datum/actionspeed_modifier/feed_marked + multiplicative_slowdown = 0.25 + +/datum/mood_event/feed_marked + description = "What happened? I... I feel so good..." + mood_change = 15 + timeout = 2 MINUTES + +/datum/status_effect/feed_marked/fake + id = "feed marked fake" + tick_interval = STATUS_EFFECT_NO_TICK + processing_speed = STATUS_EFFECT_NORMAL_PROCESS + status_type = STATUS_EFFECT_REFRESH + alert_type = null + remove_on_fullheal = TRUE + heal_flag_necessary = HEAL_WOUNDS + +/datum/status_effect/feed_marked/fake/on_apply() + if(!iscarbon(owner)) + return FALSE + RegisterSignal(owner, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) + return TRUE + +/datum/status_effect/feed_marked/fake/on_remove() + UnregisterSignal(owner, COMSIG_ATOM_EXAMINE) + +/datum/status_effect/feed_marked/fake/on_creation(mob/living/new_owner, ...) + duration = rand(5 MINUTES, 10 MINUTES) + return ..() + +/datum/status_effect/feed_marked/fake/refresh(effect, ...) + duration = max(duration, world.time + rand(5 MINUTES, 10 MINUTES)) + +/datum/status_effect/feed_marked/fake/on_examine(atom/source, mob/user, list/examine_list) + if(isobserver(user) || (get_dist(user, owner) <= 3 && !user.is_nearsighted_currently())) + examine_list += span_warning("There are two strange punctures on [owner.p_their()] neck.") + if(IS_CURATOR(user)) + examine_list += span_warning("It look like it's a hemophage bite...") diff --git a/tff_modular/modules/vampire/powers/fortitude/fortitude.dm b/tff_modular/modules/vampire/powers/fortitude/fortitude.dm index e542cdb8c21..25d642a4e67 100644 --- a/tff_modular/modules/vampire/powers/fortitude/fortitude.dm +++ b/tff_modular/modules/vampire/powers/fortitude/fortitude.dm @@ -28,13 +28,14 @@ At level 1: Gain pierce resistance.\n\ At level 2: Gain push immunity.\n\ At level 3: Gain dismember resistance.\n\ - At level 4: Gain complete stun immunity." + At level 4: Gain complete stun immunity.\n\ + At level 5: Gain grab resistance." vampire_power_flags = BP_AM_TOGGLE | BP_AM_COSTLESS_UNCONSCIOUS vampire_check_flags = BP_CANT_USE_IN_TORPOR | BP_CANT_USE_WHILE_STAKED vitaecost = 50 cooldown_time = 5 SECONDS - var/resistance = 0.8 + var/resistance = 0.9 // Flags for what immunities to turn on at which level var/pierce = TRUE @@ -42,32 +43,27 @@ var/dismember = FALSE var/stun = FALSE var/grab = FALSE - var/burn_resistance = 0.9 /datum/action/cooldown/vampire/fortitude/two - resistance = 0.6 - burn_resistance = 0.8 + resistance = 0.8 pierce = TRUE push = TRUE /datum/action/cooldown/vampire/fortitude/three - resistance = 0.4 - burn_resistance = 0.7 + resistance = 0.7 pierce = TRUE push = TRUE dismember = TRUE /datum/action/cooldown/vampire/fortitude/four - resistance = 0.3 - burn_resistance = 0.6 + resistance = 0.6 pierce = TRUE push = TRUE dismember = TRUE stun = TRUE /datum/action/cooldown/vampire/fortitude/five - resistance = 0.3 - burn_resistance = 0.5 + resistance = 0.6 pierce = TRUE push = TRUE dismember = TRUE @@ -95,7 +91,7 @@ RegisterSignal(user, COMSIG_MOB_APPLY_DAMAGE, PROC_REF(on_take_damage)) user.physiology.brute_mod *= resistance user.physiology.stamina_mod *= resistance * 2 // Stamina resistance is half as effective because they have it inherently. - user.physiology.burn_mod *= burn_resistance // they get burn resistance, but way less + user.physiology.burn_mod *= resistance // they get burn resistance, but way less /datum/action/cooldown/vampire/fortitude/proc/on_take_damage(datum/source, damage_amount, damage_type, ...) SIGNAL_HANDLER @@ -118,7 +114,7 @@ var/mob/living/carbon/human/vampire_user = owner UnregisterSignal(vampire_user, COMSIG_MOB_APPLY_DAMAGE) vampire_user.physiology.brute_mod /= resistance - vampire_user.physiology.burn_mod /= burn_resistance + vampire_user.physiology.burn_mod /= resistance vampire_user.physiology.stamina_mod /= resistance * 2 // Remove Traits & Effects diff --git a/tff_modular/modules/vampire/society.dm b/tff_modular/modules/vampire/society.dm index 7a386071b67..c55989cd1e8 100644 --- a/tff_modular/modules/vampire/society.dm +++ b/tff_modular/modules/vampire/society.dm @@ -1,6 +1,3 @@ -/datum/antagonist/vampire/proc/check_start_society() - return FALSE - /datum/antagonist/vampire/proc/princify() rank_up(8, TRUE) // Rank up a lot. to_chat(owner.current, span_cult_bold("As a true prince, you find some of your old power returning to you!")) From c0d9b0eeb1730e68609d0a95a3f8f728c8ac4fd8 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Thu, 14 May 2026 17:54:01 +0300 Subject: [PATCH 146/149] =?UTF-8?q?=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=B1=D0=B0=D0=B3=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/game/objects/items/devices/scanners/health_analyzer.dm | 2 +- tff_modular/modules/vampire/datum_vampire.dm | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/code/game/objects/items/devices/scanners/health_analyzer.dm b/code/game/objects/items/devices/scanners/health_analyzer.dm index be2f57ff0f2..47fd9c208ce 100644 --- a/code/game/objects/items/devices/scanners/health_analyzer.dm +++ b/code/game/objects/items/devices/scanners/health_analyzer.dm @@ -216,7 +216,7 @@ render_list += "Subject Minor Disabilities: [carbontarget.get_quirk_string(FALSE, CAT_QUIRK_MINOR_DISABILITY, TRUE)].
    " // NOVA EDIT ADDITION START -- Show increased/decreased brute/burn mods, to "leave a paper trail" for the fragility quirk - if(ishuman(target)) + if(ishuman(target) && !IS_VAMPIRE(target)) // TFF EDIT - ORIGINAL: if(ishuman(target)) var/mob/living/carbon/human/humantarget = target var/datum/physiology/physiology = humantarget.physiology diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index 8b0aa855e68..a42ade48533 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -225,6 +225,7 @@ current_mob.grant_language(/datum/language/vampiric, source = LANGUAGE_VAMPIRE) my_clan?.apply_effects(current_mob) + frenzy_threshold = FRENZY_THRESHOLD_ENTER - (15 * humanity) /** * Remove innate effects is everything given to the mob From 5d706f632e44328fcf92d0fed98415276bc44c6d Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Fri, 15 May 2026 18:30:58 +0300 Subject: [PATCH 147/149] =?UTF-8?q?=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B1=D0=B0=D0=BB=D0=B0=D0=BD=D1=81?= =?UTF-8?q?=D0=B0=20=D0=B8=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BB=D0=B0=D0=BD=D0=B3=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/__DEFINES/~ff_defines/vampire.dm | 8 +++----- tff_modular/modules/vampire/datum_vampire.dm | 5 ++--- tff_modular/modules/vampire/frenzy_vampire.dm | 6 +++++- tff_modular/modules/vampire/misc_procs_vampire.dm | 1 - tff_modular/modules/vampire/objects/kindred.dm | 4 ++-- .../modules/vampire/powers/celerity/celerity.dm | 3 ++- .../modules/vampire/powers/fortitude/fortitude.dm | 4 ++-- tff_modular/modules/vampire/powers/potence/lunge.dm | 10 ++++++++-- 8 files changed, 24 insertions(+), 17 deletions(-) diff --git a/code/__DEFINES/~ff_defines/vampire.dm b/code/__DEFINES/~ff_defines/vampire.dm index 40ce34a3925..b6546b3c612 100644 --- a/code/__DEFINES/~ff_defines/vampire.dm +++ b/code/__DEFINES/~ff_defines/vampire.dm @@ -78,7 +78,7 @@ /// Cost to convert someone after successful torture, in blood #define TORTURE_CONVERSION_COST 50 /// Once blood is this low, will enter a Frenzy -#define FRENZY_THRESHOLD_ENTER 175 +#define FRENZY_THRESHOLD_ENTER 125 /// Once blood is this high, will exit the Frenzy. Intentionally high, we want to kill the person we feed off of #define FRENZY_THRESHOLD_EXIT 500 /// How much blood drained from the vampire each lifetick @@ -103,11 +103,9 @@ /// How many free levels the vampire gets gradually. #define VAMPIRE_FREE_LEVELS 3 /// Vampire's default stamina resist. -#define VAMPIRE_INHERENT_STAMINA_RESIST 0.75 +#define VAMPIRE_INHERENT_STAMINA_RESIST 0.5 /// Vampire's default brute resist. -#define VAMPIRE_INHERENT_BRUTE_RESIST 0.75 -/// Vampire's default burn resist. -#define VAMPIRE_INHERENT_BURN_RESIST 0.85 +#define VAMPIRE_INHERENT_DAMAGE_RESIST 0.75 /// Humanity defines /// Default Humanity #define VAMPIRE_DEFAULT_HUMANITY 7 diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index a42ade48533..88fb028a969 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -216,8 +216,8 @@ if(ishuman(current_mob)) var/mob/living/carbon/human/current_human = current_mob current_human.physiology?.stamina_mod *= VAMPIRE_INHERENT_STAMINA_RESIST - current_human.physiology?.brute_mod *= VAMPIRE_INHERENT_BRUTE_RESIST - current_human.physiology?.burn_mod *= VAMPIRE_INHERENT_BURN_RESIST + current_human.physiology?.brute_mod *= VAMPIRE_INHERENT_DAMAGE_RESIST + current_human.physiology?.burn_mod *= VAMPIRE_INHERENT_DAMAGE_RESIST current_mob.dna?.remove_all_mutations() current_mob.add_traits(vampire_traits + always_traits, TRAIT_VAMPIRE) @@ -225,7 +225,6 @@ current_mob.grant_language(/datum/language/vampiric, source = LANGUAGE_VAMPIRE) my_clan?.apply_effects(current_mob) - frenzy_threshold = FRENZY_THRESHOLD_ENTER - (15 * humanity) /** * Remove innate effects is everything given to the mob diff --git a/tff_modular/modules/vampire/frenzy_vampire.dm b/tff_modular/modules/vampire/frenzy_vampire.dm index be724859498..6b4e9c3f1d5 100644 --- a/tff_modular/modules/vampire/frenzy_vampire.dm +++ b/tff_modular/modules/vampire/frenzy_vampire.dm @@ -28,6 +28,8 @@ TRAIT_PUSHIMMUNE, TRAIT_STRONG_GRABBER, TRAIT_STUNIMMUNE, + TRAIT_BATON_RESISTANCE, + TRAIT_IGNORESLOWDOWN, ) /datum/status_effect/frenzy/Destroy() @@ -106,12 +108,14 @@ carbon_owner.adjust_fire_loss(0.75 + (vampiredatum.vampire_level * 0.05)) carbon_owner.set_jitter_if_lower(10 SECONDS) + carbon_owner.uncuff() + /datum/status_effect/frenzy/get_examine_text() return span_danger("[owner.p_They()] seem[owner.p_s()]... inhumane, and feral!") /datum/movespeed_modifier/frenzy_speed blacklisted_movetypes = FLYING | FLOATING - multiplicative_slowdown = -0.1 // Might seem very low but at this point we are already slow as balls from hunger + multiplicative_slowdown = -0.2 // Might seem very low but at this point we are already slow as balls from hunger /atom/movable/screen/alert/status_effect/masquerade/MouseEntered(location,control,params) desc = initial(desc) diff --git a/tff_modular/modules/vampire/misc_procs_vampire.dm b/tff_modular/modules/vampire/misc_procs_vampire.dm index 3659fb1d610..3a44f8f471c 100644 --- a/tff_modular/modules/vampire/misc_procs_vampire.dm +++ b/tff_modular/modules/vampire/misc_procs_vampire.dm @@ -206,7 +206,6 @@ temp_humanity = 0 humanity = temp_humanity - frenzy_threshold = FRENZY_THRESHOLD_ENTER - (15 * humanity) return TRUE /// Bacon wanted a signal diff --git a/tff_modular/modules/vampire/objects/kindred.dm b/tff_modular/modules/vampire/objects/kindred.dm index 3de0286eae1..829f6437c0c 100644 --- a/tff_modular/modules/vampire/objects/kindred.dm +++ b/tff_modular/modules/vampire/objects/kindred.dm @@ -27,7 +27,7 @@ /obj/item/book/kindred/examine(mob/user) . = ..() if(IS_CURATOR(user)) - . += span_awe("[src] can be used by curators to identify vampires. Use this on the suspect...") + . += span_awe("[src] can be used by curators or chaplains to identify vampires. Use this on the suspect...") ///Attacking someone with the book. /obj/item/book/kindred/interact_with_atom(mob/target, mob/living/user, list/modifiers) @@ -35,7 +35,7 @@ return NONE if(DOING_INTERACTION(user, DOAFTER_SOURCE_ARCHIVE_OF_THE_KINDRED)) return ITEM_INTERACT_BLOCKING - if(!IS_CURATOR(user)) + if(!IS_CURATOR(user) && !IS_CHAPLAIN) if(!IS_VAMPIRE(user)) to_chat(user, span_warning("[src] burns your hands as you try to use it!")) user.apply_damage(3, BURN, pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM)) diff --git a/tff_modular/modules/vampire/powers/celerity/celerity.dm b/tff_modular/modules/vampire/powers/celerity/celerity.dm index a18526ae698..817f1ac9799 100644 --- a/tff_modular/modules/vampire/powers/celerity/celerity.dm +++ b/tff_modular/modules/vampire/powers/celerity/celerity.dm @@ -12,5 +12,6 @@ /datum/discipline/celerity/apply_discipline_quirks(datum/antagonist/vampire/clan_owner) . = ..() - owner.add_traits(clan_owner.vampire_traits, TRAIT_PERFECT_ATTACKER, TRAIT_VAMPIRE) + owner.add_traits(list(TRAIT_PERFECT_ATTACKER, TRAIT_TOSS_GUN_HARD), TRAIT_VAMPIRE) + clan_owner.vampire_traits += list(TRAIT_PERFECT_ATTACKER, TRAIT_TOSS_GUN_HARD) owner.next_move_modifier *= 0.9 diff --git a/tff_modular/modules/vampire/powers/fortitude/fortitude.dm b/tff_modular/modules/vampire/powers/fortitude/fortitude.dm index 25d642a4e67..a5490086b84 100644 --- a/tff_modular/modules/vampire/powers/fortitude/fortitude.dm +++ b/tff_modular/modules/vampire/powers/fortitude/fortitude.dm @@ -91,7 +91,7 @@ RegisterSignal(user, COMSIG_MOB_APPLY_DAMAGE, PROC_REF(on_take_damage)) user.physiology.brute_mod *= resistance user.physiology.stamina_mod *= resistance * 2 // Stamina resistance is half as effective because they have it inherently. - user.physiology.burn_mod *= resistance // they get burn resistance, but way less + user.physiology.burn_mod *= resistance + 0.2 // they get burn resistance, but way less /datum/action/cooldown/vampire/fortitude/proc/on_take_damage(datum/source, damage_amount, damage_type, ...) SIGNAL_HANDLER @@ -114,7 +114,7 @@ var/mob/living/carbon/human/vampire_user = owner UnregisterSignal(vampire_user, COMSIG_MOB_APPLY_DAMAGE) vampire_user.physiology.brute_mod /= resistance - vampire_user.physiology.burn_mod /= resistance + vampire_user.physiology.burn_mod /= resistance + 0.2 vampire_user.physiology.stamina_mod /= resistance * 2 // Remove Traits & Effects diff --git a/tff_modular/modules/vampire/powers/potence/lunge.dm b/tff_modular/modules/vampire/powers/potence/lunge.dm index 43d36d575d9..8a517cfdd87 100644 --- a/tff_modular/modules/vampire/powers/potence/lunge.dm +++ b/tff_modular/modules/vampire/powers/potence/lunge.dm @@ -169,10 +169,16 @@ // Did we knock them down? if(!is_source_facing_target(target, owner) || owner.alpha <= 40) target.Knockdown((1 SECONDS) + knockdown_bonus * 5) - target.Paralyze(0.1) + target.Paralyze(1) target.drop_all_held_items() target.grabbedby(owner) - target.grippedby(owner, instant = TRUE) + owner.setGrabState(GRAB_NECK) + else + target.Knockdown((1 SECONDS)) + + target.drop_all_held_items() + target.grabbedby(owner) + owner.setGrabState(GRAB_AGGRESSIVE) #undef LUNGE_TIME From ff18fcb77a8f0cbd76c56a5580047b1a5ad2030a Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Fri, 15 May 2026 18:36:25 +0300 Subject: [PATCH 148/149] =?UTF-8?q?=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D1=8F=D0=B5=D0=BC=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D1=83?= =?UTF-8?q?=20=D0=BC=D0=BE=D0=BB=D0=BE=D0=B4=D0=BE=D1=81=D1=82=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tff_modular/modules/vampire/datum_vampire.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm index 88fb028a969..85e90d53a42 100644 --- a/tff_modular/modules/vampire/datum_vampire.dm +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -260,8 +260,8 @@ if(ishuman(current_mob)) var/mob/living/carbon/human/current_human = current_mob current_human.physiology?.stamina_mod /= VAMPIRE_INHERENT_STAMINA_RESIST - current_human.physiology?.brute_mod /= VAMPIRE_INHERENT_BRUTE_RESIST - current_human.physiology?.burn_mod /= VAMPIRE_INHERENT_BURN_RESIST + current_human.physiology?.brute_mod /= VAMPIRE_INHERENT_DAMAGE_RESIST + current_human.physiology?.burn_mod /= VAMPIRE_INHERENT_DAMAGE_RESIST if(!QDELETED(current_mob)) my_clan?.remove_effects(current_mob) From 8968d0f6c291fe067bfe169e4aa03d4064645ef0 Mon Sep 17 00:00:00 2001 From: SaukyKouko Date: Fri, 15 May 2026 18:43:03 +0300 Subject: [PATCH 149/149] Update kindred.dm --- tff_modular/modules/vampire/objects/kindred.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tff_modular/modules/vampire/objects/kindred.dm b/tff_modular/modules/vampire/objects/kindred.dm index 829f6437c0c..7bb1f27a5bc 100644 --- a/tff_modular/modules/vampire/objects/kindred.dm +++ b/tff_modular/modules/vampire/objects/kindred.dm @@ -35,7 +35,7 @@ return NONE if(DOING_INTERACTION(user, DOAFTER_SOURCE_ARCHIVE_OF_THE_KINDRED)) return ITEM_INTERACT_BLOCKING - if(!IS_CURATOR(user) && !IS_CHAPLAIN) + if(!IS_CURATOR(user) && !IS_CHAPLAIN(user)) if(!IS_VAMPIRE(user)) to_chat(user, span_warning("[src] burns your hands as you try to use it!")) user.apply_damage(3, BURN, pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM))

    S?;`#ZHNFK+L?w=paa(pNx7on7wvkZy- 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�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 diff --git a/tff_modular/modules/bloodsucker/sound/owl_3.ogg b/tff_modular/modules/bloodsucker/sound/owl_3.ogg deleted file mode 100644 index 7c8524e933df8d0cc520d842d4b5f5deb555072b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5030 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 CE3usb diff --git a/tff_modular/modules/bloodsucker/sound/owl_5.ogg b/tff_modular/modules/bloodsucker/sound/owl_5.ogg deleted file mode 100644 index 1210b05ac39a053c7d653d7051964a8a8d959a58..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5796 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 diff --git a/tff_modular/modules/bloodsucker/sound/owl_7.ogg b/tff_modular/modules/bloodsucker/sound/owl_7.ogg deleted file mode 100644 index fc330687a1104dd83a68729c78bf354741596372..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6591 zcmd5v&->4NK4-2u=Q`K<-sjrReciSJ0rmhJ@K=-4 z`Z>5!)1wAC42cep@(#kWSP;{?pDV<+pa1tEwyd3hZ>*gVaCRMXBj&(~KmWODu>Zt4 z1}-}VMFgtaMg_n^gS^k}p~Ea;8tMoQbq#e*n4&E793?rxnofkL@0MOJ@u~fE%q&hZ00{}Qm6iKfYNwUanA4}0a5zzQh0ANH2 zTV@GAYm__vLizNFsU13YOb3nLBw!|39j4_g!a_B&s4A$GfOYWuit+4s<^*7%iOdu` zpzMD$58$ncOqRd5bO}d__eTaQbuHl|j*Kl?hAAyA72yVv3Wd0C-Q^-&YLq`B5R@yz z3C8=we~yZuE*XbVS-fs!ReYqG7$`@+w`3fwGY;}Z?@^G!s$Jmd$lE1Ltm+sz8bpF3 zdxUzZ3KwyPgzE@h_4rlO*Qd3$H4Q<5jAuC`;Ao zQ@%T((a$2xhP#7$YwAy-C;98|37)oT8gufgf3RE>BJjc`sJ?033SJ3%8NO#fBIq6- zao1gkCh#^>c(ij9#<>|gHIDVj z$IflV{!=GN?Wt%104o-x3X9YV3(}%)wj88XrWOFiS<$4JTCPi4w8)mT%&)L4e(PN3 zA500jK&@um6ER|mu$m(IHJtJqUiKPUCTmsZ=Tb%qrYRQEnXR<{sjKb8xXT;bZWpkXCWv;{NCI_1) zhtncxTlD|bv~5PTY(T>v1+xxdc&9&k3zIo|^zAIP1DaEeke6w4m*L3Do<(qp#20In z@kh;?EJEWCgGM_Dn1Y&j!+M~&UZiB$tIe<$!UH29Yt2!g0*R7TS3;5nN>XPo^#ej_c2={^3qSVO&2NIS+~rOfyEJ+u4nZaY1V#@wZXQ>E#SMrQk$ zZ|x1rPvbM zwKM_^iDl!XsDTM-p zD;H9zefi4;R1kSJr8r~{Irt?th|EG(DWoX%)3Cek%szS;l^O~nGg*fW?QdW2qkh;^ zaPJs&m1+8VKfP{uPeIl(sH**R>@RmicUuF=f1OHcny#|j3Z81cj}~4_tz)vLA9iRF z%vSY>^w3>u-A?PV>DF+j#`I>aDHwwG+Sq9@Prwk|^aEMLT3A;!+EvG9tl19?LGViT z(z2NXvuNCA>>k!RAM4fZw*U&a__=NpCh`a#6S0dEeltt0^!NSr`dw=6PV-lO^y*T~@R}hz&mO0>Rh3*;L!~lX=`_$ORNApN`Wh1)P?>!+<=qZy zEA1F)Qf5a3xE*xCbaVJC@OE!s-|fh%XSS+->p<|ELxA~x0)P>xP8}%%r6uYV*lPvA z*a4zCmrOj=gi9tN6J;e+nJWlh*Yn_O)zd^=QOoxf0961DauQy_dgt!Fc>gQ0_;(Bc za!1X72lX#^{IB5u9|-6DdsF>i^y39GQzL-P3xA7D3oyvi?5yD3Me$I?l9bv1Sl#~0tyZ(;6hC*F$Tq1{jsJM47gr>dh z;!>+UQH1;b!9CFs8d!zn`Vk-j>pro+ia$#!Vl^88y!vx!%-L{^}v zG~_b)&?AYgDUXZ;Yl?@OREyzQd6JO1w+a?cI03!AVw+nEthm99VWm<6)JhQ~;A#R? zk45%IEP}Gyo9-*kJqrMySJ?q0;{ICMBH?sSQC4z-B?wV6zXUayU`#U3*l*ltr@7z6 z8aZ6xeI{5_#6A-Vy@eMP4>q21*Wd$hZx{e$a6rXiirXeU$q2BBO&);mOGGy?O86xt zmmmyw(*#o>^Ja-f+kK)cyW3C~hTDY41RCcgX$0A)tGke-F#9p#m!cAThgBG>vI6*l zc`&U?fFno9wGH zciP1Z!vJeXX6MH9EXM3=k{VC+{ODaq^XW%~nLB2*ga!RBeBU4LMd zLU9S*RKG*FxN#Shc9O<}AQ>%5N+(IYj6nYqB;@dAx&rywm)@)}0cV>6>qRo|J z15+g>-Yuc+E1C0`r6&Qga(T;9Jn_?epxu{E{W#>l@gHtaoO2XKE*Hl)?MJ((nziiv zHKTLj4ljDN?O|@;u!l~55F((~eIgvO8|>EQd+T7ZW8U4&Y2P%tY<1thRy_k!vTLF5 zHYH=UrQTJ#;Rt^(XnebJSY}#6eYtHrS^j?NKKEHZQ?c02E%sL)MO@P5f?wIvDum1) z3BVQ{hvl@ns9J>p|AdZy?A6#8lWB2F+YEbQbssD9yoqZDscoxX)svDs z3YLCTUDbyYayQ$Q0u?O$-{_2&tv-+v#Jm_8#7dhZ%b%n`R94lRpb{fDA~ofuQ`MgX zvs4{llm5#^bs0y7^+mnc`GEnTTXDiFo_E`7NET?=Vso;Hf=w#?(i;1zoMi=?8*JG`xC$uUC<#Vi|HP^e5My-9%=#+f))Xq~^!L;M$8_krOoMVWS1`5vK21Ei@Nq9oX=sRNz z$4i|+J5~OVBp&x-g9K^PI`>Nd4Wn7jUSK65Nbr$>!xhu3FK^pJDqMk<17GZgD}H-g za|thS#WSbd&`0QIaePcq?WcK+lSWWz%=MOyM9JpoH)X3T^ge1_+Gad>9wl1VHED@gmv=bjPIo8WY-oroQiPvd7w_pFvpE1#O}F1>R>Z+K^eQneQp3jF>H` zSIoBnqJ$HXJbLgP#1S&S!%?lG0DQ(q8R>5?a4^Q-t$pX~ycX|1HKE1zbj&PTPzZAJIYoB6+?Pw95;COHLA)J_kc zRh;Ve+EI@3HhZq{sdUbpXO=2j4SV(Dh17;|g}3ziIdMJ5>UOLCv=f7gHx8C@})<2TjBEVSeL4*fVVaAbBg zvYaR2F8ORrb+SY)^727U7ADwe`eJ1f@$xuv7klQz@G$h1Clqu9rDUN?4ZItab|PmL zKDzRK+~CpxRxPqkZMYlGvnx&s0ncRs0`H&MH**1>p_<@tvGYWLkS z+~k~l=BwXNxSq7bo+BtE;ln zh{cvHMo}*{$vWerbvt$Ge(I;~`zLsQm7EhV0UCjQ_1aWoEf8{xZS=f6kn-pO`|C$S zbYSwrKC{PXf5d%1%~U)3`01Bv(wyz9AEbcWA6v!sKW*txC0ALF-xiiy8=A@`Y^P)_ zisrL3d+^^IFY=R4ND%C>JvTiLOc$?AMb?%4z=q3@PCIGJQ(scfbG4I2eNA+}L6oNJ&1$6n&~Y(!_}IS@`Iofu_`K3?j=7WsGEmC3d=OC`#3}(!e6<| z{~{=1Ktw=52i!+ z=?|xy0|L*A)D8E$1Y8Ok{p`!R`zhn)kHd?FJ!^GBq?=CiEpmaMOyHHd$cl| z-0|2)YvB+FnqH9ASEEY2XW8Zr%pkAUgi2bvm?ya8xp!|Yb#0%mO2U$m?o501Q>K3h z(~xIZ!R4aZBwGDz?|fI8y_#507sd&Nnu+FjpN`#CzLh%F=2I2z;1{HFb8sLmQ?nW4 zb~Pu06!VQBjI;}7B7G9#eUqa2+NqRkqs2o9@+=Y-Z}F=qb*d}PLs#rxL4+>_W&t1G zw)1=qx!brNIYo=R>x*7i$bvVnKdDFFj$>MdsgGDjr8hDO0SDKz>%MnnrFQe+F0HD- z<65PAj;lDNX?z*Z4-wv!i5GY#^d#f_2vsX0V}n;HV~pj8lF}Rx{R7DkUn4$<1KT{F zX%X3q^L#5IY#)yUA5^>fp@9$h8DpV`HxR}Z#k{rkfsgCU356xX(ru35o#Y_O_bl>! zq5SRNRPQeyS9*Mwm`sVG^^pIs?noTU@g*x7p-rl}KPi|{eg?+L~=;I%pdy~n9&2CsxG*QlDcTap^ zY>qIFI^fO}E!pG}9%MiAr9DmzED;_8X+sXy!XM4q5+NnhZ1X46#Tn14AWkorkm9ye zCI%wo`uQTI-_X`+D z4`x%o;wVv3MV~sN6;z8}jvF8?ylJn$>JHV**xPedMsx|N3xV0Nom#zJvCMXUP5n{; zk?kvFg-iy+&^hjuaCL}?(KPuTgcRE%lDtc!|K6XeaD<|5kteF) z-R6auM~O&*_-nY%o05l1S{vr@I7w29DxvS9sU!ivvA!rax*++Y zvQB51w|xA&zTS|Ry|{JUe?(@Bge$%p!?UvBq1rJCK;Sc|4TgzkkM3l4`PrFBv6Uwy|YIF-eGI#$;>kgTdHlMpSC7A^TQ_WNR>(G!>yV z*~7QUzLP>mX%V93KBMn%xv%^C-TS()`_DbEGiT2EoX>gB`K-_9!OF`E4R8T}H9M`} z6Td@hwvhdhkbqz}Jds0!7+3z@p)~ydegv`Nocw#^oP>a@H19g|Jx722bJO7djdK{> zw!;T{t6Bwn!Tj)U=eE#cW-twPxQ4ohx+YA)ir|kA48{?0{v<^XG=%r}QEB9fb09hd z5OcRtG|54|GLIK0X2MN!+|teC??j6tO>Yr}(dCGtJm1Q?hp=d<1p2HZZw@LMg%@{E z<;17D!XYm~`{)chF~$rrOzqC`BnE3gu(80RAMh1{S?5 zvL_Y8xhKmID#7Fj&H?~5p-?P=D>}B43(x=no&tsB*9yr85$Wz`qFXGW@}U603KTX= z6MlYA_Vg>|(|yL)nD7A|3}% pZGDmWK!j)zGvw=Z*xdNx(ylZL(2>9R4gmt+EORD$%za7=S1UEq<{2wqW-B&V>7Tnu;}WyuoA%xWMLf# zaTBWq*L@)qYvidl^6XHIt9>@^KlR_DgOX67NWR~K+!1r{hR+vdoJIakOc?lsENjWu zAlXyFvd`0%%`&u3-`D@MPv3II*jm`K&*r2p>Ey(NlOvgyLnO-)62|@^*1m=?GDvXF zCQPk`|5GPRZHZ_K01KwcC8h}_rpdFq>9UYQnF;_9=XjGsLa}c0tZBNeS$2t8{#*MZ zPam4sMS2<67KTKXuhD2Tuino;1nl zX_BCWn}HL^mUh8d-~s{#+EYQN2R;5T8Ld`8g<^Yo|JeWlpf1~tQa(l0GRw3%{m{np zq0MO#j1}g8YTA~4T9%+<4}nn!u-uZKy@kmfI`noD+62wWhs()4bdupoOP_>q6N$># zC=v*sM9xB^_Jc~>3mAivx53(>#16!%@(e-5d>JWIVqWr2GRjM_^`_gO3R%Ob$|Pbk z>Qq&6rkk=#NG2+&ybbggE=lmC91UKd2e1Z!Xt=3jiLhHDqBQSBqT>8bVk~@4l9-H` zFCd|m=JQBr%v;33WoaG}r6-?7JYz0j2>J)G9sKMp>`4`Y80G;KqjY_%&sx@*T2{g* z(Il+37Ix^f{=kX_8e`CFgF#~mBQ_ZOZ2gy727NY|ms*$sa0%v)?30)QLLZqtM#4;F z6UNrCj-nyf7{Y`NcI*gdXcarM8g4&GcK@u8`D)QeHs~Ya2FL_QG8VgLfzGxZ%EI-L z31e9}>;>G&nsy%v+lRr8kgy{mINMsR{c3n0Ic6#g=WL6!7Yo6z#W)USy(M8MY;m?n z&Vjp*LoqXhWY-*hD-4K?eW``DC1ag!u|tE}eVH8O5gV+12#Ace9VEZh;vkRdU~RKG z$hO(!2@=SRvtP&9u9EGCvStPeGe@vPYZ&|07;u+^Tt~)=9m9MLM~B4BkZ@B&F;n*b zSl#Sia=2?2Va5(;kGL{pmp!qTg#)4N2qR+W>_uap*KfUD4WA7qW5xX^=DX{c1=^QO zHaq(U2<|!I6ZW3Y7m{bh^qzj4EvMhjWgHeLRo?mZJ-hAxW+O9^!QP~UOQo@dDs^z*k>yw&=%^8yz3bycv?9=AMZf*qSEkmrXrQ0 zjHluq@;#~4(j1yMmElXJRVL6ByJ$Y0OgxpjRL>+dF#N`f@LNkiDowe8Suw^~TC6Xz zrB^4aE_I=tCZ7OOXjN3YQWuRr%EZ%a z{OEK-1AS?ONnqE5HzCkzD!FtY4l+}DtX>Vg6$hC*pF;z$;YXz(cFZrOa**fZX&|_A zE{)!qJ)c7dkr(6heYcQ(M(KDe2U#VTrqsnCY&Nnxnf`RTABfE6T+*+rak-QJVN1ZR zYcN&Dn9E(v%FQhSIoF`8b}bRqu+JvA*5GD9=31QNDtRc2>^u}cJA|8iCAY&He586Wup zKr9dd_|yvpge91QKpdDA5?vGFd`YMmi0y^eorrmu#|tAqnXGOEpG;;tNXyLBn1^Mi zqxis?!%msZOq4G#00`@Xd26^p@t!WnTObr00En8k1NB+tGs<)~%LlbuPOo`ynmr$1 zga<9<2vTU}bOxJE{Y_yng8JE_)Yq$0i^}PAc0H2;8imd{+`wF7gA+QtlcBuXM6YKY z235*#ss@jPCK#&;7zeX^mXZ?Fs{a@tc2T~IPfz*qC^Gs9F$r7#272EQnpzt{{_Z~9^MYnE5 zniePO!8u=s_Pm2b zh4xS$@z1&kqP`5U3MY2K!2zuM#QrM&c!6mxU4XKGxLU8ttk=%vZ!XOxeuu-d07WGt z=D{C55W`vW$=Gm~Bq*{>jL3P0{D}V#I8x7Ut z3|lkKfHL1&?kLPW3ji(=+<+lvSH;0R;Ur#BPH=)H2t_ix0QDl;DA_1wmrED7yx7OK*eAR>qx#hI9SBSbwhW=V5(UK0uqvQ z5Ei#_v@wu+v%s|B5k-~zd`~NOJCY9xjkJ?AgzV7Oor#s7{22X5UIE%>5yq*k00Cec z466d*zyWGS^&?hC&+zoZN3cW$n<%gj0J_I0adC4>%Bt!bS~|LV`hR~JRzw?LXS4+&{L0L!-;Zo#$=O_*~5c zmWC(aMM_(JPk%bl>q$OOR{y2>tFLF2t^<2zusL8PZEW`@+zXiAmW}V}boGe%uG15L z_JJCtnnoSm?t@0F=zPzR%c9W}LI-H%qe9Nc^a;v3n9X!IkWyB-yPYdOQ+#gg^;+o)H$ot7L# z9&lo}mCagS%{MSsQsQ3|TECh)eMNd05G$55>nBk@y$2dSxYUn89vOW*|I9u^LF7t) z)WcmErv#JQ9mi9eyYKR2`Wqf+cJ?~!WaHsp6;49|@J*ldtsb}b`q*aOPaX3}lucLn z=&aW>NRD&N^;oB+^w(B7N>?8c=(rdcYh4UWO^mK8wrZrxJxbW&G`Z7QEWCM*d)zs1 zn{=_@3Rhx@kjazXuo)YQUJ@{%1rbiW9beS1R8E&MtY+rQdYJ-xuys76Kox!5TIw?WytG*Wm=~IZ}XYmk~MYV@e ziM|^_nsU+!>Mwywx{e33>q=f_%7I>eQMY9Qpc`mY7&4FIUpMbL2vo0e*_j6M+}!Zs zp|Dk%BBO2e_!QPNZY$}Dr1{dwAIP5bYVUWSV8C`9QfnW6W=`?rz4EocCeYpMl7>vn z-XH9>N3HYun+r*k^3eJ9%kr^RQKt`X@Xtt((~=-)Y8UL$5b#VFG)Td0lC$nkW6#jX znn0kSDK^Tih_W1UY#DrUA2lwo zv+7<3FUe)XElt!y(qYCov`A(H+>-`(nkIF3n{~Jnvf5ToK1K?+*RJfIq-U4GkXK%n zq#O{*-#p4KTLy_w?zb@!UD)MQQ zt=hiE>P;^Vk@hwDad&sk=a=^%*JQGS^A=O`g#etjLF8w`JV@NSjArCak0UmHq z;M?h4umr*H4{puK*6cYZx~cu3|Jv}~1Ix<3zaBYgOVCrC)~CKO@ROg;Ih(iYwyIRb zk!SKF^3E4m@7@2he5TOzh7|l&h$U!_VW%ZFwChY&=lwY6rD2?bfAB?Zp{g1Fi~wJ* zNxF&0Nu`v~HK=RocQ1;B9fjJz_Z-9)GPuE0rXmk~CIlPmug~zX2H!3H*x7t7%Bkmk z_3}>C=E<*mKT~JXGLzb$w&k2F6GD9$9B3Ag68eNEbX8sbG%*quTpzg>(mrkC`Gz^7 z+qxNR=S5RH{o<^`NQdi&aYenS7L0qrrodTdI-SQ9(b zNbKDAb5Hky$^M{XKCk=Kv$bV$5*3Imd$DO)AH%Urck(D#1}U3_Gaq_;q2n%4&=9nO znN~G0Hz;icP0D|C-1+hAHVt6WG~L*8dvzGM!iW&?QU)ON|4P4^3Ap!^`+P4(X5A<{ z(FnB-Z7r$Tarf9N@6>Y-{VwwL*bVLsK_MZJ4(p2EjQMC6jY~mt#DmF^eX}7{=i@Ce zGBU90uXEqJ9HRM}t{ucG=q1Ejq+GISq|ZG{__Y4$DBp3(De(f}9 z*D3Djp~14uMU8{ixT<5UpN$>B1<}^JNXYm^NA8(z_3`mP$tr=1q9Vnva(#ljS#X4~ zO!cz6O&~mA+)3^aK?ws290D5P5oUX^Xq@qQP|HznAPqREtsT#`3dt0u92H?*lh8Dr z4uS*o%fm?>jly%^>~41Nex9d(Y?p)AW#9hK9=w~MQbvF7pUrJwsuW7TX(v}Jdk@p} zPQ2q=_8c)YXXtTtvvsPkLIX7Wx%Cdm#~UGq{u?gwbqSih0rjsEeY)ielBHN+R+{UG z{S+Fu2EC%&X!UW!c?YAGM;v(gimJXCT;MjzHEm!58DA1AsBL8*-6pqv^Tu53`q|Q0 zLNdaMjmEUFJ)79a_%`JoE{P3e)K@yDTZ_Yh2fZzVFaHEoZ{)#H^r&Yz|+yY_g z23s&E*@*6Z9u$@g6+&)0~NpF7iiEHhD;8XW5B5W8!XrXSm^Fepu zQ=x`RGTYVOFnIYlX-94to{il5(^+ln@v!Y#^QDNh&9lFF?w&@o!ksBnz(YB0$q)o< zKLdDEt;jmJt)TTaYY1PHe9+!OEw9Xq{AJkcVnldmzG{)Aq96ZVh=*9V(neE{aWkRn zqo#q&2G`(;2Yv5fTsJ+FZ1%ovj+vVp@ND|hG0(J0^`*oUf-m+)WhZMz4Snm;5$A2B z51vP^tbAUoGFDn;E&t-#w1R|ic?0hKY1N~uhEEECr6322_u0TBJ+F#OE9~6+WIvxr{G4xdz{#!1*_YHUvMAz(ikZQmI#l5#2y<9;g6@dVju<5T+=6# z#97ZvA$Fs42yv?sq=Cqwezr*AcZ@}1ai7J8T2|`;*I_cMS6!w2y^rcuUiiKAhMd-3 zW31-J+qwBAEPlsg-DLauw{rBTN-5EFUzLJ!FuDzgR5qpQL*h6fllo=-(SZym#t3Q2bgwk-t*Vj{hiS zr*ow6LSug2^snpHL*gf^?~NN@IS_Di(zX9rgyNm;fi};C1%yAS-1U)Vr+zt>{(4lc z1TE@jZh2R7=I3p998*_GbGlu3AQmkiN;$swvvHY)*t^Tto-7|A5zrZH^EfI}<_lB) zFaZ8{;KvO$L8l3`bmN!vo4-bSmY1I_qlV)6PYE&9q5`VAp9%b=I^9m3yRWeERXjh* z>4z6wbk3R-vSDL=tZl^m&$sB*A8%4^1Y15cyyVl&V7BLTpLpyV&Sy)dXGqa>TyGqn zsQIcwhohUPa4k8ru!j4zxbl4t!BGF(gOF(VSn1_iTn*d@{EOh-lsJ>(5?3u`I0_)S z>%99J646qIOKKLAB6O_iS{s-U;dng{_qcaaJ(>}#!77zq3tf*Lr#vUM{6y6h&bww# zZ)fiq#yQo#{`g5gB(hh``uj9Btp>1h&3wIQP^en%>O${GOY)i8KOWw=cdR>2>OA&l z^pEC23FH$sde~U`@=!w#QAt=4Vr)<1+Wa~MAj5B2$)fHaeJNy7cw}w`&_ZYO|5*1` zwrd_uie0b5S6--_xSXFVdq(yrgvW|>V(r}@E?3{d1P!Pqp%C99Ti9!z(8RBu7!K5k5l7_OE z$ewH|yhc$9FD>U8y}xsQ=Q`VUuJg~iuV?PLm+$>~zWe=sY@j8jitXf+G}|&=B_DM-LmFJ`bWp08uY{ z1(RFI*A}T_xIDPYEzcZ_)QUtABeUB$A-ihCcu`<&Qv)m!DsFd9f&CVei1Zip%3_Y7 zmgYwz1a#$YdqG{y+sAGOUN>x%NIXD7S}8owL#7#ViP@zqbmk!~j5v=*@air~*byz{ z4IdZbY8na(yslSAN+WW-%tiJ{K;=ULfF3Gjo-NdS zU&ivalI5_mEh=tQ8-?1$qsN&KOw(JKiE3b0d8*dmWps`;XZIbkgf^6 zdsO^<(J+w0Tc(9=A14+Si(8%7YA2{0(oCM``0y$StwM1R#w>49|1HEmzZ~! zp$QW?MT%S$-ltGi!m_7MaFZDqdc8Pf(};h2x^a4@dB*18^U$h)#L7k(HJXoh8N*C( zVm%HD79Es?05#(JEl7o^*9-VkN$xqLe~1YKUr4u==nRuF z4VUT7Q8Lffw0xlVa#+v$tFf(+^|1XJhln%N56?{IS&v6pPe!1e8qiLS*vT=hTLE@< zEAF2j{GmM&%>ZE8j96}#R&GXI(8-a3+?A>U05PUF$)}a+5EsmHWXuc7&5J)cmHGsb zePbw9EPEsdOcG|3C%sc3zf&lEhbWb{D8)FJk^`vng)~Mp^?!O)_8dG500y%qdb1@! z2R8=?kUi~!vA_a^@^oi`P7iwg-!j^K1r>@OV*h6Y0DzjzGo+F!PSZTk-m<~oy20L3 z7-fU{pPH8Su%-UaK1;(8FK)wu$QrK*TL@g<20BGOl(^QPxZ`TPlFZ3d2rG_5Pk z^Hfrf%tK~WcY)r*A_4xC5<&La09yb^gqtap3wfp^DvM61D=gi_CBqjba74sXNd!`H zsVL&C#dA?`T3Lic>dNKg&RWRb1^oly1b_SQ4rU2M42l4PVUC{77fstdO&g&zb`fY> zP4xH|z0t2$b}0QJdz2jtJ86${D$skSsXuIwdZmdP1*c%{C^&-}#SY`~QxT}?0_@Zl z+C?PN7KNR*M^7C`jc=kSH{+bf@Lpf^P~WVE@%qCNm{B~|1&>B=S=kj>kLP2C@z|++ z4EiEwa!YGC0zHhvOh%w5BQXw-&`z6i!}z4xe2kj|#z{01y_MuLp8p{NJ?(&TIDQ`7 zbs0~ZAH#dx(z8K<$mmy^Xa_vn%>g|=rZt?$M4q%qJ4J%XXooTUD@`Wyls4L-fQjr- zfS-;4i7`&wD2GkF(|G>;7B z!4N*qBOg2Oh;c$(o_8#m-pa>-P>$G1(eq9s$!^=XKWxS=MB&k5!P84Gn%8)`*UESM zhDWhpx8kOqeB3S)=S6j&t}j$m?iEsx@l-19fBKQp^4*2`U4q#a7LSLBR6{1RfpjgYMqMM=Y4?TUq~&U|TpGASt|L(t`^l6yG=EBC z5QTzmp{(xEu#9Gq6D)81TV#-pAQI)6OK~NMiM*If2EmmI z$&|i=rCSsbc_p(NFG=z?HM_0Y7Q z1fyuodh{XIsQ~NIh?xh8A7NZJ@#Fb;xAC}zam@5$GwowPt!|f6v(xx#w z(NF;3QoG9|Bu*0mQoyW`?vW1X%0LbvIPco_A(mj?1BP5u`7aP$Qh7PxT3(*|5-cwV z$pwy__eeh00)%ey=cAK>h5kG&ie|N~^erX%J&X9k0}J0+s6wSuxr;6Ly?*yj($BB0E`tN zsBuUoK#e%060?vNQWbduV7i_IuT^&=F?mhzGXPW$RLE(Ca^{`8ck%wm&g{S1_)kw% z|94RT>52ap{Qm>u{Qp{2{}=hVfvmJpAS>n{o@oX;S-P!-LRV1&6uv0xHE1rc;Q0d4 zB>}qP2Z=-|(qH*eALygyBS`Em9MbtZNTjh;UM}SF5^)WQyncU?6!@w9;rT$S){?Vx zjn;S(?q$7xZESzw>x_iYo=OM7-1|xeRuQD0f75eR=|L8phmh#D1%*u8Ju7VLXapZK@KDu5)CsC81~s}95Av% z4BhfP8=xU&#*gsP{P@Q6z+ zLg=iL1g41}Em0*TE7IY$Cum0O*_~q@*k=DygWcYijH0>iz3?8i7FAqcQ+{ z0%7k+5DDL5>k?flCLEtB_t%I#m6NiTuRP}yp|A?l5jC8S(g_ukm_eYl- zeqTPc-*2Z)tS}g`a$r3B_9~k`vl8~F$`83X&L3T~UhAD;*XACx|ANEWfGb77>cq^S z@rP}`=R6%9^1)xgtNqgWH9Yu+q78ekzdLGp*x2#?j{$&wKxw!n|5*>qU)U1CyMAsg z?$%m$d?RGCbI`V&Ih$EsE3*H&;9!NA_tDlf8()W}&tLd%|IA&)YS^u@!=-^|H0#CE zb@t1n{G3+bW*+$jl>6>;*?ylK!ZOB|fs377sTJWAJTWWRO(zjPY&5(=-uJU&ISaTl zx~dkeuN3PWD=Knt32tA>n!9{>0uU{eH6Mu}eEtZud9$b;hdeg?>q5IzuDtN&;)I3+ zDAzQTNBd4?K6`PG8#U6>n%6hvrd{9<_pNaq4}tFnT9{~&A1J6$G6&AYEz zSD%>TQs})+&K!AE=W@9I2v1K;O0sPkEGs>+uFR&5B>OmRpX^rHYBdX=RJmcDWaaZGBPo&2$Zqx0A)VwTA^T)60 zr?sqjR82@|%b8;)JF5;R=54kp`pKF3yw@HpU1>TbfPOtZfIV!AC~HrJD6gnCK*fh| zglWhgPE&gY%uuwwjruPa)n*J?H|wQ2yN z0%qt0^HRdv)st)BRXQgts$qbfVwsEa`g!!es&tq~k!+B*ZT^k9mtmSFuDf#Pu~t%J z>Za!uD@oov?q{{ArGEAj53Fn=Lof75Yppgtw{_Q%GwyivUL&@X7>CUY(@;Y$?85bNHT_$0X1?!hb-U?_W}O0 zJOE1*`2O(ryi6nCNs(Qxha=Y}?j2cE3jFohSxcOf>AF3;LG_>ceBRBXQ>Rn8CIvrV ze6{F8Sv|kxtLpi?J~s}*Uq@Pl=9q9@WkCDS*7ZF|aa*0h=m&?#XbINMbLWNxvdmCS zyw50RMr}boqQ3hQ#2pEw5&rWK2gukCTa~gL@C6%gptn8GMj!ig^~e5a*AiR@FVwH? zNA8~aru#E%!A@#M>odo#^HqY#Ph+Fc#1aHQ`(yj-u6&-Jj1F&(--_&>Gx2#(o7Cyt zO?LDpt6C16lb`JI*ij1iGqFlR%RLWA&x*Ml9&jI2yJmaU z6>{tbPzoUgE35*NRJgFgs%jY~EAF;=mo&fh)f>X8u`-|SUaCU}4X&J=QY4!;qn+^7kl>8&=B;kI}|hoxn#am z70eBaJ7F_&>n{7(zj3GoD`q*y)|~axtn!nBz$+;L&;2XsW**=*SRL@a%qagx>FGA8 zLsVyZ&AxjlH`!-*OPZxa|Hwiy?bnHhH{q@-PJFJ$>OAm@xu#|B)3z~2Xb@K zYVQg^xF014nr%s=<#p4NtuilJwNVxyr+waje1hwg#H?5ea39!Lr$r&u0D-qzMxteb z)F(}>@16+KfQguWCQr}(jQ?TDP(Awe`NkA+*5>U`qVJvcW--0bTY8fzmF8o2gbu9^ zPUhjaQ!^Jt3RoH45kKx<;vt?8$J=7NZ@TeK6)#VQ)t3CkhRBXgIcmsK-jJg?+DIba zM%o);zWV&8>>F(wfEuf4LZgR09d4iv=@A5uqa+~WlG`>1cJ{^pcT)T44mqaH}YF~TiI!oRzw*t2 z7r|K?jpz$kb3=(y-|<2S+aLzQD=|USSN;*m47ti+;UHhWS>nQN9<}6WYKn8vW!tw9 zp;*6c;M0dTuCIX)?yrSSQsW?lbVd{Hr;&KRUA0 zy0~z$E6NJ-&4;^>E8C~5ZwwU#3T;Xy@b(I}XGRZGG($7LaSLXSG7V93H`h&%FU9_A z=qE8?o69{tG)I1J|8gM9`f=csN*52*uZf2~8YKA*ZdhK-T~p`xw5|+aSR!<|#Q{u8 z_9FXx!=eji?_5;Yb;(~_vq{r{JB0{687fXZeXaWs|1AC$ggsTzPVj~2g|G_vY?Ohb z6sPKYDm(Ws`S=ZkbMgE?-BkDP2afh6M!ygB(o1G<^f2>-h6=sDDjl`Vv$*xsfO+PI#z@Jb+)Jz!vYfxK^y^S(3W{_4wn*Ga{@-}A;@}qdJDGSQLhaCY@OK0Gcfx;ivycezbtR0 zl+Ws#)MRK1Hw@=-Q-b!fQlqCsLa+qcAbcPtcw-Vy` zW)UG~GijtRJf>G5eD^!bD!pvjYDYD{^N7a;9yz3@T>UXXiFB82uuxqDRkd<$xjjA-Ne{Jh< z;JXoK3N_XbJE|I}c%coeHOU!@Pe}>&)Ws40)CvCCUZCuqS~_>FfFt(_!hW}Sq2;#X zrnz6&>&L~;)Zc$=eECSonHi6fUsn|>I798*g?NNMDc=i_VPtKb%z5`lwcJj`)57|m z#Qe`YUKpB=qQ+de&SFT&@QvfWtJLcS*LJW(f*v)H zGwn<+dJMD0=oHPRQjN3{YRXiX0F+F@8cu?u1suKIik|Q}5X`@~tsvhgw;u zM}*+tj4Y3Q|G_u}s=q01efzmDAAfT9MUE;%Z3B}Pt{TEPTVNc^w&%Mk+97IezMa zbD3FQE9i}Egt)*^R%hOLChTrx3aZuz!1;tSxzHogB*Db>< z+Vq+|`T6Jj+`!`0NblQww%Fp$8{p37?gnoLK1j>~Qnn1YpUgQ$z#Q_}GK1UwF$8#2 z_r2yu7^*%l=g!6voR?8kcVq)5$^94Qabvy8_j7k1e2J4f@9#rCwi6e&&(kj#iycE`peE?Zv+pvf1g?@YLr8muWX!faf@!k_f^zMw}{QU zWzIKh6&2<1RC2C%Wg*yrud`f8uJsA`D`e~0`{#Xw9jim}QtOM^N4CFk)%Ec8t?9PL z+&sSOdhfy8CkTmdmy3V6Z4`Kp{oy(r#a8I4)~cdJ*PSts&cBAI2cKYf7Yg`f1sQV` LszUr|XXX7DkK`_B diff --git a/tff_modular/modules/bloodsucker/structures/coffin.dm b/tff_modular/modules/bloodsucker/structures/coffin.dm deleted file mode 100644 index bc78e9900e3..00000000000 --- a/tff_modular/modules/bloodsucker/structures/coffin.dm +++ /dev/null @@ -1,352 +0,0 @@ -/datum/antagonist/bloodsucker/proc/can_claim_coffin(obj/structure/closet/crate/claimed, area/current_area) - if(coffin) - return FALSE - // ALREADY CLAIMED - if(claimed.resident) - if(claimed.resident != owner.current) - claimed.balloon_alert(owner.current, "already claimed by another!") - return FALSE - if(!(GLOB.the_station_areas.Find(current_area.type))) - claimed.balloon_alert(owner.current, "not part of station!") - return - return TRUE - -/datum/antagonist/bloodsucker/proc/claim_coffin(obj/structure/closet/crate/claimed, area/current_area) - if(!can_claim_coffin(claimed, current_area)) - return FALSE - // This is my Haven - coffin = claimed - bloodsucker_haven_area = current_area - if(!locate(/datum/action/cooldown/bloodsucker/gohome) in powers) - BuyPower(new /datum/action/cooldown/bloodsucker/gohome) - to_chat(owner, span_userdanger("You have claimed the [claimed] as your place of immortal rest! Your haven is now [bloodsucker_haven_area].")) - to_chat(owner, span_announce("Bloodsucker Tip: Find new haven recipes in the Structures tab of the Crafting Menu, including the Persuasion Rack for converting crew into Ghouls.")) - return TRUE - -/// From crate.dm -/obj/structure/closet/crate - breakout_time = 20 SECONDS - ///The resident (owner) of this crate/coffin. - var/mob/living/resident - ///The time it takes to pry this open with a crowbar. - var/pry_lid_timer = 25 SECONDS - -/obj/structure/closet/crate/coffin/examine(mob/user) - . = ..() - if(user == resident) - . += span_cult("This is your Claimed Coffin.") - . += span_cult("Rest in it while injured to enter Torpor. Entering it with unspent Ranks will allow you to spend one.") - . += span_cult("Going inside while it contains a heart will put it in your chest, letting you regain your might.") - . += span_cult("Alt-Click while inside the Coffin to Lock/Unlock. This also fixes the lock if it's broken.") - . += span_cult("Alt-Click while outside of your Coffin to Unclaim it, unwrenching it and all your other structures as a result.") - -/obj/structure/closet/crate/coffin/blackcoffin - name = "black coffin" - desc = "For those departed who are not so dear." - icon_state = "coffin" - icon = 'tff_modular/modules/bloodsucker/icons/vamp_obj.dmi' - open_sound = 'sound/machines/closet/wooden_closet_open.ogg' - close_sound = 'sound/machines/closet/wooden_closet_close.ogg' - breakout_time = 30 SECONDS - pry_lid_timer = 20 SECONDS - resistance_flags = NONE - material_drop = /obj/item/stack/sheet/iron - material_drop_amount = 2 - armor_type = /datum/armor/blackcoffin - custom_materials = list(/datum/material/wood = SHEET_MATERIAL_AMOUNT * 5, /datum/material/iron = SHEET_MATERIAL_AMOUNT) - -/datum/armor/blackcoffin - melee = 50 - bullet = 20 - laser = 30 - bomb = 50 - fire = 70 - acid = 60 - -/obj/structure/closet/crate/coffin/securecoffin - name = "secure coffin" - desc = "For those too scared of having their place of rest disturbed." - icon_state = "securecoffin" - base_icon_state = "securecoffin" - icon = 'tff_modular/modules/bloodsucker/icons/vamp_obj.dmi' - open_sound = 'sound/machines/closet/wooden_closet_open.ogg' - close_sound = 'sound/machines/closet/wooden_closet_close.ogg' - breakout_time = 35 SECONDS - pry_lid_timer = 35 SECONDS - resistance_flags = FIRE_PROOF | LAVA_PROOF | ACID_PROOF - material_drop = /obj/item/stack/sheet/iron - material_drop_amount = 2 - armor_type = /datum/armor/securecoffin - custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 5.5, /datum/material/alloy/plasteel = SHEET_MATERIAL_AMOUNT * 5) - -/datum/armor/securecoffin - melee = 35 - bullet = 20 - laser = 20 - bomb = 100 - fire = 100 - acid = 100 - -/obj/structure/closet/crate/coffin/meatcoffin - name = "meat coffin" - desc = "When you're ready to meat your maker, the steaks can never be too high." - icon_state = "meatcoffin" - base_icon_state = "meatcoffin" - icon = 'tff_modular/modules/bloodsucker/icons/vamp_obj.dmi' - resistance_flags = FIRE_PROOF - open_sound = 'sound/effects/footstep/slime1.ogg' - close_sound = 'sound/effects/footstep/slime1.ogg' - breakout_time = 25 SECONDS - pry_lid_timer = 20 SECONDS - material_drop = /obj/item/food/meat/slab/human - material_drop_amount = 3 - armor_type = /datum/armor/meatcoffin - custom_materials = list( - /datum/material/meat = SHEET_MATERIAL_AMOUNT * 20, - /datum/material/iron = SMALL_MATERIAL_AMOUNT * 1.5, - /datum/material/glass = SMALL_MATERIAL_AMOUNT * 1.5, - ) - -/datum/armor/meatcoffin - melee = 70 - bullet = 10 - laser = 10 - bomb = 70 - fire = 70 - acid = 60 - -/obj/structure/closet/crate/coffin/metalcoffin - name = "metal coffin" - desc = "A big metal sardine can inside of another big metal sardine can, in space." - icon_state = "metalcoffin" - base_icon_state = "metalcoffin" - icon = 'tff_modular/modules/bloodsucker/icons/vamp_obj.dmi' - resistance_flags = FIRE_PROOF | LAVA_PROOF - open_sound = 'sound/effects/pressureplate.ogg' - close_sound = 'sound/effects/pressureplate.ogg' - breakout_time = 25 SECONDS - pry_lid_timer = 30 SECONDS - material_drop = /obj/item/stack/sheet/iron - material_drop_amount = 5 - armor_type = /datum/armor/metalcoffin - custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 7) - -/datum/armor/metalcoffin - melee = 40 - bullet = 15 - laser = 50 - bomb = 10 - fire = 70 - acid = 60 - -////////////////////////////////////////////// - -/// NOTE: This can be any coffin that you are resting AND inside of. -/obj/structure/closet/crate/coffin/proc/claim_coffin(mob/living/claimant, area/current_area) - var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(claimant) - // Successfully claimed? - if(bloodsuckerdatum.claim_coffin(src, current_area)) - resident = claimant - anchored = TRUE - if(!(interaction_flags_click & ALLOW_RESTING)) - interaction_flags_click = interaction_flags_click | ALLOW_RESTING - START_PROCESSING(SSprocessing, src) - return TRUE - return FALSE - -/obj/structure/closet/crate/coffin/Destroy() - unclaim_coffin() - STOP_PROCESSING(SSprocessing, src) - return ..() - -/obj/structure/closet/crate/coffin/process() - . = ..() - if(!.) - return FALSE - var/list/turf/area_turfs = get_area_turfs(get_area(src)) - // Create Dirt etc. - var/turf/T_Dirty = pick(area_turfs) - if(T_Dirty && !T_Dirty.density) - // Default: Dirt - // STEP ONE: COBWEBS - // CHECK: Wall to North? - var/turf/check_N = get_step(T_Dirty, NORTH) - if(istype(check_N, /turf/closed/wall)) - // CHECK: Wall to West? - var/turf/check_W = get_step(T_Dirty, WEST) - if(istype(check_W, /turf/closed/wall)) - new /obj/effect/decal/cleanable/cobweb(T_Dirty) - // CHECK: Wall to East? - var/turf/check_E = get_step(T_Dirty, EAST) - if(istype(check_E, /turf/closed/wall)) - new /obj/effect/decal/cleanable/cobweb/cobweb2(T_Dirty) - new /obj/effect/decal/cleanable/dirt(T_Dirty) - -/obj/structure/closet/crate/proc/unclaim_coffin(manual = FALSE, silent = FALSE) - // Unanchor it (If it hasn't been broken, anyway) - anchored = FALSE - if(!resident || !resident.mind) - return - un_enlarge(resident) - // Unclaiming - var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(resident) - if(bloodsuckerdatum && bloodsuckerdatum.coffin == src) - bloodsuckerdatum.coffin = null - bloodsuckerdatum.bloodsucker_haven_area = null - for(var/datum/action/cooldown/bloodsucker/gohome/power in bloodsuckerdatum.powers) - bloodsuckerdatum.RemovePower(power) - for(var/obj/structure/bloodsucker/bloodsucker_structure in get_area(src)) - if(bloodsucker_structure.owner == resident) - bloodsucker_structure.unbolt() - if(!silent) - if(manual) - to_chat(resident, span_cult_italic("You have unclaimed your coffin! This also unclaims all your other Bloodsucker structures!")) - else - to_chat(resident, span_cult_italic("You sense that the link with your coffin and your sacred haven has been broken! You will need to seek another.")) - // Remove resident. Because this object isnt removed from the game immediately (GC?) we need to give them a way to see they don't have a home anymore. - resident = null - if(interaction_flags_click & ALLOW_RESTING) - interaction_flags_click = interaction_flags_click & ~ALLOW_RESTING - -/// You cannot lock in/out a coffin's owner. SORRY. -/obj/structure/closet/crate/coffin/can_open(mob/living/user) - if(!locked) - return ..() - if(user == resident) - if(welded) - welded = FALSE - update_icon() - locked = FALSE - return TRUE - playsound(get_turf(src), 'sound/machines/closet/wooden_closet_close.ogg', 20, 1) - to_chat(user, span_notice("[src] appears to be locked tight from the inside.")) - -/obj/structure/closet/crate/coffin/close(mob/living/user) - var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(user) - if(bloodsuckerdatum && user.mob_size > max_mob_size) - if(!HAS_TRAIT_FROM_ONLY(src, TRAIT_COFFIN_ENLARGED, "bloodsucker_coffin")) - if(prompt_coffin_claim(bloodsuckerdatum)) - enlarge(user) - else - user.balloon_alert(user, "already claimed by another!") - . = ..() - if(!.) - return FALSE - for(var/atom/thing as anything in contents) - SEND_SIGNAL(thing, COMSIG_ENTER_COFFIN, src, user) - return TRUE - -// /obj/structure/closet/crate/coffin/proc/is_claimable_coffin(datum/antagonist/bloodsucker/dracula, area/current_area) -// if(!dracula) -// return FALSE -// if(resident == dracula.owner.current) -// return TRUE -// if(!dracula.can_claim_coffin(src, current_area)) -// return FALSE -// if(!dracula.coffin && resident) -// return FALSE -// return TRUE - -/obj/structure/closet/crate/coffin/proc/prompt_coffin_claim(datum/antagonist/bloodsucker/dracula) - var/area/current_area = get_area(src) - switch(tgui_alert(dracula.owner.current, "Do you wish to claim this as your coffin? [current_area] will be your haven.", "Claim Haven", list("Yes", "No"))) - if("Yes") - return claim_coffin(dracula.owner.current, current_area) - return FALSE - -// some fatass bloodsucker is trying to fit in a too-small coffin, how about we make some room? -/obj/structure/closet/crate/proc/enlarge(mob/living/user) - ADD_TRAIT(src, TRAIT_COFFIN_ENLARGED, "bloodsucker_coffin") - max_mob_size = user.mob_size - to_chat(user, span_warning("The coffin creaks and squeaks as you try to squeeze into it. It's a tight fit but you manage it make it fit you.")) - animate(src, 1 SECONDS, FALSE, BOUNCE_EASING, transform = transform.Scale(user.mob_size * COFFIN_ENLARGE_MULT)) - -/obj/structure/closet/crate/proc/un_enlarge(mob/living/user) - if(!HAS_TRAIT_FROM_ONLY(src, TRAIT_COFFIN_ENLARGED, "bloodsucker_coffin")) - return - REMOVE_TRAIT(src, TRAIT_COFFIN_ENLARGED, "bloodsucker_coffin") - max_mob_size = initial(max_mob_size) - var/matrix/normal - // transform.Scale(user.mob_size * (COFFIN_ENLARGE_MULT + 1) - animate(src, 1 SECONDS, FALSE, transform = normal) - -/// You cannot weld or deconstruct an owned coffin. Only the owner can destroy their own coffin. -/obj/structure/closet/crate/coffin/wrench_act_secondary(mob/living/user, obj/item/tool) - if(resident && anchored) - to_chat(user, span_danger("The coffin won't come unanchored from the floor.[user == resident ? " You can Alt-Click to unclaim and unwrench your Coffin." : ""]")) - return TRUE - . = ..() - -/obj/structure/closet/crate/coffin/tool_interact(obj/item/weapon, mob/living/user) - if(locked && (weapon.tool_behaviour == TOOL_CROWBAR)) - var/pry_time = pry_lid_timer * weapon.toolspeed // Pry speed must be affected by the speed of the tool. - user.visible_message( - span_notice("[user] tries to pry the lid off of [src] with [weapon]."), - span_notice("You begin prying the lid off of [src] with [weapon]. This should take about [DisplayTimeText(pry_time)].") - ) - if(!do_after(user, pry_time, src)) - return TRUE - bust_open() - user.visible_message( - span_notice("[user] snaps the door of [src] wide open."), - span_notice("The door of [src] snaps open.") - ) - return TRUE - if(!resident) - . = ..() - if(user != resident) - if(istype(weapon, cutting_tool)) - to_chat(user, span_notice("This is a much more complex mechanical structure than you thought. You don't know where to begin cutting [src].")) - return TRUE - . = ..() - -/// Forces the coffin to get contents -/obj/structure/closet/proc/force_enter(mob/living/user) - SEND_SIGNAL(src, COMSIG_CLOSET_PRE_CLOSE, user) - take_contents() - var/inserted = insert(user) - playsound(loc, close_sound, close_sound_volume, TRUE, -3) - opened = FALSE - set_density(TRUE) - animate_door(TRUE) - update_appearance() - after_close(user) - SEND_SIGNAL(src, COMSIG_CLOSET_POST_CLOSE, user) - return inserted - -/// Distance Check (Inside Of) -/obj/structure/closet/crate/coffin/click_alt(mob/user) - . = ..() - if(user in src) - LockMe(user, !locked) - return CLICK_ACTION_SUCCESS - - if(user == resident && user.Adjacent(src)) - balloon_alert(user, "unclaim coffin?") - var/static/list/unclaim_options = list( - "Yes" = image(icon = 'icons/hud/radial.dmi', icon_state = "radial_yes"), - "No" = image(icon = 'icons/hud/radial.dmi', icon_state = "radial_no")) - var/unclaim_response = show_radial_menu(user, src, unclaim_options, radius = 36, require_near = TRUE) - switch(unclaim_response) - if("Yes") - unclaim_coffin(TRUE) - return CLICK_ACTION_SUCCESS - -/obj/structure/closet/crate/proc/LockMe(mob/user, inLocked = TRUE) - if(user == resident) - if(!broken) - locked = inLocked - if(locked) - to_chat(user, span_notice("You flip a secret latch and lock yourself inside [src].")) - else - to_chat(user, span_notice("You flip a secret latch and unlock [src].")) - return TRUE - // Broken? Let's fix it. - to_chat(resident, span_notice("The secret latch that would lock [src] from the inside is broken. You set it back into place...")) - if(!do_after(resident, 5 SECONDS, src)) - to_chat(resident, span_notice("You fail to fix [src]'s mechanism.")) - return FALSE - to_chat(resident, span_notice("You fix the mechanism and lock it.")) - broken = FALSE - locked = TRUE - return TRUE diff --git a/tff_modular/modules/bloodsucker/structures/crypt.dm b/tff_modular/modules/bloodsucker/structures/crypt.dm deleted file mode 100644 index e753d72ca32..00000000000 --- a/tff_modular/modules/bloodsucker/structures/crypt.dm +++ /dev/null @@ -1,642 +0,0 @@ -/obj/structure/bloodsucker - ///Who owns this structure? - var/mob/living/owner - /* - * We use vars to add descriptions to items. - * This way we don't have to make a new /examine for each structure - * And it's easier to edit. - */ - var/ghost_desc - var/vamp_desc - var/ghoul_desc - var/hunter_desc - -/obj/structure/bloodsucker/examine(mob/user) - . = ..() - if(!user.mind && ghost_desc != "") - . += span_cult(ghost_desc) - if(IS_BLOODSUCKER(user) && vamp_desc) - if(!owner) - . += span_cult("It is unsecured. Click on [src] while in your haven to secure it in place to get its full potential.") - return - . += span_cult(vamp_desc) - if(IS_GHOUL(user) && ghoul_desc != "") - . += span_cult(ghoul_desc) - if(IS_MONSTERHUNTER(user) && hunter_desc != "") - . += span_cult(hunter_desc) - -/// This handles bolting down the structure. -/obj/structure/bloodsucker/proc/bolt(mob/user) - to_chat(user, span_danger("You have secured [src] in place.")) - to_chat(user, span_announce("* Bloodsucker Tip: Examine [src] to understand how it functions!")) - owner = user - -/// This handles unbolting of the structure. -/obj/structure/bloodsucker/proc/unbolt(mob/user) - to_chat(user, span_danger("You have unsecured [src].")) - owner = null - -/obj/structure/bloodsucker/attackby(obj/item/item, mob/living/user, params) - /// If a Bloodsucker tries to wrench it in place, yell at them. - if(item.tool_behaviour == TOOL_WRENCH && !anchored && IS_BLOODSUCKER(user)) - user.playsound_local(null, 'sound/machines/buzz/buzz-sigh.ogg', 40, FALSE, pressure_affected = FALSE) - to_chat(user, span_announce("* Bloodsucker Tip: Examine Bloodsucker structures to understand how they function!")) - return - return ..() - -/obj/structure/bloodsucker/attack_hand(mob/user, list/modifiers) -// . = ..() // Don't call parent, else they will handle unbuckling. - var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(user) - /// Claiming the Rack instead of using it? - if(istype(bloodsuckerdatum) && !owner) - if(!bloodsuckerdatum.bloodsucker_haven_area) - to_chat(user, span_danger("You don't have a haven. Claim a coffin to make that location your haven.")) - return FALSE - if(bloodsuckerdatum.bloodsucker_haven_area != get_area(src)) - to_chat(user, span_danger("You may only activate this structure in your haven: [bloodsuckerdatum.bloodsucker_haven_area].")) - return FALSE - - /// Radial menu for securing your Persuasion rack in place. - to_chat(user, span_notice("Do you wish to secure [src] here?")) - var/static/list/secure_options = list( - "Yes" = image(icon = 'icons/hud/radial.dmi', icon_state = "radial_yes"), - "No" = image(icon = 'icons/hud/radial.dmi', icon_state = "radial_no")) - var/secure_response = show_radial_menu(user, src, secure_options, radius = 36, require_near = TRUE) - if(!secure_response) - return FALSE - switch(secure_response) - if("Yes") - user.playsound_local(null, 'sound/items/tools/ratchet.ogg', 70, FALSE, pressure_affected = FALSE) - bolt(user) - return FALSE - return FALSE - return TRUE - -/obj/structure/bloodsucker/click_alt(mob/user) - . = ..() - if(user == owner && user.Adjacent(src)) - balloon_alert(user, "unbolt [src]?") - var/static/list/unclaim_options = list( - "Yes" = image(icon = 'icons/hud/radial.dmi', icon_state = "radial_yes"), - "No" = image(icon = 'icons/hud/radial.dmi', icon_state = "radial_no"), - ) - var/unclaim_response = show_radial_menu(user, src, unclaim_options, radius = 36, require_near = TRUE) - switch(unclaim_response) - if("Yes") - unbolt(user) - return CLICK_ACTION_SUCCESS -/* -/obj/structure/bloodsucker/bloodaltar - name = "bloody altar" - desc = "It is made of marble, lined with basalt, and radiates an unnerving chill that puts your skin on edge." -/obj/structure/bloodsucker/bloodstatue - name = "bloody countenance" - desc = "It looks upsettingly familiar..." -/obj/structure/bloodsucker/bloodportrait - name = "oil portrait" - desc = "A disturbingly familiar face stares back at you. Those reds don't seem to be painted in oil..." -/obj/structure/bloodsucker/bloodbrazier - name = "lit brazier" - desc = "It burns slowly, but doesn't radiate any heat." -/obj/structure/bloodsucker/bloodmirror - name = "faded mirror" - desc = "You get the sense that the foggy reflection looking back at you has an alien intelligence to it." -/obj/item/restraints/legcuffs/beartrap/bloodsucker -*/ - -/obj/structure/bloodsucker/ghoulrack - name = "persuasion rack" - desc = "If this wasn't meant for torture, then someone has some fairly horrifying hobbies." - icon = 'tff_modular/modules/bloodsucker/icons/vamp_obj.dmi' - icon_state = "ghoulrack" - anchored = FALSE - density = TRUE - can_buckle = TRUE - buckle_lying = 180 - ghost_desc = "This is a Ghoul rack, which allows Bloodsuckers to thrall crewmembers into loyal minions." - vamp_desc = "This is the Ghoul rack, which allows you to thrall crewmembers into loyal minions in your service.\n\ - Simply click and hold on a victim, and then drag their sprite on the ghoul rack. Right-click on the ghoul rack to unbuckle them.\n\ - To convert into a Ghoul, repeatedly click on the persuasion rack. The time required scales with the tool in your off hand. This costs Blood to do.\n\ - Ghouls can be turned into special ones by continuing to torture them once converted." - ghoul_desc = "This is the ghoul rack, which allows your master to thrall crewmembers into their minions.\n\ - Aid your master in bringing their victims here and keeping them secure.\n\ - You can secure victims to the ghoul rack by click dragging the victim onto the rack while it is secured." - hunter_desc = "This is the ghoul rack, which monsters use to brainwash crewmembers into their loyal slaves.\n\ - They usually ensure that victims are handcuffed, to prevent them from running away.\n\ - Their rituals take time, allowing us to disrupt it." - custom_materials = list( - /datum/material/wood = SHEET_MATERIAL_AMOUNT * 3, - /datum/material/iron = SHEET_MATERIAL_AMOUNT * 2.3, - /datum/material/glass = SMALL_MATERIAL_AMOUNT * 3, - ) - - /// Resets on each new character to be added to the chair. Some effects should lower it... - var/convert_progress = 3 - /// Mindshielded and Antagonists willingly have to accept you as their Master. - var/disloyalty_confirm = FALSE - /// Prevents popup spam. - var/disloyalty_offered = FALSE - -/obj/structure/bloodsucker/ghoulrack/examine(mob/user) - . = ..() - var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(user) - if(bloodsuckerdatum) - . += span_cult("You can support a total of [convert_integer_to_words(bloodsuckerdatum.max_ghouls())] [bloodsuckerdatum.max_ghouls() == 1 ? "ghoul" : "ghouls"], \ - with [convert_integer_to_words(bloodsuckerdatum.free_ghoul_slots())] [bloodsuckerdatum.free_ghoul_slots() == 1 ? "slot" : "slots"] remaining.") - -/obj/structure/bloodsucker/ghoulrack/atom_deconstruct(disassembled = TRUE) - . = ..() - new /obj/item/stack/sheet/iron(src.loc, 4) - new /obj/item/stack/rods(loc, 4) - qdel(src) - -/obj/structure/bloodsucker/ghoulrack/bolt() - . = ..() - density = FALSE - anchored = TRUE - -/obj/structure/bloodsucker/ghoulrack/unbolt() - . = ..() - density = TRUE - anchored = FALSE - -/obj/structure/bloodsucker/ghoulrack/mouse_drop_receive(atom/movable/movable_atom, mob/user, params) - var/mob/living/living_target = movable_atom - if(!anchored && IS_BLOODSUCKER(user)) - user.balloon_alert(user, "not secured!") - to_chat(user, span_danger("Until this rack is secured in place, it cannot serve its purpose.")) - to_chat(user, span_announce("* Bloodsucker Tip: Examine the Persuasion Rack to understand how it functions!")) - return - // Default checks - if(!isliving(movable_atom) || !living_target.Adjacent(src) || living_target == user || !isliving(user) || has_buckled_mobs() || user.incapacitated || living_target.buckled) - return - // Don't buckle Silicon to it please. - if(issilicon(living_target)) - to_chat(user, span_danger("You realize that this machine cannot be ghouled, therefore it is useless to buckle them.")) - return - if(do_after(user, 5 SECONDS, living_target)) - attach_victim(living_target, user) - -/// Attempt Release (Owner vs Non Owner) -/obj/structure/bloodsucker/ghoulrack/attack_hand_secondary(mob/user, modifiers) - . = ..() - if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN) - return - if(!user.can_perform_action(src)) - return - if(!has_buckled_mobs() || !isliving(user)) - return - var/mob/living/carbon/buckled_carbons = pick(buckled_mobs) - if(buckled_carbons) - if(user == owner) - unbuckle_mob(buckled_carbons) - else - user_unbuckle_mob(buckled_carbons, user) - return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN - -/** - * Attempts to buckle target into the ghoulrack - */ -/obj/structure/bloodsucker/ghoulrack/proc/attach_victim(mob/living/target, mob/living/user) - if(!buckle_mob(target)) - return - user.visible_message( - span_notice("[user] straps [target] into the rack, immobilizing them."), - span_boldnotice("You secure [target] tightly in place. They won't escape you now."), - ) - - playsound(loc, 'sound/effects/pop_expl.ogg', 25, 1) - update_appearance(UPDATE_ICON) - density = TRUE - - // Set up Torture stuff now - convert_progress = 3 - disloyalty_confirm = FALSE - disloyalty_offered = FALSE - -/// Attempt Unbuckle -/obj/structure/bloodsucker/ghoulrack/user_unbuckle_mob(mob/living/buckled_mob, mob/user) - if(IS_BLOODSUCKER(user) || IS_GHOUL(user)) - return ..() - - if(buckled_mob == user) - buckled_mob.visible_message( - span_danger("[user] tries to release themself from the rack!"), - span_danger("You attempt to release yourself from the rack!"), - span_hear("You hear a squishy wet noise.")) - if(!do_after(user, 20 SECONDS, buckled_mob)) - return - else - buckled_mob.visible_message( - span_danger("[user] tries to pull [buckled_mob] rack!"), - span_danger("[user] tries to pull [buckled_mob] rack!"), - span_hear("You hear a squishy wet noise.")) - if(!do_after(user, 10 SECONDS, buckled_mob)) - return - - return ..() - -/obj/structure/bloodsucker/ghoulrack/unbuckle_mob(mob/living/buckled_mob, force = FALSE, can_fall = TRUE) - . = ..() - if(!.) - return - visible_message(span_danger("[buckled_mob][buckled_mob.stat == DEAD ? "'s corpse" : ""] slides off of the rack.")) - density = FALSE - buckled_mob.Paralyze(2 SECONDS) - update_appearance(UPDATE_ICON) - -/obj/structure/bloodsucker/ghoulrack/attack_hand(mob/user, list/modifiers) - . = ..() - if(!.) - return FALSE - // Is there anyone on the rack & If so, are they being tortured? - if(!has_buckled_mobs()) - return FALSE - - var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(user) - var/mob/living/carbon/buckled_carbons = pick(buckled_mobs) - // If I'm not a Bloodsucker, try to unbuckle them. - if(!istype(bloodsuckerdatum)) - user_unbuckle_mob(buckled_carbons, user) - return - if(!bloodsuckerdatum.my_clan) - to_chat(user, span_warning("You can't ghoul people until you enter a Clan (Through your Antagonist UI button)")) - user.balloon_alert(user, "join a clan first!") - return - var/datum/antagonist/ghoul/ghouldatum = IS_GHOUL(buckled_carbons) - // Are they our Ghoul? - if(ghouldatum && (ghouldatum in bloodsuckerdatum.ghouls)) - SEND_SIGNAL(bloodsuckerdatum, COMSIG_BLOODSUCKER_INTERACT_WITH_GHOUL, ghouldatum) - return - if(bloodsuckerdatum.free_ghoul_slots() < 1) - to_chat(user, span_warning("You can't ghoul more people until you level up more! You are currently at [bloodsuckerdatum.free_ghoul_slots()] active / [bloodsuckerdatum.max_ghouls()] max ghouls.")) - user.balloon_alert(user, "not enough ghoul slots!") - return - - - // Not our Ghoul, but Alive & We're a Bloodsucker, good to torture! - torture_victim(user, buckled_carbons) - -/** - * Torture steps: - * - * * Tick Down Conversion from 3 to 0 - * * Break mindshielding/antag (on approve) - * * Ghoulize target - */ -/obj/structure/bloodsucker/ghoulrack/proc/torture_victim(mob/living/user, mob/living/target) - var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(user) - if(IS_GHOUL(target)) - var/datum/antagonist/ghoul/ghouldatum = IS_GHOUL(target) - if(!ghouldatum.master.broke_masquerade) - balloon_alert(user, "someone else's ghoul!") - return FALSE - - var/disloyalty_requires = RequireDisloyalty(user, target) - if(disloyalty_requires == GHOULING_BANNED) - if(target.ckey) - balloon_alert(user, "can't be ghouled!") - else - balloon_alert(user, "target has no mind!") - return FALSE - - // Conversion Process - if(convert_progress) - balloon_alert(user, "spilling blood...") - bloodsuckerdatum.AdjustBloodVolume(-TORTURE_BLOOD_HALF_COST) - if(!do_torture(user, target)) - return FALSE - bloodsuckerdatum.AdjustBloodVolume(-TORTURE_BLOOD_HALF_COST) - // Prevent them from unbuckling themselves as long as we're torturing. - target.Paralyze(1 SECONDS) - convert_progress-- - - // We're done? Let's see if they can be Ghoul. - if(convert_progress) - balloon_alert(user, "needs more persuasion...") - return - - if(disloyalty_requires) - balloon_alert(user, "has external loyalties! more persuasion required!") - else - balloon_alert(user, "ready for communion!") - return - - if(!disloyalty_confirm && disloyalty_requires) - if(!do_disloyalty(user, target)) - return - if(!disloyalty_confirm) - balloon_alert(user, "refused persuasion!") - else - balloon_alert(user, "ready for communion!") - return - - user.balloon_alert_to_viewers("smears blood...", "painting bloody marks...") - if(!do_after(user, 5 SECONDS, target)) - balloon_alert(user, "interrupted!") - return - // Convert to Ghoul! - bloodsuckerdatum.AdjustBloodVolume(-TORTURE_CONVERSION_COST) - remove_loyalties(target) - if(bloodsuckerdatum.make_ghoul(target)) - SEND_SIGNAL(bloodsuckerdatum, COMSIG_BLOODSUCKER_MADE_GHOUL, user, target) - -/obj/structure/bloodsucker/ghoulrack/proc/do_torture(mob/living/user, mob/living/carbon/target, mult = 1) - // Fifteen seconds if you aren't using anything. Shorter with weapons and such. - var/torture_time = 15 - var/torture_dmg_brute = 2 - var/torture_dmg_burn = 0 - var/obj/item/bodypart/selected_bodypart = pick(target.bodyparts) - // Get Weapon - var/obj/item/held_item = user.get_inactive_held_item() - /// Weapon Bonus - if(held_item) - torture_time -= held_item.force / 4 - if(!held_item.use_tool(src, user, 0, volume = 5)) - return - switch(held_item.damtype) - if(BRUTE) - torture_dmg_brute = held_item.force / 4 - torture_dmg_burn = 0 - if(BURN) - torture_dmg_brute = 0 - torture_dmg_burn = held_item.force / 4 - switch(held_item.sharpness) - if(SHARP_EDGED) - torture_time -= 2 - if(SHARP_POINTY) - torture_time -= 3 - - // Minimum 5 seconds. - torture_time = max(5 SECONDS, torture_time * 10) - // Now run process. - if(!do_after(user, (torture_time * mult), target)) - return FALSE - - if(held_item) - held_item.play_tool_sound(target) - target.visible_message( - span_danger("[user] performs a ritual, spilling some of [target]'s blood from their [selected_bodypart.name] and shaking them up!"), - span_userdanger("[user] performs a ritual, spilling some blood from your [selected_bodypart.name], shaking you up!")) - - INVOKE_ASYNC(target, TYPE_PROC_REF(/mob, emote), "scream") - target.set_timed_status_effect(5 SECONDS, /datum/status_effect/jitter, only_if_higher = TRUE) - target.apply_damages(brute = torture_dmg_brute, burn = torture_dmg_burn, def_zone = selected_bodypart.body_zone) - return TRUE - -/// Offer them the opportunity to join now. -/obj/structure/bloodsucker/ghoulrack/proc/do_disloyalty(mob/living/user, mob/living/target) - if(disloyalty_offered) - return FALSE - // Can't willingly join if you're banned from it. It'll just ghost you anyways. - if(is_banned_from(target.ckey, ROLE_BLOODSUCKER)) - return TRUE - disloyalty_offered = TRUE - to_chat(user, span_notice("[target] has been given the opportunity for servitude. You await their decision...")) - var/alert_response = tgui_alert( - user = target, \ - message = "You are being tortured! Do you want to give in and pledge your undying loyalty to [user]? \n\ - You will not lose your current objectives, but they come second to the will of your new master!", \ - title = "THE HORRIBLE PAIN! WHEN WILL IT END?!", - buttons = list("Accept", "Refuse"), - timeout = 10 SECONDS, \ - autofocus = TRUE, \ - ) - switch(alert_response) - if("Accept") - disloyalty_confirm = TRUE - target.visible_message( - span_notice("[target] gives in to [user]'s offer of servitude!"), - span_userdanger("You give in to [user]'s offer of servitude!")) - else - target.visible_message( - span_danger("[target] stares defiantly at [user], refusing to give in!"), - span_danger("You stare defiantly at [user], refusing to give in!")) - disloyalty_offered = FALSE - return TRUE - -/obj/structure/bloodsucker/ghoulrack/proc/RequireDisloyalty(mob/living/user, mob/living/target) -#ifdef BLOODSUCKER_TESTING - if(!target || !target.mind) -#else - if(!target?.mind || !target?.client) -#endif - return GHOULING_BANNED - - if(HAS_TRAIT(target, TRAIT_MINDSHIELD)) - return GHOULING_DISLOYAL - var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(user) - return bloodsuckerdatum.AmValidAntag(target) - -/obj/structure/bloodsucker/ghoulrack/proc/remove_loyalties(mob/living/target) - // Find Mind Implant & Destroy - for(var/obj/item/implant/all_implants as anything in target.implants) - if(all_implants.type == /obj/item/implant/mindshield) - all_implants.removed(target, silent = TRUE) - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// todo, make this steal blood into a internal reservoir from nearby non-vassals/bloodsuckers -/obj/structure/bloodsucker/candelabrum - name = "candelabrum" - desc = "It burns slowly, but doesn't radiate any heat." - icon = 'tff_modular/modules/bloodsucker/icons/vamp_obj.dmi' - icon_state = "candelabrum" - light_color = "#66FFFF"//LIGHT_COLOR_BLUEGREEN // lighting.dm - light_power = 3 - light_range = 0 // to 2 - max_integrity = 100 - density = FALSE - can_buckle = TRUE - anchored = FALSE - ghost_desc = "This is a magical candle which drains at the sanity of non Bloodsuckers and Ghouls.\n\ - Ghouls can turn the candle on manually, while Bloodsuckers can do it from a distance." - vamp_desc = "This is a magical candle which drains at the sanity of mortals who are not under your command while it is active.\n\ - You can right-click on it from any range to turn it on remotely, or simply be next to it and click on it to turn it on and off normally." - ghoul_desc = "This is a magical candle which drains at the sanity of the fools who havent yet accepted your master, as long as it is active.\n\ - You can turn it on and off by clicking on it while you are next to it.\n\ - If your Master is part of the Ventrue Clan, they utilize this to upgrade their Favorite Ghoul." - hunter_desc = "This is a blue Candelabrum, which causes insanity to those near it while active." - custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 3.5) - var/lit = FALSE - -/obj/structure/bloodsucker/candelabrum/Destroy() - STOP_PROCESSING(SSobj, src) - return ..() - -/obj/structure/bloodsucker/candelabrum/update_icon_state() - icon_state = "candelabrum[lit ? "_lit" : ""]" - return ..() - -/obj/structure/bloodsucker/candelabrum/bolt() - . = ..() - set_anchored(TRUE) - density = TRUE - -/obj/structure/bloodsucker/candelabrum/unbolt() - . = ..() - set_anchored(FALSE) - density = FALSE - if(lit) - toggle() - -/obj/structure/bloodsucker/candelabrum/attack_hand(mob/living/user, list/modifiers) - . = ..() - if(!.) - return - if(IS_GHOUL(user) || IS_BLOODSUCKER(user)) - toggle() - return ..() - -/obj/structure/bloodsucker/candelabrum/Click(location, control, params) - . = ..() - var/mob/user = usr - var/list/modifiers = params2list(params) - if(!LAZYACCESS(modifiers, RIGHT_CLICK) || !IS_BLOODSUCKER(user) || !istype(user)) - return - if(user.stat >= UNCONSCIOUS) - return - user.balloon_alert_to_viewers("motions their hand at [src]") - toggle(user) - -/obj/structure/bloodsucker/candelabrum/proc/toggle(mob/user) - if(!anchored) - to_chat(user, span_danger("You can't turn this on while it is not secured!")) - return - lit = !lit - if(lit) - desc = initial(desc) - set_light(2, 3, "#66FFFF") - START_PROCESSING(SSobj, src) - else - desc = "Despite not being lit, it makes your skin crawl." - set_light(0) - STOP_PROCESSING(SSobj, src) - update_icon() - - -/obj/structure/bloodsucker/candelabrum/process() - if(!lit) - return - for(var/mob/living/carbon/nearly_people in viewers(7, src)) - /// We dont want Bloodsuckers or Ghouls affected by this - if(IS_GHOUL(nearly_people) || IS_BLOODSUCKER(nearly_people)) - continue - nearly_people.adjust_hallucinations(5 SECONDS) - nearly_people.add_mood_event("vampcandle", /datum/mood_event/vampcandle) - -/// Blood Throne - Allows Bloodsuckers to remotely speak with their Ghouls. - Code (Mostly) stolen from comfy chairs (armrests) and chairs (layers) -/obj/structure/bloodsucker/bloodthrone - name = "wicked throne" - desc = "Twisted metal shards jut from the arm rests. Very uncomfortable looking. It would take a masochistic sort to sit on this jagged piece of furniture." - icon = 'tff_modular/modules/bloodsucker/icons/vamp_obj_64.dmi' - icon_state = "throne" - buckle_lying = 0 - anchored = FALSE - density = TRUE - can_buckle = TRUE - ghost_desc = "This is a Bloodsucker throne, any Bloodsucker sitting on it can remotely speak to their Ghouls by attempting to speak aloud." - vamp_desc = "This is a blood throne, sitting on it will allow you to telepathically speak to your ghouls by simply speaking." - ghoul_desc = "This is a blood throne, it allows your Master to telepathically speak to you and others like you." - hunter_desc = "This is a chair that hurts those that try to buckle themselves onto it, though the Undead have no problem latching on.\n\ - While buckled, Monsters can use this to telepathically communicate with eachother." - custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 5, /datum/material/wood = SHEET_MATERIAL_AMOUNT) - var/mutable_appearance/armrest - -// Add rotating and armrest -/obj/structure/bloodsucker/bloodthrone/Initialize(mapload) - AddComponent(/datum/component/simple_rotation) - armrest = GetArmrest() - armrest.layer = ABOVE_MOB_LAYER - return ..() - -/obj/structure/bloodsucker/bloodthrone/Destroy() - QDEL_NULL(armrest) - return ..() - -/obj/structure/bloodsucker/bloodthrone/bolt() - . = ..() - anchored = TRUE - -/obj/structure/bloodsucker/bloodthrone/unbolt() - . = ..() - anchored = FALSE - -// Armrests -/obj/structure/bloodsucker/bloodthrone/proc/GetArmrest() - return mutable_appearance('tff_modular/modules/bloodsucker/icons/vamp_obj_64.dmi', "thronearm") - -/obj/structure/bloodsucker/bloodthrone/proc/update_armrest() - if(has_buckled_mobs()) - add_overlay(armrest) - else - cut_overlay(armrest) - -// Rotating -/obj/structure/bloodsucker/bloodthrone/setDir(newdir) - . = ..() - if(has_buckled_mobs()) - for(var/m in buckled_mobs) - var/mob/living/buckled_mob = m - buckled_mob.setDir(newdir) - - if(has_buckled_mobs() && dir == NORTH) - layer = ABOVE_MOB_LAYER - else - layer = OBJ_LAYER - -// Buckling -/obj/structure/bloodsucker/bloodthrone/buckle_mob(mob/living/user, force = FALSE, check_loc = TRUE) - if(!anchored) - to_chat(user, span_announce("[src] is not bolted to the ground!")) - return - . = ..() - user.visible_message( - span_notice("[user] sits down on [src]."), - span_boldnotice("You sit down onto [src]."), - ) - if(IS_BLOODSUCKER(user)) - RegisterSignal(user, COMSIG_MOB_SAY, PROC_REF(handle_speech)) - else - unbuckle_mob(user) - user.Paralyze(10 SECONDS) - to_chat(user, span_cult("The power of the blood throne overwhelms you!")) - -/obj/structure/bloodsucker/bloodthrone/post_buckle_mob(mob/living/target) - . = ..() - update_armrest() - target.pixel_y += 2 - -// Unbuckling -/obj/structure/bloodsucker/bloodthrone/unbuckle_mob(mob/living/user, force = FALSE, can_fall = TRUE) - src.visible_message(span_danger("[user] unbuckles themselves from [src].")) - if(IS_BLOODSUCKER(user)) - UnregisterSignal(user, COMSIG_MOB_SAY) - . = ..() - -/obj/structure/bloodsucker/bloodthrone/post_unbuckle_mob(mob/living/target) - target.pixel_y -= 2 - -// The speech itself -/obj/structure/bloodsucker/bloodthrone/proc/handle_speech(datum/source, list/speech_args) - SIGNAL_HANDLER - - var/forced_type = speech_args[SPEECH_FORCED] - if(forced_type == CLAN_MALKAVIAN) - return - var/message = speech_args[SPEECH_MESSAGE] - var/mob/living/carbon/human/user = source - var/rendered = span_cult_large("[user.real_name]: [capitalize(message)]") - user.log_talk(message, LOG_SAY, tag = ROLE_BLOODSUCKER) - var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(user) - for(var/datum/antagonist/ghoul/receiver as anything in bloodsuckerdatum.ghouls) - 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]") - - speech_args[SPEECH_MESSAGE] = "" diff --git a/tff_modular/modules/bloodsucker/structures/objects.dm b/tff_modular/modules/bloodsucker/structures/objects.dm deleted file mode 100644 index 09f108767e5..00000000000 --- a/tff_modular/modules/bloodsucker/structures/objects.dm +++ /dev/null @@ -1,358 +0,0 @@ -////////////////////// -// BLOODBAG // -////////////////////// - -#define BLOODBAG_GULP_SIZE 5 - -/obj/item/reagent_containers/blood - var/being_drunk = FALSE - -/// Taken from drinks.dm -/obj/item/reagent_containers/blood/attack(mob/living/victim, mob/living/attacker, params) - if(!can_drink(victim, attacker) || being_drunk) - return - being_drunk = TRUE - if(victim != attacker) - // show to both victim and attacker - INVOKE_ASYNC(src, GLOBAL_PROC_REF(do_after), victim, 5 SECONDS, attacker) - do_after(victim, 5 SECONDS, attacker) - if(!do_after(attacker, 5 SECONDS, victim)) - being_drunk = FALSE - return - attacker.visible_message( - span_notice("[attacker] forces [victim] to drink from the [src]."), - span_notice("You put the [src] up to [victim]'s mouth.")) - reagents.trans_to(victim, BLOODBAG_GULP_SIZE, transferred_by = attacker, methods = INGEST) - playsound(victim.loc, 'sound/items/drink.ogg', 30, 1) - being_drunk = FALSE - return TRUE - - while(do_after(victim, 1 SECONDS, timed_action_flags = IGNORE_USER_LOC_CHANGE, extra_checks = CALLBACK(src, PROC_REF(can_drink), attacker, victim))) - victim.visible_message( - span_notice("[victim] puts the [src] up to their mouth."), - span_notice("You take a sip from the [src]."), - ) - reagents.trans_to(victim, BLOODBAG_GULP_SIZE, transferred_by = attacker, methods = INGEST) - playsound(victim.loc, 'sound/items/drink.ogg', 30, 1) - being_drunk = FALSE - return TRUE - -#undef BLOODBAG_GULP_SIZE - -/obj/item/reagent_containers/blood/proc/can_drink(mob/living/victim, mob/living/attacker) - if(!canconsume(victim, attacker)) - return FALSE - if(!reagents || !reagents.total_volume) - to_chat(victim, span_warning("[src] is empty!")) - return FALSE - return TRUE - -///Bloodbag of Bloodsucker blood (used by Ghouls only) -/obj/item/reagent_containers/blood/o_minus/bloodsucker - name = "blood pack" - blood_type = null - list_reagents = list(/datum/reagent/blood/bloodsucker = 200) - -/obj/item/reagent_containers/blood/o_minus/bloodsucker/examine(mob/user) - . = ..() - if(user.mind.has_antag_datum(/datum/antagonist/ex_ghoul) || user.mind.has_antag_datum(/datum/antagonist/ghoul/revenge)) - . += span_notice("Seems to be just about the same color as your Master's...") - -////////////////////// -// STAKES // -////////////////////// -/obj/item/stack/sheet/mineral/wood/attackby(obj/item/item, mob/user, params) - if(!item.get_sharpness()) - return ..() - user.visible_message( - span_notice("[user] begins whittling [src] into a pointy object."), - span_notice("You begin whittling [src] into a sharp point at one end."), - span_hear("You hear wood carving."), - ) - // 5 Second Timer - if(!do_after(user, 5 SECONDS, src, NONE, TRUE)) - return - // Make Stake - var/obj/item/stake/new_item = new(user.loc) - user.visible_message( - span_notice("[user] finishes carving a stake out of [src]."), - span_notice("You finish carving a stake out of [src]."), - ) - // Prepare to Put in Hands (if holding wood) - var/obj/item/stack/sheet/mineral/wood/wood_stack = src - var/replace = (user.get_inactive_held_item() == wood_stack) - // Use Wood - wood_stack.use(1) - // If stack depleted, put item in that hand (if it had one) - if(!wood_stack && replace) - user.put_in_hands(new_item) - -// TODO move this into bloodsuckerdatum -/// Do I have a stake in my heart? -/mob/living/proc/am_staked() - var/obj/item/bodypart/chosen_bodypart = get_bodypart(BODY_ZONE_CHEST) - var/obj/item/stake/stake = locate() in chosen_bodypart.embedded_objects - return stake - -/mob/living/proc/get_stakes() - var/obj/item/bodypart/chosen_bodypart = get_bodypart(BODY_ZONE_CHEST) - if(!chosen_bodypart) - return FALSE - var/list/stakes = list() - for(var/obj/item/embedded_stake in chosen_bodypart.embedded_objects) - if(istype(embedded_stake, /obj/item/stake)) - stakes += list(embedded_stake) - return stakes - -/datum/embedding/stake - embed_chance = 20 - -/obj/item/stake - name = "wooden stake" - desc = "A simple wooden stake carved to a sharp point." - icon = 'tff_modular/modules/bloodsucker/icons/stakes.dmi' - icon_state = "wood" - inhand_icon_state = "wood" - lefthand_file = 'tff_modular/modules/bloodsucker/icons/bloodsucker_lefthand.dmi' - righthand_file = 'tff_modular/modules/bloodsucker/icons/bloodsucker_righthand.dmi' - slot_flags = ITEM_SLOT_POCKETS - w_class = WEIGHT_CLASS_SMALL - hitsound = 'sound/items/weapons/bladeslice.ogg' - attack_verb_continuous = list("staked", "stabbed", "tore into") - attack_verb_simple = list("staked", "stabbed", "tore into") - sharpness = SHARP_EDGED - embed_data = /datum/embedding/stake - force = 6 - throwforce = 10 - max_integrity = 30 - custom_materials = list(/datum/material/wood = SHEET_MATERIAL_AMOUNT * 3) - - ///Time it takes to embed the stake into someone's chest. - var/staketime = 5 SECONDS - var/kills_blodsuckers = FALSE - -/obj/item/stake/examine_more(mob/user) - . = ..() - . += span_notice("You can use [src] to stake someone in the chest, if they are laying down or grabbed by the neck.") - if(IS_BLOODSUCKER(user)) - . += span_warning("You feel a sense of dread as you look at the [src]...") - -/obj/item/stake/attack(mob/living/target, mob/living/user, params) - . = ..() - if(.) - return - // Invalid Target, or not targetting the chest? - if(check_zone(user.zone_selected) != BODY_ZONE_CHEST) - return - if(target == user) - return - if(!target.can_be_staked()) // Oops! Can't. - to_chat(user, span_danger("You can't stake [target] when they are moving about! They have to be laying down or grabbed by the neck!")) - return - if(HAS_TRAIT(target, TRAIT_PIERCEIMMUNE)) - to_chat(user, span_danger("[target]'s chest resists the stake. It won't go in.")) - return - - to_chat(user, span_notice("You put all your weight into embedding the stake into [target]'s chest...")) - playsound(user, 'sound/effects/magic/Demon_consume.ogg', 50, 1) - if(!do_after(user, staketime, target, extra_checks = CALLBACK(target, TYPE_PROC_REF(/mob/living/carbon, can_be_staked)))) // user / target / time / uninterruptable / show progress bar / extra checks - return - // Drop & Embed Stake - user.visible_message( - span_danger("[user.name] drives the [src] into [target]'s chest!"), - span_danger("You drive the [src] into [target]'s chest!"), - ) - playsound(get_turf(target), 'sound/effects/splat.ogg', 40, 1) - if(force_embed(target, target.get_bodypart(BODY_ZONE_CHEST))) //and if it embeds successfully in their chest, cause a lot of pain - target.apply_damage(max(10, force * 1.2), BRUTE, BODY_ZONE_CHEST, wound_bonus = 0, sharpness = TRUE) - on_stake_embed(target, user) - -/obj/item/stake/proc/on_stake_embed(mob/living/target, mob/living/user) - return - -/obj/item/stake/hardened/silver/on_stake_embed(mob/living/target, mob/living/user) - var/obj/item/organ/heart/heart = target.get_organ_slot(ORGAN_SLOT_HEART) - if(!heart) - return - target.visible_message( - span_danger("The [src.name] pierces [target]'s chest, destroying their [heart.name]!"), - span_userdanger("You feel a HORRIBLE pain as the [src.name] pierces your chest, destroying your [heart.name]!"), - ) - qdel(heart) - -/obj/item/stake/force_embed(mob/living/carbon/victim, obj/item/bodypart/target_limb) - . = ..() - if(!.) - return . - SEND_SIGNAL(target_limb, COMSIG_BODYPART_STAKED, TRUE) - SEND_SIGNAL(victim, COMSIG_MOB_STAKED, TRUE) - return . - -///Can this target be staked? If someone stands up before this is complete, it fails. Best used on someone stationary. -/mob/living/proc/can_be_staked() - return FALSE - -/mob/living/carbon/can_be_staked() - if(body_position == LYING_DOWN) - return TRUE - return FALSE - -/datum/embedding/stake/hardened - embed_chance = 35 - fall_chance = 0 - -/// Created by welding and acid-treating a simple stake. -/obj/item/stake/hardened - name = "hardened stake" - desc = "A wooden stake carved to a sharp point and hardened by fire." - icon_state = "hardened" - force = 8 - throwforce = 12 - armour_penetration = 10 - embed_data = /datum/embedding/stake/hardened - staketime = 12 SECONDS - custom_materials = list(/datum/material/iron = HALF_SHEET_MATERIAL_AMOUNT) - -/obj/item/stake/hardened/examine_more(mob/user) - . = ..() - . += span_notice("The [src] won't fall out by itself, if embedded in someone.") - -/datum/embedding/stake/silver - embed_chance = 0 // we want it to only be embeddable manually - fall_chance = 0 - -/obj/item/stake/hardened/silver - name = "silver stake" - desc = "Polished and sharp at the end. For when some mofo is always trying to iceskate uphill." - icon_state = "silver" - inhand_icon_state = "silver" - siemens_coefficient = 1 - force = 9 - armour_penetration = 25 - custom_materials = list(/datum/material/iron = HALF_SHEET_MATERIAL_AMOUNT, /datum/material/silver = SHEET_MATERIAL_AMOUNT) - embed_data = /datum/embedding/stake/silver - staketime = 15 SECONDS - -/obj/item/stake/hardened/silver/examine_more(mob/user) - . = ..() - . += span_notice("You think that the [src] could destroy someone's heart if you really slam it in someone's ribs properly.") - -////////////////////// -// ARCHIVES // -////////////////////// - -/** - * # Archives of the Kindred: - *+ - * A book that can only be used by Curators. - * When used on a player, after a short timer, will reveal if the player is a Bloodsucker, including their real name and Clan. - * This book should not work on Bloodsuckers using the Masquerade ability. - * If it reveals a Bloodsucker, the Curator will then be able to tell they are a Bloodsucker on examine (Like a Ghoul). - * Reading it normally will allow Curators to read what each Clan does, with some extra flavor text ones. - * - * Regular Bloodsuckers won't have any negative effects from the book, while everyone else will get burns/eye damage. - */ -/obj/item/book/kindred - name = "\improper Book of Nod" - starting_title = "the Book of Nod" - desc = "Cryptic documents explaining hidden truths behind Undead beings. It is said only Curators can decipher what they really mean." - icon = 'tff_modular/modules/bloodsucker/icons/vamp_obj.dmi' - lefthand_file = 'tff_modular/modules/bloodsucker/icons/bloodsucker_lefthand.dmi' - righthand_file = 'tff_modular/modules/bloodsucker/icons/bloodsucker_righthand.dmi' - icon_state = "kindred_book" - starting_author = "dozens of generations of Curators" - unique = TRUE - throw_speed = 1 - throw_range = 10 - resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF - ///Boolean on whether the book is currently being used, so you can only use it on one person at a time. - COOLDOWN_DECLARE(bloodsucker_check_cooldown) - var/cooldown_time = 1 MINUTES - -/obj/item/book/kindred/Initialize(mapload) - . = ..() - SSpoints_of_interest.make_point_of_interest(src) - -/obj/item/book/kindred/carving_act(mob/living/user, obj/item/tool) - to_chat(user, span_notice("You feel the gentle whispers of a Librarian telling you not to cut [starting_title].")) - return ITEM_INTERACT_BLOCKING - -///Attacking someone with the book. -/obj/item/book/kindred/afterattack(mob/living/target, mob/living/user, flag, params) - . = ..() - if(!user.can_read(src) || (target == user) || !ismob(target)) - return - if(!HAS_TRAIT(user.mind, TRAIT_BLOODSUCKER_HUNTER)) - if(IS_BLOODSUCKER(user)) - to_chat(user, span_notice("[src] seems to be too complicated for you. It would be best to leave this for someone else to take.")) - return - to_chat(user, span_warning("[src] burns your hands as you try to use it!")) - user.apply_damage(3, BURN, pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM)) - return - - if(!COOLDOWN_FINISHED(src, bloodsucker_check_cooldown)) - user.balloon_alert(user, "your head hurts, wait a minute ") - addtimer(CALLBACK(user, TYPE_PROC_REF(/atom, balloon_alert), user, "You feel your head clear up."), cooldown_time) - return - user.balloon_alert_to_viewers(user, "reading book...") - user.balloon_alert(target, "looks at you and checks their [src]...") - if(!do_after(user, 3 SECONDS, target, timed_action_flags = NONE, progress = TRUE)) - to_chat(user, span_notice("You quickly close [src].")) - return - COOLDOWN_START(src, bloodsucker_check_cooldown, cooldown_time) - var/datum/antagonist/bloodsucker/bloodsuckerdatum = IS_BLOODSUCKER(target) - // Are we a Bloodsucker | Are we on Masquerade. If one is true, they will fail. - if(IS_BLOODSUCKER(target) && !HAS_TRAIT(target, TRAIT_MASQUERADE)) - if(bloodsuckerdatum.broke_masquerade) - to_chat(user, span_warning("[target], also known as '[bloodsuckerdatum.return_full_name()]', is indeed a Bloodsucker, but you already knew this.")) - return - to_chat(user, span_warning("[target], also known as '[bloodsuckerdatum.return_full_name()]', [bloodsuckerdatum.my_clan ? "is part of the [bloodsuckerdatum.my_clan]!" : "is not part of a clan."] You quickly note this information down, memorizing it.")) - bloodsuckerdatum.break_masquerade() - else - to_chat(user, span_notice("You fail to draw any conclusions to [target] being a Bloodsucker.")) - -/obj/item/book/kindred/attack_self(mob/living/user) - if(user.mind && !(HAS_TRAIT(user.mind, TRAIT_BLOODSUCKER_HUNTER) || IS_BLOODSUCKER(user))) - to_chat(user, span_warning("You feel your eyes unable to read the boring texts...")) - user.set_eye_blur_if_lower(10 SECONDS) - return - ui_interact(user) - -/obj/item/book/kindred/ui_interact(mob/living/user, datum/tgui/ui) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "KindredBook", name) - ui.open() - -/obj/item/book/kindred/ui_static_data(mob/user) - var/data = list() - - for(var/datum/bloodsucker_clan/clans as anything in subtypesof(/datum/bloodsucker_clan)) - var/clan_data = list() - clan_data["clan_name"] = initial(clans.name) - clan_data["clan_desc"] = initial(clans.description) - data["clans"] += list(clan_data) - - return data - -/obj/structure/displaycase/curator - desc = "This book was found inside a coffin of a long dead Curator. It is said to be able to reveal the true nature of those who feed upon mankind." - start_showpiece_type = /obj/item/book/kindred - req_access = list(ACCESS_LIBRARY) - - -/// just a typepath to specify that it's monkey-owned, used for the heart thief objective -/obj/item/organ/heart/monkey - -/obj/item/organ/heart/examine_more(mob/user) - . = ..() - var/datum/antagonist/bloodsucker/vampire = IS_BLOODSUCKER(user) - if(!vampire) - return - var/datum/objective/steal_n_of_type/heart_thief = locate() in vampire?.objectives - if(!heart_thief) - return - if(heart_thief.check_if_valid_item(src)) - . += span_notice("This [src.name] will do for your purposes...") - else - . += span_notice("This [src.name] is of lesser quality, it won't do...") diff --git a/tff_modular/modules/bloodsucker/vassal/batform.dm b/tff_modular/modules/bloodsucker/vassal/batform.dm deleted file mode 100644 index 7faeed84388..00000000000 --- a/tff_modular/modules/bloodsucker/vassal/batform.dm +++ /dev/null @@ -1,61 +0,0 @@ -/** - * # BATFORM - * - * TG removed this, so we're re-adding it - */ -/datum/action/cooldown/spell/shapeshift/bat - name = "Bat Form" - desc = "Take on the shape of a space bat. You can fly and see in the dark, and you heal from doing melee attacks." - background_icon_state = "tremere_power_off" - active_background_icon_state = "tremere_power_on" - base_background_icon_state = "tremere_power_off" - background_icon = 'tff_modular/modules/bloodsucker/icons/tremere_bloodsucker.dmi' - power_explanation = "You can fly and see in the dark, and you heal from doing melee attacks." - invocation = "Master, grant me your might, BAT FORM!!" - invocation_type = INVOCATION_SHOUT - spell_requirements = NONE - convert_damage = TRUE - cooldown_time = 1 MINUTES - possible_shapes = list(/mob/living/basic/bat/bloodsucker) - power_explanation = "This ability turns you into a small bat, which can fly and heals from doing meele damage. \n\ - However, you don't do much meele damage, and are slightly weak to fire damage.\n\ - Using the ability also spawns some normal bats around where you cast it, causing confusion.\n\ - Keep in mind if you die in this form, your real body will also die, and any damage received is transfered as well." - var/bats_to_spawn = 3 - -/datum/action/cooldown/spell/shapeshift/bat/cast(mob/living/cast_on) - . = ..() - // spawn bats around - if(!get_turf(cast_on)) - return - for(var/i in 1 to bats_to_spawn) - var/mob/living/basic/bat/bat = new(get_turf(cast_on)) - QDEL_IN(bat, cooldown_time) - random_step(bat, 2, 50) - -/mob/living/basic/bat/bloodsucker - name ="vampiric bat" - desc = "A bat with a thirst for blood." - maxHealth = 100 - health = 100 - speed = 0 - melee_damage_lower = 10 - melee_damage_upper = 15 - wound_bonus = 10 - obj_damage = 10 - lighting_cutoff_red = 25 - lighting_cutoff_green = 8 - lighting_cutoff_blue = 5 - melee_attack_cooldown = CLICK_CD_MELEE - basic_mob_flags = FLAMMABLE_MOB - lighting_color_cutoffs = BLOODSUCKER_SIGHT_COLOR_CUTOFF - damage_coeff = list(BRUTE = 0.9, BURN = 1.25, TOX = 1, STAMINA = 1, OXY = 1) - attack_verb_simple = "drain blood from" - attack_verb_continuous = "drains blood from" - -/mob/living/basic/bat/bloodsucker/Initialize(mapload) - . = ..() - // Go as fast as people can run - AddElement(/datum/element/lifesteal, melee_damage_lower) - // Too fat to fit through vents - REMOVE_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT) diff --git a/tff_modular/modules/bloodsucker/vassal/vassal_datum.dm b/tff_modular/modules/bloodsucker/vassal/vassal_datum.dm deleted file mode 100644 index f8f77e53125..00000000000 --- a/tff_modular/modules/bloodsucker/vassal/vassal_datum.dm +++ /dev/null @@ -1,185 +0,0 @@ -/datum/antagonist/ghoul - name = "\improper Ghoul" - roundend_category = "ghouls" - antagpanel_category = "Bloodsucker" - pref_flag = ROLE_VASSAL - antag_hud_name = "ghoul" - show_in_roundend = FALSE - hud_icon = 'tff_modular/modules/bloodsucker/icons/antag_hud.dmi' - ui_name = "AntagInfoGhoul" - antag_panel_description = "You are a Ghoul, a mortal servant of a Bloodsucker." - - /// The Master Bloodsucker's antag datum. - var/datum/antagonist/bloodsucker/master - /// List of all Purchased Powers, to be cleaned up on antag removal. - var/list/datum/action/powers = list() - ///Whether this ghoul is already a special type of Ghoul. - var/special_type = FALSE - ///Description of what this Ghoul does. - /// It's shown to the bloodsucker in the radial for setting ghoul type - var/ghoul_description - /// inherent traits that are removed and addded on antag datum loss and gain - var/list/traits = list() - -/datum/antagonist/ghoul/antag_panel_data() - return "Master : [master?.owner.name ? master.owner.name : "Gone"]" - -// todo make this into a shared proc that bloodsuckers and ghouls share -/datum/antagonist/ghoul/ui_static_data(mob/user) - return ability_ui_data(powers) + ..() - -/datum/antagonist/ghoul/apply_innate_effects(mob/living/mob_override) - . = ..() - var/mob/living/current_mob = mob_override || owner.current - current_mob.apply_status_effect(/datum/status_effect/agent_pinpointer/ghoul_edition) - add_team_hud(current_mob) - if(length(traits)) - current_mob.add_traits(traits, GHOUL_TRAIT) - -/datum/antagonist/ghoul/add_team_hud(mob/target) - QDEL_NULL(team_hud_ref) - - team_hud_ref = WEAKREF(target.add_alt_appearance( - /datum/atom_hud/alternate_appearance/basic/has_antagonist, - "antag_team_hud_[REF(src)]", - hud_image_on(target), - )) - - var/datum/atom_hud/alternate_appearance/basic/has_antagonist/hud = team_hud_ref.resolve() - - var/list/mob/living/mob_list = list() - mob_list += master.owner.current - for(var/datum/antagonist/ghoul/ghoul as anything in master.ghouls) - mob_list += ghoul.owner.current - - for (var/datum/atom_hud/alternate_appearance/basic/has_antagonist/antag_hud as anything in GLOB.has_antagonist_huds) - if(!(antag_hud.target in mob_list)) - continue - antag_hud.show_to(target) - hud.show_to(antag_hud.target) - -/datum/antagonist/ghoul/remove_innate_effects(mob/living/mob_override) - . = ..() - var/mob/living/current_mob = mob_override || owner.current - current_mob.remove_status_effect(/datum/status_effect/agent_pinpointer/ghoul_edition) - if(length(traits)) - current_mob.remove_traits(traits, GHOUL_TRAIT) - -/datum/antagonist/ghoul/pre_mindshield(mob/implanter, mob/living/mob_override) - return COMPONENT_MINDSHIELD_PASSED - -/// This is called when the antagonist is successfully mindshielded. -/datum/antagonist/ghoul/on_mindshield(mob/implanter, mob/living/mob_override) - owner.remove_antag_datum(/datum/antagonist/ghoul) - owner.current.log_message("has been deconverted from Ghouling by [implanter]!", LOG_ATTACK, color="#960000") - return COMPONENT_MINDSHIELD_DECONVERTED - -/datum/antagonist/ghoul/proc/on_examined(datum/source, mob/examiner, examine_text) - SIGNAL_HANDLER - var/ghoul_examine = return_ghoul_examine(examiner) - if(ghoul_examine) - examine_text += ghoul_examine - - -/datum/antagonist/ghoul/on_gain() - RegisterSignal(owner.current, COMSIG_ATOM_EXAMINE, PROC_REF(on_examined)) - /// Enslave them to their Master - if(!master || !istype(master, master)) - return - if(special_type) - if(!master.special_ghouls[special_type]) - master.special_ghouls[special_type] = list() - master.special_ghouls[special_type] |= src - master.ghouls += src - owner.enslave_mind_to_creator(master.owner.current) - owner.current.log_message("has been ghouled by [master.owner.current]!", LOG_ATTACK, color="#960000") - /// Give Recuperate Power - BuyPower(/datum/action/cooldown/bloodsucker/recuperate) - /// Give Objectives - var/datum/objective/bloodsucker/ghoul/ghoul_objective = new - ghoul_objective.owner = owner - objectives += ghoul_objective - /// Give Vampire Language & Hud - owner.current.grant_all_languages(FALSE, FALSE, TRUE) - owner.current.grant_language(/datum/language/vampiric, ALL, LANGUAGE_MIND) - return ..() - -/datum/antagonist/ghoul/on_removal() - UnregisterSignal(owner.current, COMSIG_ATOM_EXAMINE) - //Free them from their Master - if(master && master.owner) - if(special_type && master.special_ghouls[special_type]) - master.special_ghouls.Remove(special_type) - master.ghouls -= src - owner.enslaved_to = null - //Remove ALL Traits, as long as its from BLOODSUCKER_TRAIT's source. - for(var/all_status_traits in owner.current._status_traits) - REMOVE_TRAIT(owner.current, all_status_traits, GHOUL_TRAIT) - //Remove Recuperate Power - remove_powers(powers) - //Remove Language & Hud - owner.current.remove_language(/datum/language/vampiric, ALL, LANGUAGE_MIND) - return ..() - -/datum/antagonist/ghoul/proc/remove_powers(list/removing_powers) - for(var/datum/action/cooldown/bloodsucker/power as anything in removing_powers) - removing_powers -= power - if(!(power in owner.current.actions)) - continue - power.Remove(owner.current) - -/datum/antagonist/ghoul/on_body_transfer(mob/living/old_body, mob/living/new_body) - . = ..() - for(var/datum/action/cooldown/bloodsucker/all_powers as anything in powers) - all_powers.Remove(old_body) - all_powers.Grant(new_body) - -/datum/antagonist/ghoul/greet() - . = ..() - if(silent) - return - - to_chat(owner, span_userdanger("You are now the mortal servant of [master.owner.current], a Bloodsucker!")) - to_chat(owner, span_boldannounce("The power of [master.owner.current.p_their()] immortal blood compels you to obey [master.owner.current.p_them()] in all things, even offering your own life to prolong theirs.\n\ - You are not required to obey any other Bloodsucker, for only [master.owner.current] is your master. The laws of Nanotrasen do not apply to you now; only your vampiric master's word must be obeyed.")) - owner.current.playsound_local(null, 'sound/effects/magic/mutate.ogg', 100, FALSE, pressure_affected = FALSE) - antag_memory += "You, becoming the mortal servant of [master.owner.current], a bloodsucking vampire!
    " - /// Message told to your Master. - to_chat(master.owner, span_userdanger("[owner.current] has become addicted to your immortal blood. [capitalize(owner.current.p_they(TRUE))] [owner.current.p_are()] now your mortal servant!")) - master.owner.current.playsound_local(null, 'sound/effects/magic/mutate.ogg', 100, FALSE, pressure_affected = FALSE) - -/datum/antagonist/ghoul/farewell() - if(silent) - return - - owner.current.visible_message( - span_deconversion_message("[owner.current]'s eyes dart feverishly from side to side, and then stop. [owner.current.p_They(TRUE)] seem[owner.current.p_s()] to calm, \ - like [owner.current.p_they()] [owner.current.p_have()] regained some lost part of [owner.current.p_them()]self."), \ - span_deconversion_message("With a snap, you are no longer enslaved to [master.owner]! You breathe in heavily, having regained your free will.")) - owner.current.playsound_local(null, 'sound/effects/magic/mutate.ogg', 100, FALSE, pressure_affected = FALSE) - /// Message told to your (former) Master. - if(master && master.owner) - to_chat(master.owner, span_cult_bold("You feel the bond with your ghoul [owner.current] has somehow been broken!")) - -/datum/antagonist/ghoul/admin_add(datum/mind/new_owner, mob/admin) - var/list/datum/mind/possible_vampires = list() - for(var/datum/antagonist/bloodsucker/bloodsuckerdatums in GLOB.antagonists) - var/datum/mind/vamp = bloodsuckerdatums.owner - if(!vamp) - continue - if(!vamp.current) - continue - if(vamp.current.stat == DEAD) - continue - possible_vampires += vamp - if(!length(possible_vampires)) - message_admins("[key_name_admin(admin)] tried ghoulizing [key_name_admin(new_owner)], but there were no bloodsuckers!") - return - var/datum/mind/choice = tgui_input_list(admin, "Which bloodsucker should this ghoul belong to?", "Bloodsucker", possible_vampires) - if(!choice) - return - log_admin("[key_name_admin(admin)] turned [key_name_admin(new_owner)] into a ghoul of [key_name_admin(choice)]!") - var/datum/antagonist/bloodsucker/vampire = IS_BLOODSUCKER(choice.current) - master = vampire - new_owner.add_antag_datum(src) - to_chat(choice, span_notice("Through divine intervention, you've gained a new ghoul!")) diff --git a/tff_modular/modules/bloodsucker/vassal/vassal_pinpointer.dm b/tff_modular/modules/bloodsucker/vassal/vassal_pinpointer.dm deleted file mode 100644 index 82412a34eca..00000000000 --- a/tff_modular/modules/bloodsucker/vassal/vassal_pinpointer.dm +++ /dev/null @@ -1,31 +0,0 @@ -/** - * # Ghoul Pinpointer - * - * Pinpointer that points to their Master's location at all times. - * Unlike the Monster hunter one, this one is permanently active, and has no power needed to activate it. - */ - -/atom/movable/screen/alert/status_effect/agent_pinpointer/ghoul_edition - name = "Blood Bond" - desc = "You always know where your master is." - -/datum/status_effect/agent_pinpointer/ghoul_edition - id = "agent_pinpointer" - alert_type = /atom/movable/screen/alert/status_effect/agent_pinpointer/ghoul_edition - minimum_range = GHOUL_SCAN_MIN_DISTANCE - tick_interval = GHOUL_SCAN_PING_TIME - duration = STATUS_EFFECT_PERMANENT - range_fuzz_factor = 0 - -/datum/status_effect/agent_pinpointer/ghoul_edition/on_creation(mob/living/new_owner, ...) - ..() - var/datum/antagonist/ghoul/antag_datum = new_owner.mind.has_antag_datum(/datum/antagonist/ghoul) - scan_target = antag_datum?.master?.owner?.current - -/datum/status_effect/agent_pinpointer/ghoul_edition/scan_for_target() - return - -/datum/status_effect/agent_pinpointer/ghoul_edition/Destroy() - if(scan_target) - to_chat(owner, span_notice("You've lost your master's trail.")) - return ..() diff --git a/tff_modular/modules/bloodsucker/vassal/vassal_procs.dm b/tff_modular/modules/bloodsucker/vassal/vassal_procs.dm deleted file mode 100644 index e0d8945f59e..00000000000 --- a/tff_modular/modules/bloodsucker/vassal/vassal_procs.dm +++ /dev/null @@ -1,77 +0,0 @@ -/datum/antagonist/ghoul/proc/give_warning(atom/source, danger_level, vampire_warning_message, ghoul_warning_message) - SIGNAL_HANDLER - if(ghoul_warning_message) - to_chat(owner, ghoul_warning_message) - -/** - * Returns a Ghouls's examine strings. - * Args: - * viewer - The person examining. - */ -/datum/antagonist/ghoul/proc/return_ghoul_examine(mob/living/viewer) - if((!viewer.mind && !isobserver(viewer)) || !iscarbon(owner.current)) - return FALSE - var/mob/living/carbon/carbon_current = owner.current - // Target must be a Ghoul - // Default String - var/returnString = "\[" - var/returnIcon = "" - // Ghouls and Bloodsuckers recognize eachother, while Monster Hunters can see Ghouls. - if(!IS_BLOODSUCKER(viewer) && !IS_GHOUL(viewer) && !IS_MONSTERHUNTER(viewer) && !isobserver(viewer)) - return FALSE - // Am I Viewer's Ghoul? - if(master.owner == viewer.mind) - returnString += "This [carbon_current.dna.species.name] bears YOUR mark!" - returnIcon = "[icon2html('tff_modular/modules/bloodsucker/icons/language.dmi', world, "ghoul")]" - // Am I someone ELSE'S Ghoul? - else if(IS_BLOODSUCKER(viewer) || IS_MONSTERHUNTER(viewer) || isobserver(viewer)) - returnString += "This [carbon_current.dna.species.name] bears the mark of [master.return_full_name()][master.broke_masquerade ? " who has broken the Masquerade" : ""]" - returnIcon = "[icon2html('tff_modular/modules/bloodsucker/icons/language.dmi', world, "ghoul_grey")]" - // Are you serving the same master as I am? - else if(viewer.mind.has_antag_datum(/datum/antagonist/ghoul) in master.ghouls) - returnString += "[p_they(TRUE)] bears the mark of your Master" - returnIcon = "[icon2html('tff_modular/modules/bloodsucker/icons/language.dmi', world, "ghoul")]" - // You serve a different Master than I do. - else - returnString += "[p_they(TRUE)] bears the mark of another Bloodsucker" - returnIcon = "[icon2html('tff_modular/modules/bloodsucker/icons/language.dmi', world, "ghoul_grey")]" - - returnString += "\]" // \n" Don't need spacers. Using . += "" in examine.dm does this on its own. - return returnIcon + returnString - -/// Used when your Master teaches you a new Power. -/datum/antagonist/ghoul/proc/BuyPower(datum/action/cooldown/power, list_to_add_to = powers) - for(var/datum/action/current_powers as anything in list_to_add_to) - if(current_powers.type == power.type) - return FALSE - power = new power() - list_to_add_to += power - power.Grant(owner.current) - log_uplink("[key_name(owner.current)] purchased [power].") - return TRUE - -/datum/antagonist/ghoul/proc/LevelUpPowers() - for(var/datum/action/cooldown/bloodsucker/power in powers) - power.level_current++ - -/// Called when we are made into the Favorite Ghoul -/datum/antagonist/ghoul/proc/make_special(datum/antagonist/ghoul/ghoul_type) - //store what we need - var/datum/mind/ghoul_owner = owner - var/datum/antagonist/bloodsucker/bloodsuckerdatum = master - - //remove our antag datum - silent = TRUE - ghoul_owner.remove_antag_datum(/datum/antagonist/ghoul) - - //give our new one - var/datum/antagonist/ghoul/ghouldatum = new ghoul_type(ghoul_owner) - ghouldatum.master = bloodsuckerdatum - ghouldatum.silent = TRUE - ghoul_owner.add_antag_datum(ghouldatum) - ghouldatum.silent = FALSE - - //send alerts of completion - to_chat(master, span_danger("You have turned [ghoul_owner.current] into your [ghouldatum.name]! They will no longer be deconverted upon Mindshielding!")) - to_chat(ghoul_owner, span_notice("As Blood drips over your body, you feel closer to your Master... You are now the [ghouldatum.name]!")) - ghoul_owner.current.playsound_local(null, 'sound/effects/magic/mutate.ogg', 75, FALSE, pressure_affected = FALSE) diff --git a/tff_modular/modules/bloodsucker/vassal/vassal_types/ex_vassal.dm b/tff_modular/modules/bloodsucker/vassal/vassal_types/ex_vassal.dm deleted file mode 100644 index 57988daebde..00000000000 --- a/tff_modular/modules/bloodsucker/vassal/vassal_types/ex_vassal.dm +++ /dev/null @@ -1,103 +0,0 @@ -#define BLOOD_TIMER_REQUIREMENT (10 MINUTES) -#define BLOOD_TIMER_HALWAY (BLOOD_TIMER_REQUIREMENT / 2) - -/datum/antagonist/ex_ghoul - name = "\improper Ex-Ghoul" - roundend_category = "ghouls" - antagpanel_category = "Bloodsucker" - pref_flag = ROLE_VASSAL - antag_hud_name = "ghoul_grey" - show_in_roundend = FALSE - show_in_antagpanel = FALSE - silent = TRUE - ui_name = FALSE - hud_icon = 'tff_modular/modules/bloodsucker/icons/antag_hud.dmi' - - ///The revenge ghoul that brought us into the fold. - var/datum/antagonist/ghoul/revenge/revenge_ghoul - ///Timer we have to live - COOLDOWN_DECLARE(blood_timer) - -/datum/antagonist/ex_ghoul/on_gain() - . = ..() - RegisterSignal(owner.current, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) - -/datum/antagonist/ex_ghoul/on_removal() - if(revenge_ghoul) - revenge_ghoul.ex_ghouls -= src - revenge_ghoul = null - blood_timer = null - return ..() - -/datum/antagonist/ex_ghoul/proc/on_examine(datum/source, mob/examiner, examine_text) - SIGNAL_HANDLER - - var/datum/antagonist/ghoul/revenge/ghouldatum = IS_REVENGE_GHOUL(examiner) - if(ghouldatum && !revenge_ghoul) - examine_text += span_notice("[owner.current] is an ex-ghoul!") - -/datum/antagonist/ex_ghoul/add_team_hud(mob/target) - QDEL_NULL(team_hud_ref) - - team_hud_ref = WEAKREF(target.add_alt_appearance( - /datum/atom_hud/alternate_appearance/basic/has_antagonist, - "antag_team_hud_[REF(src)]", - hud_image_on(target), - )) - - var/datum/atom_hud/alternate_appearance/basic/has_antagonist/hud = team_hud_ref.resolve() - - var/list/mob/living/mob_list = list() - mob_list += revenge_ghoul.owner.current - for(var/datum/antagonist/ex_ghoul/former_ghouls as anything in revenge_ghoul.ex_ghouls) - mob_list += former_ghouls.owner.current - - for (var/datum/atom_hud/alternate_appearance/basic/has_antagonist/antag_hud as anything in GLOB.has_antagonist_huds) - if(!(antag_hud.target in mob_list)) - continue - antag_hud.show_to(target) - hud.show_to(antag_hud.target) - -/** - * Fold return - * - * Called when a Revenge bloodsucker gets a ghoul back into the fold. - */ -/datum/antagonist/ex_ghoul/proc/return_to_fold(datum/antagonist/ghoul/revenge/mike_ehrmantraut) - revenge_ghoul = mike_ehrmantraut - mike_ehrmantraut.ex_ghouls += src - COOLDOWN_START(src, blood_timer, BLOOD_TIMER_REQUIREMENT) - add_team_hud(owner.current) - - RegisterSignal(src, COMSIG_LIVING_LIFE, PROC_REF(on_life)) - -/datum/antagonist/ex_ghoul/proc/on_life(datum/source, seconds_per_tick, times_fired) - SIGNAL_HANDLER - - if(COOLDOWN_TIMELEFT(src, blood_timer) <= BLOOD_TIMER_HALWAY + 2 && COOLDOWN_TIMELEFT(src, blood_timer) >= BLOOD_TIMER_HALWAY - 2) //just about halfway - to_chat(owner.current, span_cult_bold("You need new blood from your Master!")) - if(!COOLDOWN_FINISHED(src, blood_timer)) - return - to_chat(owner.current, span_cult_bold("You are out of blood!")) - to_chat(revenge_ghoul.owner.current, span_cult_bold("[owner.current] has ran out of blood and is no longer in the fold!")) - owner.remove_antag_datum(/datum/antagonist/ex_ghoul) - - -/** - * Bloodsucker Blood - * - * Artificially made, this must be fed to ex-ghouls to keep them on their high. - */ -/datum/reagent/blood/bloodsucker - name = "Blood two" - -/datum/reagent/blood/bloodsucker/expose_mob(mob/living/exposed_mob, methods, reac_volume, show_message, touch_protection) - var/datum/antagonist/ex_ghoul/former_ghoul = exposed_mob.mind.has_antag_datum(/datum/antagonist/ex_ghoul) - if(former_ghoul) - to_chat(exposed_mob, span_cult("You feel the blood restore you... You feel safe.")) - COOLDOWN_RESET(former_ghoul, blood_timer) - COOLDOWN_START(former_ghoul, blood_timer, BLOOD_TIMER_REQUIREMENT) - return ..() - -#undef BLOOD_TIMER_REQUIREMENT -#undef BLOOD_TIMER_HALWAY diff --git a/tff_modular/modules/bloodsucker/vassal/vassal_types/favorite_vassal.dm b/tff_modular/modules/bloodsucker/vassal/vassal_types/favorite_vassal.dm deleted file mode 100644 index a8375f011d1..00000000000 --- a/tff_modular/modules/bloodsucker/vassal/vassal_types/favorite_vassal.dm +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Favorite Ghoul - * - * Gets some cool abilities depending on the Clan. - */ -/datum/antagonist/ghoul/favorite - name = "\improper Favorite Ghoul" - antag_hud_name = "ghoul6" - special_type = FAVORITE_GHOUL - ghoul_description = "The Favorite Ghoul gets unique abilities over other Ghouls depending on the Master's Clan \ - and becomes completely immune to Mindshields. If part of Ventrue, this is the Ghoul a Bloodsucker will rank up." - - ///Bloodsucker levels, but for Ghouls, used by Ventrue. Used for ventrue creating a new bloodsucker. - var/ghoul_level - /// Power's we're going to inherit once we turn into a Bloodsucker - var/list/bloodsucker_powers = list() - -/datum/antagonist/ghoul/favorite/on_gain() - . = ..() - SEND_SIGNAL(master, COMSIG_BLOODSUCKER_MAKE_FAVORITE, src) - -/datum/antagonist/ghoul/favorite/on_removal() - SEND_SIGNAL(master, COMSIG_BLOODSUCKER_LOOSE_FAVORITE, src) - remove_powers(bloodsucker_powers) - . = ..() - -/datum/antagonist/ghoul/favorite/pre_mindshield(mob/implanter, mob/living/mob_override) - return COMPONENT_MINDSHIELD_RESISTED diff --git a/tff_modular/modules/bloodsucker/vassal/vassal_types/revenge_vassal.dm b/tff_modular/modules/bloodsucker/vassal/vassal_types/revenge_vassal.dm deleted file mode 100644 index e1496c54bd7..00000000000 --- a/tff_modular/modules/bloodsucker/vassal/vassal_types/revenge_vassal.dm +++ /dev/null @@ -1,68 +0,0 @@ -/** - * Revenge Ghoul - * - * Has the goal to 'get revenge' when their Master dies. - */ -/datum/antagonist/ghoul/revenge - name = "\improper Revenge Ghoul" - roundend_category = "abandoned Ghouls" - show_in_roundend = FALSE - show_in_antagpanel = FALSE - antag_hud_name = "ghoul4" - special_type = REVENGE_GHOUL - ghoul_description = "The Revenge Ghoul will not deconvert on a Bloodsucker's Final Death, \ - instead they will gain all your Powers, and the objective to take revenge for your demise. \ - They additionally maintain Ghouls their Master's departure, rather than become aimless." - - ///all ex-ghouls brought back into the fold. - var/list/datum/antagonist/ex_ghoul/ex_ghouls = list() - -/datum/antagonist/ghoul/revenge/roundend_report() - var/list/report = list() - report += printplayer(owner) - if(objectives.len) - report += printobjectives(objectives) - - // Now list their ghouls - if(ex_ghouls.len) - report += "The Ghouls brought back into the fold were..." - for(var/datum/antagonist/ex_ghoul/all_ghouls as anything in ex_ghouls) - if(!all_ghouls.owner) - continue - report += "[all_ghouls.owner.name] the [all_ghouls.owner.assigned_role.title]" - - return report.Join("
    ") - -/datum/antagonist/ghoul/revenge/on_gain() - . = ..() - RegisterSignal(master, COMSIG_BLOODSUCKER_FINAL_DEATH, PROC_REF(on_master_death)) - -/datum/antagonist/ghoul/revenge/on_removal() - UnregisterSignal(master, COMSIG_BLOODSUCKER_FINAL_DEATH) - return ..() - -/datum/antagonist/ghoul/revenge/proc/on_master_death(datum/antagonist/bloodsucker/bloodsuckerdatum, mob/living/carbon/master) - SIGNAL_HANDLER - - show_in_roundend = TRUE - for(var/datum/objective/all_objectives as anything in objectives) - objectives -= all_objectives - BuyPower(/datum/action/cooldown/bloodsucker/ghoul_blood) - for(var/datum/action/cooldown/bloodsucker/master_powers as anything in bloodsuckerdatum.powers) - if(master_powers.purchase_flags & BLOODSUCKER_DEFAULT_POWER) - continue - master_powers.Grant(owner.current) - owner.current.remove_status_effect(/datum/status_effect/agent_pinpointer/ghoul_edition) - - var/datum/objective/survive/new_objective = new - new_objective.name = "Avenge your Master" - new_objective.explanation_text = "Avenge your Master's final death by felling the ones that killed them, recruiting their ex-ghouls and continuing their operations." - new_objective.owner = owner - objectives += new_objective - - antag_panel_title = "You are a Ghoul tasked with taking revenge for the death of your Master!" - antag_panel_description = "You have gained your Master's old Powers, and a brand new \ - power. You will have to survive and maintain your old \ - Master's integrity. Bring their old Ghouls back into the \ - fold using your new Ability." - update_static_data_for_all_viewers() diff --git a/tff_modular/modules/vampire/clans/_clan.dm b/tff_modular/modules/vampire/clans/_clan.dm new file mode 100644 index 00000000000..543fce95b52 --- /dev/null +++ b/tff_modular/modules/vampire/clans/_clan.dm @@ -0,0 +1,234 @@ +/** + * Vampire clans + * + * Handles everything related to clans. + * The entire idea of datumizing this came to me in a dream. + */ +/datum/vampire_clan + /// The name of the clan we're in. + var/name = "Caitiff" + /// Description of what the clan is, given when joining and through your antag UI. + var/description = "Vile thinblooded mongrel. Choose a clan or die like the freak you are." + /// Description shown when trying to join the clan. + var/join_description + + /// The vampire datum that owns this clan. Use this over 'source', because while it's the same thing, this is more consistent (and used for deletion). + var/datum/antagonist/vampire/vampiredatum + + /// The icon of this clan on the selection radial menu. + var/join_icon = 'tff_modular/modules/vampire/icons/clan_icons.dmi' + var/join_icon_state = "base" + + /// Whether the clan can be joined by players. FALSE for flavortext-only clans. + var/joinable_clan = FALSE + + /// How we will drink blood using Feed. + var/blood_drink_type = VAMPIRE_DRINK_NORMAL + + // Societee + var/is_sabbat = FALSE // In case we want a bad guy clan that doesn't care about the masquerade. + var/princely_score_bonus = -10 // Will be added to playtime in get_princely_score() + + /// Unique antag HUD icon of this clan, if any. + var/antag_hud_icon + +/** + * Starting Humanity score, some clans are closer to the beast, some closer to humanity. + * We start out at null and set it in new because we want a fall back to the global default if none is set. + * 10 Saintly Toreador + * 9 Compassionate Ventrue + * 8 Caring Malkavian, Brujah + * 7 Normal Tremere + * 6 Distant + * 5 Removed + * 4 Unfeeling + * 3 Cold + * 2 Bestial + * 1 Horrific + * 0 Wight + */ + var/default_humanity + +/datum/vampire_clan/New(datum/antagonist/vampire/owner_datum) + . = ..() + RegisterSignal(SSdcs, COMSIG_VAMPIRE_BROKE_MASQUERADE, PROC_REF(on_vampire_broke_masquerade)) + + vampiredatum = owner_datum + // Apply clan-specific default humanity; fall back to the global default only if none was set. + if(isnull(default_humanity)) + default_humanity = VAMPIRE_DEFAULT_HUMANITY + vampiredatum.adjust_humanity(default_humanity - VAMPIRE_DEFAULT_HUMANITY, TRUE) + + // Masquerade breakers + for(var/datum/antagonist/vampire/unmasked in GLOB.masquerade_breakers) + if(unmasked.owner.current) + on_vampire_broke_masquerade(vampiredatum.owner.current, unmasked) + + vampiredatum.owner.current.playsound_local(get_turf(vampiredatum.owner.current), 'tff_modular/modules/vampire/sound/VampireAlert.ogg', 80, FALSE, pressure_affected = FALSE, use_reverb = FALSE) + to_chat(vampiredatum.owner.current, span_narsiesmall("I remember now. I belong with the [name]...")) + + vampiredatum.update_static_data_for_all_viewers() + + log_vampire_power("[key_name(vampiredatum.owner.current)] has joined the [name].") + +/datum/vampire_clan/proc/on_apply() + for(var/datum/discipline/disciple as anything in vampiredatum.owned_disciplines) + disciple.apply_discipline_quirks(vampiredatum) + + for(var/datum/action/cooldown/vampire/clanselect/clanselect in vampiredatum.powers) + vampiredatum.remove_power(clanselect) + + if(!QDELETED(vampiredatum.owner?.current)) + apply_effects(vampiredatum.owner.current) + +/datum/vampire_clan/proc/apply_effects(mob/living/body) + return + +/datum/vampire_clan/proc/remove_effects(mob/living/body) + return + +/datum/vampire_clan/Destroy(force) + if(!QDELETED(vampiredatum?.owner?.current)) + remove_effects(vampiredatum.owner.current) + vampiredatum = null + UnregisterSignal(SSdcs, COMSIG_VAMPIRE_BROKE_MASQUERADE) + return ..() + +/** + * Called when a Vampire exits Torpor + */ +/datum/vampire_clan/proc/on_exit_torpor() + return + +/** + * Called during Vampire's life_tick + */ +/datum/vampire_clan/proc/handle_clan_life() + if(!is_type_in_list(/datum/action/cooldown/vampire/levelup, vampiredatum.powers) && vampiredatum.vampire_level_unspent > 0) + vampiredatum.grant_power(new /datum/action/cooldown/vampire/levelup) + +/** + * Called when a Vampire successfully vassalizes someone via the persuasion rack. + * Do not call this on [/datum/antagonist/vampire/proc/make_vassal()] !!! + */ +/datum/vampire_clan/proc/on_vassal_made(mob/living/living_vampire, mob/living/living_vassal) + living_vampire.playsound_local(null, 'sound/effects/singlebeat.ogg', 70, TRUE) + + living_vassal.playsound_local(null, 'sound/effects/singlebeat.ogg', 70, TRUE) + living_vassal.set_jitter_if_lower(30 SECONDS) + living_vassal.emote("laugh") + +/** + * Called when we level up inside a coffin. + */ + + /** + * For every discipline in clan_disciplines we do: + * if the next level returns anything but null, we add it to the options + * /// + * Then we display the radial with the options. + * Picking a choice will do the following: + * Remove all powers from the discipline's current level, by: + * for every power in get_abilities_with_level(current level) > remove + * increase discipline level + * for every power in get_abilities_with_level(current level) > add + */ +/datum/vampire_clan/proc/spend_rank(mob/living/carbon/carbon_vampire) + if(QDELETED(vampiredatum.owner?.current) || vampiredatum.vampire_level_unspent <= 0) + return + + // Generate radial menu + var/list/options = list() + var/list/radial_display = list() + + for(var/datum/discipline/discipline as anything in vampiredatum.owned_disciplines) // We do owned_disciplines, not clan_disciplines. clan_disciplines is used to populate owned_disciplines. + if(discipline.get_abilities_with_level("next")) + options[discipline.name] = discipline + var/datum/radial_menu_choice/option = new + option.image = image(icon = 'tff_modular/modules/vampire/icons/disciplines.dmi', icon_state = discipline.icon_state) + option.info = "[span_boldnotice(discipline.name)]\n[span_cult(discipline.discipline_explanation)]" + radial_display[initial(discipline.name)] = option + + var/mob/living/living_vampire = vampiredatum.owner.current + + // Show radial menu + if(!length(options)) + to_chat(living_vampire, span_notice("You grow more familiar with your powers!")) + else + to_chat(living_vampire, span_notice("You have the opportunity to grow your expertise. Select a discipline to advance your Rank.")) + + // If we're in a closet, anchor the radial menu to it. If not, anchor it to the vampire body + var/datum/discipline/discipline_response + + if(istype(living_vampire.loc, /obj/structure/closet)) + var/obj/structure/closet/container = living_vampire.loc + discipline_response = show_radial_menu(living_vampire, container, radial_display) + else + discipline_response = show_radial_menu(living_vampire, living_vampire, radial_display) + + var/datum/discipline/chosen_discipline + + for(var/datum/discipline/discipline as anything in vampiredatum.owned_disciplines) + if(discipline.name == discipline_response) + chosen_discipline = discipline + break + + if(isnull(discipline_response) || QDELETED(src) || QDELETED(living_vampire)) + return FALSE + + // Remove all current powers + for(var/datum/action/cooldown/vampire/power_old as anything in vampiredatum.powers) + if(is_type_in_list(power_old, chosen_discipline.get_abilities_with_level("current"))) + vampiredatum.remove_power(power_old) + + // increment level + chosen_discipline.level_up() + + // add all current powers (of the new level) + for(var/datum/action/cooldown/vampire/power_new as anything in chosen_discipline.get_abilities_with_level("current")) + vampiredatum.grant_power(new power_new) + + living_vampire.balloon_alert(living_vampire, "learned [discipline_response] level [chosen_discipline.level - 1]!") + to_chat(living_vampire, span_notice("You have learned how to use [discipline_response]!")) + + finalize_spend_rank() + + // QoL + if(vampiredatum.vampire_level_unspent > 0) + spend_rank(carbon_vampire) + +/datum/vampire_clan/proc/finalize_spend_rank() + // Level up the vampire + vampiredatum.vampire_regen_rate += 0.05 + vampiredatum.max_vitae += 100 + + /* if(ishuman(vampiredatum.owner.current)) + var/mob/living/carbon/human/vampire_human = vampiredatum.owner.current + vampire_human.dna.species.punchdamage += 0.5 */ + + // We're almost done - Spend your Rank now. + vampiredatum.vampire_level++ + vampiredatum.vampire_level_unspent-- + + // Flavor + to_chat(vampiredatum.owner.current, span_notice("You are now a rank [vampiredatum.vampire_level] Vampire. \ + Your strength, health, feed rate, regen rate, and maximum blood capacity have all increased! \n\ + * Your existing powers have all ranked up as well!")) + vampiredatum.update_hud() + +/datum/vampire_clan/proc/on_vampire_broke_masquerade(datum/source, datum/antagonist/vampire/masquerade_breaker) + SIGNAL_HANDLER + + if(masquerade_breaker == vampiredatum) + return + + var/breaker_name = masquerade_breaker.owner.name || masquerade_breaker.owner.current.real_name || masquerade_breaker.owner.current.name + to_chat(vampiredatum.owner.current, span_userdanger("[breaker_name] has broken the Masquerade! We must destroy them at all costs, for the good of all kindred!\n\ + (Hint: You may feed on a vampire that has broken the masquerade to steal their powers.)")) + var/datum/objective/assassinate/masquerade_objective = new() + masquerade_objective.target = masquerade_breaker.owner + masquerade_objective.name = "Masquerade Objective" + masquerade_objective.explanation_text = "Ensure [breaker_name], who has broken the Masquerade, succumbs to Final Death." + vampiredatum.objectives += masquerade_objective + vampiredatum.owner.announce_objectives() + vampiredatum.update_static_data_for_all_viewers() diff --git a/tff_modular/modules/vampire/clans/assignclan.dm b/tff_modular/modules/vampire/clans/assignclan.dm new file mode 100644 index 00000000000..cfd3162ec10 --- /dev/null +++ b/tff_modular/modules/vampire/clans/assignclan.dm @@ -0,0 +1,43 @@ +/** + * Gives Vampires the ability to choose a Clan. + * If they are already in a Clan, or is in a Frenzy, they will not be able to do so. + * The arg is optional and should really only be an Admin setting a Clan for a player. + * If set however, it will give them the control of their Clan instead of the Vampire. + * This is selected through a radial menu over the player's body, even when an Admin is setting it. + * Args: + * person_selecting - Mob override for stuff like Admins selecting someone's clan. + */ +/datum/antagonist/vampire/proc/assign_clan_and_bane() + if(my_clan || HAS_TRAIT(owner.current, TRAIT_FRENZY)) + return + + var/list/options = list() + var/list/radial_display = list() + for(var/datum/vampire_clan/all_clans as anything in typesof(/datum/vampire_clan)) + if(!initial(all_clans.joinable_clan)) //flavortext only + continue + + options[initial(all_clans.name)] = all_clans + + var/datum/radial_menu_choice/option = new + option.image = image(icon = initial(all_clans.join_icon), icon_state = initial(all_clans.join_icon_state)) + option.info = "[span_boldnotice(initial(all_clans.name))]\n[span_cult(get_clan_description(all_clans.name))]" + radial_display[initial(all_clans.name)] = option + + var/chosen_clan + if(istype(owner.current.loc, /obj/structure/closet)) + var/obj/structure/closet/container = owner.current.loc + chosen_clan = show_radial_menu(owner.current, container, radial_display, radius = 45) + else + chosen_clan = show_radial_menu(owner.current, owner.current, radial_display, radius = 45) + + chosen_clan = options[chosen_clan] + + if(QDELETED(src) || QDELETED(owner.current) || !chosen_clan) + return FALSE + + my_clan = new chosen_clan(src) + my_clan.on_apply() + if(my_clan.antag_hud_icon) // regenerate their HUD if this clan has different icon + add_team_hud(owner.current) + SEND_SIGNAL(owner, COMSIG_VAMPIRE_CLAN_CHOSEN, src, my_clan) diff --git a/tff_modular/modules/vampire/clans/brujah.dm b/tff_modular/modules/vampire/clans/brujah.dm new file mode 100644 index 00000000000..52823cce3a9 --- /dev/null +++ b/tff_modular/modules/vampire/clans/brujah.dm @@ -0,0 +1,16 @@ +/datum/vampire_clan/brujah + name = CLAN_BRUJAH + description = "Mostly independent of the Camarilla's strictures, the Brujah prefer their own councils and street courts over princely salons.
    \ + They are a fallen clan, a people who have slid from warrior-scholars into fierce, argumentative rebels. Yet the embers of discipline and wisdom still glow beneath the rage.

    \ + At the same time, many Brujah are pragmatic. They respect competence, reward power, and will accept arrangements that let them keep their autonomy while serving a purpose. For the right price, leverage, or chance to settle scores, princes were known recruit Brujah as scourges or enforcers, so long as those Brujah retain visible independence." + join_icon_state = "brujah" + default_humanity = 8 + princely_score_bonus = 2 + joinable_clan = TRUE + antag_hud_icon = "brujah" + +/datum/vampire_clan/brujah/New(datum/antagonist/vampire/owner_datum) + . = ..() + vampiredatum.owned_disciplines += new /datum/discipline/celerity(vampiredatum) + vampiredatum.owned_disciplines += new /datum/discipline/potence/brujah(vampiredatum) + vampiredatum.owned_disciplines += new /datum/discipline/presence(vampiredatum) diff --git a/tff_modular/modules/vampire/clans/debug.dm b/tff_modular/modules/vampire/clans/debug.dm new file mode 100644 index 00000000000..942ae3cd2bf --- /dev/null +++ b/tff_modular/modules/vampire/clans/debug.dm @@ -0,0 +1,20 @@ +#ifdef VAMPIRE_TESTING +// debug clan with every discipline +/datum/vampire_clan/debug + name = "Debug Clan" + description = "wtf you shouldn't be seeing this outside of testing" + default_humanity = 10 + princely_score_bonus = 99 + joinable_clan = TRUE + +/datum/vampire_clan/debug/New(datum/antagonist/vampire/owner_datum) + . = ..() + vampiredatum.vampire_level_unspent = 35 + vampiredatum.owned_disciplines += new /datum/discipline/auspex/malkavian(vampiredatum) + vampiredatum.owned_disciplines += new /datum/discipline/celerity(vampiredatum) + vampiredatum.owned_disciplines += new /datum/discipline/dominate/ventrue(vampiredatum) + vampiredatum.owned_disciplines += new /datum/discipline/fortitude(vampiredatum) + vampiredatum.owned_disciplines += new /datum/discipline/potence/brujah(vampiredatum) + vampiredatum.owned_disciplines += new /datum/discipline/presence(vampiredatum) + vampiredatum.owned_disciplines += new /datum/discipline/thaumaturgy(vampiredatum) +#endif diff --git a/tff_modular/modules/vampire/clans/flavortext_clans.dm b/tff_modular/modules/vampire/clans/flavortext_clans.dm new file mode 100644 index 00000000000..93e4005c8de --- /dev/null +++ b/tff_modular/modules/vampire/clans/flavortext_clans.dm @@ -0,0 +1,30 @@ +// These have no functionality. They're just flavortext for the Archive of the Kindred +/datum/vampire_clan/tzimisce + name = CLAN_TZIMISCE + description = "The Tzimisce Clan has no knowledge about it. \n\ + If you see one, you should probably run away.\n\ + *the rest of the page is full of undecipherable scribbles...*" + joinable_clan = FALSE + +/datum/vampire_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." + joinable_clan = FALSE + +/datum/vampire_clan/lasombra + name = CLAN_LASOMBRA + description = "This Clan seems to adore living in the Shadows, worshipping it's secrets. \n\ + They take their research and vanity seriously, they are always very proud of themselves after even minor achievements. \n\ + They appear to be in search of a station with a veil weakness to be able to channel their shadow's abyssal powers. \n\ + Thanks to this, they have also evolved a dark liquid in their veins, which makes them able to manipulate shadows." + joinable_clan = FALSE + +/datum/vampire_clan/nosferatu + name = CLAN_NOSFERATU + description = "The Nosferatu Clan is unable to blend in with the crew, with no abilities such as Masquerade and Veil. \n\ + Additionally, has a permanent bad back and looks like a Vampire upon a simple examine, and is entirely unidentifiable, \n\ + they can fit in the vents regardless of their form and equipment." + joinable_clan = FALSE diff --git a/tff_modular/modules/bloodsucker/bloodsuckers/trauma.dm b/tff_modular/modules/vampire/clans/malkavian.dm similarity index 51% rename from tff_modular/modules/bloodsucker/bloodsuckers/trauma.dm rename to tff_modular/modules/vampire/clans/malkavian.dm index 82353a1dd8d..b6809c334a3 100644 --- a/tff_modular/modules/bloodsucker/bloodsuckers/trauma.dm +++ b/tff_modular/modules/vampire/clans/malkavian.dm @@ -1,3 +1,66 @@ +#define REVELATION_MIN_COOLDOWN 20 SECONDS +#define REVELATION_MAX_COOLDOWN 1 MINUTES + +/datum/vampire_clan/malkavian + name = CLAN_MALKAVIAN + description = "Malkavians are the brood of Malkav and one of the great vampiric clans. They are deranged vampires, afflicted with the insanity of their Antediluvian progenitor.

    \ + Members of the clan have assumed the roles of seers and oracles among Kindred and kine, eerie figures bound by strange compulsions and the ability to perceive what others cannot.

    \ + They are also notorious pranksters whose 'jokes' range from silly to sadistic. Against all odds, however, the children of Malkav are among the oldest surviving vampiric lineages." + join_icon_state = "malkavian" + joinable_clan = TRUE + default_humanity = 8 + princely_score_bonus = 6 + + COOLDOWN_DECLARE(revelation_cooldown) + +/datum/vampire_clan/malkavian/New(datum/antagonist/vampire/owner_datum) + . = ..() + + vampiredatum.owned_disciplines += new /datum/discipline/auspex/malkavian(vampiredatum) + vampiredatum.owned_disciplines += new /datum/discipline/obfuscate(vampiredatum) + vampiredatum.owned_disciplines += new /datum/discipline/dominate(vampiredatum) + + vampiredatum.owner.current.playsound_local(get_turf(vampiredatum.owner.current), 'sound/music/antag/creepalert.ogg', 80, FALSE, pressure_affected = FALSE, use_reverb = FALSE) + to_chat(vampiredatum.owner.current, span_hypnophrase("Welcome, childe of Malkav...")) + +/datum/vampire_clan/malkavian/apply_effects(mob/living/body) + if(iscarbon(body)) + var/mob/living/carbon/carbon_body = body + carbon_body.gain_trauma(/datum/brain_trauma/mild/hallucinations, TRAUMA_RESILIENCE_ABSOLUTE) + carbon_body.gain_trauma(/datum/brain_trauma/special/bluespace_prophet/phobetor, TRAUMA_RESILIENCE_ABSOLUTE) + + ADD_TRAIT(body, TRAIT_XRAY_VISION, TRAIT_VAMPIRE) + body.update_sight() + +/datum/vampire_clan/malkavian/remove_effects(mob/living/body) + if(iscarbon(body)) + var/mob/living/carbon/carbon_body = body + carbon_body.cure_trauma_type(/datum/brain_trauma/mild/hallucinations, TRAUMA_RESILIENCE_ABSOLUTE) + carbon_body.cure_trauma_type(/datum/brain_trauma/special/bluespace_prophet/phobetor, TRAUMA_RESILIENCE_ABSOLUTE) + + REMOVE_TRAIT(body, TRAIT_XRAY_VISION, TRAIT_VAMPIRE) + body.update_sight() + +/datum/vampire_clan/malkavian/handle_clan_life() + . = ..() + var/mob/living/living_vampire = vampiredatum.owner.current + if(!COOLDOWN_FINISHED(src, revelation_cooldown) || HAS_TRAIT(living_vampire, TRAIT_MASQUERADE) || living_vampire.stat != CONSCIOUS) + return + + if(prob(15)) + var/message = pick(strings("antagonist_flavor/malkavian_revelations.json", "revelations", "strings")) + INVOKE_ASYNC(living_vampire, TYPE_PROC_REF(/atom/movable, say), message, , , , , , "Malkavian Revelation") + COOLDOWN_START(src, revelation_cooldown, rand(REVELATION_MIN_COOLDOWN, REVELATION_MAX_COOLDOWN)) + +/datum/vampire_clan/malkavian/on_exit_torpor() + var/mob/living/carbon/carbon_vampire = vampiredatum.owner.current + if(istype(carbon_vampire)) + carbon_vampire.gain_trauma(/datum/brain_trauma/mild/hallucinations, TRAUMA_RESILIENCE_ABSOLUTE) + carbon_vampire.gain_trauma(/datum/brain_trauma/special/bluespace_prophet/phobetor, TRAUMA_RESILIENCE_ABSOLUTE) + +#undef REVELATION_MAX_COOLDOWN +#undef REVELATION_MIN_COOLDOWN + /** * # Phobetor Brain Trauma * @@ -8,17 +71,18 @@ name = "Sleepless Dreamer" desc = "The patient, after undergoing untold psychological hardship, believes they can travel between the dreamscapes of this dimension." scan_desc = "awoken sleeper" - gain_text = "Your mind snaps, and you wake up. You really wake up." - lose_text = "You succumb once more to the sleepless dream of the unwoken." + gain_text = span_notice("Your mind snaps, and you wake up. You really wake up.") + lose_text = span_warning("You succumb once more to the sleepless dream of the unwoken.") + random_gain = FALSE + resilience = TRAUMA_RESILIENCE_ABSOLUTE ///Created tears, only checking the FIRST one, not the one it's created to link to. var/list/created_firsts = list() ///When the trauma is removed from a mob. /datum/brain_trauma/special/bluespace_prophet/phobetor/on_lose(silent) - . = ..() - for(var/obj/effect/client_image_holder/phobetor/phobetor_tears as anything in created_firsts) - qdel(phobetor_tears) + QDEL_LIST(created_firsts) + return ..() /datum/brain_trauma/special/bluespace_prophet/phobetor/on_life(seconds_per_tick, times_fired) if(!COOLDOWN_FINISHED(src, portal_cooldown)) @@ -46,18 +110,18 @@ first.linked_to = second first.seer = owner - first.desc += " This one leads to [get_area(second)]." + first.desc += " This one leads to [get_area(second)]." first.name += " ([get_area(second)])" created_firsts += first second.linked_to = first second.seer = owner - second.desc += " This one leads to [get_area(first)]." + second.desc += " This one leads to [get_area(first)]." second.name += " ([get_area(first)])" // Delete Next Portal if it's time (it will remove its partner) var/obj/effect/client_image_holder/phobetor/first_on_the_stack = created_firsts[1] - if(created_firsts.len && world.time >= first_on_the_stack.created_on + first_on_the_stack.exist_length) + if(length(created_firsts) && world.time >= first_on_the_stack.created_on + first_on_the_stack.exist_length) var/targetGate = first_on_the_stack created_firsts -= targetGate qdel(targetGate) @@ -107,7 +171,7 @@ /obj/effect/client_image_holder/phobetor name = "phobetor tear" desc = "A subdimensional rip in reality, which gives extra-spacial passage to those who have woken from the sleepless dream." - image_icon = 'tff_modular/modules/bloodsucker/icons/phobetor_tear.dmi' + image_icon = 'tff_modular/modules/vampire/icons/phobetor_tear.dmi' image_state = "phobetor_tear" // Place this above shadows so it always glows. image_layer = ABOVE_MOB_LAYER @@ -124,26 +188,34 @@ /obj/effect/client_image_holder/phobetor/Initialize(mapload) . = ..() created_on = world.time + AddElement(/datum/element/block_turf_fingerprints) + AddComponent(/datum/component/redirect_attack_hand_from_turf, interact_check = CALLBACK(src, PROC_REF(verify_user_can_see))) /obj/effect/client_image_holder/phobetor/Destroy() + seer = null if(linked_to) linked_to.linked_to = null QDEL_NULL(linked_to) return ..() +/obj/effect/client_image_holder/phobetor/proc/verify_user_can_see(mob/user) + return user == seer + /obj/effect/client_image_holder/phobetor/proc/check_location_seen(atom/subject, turf/target_turf) - if(!target_turf) - return FALSE if(!isturf(target_turf)) return FALSE - if(!target_turf.lighting_object || !target_turf.get_lumcount() >= 0.1) + if(GET_SIMPLE_LUMCOUNT(target_turf) <= 0.2) return FALSE - for(var/mob/living/nearby_viewers in viewers(target_turf)) - if(nearby_viewers == subject) + for(var/mob/living/nearby_viewers in viewers(target_turf) - subject) + if(!nearby_viewers.mind || !nearby_viewers.client || nearby_viewers.client?.is_afk()) + continue + if(isanimal_or_basicmob(nearby_viewers)) + continue + if(HAS_MIND_TRAIT(nearby_viewers, TRAIT_VAMPIRE_ALIGNED) || HAS_MIND_TRAIT(nearby_viewers, TRAIT_OCCULTIST)) continue - if(!isliving(nearby_viewers) || !nearby_viewers.mind) + if(nearby_viewers.is_blind() || nearby_viewers.is_nearsighted_currently()) continue - if(nearby_viewers.is_blind()) + if(HAS_SILICON_ACCESS(nearby_viewers)) continue return TRUE return FALSE @@ -151,11 +223,12 @@ /obj/effect/client_image_holder/phobetor/attack_hand(mob/living/user, list/modifiers) if(user != seer || !linked_to) return - if(user.loc != src.loc) - to_chat(user, "Step into the Tear before using it.") + if(user.loc != loc) + to_chat(user, span_warning("Step into the Tear before using it.")) return - for(var/obj/item/implant/tracking/imp in user.implants) - to_chat(user, span_warning("[imp] gives you the sense that you're being watched.")) + var/obj/item/implant/tracking/tracking_implant = locate() in user.implants + if(tracking_implant) + to_chat(user, span_warning("[tracking_implant] gives you the sense that you're being watched.")) return // Is this, or linked, stream being watched? if(check_location_seen(user, get_turf(user))) diff --git a/tff_modular/modules/vampire/clans/toreador.dm b/tff_modular/modules/vampire/clans/toreador.dm new file mode 100644 index 00000000000..5bb0f23f3ae --- /dev/null +++ b/tff_modular/modules/vampire/clans/toreador.dm @@ -0,0 +1,16 @@ +/datum/vampire_clan/toreador + name = CLAN_TOREADOR + description = "The Toreador are a clan of vampires known for being some of the most beautiful, sensual, seductive, emotional and glamorous of the Kindred.

    \ + Responsible for the legends of vampires who seduce and entice their prey with beauty, love and sensuality. Famous and infamous as a clan of artists and innovators, they are one of the bastions of the Camarilla, as their very survival depends on the facades of civility and grace on which the sect prides itself.

    \ + They are inherently divas by blood, and their humanity and sense of morality may plummit as fast as it rises." + join_icon_state = "toreador" + blood_drink_type = VAMPIRE_DRINK_SNOBBY + default_humanity = 10 + princely_score_bonus = 10 + joinable_clan = TRUE + +/datum/vampire_clan/toreador/New(datum/antagonist/vampire/owner_datum) + . = ..() + vampiredatum.owned_disciplines += new /datum/discipline/celerity(vampiredatum) + vampiredatum.owned_disciplines += new /datum/discipline/auspex(vampiredatum) + vampiredatum.owned_disciplines += new /datum/discipline/presence(vampiredatum) diff --git a/tff_modular/modules/vampire/clans/tremere.dm b/tff_modular/modules/vampire/clans/tremere.dm new file mode 100644 index 00000000000..fc663257dc5 --- /dev/null +++ b/tff_modular/modules/vampire/clans/tremere.dm @@ -0,0 +1,15 @@ +/datum/vampire_clan/tremere + name = CLAN_TREMERE + description = "In the (comparatively) little time since their founding, the Tremere have made incredible inroads within vampiric society and are arguably the most powerful clan in the modern nights.

    \ + This is due in no small part to their strict hierarchy, secretive nature, and mastery of Thaumaturgy, all of which elicit suspicion, fear, and respect from other Cainites.

    \ + The Tremere stand as a pillar of the Camarilla and are one of its main defenders, despite the fact that they exist almost as a subsect." + join_icon_state = "tremere" + default_humanity = 7 + princely_score_bonus = 8 + joinable_clan = TRUE + +/datum/vampire_clan/tremere/New(datum/antagonist/vampire/owner_datum) + . = ..() + vampiredatum.owned_disciplines += new /datum/discipline/dominate(vampiredatum) + vampiredatum.owned_disciplines += new /datum/discipline/auspex(vampiredatum) + vampiredatum.owned_disciplines += new /datum/discipline/thaumaturgy(vampiredatum) diff --git a/tff_modular/modules/vampire/clans/ventrue.dm b/tff_modular/modules/vampire/clans/ventrue.dm new file mode 100644 index 00000000000..71c280d1648 --- /dev/null +++ b/tff_modular/modules/vampire/clans/ventrue.dm @@ -0,0 +1,17 @@ +/datum/vampire_clan/ventrue + name = CLAN_VENTRUE + description = "The Ventrue have long been one of the proudest lines of vampires. Its members work hard to maintain a reputation for honor, genteel behavior, and leadership.

    \ + A sense of noblesse oblige has long pervaded the clan, accompanied by the genuine belief that the Ventrue know what is best for everyone.

    \ + They not only consider themselves the oldest clan, but see themselves as the enforcers of tradition and the rightful leaders of Kindred society. " + join_icon_state = "ventrue" + blood_drink_type = VAMPIRE_DRINK_SNOBBY + default_humanity = 9 + princely_score_bonus = 15 // IT'S OVER NIN- ten. It's over ten. + joinable_clan = TRUE + +/datum/vampire_clan/ventrue/New(datum/antagonist/vampire/owner_datum) + . = ..() + + vampiredatum.owned_disciplines += new /datum/discipline/presence(vampiredatum) + vampiredatum.owned_disciplines += new /datum/discipline/dominate/ventrue(vampiredatum) + vampiredatum.owned_disciplines += new /datum/discipline/fortitude(vampiredatum) diff --git a/tff_modular/modules/vampire/component.dm b/tff_modular/modules/vampire/component.dm new file mode 100644 index 00000000000..db4c18ba50f --- /dev/null +++ b/tff_modular/modules/vampire/component.dm @@ -0,0 +1,361 @@ +PROCESSING_SUBSYSTEM_DEF(movable_physics) + name = "Movable Physics" + priority = 24 + wait = 0.05 SECONDS + stat_tag = "MPhys" + runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME + +/** + * MOVABLE PHYSICS COMPONENT - By ma44, bob joga and pyroshark (https://github.com/DaedalusDock/daedalusdock/pull/96/) + * + * Essentially, this component adds a very dodgy, very barebones simulation of pixel movement and physics for the movable. + * Using animate here would be very expensive, so instead this processes every 1/20 seconds and adjusts pixel_x, pixel_y and pixel_z. + * Whenever the movable crosses a tile's boundary, it will attempt to move into the appropriate tile. + * Collisions are accounted for, but they are very simple and tile based. No complex hitboxes or anythin'. + * All of this, of course, only works while the movable is located a turf. + */ +/datum/component/movable_physics + /// Flags for turning on certain physic properties, see the top of the file for more information on flags + var/physics_flags + /// The angle of the path the object takes on the x/y plane + var/angle + /** + * Modifies the pixel_x/pixel_y of an object every process() + * Movables aren't Move()'d into another turf if pixel_z exceeds 16, so try not to supply a super high vertical value + * if you don't want the movable to clip through multiple turfs (looks dumb) + */ + var/horizontal_velocity + /// Modifies the pixel_z of an object every process() + var/vertical_velocity + /** + * The horizontal_velocity is reduced by this every process() + * this doesn't take into account the object being in the air vs gravity pushing it against the ground + */ + var/horizontal_friction + /// The vertical_velocity is reduced by this every process() + var/vertical_friction + /** + * Conservation of momentum for x/y plane + * horizontal_velocity gets multiplied by this when bumping on a wall + */ + var/horizontal_conservation_of_momentum + /** + * Conservation of momentum for z plane + * vertical_velocity gets multiplied by this when bumping on the floor + */ + var/vertical_conservation_of_momentum + /** + * The pixel_z that the object will no longer be influenced by gravity for a 32x32 turf + * Keep this value between -16 to 0 so it's visuals matches up with it physically being in the turf + */ + var/z_floor + /// Visual angle velocity of the object + var/visual_angle_velocity + /// Visual angle friction of the object + var/visual_angle_friction + /// For calling spinanimation at the start of movement + var/spin_speed + /// For calling spinanimation at the start of movement + var/spin_loops + /// For calling spinanimation at the start of movement + var/spin_clockwise + /// For calling spinanimation when bouncing + var/bounce_spin_speed + /// For calling spinanimation when bouncing + var/bounce_spin_loops + /// For calling spinanimation when bouncing + var/bounce_spin_clockwise + /// The sound effect to play when bouncing off of something + var/bounce_sound + /// If we have this callback, it gets invoked when bouncing on the floor + var/datum/callback/bounce_callback + /// If we have this callback, it gets invoked when stopping movement + var/datum/callback/stop_callback + /// If we have this callback, it gets invoked when bumping on another atom + var/datum/callback/bump_callback + + /** + * The cached animate_movement of the parent + * Any kind of gliding when doing Move() makes the physics look derpy, so we'll just make Move() be instant + */ + var/cached_animate_movement + /// Cached transform of the parent, in case some fucking idiot decides its a good idea to make the damn movable spin forever + var/cached_transform + +// It's a BAD IDEA to use this on something that is not an item, even though you can +/datum/component/movable_physics/Initialize( + physics_flags = NONE, + angle = 0, + horizontal_velocity = 0, + vertical_velocity = 0, + horizontal_friction = 0, + vertical_friction = 0, + horizontal_conservation_of_momentum = 0.8, + vertical_conservation_of_momentum = 0.8, + z_floor = 0, + visual_angle_velocity = 0, + visual_angle_friction = 0, + spin_speed = 2 SECONDS, + spin_loops = 0, + spin_clockwise = TRUE, + bounce_spin_speed = 0, + bounce_spin_loops = 0, + bounce_spin_clockwise = 0, + bounce_sound, + bounce_callback, + bump_callback, + stop_callback, +) + if(!ismovable(parent)) + return COMPONENT_INCOMPATIBLE + + src.horizontal_velocity = horizontal_velocity + src.vertical_velocity = vertical_velocity + src.horizontal_friction = horizontal_friction + src.vertical_friction = vertical_friction + src.z_floor = z_floor + src.physics_flags = physics_flags + src.angle = angle + src.horizontal_conservation_of_momentum = horizontal_conservation_of_momentum + src.vertical_conservation_of_momentum = vertical_conservation_of_momentum + src.visual_angle_velocity = visual_angle_velocity + src.visual_angle_friction = visual_angle_friction + src.spin_speed = spin_speed + src.spin_loops = spin_loops + src.spin_clockwise = spin_clockwise + src.bounce_spin_speed = bounce_spin_speed + src.bounce_spin_loops = bounce_spin_loops + src.bounce_spin_clockwise = bounce_spin_clockwise + src.bounce_sound = bounce_sound + src.bounce_callback = bounce_callback + src.bump_callback = bump_callback + src.stop_callback = stop_callback + set_angle(angle) + +/datum/component/movable_physics/Destroy(force) + STOP_PROCESSING(SSmovable_physics, src) + bounce_callback = null + stop_callback = null + cached_transform = null + return ..() + +/datum/component/movable_physics/RegisterWithParent() + RegisterSignal(parent, COMSIG_MOVABLE_NEWTONIAN_MOVE, PROC_REF(on_newtonian_move)) + RegisterSignal(parent, COMSIG_MOVABLE_BUMP, PROC_REF(on_bump)) + if(isitem(parent)) + RegisterSignal(parent, COMSIG_ITEM_PICKUP, PROC_REF(on_item_pickup)) + if(has_movement()) + start_movement() + else if(physics_flags & MPHYSICS_QDEL_WHEN_NO_MOVEMENT) + qdel(src) + +/datum/component/movable_physics/UnregisterFromParent() + UnregisterSignal(parent, COMSIG_MOVABLE_IMPACT) + if(isitem(parent)) + UnregisterSignal(parent, COMSIG_ITEM_PICKUP) + stop_movement() + +// NOTE: This component will work very poorly at anything less than ticking 10 times per second +/datum/component/movable_physics/process(seconds_per_tick) + var/atom/movable/moving_atom = parent + if(!isturf(moving_atom.loc) || QDELING(moving_atom.loc) || !has_movement()) + stop_movement() + return PROCESS_KILL + + // We will not process when paused + if(physics_flags & MPHYSICS_PAUSED) + return + + // this component was designed to tick every 1/20 seconds, so we have to always account for that + var/tick_amount = 20 * seconds_per_tick + //this code basically only makes sense if we only move at most a single tile per tick, it is absolutely fucked otherwise + while(tick_amount > 0) + tick_amount-- + //we need to know if we have gravity right now to apply friction and such, yeah + var/has_gravity = moving_atom.has_gravity() + + moving_atom.pixel_x = round(moving_atom.pixel_x + (horizontal_velocity * sin(angle)), MOVABLE_PHYSICS_PRECISION) + moving_atom.pixel_y = round(moving_atom.pixel_y + (horizontal_velocity * cos(angle)), MOVABLE_PHYSICS_PRECISION) + + moving_atom.pixel_z = round(clamp(moving_atom.pixel_z + vertical_velocity, z_floor, world.icon_size), MOVABLE_PHYSICS_PRECISION) + + moving_atom.adjust_visual_angle(round(visual_angle_velocity, 1)) + + if(has_gravity) + visual_angle_velocity = max(0, visual_angle_velocity - visual_angle_friction) + horizontal_velocity = max(0, horizontal_velocity - horizontal_friction) + // we are not on the floor, apply friction + if(moving_atom.pixel_z > z_floor) + vertical_velocity -= vertical_friction + // we are on the floor, try to bounce if we have any vertical velocity + else if(moving_atom.pixel_z <= z_floor && vertical_velocity) + z_floor_bounce(moving_atom) + // z_floor_bounce could have deleted us + if(QDELETED(src)) + return + + var/move_direction = NONE + var/effective_pixel_x = moving_atom.pixel_x - moving_atom.base_pixel_x + var/effective_pixel_y = moving_atom.pixel_y - moving_atom.base_pixel_y + //crossed east boundary + if(effective_pixel_x > world.icon_size/2) + move_direction |= EAST + //crossed west boundary + else if(effective_pixel_x < -world.icon_size/2) + move_direction |= WEST + + //crossed north boundary + if(effective_pixel_y > world.icon_size/2) + move_direction |= NORTH + //crossed south boundary + else if(effective_pixel_y < -world.icon_size/2) + move_direction |= SOUTH + + //check if we need to move, continue otherwise + if(!move_direction) + continue + //get the tile we should move towards + var/step = get_step(moving_atom, move_direction) + //attempt to move to that tile, if successful we reset the pixel_x and pixel_y to be on the edge of appropriate boundaries + //if unsuccessful, bump signal will be called and newton's third law comes into play + if(moving_atom.Move(step, move_direction, world.icon_size)) + if(move_direction & EAST) + moving_atom.pixel_x -= world.icon_size + else if(move_direction & WEST) + moving_atom.pixel_x += world.icon_size + + if(move_direction & NORTH) + moving_atom.pixel_y -= world.icon_size + else if(move_direction & SOUTH) + moving_atom.pixel_y += world.icon_size + +/// Checks if we still have any movement going on +/datum/component/movable_physics/proc/has_movement() + var/atom/movable/moving_atom = parent + // horizontal velocity and visual_angle_velocity should NEVER be negative + if(horizontal_velocity < MOVABLE_PHYSICS_MINIMAL_VELOCITY && \ + abs(vertical_velocity) < MOVABLE_PHYSICS_MINIMAL_VELOCITY && \ + moving_atom.pixel_z <= z_floor && \ + visual_angle_velocity < MOVABLE_PHYSICS_MINIMAL_VELOCITY) + return FALSE + return TRUE + +/// Does a bunch of setup, then starts the movement sequence +/datum/component/movable_physics/proc/start_movement() + if(physics_flags & MPHYSICS_MOVING) + stack_trace("[type] attempted to start_movement() while already moving") + return + START_PROCESSING(SSmovable_physics, src) + physics_flags |= MPHYSICS_MOVING + var/atom/movable/moving_atom = parent + cached_animate_movement = moving_atom.animate_movement + moving_atom.animate_movement = NO_STEPS + if(!spin_speed || visual_angle_velocity || visual_angle_friction) + return + moving_atom.SpinAnimation(speed = spin_speed, loops = spin_loops) + if(spin_loops == INFINITY) + cached_transform = matrix(moving_atom.transform) + +/// Stops movement sequence, and deletes component if we have the MPHYSICS_QDEL_WHEN_NO_MOVEMENT flag +/datum/component/movable_physics/proc/stop_movement() + STOP_PROCESSING(SSmovable_physics, src) + physics_flags &= ~MPHYSICS_MOVING + var/atom/movable/moving_atom = parent + if(cached_animate_movement) + moving_atom.animate_movement = cached_animate_movement + // this will probably bite my ass later + moving_atom.pixel_z = z_floor + if(cached_transform) + animate(moving_atom, transform = cached_transform, time = 0, loop = 0) + stop_callback?.Invoke() + if((physics_flags & MPHYSICS_QDEL_WHEN_NO_MOVEMENT) && !QDELING(src)) + qdel(src) + +/// Helper to set angle, futureproofing in case new behavior like altering the transform of the movable based on angle is needed +/datum/component/movable_physics/proc/set_angle(new_angle) + if(!isnull(new_angle)) + angle = SIMPLIFY_DEGREES(new_angle) + +/// We do not EVER want newtonian movement while handling movement ourselves, so block it! +/datum/component/movable_physics/proc/on_newtonian_move(atom/movable/source, direction, start_delay) + SIGNAL_HANDLER + + return COMPONENT_MOVABLE_NEWTONIAN_BLOCK + +/// Proc for bouncing, aka object reached z_floor on pixel_z and needs a dose of Newton's third law +/datum/component/movable_physics/proc/z_floor_bounce(atom/movable/moving_atom) + moving_atom.pixel_z = round(z_floor, MOVABLE_PHYSICS_PRECISION) + if(bounce_spin_speed && !visual_angle_velocity && !visual_angle_friction) + moving_atom.SpinAnimation(speed = bounce_spin_speed, loops = max(0, bounce_spin_loops)) + vertical_velocity = abs(vertical_velocity * vertical_conservation_of_momentum) + bounce_callback?.Invoke() + +/// Basically handles bumping on a solid object and ricocheting away according to a dose of Newton's third law +/datum/component/movable_physics/proc/on_bump(atom/movable/source, atom/bumped_atom) + SIGNAL_HANDLER + + horizontal_velocity = horizontal_velocity * horizontal_conservation_of_momentum + var/face_direction = get_dir(bumped_atom, source) + var/face_angle = dir2angle(face_direction) + var/incidence = GET_ANGLE_OF_INCIDENCE(face_angle, angle + 180) + var/new_angle = SIMPLIFY_DEGREES(face_angle + incidence) + set_angle(new_angle) + bump_callback?.Invoke(bumped_atom) + if(!visual_angle_velocity) + return + incidence = GET_ANGLE_OF_INCIDENCE(face_angle, source.visual_angle + 180) + new_angle = SIMPLIFY_DEGREES(face_angle + incidence) + source.set_visual_angle(new_angle) + bumped_atom.hitby(source, FALSE) + +/// Stops movement for pesky items when they get picked up, as that essentially invalidates this component +/datum/component/movable_physics/proc/on_item_pickup(obj/item/source) + SIGNAL_HANDLER + + stop_movement() + +/** + * DEBUG PROC + * + * Basically, loosely throws src towards target. For simple, no-nonsense testing of the component. + * Deviation is just the amount of degrees the angle can deviate. + */ +/atom/movable/proc/physics_chungus_deluxe(atom/movable/target, deviation = rand(-10, 10)) + var/angle_to_target = get_angle(src, target) + var/angle_of_movement = angle_to_target + if(deviation) + angle_of_movement += SIMPLIFY_DEGREES(rand(-deviation * 100, deviation * 100) * 0.01) + AddComponent(/datum/component/movable_physics, \ + angle = angle_of_movement, \ + horizontal_velocity = rand(4.5 * 100, 5.5 * 100) * 0.01, \ + vertical_velocity = rand(4 * 100, 4.5 * 100) * 0.01, \ + horizontal_friction = rand(0.2 * 100, 0.24 * 100) * 0.01, \ + vertical_friction = 10 * 0.05, \ + z_floor = 0, \ + visual_angle_velocity = rand(1 * 100, 3 * 100) * 0.01, \ + visual_angle_friction = 0.1, \ + ) + +/atom/movable + /** + * Current visual angle in degrees + * Generally if you want to make an atom rotate visually, you should use this var + * and it's setter procs + */ + var/visual_angle = 0 + +/// Adjusts the visual angle of the atom by angle_amount in degrees, based on it's current transform +/atom/movable/proc/adjust_visual_angle(angle_amount, animate_time = 0, animate_loop = 0, animate_easing = LINEAR_EASING, animate_flags = NONE) + angle_amount = SIMPLIFY_DEGREES(angle_amount) + if(!angle_amount) + return + animate(src, transform = transform.Turn(angle_amount), time = animate_time, loop = animate_loop, easing = animate_easing, flags = animate_flags) + visual_angle += angle_amount + visual_angle = SIMPLIFY_DEGREES(visual_angle) + +/// Sets the angle of the transform to exactly new_angle in degrees +/atom/movable/proc/set_visual_angle(new_angle = 0) + if(isnull(new_angle)) + return + var/difference = SIMPLIFY_DEGREES(new_angle - visual_angle) + return adjust_visual_angle(difference) diff --git a/tff_modular/modules/vampire/config.dm b/tff_modular/modules/vampire/config.dm new file mode 100644 index 00000000000..685c9f6cf57 --- /dev/null +++ b/tff_modular/modules/vampire/config.dm @@ -0,0 +1,5 @@ +/datum/config_entry/string/default_view + default = "15x15" + +/datum/config_entry/string/default_view_square + default = "15x15" diff --git a/tff_modular/modules/vampire/conversion_vampire.dm b/tff_modular/modules/vampire/conversion_vampire.dm new file mode 100644 index 00000000000..e73fe7b6d46 --- /dev/null +++ b/tff_modular/modules/vampire/conversion_vampire.dm @@ -0,0 +1,63 @@ +/** + * This file contains all of the procs related to vassalizing someone + * +**/ + +/** + * Checks if the target's antag_datums contain any of the banned antags. +**/ +/datum/antagonist/vampire/proc/is_blacklisted_antag(mob/target) + for(var/datum/antagonist/antag_datum as anything in target.mind.antag_datums) + if(antag_datum.type in vassal_banned_antags) + return TRUE + return FALSE + +/** + * Checks if the person is allowed to turn into the Vampire's vassal +**/ +/datum/antagonist/vampire/proc/can_make_vassal(mob/living/conversion_target, ignore_concious_check = FALSE) + var/mob/living/living_vampire = owner.current + + if(!my_clan) + living_vampire.balloon_alert(living_vampire, "enter a clan first.") + return FALSE + + if(count_vassals() >= 4) + living_vampire.balloon_alert(living_vampire, "too many vassals.") + return FALSE + +#ifndef VAMPIRE_TESTING + if(!conversion_target.ckey) + living_vampire.balloon_alert(living_vampire, "can't be vassalized.") + return FALSE +#endif + + if(!iscarbon(conversion_target) || !conversion_target.mind || HAS_MIND_TRAIT(conversion_target, TRAIT_UNCONVERTABLE) || is_blacklisted_antag(conversion_target)) + living_vampire.balloon_alert(living_vampire, "can't be vassalized.") + return FALSE + + var/datum/antagonist/vassal/vassaldatum = IS_VASSAL(conversion_target) + var/mob/living/vassal_master = conversion_target.mind.enslaved_to?.resolve() + if((vassaldatum && !vassaldatum.master.broke_masquerade) || (vassal_master && vassal_master != owner.current)) + living_vampire.balloon_alert(living_vampire, "enslaved to someone else.") + return FALSE + + if(!ignore_concious_check && conversion_target.stat > UNCONSCIOUS) + living_vampire.balloon_alert(living_vampire, "must be awake.") + return FALSE + + return TRUE + +/datum/antagonist/vampire/proc/make_vassal(mob/living/conversion_target) + if(IS_VASSAL(conversion_target)) + conversion_target.mind.remove_antag_datum(/datum/antagonist/vassal) + + // Set the master, then give the datum. + var/datum/antagonist/vassal/vassaldatum = new(conversion_target.mind) + vassaldatum.master = src + conversion_target.mind.add_antag_datum(vassaldatum) + + message_admins("[ADMIN_LOOKUPFLW(conversion_target)] has become a vassal, and is enslaved to [ADMIN_LOOKUPFLW(owner.current)].") + log_admin("[key_name(conversion_target)] has become a vassal, and is enslaved to [key_name(owner.current)].") + + return TRUE diff --git a/tff_modular/modules/vampire/crafts.dm b/tff_modular/modules/vampire/crafts.dm new file mode 100644 index 00000000000..2ed580d02cd --- /dev/null +++ b/tff_modular/modules/vampire/crafts.dm @@ -0,0 +1,153 @@ + +/datum/crafting_recipe/stake + name = "Stake" + result = /obj/item/stake + reqs = list(/obj/item/stack/sheet/mineral/wood = 3) + time = 8 SECONDS + category = CAT_WEAPON_MELEE + +/datum/crafting_recipe/hardened_stake + name = "Hardened Stake" + result = /obj/item/stake/hardened + tool_behaviors = list(TOOL_WELDER) + reqs = list(/obj/item/stack/rods = 1) + time = 6 SECONDS + category = CAT_WEAPON_MELEE + +/datum/crafting_recipe/silver_stake + name = "Silver Stake" + result = /obj/item/stake/hardened/silver + tool_behaviors = list(TOOL_WELDER) + reqs = list( + /obj/item/stack/sheet/mineral/silver = 1, + /obj/item/stake/hardened = 1, + ) + time = 8 SECONDS + category = CAT_WEAPON_MELEE + crafting_flags = CRAFT_MUST_BE_LEARNED + +/datum/crafting_recipe/vassalrack + name = "Vassalization Rack" + result = /obj/structure/vampire/vassalrack + time = 5 SECONDS + + reqs = list( + /obj/item/stack/sheet/iron = 5, + /obj/item/stack/rods = 6, + ) + + category = CAT_VAMPIRE + crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND | CRAFT_MUST_BE_LEARNED + +/datum/crafting_recipe/candelabrum + name = "Candelabrum" + result = /obj/structure/vampire/candelabrum + time = 5 SECONDS + + reqs = list( + /obj/item/stack/sheet/iron = 1, + /obj/item/stack/rods = 3, + /obj/item/flashlight/flare/candle = 2, + ) + + category = CAT_VAMPIRE + crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND | CRAFT_MUST_BE_LEARNED + +/datum/crafting_recipe/bloodthrone + name = "Blood Throne" + result = /obj/structure/vampire/bloodthrone + time = 5 SECONDS + + reqs = list( + /obj/item/stack/sheet/iron = 10, + /obj/item/stack/rods = 2, + ) + + category = CAT_VAMPIRE + crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND | CRAFT_MUST_BE_LEARNED + +/datum/crafting_recipe/meatcoffin + name = "Meat Coffin" + result = /obj/structure/closet/crate/coffin/meatcoffin + tool_behaviors = list(TOOL_KNIFE, TOOL_ROLLINGPIN) + reqs = list( + /obj/item/food/meat/slab = 5, + /obj/item/restraints/handcuffs/cable = 1, + ) + time = 15 SECONDS + category = CAT_STRUCTURE + crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND | CRAFT_MUST_BE_LEARNED + +/datum/crafting_recipe/vassalrack + name = "Vassalization Rack" + result = /obj/structure/vampire/vassalrack + time = 5 SECONDS + + reqs = list( + /obj/item/stack/sheet/iron = 5, + /obj/item/stack/rods = 6, + ) + + category = CAT_VAMPIRE + crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND | CRAFT_MUST_BE_LEARNED + +/datum/crafting_recipe/candelabrum + name = "Candelabrum" + result = /obj/structure/vampire/candelabrum + time = 5 SECONDS + + reqs = list( + /obj/item/stack/sheet/iron = 1, + /obj/item/stack/rods = 3, + /obj/item/flashlight/flare/candle = 2, + ) + + category = CAT_VAMPIRE + crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND | CRAFT_MUST_BE_LEARNED + +/datum/crafting_recipe/bloodthrone + name = "Blood Throne" + result = /obj/structure/vampire/bloodthrone + time = 5 SECONDS + + reqs = list( + /obj/item/stack/sheet/iron = 10, + /obj/item/stack/rods = 2, + ) + + category = CAT_VAMPIRE + crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND | CRAFT_MUST_BE_LEARNED + +/datum/crafting_recipe/blackcoffin + name = "Black Coffin" + result = /obj/structure/closet/crate/coffin/blackcoffin + tool_behaviors = list(TOOL_WELDER, TOOL_SCREWDRIVER) + reqs = list( + /obj/item/stack/sheet/cloth = 1, + /obj/item/stack/sheet/mineral/wood = 5, + /obj/item/stack/sheet/iron = 1, + ) + time = 15 SECONDS + category = CAT_STRUCTURE + +/datum/crafting_recipe/securecoffin + name = "Secure Coffin" + result = /obj/structure/closet/crate/coffin/securecoffin + tool_behaviors = list(TOOL_WELDER, TOOL_SCREWDRIVER) + reqs = list( + /obj/item/stack/rods = 1, + /obj/item/stack/sheet/plasteel = 5, + /obj/item/stack/sheet/iron = 5, + ) + time = 15 SECONDS + category = CAT_STRUCTURE + +/datum/crafting_recipe/metalcoffin + name = "Metal Coffin" + result = /obj/structure/closet/crate/coffin/metalcoffin + reqs = list( + /obj/item/stack/sheet/iron = 6, + /obj/item/stack/rods = 2, + ) + time = 10 SECONDS + category = CAT_STRUCTURE diff --git a/tff_modular/modules/vampire/datum_vampire.dm b/tff_modular/modules/vampire/datum_vampire.dm new file mode 100644 index 00000000000..c4e46933296 --- /dev/null +++ b/tff_modular/modules/vampire/datum_vampire.dm @@ -0,0 +1,852 @@ +/datum/antagonist/vampire + name = "\improper Vampire" + roundend_category = "vampires" + antagpanel_category = "Vampire" + show_in_roundend = ROLE_VAMPIRE + ui_name = "AntagInfoVampire" + hijack_speed = 0.5 + stinger_sound = 'tff_modular/modules/vampire/sound/lunge_warn.ogg' + hud_icon = 'tff_modular/modules/vampire/icons/antag_hud.dmi' + antag_hud_name = "vampire" + preview_outfit = /datum/outfit/vampire_outfit + + hijack_speed = 0 + + show_to_ghosts = TRUE + + /// How much blood we have, starting off at default blood levels. + /// We don't use our actual body's temperature because some species don't have blood and we don't want to exclude them + var/current_vitae = BLOOD_VOLUME_NORMAL + /// How much blood we can have at once, increases per level. + var/max_vitae = 600 + + /// The vampire team, used for vassals + var/datum/team/vampire/vampire_team + /// The vampire's clan + var/datum/vampire_clan/my_clan + /// Our disciplines + var/list/owned_disciplines = list() + + /// Timer between alerts for Burn messages + COOLDOWN_DECLARE(vampire_spam_sol_burn) + /// Timer between alerts for Healing messages + COOLDOWN_DECLARE(vampire_spam_healing) + + /// Should we automatically forge objectives? + var/should_forge_objectives = TRUE + + /// Flavor only + var/vampire_name + + /// Are we the prince? + var/prince = FALSE + /// Are we the scourge? Literally only used for the examine. Okay. + var/scourge = FALSE + /// Have we been broken the Masquerade? + var/broke_masquerade = FALSE + /// How many Masquerade Infractions do we have? + var/masquerade_infractions = 0 + /// Cooldown between masquerade infractions, so you can't have a bunch of them in the span of a single fight. + COOLDOWN_DECLARE(masquerade_infraction_cooldown) + + /// Have / are we embracing a new vampire? + /// If so, this will halve our max vassal count! + var/embracing = FALSE + + /// How many vampires we've diablerized, if any. + var/diablerie_count = 0 + + /// How many humanity points do we have? 0-10 + /// We actually always start with 7 and then add the clan's default humanity + var/humanity = VAMPIRE_DEFAULT_HUMANITY + + /// Blood required to enter Frenzy + var/frenzy_threshold = FRENZY_THRESHOLD_ENTER + /// If we've already alerted the player about low blood + var/low_blood_alerted = FALSE + /// Cooldown for re-entering frenzy after we exit it, to prevent potential spam/loops. + COOLDOWN_DECLARE(frenzy_cooldown) + + /// Goal of vitae required for the next level up + var/current_vitae_goal = VITAE_GOAL_STANDARD + /// progress to that goal + var/vitae_goal_progress = 0 + /// To keep track of objective + var/total_blood_drank = 0 + + /// Powers currently owned + var/list/datum/action/cooldown/vampire/powers = list() + + /// Vassals under my control. Periodically remove the dead ones. + var/list/datum/antagonist/vassal/vassals = list() + + /// The rank this vampire is at, used to level abilities and strength up + var/vampire_level = 0 + var/vampire_level_unspent = VAMPIRE_STARTING_LEVELS + /// How many more "free" levels this vampire will get. + var/free_levels_remaining = VAMPIRE_FREE_LEVELS + + /// If this guy has suffered final death. + var/final_death = FALSE + + /// Additional regeneration when the vampire has a lot of blood + var/additional_regen + /// How much damage the vampire heals each life tick. Increases per rank up + var/vampire_regen_rate = 0.3 + + /// Minimum cooldown when reviving. + COOLDOWN_DECLARE(revive_cooldown) + + /// How much more punch/kick damage the vampire gets per rank. + var/extra_damage_per_rank = VAMPIRE_UNARMED_DMG_INCREASE_ON_RANKUP + + /// Lair + var/area/vampire_lair_area + var/obj/structure/closet/crate/coffin + + /// Blood display HUD + var/atom/movable/screen/vampire/blood_counter/blood_display + /// Vampire level display HUD + var/atom/movable/screen/vampire/rank_counter/vamprank_display + /// Vampire humanity display HUD + var/atom/movable/screen/vampire/humanity_counter/humanity_display + + /// Tracker so that vassals know where their master is + var/obj/effect/abstract/vampire_tracker_holder/tracker + + /// List of limbs we've applied modifications to. + var/list/affected_limbs = list( + BODY_ZONE_L_ARM = null, + BODY_ZONE_R_ARM = null, + BODY_ZONE_L_LEG = null, + BODY_ZONE_R_LEG = null, + BODY_ZONE_HEAD = null, + BODY_ZONE_CHEST = null, + ) + + /// Static typecache of all vampire powers. + var/static/list/all_vampire_powers = typecacheof(/datum/action/cooldown/vampire, ignore_root_path = TRUE) + /// Antagonists that cannot be vassalized no matter what + var/static/list/vassal_banned_antags = list( + /datum/antagonist/vampire, + /datum/antagonist/changeling, + /datum/antagonist/cult, + /datum/antagonist/clock_cultist, + ) + + /// List of traits that the Masquerade ability does not remove. + var/static/list/always_traits = list( + TRAIT_DRINKS_BLOOD, + TRAIT_GENELESS, // prevents vamps from having genes at all. masquerade will work around this being an antag test with TRAIT_FAKEGENES + TRAIT_NO_DNA_COPY, // no, you can't cheat your curse with a cloner. + TRAIT_NO_MINDSWAP, // mindswapping vampires is buggy af and I'm too lazy to properly fix it. ~Absolucy + ) + + /// List of traits applied inherently + var/static/list/vampire_traits = list( + TRAIT_AGEUSIA, + TRAIT_HARDLY_WOUNDED, + TRAIT_NOBREATH, + TRAIT_NOCRITDAMAGE, + TRAIT_NOHARDCRIT, + TRAIT_NOSOFTCRIT, + TRAIT_NO_MIRROR_REFLECTION, + TRAIT_RADIMMUNE, + TRAIT_RESISTCOLD, + TRAIT_SLEEPIMMUNE, + TRAIT_STABLEHEART, + TRAIT_STABLELIVER, + TRAIT_TOXIMMUNE, + TRAIT_VIRUSIMMUNE, + // they eject zombie tumors and xeno larvae during eepy time anyways + TRAIT_NO_ZOMBIFY, // they're already undead lol + TRAIT_XENO_IMMUNE, // something something facehuggers only latch onto living things + ) + + /// Humanity gain tracking, when adding more, remember to add the type define + var/humanity_petting_goal = 5 + var/humanity_art_goal = 2 + var/humanity_hugging_goal = 3 + var/list/humanity_trackgain_hugged = list() + var/list/humanity_trackgain_petted = list() + var/list/humanity_trackgain_art = list() + +/datum/antagonist/vampire/proc/create_vampire_team() + vampire_team = new(owner) + vampire_team.name = "[ADMIN_LOOKUP(owner.current)]'s vampire team" // only displayed to admins + vampire_team.master_vampire = src + +/datum/team/vampire + name = "vampire team" + var/datum/antagonist/vampire/master_vampire + +/datum/team/vampire/roundend_report() + return + +/** + * Apply innate effects is everything given to the mob + * When a body is tranferred, this is called on the new mob + * while on_gain is called ONCE per ANTAG, this is called ONCE per BODY. + */ +/datum/antagonist/vampire/apply_innate_effects(mob/living/mob_override) + . = ..() + var/mob/living/current_mob = mob_override || owner.current + RegisterSignals(current_mob, list(COMSIG_MOB_LOGIN, COMSIG_MOVABLE_Z_CHANGED), PROC_REF(on_login)) + RegisterSignal(current_mob, COMSIG_LIVING_LIFE, PROC_REF(life_tick)) + RegisterSignal(current_mob, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) + RegisterSignal(current_mob, COMSIG_ATOM_AFTER_EXPOSE_REAGENTS, PROC_REF(after_expose_reagents)) + RegisterSignal(current_mob, COMSIG_LIVING_DEATH, PROC_REF(on_death)) + RegisterSignal(current_mob, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved)) + RegisterSignal(current_mob, COMSIG_HUMAN_ON_HANDLE_BLOOD, PROC_REF(handle_blood)) + RegisterSignal(current_mob, COMSIG_MOB_UPDATE_SIGHT, PROC_REF(on_update_sight)) + + RegisterSignal(current_mob, COMSIG_LIVING_PET_ANIMAL, PROC_REF(on_pet_animal)) + RegisterSignal(current_mob, COMSIG_LIVING_HUG_CARBON, PROC_REF(on_hug_carbon)) + RegisterSignal(current_mob, COMSIG_LIVING_APPRAISE_ART, PROC_REF(on_appraise_art)) + + handle_clown_mutation(current_mob, "Your clownish nature has been subdued by your thirst for blood.") + + current_mob.update_sight() + current_mob.clear_mood_event("vampcandle") + + add_team_hud(current_mob) + + current_mob.faction += FACTION_VAMPIRE + + if(current_mob.hud_used) + on_hud_created() + else + RegisterSignal(current_mob, COMSIG_MOB_HUD_CREATED, PROC_REF(on_hud_created)) + + ensure_brain_nonvital(current_mob) + setup_limbs(current_mob) + setup_tracker(current_mob) + + if(ishuman(current_mob)) + var/mob/living/carbon/human/current_human = current_mob + current_human.physiology?.stamina_mod *= VAMPIRE_INHERENT_STAMINA_RESIST + + current_mob.has_dna()?.remove_all_mutations() + current_mob.add_traits(vampire_traits + always_traits, TRAIT_VAMPIRE) + + current_mob.grant_language(/datum/language/vampiric, source = LANGUAGE_VAMPIRE) + + my_clan?.apply_effects(current_mob) + +/** + * Remove innate effects is everything given to the mob + * When a body is tranferred, this is called on the old mob. + * while on_removal is called ONCE per ANTAG, this is called ONCE per BODY. +**/ +/datum/antagonist/vampire/remove_innate_effects(mob/living/mob_override) + . = ..() + var/mob/living/current_mob = mob_override || owner.current + UnregisterSignal(current_mob, list( + COMSIG_MOB_LOGIN, + COMSIG_MOVABLE_Z_CHANGED, + COMSIG_LIVING_LIFE, + COMSIG_ATOM_EXAMINE, + COMSIG_ATOM_AFTER_EXPOSE_REAGENTS, + COMSIG_LIVING_DEATH, + COMSIG_MOVABLE_MOVED, + COMSIG_HUMAN_ON_HANDLE_BLOOD, + COMSIG_MOB_UPDATE_SIGHT, + COMSIG_LIVING_PET_ANIMAL, + COMSIG_LIVING_HUG_CARBON, + COMSIG_LIVING_APPRAISE_ART, + )) + current_mob.update_sight() + current_mob.remove_traits(vampire_traits + always_traits, TRAIT_VAMPIRE) + + handle_clown_mutation(current_mob, removing = FALSE) + + cleanup_limbs(current_mob) + cleanup_tracker() + + remove_hud_elements(current_mob) + QDEL_NULL(blood_display) + QDEL_NULL(vamprank_display) + QDEL_NULL(humanity_display) + + current_mob.faction -= FACTION_VAMPIRE + + if(ishuman(current_mob)) + var/mob/living/carbon/human/current_human = current_mob + current_human.physiology?.stamina_mod /= VAMPIRE_INHERENT_STAMINA_RESIST + + if(!QDELETED(current_mob)) + my_clan?.remove_effects(current_mob) + +/datum/antagonist/vampire/proc/remove_hud_elements(mob/living/current_mob) + var/datum/hud/hud_used = current_mob?.hud_used + if(hud_used) + hud_used.infodisplay -= blood_display + hud_used.infodisplay -= vamprank_display + hud_used.infodisplay -= humanity_display + var/client/current_client = current_mob?.client + if(current_client) + current_client?.screen -= blood_display + current_client?.screen -= vamprank_display + current_client?.screen -= humanity_display + +/datum/antagonist/vampire/proc/on_hud_created(datum/source) + SIGNAL_HANDLER + var/datum/hud/vampire_hud = owner.current.hud_used + + blood_display = new /atom/movable/screen/vampire/blood_counter(null, vampire_hud) + vampire_hud.infodisplay += blood_display + + vamprank_display = new /atom/movable/screen/vampire/rank_counter(null, vampire_hud) + vampire_hud.infodisplay += vamprank_display + + humanity_display = new /atom/movable/screen/vampire/humanity_counter(null, vampire_hud) + vampire_hud.infodisplay += humanity_display + + vampire_hud.show_hud(vampire_hud.hud_version) + UnregisterSignal(owner.current, COMSIG_MOB_HUD_CREATED) + +/datum/antagonist/vampire/get_admin_commands() + . = ..() + .["Level Add"] = CALLBACK(src, PROC_REF(rank_up), 1) + + if(vampire_level_unspent > 0) + .["Level Deduct"] = CALLBACK(src, PROC_REF(rank_down)) + + if(!broke_masquerade) + .["Break Masq"] = CALLBACK(src, PROC_REF(break_masquerade)) + .["Add Infraction"] = CALLBACK(src, PROC_REF(give_masquerade_infraction), TRUE) + + if(humanity > 0) + .["Humanity Deduct"] = CALLBACK(src, PROC_REF(adjust_humanity), -1, FALSE) + else if(humanity < 10) + .["Humanity Add"] = CALLBACK(src, PROC_REF(adjust_humanity), 1, FALSE) + +/datum/antagonist/vampire/on_gain() + . = ..() + ADD_TRAIT(owner, TRAIT_VAMPIRE_ALIGNED, REF(src)) + + RegisterSignal(src, COMSIG_VAMPIRE_TRACK_HUMANITY_GAIN, PROC_REF(on_track_humanity_gain_signal)) + + owner.teach_crafting_recipe(list( + /datum/crafting_recipe/vassalrack, + /datum/crafting_recipe/candelabrum, + /datum/crafting_recipe/bloodthrone, + /datum/crafting_recipe/meatcoffin, + )) + + // Set name and reputation + select_first_name() + + // Objectives + if(should_forge_objectives) + forge_objectives() + + create_vampire_team() + + // Assign starting stats skill point. + give_starting_powers() + GLOB.all_vampires += src + SSvampire_leveling.check_enable() + + // Start society if we're the first vampire + check_start_society() + + if(!QDELETED(owner.current)) + for(var/quirk_type in typesof(/datum/quirk/item_quirk/addict/junkie) + /datum/quirk/skittish) + owner.current.remove_quirk(quirk_type) + +#ifdef VAMPIRE_TESTING + var/turf/user_loc = get_turf(owner.current) + new /obj/structure/closet/crate/coffin(user_loc) + new /obj/structure/vampire/vassalrack(user_loc) +#endif + +/datum/antagonist/vampire/on_removal() + REMOVE_TRAIT(owner, TRAIT_VAMPIRE_ALIGNED, REF(src)) + + owner.forget_crafting_recipe(list( + /datum/crafting_recipe/vassalrack, + /datum/crafting_recipe/candelabrum, + /datum/crafting_recipe/bloodthrone, + /datum/crafting_recipe/meatcoffin, + )) + + clear_powers_and_stats() + GLOB.all_vampires -= src + SSvampire_leveling.check_enable() + check_cancel_society() + + if(iscarbon(owner.current)) + var/mob/living/carbon/carbon_owner = owner.current + var/obj/item/organ/brain/not_vamp_brain = carbon_owner.get_organ_slot(ORGAN_SLOT_BRAIN) + if(not_vamp_brain && (not_vamp_brain.decoy_override != initial(not_vamp_brain.decoy_override))) + not_vamp_brain.organ_flags |= ORGAN_VITAL + not_vamp_brain.decoy_override = FALSE + + return ..() + +/datum/antagonist/vampire/on_body_transfer(mob/living/old_body, mob/living/new_body) + . = ..() + + // Transfer powers + for(var/datum/action/cooldown/vampire/all_powers in powers) + if(old_body) + all_powers.Remove(old_body) + all_powers.Grant(new_body) + + // Vampire Traits + old_body?.remove_traits(vampire_traits + always_traits, TRAIT_VAMPIRE) + new_body.add_traits(vampire_traits + always_traits, TRAIT_VAMPIRE) + +/datum/antagonist/vampire/greet() + if(silent) + return + var/fullname = return_full_name() + var/list/msg = list() + + msg += span_cult_large("You are a Vampire!\n") + msg += span_cult("Open the Vampire Information panel for information about your Powers, Clan, and more. \n\n\ + You can also click on all of your hud meters for more information about them!") + + to_chat(owner, boxed_message(msg.Join("\n"))) + play_stinger() + + if(should_forge_objectives) + owner.announce_objectives() + antag_memory += "Although you were born a mortal, in undeath you earned the name [fullname].
    " + +/datum/antagonist/vampire/farewell() + to_chat(owner.current, span_userdanger("With a snap, your curse has ended. You are no longer a Vampire. You live once more!")) + // Refill with Blood so they don't instantly die. + if(!HAS_TRAIT(owner.current, TRAIT_NOBLOOD)) + owner.current.blood_volume = max(owner.current.blood_volume, BLOOD_VOLUME_NORMAL) + +// Called when using admin tools to give antag status +/datum/antagonist/vampire/admin_add(datum/mind/new_owner, mob/admin) + var/levels = input("How many unspent Ranks would you like [new_owner] to have?","Vampire Rank", vampire_level_unspent) as null | num + var/msg = "made [key_name_admin(new_owner)] into \a [name]" + if(levels > 0) + vampire_level_unspent = levels + msg += " with [levels] extra unspent Ranks." + message_admins("[key_name_admin(usr)] [msg]") + log_admin("[key_name(usr)] [msg]") + new_owner.add_antag_datum(src) + +/datum/antagonist/vampire/ui_static_data(mob/user) + . = ..() + + //we don't need to update this that much. + .["in_clan"] = !!my_clan + var/list/clan_data = list() + if(my_clan) + clan_data["name"] = my_clan.name + clan_data["description"] = my_clan.description + clan_data["icon"] = my_clan.join_icon + clan_data["icon_state"] = my_clan.join_icon_state + + .["clan"] += list(clan_data) + + for(var/datum/action/cooldown/vampire/power as anything in powers) + var/list/power_data = list() + + power_data["name"] = power.name + power_data["explanation"] = power.power_explanation + power_data["icon"] = power.background_icon + power_data["icon_state"] = power.button_icon_state + + power_data["cost"] = power.vitaecost ? power.vitaecost : "0" + power_data["constant_cost"] = power.constant_vitaecost ? power.constant_vitaecost : "0" + power_data["cooldown"] = power.cooldown_time / 10 + + .["powers"] += list(power_data) + +/datum/antagonist/vampire/get_preview_icon() + var/icon/final_icon = render_preview_outfit(/datum/outfit/vampire_outfit) + var/icon/blood_icon = icon('icons/effects/blood.dmi', "suitblood") + blood_icon.Blend(BLOOD_COLOR_RED, ICON_MULTIPLY) + final_icon.Blend(blood_icon, ICON_OVERLAY) + + return finish_preview_icon(final_icon) + +/datum/antagonist/vampire/roundend_report() + var/list/report = list() + + // Vamp name + report += "
    [span_header(return_full_name())]" + report += printplayer(owner) + if(my_clan) + report += "They were part of the [my_clan.name]!" + + // Default Report + var/objectives_complete = TRUE + if(length(objectives)) + report += printobjectives(objectives) + for(var/datum/objective/objective in objectives) + if(!objective.check_completion()) + objectives_complete = FALSE + break + + // Now list their vassals + if(length(vassals)) + report += span_header("
    Their vassals were...") + for(var/datum/antagonist/vassal/vassal in vassals) + if(!vassal.owner) + continue + + var/list/vassal_report = list() + vassal_report += "[vassal.owner.name]" + + if(vassal.owner.assigned_role) + vassal_report += " the [vassal.owner.assigned_role.title]" + report += vassal_report.Join() + + if(objectives_complete) + report += span_greentext(span_big("
    The [name] was successful!")) + else + report += span_redtext(span_big("
    The [name] has failed!")) + + return report.Join("
    ") + +/datum/antagonist/vampire/hijack_speed() + . = ..() + if(istype(my_clan, /datum/vampire_clan/malkavian)) // the voices told them to do it + return max(., 1) + +/// "Oh, well, that's step one. What about two through ten?" +/// Beheading vampires is kinda buggy and results in them being dead-dead without actually being final deathed, which is NOT something that's desired. +/// Just stake them. No shortcuts. +/datum/antagonist/vampire/proc/ensure_brain_nonvital(mob/living/mob_override) + var/mob/living/carbon/carbon_owner = mob_override || owner.current + if(!iscarbon(carbon_owner)) + return + var/obj/item/organ/brain/brain = carbon_owner.get_organ_slot(ORGAN_SLOT_BRAIN) + if(QDELETED(brain)) + return + brain.organ_flags &= ~ORGAN_VITAL + brain.decoy_override = TRUE + + +/datum/antagonist/vampire/proc/give_starting_powers() + for(var/datum/action/cooldown/vampire/all_powers as anything in all_vampire_powers) + if(!(initial(all_powers.special_flags) & VAMPIRE_DEFAULT_POWER)) + continue + grant_power(new all_powers) + +/** + * ##clear_power_and_stats() + * + * Removes all Vampire related Powers/Stats changes, setting them back to pre-Vampire + * Order of steps and reason why: + * Remove clan - Clans like Nosferatu give Powers on removal, we have to make sure this is given before removing Powers. + * Powers - Remove all Powers, so things like Masquerade are off. + * Species traits, Traits, MaxHealth, Language - Misc stuff, has no priority. + * Organs - At the bottom to ensure everything that changes them has reverted themselves already. + * Update Sight - Done after Eyes are regenerated. + */ +/datum/antagonist/vampire/proc/clear_powers_and_stats() + var/mob/living/carbon/user = owner.current + + // Remove clan first + if(my_clan) + my_clan.remove_effects(user) + QDEL_NULL(my_clan) + + // Powers + for(var/datum/action/cooldown/vampire/all_powers as anything in powers) + remove_power(all_powers) + + /// Stats + if(ishuman(owner.current)) + var/mob/living/carbon/human/human_user = user + human_user.physiology.stamina_mod /= VAMPIRE_INHERENT_STAMINA_RESIST + + // Remove all vampire traits + user.remove_traits(vampire_traits + always_traits, TRAIT_VAMPIRE) + + // Update Health + user.setMaxHealth(initial(user.maxHealth)) + + // Language + user.remove_language(/datum/language/vampiric, source = LANGUAGE_VAMPIRE) + + // Heart + var/obj/item/organ/heart/newheart = user.get_organ_slot(ORGAN_SLOT_HEART) + newheart?.beating = initial(newheart.beating) + +/datum/antagonist/vampire/proc/claim_coffin(obj/structure/closet/crate/claimed) + var/static/list/banned_areas_typecache + if(isnull(banned_areas_typecache)) + banned_areas_typecache = typecacheof(list( + /area/icemoon, + /area/lavaland, + /area/ocean, + /area/space, + )) + + // ALREADY CLAIMED + if(claimed.resident) + if(claimed.resident == owner) + to_chat(owner, span_notice("This is your [claimed].")) + else + to_chat(owner, span_warning("This [claimed] has already been claimed by another.")) + return FALSE + var/turf/coffin_turf = get_turf(claimed) + var/area/current_area = get_area(coffin_turf) + // this if check is split up bc it's annoying to read and mentally parse when it's combined into one big if statement + var/valid_lair_area = TRUE + if(!coffin_turf) + valid_lair_area = FALSE + else if(!(current_area.area_flags & ALWAYS_VALID_VAMPIRE_LAIR)) + if(is_type_in_typecache(current_area, banned_areas_typecache) || (istype(current_area, /area/ruin) && current_area.outdoors)) + valid_lair_area = FALSE + if(!valid_lair_area) + claimed.balloon_alert(owner.current, "ineligible area!") + return + // This is my Lair + coffin = claimed + coffin.resident = owner + vampire_lair_area = current_area + + if(!(locate(/datum/action/cooldown/vampire/gohome) in powers)) + grant_power(new /datum/action/cooldown/vampire/gohome) + + to_chat(owner, span_userdanger("You have claimed [claimed] as your place of immortal rest! Your lair is now [vampire_lair_area].")) + return TRUE + +/// Name shown on antag list +/datum/antagonist/vampire/antag_listing_name() + return ..() + return_full_name() + +/datum/action/antag_info/vampire + name = "Vampire Guide" + background_icon = 'tff_modular/modules/vampire/icons/actions_vampire.dmi' + background_icon_state = "vamp_power_off" + +/datum/antagonist/vampire/make_info_button() + if(!ui_name) + return + var/datum/action/antag_info/vampire/info_button = new(src) + info_button.Grant(owner.current) + info_button_ref = WEAKREF(info_button) + return info_button + +/datum/antagonist/vampire/add_team_hud(mob/target, antag_to_check, passed_hud_keys) + if(broke_masquerade) + antag_hud_name = "masquerade_broken" + else if(scourge) + antag_hud_name = "scourge" + else if(prince) + antag_hud_name = "prince" + else + antag_hud_name = my_clan?.antag_hud_icon || initial(antag_hud_name) + + QDEL_NULL(team_hud_ref) + + var/datum/atom_hud/alternate_appearance/basic/has_antagonist/hud = target.add_alt_appearance( + /datum/atom_hud/alternate_appearance/basic/has_antagonist, + "antag_team_hud_[REF(src)]", + hud_image_on(target), + ) + team_hud_ref = WEAKREF(hud) + + var/list/mob/living/mob_list = list() + for(var/datum/antagonist/antag as anything in GLOB.antagonists) + if(!istype(antag, /datum/antagonist/vampire) && !istype(antag, /datum/antagonist/vassal)) + continue + var/mob/living/current = antag.owner?.current + if(!QDELETED(current)) + mob_list |= current + + for (var/datum/atom_hud/alternate_appearance/basic/has_antagonist/antag_hud as anything in GLOB.has_antagonist_huds) + if(!(antag_hud.target in mob_list)) + continue + antag_hud.show_to(target) + hud.show_to(antag_hud.target) + + +/** + * Every vampire has 3 starting objective categories: + * Ego: Grow more powerful / strengthen your position / etc + * Hedonism: Indulge in bad things that feel all too right. + * Survival: Survive. Obviously. + */ +/datum/antagonist/vampire/forge_objectives() + var/datum/objective/vampire/extra_objective + + if(prob(80)) + extra_objective = new /datum/objective/vampire/ego/vassals + else + extra_objective = new /datum/objective/vampire/ego/department_vassal + + extra_objective.owner = owner + objectives += extra_objective + + //pick Hedonism objective + switch(rand(1, 2)) + if(1) + extra_objective = new /datum/objective/vampire/hedonism/gourmand + if(2) + extra_objective = new /datum/objective/vampire/hedonism/thirster + + extra_objective.owner = owner + objectives += extra_objective + + // Survive Objective + var/datum/objective/survive/vampire/survive_objective = new + survive_objective.owner = owner + objectives += survive_objective + +/// Use this instead of `length(vassals)`, as it won't count round removed vassals and such. +/datum/antagonist/vampire/proc/count_vassals(only_living = FALSE) + . = 0 + for(var/datum/antagonist/vassal/vassal as anything in vassals) + var/mob/living/vassal_body = vassal.owner.current + if(QDELETED(vassal_body)) + continue + if(only_living && !considered_alive(vassal.owner)) + continue + if(!HAS_TRAIT(vassal_body, TRAIT_MIND_TEMPORARILY_GONE)) + if(vassal_body.stat == DEAD) + if(HAS_TRAIT(vassal_body, TRAIT_DEFIB_BLACKLISTED)) + continue + if(!vassal_body.key) + var/mob/dead/observer/vassal_ghost = vassal_body.get_ghost(TRUE, TRUE) + if(isnull(vassal_ghost) || (istype(vassal_ghost) && !vassal_ghost.can_reenter_corpse)) // soulcatcher shitcode workaround + continue + else if(!vassal_body.key) + continue + .++ + +/datum/antagonist/vampire/proc/on_examine(datum/source, mob/examiner, list/examine_text) + SIGNAL_HANDLER + var/text + if(prince) + text = " " + else if(scourge) + text = " " + else + text = " " + + if(IS_VASSAL(examiner) in vassals) + text += span_cult("This is, [return_full_name()] your Master!") + examine_text += text + return + + if(HAS_MIND_TRAIT(examiner, TRAIT_VAMPIRE_ALIGNED)) + + if(my_clan) + text += span_cult("[return_full_name()], of the [my_clan].") + else + text += span_cult("[return_full_name()], a disgusting caitiff thinblood.") + + if(examiner != owner.current) // So many ifs. where is yanderedev. + if(scourge) + text += span_cult_large("
    [owner.current.p_They()] [owner.current.p_are()] the Scourge!") + if(prince) + text += span_cult_large("
    [owner.current.p_They()] [owner.current.p_are()] your Prince!") + if(broke_masquerade) + text += span_cult_large("
    You recognize [owner.current.p_them(TRUE)] as a masquerade breaker!") + + examine_text += text + + if(diablerie_count > 0 && HAS_TRAIT(examiner, TRAIT_SEE_DIABLERIE)) + examine_text += span_cult_large("
    You can see the corrupted marks of a diablerist in [owner.current.p_their()] aura!") + +/datum/antagonist/vampire/proc/on_moved(datum/source) + SIGNAL_HANDLER + + var/mob/living/current = owner?.current + if(QDELETED(current)) + return + + tracker?.tracking_beacon?.update_position() + +/datum/antagonist/vampire/proc/setup_limbs(mob/living/carbon/target) + if(!iscarbon(target)) + return + RegisterSignal(target, COMSIG_CARBON_POST_ATTACH_LIMB, PROC_REF(register_limb)) + RegisterSignal(target, COMSIG_CARBON_POST_REMOVE_LIMB, PROC_REF(unregister_limb)) + for(var/body_part in affected_limbs) + var/obj/item/bodypart/limb = target.get_bodypart(check_zone(body_part)) + if(limb) + register_limb(target, limb, initial = TRUE) + +/datum/antagonist/vampire/proc/cleanup_limbs(mob/living/carbon/target) + if(!iscarbon(target)) + return + UnregisterSignal(target, list(COMSIG_CARBON_POST_ATTACH_LIMB, COMSIG_CARBON_POST_REMOVE_LIMB)) + for(var/body_part in affected_limbs) + var/obj/item/bodypart/limb = target.get_bodypart(check_zone(body_part)) + if(limb) + unregister_limb(target, limb) + +/datum/antagonist/vampire/proc/register_limb(mob/living/carbon/owner, obj/item/bodypart/new_limb, special, initial = FALSE) + SIGNAL_HANDLER + + affected_limbs[new_limb.body_zone] = new_limb + RegisterSignal(new_limb, COMSIG_QDELETING, PROC_REF(limb_gone)) + + // if the limb has reduced burn damage, offset that. + if(initial(new_limb.burn_modifier) < 1) + new_limb.burn_modifier /= initial(new_limb.burn_modifier) + + if(new_limb.body_zone in BODY_ZONES_LIMBS) + var/extra_damage = 1 + (vampire_level * extra_damage_per_rank) + new_limb.unarmed_damage_low += extra_damage + new_limb.unarmed_damage_high += extra_damage + +/datum/antagonist/vampire/proc/unregister_limb(mob/living/carbon/owner, obj/item/bodypart/lost_limb, special) + SIGNAL_HANDLER + + affected_limbs[lost_limb.body_zone] = null + UnregisterSignal(lost_limb, COMSIG_QDELETING) + + // undo any offset we've done to reduce limb burn damage. + if(initial(lost_limb.burn_modifier) < 1) + lost_limb.burn_modifier *= initial(lost_limb.burn_modifier) + + if(lost_limb.body_zone in BODY_ZONES_LIMBS) + var/extra_damage = 1 + (vampire_level / extra_damage_per_rank) + // safety measure in case we ever accidentally fuck up the math or something + lost_limb.unarmed_damage_low = max(lost_limb.unarmed_damage_low - extra_damage, initial(lost_limb.unarmed_damage_low)) + lost_limb.unarmed_damage_high = max(lost_limb.unarmed_damage_high - extra_damage, initial(lost_limb.unarmed_damage_high)) + +/datum/antagonist/vampire/proc/limb_gone(obj/item/bodypart/deleted_limb) + SIGNAL_HANDLER + if(affected_limbs[deleted_limb.body_zone]) + affected_limbs[deleted_limb.body_zone] = null + UnregisterSignal(deleted_limb, COMSIG_QDELETING) + +/datum/antagonist/vampire/proc/after_expose_reagents(mob/source_mob, list/reagents, datum/reagents/source, methods = TOUCH, volume_modifier = 1, show_message = TRUE) + SIGNAL_HANDLER + var/datum/reagent/blood/blood_reagent = locate() in reagents + if(!blood_reagent) + return + var/blood_volume = round(reagents[blood_reagent], 0.1) + if(blood_volume > 0) + adjust_blood_volume(blood_volume) + +/datum/antagonist/vampire/proc/on_login() + SIGNAL_HANDLER + var/mob/living/current = owner.current + if(!QDELETED(current)) + addtimer(CALLBACK(src, TYPE_PROC_REF(/datum/antagonist, add_team_hud), current), 0.5 SECONDS, TIMER_OVERRIDE | TIMER_UNIQUE) //i don't trust this to not act weird + +/datum/antagonist/vampire/proc/on_update_sight(mob/user) + SIGNAL_HANDLER + user.add_sight(SEE_MOBS) + user.lighting_cutoff = max(user.lighting_cutoff, LIGHTING_CUTOFF_HIGH) + user.lighting_color_cutoffs = user.lighting_color_cutoffs ? blend_cutoff_colors(user.lighting_color_cutoffs, list(25, 8, 5)) : list(25, 8, 5) + +/datum/outfit/vampire_outfit + name = "Vampire outfit (Preview only)" + suit = /obj/item/clothing/suit/costume/dracula + +/datum/outfit/vampire_outfit/post_equip(mob/living/carbon/human/enrico, visualsOnly=FALSE) + enrico.hairstyle = "Undercut" + enrico.hair_color = "FFF" + enrico.skin_tone = "african2" + enrico.eye_color_left = "#663300" + enrico.eye_color_right = "#663300" + + enrico.update_body(is_creating = TRUE) diff --git a/tff_modular/modules/vampire/effects.dm b/tff_modular/modules/vampire/effects.dm new file mode 100644 index 00000000000..49b0f8069c5 --- /dev/null +++ b/tff_modular/modules/vampire/effects.dm @@ -0,0 +1,187 @@ +/// Blood drip subtype meant to be thrown around as a particle +/obj/effect/decal/cleanable/blood/particle + name = "blood droplet" + icon_state = "drip5" //using drip5 since the others tend to blend in with pipes & wires. + random_icon_states = list("drip1","drip2","drip3","drip4","drip5") + plane = GAME_PLANE + layer = BELOW_MOB_LAYER + bloodiness = BLOOD_AMOUNT_PER_DECAL * 0.2 + mergeable_decal = FALSE + /// Splatter type we create when we bounce on the floor + var/obj/effect/decal/cleanable/splatter_type_floor = /obj/effect/decal/cleanable/blood/splatter/stacking + /// Splatter type we create when we bump on a wall + var/obj/effect/decal/cleanable/splatter_type_wall = /obj/effect/decal/cleanable/blood/splatter/over_window + /// Whether or not we transfer our pixel_x and pixel_y to the splatter, only works for floor splatters though + var/messy_splatter = TRUE + +/obj/effect/decal/cleanable/blood/particle/Initialize(mapload) + . = ..() + if(QDELETED(loc)) + return INITIALIZE_HINT_QDEL + +/obj/effect/decal/cleanable/blood/particle/can_bloodcrawl_in() + return FALSE + +/obj/effect/decal/cleanable/blood/particle/proc/start_movement(movement_angle) + get_or_init_physics()?.set_angle(movement_angle) + +/obj/effect/decal/cleanable/blood/particle/proc/get_or_init_physics() as /datum/component/movable_physics + RETURN_TYPE(/datum/component/movable_physics) + if(QDELETED(src)) + return + return LoadComponent(/datum/component/movable_physics, \ + horizontal_velocity = rand(3 * 100, 5.5 * 100) * 0.01, \ + vertical_velocity = rand(4 * 100, 4.5 * 100) * 0.01, \ + horizontal_friction = rand(0.05 * 100, 0.1 * 100) * 0.01, \ + vertical_friction = 10 * 0.05, \ + vertical_conservation_of_momentum = 0.1, \ + z_floor = 0, \ + bounce_callback = CALLBACK(src, PROC_REF(on_bounce)), \ + bump_callback = CALLBACK(src, PROC_REF(on_bump)), \ + ) + +/obj/effect/decal/cleanable/blood/particle/proc/on_bounce() + if(QDELETED(src)) + return + else if(!isturf(loc) || QDELING(loc) || !splatter_type_floor) + qdel(src) + return + + // xenoblood splatter check + // note: xenomorphs don't have actual DNA datums, but get_blood_dna_list() still returns list("UNKNOWN DNA" = blood.type) + // so yeah, blood_dna will be populated for xenomorphs + var/list/blood_dna = GET_ATOM_BLOOD_DNA(src) + var/is_xenoblood = FALSE + if(blood_dna) + for(var/dna_sample in blood_dna) + var/blood_type_value = blood_dna[dna_sample] + if(blood_type_value == "X*") + is_xenoblood = TRUE + break + var/datum/blood_type/blood = GLOB.blood_types[blood_type_value] + if(istype(blood, /datum/blood_type/xeno)) + is_xenoblood = TRUE + break + + var/obj/effect/decal/cleanable/splatter + if(is_xenoblood) + splatter = new /obj/effect/decal/cleanable/blood/xeno(loc) + if(blood_dna) + splatter.add_blood_DNA(blood_dna) + else if(!ispath(splatter_type_floor, /obj/effect/decal/cleanable/blood/splatter/stacking)) + splatter = new splatter_type_floor(loc) + splatter.color = color + if(messy_splatter) + splatter.pixel_x = src.pixel_x + splatter.pixel_y = src.pixel_y + else + var/obj/effect/decal/cleanable/blood/splatter/stacking/stacker = locate(splatter_type_floor) in loc + if(!stacker) + stacker = new splatter_type_floor(loc) + stacker.color = color + if(messy_splatter && length(stacker.splat_overlays)) + var/mutable_appearance/existing_appearance = stacker.splat_overlays[1] + existing_appearance.pixel_x = src.pixel_x + existing_appearance.pixel_y = src.pixel_y + stacker.bloodiness = src.bloodiness + stacker.update_appearance(UPDATE_ICON) + else + var/obj/effect/decal/cleanable/blood/splatter/stacking/other_splatter = new splatter_type_floor() + other_splatter.color = color + if(messy_splatter && length(other_splatter.splat_overlays)) + var/mutable_appearance/existing_appearance = other_splatter.splat_overlays[1] + existing_appearance.pixel_x = src.pixel_x + existing_appearance.pixel_y = src.pixel_y + other_splatter.bloodiness = src.bloodiness + other_splatter.handle_merge_decal(stacker) + qdel(other_splatter) + splatter = stacker + if(blood_dna && !is_xenoblood) + splatter.add_blood_DNA(blood_dna) + qdel(src) + +/obj/effect/decal/cleanable/blood/particle/proc/on_bump(atom/bumped_atom) + if(QDELETED(src) || !isturf(loc) || QDELING(loc) || QDELETED(bumped_atom) || !splatter_type_wall) + return + if(iswallturf(bumped_atom)) + //Adjust pixel offset to make splatters appear on the wall + var/obj/effect/decal/cleanable/blood/splatter/over_window/final_splatter = new splatter_type_wall(loc) + var/dir_to_wall = get_dir(src, bumped_atom) + final_splatter.pixel_x = (dir_to_wall & EAST ? world.icon_size : (dir_to_wall & WEST ? -world.icon_size : 0)) + final_splatter.pixel_y = (dir_to_wall & NORTH ? world.icon_size : (dir_to_wall & SOUTH ? -world.icon_size : 0)) + final_splatter.color = color + var/list/blood_dna = GET_ATOM_BLOOD_DNA(src) + if(blood_dna) + final_splatter.add_blood_DNA(blood_dna) + qdel(src) + else if(istype(bumped_atom, /obj/structure/window)) + var/obj/structure/window/the_window = bumped_atom + if(!the_window.fulltile) + return + var/obj/effect/decal/cleanable/blood/splatter/over_window/final_splatter = new splatter_type_wall() + final_splatter.forceMove(the_window) + final_splatter.color = color + the_window.vis_contents += final_splatter + qdel(src) + +/// subtype of splatter capable of doing proper "stacking" behavior +/obj/effect/decal/cleanable/blood/splatter/stacking + /// Maximum amount of blood overlays we can have visually + var/maximum_splats = 50 + /// Listing containing overlays of all the splatters we've merged with + var/list/splat_overlays = list() + +/obj/effect/decal/cleanable/blood/splatter/stacking/proc/add_splat_overlay(mutable_appearance/overlay) + splat_overlays |= overlay + var/excess_splats = length(splat_overlays) - maximum_splats + if(excess_splats > 0) + splat_overlays.Cut(1, excess_splats + 1) + update_appearance(UPDATE_OVERLAYS) + +/obj/effect/decal/cleanable/blood/splatter/stacking/Initialize(mapload, blood_color = LIGHT_COLOR_BLOOD_MAGIC) + color = blood_color + . = ..() + var/mutable_appearance/our_appearance = mutable_appearance(src.icon, src.icon_state) + our_appearance.color = src.color + our_appearance.pixel_x = src.pixel_x + our_appearance.pixel_y = src.pixel_y + icon_state = null + color = null + pixel_x = 0 + pixel_y = 0 + add_splat_overlay(our_appearance) + +/obj/effect/decal/cleanable/blood/splatter/stacking/Destroy() + splat_overlays = null + return ..() + +/obj/effect/decal/cleanable/blood/splatter/stacking/update_overlays() + . = ..() + . += splat_overlays + +/obj/effect/decal/cleanable/blood/splatter/stacking/handle_merge_decal(obj/effect/decal/cleanable/blood/splatter/stacking/merger) + . = ..() + merger.add_splat_overlay(splat_overlays) + +/obj/effect/decal/cleanable/blood/line + name = "blood line" + desc = "Raining blood, from a lacerated sky, bleeding its horror!" + icon_state = "line" + random_icon_states = null + base_name = "dried blood line" + dry_desc = "Creating my structure - Now I shall reign in blood!" + +/obj/effect/decal/cleanable/blood/line/Initialize(mapload, direction) + if(!isnull(direction)) + //has to be done before we call replace_decal() + setDir(direction) + return ..() + +/obj/effect/decal/cleanable/blood/line/replace_decal(obj/effect/decal/cleanable/merger) + . = ..() + if(!.) + return + //squirts of the same dir are redundant, but not if they're different + if(merger.dir != src.dir) + return FALSE + diff --git a/tff_modular/modules/vampire/frenzy_vampire.dm b/tff_modular/modules/vampire/frenzy_vampire.dm new file mode 100644 index 00000000000..771ca5b5159 --- /dev/null +++ b/tff_modular/modules/vampire/frenzy_vampire.dm @@ -0,0 +1,115 @@ +/** + * # Status effect + * + * This is the status effect given to Vampires in a Frenzy + * This deals with everything entering/exiting Frenzy is meant to deal with. + */ +/atom/movable/screen/alert/status_effect/frenzy + name = "Frenzy" + desc = "You are in a Frenzy! You are entirely Feral and, depending on your Clan, fighting for your life!" + icon = 'tff_modular/modules/vampire/icons/actions_vampire.dmi' + icon_state = "frenzy_alert" + alerttooltipstyle = "cult" + +/datum/status_effect/frenzy + id = "frenzy" + status_type = STATUS_EFFECT_UNIQUE + duration = STATUS_EFFECT_PERMANENT + tick_interval = 1 SECONDS + alert_type = /atom/movable/screen/alert/status_effect/frenzy + + /// The stored vampire antag datum + var/datum/antagonist/vampire/vampiredatum + + /// Traits given by frenzy. + var/static/list/frenzy_traits = list( + TRAIT_DISCOORDINATED_TOOL_USER, + TRAIT_FRENZY, + TRAIT_PUSHIMMUNE, + TRAIT_STRONG_GRABBER, + TRAIT_STUNIMMUNE, + ) + +/datum/status_effect/frenzy/Destroy() + . = ..() + vampiredatum = null + +/datum/status_effect/frenzy/on_apply() + var/mob/living/carbon/carbon_owner = owner + if(!iscarbon(carbon_owner)) + return FALSE + vampiredatum = IS_VAMPIRE(carbon_owner) + + ASSERT(!isnull(vampiredatum), "Frenzy status effect applied to a non-vampire!") + + if(vampiredatum.current_vitae >= FRENZY_THRESHOLD_EXIT) + return FALSE + + // Basic stuff + carbon_owner.add_movespeed_modifier(/datum/movespeed_modifier/frenzy_speed) + carbon_owner.add_client_colour(/datum/client_colour/bloodlust) + carbon_owner.uncuff() + carbon_owner.pulledby?.stop_pulling() + carbon_owner.adjust_stamina_loss(-200) + carbon_owner.SetAllImmobility(0) + carbon_owner.set_resting(FALSE, silent = TRUE, instant = TRUE) + + // Alert them + vampiredatum.disable_all_powers(forced = TRUE) + vampiredatum.adjust_humanity(-2) + to_chat(carbon_owner, span_userdanger("BLOOD! YOU NEED BLOOD NOW!")) + to_chat(carbon_owner, span_announce("* Vampire Tip: While in Frenzy, you instantly aggressively grab, have stun immunity, and cannot use any powers outside of Feed and Trespass (If you have it).")) + carbon_owner.balloon_alert(carbon_owner, "you enter a frenzy!") + carbon_owner.playsound_local(null, 'tff_modular/modules/vampire/sound/rage_increase.ogg', 100, FALSE, pressure_affected = FALSE) + + // Stamina modifier + if (ishuman(carbon_owner)) + var/mob/living/carbon/human/human_owner = carbon_owner + human_owner.physiology?.stamina_mod *= 0.4 + + // Traits + carbon_owner.add_traits(frenzy_traits, TRAIT_STATUS_EFFECT(id)) + + return TRUE + +/datum/status_effect/frenzy/on_remove() + var/mob/living/carbon/carbon_owner = owner + if(!iscarbon(carbon_owner)) + return + + COOLDOWN_START(vampiredatum, frenzy_cooldown, 30 SECONDS) + + // Basic stuff + carbon_owner.remove_movespeed_modifier(/datum/movespeed_modifier/frenzy_speed) + carbon_owner.remove_client_colour(/datum/client_colour/bloodlust) + + // Alert them + carbon_owner.balloon_alert(carbon_owner, "you come back to your senses.") + carbon_owner.playsound_local(null, 'tff_modular/modules/vampire/sound/rage_decrease.ogg', 100, FALSE, pressure_affected = FALSE) + + // Stamina modifier + if (ishuman(carbon_owner)) + var/mob/living/carbon/human/human_owner = carbon_owner + human_owner.physiology?.stamina_mod /= 0.4 + + // Traits + carbon_owner.remove_traits(frenzy_traits, TRAIT_STATUS_EFFECT(id)) + +/datum/status_effect/frenzy/tick() + var/mob/living/carbon/carbon_owner = owner + if(vampiredatum.current_vitae >= FRENZY_THRESHOLD_EXIT) + qdel(src) + return + carbon_owner.adjust_fire_loss(0.75) + carbon_owner.set_jitter_if_lower(10 SECONDS) + +/datum/status_effect/frenzy/get_examine_text() + return span_danger("[owner.p_They()] seem[owner.p_s()]... inhumane, and feral!") + +/datum/movespeed_modifier/frenzy_speed + blacklisted_movetypes = FLYING | FLOATING + multiplicative_slowdown = -0.1 // Might seem very low but at this point we are already slow as balls from hunger + +/atom/movable/screen/alert/status_effect/masquerade/MouseEntered(location,control,params) + desc = initial(desc) + return ..() diff --git a/tff_modular/modules/vampire/icons/64x64.dmi b/tff_modular/modules/vampire/icons/64x64.dmi new file mode 100644 index 0000000000000000000000000000000000000000..41a12a375c328035a56072cf1582743dd04d2447 GIT binary patch literal 8774 zcmZ{pRZyG_%&6Z*7g*fg-Q68p910YQ6fIWV9TtifEl$zW;$Ey2S)8H^6u08;4vU=c zoU8v_{FzLWi)1pHT;!Qatd7=eY)lGF006L6Rg`oA0Q6r7bb-9u96^4z4Z$;Fp^>$dB2>M})Q}eo7>J%uzgfa6_W{1#(QxlroR9sFYIX7l`h< zcF{ezA!T+25q1b@HC6a*0eP>zLG5&Hk&8yK8reT*t|mMaHc3R7X%}-6pzh$PGM|h^ zmeMDkGe*p}l^@|x$bBh)N+ARQ^d728^7?*@ zN6Y*!gz{vlYotUJWqQh<5mzcE>zs7*>#N+PYj|C#g)BV(w3o&ZfK3eM6(R- ziRBlkx2m;E!xso?$<@67=KSA9e{$fCtguEz?>WPUB1rh%MQxBe97$c~D(zOX^)A_z zWnpXe6|-6numAOicHAl!pT@B4k6*V#4NF@Anafujt`Mk=Lu&k@tga7mg#^hisTted z`j}bOJk-{EQJeZi)?4`V{--v2&o_f_ch;a3NJDv9CPMQ7TmyRO`f>WzLj|sV;LV!xBo^IFN*1m|pC72A!u2>C}A%$|1 zlH>i;@VR&&wM-V+!K(Xn;oCBFeFMsYZZ@HX5zDFL?;e4O9$77}A0q640mlKynOFCu zZRk2Jz~%N!M*Ht;y5x(}#Pup7uU~!Utcc7ZcrVB;vq}op9!&Ma=e{MiBdi`!CqrsO zNQdQko!mN-$Y#8R=A^-L(mEeFEH(^1?ipKkaw>KT&Rt*Y);zM3Sh&f7lisL{-pX`Y zf)cS&S)aQY`Cp7rA1Oa2K8AlC3=u{TMHnbSK>Bfnafp9>LeYOjrjqcgcE`w5qf=yv z`uGsEjyWhVk;W5z5z-y4?g7X4-MW6Yhz`-dER=5xQG*o|qEN%M8 z!|ao%wOgm%x%8~>dZAJ07GC#hd+BceqyNb-<>Nm?}f?bHCwvrAH4fLV%2aEqjElRSB_-K07#QFQqM(wxK(UJPf5wn1WSTi{3oaez^B#hx(IVpq!aWyv?ZL zQN=w`F|SprBthiTST9Wshnf$c`aIv{95?Wbh$Lf78ZC~Dya{$bo)z&m7@blfL$&k7 z7%nEPJtK-ZlmcTKn59!itMnBAGLaI)#m8Egt5Z{A^%!-E7p6qUjKb?O&p{D?7))sa>;~uS}ADf12Td6{A z1)Qp?mRCh{UfT%@n$tu_>+K*F<^d6P14Z|~VcM)+r?PUF$Z|@B@T{G z=u6&RGspUX@v!($!1JlAt&3JNCsV^NMH%mG|2qX+;y*XiJs$l!Pd6!)(@;f>0F*P9vY;02* z4i;qqJ7aN$o2qDyWK8zRavN(E(R~0b2yt*@)+Lxd7_Wg7(uQWBApq+}Fh=@9#BQJgY5vdBcs(!=w7HB~`eNbZ^vWo-x)4 zx>AwW(Bz8aEY>?tUh=2!-Xl#1fMR&Ualcl-cXgWHnND-T!5$hFT3M;CU$>MV{?Iu2 zuU698`A}VcZ8iLE@^SOOYE-)RxfU}(6i8Hqc27C-6<|Wup&T1YFtkQv9w5-RJKPA- zwzIS3Dv-?!-`(-5C|9*DNz_+^v#<*D%hV*Kryn2B%s9<3vf3N zX>{^&tkYoB@Z)Z`>uzw7%LIrAX&q56EK7F}zkC_U3wrL>;%Rvdv9Ne>`GJ4pt_@!t zoSf{hJv`(MadA#C3bIaPwOs+&QXeN#vaahX-O4pMo&3hUK>;Lf(n6KBLeFPr=Bwdi z=(?x!^>M-BYi{P?jM&w?M6>YV`D!)_w%S4 zGQaM>1{sh zJ9CLwTth=$&|PJo5NTs6F-%C=`pnD6aq%q&+_M?8AbPOQ;f8idVjTKAtpDYV{6}O9 z5y10nhZI`6ZjjpzEs(!8DkgXF|I(kKt~5xWC;`>Sq+-Lo<`RPn!kO^UU%3ub1dX;!3#l%>03{oZ*txR@3f?s@U1L-W|Z1kqToZQK0 zYrZ&F$?Y`Hdl#oo3aHKTB33*XJ+-u-MEyTzq)JRy-bBQi2l!l^ye|+veR&DuY9L5^ z$-w|mmZ_-~H_pF)k`oywlx`R`F1D4UE<>@A%j5N7*4K7O)a!o=p{9h?{835C=zGEQ z!)!;&M;|NXV*LE|Zlh@2xqj~?dn}YvL4atgWb=F&0ymsEt)yvuGmIHC^rr6^bV)n% z5ABS}52DY}1c};v%U@6{wdN+|@l6Lgq(-qybItn<{|@B{)$#6K)vBQAoCjjD$=kQI z^iTmOnrHpm;753O^k1$viUk-f<}ve*fVG|Z zd78P=(ZB1Fk;3jRfrOAXa{g>5=7t~?eJBC*RV$?aNCNePvTducS2i&}WpbR*i0*mn zgkiXk88GzFR^nOluW;8_ z2G>%URBhSwp5Lzh;z=62`F4G={a18wP@C)PSfGN|t_)e%Qn~#VF#BQ5Lv$Wo;kj!f zgyvSz!TY`L2>!S!C@<}n?nE*AVaT^0a{+9lFc&7E@cKMmx5}{_hv4OQO;93EqA-k4 zZHSE{#<&j0sR&ZWZE>lW`lcEw>65|4fTt-UZ()IPXL2%?FAT0%KW~`AmiPm8J+bR& zV%doB&aaT*WdQ+!&m3!#Niz@1^Xp<`4^O3i`W5JbAH>zrbWo@JCpZL^R%Hx%fL0@- zKvcRoJ?@uhp{Er{KC+|dcz&q@8)|}_9%P|lqZ;Mff_O3u!DM-a^d7GpikI|4R{#`R+JE~dXfxMoZJ61TR{Y2@Z{hv8V^F*?%oiWiZB6pln@6~3~ z-&fyhI-c>O0$J9qS6q1bgo$C&LPRirF|v1A+1ZeJr&nZ9nuSoZ1sH9~9rKO2Qk1TG zNd-rRfEcYf=+E31zK%8j?Y&Xz2)Voq$fki&9}}je$e*C`IFoi?VS^xXI@Mn2%+RQg z-1zuiY!+*1Yv2Q2ouLMkL@G^^jAhGGM{h4|0iG)^y7bo*;@BL1Tm^5T41WONd27_a zIlT)TCju;Dch&peX=Hv@s*po2P!VEma}9HA=9Fx4GyJw$Z~uAuhqjRuyH;)-z z>kLHqO6X%8go^^h7s3m>+bGHJ3$y{{j3@GYR*bA6n~OK44JhQ+pZ;93GRxl?Z2hv% zLW2Dk(lQRjYb4SnR$@UPX4`b7lb7W@dyM;4CwYQ{3-jMRTF?$g>upv3WO+mSo!|4h zCsIS(uJp?Lbu{koMGZVF3#-GRMEPw$V04$=Pe$MA=HuAV-1wgug;mL}3tEthJkAC_~oO<*)Mu!oH>lSeBG zGraN5QJc}t{W7^kM`Gxprhc#a@%q!NrU!wG1FeV}WoeJUR;K`<=R~zW;tet|{IwGp2F%j5Zz%6CHI(A7K<~ZI#`n zk(M|ViL+TO(zoi^vs;twRsBR(9X@pXj}Pe*dVQvEl7^2zc%hvS@m_2w-RUmZV`c_{ ztWYy6x0RHVquV5l3uLut#Kp~~7xwc>sFw9J(}@=jM zOZbclb$U#6QVU+H8HBH)T+G`+6IB%Gs8d9cnVLW(}s{w>#UY>`CLVzJkuNKH`JWoC6d^kgNmDI+sgAZk%kUriycZw77bDSXov4Xl*_A$G{kaD=NM< z6%@>TO~_KENajzP4^Nf*AsS=&x z=s(93VCh`V>Em(Wd45qums~V3)6~SkP()N*cZ8M6t5=to*PhbbI%W3u8v8qXJ1%6> z5qbWfEWxSK=gRd4Ht>d}}~)EUh_a!@~P5n{r8s;l@}Sv$F; zg6eDP&*2(8(imjOkU2dh$Sm+mU^PG>e_OvbdazXZ`Ps4aWry-1-UKpuB=ci!@0e$eSHbX6l3TCBoDBTkvFB3Sl*#; z9KD;GBv@GsnK;z&cMlegyq^M2dpQmNT+ed<_CSc7^O_bK`#miFV5)%sp<8AprlUB3 zU>1G7x}qUZL56PKZFjbzdnb=tu|If6!sN3&p?-*#4}`iRU&|T_tmpFF7|) zclgq^W?W6kK-oQ8y`;D{gF`K@kR$3^veM?83gq)LOXqoDVX}ef-R{1>W(v3}`>o1_ zqpWqWU83iNv#FVIZSj}(kyho5_0?wfy>78FCc%|D+aHXnL^~Ym!*-?`IHg!K610P1F)-?-3p44}RPbE{)ap!*wGf&v!~8A>N?D zs0tr#`P5}Nt!LnBW-du>rEZ-tl;rSn6@&0k5S+%t&8@IMj^xWs%RgNSg)W}#`21cl zlNEQk<^AE`zsh+{O*QY2kFjF@O!EyFX^@QyJ$hYVjXD^zHKzpzA{ME{i&6`umsnOB z_ls|PD-`#(b<7`K-Chk8qfQV_m~lSSyG|>ZC+c65whiwAh?QH72Wy22s2iKu1nC#PIn{PQWzI<0L zEJac%oHORLlBlb}`GS*SXY}AOL>qp-u)5j{NyHN%8DWd)|9a;J1qfL?8K8_@FGZ19 zLzww;0M>kXB>AU*ZW7r*m>B7thS-1=Ii(v4A6nMj)5Z2&6FYk|ZW2v;u5oJ$M>OP{ zu((dNogSh(-ueQ6M!q2p@qUOWo- zeAnSZZNqJT(qmF@RU`w?Y@aL_qsc#LGzLc);yq7a9?*3~|#d2(zlMtyv| z{n|2}>1M1W_PwkP-5!~=@$nQ%HkS~mOlQ3g2Xop>OjXq%`vJ&>0@x3=eB$c4&~a|~;`qp?1tao|O=uoWGp%IGi&3r@6|ILOqOb>-O+6T--6wDVr|1-MY|=8NO4eT!cx!*V+RR+BSpm+Uek1)^-8~W@Ao9o$F zCGJQmvkWHw$#qd0*K8(wOEr0?qc+}+%>?Yv5Zt<0WI5Zoay|2|DLn`YBc%03(@(-$ z2@s3i8O_&huEnshls6enAnXOW#%=4-nlLCQj*t~`gd#MkRX`}u&)f8Tz!$nMLa_8} zgIX5Htv2oCmxnIKPUvmw<~mlrc)lr&XH3%jqhe!Zza-4g^oo7TQZ1Bml?|bZOoH4t zvFZN1^4EMcGUF~z676S15ZV|c+5NL!L5Ldq+V$Tr1mHTfa=s`j6B7lY`LYd<)bh^f zAl^v@mUOFwmxoNucFZTlgUsRaiPF&?V>6)l7nY@zP%GVSE%??wuA1NyH-X8ZCKGi-# z5}2A0+n^9Ukd`e9n!%m?k)I|o;(rM)ZSQg3iXm8o;X!TK(AE-KZ_lCR9_yiAW%@9E z_txz0Gw7|wR?m6ztpf5L{(Wb30c~XWo-!SWG5F2I!cgpiu5QG!jm=G7b#*AYQb_Rl z(;)CSj2S9k_r0{~TF(2!R-U<&v!qsmjOHwz|LuBjFb5^&N^p!R3F20dMhWg=Zocwq zBok4MLt7&KF3w8CWVuGypWut|nYguS)WQB!C=i4)+8^;x;0NfCA82fCYW67*5S?R| zS>p)24<|F4j)BiEQykaMI6Jt```v+{OL#={lEnniStOGgkA1_!U8DJgFA}vPM zAyw67Vwe|jC3fmVjaO*vPcJdR2-yYWZfUgR+_NZB9fTdp0_B@(7nKF-8MfI;UBl?V zf2)>5Debkdl33`atVBfQ35xQCgd)Tg!HvEAfnyXua|M_MN2WYPMSz;(`%&0^ey5CI z)Z_QC*!bImp~jPt+49LzuHWv~CTBOtLpzkBQ|98)*|GTvTCBXupOmB2Y+ z;iohDfG?Gf*2@W$aL%4yZC^(rS^O{Db=XaIE)wKo2UsD@& ziD*Ol<9bzJW4ZkY6_vqHAka#rgG2B-U%>4bwC(RF=GbOk=A^CyL8%PzJ7%0!#Q(_75QUUA0PiE+ZhEBM_rUM)fsJA4?2Yi2y6gIsFMvfGu+s{rTTb>!ICl$K0?Ys-h_U8 zAi)>FPsUgWgWO_DetMwnJd|$t_dAa#CUycz&vdd966I_HKYti-%#;ZTN?J)tJv^at zF!BMbZZS?}&*w5S!54!`OK-)+6UZ<~n&#%rkr%kvu5lIhrB?o~y2QTO;Kh62j!th> zYmV)6=8Qsi=L`jW-TwAQ;j#vm;=Xxq+dg971ddScz_sDNZeaPR7oJy2)RoLB=dgy7fq(;0!m1Qbe$rf1 zqlWHa|JWA^aU;A*ap6qLAaBIYFeBn-pXzLs+Y;=Xm2>Fw&ZzuzZmt;i!os+H_)n{d zKJqTo(cL7FUT_Gb&U@7%okoGAuy>-YvMf7?MG+Cz!&Oxs#0-;;Su$2v7oRabu^Hc+EXec=;OU8&q<8z}) z4RQR?;zDgGCho6~j@oay0(-d=rKGeYmq2sW)%Cd&5p~@^K7NuERK4R*H475E^r zUeTj~YKF$}1p_4{>q=6OGt+#~8>C50O!_jj+S(|Buk0RlQIpiH`cUVPEECiiZc)i@ zFHbtF=DpduQKZ{Yw^joFearYx9tI60tuakgP_12`xYIgc|j7K;c?; zzkZM7y0=l(ZF#S70Ft2qWb#JA^kMTLMMHu~?!8efK>ifTGlKgwFArAw5QQJ^`HGGK zPevXl`En{IsstR~8F66+{)eO3{?5*(L$>A$J)u~Gxa#{?$u(@fqkK_r#FhX}IXL%@X2$+y{r*63Z#4 z;FP+XyJfp7rYsL1R3wo?^J?>IT$ojbUfbK9gdIsAV}ir!p$pLXnneN1h3`S%!&BG*VNV# zOgjuUp;TAb?&Reemy=y9*JYDJhj-mt5Z|z;s%T``+;jZBrs2b*<~cc%TI3}bk8j_X9?xy#k&B|+AB6JAmi80ita^I9(F&5JpO zO2}jfz;`fCaKMC1U*7VuTO5p_M+$n+nYDKeE3j;YBHm)fEHHy6D9@Z~YZ2dwz~R4g zAOr1DHR!ndO(wkQyW4`Bht{upB{2di z-d#-+3M**-rKh(b-MPyi`>ocRJE;GbH4`lDm!Ef8=XWhj%SxlFjbA#6^rWOMpin=t z*|UEid`0FQz#$;7v-5%*+RL_5fFiGx!UQG=BPvFb!$ZNyNWqXtDsoi7LtzHO=~T*4 sV=-0C=2@&CL#iFc1XbbNdtV~f`Wq- zH^zas{NvID*sPUGnveJd4n@%%w1h%w<|B4C@eEG%y}Rr zH8(y>93V3Q%rqM#Hxm~o90)T2W*He77#A5c05c2>EgS&{tl*0T00003bW%=J0Emd{ zPu-6I00Ik1L_t(|+U=OzZo)7SMBS7?8$!y>#5GAu*8cx*>~7w7EEQEPVh>JUR*?^* z36^jg^u~)(=N&Iboj1G~b>8w~umBMjAi@GfSbzu$RP+V~D(av>MGX|FsKo+efCR(< z35Wp_5CbHzWI(zAb#UHL1Ly6M0RaJ?!V>ZvmXPPLggnP36a}0BoHwF?6F~Fj9mENA z9ZsNWZ~|=$6A(MOetm8jhG7_nVHn20g*Lnxr*PZyV$|pNycnmFQYs1%VS(EX3lQl7 z>2T^37N}?g1zy+y2~=#b*Z1cH`UC~U011cz5)cDj;FMfJV99`VfhB{RF0f=kK;Tdi zsEA+*d3RXCill{l15c-(??6BlPy(WW6OiXY1^fPbMFN`*PGGym3GDYU0jVJKkZuPj-ZEm^aBfw8B~x1iWyX}uGi}cRPcB_ zpJ((I#0Wabgp3l93Zew0g3LX?0|Aa<1qErqUF290SQiA&4=*ql1U?D^pARo^|6ycD hzF`=KVHk#U?i;0+Ot-gOUdjLf002ovPDHLkV1g)neoz1a literal 0 HcmV?d00001 diff --git a/tff_modular/modules/vampire/icons/bs_leftinhand.dmi b/tff_modular/modules/vampire/icons/bs_leftinhand.dmi new file mode 100644 index 0000000000000000000000000000000000000000..a2f682fa8dfc9c452266b03ea0717b81066a8277 GIT binary patch literal 2218 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 literal 0 HcmV?d00001 diff --git a/tff_modular/modules/vampire/icons/bs_rightinhand.dmi b/tff_modular/modules/vampire/icons/bs_rightinhand.dmi new file mode 100644 index 0000000000000000000000000000000000000000..075f73bc779b3f2c8f8cc55f9b8d1e932d7e3223 GIT binary patch literal 2188 zcmYjS3pmsJ8~@D@Kb$t*T$;-yl|;ELS<2L?P%6nO%7l=JD8sQaWpN}?I@Fkvgrdl$ zFp5)dZObK!Y`Kk=OO2zA*?+75={e8yKHvBIzR&l0FQ51FO*-tn53Yh#0RRB*u;0!F z0ASK9z*PdJXFqMfx0F>yyB@!2cP88?>}=@8vmxgJAd;HEs#m#ex>|vYiTX3Sw4nRl zp1+LkHz7nSD_bj{WuhG7JFBPJ^rLq_ErV6pMtt3|revb-GJe{$eBGXyR+mwq3r4-1k&- zX$GebA8@so@+|NdHpu;J({tVzt# zd%-+@Ur#CiCvi)@iR?5+CVJ8|GkgE|o@+5*cD=bzy{7Qscc?x#`jUYnt#L!L2qNCO zt&^0tF-{`)y`7k}J+Hb8KRd6%?+U{!@iMlwY0Xp;tnlXyL!n4MgPmAckHOFWQ-20; zxHPT&e^0+$mURrPKG(zQ>Lih)78Ow!$NGo;l6GY`k=jKJe{#yI8CB7nEGH-L1}txJ z!GymsC2x768#|tQHtJ@xfE4>mNUMH`o!FuwE9U;b9dU}(yMCgjL^#{9t57=Mvnu3ZZPS1X5fhh^08)PuJy3)=Ae=ANZ}PPPsCHT z_G9P9s8(wE8GWs=7EmJuNI>1g#C=>iKM5c?)z)l3S2@=Bi&*2!;B_0x?0V+)-k6G*GMIFBXqdVYluS8(z9Sl;Tva3YcZgg^HNoBq)!f@mAff~c?bD&czA)DSS>Ngw)L*pZcdEB#Xp!vIS?V6PM6d!)$dS)-^ZW7&FtK8G6CcG4)bfCUAQtZ{g<_&za|%V!d!I*t zvWxaw3t1J)RV22MBXPKEaTLWVTQfQBaZ9vjJ8uCFZzPx646Z2Wz~K}@)cH|C4kjo< z>ZGT)_w(fY0d|}~c-75D!i9TDwH)WGmHjeR1TLR%d%R)NmT!sX#xOpzALoFl#Z_R6 zc2Hn|W)92x>X)E{2=qy;P=87NeK#BU7G;=I)k^N2fVl7!2i<@GD}?;)T4-gKLyy*& zz|ZLS&Uu1~2==Sp->N2(8r8lDkBF4@yH>5)Nh{lj)x@~X%@+E{*Dwt5*rY+WMNz8NLjJ8SZY9@{y2zgB`wd#i%3R^j?OI4@b9x1+ z&{Gx+MPFzekOh`YKP{{VotF9@rdr=HKEo{9ze#v4MmHp&?AKm~=nI!fc9 zhM_SM8EV7Pw&jo?llsYfkK@2ti4E6wA1WH=Ck1T4h*sT7rtnL)4uzy0gr|6n3M?@* zJH+yJbhB0v0ca~t)Ml>Fxcd)i&Krk*?F2ilo(P67LwQ9gi$^9l;_<%G`j>fv$-CJ- zU9=qKA<-nEG+LB=H~Vc2gIH0K^A2AZKBq30@7&Q4viuFt8V-M5CHOeh;Xgi1Nap9! zVPk@93dJHW0c5dXPpenk6@~GfLt;b17GE49?ruBN_eAqB)5s%xH)l(>)KqDNE&F=BU;m$5w zq$u8Iohzf$(FT^=WwRijn0EB>4#y3v%rB(IaehuqQ-IP8g+h}hYAGsg0ELSj={w79 w=+YZ3Re&vfblPmVE)Z>6e$6%*@Qq&CSrz(4?fKrlzLK%F5N% z)yc`p&d$!o#l_gz*sQFq)6>(|*4Ee8*O{4_sHmvR%ge^b#(8;p$H&LBv$N07&&bHg zqobp=w6uzfio?UhrKP2?u&}DCs=vR#n3$Nly1LTR(y_6zva+(AoSe3{wz#;ssi~>H zzP`J=ySKNuwY9aNprFLW#Gam>+uPfup`oFnp}f4j!NI|zqN3W`+Q7iTpP!%YH8o2B z0004WQchCV=-0C=2JR&a84_w-Y6@%7{?OD!tS z%+FJ>RWQ*r;NmRLOex6#a*U0*I5Sc+(=$pSoZ^zil2jm5DJ?ZMCEiepi!&v&s2C_< z$iYDx1^_X6I(xRtp!Wa(17%4>K~z|U?N(`1 z+b|H_)fHl;m_Xd72RJlTB~1?`N?VgUJ^%l2>XRph_@V=y&h!K8I0Ih2w{M>mOGN)o z@NGtlzbGVuXVF>i`k_*NXiZuOMzkd3(dLN)9(NbsXrjS@cUTyM|8Q*+L<$}%t~h!W za-yX%2{e#lYZ_@oj0zmufOTfu!xKy}Gh;zo-4U>VO{Qv8|1 zQ>ZHW`cN4|&^cJD^IPAGn-cGRcrK*}iQkeD;kbd$A_2cg(stoxkUn_e{oG${sQ?rd z0iO?o{d>#Sw)PKj2A|jsxLC@I z2*2LFWI!&QgJw1p5OD6jt=GpV1e6Ggl*=W@tgG#Qp{k!9&N+krGizeJ(J-*H?`|{;Le%c|EhI1)6L~5F*M<0un!XyJ1sAVc+{ zsZd}Z#YpnVx~$+aw;71T_rS4sT5{Jq!VnPnVpX0Lw&eB^L~@Wk0YgD$GZ*`X3(gZ~ zmp>i5?lX)SaqyqHEL#jdP9)KqEWjnM!gU^kxUBqd2_V}10HMISmGeCci1s763;(;1 y>Sq|SJ*Tk#w6m6;AO@!6isYyTn& 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
    _Diu?`g0CRqr~ zn74$nnj+wY`e82Gnv<*9Q*0KGDn=5n%$jDRfGra2WHrNlZ|5)? zJVuMu#yy2L1t`=f#OCZ1eFLqg%&QnuLVI~ic|nvIMDcw8FP^*&;yBdzc$n7X3(td@ zuXvvCI9eWQe45VkO$S0ipiI+D_+>+xH`E;s7~h9N%8Y&}aWxuUOw_bx9$qd$QJ;o2d z7@S&696!@xN#37!>N)qih7f2^kBBb(LDO--;S!;g{<+LYDL>AJMRQJhWnb{M-vM~o zzz@@*K|U$zf5Hy}?Op<8{r|`A{YS0akIxF#ow9kf;cL4oF2faB<9{Ohcogk6a=7;s zh3`lwI^xC2ojrQ!Ee$o3Vf4xR&UHM*6LU|9uzYWC2XaU1v=_x&Y7J{lkF5u8Dh(P} z+*N}2nUu=IE6rMi2hxK|c&RFTahV+|aMTIj{EiZ=e%nTAkSbGgZ=dDT=%L>+ren>C zUDhF+(pI>s>U~1)Fe%?VA`t?s$nMDmavgjM4aN|X{THrBa^}mRt6stPn>R8IJW9NU z_gVJwq=S>uqBo0^P>UC+N@ED# zr>`E0zU_uo>*Ls;hTbnX#(|e+b~*bipeN1d3F{{mpOE9$`itNrzf(T{VUEgVVo}V< zDxe-4d+rm~1Y44u2JJR*sJV8jF&5-D#)Lf?h|AKl1b=hIAx$|ZO7NP*@PI`ooNyw2f!t51AYVFvjD z+F%@HilS0J{z}6cWKOqk9K0a&Z3EJ3*Vh=+?#HM${UpCG;}y|b)$465UZG- zLc1yBRr+Mi1VpSN6GduxJmM$8I}AQe$XZU1e!A7@`reL=>a2)H9(IjaCD0%KGVBWd zC_rS&8ZvR`_}G_W{apGt(e}iP<-W7KbaD@lh_N~X$kpn;2~(|{?W*hTC4n92mA^O| z#IUjbv-l)|>&rtAj5KInjd6r|4Zj?|+9E({)|T!3G`b`ActM~A*6H&XK_G^6rXUda z%>WvZa{!1Q)I@WJxh9p)*fp5;Ebf=FJN*bQB*^+zud7PNIWB}T-9T!mM zO#U5T^R(RW33&-Too4li4`N(DcD)3Q+6MTTD6Z>pPQ+o9any}m@7()qeyg035+3a< z<}}?9fj5&{37~Wl0ENjoRhkAgk#JaC)fzWVQU1NB`FYF|WJO{~F)|0A8}#8r+S2>* zP*^{2%xi4XVA*_cReGN^cgT9-a`xFlV%V?KBzL|>&c?$Ay8)inqEsT*VRz4 z?u41jc3FS5`Qc)>OFbvNcVBuYY~*sDw(>r-BiEtg-83@<>?U;Y9#CaQd3pJO9Z6hj=D$)GPCW;?qerlrx(~~=7}5p`@hxjU#}}d@LbY%uEk%nN>E-=51Zi{9F2$77}S+u_NV7 zA~_YJ1T4lG_Rpn-zPMGl09ScuU~o^VprmB<UFo)&)9hGyx=;E zzeTgj((gOz1#7kaZq8Glca%i0QFRtWwhDaurhsLFN4%(7aDu9*q>1(?^D8BbJH_)q zMIBduVLA9coUc{YFH5rS{K^N45M!EBXl2V1c1vJnT_W)#`YCXXPXcJJx! zR}lkW`4pbGt-Kk*U{sW)>FqEjRV*!`+xlW2Day9Cca)yq$#kC(5*6QKmO3l*v3YxI z)ew@JR8AhJcrvm*_qyG| z|6EA%X;*4)Nm{oH!?Q-h^44l=+%_F`*7}XhpNXPx|&7~$f zYdBfoeE$5^L~;!FcYX3ZL!+X)I%hjDv>iiOExH``T5@GumtUzcovW}WYl^LCWGuHj z7zpD)JVvkK5;r`&Hl3g&P(4K&v;}@3IpdjnHljsF+*P7t_>HR>_Nb$A-b`XHh&BavZjX$5+|5L4_Jcl_U`^^^QZi@T{@bm^(_mvTyDv)p>V% z<^Pet&52V#KMAipuft14<9tG&IG~hORJ4tai)*s@6oU0gH-=*))S18x)q)b2Zj?Cr zxfeLXo|MU2r*9cB;tp7vR(61Pv~@h{*zW7y6ujI?seNErQoF>-$nljU%+}g^I24lV zi17Mj+W77S8>=Sf(*)n2_Sv#9s-FF3u0FKXn;atw+Pp6QmP{mQ*{^B}5ildt`Jc3K zubEzoiHX?`rHAO}3*Vto@IpOLDr*^xAo@9gdI0zb_juPRo7qfVD+V_ommklIpAvM|b7L zGXS&^khl)#pQFxxex;WJCh-khh}*vYM?}%H@5{bNJnZGW1UjeC{ZenW(bO#;?& z`Ni3bpxK^8@22Jqt3GPoH-8Zh5DQNZU#QJ%RfRJklGkk}V5`#?dS@`6z#w5e?+KtnQxEesvZ?rQ5ZNsGBVOdIGvR4xvGgj0b$$hE%lDt zo&gQ86|$Sf#m5(vmHn~o;s^UCh(bz!{=5Z{Y=4DaQ=jWZiSi zVaAD!Wd^+NbB)ADFC!x(1slx_KhLT-)%XA(&cWw;@gi%A{4cpj7{1oOnz~tGsU0|4 zWIGTQR64?Ejmc3>oU1zz0=pM9^f^;KmZ$CS zl;F~$_sri@>iB|a7KCIYXhywEo>-g*9Y=tIudQaNoTKgZJo}(%J0!JYiXp%^=8(qs zS955-T%w~cH@82z<*|R3Xv%?B%&Lx8dvuFaz)Sy?D=1+RU`HGrJ~V;DXfGjmLQNeu z@b_~2@#$5s3`uoi;=Lb=|BRwacE?WEqg_rZ`1$nfg8c@W#eOm`ry)TjqtduN;bD#6 zd%fJ1R0GQl8lAR=HacDS)o;sj0@YG>noP&@?j6ae8_@ENjP7}YZ*eM-D>=}^bZ>9t zuIP?k?TETJ`RLCl%f47OLG03f-n@x~jbUE*K-DQ`gH3kotuo&YIw=B%%J*?#w75bG zN7#YzCZ*uY+E{sRC`?GI7uovEf+Q+GVQPc(1&E-NkzV0tnaH+&Tj6Al#yKr?V&6lBaC z;%64^r-jV0%4E1Cr`f|&DO3VQ$-+2BUv4p?eHIx<-u6D1xE} z$**?>!t1Cy9MDHrMeX9r%!0dwbgUPNhP3}+6d_~L(?by5y_&A=!Wqj)7 z_jjK@S**@WR;Yb`SJ=WqQ9K_KH%sbqs4@-{oG9=gp6dutDi|d+y7~}Wr71ilbv<^r{YU5t zRAVoqHt)yHHWp&&b@$e2>`B;D_o_kROoe=4kncMcp{qQdj4dMKST=ENyB z7CmgmMzxy%ymjWkA|Cc)g7VW#x{@WT>+y}hocMxdSi1(ldP$dTD|iXubuIk4=Uw#A z&wl@T_x*b~yTiEk`!JukLVWfGKVLmA%<`J4_;g!)u*Fq~FXb8KUY82ley*nOZjcX! zrSf61lUNF@E~||zB^L*G^lnl&j6F9wFq(5$ zO?G!?0ac0}sCI$~8@MI23D>E?;rK-PS|LB;YHrd4v(F_cqOGyppO+IB3C5K@BK0dj z!$k&1bRos(S?{h4X@D847{~8R{TXtp2-mZ`*Bj60{V?s82GwUhu`;wC{`X9Y&Sq=4g zeU5L^f<}6cKJk-6_9q2ayfNWpz3NRbG6_*&<`qz?n-{NMjf>_iMt10IiDQmt@nO8EV|yzT(2M!B_m^WD^tWh8 zt$mbUk8=z@D4F{~KKt4O&kcPJM@`aUjtEnO8aC>!jS~d0k-A~~*q%|`YOc#GkhpFo zdvs*(5L0>h-E89SYG5>Yl;lV3By~>5r5xLL<_{9V{7`g^=(k&sg)zL3UH}`+;4}e^ zwEO1Ov=fbST%sn6*F|OAgpKKLX#WoPw$Y_AtOKbi8*SJRBIKj6wICH+S;{`q#5>^z zEP-x2DSR=%cDa7({o(>^A#aP1AH}=pc&2o6Hz3yIS|x9bJJ@=YE*)0qrc%?}3BBfq zFwqJA2|hkV6J`~8SBErY|1j{vicIR);ggOET3T9#Xl}8I$z(S0?rZ{*;~i!mO7LRr(_# z5!)AjDS7DY-3S>uA&9pzWpI>EuVjg4x#dZgh3*}Z@A-xa$95uUakjN5S$?C{DTlou zwz^`3`{?LhHKG|!1=*+no)fr>Pj*g$L9IUq_-#g`Us6%Dy(G0{X_!r6iAuv|#gc~0 z3}2I>Zb0bmYvHcdX(&hnSRei?QG@?IDp%?#HwpsXm^#e`IEC$gcq*bg+kW2lOJ2}4U-Or7hV#4DeodK-y{w|$xa%pF-0)^u0|0Cee&HnhJYaLS&iZ$k4tsSDRIe2 zeFRmvs=-S}{s2;`p7buM2#EVs4J}tBev9vTZ#GFWf9^*jNDb3&GHoV3Rk9M*n=SIc z|Nd&^*3p*z*lfKreA;WXqQp@%q(T4CNokPstNvL&dM)k+dB=Qe7-qJy49`+ftU1>8 z%JEO;UtP&)Oc{pFX10Co%c!sKN&`O?)o|4`4*T^Uo@M=HEssvPpx_E(p{HkFeGN=S zwBcsVAY-rmRG@7VGp0w=Pwn7$)l;mi{2%z5U(USaXHsRr3mPE1omfy?c84vP)=C;p zL2{H;FJ>=G?X^cC{C&sB`{a+!$l>APtkVY&=);gB^H_L$L)#atx3AN5N@e7cR zl$r~~&HAl){u`cz)Ps`GBI48EmkNJ$SV!=8h5H!MF@mhMLV|yMyklQcCJ9V=M{ZREAnEFow!OjJ{6S4&j$Y{JJ$k`q!C4gw_ zWB)&ejyvro4=og8t#$XWG@n|IL&pC!-uEo5p%WtE*(#BCnT{ntCH(_U-RnAvr*{j+iSXA zFW!eHKfGI8a_@`3eKQfI3-KG_FfYPvt?%Tf(E3v#jr%8PXjdG&>?7#x?fD`~dXiH~ z+xxO*^Rlr$CcNVNGQBo4zhCbk>MpiE9eREFj^pDEN@Vi&w1$_$gvOVzEQ1@Fi`@@dHCZ(u zmb`cG2Jwb;ZAVs0gO<7k+#Ocpl8 zU4-!%nelA!1oIDo^Q^2k=(+Y=cki6_tYojNIGL`7O-i|*><4@*72ekjNuBS-M)|cU zA1|=D{Xiwo-VqJHFywztqw}|&zdW%);_r^}LSS9EA~T&OkRB_r$|*E5B7HX103viJ zmD7LKPD6O$nozY0^pQ*b$uk?!qv>hne_niSVGI7D1z;dIH(Q8{?RyK`_ZCda z=$d?9C)5Q=i?P~3g4PmEG}kEh^&ns)a=y5PC%A}{CQRsF!I`F}Dm+5{2d?#^J7f57 z@R2$odSg!6{4X>AwCWV)dAy~5T_UI#Sn_sUq75a;t0N1p(A)tv|`~PX=rzs`^F9rgA z^@MtMY2@!3(QG9>Rr=5Qsl&dcM_>c7*wF&?*YW=1gynF2|?*3+}TU>!8J86*A zxga}std{2(qG1Q?<6RqZadEwNvpleW!=jWl9gK~;QGb5@f)f)TC_K=ExlGN)`VEEW z8lGmyC6^;=yehN&b5sDl>~EW@{kf^R+FHYBhcOQYHDZyxIQYZm9LIAFEM4y3K7Wpw zHGEfDeT$Bc*yB;ZvD1o)fBnJomhaGu+X8|-kiTp!^9bfUHDYSXIkzf|+c|D;6#ol8 zw(lTqfdxSA?kU9(k8x(GZI9XU^TlS|Fk5^bR$UpO~a(5rh zPRMbrr$7lp_bW94p5JdsS>c8qKC;=l&VCRg;MZ)mwd3lF8ya+gv8=N`$C(lSGQ!r@ zmS0fff@xgn9ejdY%r@cLvCLF(@GyzaqvZL1NNV6LsYI~!(b*f(qVH5)99BnEzF?6` znyxZepv-!im3!CUkB~dtih&UMjC6F^pk$ng%v*?zW$Xc$tmaZH zGaTzwhkjSThR?t-2P4q?3SMi&`9PSk)pNg0(PUtt`Q+!h|)+UwC}uVG)^$vijn zrjjvo%i#^eq_J|g*B$CJF9pv^u+z0`#ct_2gz&aCXILi;(vBnd<&eG13nKV4N3$H3 zuZaqiec!*wlv8R6`x*Xr4c2pGdVPR%?F;eArM~Zh8wa~7w+%dd{4L*ZJ@G=7&T^=%{JUL%*bI*DymlK zPTh{nnuyWxFn}G4$4eDc$y)+_=eJH++-i5`dUaQGQWDk+E(Wzw07GzZ=?>xy(|$m) zalo+e38gGK@zu0^KV?Up*Qc%R>fz6+rF+&?TdVwR2BTQBbYZbp-Cdui(2q^{wK-0c zl!mNV;;#n2?o?{@Q`p+1o8@=k-`t?&dT$#q6S!I5hz3S$&V;z@(DJZx{ zxK*^f+cxXjD=|~r+B6rNteO&{HgnYI+I29w5j%g#pYKBmh}PVDl4a5h+oYpYZ^3-= z^35=Ltu8}UD$IXvmQKqQ_KJCAAVXo}nti-~a~zCk?29P}7XGhCHgM2TwM{F%5P{61 zj=L+h7{ix>a%iQW{+m`V?>j?^1MgnIRDY|xar!_0!SqGW|Mn33e~jg?-0=9+(&B#? zixM^z^BLY6Ctz&@i-~Zz(Kr2*#!in$xg`5~h#Vv6lw+R(zx^$#2gf8o03V3MS)DpQ z;NYR1xowAL`A*`vJ1 z_EnU*U-<+eQC15L7#2Lmd#|OK*Ir?DeH^Mf_(3UJX-!-II@AyB*3Y??NK3C|mA{DM zZCB{_OIM6Ttgf*`YQej>^5O=h(HHWC;$cWbjXG)5 zM|%QUn?%|nXo_AWoD4LI&n42{eT_iGs>`ZLdS_d$i6Mhr zwtZ}EvtHM_8N^ktTU?BMk@r~!7b#lu2Ne=wTP35~oaR*O?<}=zxI(iYvPIU)$+Azc z@U8W~?BP-sv?Z!YePrRI?GPt2Wbuzd>W*d5LW)BC9gy%iU9K?Ec4Ytg?Zt@l)i4R1)QQaSiVF;YU}FUg*L^-l|S5c z869|WB-?QRGRhOfwKeNCN1Jx2NN> z+8$l$M-V%0`pz72^(55a6ILSnZyctMLQoCAZ5y|;g&l-aWel;F{px8KnPR{vCq(5{ z0%PcQ+?5`TI6sp2LEfDp4X%VEl!d53aE6_&yyJ}eg6{=I87h=_L~3>~`t~GkxPVZ^inW*rG*ryd7!_Y=`=23XQ(789eZV zma&PZVWk%)-_N(#!s8Tgioes|m#hE!B*dPXQPueOm{f5k>XAEN9VkZZgbq#LZ=z`k6zI@I#05#xVWr zhwj#OQk_>(l!3=IDaNO&6ja8rqLEI~7TE9z(n0OkRn<1Vn*QQ*NS;Fs;sr#S9?e2N zg{H7WL9``V{j>)P)y3kAoi7u8P@%I{E!BRZ66mc07*5pSA|#!+#ow=m{rTAkyYikF zjUk4!LVrjbOc4zi$?gDIr;moVgpjiB@chVwIY^{@wv{7*JN6Q;L)3HX>OMYhqPCd&zp7L7%@|71QkmCFq*nYZ1a!U+C$!J9VI|C7!XNza!)Zzk( z_$(FCkw6S2{YndveZBC#Iq=YDm-n#h1j5EG;miPQ`5o&+p)-_ic?LU@fymq>&%hC@ z?0eL|Qbib1UZqIKse)1k>!WSj-UQVC9X}ElHwr9xdFADgrl9y@;?aC`@d$c%D#mS- zHj~hHb@ga*5I$sA<-C4zbPZhLm`ZN~&7Z?S5S`fxwnGGr-P&bEYy4<2;Ds$DnKFxU zv^|$%>lXg>dpP@qb)ANK+WMz_7ol0!BCzA+GyE)95p1YVr8vZ?l;VdUt-1h#Hpwyd zh+R$P>At~eK3#Jgb}VCND1%cabVPFH0+B1p!qWmzm;b)gw}z{BOcl8lglLmC{bAU3 zwfn~PlDobSeUConXr#-IwuTVL@qoC+<7JIf1q04QZi+u-=2&T;_9qq3Ph8MxVed2s z+&)JUtd!+tl$;|FfY}GFvY$S0-UjIRhhFLji4MqYtLw>$FNQd6&lQpnd=h5p>dpg9 zioZBIGsR1D$xRFRrV(&?-LxQ*tubxKCO_)mb6x>b;2)f2{9h8^2V_KA3U&?B^F+i) zW&hmDu`VRO{k87*lfI*WCl~*`gEulIg&-fRcQQK=9YY-U)P{x7j(v|WL`rLzARUZz zx`9pq`=@LV!`fNFvH+0Er6K?DrCJ->9EcpKIacrTPx_vey`JMM$H`^%Y0Nl6d<-8#O1uOL!l9G`6F1Magw?TG+HbS=mKF*qP)hqm((_4`o5 z=ut-sYW;mOtn6WIx(b(TJ>#)Q!}A-PGz_icSd3SiwE2gKZ>zg$rCA@r*H1AkwSCb1 z0a&Z{!|&PxZ+E3zK}kOHVlQYrINhBm1v_kaYW!9|v4(ThqpAB%=l6rk_D%%Q{@^j) z(-vxnTVjewHJk#~5+_Xej$)qDI(+@Y^8+HJ#bv||Q|7uqy!8g;$?xlD7UWD6g5mkD zdM!e3>BDx_z>Zcl3%u2fpbHdKVC%r>+31nyM>&Tlsob#bm#^7*VGq_d&kVc=W#K$8 z2NX{%+yohSjnVg@sX7j&Z_rbq=|sN8lFjqLxez*ubpn8=)%eg18lm}R{ucgt1@)W> zIPbBCRzKTE4eqsI$*OGra}mUD9hfZU=5-FL_<4AX&a*_xraN-EYfAga+g}aem$&bY z&FoO`xYtMSHqS@rI#j=fEVhS>L+DZl@zvfZ6z!%@+p|Z)CUi{uZyZq97W<5*xYy$T zfS?ifLvr@2&ofR(PT(KBb;zmhn{1nEClJbZks`d}PDHY{fk2f`A%d;JI_8yRuAcvhGKL~a+ zGNl7G^u-0G0lg9uyFL`z)v_w20lT>RQ3L zeC1;tEl5swVirj228!c>JUE~Wt9hAGeG{!d2jf=qyw}Ku(vRnZU$C+nr~Jj<01Hyh zbKn3X#yNEqKLHx)odT&CbZqXD{}6HD2_YZI60I*t7mbo!v;H`!Bv7?;O_7U>uVF_3 zNKjk8#%>4XqwP9gFJ|Nt3o;g4E&TEYp7p#sViZU}b2D)%6SE)t;kQ`IAPppf=w_d0 zRZ~Zos+=^_iNm?F^5t85{go5Qozl$W;WU@PZ~lWCf%J@nK-qWxt*r%hM+9_Tp96t@0I5vaA0~}Zo7QCf{z1DZzmh1XWHh)MSEh*rKs`8K_Io_y>B01jJ%t!pct^<-GE>6`8c^8qSQ^ z{%R%aIRt`F>VY~KZJ5Bx%K;T5o=_$Z(7@h?Ue$nIXgrAE zia_m;#eP_!3-oMfZ10wsNmorvDWlv17H^RKxch|u#E5GzFZkel)}^6<`ymTJ z;!w`*P>@FmpEF2C|9#jutap>0NW5nd)l#dsacZArCMn^FaSq79%cX~8HSE%5~Zpkd%R!yw1}@A=NA=QukR00uVy7oO-%Zvgen z01$Y}zv3}`)*x@7!wa7q7-xXCY8=miZbo}wNmmEXWI5-{FARjs9Yrul%W1M~ysG`c-X9v+lwM zSJBCihNq$%+Lkr2kIxmwFi}^tOdK!cP{#0m_Hc);q7LdYjYN+!D4pE>rqSEcZ?2E~ zcCXUO&=&ebUgU0)P2c|nx?GP5?Xa~&T7Rc(N>HYH!nY^(?UC>-aW+2<)+o4+EGYm; zsXA(wf^{*|0#pxz+15}+D`og#OJj6JMv@j zM9so&Lc(g}+=C+-oY`Z?VXkmgE>NlH^)`T*wlbkoGBW&89g}NL6i9HIt{5~Rx3tJR zOgBh)lMuI~tgm&N?fRf185!Z@X-4#iG@Tj;A}z|yQxdNX%F%IyFL79@GFS5nzn;&0 zlSA5xUo0uHylcOK3jM%_MQ4-_wFTl2t-pBG&(mmMPuzw!rztT{@b=n!cWLYCjZLy5 zhc1e6K9B?IzjtrKaQB=ENQd^>wsZn_Fpq6U%rXqs<8Y_uWIGYks>YO9 zlf9D!-Qd6sQW)g=IgV%B*c@*tQUi42By9_Lc7NwrQ^j6zd|}1iM1}c-@mp8OSeoI` zkMoLxi<1c67E0WJ%=p0|Uja9yBxC-{p-@KxKB6bbZuN$Ts2piL+CQuP5La!WWm`L; zZ}Pl+*)SHxEN4=FrD;5e^UDns>dVfTP?iJWc#(Y&!fCOBd1d=8?fz1KdtU8z!P$CO z3*wVRHrBf}X*q)ui_@xz?#>49e&wmmYm$3kmFkv%#V=m#f${8W542;;vkBfaR5BiN zM+tC5z7_AG6$MGaDVyVP@i}MvMdf~O4?TW7WjQ_C6U)*k#<&V!1Sfp(10oovf|8{P8rqLzXi)G?|^>f-uefP=37bm^Efz}26RK=AMN}e97_wGlQwl@Kk=q1 zVQG>xxg9{Gdun$7pN}iJzEe<`S4XR;>z-T!&E5?7#63DNFt*yCGnu$W$09o&cBRv- zS7uE7P9xYm+q=UF2@ppaFBs=4`ma<3=O$wXGlRPN8= z9UzfxCjlO1J3S47hlPb595zH{3DI1t0c_1wz{613aC>|E%#zpMqdBL)?%jj)yWjV{ zbB4n?1Vmq#u^(PI!E4(W45Bxhy>ypK$tzm97X7@Tc@r{Y8nq H>F56e2*>V= literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/icons/phobetor_tear.dmi b/tff_modular/modules/vampire/icons/phobetor_tear.dmi similarity index 100% rename from tff_modular/modules/bloodsucker/icons/phobetor_tear.dmi rename to tff_modular/modules/vampire/icons/phobetor_tear.dmi diff --git a/tff_modular/modules/vampire/icons/stakes.dmi b/tff_modular/modules/vampire/icons/stakes.dmi new file mode 100644 index 0000000000000000000000000000000000000000..c8dfa6bf2da2a8957172d902859d69006ad90f6b GIT binary patch literal 535 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 literal 0 HcmV?d00001 diff --git a/tff_modular/modules/vampire/icons/umbrellas_inhand_lh.dmi b/tff_modular/modules/vampire/icons/umbrellas_inhand_lh.dmi new file mode 100644 index 0000000000000000000000000000000000000000..bc7f1d611aa89b5b94eb35a3c56bf9199a679dfa GIT binary patch literal 4764 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 PPXe?w^whtp*@gcPs}`{f literal 0 HcmV?d00001 diff --git a/tff_modular/modules/vampire/icons/umbrellas_inhand_rh.dmi b/tff_modular/modules/vampire/icons/umbrellas_inhand_rh.dmi new file mode 100644 index 0000000000000000000000000000000000000000..68b9611481108eacadcee4f5ec69d75fe654d893 GIT binary patch literal 4836 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 literal 0 HcmV?d00001 diff --git a/tff_modular/modules/vampire/icons/vamp_obj.dmi b/tff_modular/modules/vampire/icons/vamp_obj.dmi new file mode 100644 index 0000000000000000000000000000000000000000..89ee920fb77b6335f6c2c7d3716d04426a08aa0c GIT binary patch literal 5718 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 literal 0 HcmV?d00001 diff --git a/tff_modular/modules/vampire/icons/vampire_bloodbolt.dmi b/tff_modular/modules/vampire/icons/vampire_bloodbolt.dmi new file mode 100644 index 0000000000000000000000000000000000000000..d8920f7ab6275f7cd351f193745fcfa83cb2568f GIT binary patch literal 363 zcmV-x0hIoUP)V=-0C=2JR&a84_w-Y6@%7{?OD!tS%+FJ>RWQ*r;NmRLOex6#a*U0*I5Sc+ z(=$pSoZ^zil2jm5DKRHUiHkEOv#1!zGvwk-D@x2wg|L+sT>V_Yh5`Wg-5Err*40)3 z000|MOjJd{z`);4gvm00DGTPE!Ct=GbNc z004_gL_t(|+U=7;4#OY}1dFq~-v7V2GKDIR)bw6;Bo1ii07g9ie1s7ZywPLQ6TWvb z{9?q}+kEM;B>~8DLE|u&#!&!05X{n9e$oQV=G4;mYQfeJuza>ta%usXOUlbFoT*K^ z7#Cl7F^bD5J&8@(4jn<(K-pBgr@QLV!tu4Z3)XYpLjLj}cmiXE1rF^on!x}7002ov JPDHLkV1oEum5KlW literal 0 HcmV?d00001 diff --git a/tff_modular/modules/vampire/icons/vampire_blooddrain.dmi b/tff_modular/modules/vampire/icons/vampire_blooddrain.dmi new file mode 100644 index 0000000000000000000000000000000000000000..3b0cb526f6e7e693ff123d5db9c67d9759c61dab GIT binary patch literal 466 zcmV;@0WJQCP)V=-0C=2JR&a84_w-Y6@%7{?OD!tS%+FJ>RWQ*r;NmRLOex6#a*U0*I5Sc+ z(=$pSoZ^zil2jm5DKRHUiHkEOv#1!zGvwk-D@x2wg|L+sT>V_Yh5`Wg-5Err*40)3 z001*kOjJd{z`y_i08s(}kpKX#3IOx~0G2;LVq#)NMMXL~I)f}MYZMfGB_$vrAm2@d z%m6!(04l=0X*K`=00DGTPE!Ct=GbNc007!aL_t(|+TGJ#5`r)c1mJGce+udSPiq== zr11pGL)htlL-RuTvj+gSn|`B04A6WNZ5gZ zUe{P{EBHGuQDyr9gfFnprU1Yc5zP*0C-#~)toP(I=db-w56bchZZnbEwg3PC07*qo IM6N<$f=TMVOaK4? literal 0 HcmV?d00001 diff --git a/tff_modular/modules/vampire/icons/vampire_command.dmi b/tff_modular/modules/vampire/icons/vampire_command.dmi new file mode 100644 index 0000000000000000000000000000000000000000..6f610a01492fa2ce5ab26ec5f0996377b4656d3b GIT binary patch literal 356 zcmV-q0h|7bP)V=-0C=2JR&a84_w-Y6@%7{?OD!tS%+FJ>RWQ*r;NmRLOex6#a*U0*I5Sc+ z(=$pSoZ^zil2jm5Nr{UyC9|j)$TZ~QOe;#vO@*+P6fGfY9(@`vw@a`6;b?%&-xF7JTn(>WC{4twlsV(*$~p=(X1jb)*c( z(8wjV_7Z?{crBT9yF{M6za(gle**dmq>lKY@ALvnqysxj7z_je0000D)!>;8N@4TkYOM>fSZ%*e~YUJ?Gs;>DoEx+bQbWI_KFj=GZaj z*emAoF}0Hb0004WQchCV=-0C=2JR&a84_w-Y6 z@%7{?OD!tS%+FJ>RWQ*r;NmRLOex6#a*U0*I5Sc+(=$pSoZ^zil2jm5Nr{UyC9|j) z$TZ~QOe;#vO$D({fTF26iIpH>0|OmH9U~n>E@cH*KNqki0GIL{R^RgQ>;M1&+(|@1 zR9J=Wmf0GDAP`1pK(u||H%oi}XACea`&dHyyqa@^dYE5?3kQH8{ts#*%iBljQpOw! z?s#c9lL5>&4bizoRnIvl2}5D6ue>n=Wf@OX9g+#d8&rAijqyTcat5Y0k63%lCdi1) zxk>&biaNr0di~G4!7$K|#xPOibT(h8aS5w+hzHng^{@lj>x;uN%%9-=yt-6F4%ZO> z<_1uh&2PRe$|w(TcWbXF2!iN}$bXloKlq+$eCp^Ayvy|V2Te@g(;tANyy>lrw|#s^ gP=D}(`U9dB59rekielTdTL1t607*qoM6N<$f=|c-x&QzG literal 0 HcmV?d00001 diff --git a/tff_modular/modules/vampire/icons/vampire_feed.dmi b/tff_modular/modules/vampire/icons/vampire_feed.dmi new file mode 100644 index 0000000000000000000000000000000000000000..89714e00d81ae708b1da62544a2f0bf4c0f28216 GIT binary patch literal 400 zcmV;B0dM|^P)V=-0C=2JR&a84_w-Y6@%7{?OD!tS%+FJ>RWQ*r;NmRLOex6#a*U0*I5Sc+ z(=$pSoZ^zil2jm5Nr{UyC9|j)$TZ~QOe;#vO@*+P6$aPsk3Lyt;Hyn-dONIJ>N)MlsAg|haez904r zyO>IKIQKp5(t%DL*dG|7&?OWD)*4t-61hg2Mc6GEnPOAsAnaZ+i?gyOD@oWLK(BQ7 uEO)@3Aia_H)N!x@_QKJuy-GgvhyMYxA_WRc#1t9;0000 zg2M`mO22;zF8KKMiI%sn*10q1gExd4Tr__0Nawtd=1GR4p57f6#zDrHjlC4+JeqW5 zQiwvZXJ@yu>gE*^Crq9^^3nD>nT zAk&9|;Xi{hx3IFZbzt+uyOt4+vIb6uJ_Xz698v*FGnNGT1v5B2yO9RubbGouhE&|T zdifyVVFe!M3o~X({rlg}zSCj)(z{#jCaG(8wd^&L*g4mpL4-k7)IgiPkF#NZf~rKl zvUvmd2li{HmN2r-k3SOL*tpzJSK#}SCAi^0>?&t;uc GLK6VL_=ZUU literal 0 HcmV?d00001 diff --git a/tff_modular/modules/vampire/icons/vampire_mesmerize.dmi b/tff_modular/modules/vampire/icons/vampire_mesmerize.dmi new file mode 100644 index 0000000000000000000000000000000000000000..ba1631b41b84e912c99b2fd182138ffb512f0b56 GIT binary patch literal 495 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dynN=YXB`&GO$wiq3C7Jno3=9=> zRFCiFYETeiyKwWji2N@1`qkbV4;Q>w$aoph=(V@5`L-p~?0dbKfn^ z;tHf^GRy>`|Ns9#{{Q&Q|1jSL%~LlqmB zh%+QGB&0DITW|smVBpvzS_`C@OM?7@85Z6-#DBdL$bIPP;uunK>+0l-MJ)t&HKZ6{ie1<_O*FwB60b!?b+z;z$lg=L;)YW}4N>h-DoUIxzS7oZW^T z0j;v;r|-Y6Qr2nR9~aU3c;`3GY26=!dA@M{ycxBCZ}$q_Jx%8YqPZt#o>IyQtGsh7 z{6y;I5LR=p{vC@CZF!xvNAS1W{e5kohF9}eESovMUN|<;%O=o##+&yxcQ_St8QCC`kOW7nt-(1iIgdzFz|Hsb6Mw<&;$S|fX-O} literal 0 HcmV?d00001 diff --git a/tff_modular/modules/vampire/icons/vampire_strength.dmi b/tff_modular/modules/vampire/icons/vampire_strength.dmi new file mode 100644 index 0000000000000000000000000000000000000000..1707e2c21ae57acc03b3d66ba0ca02eecdeae59e GIT binary patch literal 436 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dy*;OGCB`&GO$wiq3C7Jno3=9=> zRFCiFYETeiyKwWji2N@1`qkbN4;Q>w$k2>v^x9kJeA|-g^sY?qR1@2US4!e1%-B8e z#_XEz2{YW143{Wxv){T?OyOYcxj8fZmpUaWY!feUyU(;bG{EgL`?tH2F1z$*>H@7b z4)6(a1=9b)0LXvy=+dkEXKvlP_3-k}>t~mpJbCic(Iv-sHt$=PJH6H^Kf%VqDHy11 z_mcOFKy54~L4Lsu8h#CI{Sz{Q{H>lYjv*Ddu1-EJu>5NaU<31oX`Q* z+sqaRezBS5^t8|A@Rym#wPND^zm3(;!&XSDnp#MT{jEE%Ca~YV?PIYoPt8#QgHJYE z3>u8_a|6zBO<=gj_27l%#yf_dD^LAhIb$>1IW6@W>rbkNtz^*ZW?nJL^uXTo7p8(= co9o}QO8w$o6dT032Iv6>Pgg&ebxsLQ0FOJl9RL6T literal 0 HcmV?d00001 diff --git a/tff_modular/modules/vampire/icons/vampire_summon.dmi b/tff_modular/modules/vampire/icons/vampire_summon.dmi new file mode 100644 index 0000000000000000000000000000000000000000..f01893652fd8b446987f3bb3704ac8d816a8883f GIT binary patch literal 336 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyDODj6B`&GO$wiq3C7Jno3=9=> zg2M`mO22;zF8KKMiI%sn*10q1gExd4Tr__0Nawtd=1GR4p57f6#zDrHjlC4+JeqW5 zQiwvZXJ@yu>gE*^Crq9^^3nD>nT zK1qE&`vjoCLzaIoDb$L~oh&U|Gcrh8-d*C#&aqFvYWfcF- f$GsPIPtM1g_cE#UXJ3c|I)cH|)z4*}Q$iB}vyy_? literal 0 HcmV?d00001 diff --git a/tff_modular/modules/vampire/icons/vampire_trespass.dmi b/tff_modular/modules/vampire/icons/vampire_trespass.dmi new file mode 100644 index 0000000000000000000000000000000000000000..562cd9e61236ceba5b2a9185575c89beb756158d GIT binary patch literal 437 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dy*;OGCB`&GO$wiq3C7Jno3=9=> zRFCiFYETeiyKwWji2N@1`qkbN4;Q>w$k2>v^x9kJeA|-g^sY?qR1@2US4!e1%-B8e z#_XEz2{YW143{Wxv){T?OyOYcxj8fZmpUaWY!feUyU(;bG{EgL`?tH2F1z$*>H@8G z4e$wZ1=7-ek9n4z;p$n#koF&lxJtH|)xQCfKsIyW3MR`QAOk4ED4q{t0NFqWh|8YH zz!1Q|pe6C)8IZ*wSQ6wH%n+BES-0`f*)wO)oVj!F!G}))6_@*flG8n1978H@z3sWk z*JQxsdV5{7ugKkmzyJNW@(65_?EHALW%8GWmg?gFdY-ADmwNH>IBV7FmruX@^P0Mx z$eys^kVNx|4Q!!~t3ETFchu;9W4ht4%#lq7lefQF^S<41smST33@(xT+qS!NY}7eX zz_+Jp?{Oc28xB!yyL1I^G*=#sT_Eo!xY9;J$%36b=m(eO2L*OH7QcPZIG1a)ZOGo2 Rv=Hb-22WQ%mvv4FO#l(lvr7N~ literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/icons/vampiric.dmi b/tff_modular/modules/vampire/icons/vampiric.dmi similarity index 100% rename from tff_modular/modules/bloodsucker/icons/vampiric.dmi rename to tff_modular/modules/vampire/icons/vampiric.dmi diff --git a/tff_modular/modules/vampire/icons/worn.dmi b/tff_modular/modules/vampire/icons/worn.dmi new file mode 100644 index 0000000000000000000000000000000000000000..063aa5e70600747af72fa00d6a1929940a83942b GIT binary patch literal 841 zcmV-P1GfB$P)V=-0C=2JR&a84_w-Y6@%7{?OD!tS%+FJ>RWQ*r;NmRLOex6#a*U0*I5Sc+ z(=$pSoZ^zil2jm5DK|f_xFoeGqcjghCYC61ai(Mz6@&D1ai$d|=B9$!hB!3fQmw4u z>gNJ>4*=+bEhza^bj$z%076hqR7C*+0SyfeA0Hn8001c|DI_E$fPjD*85t@nDz2=o zF)=Y_5))TfS3f^LM@L64E-nTJ2BrlC*9HbeL_~%J1UoxBmrt->00001bW%=J06^y0 zW&i*JGf6~2RCwC$nBlG(ArOT*hZ%R(tG#!ZdH+`};HGJ-u+7-b{lgal%^CPa5<@op z0Z?9T_H+E5^Qj{A*w4EapiqcTPGL6}5q1Tne}S5J3P66P!WW6%yjOshA7BB1D-QrS zuzN=Syb=b3!C){L3 zSsy92@=DCPhqNr&fEDFUBNwGg&0QNi9CJq=L}31z4F5AopT;&Z!hLH4`e~ z5D3+P3t&olAuv+J%tT0o=Wi;i;c~gaGz#$|F9sDMOYYbJehEOqi<~M_9DL6AIh{|x z3G%1sd=sd$<_;*BFEfO#Tv^bXI|U>=f@)B|U=o0UOpQE7#@d39$O$uMOpJ}3#@gZ= zg1ILUk<$DEg0q5cfs$0efYKAhDnJ!Pw?MN%juTiFSW}=Z0zFQU0ZF$Y&%4goGB)B( zPzu~!cfJC08<&^CVDJtJSl2al$pt`i8`82Yk)a7=E=Vc(1zC|+v~sLDPJTh8iKf0F zsTgB$0hnrJU%;qpfKxyPd(#0^Lg^LQCa}=JHi5YX_!j}(0^)qy7o5(ZQ-D+MReA!^ zJe=SYC~7agLl&*0`ULSIU|Yb4AUXwL2#kF}EHzO76R9F#Xuu-KAb16;`vTRs1j_zT zMD+`%=|`b2s3p_n6WniQw)F&7DsFe5;PZaZie14imwoyK4}j1F*owye;y>~etmheW Te6v6=00000NkvXXu0mjfIi_8; literal 0 HcmV?d00001 diff --git a/tff_modular/modules/vampire/language.dm b/tff_modular/modules/vampire/language.dm new file mode 100644 index 00000000000..c035863bd78 --- /dev/null +++ b/tff_modular/modules/vampire/language.dm @@ -0,0 +1,21 @@ +/datum/language/vampiric + name = "Enochian" + desc = "The language of Enoch, the first city of man. It was preserved past the great flood by the antediluvians, and is now learned intuitively by Fledglings as they pass from death into immortality." + key = "l" + space_chance = 40 + default_priority = 90 + + flags = TONGUELESS_SPEECH | LANGUAGE_HIDE_ICON_IF_NOT_UNDERSTOOD + syllables = list( + "luk","cha","no","kra","pru","chi","busi","tam","pol","spu","och", + "umf","ora","stu","si","ri","li","ka","red","ani","lup","ala","pro", + "to","siz","nu","pra","ga","ump","ort","a","ya","yach","tu","lit", + "wa","mabo","mati","anta","tat","tana","prol", + "tsa","si","tra","te","ele","fa","inz", + "nza","est","sti","ra","pral","tsu","ago","esch","chi","kys","praz", + "froz","etz","tzil", + "t'","k'","t'","k'","th'","tz'" + ) + + icon_state = "vampire" + icon = 'tff_modular/modules/vampire/icons/vampiric.dmi' diff --git a/tff_modular/modules/vampire/leveling_vampire.dm b/tff_modular/modules/vampire/leveling_vampire.dm new file mode 100644 index 00000000000..52e515ab258 --- /dev/null +++ b/tff_modular/modules/vampire/leveling_vampire.dm @@ -0,0 +1,25 @@ +/** + * Called every 15 minutes or so. Give our vampire a level to spend. +**/ +/datum/antagonist/vampire/proc/give_natural_level() + if(QDELETED(owner.current) || free_levels_remaining < 1) + return + owner.current.balloon_alert(owner.current, "you have grown more ancient!") + free_levels_remaining-- + INVOKE_ASYNC(src, PROC_REF(rank_up), 1, TRUE) + +SUBSYSTEM_DEF(vampire_leveling) + name = "Vampire Leveling" + wait = 15 MINUTES + flags = SS_NO_INIT | SS_KEEP_TIMING + can_fire = FALSE + +/datum/controller/subsystem/vampire_leveling/fire(resumed = FALSE) + for(var/datum/antagonist/vampire/vampire as anything in GLOB.all_vampires) + vampire.give_natural_level() + +/datum/controller/subsystem/vampire_leveling/proc/check_enable() + if(length(GLOB.all_vampires)) + can_fire = TRUE + else + can_fire = FALSE diff --git a/tff_modular/modules/vampire/life_vampire.dm b/tff_modular/modules/vampire/life_vampire.dm new file mode 100644 index 00000000000..9b470bb2278 --- /dev/null +++ b/tff_modular/modules/vampire/life_vampire.dm @@ -0,0 +1,318 @@ +/// Runs from COMSIG_LIVING_LIFE, handles Vampire constant processes. +/datum/antagonist/vampire/proc/life_tick(datum/source, seconds_per_tick, times_fired) + SIGNAL_HANDLER + + // Weirdness shield + if(isbrain(owner?.current)) + update_hud() + return + if(QDELETED(owner)) + INVOKE_ASYNC(src, PROC_REF(handle_death)) + return + + // Deduct Blood + if(owner.current.stat == CONSCIOUS && !HAS_TRAIT(owner.current, TRAIT_IMMOBILIZED) && !HAS_TRAIT(owner.current, TRAIT_NODEATH)) + adjust_blood_volume(-VAMPIRE_PASSIVE_BLOOD_DRAIN) + + // Healing + if(handle_healing(seconds_per_tick) && !isanimal_or_basicmob(owner)) + if((COOLDOWN_FINISHED(src, vampire_spam_healing)) && current_vitae > 0) + to_chat(owner.current, span_notice("The power of your blood knits your wounds...")) + COOLDOWN_START(src, vampire_spam_healing, VAMPIRE_SPAM_HEALING) + + var/area/current_area = get_area(owner.current) + if(istype(current_area, /area/station/service/chapel) && !is_chaplain_job(owner.assigned_role) && humanity <= 2) + to_chat(owner, span_warning("Your inhuman nature is rejected by a holy presence!")) + owner.current.adjust_fire_loss(10) + owner.current.adjust_fire_stacks(4) + owner.current.ignite_mob() + + // Standard Updates + + // Clan specific stuff + if(my_clan) + my_clan.handle_clan_life() + else if(!(locate(/datum/action/cooldown/vampire/clanselect) in powers)) + grant_power(new /datum/action/cooldown/vampire/clanselect) + + // Set our body's blood_volume to mimick our vampire one (if we aren't using the Masquerade power) + update_hud() + +/** + * Pretty simple, add a value to the vampire's blood volume +**/ +/datum/antagonist/vampire/proc/adjust_blood_volume(value) + current_vitae = clamp(current_vitae + value, 0, max_vitae) + +/** + * Runs on the vampire's lifetick. + * Heal clone, brain, brute and burn damage. + * + * By default, burn damage is healed 50% as effectively as brute + * When undergoing torpor it's 80%, if you're in a coffin 100% +**/ +/datum/antagonist/vampire/proc/handle_healing(seconds_per_tick) + var/mob/living/current = owner.current + + // Weirdness shield + if(QDELETED(current)) + return FALSE + + var/in_torpor = HAS_TRAIT(current, TRAIT_TORPOR) + if(!in_torpor && HAS_TRAIT(current, TRAIT_MASQUERADE)) + return FALSE + + // oh god why + if(HAS_TRAIT_FROM(current, TRAIT_DEATHCOMA, CHANGELING_TRAIT)) + return FALSE + + var/actual_regen = vampire_regen_rate + additional_regen + + current.adjust_organ_loss(ORGAN_SLOT_BRAIN, -1 * (actual_regen * 4) * seconds_per_tick) + + if(!iscarbon(current)) + return FALSE + var/mob/living/carbon/carbon_owner = current + + var/vitaecost_multiplier = 0.5 // Coffin makes it cheaper + var/healing_multiplier = 1 + + if(carbon_owner.on_fire) + healing_multiplier = 0 + else if(HAS_TRAIT(carbon_owner, TRAIT_SLIME_HYDROPHOBIA)) + healing_multiplier = 0.75 + + var/brute_heal = min(carbon_owner.get_brute_loss(), actual_regen) + var/burn_heal = min(carbon_owner.get_fire_loss(), actual_regen) * (HAS_TRAIT(carbon_owner, TRAIT_NOFIRE) ? 0.3 : 0.5) // if they have nofire, they get less innate burn healing as a compromise + + if(length(carbon_owner.all_wounds)) + var/datum/wound/bloodiest_wound + for(var/datum/wound/wound as anything in carbon_owner.all_wounds) + if(wound.blood_flow && (!bloodiest_wound || wound.blood_flow > bloodiest_wound?.blood_flow)) + bloodiest_wound = wound + + bloodiest_wound?.adjust_blood_flow(-0.25 * seconds_per_tick) + + for(var/obj/item/bodypart/bodypart as anything in carbon_owner.bodyparts) + if(bodypart.generic_bleedstacks) + bodypart.adjustBleedStacks(-1, 0) + + if(in_torpor) + // If in a coffin: heal 5x as fast, heal burn damage at full capacity, set vitaecost to 50%, and regenerate limbs + // If not: heal 3x as fast and heal burn damage at 80% + if(istype(carbon_owner.loc, /obj/structure/closet/crate/coffin)) + if(HAS_TRAIT(owner.current, TRAIT_MASQUERADE) && COOLDOWN_FINISHED(src, vampire_spam_healing)) + to_chat(carbon_owner, span_alert("You do not heal while your Masquerade ability is active.")) + COOLDOWN_START(src, vampire_spam_healing, VAMPIRE_SPAM_MASQUERADE) + return FALSE + + burn_heal = min(carbon_owner.get_fire_loss(), actual_regen) + healing_multiplier = 5 + vitaecost_multiplier = 0.25 // Decrease cost if we're sleeping in a coffin. + + // Extinguish and remove embedded objects + carbon_owner.extinguish_mob() + carbon_owner.remove_all_embedded_objects() + + if(try_regenerate_limbs(vitaecost_multiplier)) + return TRUE + else + burn_heal = min(carbon_owner.get_fire_loss(), actual_regen) * 0.8 + healing_multiplier = 3 + + // Heal if Damaged + brute_heal *= healing_multiplier + burn_heal *= healing_multiplier + + if(brute_heal > 0 || burn_heal > 0) // Just a check? Don't heal/spend, and return. + var/vitaecost = (brute_heal * 0.5 + burn_heal) * vitaecost_multiplier * healing_multiplier + carbon_owner.heal_overall_damage(brute_heal * seconds_per_tick, burn_heal * seconds_per_tick) + adjust_blood_volume(-vitaecost) + return TRUE + + // Revive them if dead and there is no damage left to heal, just in case we are not in torpor because of some wackyness. + // Note this doesn't revive when staked. + if(carbon_owner.stat == DEAD && !in_torpor) + heal_vampire_organs() + return TRUE + + return FALSE + +/datum/antagonist/vampire/proc/try_regenerate_limbs(cost_muliplier = 1) + var/mob/living/carbon/carbon_owner = owner.current + if(!iscarbon(carbon_owner) || QDELING(carbon_owner)) + return + var/limb_regen_cost = 50 * -cost_muliplier + + var/list/missing = carbon_owner.get_missing_limbs() + if(length(missing) && (current_vitae < limb_regen_cost + 5)) + return FALSE + for(var/missing_limb in missing) //Find ONE Limb and regenerate it. + carbon_owner.regenerate_limb(missing_limb, FALSE) + adjust_blood_volume(-limb_regen_cost) + var/obj/item/bodypart/missing_bodypart = carbon_owner.get_bodypart(missing_limb) + if(missing_limb == BODY_ZONE_HEAD) + ensure_brain_nonvital(carbon_owner) + else + missing_bodypart.receive_damage(brute = 60, wound_bonus = CANT_WOUND) + to_chat(carbon_owner, span_notice("Your flesh knits as it regrows your [missing_bodypart]!")) + playsound(carbon_owner, 'sound/effects/magic/demon_consume.ogg', 50, TRUE) + return TRUE + +/** + * This is used when exiting Torpor and when given vampire status, these are the steps of this proc: + * Step 1 - Cure husking and Regenerate organs. regenerate_organs() removes their Vampire Heart & Eye augments, which leads us to... + * Step 2 - Repair any (shouldn't be possible) Organ damage, then return their Vampiric Heart & Eye benefits. + * Step 3 - Revive them, clear all wounds, remove any Tumors (If any). +**/ +/datum/antagonist/vampire/proc/heal_vampire_organs() + var/mob/living/carbon/carbon_user = owner.current + if(!istype(carbon_user)) + return + + // Clear husk and regenerate organs + carbon_user.cure_husk() + carbon_user.regenerate_organs() + ensure_brain_nonvital(carbon_user) + + // Heal organs + for(var/obj/item/organ/organ as anything in carbon_user.organs) + organ.set_organ_damage(0) + + // Heart + if(!HAS_TRAIT(carbon_user, TRAIT_MASQUERADE)) + var/obj/item/organ/heart/current_heart = carbon_user.get_organ_slot(ORGAN_SLOT_HEART) + current_heart?.Stop() + + // Heal wounds + for(var/datum/wound/iter_wound as anything in carbon_user.all_wounds) + iter_wound.remove_wound() + for(var/obj/item/organ/organ as anything in carbon_user.organs) + + organ.Remove(carbon_user) + organ.forceMove(carbon_user.drop_location()) + + // Don't Revive if staked or being staked + if(carbon_user.stat == DEAD && COOLDOWN_FINISHED(src, revive_cooldown) && !check_if_staked() && !HAS_TRAIT(carbon_user, TRAIT_BEINGSTAKED)) + carbon_user.revive() + // Heal suffocation + carbon_user.set_oxy_loss(0) + +/** + * Called when we die +**/ +/datum/antagonist/vampire/proc/on_death(mob/living/source, gibbed) + SIGNAL_HANDLER + + if(source.stat != DEAD) // weirdness shield + return + + COOLDOWN_START(src, revive_cooldown, 25 SECONDS) // ensure we take at minimum 25 seconds to revive. + INVOKE_ASYNC(src, PROC_REF(handle_death)) + +/datum/antagonist/vampire/proc/handle_death() + if(QDELETED(owner.current)) + return + if(check_if_staked()) + final_death() + else + owner.current.apply_status_effect(/datum/status_effect/vampire_torpor) + +/** + * Handle things related to blood + * + * Step 1 - Set nutrition to our blood level + * Step 2 - If we are in a frenzy, check if we have enough blood to exit it + * Step 3 - If we have too little blood, enter a frenzy + * Step 4 - If we're low on blood, start jittering + * Step 5 - Set regeneration rate based off how much blood we have +**/ +/datum/antagonist/vampire/proc/handle_blood() + SIGNAL_HANDLER + // Set nutrition + owner.current.set_nutrition(min(current_vitae, NUTRITION_LEVEL_WELL_FED)) + + if(HAS_TRAIT(owner.current, TRAIT_MASQUERADE)) + owner.current.blood_volume = BLOOD_VOLUME_NORMAL + else + owner.current.blood_volume = clamp(current_vitae, BLOOD_VOLUME_BAD, BLOOD_VOLUME_NORMAL) // we want to get pale but not completely fucked up + + // Try and exit frenzy + if(current_vitae >= FRENZY_THRESHOLD_EXIT) + owner.current.remove_status_effect(/datum/status_effect/frenzy) + + // Blood is low, lets show some effects + if(current_vitae < 100 && !HAS_TRAIT(owner.current, TRAIT_MASQUERADE)) + owner.current.set_jitter_if_lower(6 SECONDS) + + // Enter frenzy if our blood is low enough + if(current_vitae < FRENZY_THRESHOLD_ENTER && COOLDOWN_FINISHED(src, frenzy_cooldown)) + owner.current.apply_status_effect(/datum/status_effect/frenzy) + + // Warn them at low blood + if(current_vitae < VAMPIRE_LOW_BLOOD_WARNING && !low_blood_alerted) + owner.current.playsound_local(null, 'tff_modular/modules/vampire/sound/bloodneed.ogg', 100, FALSE, pressure_affected = FALSE) + to_chat(owner.current, span_narsiesmall("Care now. Your vitae runs low!"), type = MESSAGE_TYPE_WARNING) + low_blood_alerted = TRUE + else if(current_vitae > VAMPIRE_LOW_BLOOD_WARNING) + low_blood_alerted = FALSE + + // The more blood, the better the regeneration + if(current_vitae < BLOOD_VOLUME_BAD) + additional_regen = 0.1 + else if(current_vitae < BLOOD_VOLUME_OKAY) + additional_regen = 0.2 + else if(current_vitae < BLOOD_VOLUME_NORMAL) + additional_regen = 0.3 + else if(current_vitae < BS_BLOOD_VOLUME_MAX_REGEN) + additional_regen = 0.4 + else + additional_regen = 0.5 + + return HANDLE_BLOOD_NO_NUTRITION_DRAIN | HANDLE_BLOOD_NO_OXYLOSS + +/// dust +/datum/antagonist/vampire/proc/final_death(skip_destruction = FALSE) + var/mob/living/body = owner.current + // If we have no body, end here. + if(QDELETED(body)) + return + + UnregisterSignal(body, list( + COMSIG_LIVING_LIFE, + COMSIG_ATOM_EXAMINE, + COMSIG_LIVING_DEATH, + COMSIG_HUMAN_ON_HANDLE_BLOOD, + COMSIG_MOVABLE_MOVED, + COMSIG_LIVING_APPRAISE_ART, + )) + + final_death = TRUE + free_all_vassals() + + if(!skip_destruction) + if(iscarbon(body)) + // Drop anything in us + var/mob/living/carbon/carbon_body = body + carbon_body.drop_all_held_items() + carbon_body.unequip_everything() + carbon_body.remove_all_embedded_objects() + playsound(owner.current, 'tff_modular/modules/vampire/sound/burning_death.ogg', 100, TRUE) + else + body.dust(drop_items = TRUE) + + if(SEND_SIGNAL(src, COMSIG_VAMPIRE_FINAL_DEATH) & DONT_DUST) + return + + if(skip_destruction || QDELETED(body)) + return + + // Get dusted lmao + body.visible_message( + span_warning("[body]'s skin crackles and dries, [body.p_their()] skin and bones withering to dust. A hollow cry whips from what is now a sandy pile of remains."), + span_userdanger("Your soul escapes your withering body as the abyss welcomes you to your Final Death."), + span_hear("You hear a dry, crackling sound.") + ) + + body.remove_status_effect(/datum/status_effect/vampire_torpor) + body.dust(just_ash = FALSE, drop_items = TRUE) diff --git a/tff_modular/modules/vampire/misc_procs_vampire.dm b/tff_modular/modules/vampire/misc_procs_vampire.dm new file mode 100644 index 00000000000..1b4c8298e55 --- /dev/null +++ b/tff_modular/modules/vampire/misc_procs_vampire.dm @@ -0,0 +1,571 @@ +/** + * Helper proc for adding a power +**/ +/datum/antagonist/vampire/proc/grant_power(datum/action/cooldown/vampire/power) + for(var/datum/action/cooldown/vampire/current_powers as anything in powers) + if(current_powers.type == power.type) + return FALSE + powers += power + + power.Grant(owner.current) + log_vampire_power("[key_name(owner.current)] has purchased: [power].") + update_static_data_for_all_viewers() + return TRUE + +/** + * Helper proc for removing a power +**/ +/datum/antagonist/vampire/proc/remove_power(datum/action/cooldown/vampire/power) + if(power.currently_active) + power.deactivate_power() + powers -= power + power.Remove(owner.current) + update_static_data_for_all_viewers() + +/** + * When a Vampire breaks the Masquerade, they get their HUD icon changed, and Malkavian Vampires get alerted. +**/ +/datum/antagonist/vampire/proc/break_masquerade(mob/admin) + if(broke_masquerade) + return + broke_masquerade = TRUE + + owner.current.playsound_local(null, 'tff_modular/modules/vampire/sound/masquerade_violation.ogg', 100, FALSE, pressure_affected = FALSE) + to_chat(owner.current, span_userdanger("You have broken the Masquerade!")) + to_chat(owner.current, span_warning("Vampire Tip: When you break the Masquerade, you become open for termination by fellow Vampires, and your vassals are no longer completely loyal to you, as other Vampires can steal them for themselves!")) + + add_team_hud(owner.current) + + SEND_GLOBAL_SIGNAL(COMSIG_VAMPIRE_BROKE_MASQUERADE, src) + GLOB.masquerade_breakers += src + +/** + * Increment the masquerade infraction counter and warn the vampire accordingly +**/ +/datum/antagonist/vampire/proc/give_masquerade_infraction(ignore_cooldown = FALSE) + if(broke_masquerade) + return + if(!ignore_cooldown) + if(!COOLDOWN_FINISHED(src, masquerade_infraction_cooldown)) + return + COOLDOWN_START(src, masquerade_infraction_cooldown, 90 SECONDS) + masquerade_infractions++ + + owner.current.playsound_local(null, 'tff_modular/modules/vampire/sound/lunge_warn.ogg', 100, FALSE, pressure_affected = FALSE) + + if(masquerade_infractions >= 3) + break_masquerade() + else + to_chat(owner.current, span_cult_bold("You violated the Masquerade! Break the Masquerade [3 - masquerade_infractions] more times and you will become hunted by all other Vampires!")) + +/** + * Offers the vampire the option to thicken their blood if they've reached their vitae goal. + * Called when the vampire sleeps in a coffin. +**/ +/datum/antagonist/vampire/proc/rank_up_if_goal() + while(vitae_goal_progress >= current_vitae_goal) + if(!rank_up(1)) + return + +/** + * Increase our unspent vampire levels by one and try to rank up if inside a coffin + * Called when sleeping in a coffin, and admin abuse +**/ +/datum/antagonist/vampire/proc/rank_up(levels, ignore_reqs = FALSE) + if(QDELETED(owner) || QDELETED(owner.current)) + return FALSE + + if(vitae_goal_progress < current_vitae_goal && !ignore_reqs) + to_chat(owner.current, span_notice("Your lack of experience has left you unable to level up. Fulfill your vitae goal next time in order to level up.")) + return FALSE + + vampire_level_unspent += levels + for(var/limb_slot, current_limb in affected_limbs) + var/obj/item/bodypart/limb = current_limb + if(QDELETED(limb) || !(limb_slot in BODY_ZONES_LIMBS)) + continue + // This affects the hitting power of regular unarmed attacks and Brawn. + limb.unarmed_damage_low += extra_damage_per_rank + limb.unarmed_damage_high += extra_damage_per_rank + + if(!my_clan) + to_chat(owner.current, span_notice("You have grown in power. Join a clan to spend it.")) + return FALSE + + to_chat(owner, span_notice("You have grown familiar with your powers!")) + + if(!ignore_reqs) + vitae_goal_progress = max(vitae_goal_progress - current_vitae_goal, 0) + /* else + vitae_goal_progress = 0 */ + current_vitae_goal += VITAE_GOAL_STANDARD + + return TRUE + +/** + * Decrease the unspent vampire levels by one. Only for admins +**/ +/datum/antagonist/vampire/proc/rank_down() + vampire_level_unspent-- + +/datum/antagonist/vampire/proc/remove_nondefault_powers(return_levels = FALSE) + for(var/datum/action/cooldown/vampire/power as anything in powers) + if(power.special_flags & VAMPIRE_DEFAULT_POWER) + continue + remove_power(power) + if(return_levels) + vampire_level_unspent++ + +/** + * Disables all Torpor exclusive powers, if forced is TRUE, disable all powers +**/ +/datum/antagonist/vampire/proc/disable_all_powers(forced = FALSE) + for(var/datum/action/cooldown/vampire/power as anything in powers) + if(forced || ((power.vampire_check_flags & BP_CANT_USE_IN_TORPOR) && HAS_TRAIT(owner.current, TRAIT_TORPOR))) + if(power.currently_active) + power.deactivate_power() + +/** + * Check if we have a stake in our heart +**/ +/datum/antagonist/vampire/proc/check_if_staked() + var/obj/item/bodypart/chosen_bodypart = owner.current?.get_bodypart(BODY_ZONE_CHEST) + if(locate(/obj/item/stake) in chosen_bodypart?.embedded_objects) + return TRUE + return FALSE +/** + * ##adjust_humanity(count, silent) + * + * Adds the specified amount of humanity to the vampire + * Checks to make sure it doesn't exceed 10, + * Checks to make sure it doesn't go under 0, + * Adds the masquerade power at 9 or above + */ +/datum/antagonist/vampire/proc/adjust_humanity(count, silent = FALSE) + // Step one: Toreadors have doubled gains and losses + if(istype(my_clan, /datum/vampire_clan/toreador)) + count = count * 2 + + // No-op if nothing to change + if(count == 0) + return FALSE + + // If trying to add but already at max, there's nothing to do + if(count > 0 && humanity >= 10) + return FALSE + + // Same for removing + if(count < 0 && humanity <= 0) + return FALSE + + var/temp_humanity = humanity + count + + var/power_given = FALSE + var/power_removed = FALSE + + // Are we adding or removing? + if(count > 0) + // We are adding + if(temp_humanity >= VAMPIRE_HUMANITY_MASQUERADE_POWER && !is_type_in_list(/datum/action/cooldown/vampire/masquerade, powers)) + // Grant_power might fail, so we need to check if it actually got granted + var/was_granted = grant_power(new /datum/action/cooldown/vampire/masquerade) + if(was_granted) + power_given = TRUE + + // Only run this code if there is an actual increase in humanity. Also don't run it if we wanna be silent. + if(humanity < temp_humanity && !silent) + owner.current.playsound_local(null, 'tff_modular/modules/vampire/sound/humanity_gain.ogg', 50, TRUE, pressure_affected = FALSE) + if(power_given) + to_chat(owner.current, span_userdanger("Your closeness to humanity has granted you the ability to feign life!")) + else + to_chat(owner.current, span_userdanger("You have gained humanity.")) + else + // We are removing + if(temp_humanity < VAMPIRE_HUMANITY_MASQUERADE_POWER) + for(var/datum/action/cooldown/vampire/masquerade/power in powers) + remove_power(power) + power_removed = TRUE + + // Only run this code if there is an actual decrease in humanity + if(humanity > temp_humanity && !silent) + owner.current.playsound_local(null, 'tff_modular/modules/vampire/sound/humanity_loss.ogg', 50, TRUE, pressure_affected = FALSE) + if(power_removed) + to_chat(owner.current, span_userdanger("Your inhuman actions have caused you to lose the masquerade ability!")) + else + to_chat(owner.current, span_userdanger("You have lost humanity.")) + + // Clamp to valid range, we are so sane we might see the face of god + if(temp_humanity > 10) + temp_humanity = 10 + if(temp_humanity < 0) + temp_humanity = 0 + + humanity = temp_humanity + return TRUE + +/// Bacon wanted a signal +/datum/antagonist/vampire/proc/on_track_humanity_gain_signal(datum/source, type, subject) + SIGNAL_HANDLER + return track_humanity_gain_progress(type, subject) + +/// Signal handler for when the vampire pets an animal +/datum/antagonist/vampire/proc/on_pet_animal(datum/source, mob/living/pet) + SIGNAL_HANDLER + return track_humanity_gain_progress(HUMANITY_PETTING_TYPE, pet) + +/// Signal handler for when the vampire hugs a carbon +/datum/antagonist/vampire/proc/on_hug_carbon(datum/source, mob/living/carbon/hugged) + SIGNAL_HANDLER + if(!hugged.client) // Only count hugs with real players for humanity + return + return track_humanity_gain_progress(HUMANITY_HUGGING_TYPE, hugged) + +/// Signal handler for when the vampire appraises art +/datum/antagonist/vampire/proc/on_appraise_art(datum/source, atom/art_piece) + SIGNAL_HANDLER + return track_humanity_gain_progress(HUMANITY_ART_TYPE, art_piece) + +/** + * ##track_humanity_gain_progress(type, subject) + * + * Adds the specified subject to the tracking lists and handles all the other stuff related to it. + * When a defined threshold is met, hands out humanity as appropriate and stops tracking. + * Ideally this can be expanded on easily by just defining a new threshold and tracking list in the datum and defines respectively. + * We return TRUE if it successfully added to tracked, and FALSE if it was already tracked or failed for some other reason. + */ +/datum/antagonist/vampire/proc/track_humanity_gain_progress(type, subject) + // placeholders to populate // I dunno why this works btw, i thought i made a mistake but it worked anyways. + var/list/tracking_list = null + var/goal = null + + if(humanity >= 10) // Don't add anything if we're already at max. + return + + // map all the placeholders to the correct type, get the list for easier handling + switch(type) + if(HUMANITY_HUGGING_TYPE) + tracking_list = humanity_trackgain_hugged + goal = humanity_hugging_goal + if(HUMANITY_PETTING_TYPE) + tracking_list = humanity_trackgain_petted + goal = humanity_petting_goal + if(HUMANITY_ART_TYPE) + tracking_list = humanity_trackgain_art + goal = humanity_art_goal + else + return FALSE // Cheeky check for type built in? Tsunami you genius! + + if(isatom(subject)) + var/atom/atom_subject = subject + if(atom_subject.flags_1 & HOLOGRAM_1) // doesn't count!! + return FALSE + + // track the weakref, not the actual reference + subject = WEAKREF(subject) + + // already tracked? + if(subject in tracking_list) + return FALSE + + // Update the corresponding list + switch(type) + if(HUMANITY_HUGGING_TYPE) + humanity_trackgain_hugged += subject + if(HUMANITY_PETTING_TYPE) + humanity_trackgain_petted += subject + if(HUMANITY_ART_TYPE) + humanity_trackgain_art += subject + + if(length(tracking_list) >= goal) + // set the corresponding gained flag and award humanity + switch(type) + if(HUMANITY_HUGGING_TYPE) + humanity_hugging_goal *= 2 + if(HUMANITY_PETTING_TYPE) + humanity_petting_goal *= 2 + if(HUMANITY_ART_TYPE) + humanity_art_goal *= 2 + adjust_humanity(1) + + return TRUE + +/datum/antagonist/vampire/proc/get_rank_string() + switch(vampire_level) + if(0 to 1) + return "'Initiate'" + if(2 to 3) + return "'Novice'" + if(4 to 5) + return "'Apprentice'" + if(6 to 7) + return "'Adept'" + if(8 to 9) + return "'Expert'" + if(10 to 11) + return "'Master'" + if(12 to 24) + return "'Grand Master'" + if(25 to INFINITY) + return "[span_narsiesmall("'Methuselah'")]" + +/// This is where we store clan descriptions. +/// We will need to know the description of a clan before we "make" one, +/// because we can't just get the description from the "not-made" clan ref. +/datum/antagonist/vampire/proc/get_clan_description(clan_name) + /// This makes descriptions about a billion times cleaner: Spans for discipline names and their individual descriptions: + var/disciplines = "[span_tooltip("Disciplines are the aspects of the original curse bestowed upon caine, of which every kindred suffers/benefits. In terms of gameplay, they are groups of abilities that you level up.", "Disciplines")]" + var/animalism = "[span_tooltip("Animalism is a Discipline that brings the vampire closer to their animalistic nature. This typically allows them to communicate with and gain dominance over creatures of nature.", "Animalism")]" + var/auspex = "[span_tooltip("Auspex is a Discipline that grants vampires supernatural senses, letting them peer far further and deeper than any mortal. The malkavians especially have a strong bond with it.", "Auspex")]" + var/celerity = "[span_tooltip("Celerity is a Discipline that grants vampires supernatural quickness and reflexes.", "Celerity")]" + var/dominate = "[span_tooltip("Dominate is a Discipline that overwhelms another person's mind with the vampire's will.", "Dominate")]" + var/fortitude = "[span_tooltip("Fortitude is a Discipline that grants Kindred unearthly toughness.", "Fortitude")]" + var/obfuscate = "[span_tooltip("Obfuscate is a Discipline that allows vampires to conceal themselves, deceive the mind of others, or make them ignore what the user does not want to be seen.", "Obfuscate")]" + var/potence = "[span_tooltip("Potence is the Discipline that endows vampires with physical vigor and preternatural strength.", "Potence")]" + var/presence = "[span_tooltip("Presence is the Discipline of supernatural allure and emotional manipulation which allows Kindred to attract, sway, and control crowds.", "Presence")]" + var/protean = "[span_tooltip("Protean is a Discipline that gives vampires the ability to change form, from growing feral claws to turning into something entirely different.", "Protean")]" + var/thaumaturgy = "[span_tooltip("Thaumaturgy is the secret blood-art of the clan tremere. Allowing them all manners of blood-sorcery and pacts.", "Thaumaturgy")]" + + /// All the descriptions: + var/ventrue = "The Ventrue are the de-facto leaders of the Camarilla. They style themselves as kings and emperors, often inhabiting positions of power.\n\ + IMPORTANT: Members of the Ventrue Clan are the most eligible for princedom. Please remember that princes are expected to behave in a manner befitting their office.\n\ + [disciplines]: [dominate], [fortitude], [presence]" + var/tremere = "With a powerful ancestry of wizards and magicians, the Tremere wield the secret art of blood magic, which they guard with utmost care.\n\ + [disciplines]: [thaumaturgy], [auspex], [dominate]" + var/toreador = "Artists, Pleasure-workers, Celebrities. These are the people of the Toreador clan. They are by far the closest to humanity of all kindred, each a deeply sensitive individual.\n\ + [disciplines]: [presence], [auspex], [celerity]" + var/malkavian = "Completely insane. You gain constant hallucinations, become a prophet with unintelligable rambling, and gain insights better left unknown. You can also travel through Phobetor tears, rifts through spacetime only you can travel through.\n\ + [disciplines]: [dominate], [auspex], [obfuscate]" + var/gangrel = "Often mistaken as werewolves, Gangrel carry the smell of wet dog wherever they go. Their unique bond with the beast within allows them to transform parts of their body into powerful claws, even becoming entirely different beings.\n\ + [disciplines]: [animalism], [protean], [fortitude]" + var/brujah = "A clan now, of mostly rebels. Though some still show fragments of their lost lineage of warrior-poets. They are long split from the Camarilla, and often form their own groups.\n\ + [disciplines]: [potence], [celerity], [presence]" + + // Now the logic + switch(clan_name) + if(CLAN_TOREADOR) + return toreador + if(CLAN_VENTRUE) + return ventrue + if(CLAN_BRUJAH) + return brujah + if(CLAN_MALKAVIAN) + return malkavian + if(CLAN_TREMERE) + return tremere + if(CLAN_GANGREL) + return gangrel + + log_runtime("Unknown clan name passed to get_clan_description: [clan_name]") + return "No description available." + +/// Checks to see if an entity counts as a "watcher" for a masquerade breach +/datum/antagonist/vampire/proc/is_masq_watcher(mob/living/watcher, recursion = 1) + /// List of "weirdo" antags who won't count as masq breaks due to also being supernaturals or supernatural-adjacent. + var/static/list/weirdo_antags = list( + /datum/antagonist/changeling, + /datum/antagonist/heretic, + /datum/antagonist/heretic_monster, + /datum/antagonist/nightmare, + /datum/antagonist/wizard, + ) + + if(!isliving(watcher) || QDELING(watcher)) + return FALSE + if(!watcher.mind || !watcher.client || watcher.client.is_afk()) + return FALSE + if(HAS_MIND_TRAIT(watcher, TRAIT_VAMPIRE_ALIGNED)) + return FALSE + if((FACTION_VAMPIRE in watcher.faction) || (REF(owner.current) in watcher.faction)) + return FALSE + if(watcher.mind.has_antag_datum_in_list(weirdo_antags)) + return FALSE + if(isanimal_or_basicmob(watcher)) + return FALSE + if(watcher.stat != CONSCIOUS || HAS_TRAIT(watcher, TRAIT_RESTRAINED)) + return FALSE + if(is_jaunting(watcher) || HAS_TRAIT(watcher, TRAIT_MOVE_VENTCRAWLING)) + return FALSE + if(watcher.is_blind() || watcher.is_nearsighted_currently()) + return FALSE + if(HAS_SILICON_ACCESS(watcher)) + return FALSE + if(watcher in owner.current?.get_all_linked_holoparasites()) + return FALSE + if(recursion > 0) + var/mob/living/master = watcher.mind.enslaved_to?.resolve() + if(master) + return .(master, recursion - 1) + return TRUE + +/** + * Called when a Vampire reaches Final Death + * Releases all Vassals. + */ +/datum/antagonist/vampire/proc/free_all_vassals() + for(var/datum/antagonist/vassal/all_vassals in vassals) + all_vassals.owner.remove_antag_datum(/datum/antagonist/vassal) + +//Returns an in proportion scaled out view, with zoom_amt extra tiles on the y axis. +/proc/get_zoomed_view(view, zoom_amt) + var/view_x + var/view_y + if(IS_SAFE_NUM(view)) + return view + zoom_amt + else + var/list/viewrangelist = splittext(view, "x") + view_x = text2num(viewrangelist[1]) + view_y = text2num(viewrangelist[2]) + var/proportion = view_x / view_x + view_x += zoom_amt * proportion + view_y += zoom_amt + //God, I hate that we have to round this. + return "[round(view_x, 1)]x[round(view_y, 1)]" + +/mob/living/carbon/human/proc/backup_clothing_prefs() as /alist + return alist( + "underwear" = underwear, + "underwear_color" = underwear_color, + "undershirt" = undershirt, + "socks" = socks, + "socks_color" = socks_color, + "jumpsuit_style" = jumpsuit_style, + ) + +/mob/proc/incapacitated(flags) + return + +/mob/living/incapacitated(flags) + if(!(flags & IGNORE_RESTRAINTS) && HAS_TRAIT(src, TRAIT_RESTRAINED)) + return TRUE + if(!(flags & IGNORE_GRAB) && pulledby?.grab_state >= GRAB_AGGRESSIVE) + return TRUE + if(!(flags & IGNORE_STASIS) && HAS_TRAIT(src, TRAIT_STASIS)) + return TRUE + + if(flags & IGNORE_SOFTCRIT) + if((stat <= SOFT_CRIT) && !(HAS_TRAIT_NOT_FROM(src, TRAIT_INCAPACITATED, STAT_TRAIT))) + return FALSE + + if(HAS_TRAIT(src, TRAIT_INCAPACITATED)) + return TRUE + + return FALSE + +/mob/living/proc/blood_particles(amount = rand(1, 3), angle = rand(0,360), min_deviation = -30, max_deviation = 30, min_pixel_z = 0, max_pixel_z = 6) + if(QDELETED(src) || !isturf(loc) || !blood_volume || HAS_TRAIT(src, TRAIT_NOBLOOD)) + return + var/list/blood_dna = get_blood_dna_list() + var/blood_color = get_blood_type()?.color + for(var/i in 1 to amount) + var/obj/effect/decal/cleanable/blood/particle/droplet = new(loc) + if(QDELETED(droplet)) // if they're deleting upon init, let's not waste any more time, any others will prolly just do the same thing + return + droplet.color = blood_color + if(blood_dna) + droplet.add_blood_DNA(blood_dna) + droplet.pixel_z = rand(min_pixel_z, max_pixel_z) + droplet.start_movement(angle + rand(min_deviation, max_deviation)) + +//Just new and forget +//Depricated, use movement loops instead. Exists to support things that want to move more then 10 times a second +/datum/forced_movement + var/atom/movable/victim + var/atom/target + var/last_processed + var/steps_per_tick + var/allow_climbing + var/datum/callback/on_step + var/moved_at_all = FALSE + //as fast as ssfastprocess +/datum/forced_movement/New(atom/movable/_victim, atom/_target, _steps_per_tick = 0.5, _allow_climbing = FALSE, datum/callback/_on_step = null) + victim = _victim + target = _target + steps_per_tick = _steps_per_tick + allow_climbing = _allow_climbing + on_step = _on_step + + . = ..() + + if(_victim && _target && _steps_per_tick && !_victim.force_moving) + last_processed = world.time + _victim.force_moving = src + START_PROCESSING(SSfastprocess, src) + else + qdel(src) //if you want to overwrite the current forced movement, call qdel(victim.force_moving) before creating this + +/datum/forced_movement/Destroy() + if(victim.force_moving == src) + victim.force_moving = null + if(moved_at_all) + victim.forceMove(victim.loc) //get the side effects of moving here that require us to currently not be force_moving aka reslipping on ice + STOP_PROCESSING(SSfastprocess, src) + victim = null + target = null + on_step = null + return ..() + +//Todo: convert +/datum/forced_movement/process() + if(QDELETED(victim) || !victim.loc || QDELETED(target) || !target.loc) + qdel(src) + return + var/steps_to_take = round(steps_per_tick * (world.time - last_processed)) + if(steps_to_take) + for(var/i in 1 to steps_to_take) + if(TryMove()) + moved_at_all = TRUE + if(on_step) + on_step.InvokeAsync() + else + qdel(src) + return + last_processed = world.time + +/datum/forced_movement/proc/TryMove(recursive = FALSE) + if(QDELETED(src)) //Our previous step caused deletion of this datum + return + + var/atom/movable/vic = victim //sanic + var/atom/tar = target + + if(!recursive) + . = step_towards(vic, tar) + + //shit way for getting around corners + if(!.) //If stepping towards the target failed + if(tar.x > vic.x) //If we're going x, step x + if(step(vic, EAST)) + . = TRUE + else if(tar.x < vic.x) + if(step(vic, WEST)) + . = TRUE + + if(!.) //If the x step failed, go y + if(tar.y > vic.y) + if(step(vic, NORTH)) + . = TRUE + else if(tar.y < vic.y) + if(step(vic, SOUTH)) + . = TRUE + + if(!.) //If both failed, try again for some reason + if(recursive) + return FALSE + else + . = TryMove(TRUE) + + . = . && (vic.loc != tar.loc) + +/atom/movable + var/datum/forced_movement/force_moving = null + +/// Restores the clothing prefs from an alist returned by backup_clothing_prefs() +/mob/living/carbon/human/proc/restore_clothing_prefs(alist/backup) + if(length(backup) != 6) + CRASH("Invalid clothing backup alist passed, expected 6 entries!") + underwear = backup["underwear"] + underwear_color = backup["underwear_color"] + undershirt = backup["undershirt"] + socks = backup["socks"] + socks_color = backup["socks_color"] + jumpsuit_style = backup["jumpsuit_style"] diff --git a/tff_modular/modules/vampire/monitor.dm b/tff_modular/modules/vampire/monitor.dm new file mode 100644 index 00000000000..9f3764b9d13 --- /dev/null +++ b/tff_modular/modules/vampire/monitor.dm @@ -0,0 +1,820 @@ +#define ALT_APPEARENCE_ID "team_monitor" + +//================== +// Helpers +//================== + +//A list that tracks everything that should be tracked by team monitors +//Assoc list: +// Key = Frequency +// Value = Components +GLOBAL_LIST_EMPTY(tracker_huds) +GLOBAL_LIST_EMPTY(tracker_beacons) + +//Gets the first free team element, useful for creating new teams +//Special key is for what kind of team frequency it should be +//Everything that has a team monitor can be configured to change what frequency it tracks on +//The special key can be used to make keys like synd5 or synd83 to prevent centcom tracking syndies. +/proc/get_free_team_frequency(special_key = "") + var/sanity = 5 + //5 attempts to find a free team element, should never get that far + while(sanity > 0) + sanity -- + var/random_id = rand(1, 999) + var/key = "[random_id]" + if(!GLOB.tracker_beacons.Find("[special_key][key]")) + return key + //Return something anyways + var/random_id = rand(1, 999) + var/key = "[random_id]" + return key + +//Adds a new tracking hud +/proc/add_tracker_hud(frequency_added, datum/component/component_added) + if(!frequency_added) + return + if(islist(GLOB.tracker_huds[frequency_added])) + GLOB.tracker_huds[frequency_added] |= component_added + else + GLOB.tracker_huds[frequency_added] = list(component_added) + +//Adds a new tracking beacon +/proc/add_tracker_beacon(frequency_added, datum/component/component_added) + if(!frequency_added) + return + if(islist(GLOB.tracker_beacons[frequency_added])) + GLOB.tracker_beacons[frequency_added] |= component_added + else + GLOB.tracker_beacons[frequency_added] = list(component_added) + +/proc/get_all_beacons_on_frequency(frequency, base_frequency) + if(!frequency) + return GLOB.tracker_beacons["[base_frequency]-GLOB"] + var/list/found_beacons = list() + if(islist(GLOB.tracker_beacons[frequency])) + found_beacons.Add(GLOB.tracker_beacons[frequency]) + if(islist(GLOB.tracker_beacons["[base_frequency]-GLOB"])) + found_beacons.Add(GLOB.tracker_beacons["[base_frequency]-GLOB"]) + return found_beacons + +/proc/get_all_watchers_on_frequency(frequency, team_key = "", global_freq = FALSE) + if(global_freq) + . = list() + for(var/tracker_freq in GLOB.tracker_huds) + for(var/datum/component/team_monitor/TM as() in GLOB.tracker_huds[tracker_freq]) + if(TM.team_freq_key == team_key) + . += TM + else + return GLOB.tracker_huds[frequency] + +//================== +// Component +// - HUD COMPONENT +// - HANDLES POINTING TOWARDS TRACKED BEACONS +//================== + +//The component that handles tracking atoms +/datum/component/team_monitor + /// The frequency of the team signals we are trackings + /// Key <-- cannot be changed + var/team_freq_key = "debug" + /// Final compiled: Consists of key then numbers between 1 and 999 + var/team_frequency = "" + /// The atoms we are actually tracking + /// Key = Beacon component + /// Value = image + var/list/tracking = list() + /// Who are we updating for + var/mob/updating = null + /// Distance from center + /// Probably in pixels or something idk + var/distance = 20 + /// Should we display the hud in the firstplace + var/hud_visible = TRUE + /// The attached beacon: Ignore this one + var/datum/component/tracking_beacon/attached_beacon + /// If we can track beacons within the same zgroup (e.g. on a multiz station) + var/multiz = TRUE + +/datum/component/team_monitor/Initialize(frequency_key, frequency, _attached_beacon, _multiz = TRUE) + multiz = _multiz + team_freq_key = frequency_key + if(frequency) + team_frequency = "[frequency_key][frequency]" + else + team_frequency = team_freq_key + + + attached_beacon = _attached_beacon + + get_matching_beacons() + add_tracker_hud(team_frequency, src) + +/datum/component/team_monitor/Destroy(force) + if(team_frequency) + GLOB.tracker_huds[team_frequency] -= src + + SEND_SIGNAL(parent, COMSIG_LIVING_TRACKER_REMOVED, team_frequency) + + //Stop processing + STOP_PROCESSING(SSprocessing, src) + + //Remove the HUD from the equipped mob + if(updating) + hide_hud(updating) + + //Dispose + if(attached_beacon) + if(attached_beacon.attached_monitor == src) + attached_beacon.attached_monitor = null + attached_beacon = null + + . = ..() + +//Gets the active trackers for when the team_monitor component +//is initialized while other trackers are already active. +/datum/component/team_monitor/proc/get_matching_beacons() + for(var/datum/component/tracking_beacon/beacon as() in get_all_beacons_on_frequency(team_frequency, team_freq_key)) + if(beacon != attached_beacon && (beacon.updating || beacon.always_update)) + add_to_tracking_network(beacon) + +//=========== +// Handles the parent being moved and updates the direction of the arrows. +//=========== + +/datum/component/team_monitor/process() + update_all_directions() + +//When the parent is removed, we need to update our arrows +//Also if we are visible update the arrows of anything tracking us +/datum/component/team_monitor/proc/parent_moved() + SIGNAL_HANDLER + + //Update our alt appearances + update_all_directions() + +//Updates the direction of the arrows for all atoms we are tracking +/datum/component/team_monitor/proc/update_all_directions() + if(!updating) + return + for(var/datum/component/tracking_beacon/beacon as() in tracking) + update_atom_dir(beacon) + +//Update the arrow towards another atom +/datum/component/team_monitor/proc/update_atom_dir(datum/component/tracking_beacon/beacon) + if(!updating?.hud_used || !beacon?.visible) + return + var/atom/movable/screen/arrow/screen = tracking[beacon] + var/turf/target_turf = get_turf(beacon.parent) + var/turf/parent_turf = get_turf(parent) + if(!target_turf || !parent_turf) + return + var/share_z = target_turf.z == parent_turf.z + if((!share_z && (!multiz)) || target_turf == parent_turf) + if(screen) + //Remove the screen + updating.hud_used.team_finder_arrows -= screen + qdel(screen) + tracking[beacon] = null + //Update their hud + updating.hud_used.show_hud(updating.hud_used.hud_version, updating) + return + if(!screen) + //Create the screen + screen = new(null, updating.hud_used) + screen.alpha = 240 + if(multiz && !share_z) + if(screen.color != beacon.z_diff_colour) + screen.color = beacon.z_diff_colour + else if(screen.color != beacon.colour) + screen.color = beacon.colour + updating.hud_used.team_finder_arrows += screen + tracking[beacon] = screen + //Update their hud + updating.hud_used.show_hud(updating.hud_used.hud_version, updating) + if(multiz && !share_z) + if(screen.color != beacon.z_diff_colour) + screen.color = beacon.z_diff_colour + else if(screen.color != beacon.colour) + screen.color = beacon.colour + var/matrix/rotationMatrix = matrix() + rotationMatrix.Scale(1.5) + rotationMatrix.Translate(0, -distance) + rotationMatrix.Turn(get_angle(target_turf, parent_turf)) + var/new_alpha = 240 + if(share_z) + switch(get_dist(target_turf, parent_turf)) + if(0) + new_alpha = 0 + if(1) + new_alpha = 60 + if(2) + new_alpha = 100 + if(3) + new_alpha = 150 + else + new_alpha = 240 + animate(screen, alpha = new_alpha, transform = rotationMatrix, time = 0.2 SECONDS) + +//=========== +// Handles hiding / showing the hud when equipped +//=========== + +/datum/component/team_monitor/proc/show_hud(mob/target) + //Our hud is disabled + if(!hud_visible || !target) + return + updating = target + //Start processing to update in weird situations + START_PROCESSING(SSprocessing, src) + //Register parent signal + RegisterSignal(target, COMSIG_MOVABLE_MOVED, PROC_REF(parent_moved)) + //Mob doesnt have a hud, dont add hud arrows + if(!target.hud_used) + return + for(var/datum/component/tracking_beacon/key in tracking) + if(!key.visible) // calling show_hud should not show hidden beacons + continue + var/atom/movable/screen/arrow/arrow = new(null, target.hud_used) + arrow.alpha = 240 + var/turf/target_turf = get_turf(key.parent) + var/turf/parent_turf = get_turf(parent) + if(multiz && target_turf.z != parent_turf.z) + if(arrow.color != key.z_diff_colour) + arrow.color = key.z_diff_colour + else if(arrow.color != key.colour) + arrow.color = key.colour + target.hud_used.team_finder_arrows += arrow + tracking[key] = arrow + //Update their hud + target.hud_used.show_hud(target.hud_used.hud_version, target) + update_all_directions() + +/datum/component/team_monitor/proc/hide_hud(mob/target) + updating = null + //Stop processing + STOP_PROCESSING(SSprocessing, src) + if(!target) + return + //UnRegister parent signal + UnregisterSignal(target, COMSIG_MOVABLE_MOVED) + //Remove our arrows + for(var/key in tracking) + var/atom/movable/screen/arrow = tracking[key] + if(!arrow) + continue + if(target.hud_used) + target.hud_used.team_finder_arrows -= arrow + qdel(arrow) + tracking[key] = null + //Update their hud + if(target.hud_used) + target.hud_used.show_hud(target.hud_used.hud_version, target) + +//=========== +// Handles user interaction +// - Disabling hud transmission +// - Disabling hud view +// - Changing transmission frequency +//=========== + +/datum/component/team_monitor/proc/toggle_hud(new_hud_status, mob/user) + hud_visible = new_hud_status + if(hud_visible && !updating) + show_hud(user) + else if(!hud_visible) + hide_hud(user) + +/datum/component/team_monitor/proc/change_frequency(mob/user) + //Get new frequency + var/new_freq = input(user, "Enter a new frequency (1 - 999):", "Frequency Change", 1) as num|null + if(!new_freq) + to_chat(user, "Invalid frequency. Encrypted tracking HUD disabled.") + return + if(new_freq < 1 || new_freq > 999) + to_chat(user, "Frequency is out of range. Must be between 1 and 999.") + return + set_frequency(new_freq) + to_chat(user, "Tracking HUD now scanning on frequency [team_frequency].") + //Set frequency of the linked beacon + if(attached_beacon) + attached_beacon.set_frequency(new_freq) + +/datum/component/team_monitor/proc/set_frequency(new_frequency) + var/hud_on = hud_visible + var/mob/user = updating + //Remove tracking from old frequency + if(team_frequency) + if(updating) + toggle_hud(FALSE, updating) + //Remove from the global frequency + GLOB.tracker_huds[team_frequency] -= src + //Clear tracking + tracking.Cut() + team_frequency = "[team_freq_key][new_frequency]" + //Add tracking to new frequency + if(!team_frequency) + return + //Adds our tracking component to the global list of trackers + add_tracker_hud(team_frequency, src) + //Gets the other trackers on our frequency + get_matching_beacons() + //Show hud if needed + if(user) + toggle_hud(hud_on, user) + +//Adds a new atom to the tracking monitor, will create a hud element that tracks them +//TODO: Add the screen if already equipped +//Should be the only way atoms are added to the tracking list +/datum/component/team_monitor/proc/add_to_tracking_network(datum/component/tracking_beacon/beacon) + if(beacon != attached_beacon) + if(updating?.hud_used) + var/atom/movable/screen/arrow/arrow = new(null, updating.hud_used) + arrow.alpha = 240 + var/turf/target_turf = get_turf(beacon.parent) + var/turf/parent_turf = get_turf(parent) + if(multiz && target_turf.z != parent_turf.z) + if(arrow.color != beacon.z_diff_colour) + arrow.color = beacon.z_diff_colour + else if(arrow.color != beacon.colour) + arrow.color = beacon.colour + updating.hud_used.team_finder_arrows += arrow + tracking[beacon] = arrow + //Update arrow direction + update_atom_dir(beacon) + //Update their hud + updating.hud_used.show_hud(updating.hud_used.hud_version, updating) + else + tracking[beacon] = null + +// ============ +// Worn version, hides when dequipped +// ============ + +/datum/component/team_monitor/worn/Initialize(frequency_key, frequency, _attached_beacon) + var/obj/item/clothing/item = parent + if(!istype(item)) + return COMPONENT_INCOMPATIBLE + RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, PROC_REF(parent_equipped)) + RegisterSignal(parent, COMSIG_ITEM_DROPPED, PROC_REF(parent_dequpped)) + ..() + +//=========== +// Handles being equipped / dequipped +//=========== + +//The parent equipped an item with a team_monitor, check if its in the right slot and apply the hud +//Also needs to enable other trackers pointers towards us +/datum/component/team_monitor/worn/proc/parent_equipped(datum/source, mob/equipper, slot) + SIGNAL_HANDLER + + var/obj/item/clothing/item = parent + if(!istype(item)) + return + if(item.slot_flags & slot) //Was equipped to a valid slot for this item? + show_hud(equipper) + else + hide_hud(equipper) + +//Disable our hud +//Disable the pointers to us +/datum/component/team_monitor/worn/proc/parent_dequpped(datum/source, mob/user) + SIGNAL_HANDLER + + hide_hud(user) + +/datum/component/team_monitor/worn/Destroy(force) + //Unregister signals + if(parent) + UnregisterSignal(parent, COMSIG_ITEM_EQUIPPED) + UnregisterSignal(parent, COMSIG_ITEM_DROPPED) + return ..() + +//================== +// Component +// - TRACKER COMPONENT +// - HANDLES UPDATING TRACKERS WHEN MOVED +//================== + +/datum/component/tracking_beacon + /// The frequency of the team signals we are trackings + /// Key <-- cannot be changed + var/team_freq_key = "debug" + /// Final compiled: Consists of key then numbers between 1 and 999 + var/team_frequency = "" + /// Are we visible to other trackers? + var/visible = TRUE + /// Our colour + var/colour = "#FFFFFF" + /// Colour when on a different z level + var/z_diff_colour = "#808080" + /// Who are we updating for + var/mob/updating = null + /// Do we have an attached monitor? + var/datum/component/team_monitor/attached_monitor + /// Should we update when not equipped? + var/always_update = FALSE + /// Global signal? + var/global_signal = FALSE + +/datum/component/tracking_beacon/Initialize(_frequency_key, _frequency, _attached_monitor, _visible = TRUE, _colour = "#ffffff", _global = FALSE, _always_update = FALSE, _z_diff_colour = "#808080") + . = ..() + + //Set vars + colour = _colour + z_diff_colour = _z_diff_colour + attached_monitor = _attached_monitor + always_update = _always_update + global_signal = _global + + //Set the frequency we are transmitting on + team_freq_key = _frequency_key + if(_global) + team_frequency = "[_frequency_key]-GLOB" + else if(_frequency) + team_frequency = "[_frequency_key][_frequency]" + else + team_frequency = team_freq_key + + //Add ourselves to the tracking network + add_tracker_beacon(team_frequency, src) + + //Register tracking signal + if(always_update) + RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(update_position)) + else + //Reigster equipping signals + RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, PROC_REF(parent_equipped)) + RegisterSignal(parent, COMSIG_ITEM_DROPPED, PROC_REF(parent_dequpped)) + + //Set our visibility on the tracking network + toggle_visibility(_visible) + +/datum/component/tracking_beacon/Destroy(force) + //Unregister signals + if(parent) + //Register tracking signal + if(always_update) + UnregisterSignal(parent, COMSIG_MOVABLE_MOVED) + else + UnregisterSignal(parent, COMSIG_ITEM_EQUIPPED) + UnregisterSignal(parent, COMSIG_ITEM_DROPPED) + + //Unregister movement signal + if(updating) + UnregisterSignal(updating, COMSIG_MOVABLE_MOVED) + + //Goodbye, it was a good life + remove_from_huds() + + //Remove from the global network + if(team_frequency) + GLOB.tracker_beacons[team_frequency] -= src + + if(attached_monitor?.attached_beacon == src) + attached_monitor.attached_beacon = null + attached_monitor = null + + . = ..() + +//=========== +// Equip/Dequip transmission handling +//=========== + +//The parent equipped an item with a team_monitor, check if its in the right slot and apply the hud +//Also needs to enable other trackers pointers towards us +/datum/component/tracking_beacon/proc/parent_equipped(datum/source, mob/equipper, slot) + SIGNAL_HANDLER + + var/obj/item/clothing/item = parent + if(!istype(item)) + return + if(item.slot_flags & slot) //Was equipped to a valid slot for this item? + updating = equipper + toggle_visibility(TRUE) + RegisterSignal(updating, COMSIG_MOVABLE_MOVED, PROC_REF(update_position)) + else + toggle_visibility(FALSE) + if(updating) + UnregisterSignal(updating, COMSIG_MOVABLE_MOVED) + updating = null + +//Disable our hud +//Disable the pointers to us +/datum/component/tracking_beacon/proc/parent_dequpped(datum/source, mob/user) + SIGNAL_HANDLER + + toggle_visibility(FALSE) + if(updating) + UnregisterSignal(updating, COMSIG_MOVABLE_MOVED) + updating = null + +//=========== +// Visibility Handling +//=========== + +//Toggle visibility +//If visibility is disabled we will hide ourselves from others +/datum/component/tracking_beacon/proc/toggle_visibility(new_vis) + visible = new_vis + //If we are updating toggle our visibility + if((updating || always_update) && visible) + add_to_huds() + else + remove_from_huds() + +//=========== +// Position Updating +//=========== + +/datum/component/tracking_beacon/proc/update_position() + SIGNAL_HANDLER + + //Update everyone tracking us + if(!visible) + return + if(!team_frequency) + return + for(var/datum/component/team_monitor/TM as() in get_all_watchers_on_frequency(team_frequency, team_freq_key, global_signal)) + if(TM != attached_monitor) + TM.update_atom_dir(src) + +//=========== +// Showing on huds +//=========== + +//Remove ourselves from other tracking components +/datum/component/tracking_beacon/proc/remove_from_huds() + if(!team_frequency) + return + for(var/datum/component/team_monitor/team_monitor as() in get_all_watchers_on_frequency(team_frequency, team_freq_key, global_signal)) + //Remove ourselves from the tracking list + var/atom/movable/screen/arrow = team_monitor.tracking[src] + team_monitor.tracking.Remove(src) + //Delete the arrow pointing to use + if(!arrow) + continue + if(team_monitor.updating?.hud_used) + team_monitor.updating.hud_used.team_finder_arrows -= arrow + //Update their hud + team_monitor.updating.hud_used.show_hud(team_monitor.updating.hud_used.hud_version, team_monitor.updating) + qdel(arrow) + +//Add ourselves to other tracking components +/datum/component/tracking_beacon/proc/add_to_huds() + //If we are invisibile, dont bother + if(!visible) + return + //Find other trackers and add ourselves to their tracking network + if(!team_frequency) + return + for(var/datum/component/team_monitor/team_monitor as() in get_all_watchers_on_frequency(team_frequency, team_freq_key, global_signal)) + if(team_monitor != attached_monitor) + team_monitor.add_to_tracking_network(src) + +//=========== +// Handles user interaction +// - Disabling hud transmission +// - Disabling hud view +// - Changing transmission frequency +//=========== + +/datum/component/tracking_beacon/proc/change_frequency(mob/user) + //Get new frequency + var/new_freq = input(user, "Enter a new frequency (1 - 999):", "Frequency Change", 1) as num|null + if(!new_freq) + to_chat(user, "Invalid frequency. Encrypted tracking beacon disabled.") + return + if(new_freq < 1 || new_freq > 999) + to_chat(user, "Frequency is out of range. Must be between 1 and 999.") + return + set_frequency(new_freq) + to_chat(user, "Tracking HUD now transmitting on frequency [team_frequency].") + //Set frequency of the linked tracker + if(attached_monitor) + attached_monitor.set_frequency(new_freq) + +/datum/component/tracking_beacon/proc/set_frequency(new_frequency) + //Remove tracking from old frequency + if(team_frequency) + //Disable the beacon on other trackers + toggle_visibility(FALSE) + //Remove from the global frequency + GLOB.tracker_beacons[team_frequency] -= src + team_frequency = "[team_freq_key][new_frequency]" + //Add tracking to new frequency + if(!team_frequency) + return + //Adds our tracking component to the global list of trackers + add_tracker_beacon(team_frequency, src) + //Set our visibility on the tracking network + toggle_visibility(visible) + +//======= +// Generic Arrow, No special effects +//======= + +/atom/movable/screen/arrow + icon = 'tff_modular/modules/vampire/icons/hud.dmi' + icon_state = "hud_arrow" + screen_loc = ui_team_finder + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + +#undef ALT_APPEARENCE_ID + +/// 1 tile up +#define UI_HUMANITY_DISPLAY "WEST:6,CENTER+1:-8" +/// 1 tile down +#define UI_BLOOD_DISPLAY "WEST:6,CENTER:0" +/// 2 tiles down +#define UI_VAMPRANK_DISPLAY "WEST:6,CENTER-1:-2" + +///Maptext define for Vampire HUDs +#define FORMAT_VAMPIRE_HUD_TEXT(valuecolor, value) MAPTEXT("

  • 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 gFTHH&B9EbrdGHeg+`z&yPa<}6 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%0Al#gV;D`pUW$RtEI?4nd1a0krEh- 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 literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/sound/coffin_open.ogg b/tff_modular/modules/bloodsucker/sound/coffin_open.ogg new file mode 100644 index 0000000000000000000000000000000000000000..d0a199926984f91faaba22a4fb76f10234bf39f5 GIT binary patch literal 66698 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 JR+Rt$`9G5QHOl}1 literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/sound/drinkblood1.ogg b/tff_modular/modules/bloodsucker/sound/drinkblood1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..727c5fc25ba81a75c92942bd70256f05761f42c4 GIT binary patch literal 54662 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 z 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 a^%{$(M6s4EunqtK002Ds`03|&2LJ#v-fnCF literal 0 HcmV?d00001 diff --git a/tff_modular/modules/bloodsucker/sound/fortitude_on.ogg b/tff_modular/modules/bloodsucker/sound/fortitude_on.ogg new file mode 100644 index 0000000000000000000000000000000000000000..b1033fec8dfc5807278bed932a0f4f07eb3b62d7 GIT binary patch literal 14575 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πaNKGYiM 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 N=!SBOIxkKqMqWpeX`I2oR(sq1BcZBv?S8 zh#^Npq!1v;10qI1jTTv~sGta?kYW}TSrXUa$F>$cQcrhYu-)$2ud`?W**TNRojZ4a z@7_E2&bu!vH8lp9f!8hOjb&nGgbg3F5tDl$Cz&TeS(uRa<(2$P%l{WJQRvQJ8oCn$ zXH7okJAd=ePrq(H=F2$la5;{bo#q*plZwyeCGRnz<7s#wFK-_&AFsFZu2K9fUUm*w zz|9g8QD}_C^43k19eW@;2H;Yd#GN&aujwTY0*Uv|n&c{aNwe6VLOmt0i)kfm&tg zLBL?72S0?5r1ap$YmSUmvQRzyg0PNiYp@#tY-t0o)J%M|-3<5uu%h0z;(=?$7IIYz z&E6yeosR{eFWZiG-0tRC=kTvR!pB0QS$X4rEY^aEqeVNOv~L}X8bocWX?Dc-+w8+x ztzlaLJao}c*M6+|&+Y-quH@pky7Zq4Dhl_L)7-AP>sVKNjk4aoWyLG~^bS+Ssx&!Vh{)O!vsp9m-@?{9L;?t%6O5vYcwX>YQeiW8E6o*m#`r2rpp{(1@p&Ew=)IAhu&r2}Q4mV!}~e@(p5({D`$% zYm=hXXVBx^EuSHDFm|3B4w(1)3cJImqsultvU@x(rQ@POp0W1pcwR^M1fAFnPnl@) zUp_n@D~ElR!8=jpVuDhhGe|sLZ)S2QTtxFC@TMRnO!&8cT@V;138BH>6*2TpMASOg zcr_(32-;j_4~WVKM8yNLVhdftjaMksRj##aqek_gx~D0?D*+fe?sW6G z6AW+~BrqoL!dx%|**4cJVbH^fe{EybbLddcsKu`j001xNs|=4Y0f{DIhIca~yP4tZ zSW&G1)O;hyNRiO7TVd9LzU1;h%;5=Jx6Vyt`>`kLyx$^pe?VAqylUEe<+{Q;AB9cM zG-VcBxDh(-w;%*sK7hZD72F_)wVtpg8%_%)js~aZ3PvjN+R5bGuGQZ%+RFtMjIfSI zNwUYbTnVGRbpS?-nG^hZh@tu`Kr{eiZz{3LF1d`{BHvL)G@KM1_0~HHD#(U$gyM2s|2Tg@F4@paW)&PUwI zMc*+YXN<+26mlkWxv}Rt?1j8BQPI6>ZelE#jmzaM7A0t_=Y*W8SZ?h0J#aNaTQoBv zN~#HrVnJli9TF#2#7T_hXeWHfBq;JElf%x1$eh>-(H#Suksc1?Fg}Lk( ztk?w+TU$Ld!JpaA(Jr#s3q^1hMZPHF;ND~XkQb9%G$Z8R(-z%hXL05^;`o!eJ#71J$CYfSp$y}ox3M?6NAzjp$JSTB7m7Fs_j9fBzl82~?GL;8U#*44pFO#*@ zDAQ!B44JaMR7o6CrVpxlGWEPh&A+6|)G2tTX{Jo+aY@~#Q_VlpG_jSf2kUt0br8xV ztZF-0mwu=&4XJZQkaPs;KoE}vxGHh>j*fv6gY z=a8EJ=DExzO`7brR&F}=wj~YJ>gk~BKpWC-M5j+)sZB#w81^|~0fR$H+jh&;~78JuRyV2 zD`{USz`8((>>xIw?_AT1_a6u9zgqaGJ6iu8)IZ(vU%~$$2v`4WSN$*cS%b>bY*2aV z=g6eOAS;We69?plSZ_TpWrXHROuj`PaDt&Y=Oo55c-zho!WeD(hQY59FyfCvp|=f9 zO?C;l$)7P8$Ij|y8BdzJ_GGAh4e{}9zFN89_Qfvy3>B=x1w-C&fOQ}4b@68b?vwmM z{>E=R1Nv#BaeIFbX)}jrROBI+QARevhi)!Hr&a_eIu&9mr*Q%_PsEj`RaiI))&`i0 zZOaX?;)WT6rji&-cZCC76=MU?!9<}0gKnCxYLM&(U~hpr2+Cj6wnc7NZefomCoDno zouu`QVR3Lp@aJoS2czF!Lx~`d)+Fyre|ud_B^i54XzP$3Jo$moYIu9&0lseq7Ke9z zL9r_KhDB`gE$pfyR%c(mjiZwu(`Ozc4gr-X>#3J6?j$Lo%v=yFRY`=@w1p z)vk5j*Dqgxyeaj?GYr#EPJK@j*I^d1eO>8A+2LW?sKusf?(@+fNuyQA_i=+Cn1^X? zNt+&ty^>$h?tK5r0s8xX&TGYI26}(P~nKt9Vp)08VUyTKx3&5~QHPxq9~7uQ8s2j9f4KiN|LCDlB2ydbL8CcE+4)s*(;mO;*gv+)*+y`9q}JEL!RK>tu$R3@jT60# z%q*49Wz63!w#=(F*p}>mQt{`Hh>iz^8(wDRYM6>IyAWd6Oxo$Ni{XI@D<7YEZYc|S zRUm&FJ3Kf&#G?(-rSFHH_{(K-X4gpB(ZQFknHS6p571FdhJ?3E@c@{75(60Qq=et^-qXHB2` w!j0W>hKd|l5weveW$a@sqOwFci7{nKS&Kx`CWBVJ zaxEpLS41jhDSMmH@}}~=^uF)s^Zk5(fBw$rbMJZX*`IUHbDkN;z(7}k0e{2$2iE=b z%a9w{*C7hDch_#8pvZXw#JxO^0Dy1*#y26ydCh-eUK2vUJ{_*Y5;o2)z#8mt17;}Q zJt&;7=eRqN8XDx|wqTZOOEqAwG+-JqS5fJXVLOAucl$^B?~Gcumg*QD74)~zUZ$Rb z9&_Feg!^qx!@|-H^#uJJwJ{M#gby{I0q`4CEE53g8UXO~Dt`l&<);WZ0C40m@Z-$Q z0LB2=N!rR;dV!G%0V-G@zNp0+EO3Dwfd5Mqbv3|4UrEWAF(?yAg9SZwIp7oy01ATyG$;U4AfOC@)x6+uPgDS>+^x2uDP`Kwh$$9Y$K1*Csm;~2 zEdMGSk^8*r0xamGj*rkH$gNq7^;xLE)-3H~jMgk#Yu3M}=4GuS=;AGd2!#9_&2KgV zzzxS}cGa{;9gOsVDuz;;wQtq$z&P`{{BPj!@9WO*ij&oR#wOj*MyS1pD5qL23D8`j z*};Le* z0igCcaH%_dR>a9-@SGU{pVL&$U>wGxnYRLRIKT@h+diQ=9=Gq9W~VKSDYKrjPY;ac zW{i;>NUV-kR`yxrF=c^5R$dvu(_TT#8KCyC=yTYKe_sfwk^s@%nzO_vRO}MidM+}g-au79cdc;viZU zF%W?PO082YyBZPWQPZK(hABqTNDRep8VuOxBo7C%9(7Lg0fh|!1+W3dy&$=zshS0k z4#rSG`F9YHP(@D#Dvds9$l_$Qb?oWb!^xM$KnZ&0(tT4) z)<@Fp6im4-S#nkd=VK_2+&7xR{AkV-hBFPrp4IB4}8Gg)rwk8BrhuSTfXIeef)wAzH8^ z4uFre#XaSuqvjiyoz1i$ETf?rM$ox|BpLi}sEq*m+rs}7qN2e!LY#?)1rHklRS_V? z^l)RcJg@41T~GliZ-BrIlH5(&D7=S}lG!Q&&SHQ&`R;B;D%T>5;egGgIW(0VEZbUO z{lr}Cv4$b6bCD{`6-hDrbgCL|_Kkh~*@@sUOct=1~8g|{MuNk1f>5`)&8 zq)7ra9eSspUhzY)I4Yv&pj@I{5>*NB#K90Z-W*IdVh@Th9b1%b@_UkCK{NoybXXu5 z(Pii{4Opv#hc?R`PGNP3-;+0 z4^r7r>&~w8jqk6qrt>^TF9bS#y91bq&V#4IVwX3+T!jzrPLaDMMh+}*&6J?6B|I|` z2i<;(*N5%PuAdyN?@G?koxw(~`rwK+GDKz@!7M<&0(h5NvGl+hNgf?}3RU=E`o+k< z7)JSH${41L#)}C*zx(U}P`u`uOSjasIrG;__oy~9LcEncvlW{RbhgAQJQKG6V;|#$2)} zOB-qLSF(JoM)@ua1_C7fE;*ZDd#ZgW40IHMR zv8%fvW$eHsX~6q%6rSU}o(yiP+F^TBvUm>TE_L1hqcCl)>w!S%vqg1W$BL6bfBa=) zdZq8Z8ekNtm|uMBe~g?G*U0-b<@&9ziFl)sqnv%7*|<1^(%o(KW3j`JOQFfg?bHgI9*gQ9-rQ$Pe%_VymKd=hEA<7hAt< zx`&$vQEwF~a^IkJ{Vk%Tp{sdXoi>hv_M!eMyt~h z#nmcm&86Q;oU?J8#%~vSCsH*V6ktn%4KtHhUN#$|PCMt@U6-khA@XVi6Vra#h%}9!RqlH# zPW9yHdmOkE9JakA7Z0m2z)2-(J;nM8m8g20qE4}sFAK*L4|l;b^A(*O$ZY+jv$&%p zf#x-Suc9Ycd&-RYW(|x=A`Wmp2_S1BaU60{#wlm8P>O0lpaJ8bG92GJTc2}<%Fq1D zYM1<}Yxdgr!f40NtG3`MC28@w>)TI~XC5D&&20>{>woxq$@^s${dc#><%;Z}KD$@V zw!6=6zR)W+o4GG+|I6ZYD>s?Ex6#>_=C7D0y#)SmQ&p9{eCaT(RncLRCiQu;)?67KN1gg=SP_C-A&UL{50*K zet3^d^PyPTmsa)HCfzSq3En2luRasi+7eHUX&Q+gEj%dE%<8vhs^P82I2bojMDCY8 zvDq;$qm$pOVOp7*mZOG`jx7RtJ6{tj9$-u+jvUUB7thrOxn!4t+Q(mlu{Nm7fbD|Y3i-Whukj7ckR>R`<#vis}*DhR>A73QSTso1XH|Z z0JRd?Dn! zMRn=w&x@XmCtV4yeo?sM`%U(==rhwOK+)CcMw1ItIF@aaL2W|ZroO)^>e{$2{^+&E znbwRQuYwalDh7#RuQ?&)LquMpB8)ts-eIpZx@eZ*S$R&nZb;yK|fx=Ys5vhV&VFnI6XK*UD;-}>AvF?C(}OISmP4E#7qtLhOJ2WV^=#r zL>5TPOEl9z_aui~oc}ZaZ9(I`5XG~T*O8}-2d*hEe<0G@5%XcCvtQ`w-FLdrJ6CK| zjLFn`cRPZwZZz_{qvU21AQ?G57?}ao)5yZHc!V_yc<^Ilb}$vCfT6=zBwn zYqlIB`uRgAEZ@=d(jkATa~q~TpGN6taw|x~J`aCNN~oIZubU7#j`lw+h`Kp8`?hW9 zZFWXc1-N+_;)zQkB|c(XgEdyO()5#8MLGE8lGWlWSv{xnkw{R0Eq20>=K7GNrXYnUG<@EWCtnmhQNo=_}?@{652*si)v$E$su255tj|R3m4|Oym)FRaY6La5ek8u$9kQky z?;IVx?VG}bqt4ko`0vxgdmcv0wBbfR1RrX|WLztiVhwI3P!C!kF#L)A_6J{b145GE zNp0}PsDL8r(&Hd60C>{vfP;I$kJAu%=7fLA z!z4h_#n4Oy$4jcnbC)A^OZ=#skhd-NOoy0CGT`_R8aHCpuULW7ol+iQi_4}Tsd z6o!xx8-d7FDY$zN)@gOYL?rXBVj z9+5|soUoz-7~3a(L%_6!Or6@h3|_o=k~RDe;vARGgoA}${f?Qh);w53Jxl|S1-h@D zW)*6k`mUA{c2te7^tjR=hh+(nbH^;8>eK{&T4d&KD^bMOispX;<473_Y_ch`_h@tle^`kKuKIS$LqwOL46Kac&q|DM!T0K6nNPHbfAo+Yw{8{9Sg%wjFOxf3ovp~O@H&ZacK9;*Ym{7gyaMFagF$}A02A>21E?g5%%mrIm@#zKunnJJ zU+EyW|M^;pv#@ z{BrcTTSa3Y9^dBqu;>#nduIszOCZ{CgtJPT7iSLUXsU<}+@cF_Azl8CzZrlD0VaLY zTY^Ya0RAotJO13}OEFaZoMvITUy~V_IdXDM+V&eC+l}-#SY(xlU$;{YWW?;58;i*l z4#l6&olvZ(k9??hr2o#AVySiPs>>R?){U`;THH9aY#~Pw%f2Et(_u z4cX5xEM2y=Zu71%XuL(2ui3t?I@@^ETy}hEudn&qsmUaMx*eW5$_B&7SDbo(Ke5lw zI5}Zz@~-dI3m$KHosQcE2)gFE@@oqe!l&eBGM4b;6mr_c>yXeT#qZ6xUX&pc{{tzO B?zI2_ literal 7282 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 E0I%fCYybcN diff --git a/tff_modular/modules/bloodsucker/sound/griffin_2.ogg b/tff_modular/modules/bloodsucker/sound/griffin_2.ogg index 4ae4de2595f4bd827acef6194fcb571287f8be5c..c6ba9d19621d6115a118811bc5d680d04ef1588b 100644 GIT binary patch literal 2224 zcmb_cdsI{R9sk~Y^8%6(0>qF7OhTv-qNErn3d36-gB%z^MGX|`MS~>jAo5V?=z5_< z7-v(Y*5{5u>v2b*Gk~>BIGCcFV#h>1+p#zWt*>sjMMIsgQun(zfc5`<&b`0K_xJg} zfA^Y;i&p~HL?pJ@9kxa0vSQU%`-ZiwRh3BBO4 z9ToN&(ssk5*hL1$3&!ler1;DaYj7={{+XWq?M&brJ2t>JDK!a>Bu!c)_}&QL*Got|Mq7F3ydyA{2@MF$_YX zbFNcp&$=K1ge}@_+6E%61$@%yeEgV*xIm9KuK}6^v@octZU|IHYcQw?CNTqLh|ET% zW0RHuGWaSaiXLBR29U_Jh0YJXUahEfUM6c7nW0}*0>(oG!&1=%1!CaRn3%l9R5Jil zFpw+LdX1*=N5)@VHA-coUHmYG|7gN)zO*Vq;cxa-xsy>uG=W}cw(UX_sC>b#HtqX^ zspVL;Y`3<$B~|k%!PGlx2{VcgS*vBHy^mj8EsrE@3gqW1Qy38#Q3?tW(L6vKfVMr}8AQy%ESOUUHt&RJ zFYf@-LVc2>jtUIz!XQPD1{wol(jv>)P-v3rK@Tz+WYlppaQ%#S3zx!N6td8)htF{f zfFE-(L0fYzfCjX7S-_8GZx6U5)@Iyy4AYaz#Gy@g8;}GCUClVurE6_b-Em~QIvS&M(AV;%!$ND9>0!7VMvY)I zGNmC2#u*Cx`n9O~@91Pf9();f1~ahR`3vQZMtQ(K!08>8waNdon&v3T1sW8(ib zVX!Jd46FQSvptToO|2!IFJpb_2nUBk38ep4OX#hmHoa@K`2!$zK&P(MrnRIiwLZ|o zk%CV%_((wtDlC0Y6;(;bR>`$|$aL94F?9kJKq##?k*lB~8Bgm0KGn`BkP?tkxIicg zs!?;!$$?g-Y-+3@(pji%o=EJ02~3luf%MGmqwDj@{n(-hxBp0}IcmWhdT|@gQU2a> zHn6m6NR%}irK?1BM&Q9DfFm0M0!G$Y@+qrrtD~X{g@oV-HRumBpG-+950=f7hbVrc z3=Kn7_ktuzcA-KeNwU9dPGT4<0_JzkT&Imqt1pW}m2$bDwQDey({<<(}^bbYqn#dKbPKU1Ncq z`%9HWetmnAbSpl-a>cp7_&14nicbYgtwp~4<-Y%jveMJr;?JaAsydgAg0Y10aH4fOd~@aTe-?cG&6dt5KkJeHIuJHVxYR=5 zKPzsUqc&vi`&H*D>W2ldg~Zlc`S{xRFmg%mzSY48$MQl3%Z(574%YoC^wV{pt>M?) zhIugQ4^O8cgnm;@NvJRByhH8<82<2lakkAjK2e176@5Hqi1-Da# zG3lcC&FLC`){=>Wn#|nw&*Mtm-A~rfEB#(~J@0z{Kw{I$$~x{lf}H- zpDeVE7|(4v9AEL`rxT;N1)uD|;9)uE>6Qrb37=h+2OSY@FNiLDFu$~V<$q4r&F?r< z8|L}yERjgS_6tFlPddgg2^M}W_#*4H=WtQ*VLloE{zjiIixn|rD}*^UBZF9h=zWO) zZi##3Eukf#F4-5%6W*NR_-RpZJS_?1kNWc2r8TZ()$W-3+!MEYPwCnM+ x1KOSKH&1j`$2HXV564qm-__Wg2WscZ&fL>P#y67_?<70L2VCxZzXP#Y{6DM^PFVl| literal 4352 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 diff --git a/tff_modular/modules/bloodsucker/sound/griffin_3.ogg b/tff_modular/modules/bloodsucker/sound/griffin_3.ogg index 28b65b852a675bdf8dcf5882bab6730f5d9f77db..618399746e94d3bb28cdd96250540509441ef61f 100644 GIT binary patch literal 2828 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 literal 4912 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 diff --git a/tff_modular/modules/bloodsucker/sound/griffin_4.ogg b/tff_modular/modules/bloodsucker/sound/griffin_4.ogg index 2d6612c7c00eb6efb3a20e66c8698ccab8a551ae..bac703090d2bb479df9bc62b9f012088cea39266 100644 GIT binary patch literal 3171 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 JqFO+w{|oS!CkFrk literal 5274 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 diff --git a/tff_modular/modules/bloodsucker/sound/griffin_5.ogg b/tff_modular/modules/bloodsucker/sound/griffin_5.ogg index 61258463922015119de35a9c517eb62161e8f1fe..cc71e28f68e807a827d5c818f1398ec37885cde1 100644 GIT binary patch literal 3413 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 diff --git a/tff_modular/modules/bloodsucker/sound/griffin_6.ogg b/tff_modular/modules/bloodsucker/sound/griffin_6.ogg index 43520cddf2a753ada7d4ff6840b7e0d1aa6b28c1..228eca3dcd4c28b6d5ea79b8688cc67378bb8a1b 100644 GIT binary patch literal 3830 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