diff --git a/code/__DEFINES/~darkpack/traits/macros.dm b/code/__DEFINES/~darkpack/traits/macros.dm index e69de29bb2d1..864a9e0b1ae6 100644 --- a/code/__DEFINES/~darkpack/traits/macros.dm +++ b/code/__DEFINES/~darkpack/traits/macros.dm @@ -0,0 +1,2 @@ +/// Trait applied by element +#define DISCIPLINE_TRAIT(source) "discipline_trait_[source]" diff --git a/code/__DEFINES/~darkpack/traits/sources.dm b/code/__DEFINES/~darkpack/traits/sources.dm index fbe972ee6d3a..4af017a33555 100644 --- a/code/__DEFINES/~darkpack/traits/sources.dm +++ b/code/__DEFINES/~darkpack/traits/sources.dm @@ -2,7 +2,6 @@ /// Trait given by a vampire's Clan #define CLAN_TRAIT "clan" -#define DISCIPLINE_TRAIT "discipline" #define GIFT_TRAIT "gift" diff --git a/code/__DEFINES/~darkpack/vampire_clan.dm b/code/__DEFINES/~darkpack/vampire_clan.dm index ddd9cda82ac6..29b510f95b25 100644 --- a/code/__DEFINES/~darkpack/vampire_clan.dm +++ b/code/__DEFINES/~darkpack/vampire_clan.dm @@ -15,7 +15,8 @@ #define VAMPIRE_CLAN_NAGARAJA "nagaraja" #define VAMPIRE_CLAN_NOSFERATU "nosferatu" #define VAMPIRE_CLAN_OLD_CLAN_TZIMISCE "old_clan_tzimisce" -#define VAMPIRE_CLAN_SALUBRI "salubri" +#define VAMPIRE_CLAN_HEALER_SALUBRI "healer_salubri" +#define VAMPIRE_CLAN_WARRIOR_SALUBRI "warrior_salubri" #define VAMPIRE_CLAN_SETITE "setite" #define VAMPIRE_CLAN_TOREADOR "toreador" #define VAMPIRE_CLAN_TREMERE "tremere" @@ -26,4 +27,4 @@ #define VAMPIRE_CLAN_HARBINGER "harbinger_of_skulls" //all of the playable clans -#define VAMPIRE_CLAN_ALL list(VAMPIRE_CLAN_BAALI, VAMPIRE_CLAN_BANU_HAQIM, VAMPIRE_CLAN_BRUJAH, VAMPIRE_CLAN_CAITIFF, VAMPIRE_CLAN_CAPPADOCIAN, VAMPIRE_CLAN_CITY_GANGREL, VAMPIRE_CLAN_DAUGHTERS_OF_CACOPHONY, VAMPIRE_CLAN_GANGREL, VAMPIRE_CLAN_GARGOYLE, VAMPIRE_CLAN_GIOVANNI, VAMPIRE_CLAN_KIASYD, VAMPIRE_CLAN_LASOMBRA, VAMPIRE_CLAN_MALKAVIAN, VAMPIRE_CLAN_NAGARAJA, VAMPIRE_CLAN_NOSFERATU, VAMPIRE_CLAN_OLD_CLAN_TZIMISCE, VAMPIRE_CLAN_SALUBRI, VAMPIRE_CLAN_SETITE, VAMPIRE_CLAN_TOREADOR, VAMPIRE_CLAN_TREMERE, VAMPIRE_CLAN_TRUE_BRUJAH, VAMPIRE_CLAN_TZIMISCE, VAMPIRE_CLAN_VENTRUE, VAMPIRE_CLAN_SAMEDI, VAMPIRE_CLAN_HARBINGER) +#define VAMPIRE_CLAN_ALL list(VAMPIRE_CLAN_BAALI, VAMPIRE_CLAN_BANU_HAQIM, VAMPIRE_CLAN_BRUJAH, VAMPIRE_CLAN_CAITIFF, VAMPIRE_CLAN_CAPPADOCIAN, VAMPIRE_CLAN_CITY_GANGREL, VAMPIRE_CLAN_DAUGHTERS_OF_CACOPHONY, VAMPIRE_CLAN_GANGREL, VAMPIRE_CLAN_GARGOYLE, VAMPIRE_CLAN_GIOVANNI, VAMPIRE_CLAN_KIASYD, VAMPIRE_CLAN_LASOMBRA, VAMPIRE_CLAN_MALKAVIAN, VAMPIRE_CLAN_NAGARAJA, VAMPIRE_CLAN_NOSFERATU, VAMPIRE_CLAN_OLD_CLAN_TZIMISCE, VAMPIRE_CLAN_HEALER_SALUBRI, VAMPIRE_CLAN_WARRIOR_SALUBRI, VAMPIRE_CLAN_SETITE, VAMPIRE_CLAN_TOREADOR, VAMPIRE_CLAN_TREMERE, VAMPIRE_CLAN_TRUE_BRUJAH, VAMPIRE_CLAN_TZIMISCE, VAMPIRE_CLAN_VENTRUE, VAMPIRE_CLAN_SAMEDI, VAMPIRE_CLAN_HARBINGER) diff --git a/modular_darkpack/modules/deprecated/icons/UI/actions.dmi b/modular_darkpack/modules/deprecated/icons/UI/actions.dmi deleted file mode 100644 index 0a4a4c6d6fee..000000000000 Binary files a/modular_darkpack/modules/deprecated/icons/UI/actions.dmi and /dev/null differ diff --git a/modular_darkpack/modules/jobs/code/anarchs/bruiser.dm b/modular_darkpack/modules/jobs/code/anarchs/bruiser.dm index 22c91e72b194..5f0db8739caa 100644 --- a/modular_darkpack/modules/jobs/code/anarchs/bruiser.dm +++ b/modular_darkpack/modules/jobs/code/anarchs/bruiser.dm @@ -26,7 +26,7 @@ ) known_contacts = list("Baron", "Bouncer", "Emissary", "Sweeper") - allowed_clans = list(VAMPIRE_CLAN_DAUGHTERS_OF_CACOPHONY, VAMPIRE_CLAN_TRUE_BRUJAH, VAMPIRE_CLAN_BRUJAH, VAMPIRE_CLAN_NOSFERATU, VAMPIRE_CLAN_GANGREL, VAMPIRE_CLAN_CITY_GANGREL, VAMPIRE_CLAN_TOREADOR, VAMPIRE_CLAN_TREMERE, VAMPIRE_CLAN_MALKAVIAN, VAMPIRE_CLAN_BANU_HAQIM, VAMPIRE_CLAN_TZIMISCE, VAMPIRE_CLAN_CAITIFF, VAMPIRE_CLAN_VENTRUE, VAMPIRE_CLAN_LASOMBRA, VAMPIRE_CLAN_GARGOYLE, VAMPIRE_CLAN_KIASYD, VAMPIRE_CLAN_CAPPADOCIAN, VAMPIRE_CLAN_SETITE, VAMPIRE_CLAN_SALUBRI, VAMPIRE_CLAN_SAMEDI, VAMPIRE_CLAN_NAGARAJA) + allowed_clans = list(VAMPIRE_CLAN_DAUGHTERS_OF_CACOPHONY, VAMPIRE_CLAN_TRUE_BRUJAH, VAMPIRE_CLAN_BRUJAH, VAMPIRE_CLAN_NOSFERATU, VAMPIRE_CLAN_GANGREL, VAMPIRE_CLAN_CITY_GANGREL, VAMPIRE_CLAN_TOREADOR, VAMPIRE_CLAN_TREMERE, VAMPIRE_CLAN_MALKAVIAN, VAMPIRE_CLAN_BANU_HAQIM, VAMPIRE_CLAN_TZIMISCE, VAMPIRE_CLAN_CAITIFF, VAMPIRE_CLAN_VENTRUE, VAMPIRE_CLAN_LASOMBRA, VAMPIRE_CLAN_GARGOYLE, VAMPIRE_CLAN_KIASYD, VAMPIRE_CLAN_CAPPADOCIAN, VAMPIRE_CLAN_SETITE, VAMPIRE_CLAN_HEALER_SALUBRI, VAMPIRE_CLAN_WARRIOR_SALUBRI, VAMPIRE_CLAN_SAMEDI, VAMPIRE_CLAN_NAGARAJA) allowed_splats = list(SPLAT_KINDRED) description = "You are the enforcer of the Anarchs. The baron is always in need of muscle power. Enforce the Traditions - in the anarch way." minimal_masquerade = 2 diff --git a/modular_darkpack/modules/jobs/code/anarchs/emissary.dm b/modular_darkpack/modules/jobs/code/anarchs/emissary.dm index 77119155c426..fc07d8cfcd6a 100644 --- a/modular_darkpack/modules/jobs/code/anarchs/emissary.dm +++ b/modular_darkpack/modules/jobs/code/anarchs/emissary.dm @@ -15,7 +15,7 @@ ) known_contacts = list("Baron", "Bouncer", "Emissary", "Sweeper", "Prince", "Sheriff") - allowed_clans = list(VAMPIRE_CLAN_DAUGHTERS_OF_CACOPHONY, VAMPIRE_CLAN_TRUE_BRUJAH, VAMPIRE_CLAN_BRUJAH, VAMPIRE_CLAN_NOSFERATU, VAMPIRE_CLAN_GANGREL, VAMPIRE_CLAN_CITY_GANGREL, VAMPIRE_CLAN_TREMERE, VAMPIRE_CLAN_TOREADOR, VAMPIRE_CLAN_MALKAVIAN, VAMPIRE_CLAN_BANU_HAQIM, VAMPIRE_CLAN_TZIMISCE, VAMPIRE_CLAN_CAITIFF, VAMPIRE_CLAN_VENTRUE, VAMPIRE_CLAN_LASOMBRA, VAMPIRE_CLAN_GARGOYLE, VAMPIRE_CLAN_KIASYD, VAMPIRE_CLAN_CAPPADOCIAN, VAMPIRE_CLAN_SETITE, VAMPIRE_CLAN_SALUBRI, VAMPIRE_CLAN_SAMEDI, VAMPIRE_CLAN_NAGARAJA) + allowed_clans = list(VAMPIRE_CLAN_DAUGHTERS_OF_CACOPHONY, VAMPIRE_CLAN_TRUE_BRUJAH, VAMPIRE_CLAN_BRUJAH, VAMPIRE_CLAN_NOSFERATU, VAMPIRE_CLAN_GANGREL, VAMPIRE_CLAN_CITY_GANGREL, VAMPIRE_CLAN_TREMERE, VAMPIRE_CLAN_TOREADOR, VAMPIRE_CLAN_MALKAVIAN, VAMPIRE_CLAN_BANU_HAQIM, VAMPIRE_CLAN_TZIMISCE, VAMPIRE_CLAN_CAITIFF, VAMPIRE_CLAN_VENTRUE, VAMPIRE_CLAN_LASOMBRA, VAMPIRE_CLAN_GARGOYLE, VAMPIRE_CLAN_KIASYD, VAMPIRE_CLAN_CAPPADOCIAN, VAMPIRE_CLAN_SETITE, VAMPIRE_CLAN_HEALER_SALUBRI, VAMPIRE_CLAN_WARRIOR_SALUBRI, VAMPIRE_CLAN_SAMEDI, VAMPIRE_CLAN_NAGARAJA) allowed_splats = list(SPLAT_KINDRED) description = "You are a diplomat for the anarchs. Make deals, keep the peace, all through words, not violence. But the latter may come to pass if the former fails." minimal_masquerade = 2 diff --git a/modular_darkpack/modules/jobs/code/anarchs/sweeper.dm b/modular_darkpack/modules/jobs/code/anarchs/sweeper.dm index 8cb341be4feb..7988a03e0bb8 100644 --- a/modular_darkpack/modules/jobs/code/anarchs/sweeper.dm +++ b/modular_darkpack/modules/jobs/code/anarchs/sweeper.dm @@ -15,7 +15,7 @@ ) known_contacts = list("Baron", "Bouncer", "Emissary", "Sweeper") - allowed_clans = list(VAMPIRE_CLAN_DAUGHTERS_OF_CACOPHONY, VAMPIRE_CLAN_TRUE_BRUJAH, VAMPIRE_CLAN_BRUJAH, VAMPIRE_CLAN_NOSFERATU, VAMPIRE_CLAN_GANGREL, VAMPIRE_CLAN_CITY_GANGREL, VAMPIRE_CLAN_TREMERE, VAMPIRE_CLAN_TOREADOR, VAMPIRE_CLAN_MALKAVIAN, VAMPIRE_CLAN_BANU_HAQIM, VAMPIRE_CLAN_TZIMISCE, VAMPIRE_CLAN_CAITIFF, VAMPIRE_CLAN_VENTRUE, VAMPIRE_CLAN_LASOMBRA, VAMPIRE_CLAN_GARGOYLE, VAMPIRE_CLAN_KIASYD, VAMPIRE_CLAN_CAPPADOCIAN, VAMPIRE_CLAN_SETITE, VAMPIRE_CLAN_SALUBRI, VAMPIRE_CLAN_SAMEDI, VAMPIRE_CLAN_NAGARAJA) + allowed_clans = list(VAMPIRE_CLAN_DAUGHTERS_OF_CACOPHONY, VAMPIRE_CLAN_TRUE_BRUJAH, VAMPIRE_CLAN_BRUJAH, VAMPIRE_CLAN_NOSFERATU, VAMPIRE_CLAN_GANGREL, VAMPIRE_CLAN_CITY_GANGREL, VAMPIRE_CLAN_TREMERE, VAMPIRE_CLAN_TOREADOR, VAMPIRE_CLAN_MALKAVIAN, VAMPIRE_CLAN_BANU_HAQIM, VAMPIRE_CLAN_TZIMISCE, VAMPIRE_CLAN_CAITIFF, VAMPIRE_CLAN_VENTRUE, VAMPIRE_CLAN_LASOMBRA, VAMPIRE_CLAN_GARGOYLE, VAMPIRE_CLAN_KIASYD, VAMPIRE_CLAN_CAPPADOCIAN, VAMPIRE_CLAN_SETITE, VAMPIRE_CLAN_HEALER_SALUBRI, VAMPIRE_CLAN_WARRIOR_SALUBRI, VAMPIRE_CLAN_SAMEDI, VAMPIRE_CLAN_NAGARAJA) allowed_splats = list(SPLAT_KINDRED) description = "You are the observer of the anarchs. You watch out for any new kindred, suspicious individuals, and any new rumors near the anarch turf, and then report it to your anarchs." minimal_masquerade = 2 diff --git a/modular_darkpack/modules/jobs/code/clinic/director.dm b/modular_darkpack/modules/jobs/code/clinic/director.dm index aea4f661a66b..3b936a48fa09 100644 --- a/modular_darkpack/modules/jobs/code/clinic/director.dm +++ b/modular_darkpack/modules/jobs/code/clinic/director.dm @@ -16,7 +16,7 @@ description = "Keep Saint John's clinic up and running. Collect blood by helping mortals at the Clinic." allowed_splats = list(SPLAT_KINDRED, SPLAT_GHOUL, SPLAT_NONE) - allowed_clans = list(VAMPIRE_CLAN_DAUGHTERS_OF_CACOPHONY, VAMPIRE_CLAN_SALUBRI, VAMPIRE_CLAN_BAALI, VAMPIRE_CLAN_BRUJAH, VAMPIRE_CLAN_TREMERE, VAMPIRE_CLAN_VENTRUE, VAMPIRE_CLAN_NOSFERATU, VAMPIRE_CLAN_GANGREL, VAMPIRE_CLAN_CITY_GANGREL, VAMPIRE_CLAN_TOREADOR, VAMPIRE_CLAN_MALKAVIAN, VAMPIRE_CLAN_BANU_HAQIM, VAMPIRE_CLAN_GIOVANNI, VAMPIRE_CLAN_SETITE, VAMPIRE_CLAN_TZIMISCE, VAMPIRE_CLAN_LASOMBRA, VAMPIRE_CLAN_CAITIFF, VAMPIRE_CLAN_KIASYD, VAMPIRE_CLAN_NAGARAJA) + allowed_clans = list(VAMPIRE_CLAN_DAUGHTERS_OF_CACOPHONY, VAMPIRE_CLAN_HEALER_SALUBRI, VAMPIRE_CLAN_WARRIOR_SALUBRI, VAMPIRE_CLAN_BAALI, VAMPIRE_CLAN_BRUJAH, VAMPIRE_CLAN_TREMERE, VAMPIRE_CLAN_VENTRUE, VAMPIRE_CLAN_NOSFERATU, VAMPIRE_CLAN_GANGREL, VAMPIRE_CLAN_CITY_GANGREL, VAMPIRE_CLAN_TOREADOR, VAMPIRE_CLAN_MALKAVIAN, VAMPIRE_CLAN_BANU_HAQIM, VAMPIRE_CLAN_GIOVANNI, VAMPIRE_CLAN_SETITE, VAMPIRE_CLAN_TZIMISCE, VAMPIRE_CLAN_LASOMBRA, VAMPIRE_CLAN_CAITIFF, VAMPIRE_CLAN_KIASYD, VAMPIRE_CLAN_NAGARAJA) /datum/outfit/job/vampire/clinic_director name = "Clinic Director" diff --git a/modular_darkpack/modules/jobs/code/clinic/doctor.dm b/modular_darkpack/modules/jobs/code/clinic/doctor.dm index 0c0fc2c194a8..69704864df65 100644 --- a/modular_darkpack/modules/jobs/code/clinic/doctor.dm +++ b/modular_darkpack/modules/jobs/code/clinic/doctor.dm @@ -17,7 +17,7 @@ description = "Help your fellow kindred in all matters medicine related. Sell blood. Keep your human colleagues ignorant." allowed_splats = list(SPLAT_KINDRED, SPLAT_GHOUL, SPLAT_KINFOLK, SPLAT_NONE) - allowed_clans = list(VAMPIRE_CLAN_DAUGHTERS_OF_CACOPHONY, VAMPIRE_CLAN_SALUBRI, VAMPIRE_CLAN_BAALI, VAMPIRE_CLAN_BRUJAH, VAMPIRE_CLAN_TREMERE, VAMPIRE_CLAN_VENTRUE, VAMPIRE_CLAN_NOSFERATU, VAMPIRE_CLAN_GANGREL, VAMPIRE_CLAN_CITY_GANGREL, VAMPIRE_CLAN_TOREADOR, VAMPIRE_CLAN_MALKAVIAN, VAMPIRE_CLAN_BANU_HAQIM, VAMPIRE_CLAN_GIOVANNI, VAMPIRE_CLAN_SETITE, VAMPIRE_CLAN_TZIMISCE, VAMPIRE_CLAN_LASOMBRA, VAMPIRE_CLAN_CAITIFF, VAMPIRE_CLAN_KIASYD, VAMPIRE_CLAN_NAGARAJA) + allowed_clans = list(VAMPIRE_CLAN_DAUGHTERS_OF_CACOPHONY, VAMPIRE_CLAN_HEALER_SALUBRI, VAMPIRE_CLAN_WARRIOR_SALUBRI, VAMPIRE_CLAN_BAALI, VAMPIRE_CLAN_BRUJAH, VAMPIRE_CLAN_TREMERE, VAMPIRE_CLAN_VENTRUE, VAMPIRE_CLAN_NOSFERATU, VAMPIRE_CLAN_GANGREL, VAMPIRE_CLAN_CITY_GANGREL, VAMPIRE_CLAN_TOREADOR, VAMPIRE_CLAN_MALKAVIAN, VAMPIRE_CLAN_BANU_HAQIM, VAMPIRE_CLAN_GIOVANNI, VAMPIRE_CLAN_SETITE, VAMPIRE_CLAN_TZIMISCE, VAMPIRE_CLAN_LASOMBRA, VAMPIRE_CLAN_CAITIFF, VAMPIRE_CLAN_KIASYD, VAMPIRE_CLAN_NAGARAJA) known_contacts = list("Clinic Director") alt_titles = list( diff --git a/modular_darkpack/modules/powers/code/discipline/__discipline.dm b/modular_darkpack/modules/powers/code/discipline/__discipline.dm index 12f01c8600af..5ab7bc243a0e 100644 --- a/modular_darkpack/modules/powers/code/discipline/__discipline.dm +++ b/modular_darkpack/modules/powers/code/discipline/__discipline.dm @@ -5,7 +5,7 @@ ///Text description of this Discipline. var/desc = "Discipline description" ///Icon file for this Discipline - var/icon = 'modular_darkpack/modules/deprecated/icons/UI/actions.dmi' + var/icon = 'modular_darkpack/modules/powers/icons/actions.dmi' ///Icon state for this Discipline var/icon_state ///If this Discipline is unique to a certain Clan. diff --git a/modular_darkpack/modules/powers/code/discipline/__discipline_power.dm b/modular_darkpack/modules/powers/code/discipline/__discipline_power.dm index b13486279281..258262dd574c 100644 --- a/modular_darkpack/modules/powers/code/discipline/__discipline_power.dm +++ b/modular_darkpack/modules/powers/code/discipline/__discipline_power.dm @@ -177,6 +177,11 @@ to_chat(owner, span_warning("[src] is still on cooldown for [DisplayTimeText(get_cooldown())]!")) return FALSE + if(!check_discipline_flags(alert)) + return FALSE + return TRUE + +/datum/discipline_power/proc/check_discipline_flags(alert = FALSE) //status checks if ((check_flags & DISC_CHECK_TORPORED) && HAS_TRAIT(owner, TRAIT_TORPOR)) if (alert) @@ -719,7 +724,7 @@ /datum/discipline_power/proc/clear_duration_timer(to_clear = 1) if(duration_override) return - + if (toggled && (duration_length == 0)) return diff --git a/modular_darkpack/modules/powers/code/discipline/auspex/auspex.dm b/modular_darkpack/modules/powers/code/discipline/auspex/auspex.dm index 615c6200ca15..e3446ce3cb7c 100644 --- a/modular_darkpack/modules/powers/code/discipline/auspex/auspex.dm +++ b/modular_darkpack/modules/powers/code/discipline/auspex/auspex.dm @@ -50,18 +50,18 @@ if(SENSE_VISION in output_senses) owner.client?.view_size?.setTo(2) // This increases the view size of the player by 2 tiles in each direction. I dont know why it's called Set if it Adds. - ADD_TRAIT(owner, TRAIT_REFLECTIVE_EYES, DISCIPLINE_TRAIT) + ADD_TRAIT(owner, TRAIT_REFLECTIVE_EYES, DISCIPLINE_TRAIT(type)) var/obj/item/organ/eyes/kindred_eyes = owner.get_organ_slot(ORGAN_SLOT_EYES) if(kindred_eyes) kindred_eyes.flash_protect = max(kindred_eyes.flash_protect += -2, FLASH_PROTECTION_HYPER_SENSITIVE) if(SENSE_HEARING in output_senses) - ADD_TRAIT(owner, TRAIT_GOOD_HEARING, DISCIPLINE_TRAIT) + ADD_TRAIT(owner, TRAIT_GOOD_HEARING, DISCIPLINE_TRAIT(type)) var/obj/item/organ/ears/kindred_ears = owner.get_organ_slot(ORGAN_SLOT_EARS) kindred_ears.damage_multiplier = kindred_ears.damage_multiplier + 1 if(SENSE_SMELL in output_senses) - owner.dna?.add_mutation(/datum/mutation/olfaction, DISCIPLINE_TRAIT) + owner.dna?.add_mutation(/datum/mutation/olfaction, DISCIPLINE_TRAIT(type)) if(SENSE_TASTE in output_senses) - ADD_TRAIT(owner, TRAIT_REAGENT_SCANNER, DISCIPLINE_TRAIT) + ADD_TRAIT(owner, TRAIT_REAGENT_SCANNER, DISCIPLINE_TRAIT(type)) if(SENSE_TOUCH in output_senses) RegisterSignals(owner, list(COMSIG_CARBON_HELP_ACT, COMSIG_ON_CARBON_SLIP, COMSIG_LIVING_DISARM_HIT, COMSIG_LIVING_TRYING_TO_PULL), PROC_REF(on_touch)) owner.AddComponent(/datum/component/heartbeat_sensing, color_path = /datum/client_colour/psyker) @@ -75,17 +75,17 @@ if(mutation) owner.dna?.remove_mutation(mutation, mutation.sources) // Hearing - REMOVE_TRAIT(owner, TRAIT_GOOD_HEARING, DISCIPLINE_TRAIT) + REMOVE_TRAIT(owner, TRAIT_GOOD_HEARING, DISCIPLINE_TRAIT(type)) var/obj/item/organ/ears/kindred_ears = owner.get_organ_slot(ORGAN_SLOT_EARS) kindred_ears.damage_multiplier = initial(kindred_ears.damage_multiplier) // Vision owner.client?.view_size?.resetToDefault() - REMOVE_TRAIT(owner, TRAIT_REFLECTIVE_EYES, DISCIPLINE_TRAIT) + REMOVE_TRAIT(owner, TRAIT_REFLECTIVE_EYES, DISCIPLINE_TRAIT(type)) var/obj/item/organ/eyes/kindred_eyes = owner.get_organ_slot(ORGAN_SLOT_EYES) if(kindred_eyes) kindred_eyes.flash_protect = max(kindred_eyes.flash_protect += 2, FLASH_PROTECTION_NONE) // Taste - REMOVE_TRAIT(owner, TRAIT_REAGENT_SCANNER, DISCIPLINE_TRAIT) + REMOVE_TRAIT(owner, TRAIT_REAGENT_SCANNER, DISCIPLINE_TRAIT(type)) // Touch UnregisterSignal(owner, list(COMSIG_CARBON_HELP_ACT, COMSIG_ON_CARBON_SLIP, COMSIG_LIVING_DISARM_HIT, COMSIG_LIVING_TRYING_TO_PULL)) qdel(owner.GetComponent(/datum/component/heartbeat_sensing)) diff --git a/modular_darkpack/modules/powers/code/discipline/healer_valeren.dm b/modular_darkpack/modules/powers/code/discipline/healer_valeren.dm deleted file mode 100644 index 247d292c1596..000000000000 --- a/modular_darkpack/modules/powers/code/discipline/healer_valeren.dm +++ /dev/null @@ -1,154 +0,0 @@ -/datum/discipline/valeren - name = "Healer Valeren" - desc = "Use your third eye in healing or protecting needs." - icon_state = "valeren" - clan_restricted = TRUE - power_type = /datum/discipline_power/valeren - -/datum/discipline_power/valeren - name = "Valeren power name" - desc = "Valeren power description" - - activate_sound = 'modular_darkpack/modules/deprecated/sounds/valeren.ogg' - -//SENSE VITALITY -/datum/discipline_power/valeren/sense_vitality - name = "Sense Vitality" - desc = "Discipline power description" - - level = 1 - check_flags = DISC_CHECK_CONSCIOUS | DISC_CHECK_CAPABLE | DISC_CHECK_IMMOBILE | DISC_CHECK_FREE_HAND - target_type = TARGET_MOB - range = 1 - - cooldown_length = 5 SECONDS - -/datum/discipline_power/valeren/sense_vitality/activate(mob/living/target) - . = ..() - healthscan(owner, target, 1, FALSE) - chemscan(owner, target) - to_chat(owner, "[target] has [num2text(target.bloodpool)]/[target.maxbloodpool] blood points.") - to_chat(owner, "[target] has a rating of [target.humanity] on their path.") - -//ANESTHETIC TOUCH -/datum/discipline_power/valeren/anesthetic_touch - name = "Anesthetic Touch" - desc = "Soothe your patient's pain, or put them to peaceful sleep." - - level = 2 - check_flags = DISC_CHECK_CONSCIOUS | DISC_CHECK_CAPABLE | DISC_CHECK_LYING | DISC_CHECK_FREE_HAND - target_type = TARGET_LIVING - range = 1 - - aggravating = TRUE - hostile = TRUE - - cooldown_length = 20 SECONDS - -/datum/discipline_power/valeren/anesthetic_touch/activate(mob/living/target) - . = ..() - //I'm not a fan of how punishing this is towards human players, but not my job to rework it - if (ismundane(target)) - target.SetSleeping(15 SECONDS) - else - target.add_confusion(5) - target.drowsyness += 4 - -//CORPORE SANO -/datum/discipline_power/valeren/corpore_sano - name = "Corpore Sano" - desc = "Lay hands on your patient and heal their wounds." - - level = 3 - check_flags = DISC_CHECK_CONSCIOUS | DISC_CHECK_CAPABLE | DISC_CHECK_FREE_HAND | DISC_CHECK_IMMOBILE - target_type = TARGET_LIVING - range = 1 - - violates_masquerade = TRUE - - cooldown_length = 5 SECONDS - -/datum/discipline_power/valeren/corpore_sano/activate(mob/living/target) - . = ..() - owner.Beam(target, icon_state="sm_arc", time = 5 SECONDS, maxdistance = 9, beam_type = /obj/effect/ebeam/medical) - - target.heal_ordered_damage(60, list(BRUTE, TOX, BURN, AGGRAVATED, OXY, BRAIN)) - if(ishuman(target)) - var/mob/living/carbon/human/human_target = target - if(length(human_target.all_wounds)) - var/datum/wound/wound = pick(human_target.all_wounds) - wound.remove_wound() - - target.update_damage_overlays() - target.update_health_hud() - -//SHEPHERD'S WATCH -/datum/discipline_power/valeren/shepherds_watch - name = "Shepherd's Watch" - desc = "Create a supernatural barrier to protect yourself from harm." - - level = 4 - - cooldown_length = 40 SECONDS - -/datum/discipline_power/valeren/shepherds_watch/activate() - . = ..() - for (var/turf/turf in orange(1, get_turf(owner))) - new /obj/effect/forcefield/wizard(turf, owner) - -//UNBURDEN THE BESTIAL SOUL -/datum/discipline_power/valeren/unburden_the_bestial_soul - name = "Unburden The Bestial Soul" - desc = "Draw out a Kindred's soul and heal it of impurities." - - level = 5 - check_flags = DISC_CHECK_CONSCIOUS | DISC_CHECK_CAPABLE | DISC_CHECK_IMMOBILE | DISC_CHECK_FREE_HAND - target_type = TARGET_LIVING - range = 1 - - cooldown_length = 5 SECONDS - - var/points_can_restore = 3 - -/datum/discipline_power/valeren/unburden_the_bestial_soul/can_activate_untargeted(alert) - . = ..() - - if (points_can_restore <= 0) - if (alert) - to_chat(owner, span_warning("You've exhausted yourself too much to cleanse more souls.")) - return FALSE - - return . - -/datum/discipline_power/valeren/unburden_the_bestial_soul/can_activate(mob/living/target, alert) - . = ..() - - if (!get_kindred_splat(target)) - if (alert) - to_chat(owner, span_warning("[src] can only be used on Kindred.")) - return FALSE - - if (!target.client) - if (alert) - to_chat(owner, span_warning("[target] does not have a soul to cleanse!")) - return FALSE - - if (target.humanity >= 10 && !target.client?.prefs?.enlightenment) - if (alert) - to_chat(owner, span_warning("[target]'s soul is already completely pure.")) - return FALSE - - return . - -/datum/discipline_power/valeren/unburden_the_bestial_soul/pre_activation_checks(mob/living/carbon/human/target) - to_chat(owner, span_warning("You begin cleansing [target]'s soul...")) - if (do_mob(owner, target, 10 SECONDS)) - return TRUE - -/datum/discipline_power/valeren/unburden_the_bestial_soul/activate(mob/living/carbon/human/target) - . = ..() - to_chat(owner, span_notice("You have healed [target]'s soul slightly.")) - SEND_SIGNAL(owner, COMSIG_PATH_HIT, 1, 10, FALSE) - points_can_restore-- - - diff --git a/modular_darkpack/modules/powers/code/discipline/obeah/obeah.dm b/modular_darkpack/modules/powers/code/discipline/obeah/obeah.dm new file mode 100644 index 000000000000..8dbaa5a7bc29 --- /dev/null +++ b/modular_darkpack/modules/powers/code/discipline/obeah/obeah.dm @@ -0,0 +1,302 @@ +/datum/discipline/obeah + name = "Obeah" + desc = "Use your third eye in healing or protecting needs." + icon_state = "obeah" + clan_restricted = TRUE + power_type = /datum/discipline_power/obeah + +/datum/discipline_power/obeah + name = "Valeren power name" + desc = "Valeren power description" + + activate_sound = 'modular_darkpack/modules/powers/sounds/obeah.ogg' + +/datum/discipline_power/obeah/sense_vitality + name = "Sense Vitality" + desc = "Allows you to determine the vitality of a target." + level = 1 + check_flags = DISC_CHECK_CAPABLE + target_type = TARGET_HUMAN | TARGET_SELF + range = 1 + cooldown_length = 3 TURNS + duration_length = 1 TURNS + activate_sound = null + vitae_cost = 0 + var/successes = 0 + + var/msg_creature = "" // what kinda phreak they is + var/msg_damage = "" + var/msg_blood = "" + var/msg_disease = "" + var/msg_mental = "" + +/datum/discipline_power/obeah/sense_vitality/pre_activation_checks(mob/living/target) + . = ..() + successes = SSroll.storyteller_roll(owner.st_get_stat(STAT_PERCEPTION) + owner.st_get_stat(STAT_EMPATHY), 7, owner, TRUE) + if(successes > 1) + return TRUE + else + return FALSE + +/datum/discipline_power/obeah/sense_vitality/proc/blood_read(mob/living/carbon/human/target) + var/blood_volume = target.get_blood_volume(apply_modifiers = TRUE) + switch(blood_volume) + if(BLOOD_VOLUME_EXCESS to INFINITY) + return "Their veins are engorged to the point of rupture." + if(BLOOD_VOLUME_MAXIMUM to BLOOD_VOLUME_EXCESS) + return "They are heavily overloaded with blood." + if(BLOOD_VOLUME_SAFE to BLOOD_VOLUME_MAXIMUM) + return "Their blood volume is healthy." + if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE) + return "Their blood is lower than normal." + if(BLOOD_VOLUME_RISKY to BLOOD_VOLUME_OKAY) + return "Their blood volume is dangerously low." + if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_RISKY) + return "Dangerously low blood." + if(BLOOD_VOLUME_SURVIVE to BLOOD_VOLUME_BAD) + return "They are nearly void of blood altogether. Death comes for them soon without immediate intervention." + else + return "They are completely exsanguinated." + +/datum/discipline_power/obeah/sense_vitality/proc/damage_severity(damage) + if(damage < 30) + return "some" + if(damage < 50) + return "moderate" + return "heavy" + +/datum/discipline_power/obeah/sense_vitality/ui_state(mob/user) + return GLOB.always_state + +/datum/discipline_power/obeah/sense_vitality/ui_interact(mob/user, datum/tgui/ui) + . = ..() + var/datum/asset/valeren_files = get_asset_datum(/datum/asset/simple/valeren_assets) + if(user.client) + valeren_files.send(user.client) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new /datum/tgui(user, src, "Valeren") + ui.open() + +/datum/discipline_power/obeah/sense_vitality/ui_data(mob/living/user) + var/list/data = list() + data["creature"] = msg_creature + data["damage"] = msg_damage + data["blood"] = msg_blood + data["disease"] = msg_disease + data["mental"] = msg_mental + return data + +/datum/discipline_power/obeah/sense_vitality/activate(mob/living/target) + . = ..() + msg_creature = "" + msg_damage = "" + msg_blood = "" + msg_disease = "" + msg_mental = "" + + // on one success, identify their splat + var/creature_type = "a mortal" + if(get_kindred_splat(target)) + creature_type = "kindred" + else if(get_ghoul_splat(target)) + creature_type = "a ghoul" + else if(isavatar(target) || isobserver(target)) // because salubri spend all their time in the clinic anyway. they'll use this on ghosts + creature_type = "a wraith" + msg_creature = "[target] is [creature_type]." + + // on two successes, identify their damage + if(successes >= 2) + var/brute = target.get_brute_loss() + var/burn = target.get_fire_loss() + var/tox = target.get_tox_loss() + var/oxy = target.get_oxy_loss() + var/agg = target.get_agg_loss() + var/list/damage_parts = list() + if(brute > 0) + damage_parts += "[damage_severity(brute)] bruising" + if(burn > 0) + damage_parts += "[damage_severity(burn)] burns" + if(tox > 0) + damage_parts += "[damage_severity(tox)] toxin damage" + if(oxy > 0) + damage_parts += "[damage_severity(oxy)] oxygen deprivation" + if(agg > 0) + damage_parts += "[damage_severity(agg)] supernatural wounds" + msg_damage = length(damage_parts) ? "They bear [english_list(damage_parts)]." : "They appear uninjured." + + // on three successes, detect their bloodpool, if any exists + if(successes >= 3) + msg_blood = "[blood_read(target)] [round(target.bloodpool / target.maxbloodpool * 100)]% of Blood Pool remaining." + + // on four, display any diseases they might have + if(successes >= 4) + var/list/datum/disease/diseases = target.get_static_viruses() + if(LAZYLEN(diseases)) + var/list/disease_names = list() + for(var/datum/disease/D in diseases) + disease_names += D.name + msg_disease = "Detected [english_list(disease_names)] in their blood." + else + msg_disease = "Found no diseases in their blood." + var/list/mental_conditions = list() + if(target.has_quirk(/datum/quirk/insanity)) + mental_conditions += "insanity" + if(target.has_quirk(/datum/quirk/derangement)) + mental_conditions += "an incurable derangement" + if(length(mental_conditions)) + msg_mental = "[english_list(mental_conditions)] clouds their mind." + + ui_interact(owner) + to_chat(owner, span_notice("[msg_creature] \n[msg_damage] \n[msg_blood] \n[msg_disease] \n[msg_mental]")) + +/datum/discipline_power/obeah/sense_vitality/deactivate() + . = ..() + +/datum/discipline_power/obeah/anesthetic_touch + name = "Anesthetic Touch" + desc = "Soothe your patient's pain, or place a mortal into peaceful slumber." + level = 2 + check_flags = DISC_CHECK_CONSCIOUS | DISC_CHECK_CAPABLE | DISC_CHECK_FREE_HAND + target_type = TARGET_LIVING + range = 1 + cooldown_length = 3 TURNS + var/sleep_duration_length = 10 TURNS + var/soothe_duration_length = 1 SCENES + var/successes = 0 + +/datum/discipline_power/obeah/anesthetic_touch/pre_activation_checks(mob/living/target) + . = ..() + successes = SSroll.storyteller_roll(owner.st_get_stat(STAT_TEMPORARY_WILLPOWER), (target.combat_mode ? 8 : 6), owner, TRUE) + if(successes >= 1) + return TRUE + else + return FALSE + +/datum/discipline_power/obeah/anesthetic_touch/activate(mob/living/target) + . = ..() + var/list/choices = list( + "Soothe Pain" = icon('icons/mob/actions/actions_spells.dmi', "statue"), + "Put To Sleep" = icon('icons/mob/actions/actions_spells.dmi', "blind"), + ) + var/chosen_option = show_radial_menu(owner, target, choices, radius = 38, require_near = TRUE) + switch(chosen_option) + if("Soothe Pain") + ADD_TRAIT(target, TRAIT_IGNORESLOWDOWN, type) + addtimer(CALLBACK(src, PROC_REF(end_soothe_pain), target), (successes TURNS) + soothe_duration_length) + if("Put To Sleep") + if(get_kindred_splat(target)) + to_chat(owner, span_warning("You can't put a Kindred to sleep with this power!")) + return TRUE + target.SetSleeping(sleep_duration_length + (successes TURNS)) // 50 seconds + successes in turns + target.adjust_blood_pool(1) // restores a BP to the target, but if this gets abused, maybe make this depend on successes + return TRUE + +/datum/discipline_power/obeah/anesthetic_touch/proc/end_soothe_pain(mob/living/target) + REMOVE_TRAIT(target, TRAIT_IGNORESLOWDOWN, type) + +/datum/discipline_power/obeah/corpore_sano + name = "Corpore Sano" + desc = "Lay hands on your patient and heal their wounds." + + level = 3 + check_flags = DISC_CHECK_CONSCIOUS | DISC_CHECK_CAPABLE | DISC_CHECK_FREE_HAND | DISC_CHECK_IMMOBILE + target_type = TARGET_LIVING + range = 1 + + violates_masquerade = TRUE + cooldown_length = 1 TURNS + +/datum/discipline_power/obeah/corpore_sano/activate(atom/target) + . = ..() + var/mob/living/living_target = target + if(living_target.get_agg_loss() && (owner.bloodpool >= 1)) + owner.adjust_blood_pool(-1) + living_target.heal_storyteller_health(dots_to_heal = 1, heal_aggravated = TRUE, heal_scars = TRUE, heal_blood = TRUE) + else + living_target.heal_storyteller_health(dots_to_heal = 1, heal_aggravated = FALSE, heal_scars = TRUE, heal_blood = TRUE) + +// Radius - the length of the line you draw from the central point of a circle towards any point of the outer boundary, which in geometry is called the circumference. +#define SHEPHERDS_WATCH_RADIUS 3 +/datum/discipline_power/obeah/shepherds_watch + name = "Shepherd's Watch" + desc = "Create a supernatural barrier to protect yourself from harm." + + level = 4 + check_flags = DISC_CHECK_CONSCIOUS | DISC_CHECK_CAPABLE | DISC_CHECK_FREE_HAND | DISC_CHECK_IMMOBILE + violates_masquerade = TRUE + cooldown_length = 1 TURNS + duration_length = 1 TURNS + willpower_cost = 2 + cancelable = TRUE + var/datum/proximity_monitor/advanced/shepherds_watch/area_of_effect + +/datum/discipline_power/obeah/shepherds_watch/activate(atom/target) + . = ..() + area_of_effect = new(owner, SHEPHERDS_WATCH_RADIUS) + for(var/mob/living/mob_living in range(SHEPHERDS_WATCH_RADIUS, owner)) + area_of_effect.ignored_mobs |= mob_living + +/datum/discipline_power/obeah/shepherds_watch/duration_expire(atom/target) + clear_duration_timer() + owner.update_action_buttons() + if(!check_discipline_flags()) + deactivate(owner, FALSE) + return + do_duration(owner) + +/datum/discipline_power/obeah/shepherds_watch/deactivate(atom/target, direct) + . = ..() + QDEL_NULL(area_of_effect) + +#undef SHEPHERDS_WATCH_RADIUS + +/datum/discipline_power/obeah/unburden_the_bestial_soul + name = "Unburden The Bestial Soul" + desc = "Draw out a Kindred's soul and heal it of impurities." + + level = 5 + check_flags = DISC_CHECK_CONSCIOUS | DISC_CHECK_CAPABLE | DISC_CHECK_FREE_HAND | DISC_CHECK_IMMOBILE + violates_masquerade = TRUE + cooldown_length = 1 TURNS + vitae_cost = 2 + target_type = TARGET_LIVING + range = 1 + var/datum/storyteller_roll/unburden_the_bestial_soul/discipline_roll + +/datum/storyteller_roll/unburden_the_bestial_soul + bumper_text = "unburden the bestial soul" + applicable_stats = list(STAT_INTELLIGENCE, STAT_EMPATHY) + difficulty = 8 + roll_output_type = ROLL_PRIVATE_AND_TARGET + +/datum/discipline_power/obeah/unburden_the_bestial_soul/activate(atom/target) + . = ..() + var/mob/living/carbon/carbon_target = target + var/obj/item/organ/brain/target_brain = carbon_target.get_organ_by_type(/obj/item/organ/brain) + var/list/gotten_traumas = target_brain.traumas + if(carbon_target.has_quirk(/datum/quirk/derangement)) + gotten_traumas += "Derangement" + var/chosen_derangement = tgui_input_list(owner, "Choose a trauma to cure", "Traumas", gotten_traumas) + if(!chosen_derangement) + to_chat(owner, span_notice("You fail to find any traumas.")) + return + var/datum/storyteller_roll/unburden_the_bestial_soul/discipline_roll = new() + var/success = discipline_roll.st_roll(owner, target) + switch(success) + if(ROLL_BOTCH) + var/obj/item/organ/brain/owner_brain = owner.get_organ_by_type(/obj/item/organ/brain) + if(chosen_derangement == "Derangement") + owner.add_quirk(/datum/quirk/derangement) + else + owner_brain.gain_trauma_type(chosen_derangement, TRAUMA_RESILIENCE_MAGIC) + to_chat(owner, span_bolddanger("You fail to alleviate [target]'s [chosen_derangement] as your own brain inherits it!")) + if(ROLL_FAILURE) + to_chat(owner, span_danger("You fail to alleviate [target]'s [chosen_derangement].")) + if(ROLL_SUCCESS) + if(chosen_derangement == "Derangement") + carbon_target.remove_quirk(/datum/quirk/derangement) + else + target_brain.cure_trauma_type(chosen_derangement, TRAUMA_RESILIENCE_MAGIC) + to_chat(owner, span_notice("You succesfully alleviate [target]'s [chosen_derangement].")) + diff --git a/modular_darkpack/modules/powers/code/discipline/obeah/shepherds_watch.dm b/modular_darkpack/modules/powers/code/discipline/obeah/shepherds_watch.dm new file mode 100644 index 000000000000..62c5d4d0284f --- /dev/null +++ b/modular_darkpack/modules/powers/code/discipline/obeah/shepherds_watch.dm @@ -0,0 +1,84 @@ +/datum/storyteller_roll/shepherds_watch + bumper_text = "shepherd's watch" + applicable_stats = list(STAT_PERMANENT_WILLPOWER) + roll_output_type = ROLL_PRIVATE_ADMIN + numerical = TRUE + spammy_roll = TRUE + difficulty = 1 // This changes for both. + +/datum/storyteller_roll/shepherds_watch/contested + bumper_text = "willpower" + +/datum/proximity_monitor/advanced/shepherds_watch + edge_is_a_field = TRUE + var/list/ignored_mobs + var/datum/storyteller_roll/salubri_roll_type = /datum/storyteller_roll/shepherds_watch + var/datum/storyteller_roll/contested_roll_type = /datum/storyteller_roll/shepherds_watch/contested + +/datum/proximity_monitor/advanced/shepherds_watch/New(atom/_host, range, _ignore_if_not_on_turf = TRUE) + . = ..() + ignored_mobs = new() + recalculate_field(full_recalc = TRUE) + +/datum/proximity_monitor/advanced/shepherds_watch/Destroy() + ignored_mobs = null + return ..() + +/datum/proximity_monitor/advanced/shepherds_watch/setup_field_turf(turf/target) + if(QDELETED(src)) + return + for(var/mob/living/possible_mob in target) + if(possible_mob == host) + continue + barrier_check(host, possible_mob) + +/datum/proximity_monitor/advanced/shepherds_watch/on_entered(atom/source, atom/movable/arrived, turf/old_loc) + . = ..() + if(QDELETED(src)) + return + if(!isliving(arrived)) + return + if(arrived == host) + return + barrier_check(host, arrived, old_loc) + +/datum/proximity_monitor/advanced/shepherds_watch/on_moved(atom/movable/source, atom/old_loc) + . = ..() + if(QDELETED(src)) + return + if(!isliving(source)) + return + if(source == host) + return + barrier_check(host, source, old_loc) + +/datum/proximity_monitor/advanced/shepherds_watch/on_z_change(datum/source, turf/old_turf, turf/new_turf) + . = ..() + if(QDELETED(src)) + return + if(!isliving(source)) + return + if(source == host) + return + barrier_check(host, source, old_turf) + +/datum/proximity_monitor/advanced/shepherds_watch/proc/barrier_check(mob/living/salubri, mob/living/opponent, turf/old_loc) + if(opponent in ignored_mobs) + return + if(roll_contested_willpower(salubri, opponent) > 3) + ignored_mobs |= opponent + return + var/throwtarget = old_loc + if(!throwtarget) + throwtarget = get_edge_target_turf(salubri, get_dir(salubri, get_step_away(opponent, salubri))) + opponent.safe_throw_at(throwtarget, 1, 1, src, spin = FALSE, force = MOVE_FORCE_VERY_STRONG, gentle = TRUE) + +/datum/proximity_monitor/advanced/shepherds_watch/proc/roll_contested_willpower(mob/living/salubri, mob/living/opponent) + var/datum/storyteller_roll/shepherds_watch/salubri_roll = new salubri_roll_type() + var/datum/storyteller_roll/shepherds_watch/contested/contested_roll = new contested_roll_type() + salubri_roll.difficulty = opponent.st_get_stat(STAT_TEMPORARY_WILLPOWER) + contested_roll.difficulty = salubri.st_get_stat(STAT_TEMPORARY_WILLPOWER) + + var/salubri_successes = salubri_roll.st_roll(salubri, opponent) + var/opponent_successes = contested_roll.st_roll(opponent, salubri) + return (opponent_successes - salubri_successes) diff --git a/modular_darkpack/modules/powers/code/discipline/quietus/fields/silence_of_death_aoe.dm b/modular_darkpack/modules/powers/code/discipline/quietus/fields/silence_of_death_aoe.dm index 5864674617d7..de258b8f4431 100644 --- a/modular_darkpack/modules/powers/code/discipline/quietus/fields/silence_of_death_aoe.dm +++ b/modular_darkpack/modules/powers/code/discipline/quietus/fields/silence_of_death_aoe.dm @@ -9,13 +9,13 @@ . = ..() silenced_mobs = list() if(ishuman(_host)) - ADD_TRAIT(_host, TRAIT_SILENCED, DISCIPLINE_TRAIT) + ADD_TRAIT(_host, TRAIT_SILENCED, DISCIPLINE_TRAIT(type)) silenced_mobs |= _host /datum/proximity_monitor/advanced/silence_of_death/Destroy() for(var/mob/living/carbon/human/H in silenced_mobs) - REMOVE_TRAIT(H, TRAIT_SILENCED, DISCIPLINE_TRAIT) - REMOVE_TRAIT(H, TRAIT_MUTE, DISCIPLINE_TRAIT) + REMOVE_TRAIT(H, TRAIT_SILENCED, DISCIPLINE_TRAIT(type)) + REMOVE_TRAIT(H, TRAIT_MUTE, DISCIPLINE_TRAIT(type)) silenced_mobs = null return ..() @@ -29,10 +29,10 @@ return var/mob/living/carbon/human/H = entered - ADD_TRAIT(H, TRAIT_SILENCED, DISCIPLINE_TRAIT) + ADD_TRAIT(H, TRAIT_SILENCED, DISCIPLINE_TRAIT(type)) if(H != host) - ADD_TRAIT(H, TRAIT_MUTE, DISCIPLINE_TRAIT) + ADD_TRAIT(H, TRAIT_MUTE, DISCIPLINE_TRAIT(type)) H.adjust_confusion_up_to(15 SECONDS, 15 SECONDS) @@ -50,16 +50,16 @@ return var/mob/living/carbon/human/H = gone - REMOVE_TRAIT(H, TRAIT_SILENCED, DISCIPLINE_TRAIT) - REMOVE_TRAIT(H, TRAIT_MUTE, DISCIPLINE_TRAIT) + REMOVE_TRAIT(H, TRAIT_SILENCED, DISCIPLINE_TRAIT(type)) + REMOVE_TRAIT(H, TRAIT_MUTE, DISCIPLINE_TRAIT(type)) silenced_mobs -= H /datum/proximity_monitor/advanced/silence_of_death/on_z_change() if(QDELETED(src)) return for(var/mob/living/carbon/human/H in silenced_mobs) - REMOVE_TRAIT(H, TRAIT_SILENCED, DISCIPLINE_TRAIT) - REMOVE_TRAIT(H, TRAIT_MUTE, DISCIPLINE_TRAIT) + REMOVE_TRAIT(H, TRAIT_SILENCED, DISCIPLINE_TRAIT(type)) + REMOVE_TRAIT(H, TRAIT_MUTE, DISCIPLINE_TRAIT(type)) silenced_mobs.Cut() /datum/proximity_monitor/advanced/silence_of_death/cleanup_field_turf(turf/target) @@ -67,6 +67,6 @@ return for(var/mob/living/carbon/human/H in target.contents) if((H in silenced_mobs) && H != host) - REMOVE_TRAIT(H, TRAIT_SILENCED, DISCIPLINE_TRAIT) - REMOVE_TRAIT(H, TRAIT_MUTE, DISCIPLINE_TRAIT) + REMOVE_TRAIT(H, TRAIT_SILENCED, DISCIPLINE_TRAIT(type)) + REMOVE_TRAIT(H, TRAIT_MUTE, DISCIPLINE_TRAIT(type)) silenced_mobs -= H diff --git a/modular_darkpack/modules/powers/code/discipline/serpentis.dm b/modular_darkpack/modules/powers/code/discipline/serpentis.dm index ae576f3aec15..1384f25c69d9 100644 --- a/modular_darkpack/modules/powers/code/discipline/serpentis.dm +++ b/modular_darkpack/modules/powers/code/discipline/serpentis.dm @@ -117,10 +117,10 @@ if(choice == "Obvious") owner.st_add_stat_mod(STAT_INTIMIDATION, 2, "Serpentis") // 'reduce intimidation difficulties by two' placeholder owner.st_add_stat_mod(STAT_STAMINA, 3, "Serpentis") // 'reduces all soak difficulty to 5' placeholder - ADD_TRAIT(owner, TRAIT_MASQUERADE_VIOLATING_FACE, DISCIPLINE_TRAIT) + ADD_TRAIT(owner, TRAIT_MASQUERADE_VIOLATING_FACE, DISCIPLINE_TRAIT(type)) else owner.st_add_stat_mod(STAT_STAMINA, 2, "Serpentis") // permanently on with no downsides according to dav20. its staying at fort one bro - ADD_TRAIT(owner, TRAIT_SERPENTIS_SKIN, DISCIPLINE_TRAIT) //ideally this would either be blatantly obvious or not so much depending on the choice. I guess masq violating face trait will work for obvious. + ADD_TRAIT(owner, TRAIT_SERPENTIS_SKIN, DISCIPLINE_TRAIT(type)) //ideally this would either be blatantly obvious or not so much depending on the choice. I guess masq violating face trait will work for obvious. owner.st_add_stat_mod(STAT_APPEARANCE, -(owner.st_get_stat(STAT_APPEARANCE) - 1), "Serpentis") /* owner.Stun(duration_length) @@ -132,10 +132,10 @@ if(choice == "Obvious") owner.st_remove_stat_mod(STAT_INTIMIDATION, 2, "Serpentis") owner.st_remove_stat_mod(STAT_STAMINA, 3, "Serpentis") - REMOVE_TRAIT(owner, TRAIT_MASQUERADE_VIOLATING_FACE, DISCIPLINE_TRAIT) + REMOVE_TRAIT(owner, TRAIT_MASQUERADE_VIOLATING_FACE, DISCIPLINE_TRAIT(type)) else owner.st_remove_stat_mod(STAT_STAMINA, 2, "Serpentis") - REMOVE_TRAIT(owner, TRAIT_SERPENTIS_SKIN, DISCIPLINE_TRAIT) + REMOVE_TRAIT(owner, TRAIT_SERPENTIS_SKIN, DISCIPLINE_TRAIT(type)) owner.st_remove_stat_mod(STAT_APPEARANCE, "Serpentis") @@ -246,7 +246,7 @@ owner.dna.species.inherent_traits |= TRAIT_STUNIMMUNE owner.dna.species.inherent_traits |= TRAIT_SLEEPIMMUNE owner.dna.species.inherent_traits |= TRAIT_NOSOFTCRIT - ADD_TRAIT(owner, TRAIT_STAKE_IMMUNE, DISCIPLINE_TRAIT) + ADD_TRAIT(owner, TRAIT_STAKE_IMMUNE, DISCIPLINE_TRAIT(type)) urn = new(owner.loc) urn.own = owner //var/obj/item/organ/heart/heart = owner.get_organ_slot(ORGAN_SLOT_HEART) DARKPACK TODO - Vampire Organs need to be made useless @@ -256,7 +256,7 @@ owner.dna.species.inherent_traits -= TRAIT_STUNIMMUNE owner.dna.species.inherent_traits -= TRAIT_SLEEPIMMUNE owner.dna.species.inherent_traits -= TRAIT_NOSOFTCRIT - REMOVE_TRAIT(owner, TRAIT_STAKE_IMMUNE, DISCIPLINE_TRAIT) + REMOVE_TRAIT(owner, TRAIT_STAKE_IMMUNE, DISCIPLINE_TRAIT(type)) //for(var/obj/item/organ/heart/heart in urn) //heart.forceMove(owner) //heart.Insert(owner) diff --git a/modular_darkpack/modules/powers/code/discipline/temporis/temporis.dm b/modular_darkpack/modules/powers/code/discipline/temporis/temporis.dm index 839b6e4bb325..a811e90c4688 100644 --- a/modular_darkpack/modules/powers/code/discipline/temporis/temporis.dm +++ b/modular_darkpack/modules/powers/code/discipline/temporis/temporis.dm @@ -13,7 +13,7 @@ /datum/discipline_power/temporis/activate() . = ..() - ADD_TRAIT(owner, TRAIT_TIMEWARPER, DISCIPLINE_TRAIT) + ADD_TRAIT(owner, TRAIT_TIMEWARPER, DISCIPLINE_TRAIT(type)) /datum/discipline_power/temporis/proc/celerity_explode(datum/source, datum/discipline_power/power, atom/target) SIGNAL_HANDLER diff --git a/modular_darkpack/modules/powers/code/discipline/valeren.dm b/modular_darkpack/modules/powers/code/discipline/valeren.dm new file mode 100644 index 000000000000..ffae30e068ed --- /dev/null +++ b/modular_darkpack/modules/powers/code/discipline/valeren.dm @@ -0,0 +1,574 @@ +// VAMPIRE THE MASQUERADE 20th ANNIVERSARY EDITION - VALEREN (WARRIOR) +/* A healer learns a subject's illnesses to cure them. The +Salubri antitribu, however, learn how close to death a +target is so that they may hasten the process. +System: This power works identically to the Obeah +power of the same name (p. 457): + +"With a touch, the Salubri can instantaneously read +a target's injuries. She may learn how much damage a +target has incurred, and therefore make a guess at what +must be done to save him. This power can also be used +for diagnostic purposes - useful for a victim who can +no longer speak. + +System: The Salubri must touch the target to see how +close to death she is. He must then make a Perception ++ Empathy roll (difficulty 7). One success on this roll +identifies a subject as a mortal, vampire, ghoul, or other creature. + +Two successes reveal how many health levels +of damage the subject has suffered. Three successes tell +how full the subject's blood pool is (if a vampire) or +how many blood points she has left in her system (if a +mortal or other blood-bearing form of life). Four suc- +cesses reveal any diseases in the subject's bloodstream. +A player may opt to learn the information yielded by +a lesser degree of success - for example, a player who +accumulates three successes may learn whether or not +a subject is a vampire as well as the contents of his +blood pool. +*/ + +/datum/discipline/valeren + name = "Valeren" + desc = "The warrior's path of Valeren, used by the Salubri antitribu to read and exploit weakness in their enemies." + icon_state = "valeren" + clan_restricted = TRUE + power_type = /datum/discipline_power/valeren + +// Assets for the UI +/datum/asset/simple/valeren_assets + legacy = TRUE + assets = list( + "da_vinci_vitruve_luc_viatour.webp" = 'modular_darkpack/modules/powers/icons/images/da_vinci_vitruve_luc_viatour.webp', + ) + +/datum/discipline_power/valeren + name = "Valeren power name" + desc = "Valeren power description" + +/datum/discipline_power/valeren/sense_vitality + name = "Sense Vitality" + desc = "Allows you to determine the vitality of a target." + level = 1 + check_flags = DISC_CHECK_CAPABLE + target_type = TARGET_HUMAN | TARGET_SELF + range = 1 + cooldown_length = 3 TURNS + duration_length = 1 TURNS + activate_sound = null + vitae_cost = 0 + var/successes = 0 + + var/msg_creature = "" // what kinda phreak they is + var/msg_damage = "" + var/msg_blood = "" + var/msg_disease = "" + var/msg_mental = "" + +/datum/discipline_power/valeren/sense_vitality/pre_activation_checks(mob/living/target) + . = ..() + successes = SSroll.storyteller_roll(owner.st_get_stat(STAT_PERCEPTION) + owner.st_get_stat(STAT_EMPATHY), 7, owner, TRUE) + if(successes > 1) + return TRUE + else + return FALSE + +/datum/discipline_power/valeren/sense_vitality/proc/blood_read(mob/living/carbon/human/target) + var/blood_volume = target.get_blood_volume(apply_modifiers = TRUE) + switch(blood_volume) + if(BLOOD_VOLUME_EXCESS to INFINITY) + return "Their veins are engorged to the point of rupture." + if(BLOOD_VOLUME_MAXIMUM to BLOOD_VOLUME_EXCESS) + return "They are heavily overloaded with blood." + if(BLOOD_VOLUME_SAFE to BLOOD_VOLUME_MAXIMUM) + return "Their blood volume is healthy." + if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE) + return "Their blood is lower than normal." + if(BLOOD_VOLUME_RISKY to BLOOD_VOLUME_OKAY) + return "Their blood volume is dangerously low." + if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_RISKY) + return "Dangerously low blood." + if(BLOOD_VOLUME_SURVIVE to BLOOD_VOLUME_BAD) + return "They are nearly void of blood altogether. Death comes for them soon without immediate intervention." + else + return "They are completely exsanguinated." + +/datum/discipline_power/valeren/sense_vitality/proc/damage_severity(damage) + if(damage < 30) + return "some" + if(damage < 50) + return "moderate" + return "heavy" + +/datum/discipline_power/valeren/sense_vitality/ui_state(mob/user) + return GLOB.always_state + +/datum/discipline_power/valeren/sense_vitality/ui_interact(mob/user, datum/tgui/ui) + . = ..() + var/datum/asset/valeren_files = get_asset_datum(/datum/asset/simple/valeren_assets) + if(user.client) + valeren_files.send(user.client) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new /datum/tgui(user, src, "Valeren") + ui.open() + +/datum/discipline_power/valeren/sense_vitality/ui_data(mob/living/user) + var/list/data = list() + data["creature"] = msg_creature + data["damage"] = msg_damage + data["blood"] = msg_blood + data["disease"] = msg_disease + data["mental"] = msg_mental + return data + +/datum/discipline_power/valeren/sense_vitality/activate(mob/living/target) + . = ..() + msg_creature = "" + msg_damage = "" + msg_blood = "" + msg_disease = "" + msg_mental = "" + + // on one success, identify their splat + var/creature_type = "a mortal" + if(get_kindred_splat(target)) + creature_type = "kindred" + else if(get_ghoul_splat(target)) + creature_type = "a ghoul" + else if(isavatar(target) || isobserver(target)) // because salubri spend all their time in the clinic anyway. they'll use this on ghosts + creature_type = "a wraith" + msg_creature = "[target] is [creature_type]." + + // on two successes, identify their damage + if(successes >= 2) + var/brute = target.get_brute_loss() + var/burn = target.get_fire_loss() + var/tox = target.get_tox_loss() + var/oxy = target.get_oxy_loss() + var/agg = target.get_agg_loss() + var/list/damage_parts = list() + if(brute > 0) + damage_parts += "[damage_severity(brute)] bruising" + if(burn > 0) + damage_parts += "[damage_severity(burn)] burns" + if(tox > 0) + damage_parts += "[damage_severity(tox)] toxin damage" + if(oxy > 0) + damage_parts += "[damage_severity(oxy)] oxygen deprivation" + if(agg > 0) + damage_parts += "[damage_severity(agg)] supernatural wounds" + msg_damage = length(damage_parts) ? "They bear [english_list(damage_parts)]." : "They appear uninjured." + + // on three successes, detect their bloodpool, if any exists + if(successes >= 3) + msg_blood = "[blood_read(target)] [round(target.bloodpool / target.maxbloodpool * 100)]% of Blood Pool remaining." + + // on four, display any diseases they might have + if(successes >= 4) + var/list/datum/disease/diseases = target.get_static_viruses() + if(LAZYLEN(diseases)) + var/list/disease_names = list() + for(var/datum/disease/D in diseases) + disease_names += D.name + msg_disease = "Detected [english_list(disease_names)] in their blood." + else + msg_disease = "Found no diseases in their blood." + var/list/mental_conditions = list() + if(target.has_quirk(/datum/quirk/insanity)) + mental_conditions += "insanity" + if(target.has_quirk(/datum/quirk/derangement)) + mental_conditions += "an incurable derangement" + if(length(mental_conditions)) + msg_mental = "[english_list(mental_conditions)] clouds their mind." + + ui_interact(owner) + to_chat(owner, span_notice("[msg_creature] \n[msg_damage] \n[msg_blood] \n[msg_disease] \n[msg_mental]")) + +/datum/discipline_power/valeren/sense_vitality/deactivate() + . = ..() + +//ANESTHETIC TOUCH +// +/* +The vampire can ease a target’s pain or place him +into a deep, soothing sleep with nothing but a touch. +This power is intended to heal the pain or succor the +mind of willing targets, but the character can, with +some effort, employ the power against someone who +does not wish it. + +System: If the subject is willing to undergo this +process, the player spends a blood point and makes a +Willpower roll (difficulty 6) to block the subject’s pain. +This allows the subject to ignore all wound penalties +for one turn per success. A second application of this +power may be made once the first one has expired, at +the cost of another blood point and another Willpow +er roll. If the subject is unwilling for some reason, the +player must make a contested Willpower roll against +the subject (difficulty 8). + +To put a mortal to sleep, the same system applies. +The mortal sleeps for five to 10 hours — whatever his +normal sleep cycle is — and regains one temporary +Willpower point upon awakening. He sleeps peace +fully and does not suffer nightmares or the effects of +any derangements while asleep. He may be awakened +normally (or violently). + +Kindred, including the Salubri herself, are unaffected +by this power — their corpselike bodies are too tied to +death. +*/ +/datum/discipline_power/valeren/anesthetic_touch + name = "Anesthetic Touch" + desc = "Soothe your patient's pain, or place a mortal into peaceful slumber." + level = 2 + check_flags = DISC_CHECK_CONSCIOUS | DISC_CHECK_CAPABLE | DISC_CHECK_FREE_HAND + target_type = TARGET_LIVING + range = 1 + cooldown_length = 3 TURNS + var/sleep_duration_length = 10 TURNS + var/soothe_duration_length = 1 SCENES + var/successes = 0 + +/datum/discipline_power/valeren/anesthetic_touch/pre_activation_checks(mob/living/target) + . = ..() + successes = SSroll.storyteller_roll(owner.st_get_stat(STAT_TEMPORARY_WILLPOWER), (target.combat_mode ? 8 : 6), owner, TRUE) + if(successes >= 1) + return TRUE + else + return FALSE + +/datum/discipline_power/valeren/anesthetic_touch/activate(mob/living/target) + . = ..() + var/list/choices = list( + "Soothe Pain" = icon('icons/mob/actions/actions_spells.dmi', "statue"), + "Put To Sleep" = icon('icons/mob/actions/actions_spells.dmi', "blind"), + ) + var/chosen_option = show_radial_menu(owner, target, choices, radius = 38, require_near = TRUE) + switch(chosen_option) + if("Soothe Pain") + ADD_TRAIT(target, TRAIT_IGNORESLOWDOWN, type) + addtimer(CALLBACK(src, PROC_REF(end_soothe_pain), target), (successes TURNS) + soothe_duration_length) + if("Put To Sleep") + if(get_kindred_splat(target)) + to_chat(owner, span_warning("You can't put a Kindred to sleep with this power!")) + return TRUE + target.SetSleeping(sleep_duration_length + (successes TURNS)) // 50 seconds + successes in turns + target.adjust_blood_pool(1) // restores a BP to the target, but if this gets abused, maybe make this depend on successes + return TRUE + +/datum/discipline_power/valeren/anesthetic_touch/proc/end_soothe_pain(mob/living/target) + REMOVE_TRAIT(target, TRAIT_IGNORESLOWDOWN, type) + +//BURNING TOUCH +/* +Burning Touch +The character’s hands bring searing pain, as though +the target is being burnt with red-hot metal. Although +the power does not inflict actual damage, prolonged +or repeated exposure can be enough to traumatize a +victim. This power works extremely well as a torture +method. + +System: The vampire must touch his subject for this +power to take effect, and the effects diminish rapidly +after he removes his hand. The player spends at least +one blood point to activate this power, and each blood +point spent reduces the victim’s dice pools by two while +the Fury is in contact with the victim. This power is +often used for interrogation or torture, wearing down +the subject’s resistance and rendering him much more +tractable. +*/ +/datum/discipline_power/valeren/burning_touch + name = "Burning Touch" + desc = "Channel supernatural fire through your hands, inflicting searing pain on anyone you grab, lasting 30 seconds. The burning does not cause damage but overwhelms the senses, disrupts concentration, and makes using Disciplines extremely difficult." + level = 3 + check_flags = DISC_CHECK_CONSCIOUS | DISC_CHECK_CAPABLE | DISC_CHECK_FREE_HAND + target_type = TARGET_LIVING + range = 1 + vitae_cost = 1 + hostile = TRUE + violates_masquerade = FALSE + +/datum/discipline_power/valeren/burning_touch/activate(mob/living/target) + . = ..() + target.apply_status_effect(/datum/status_effect/burning_touch) + if(owner.grab_state <= GRAB_AGGRESSIVE) + target.grabbedby(owner) + target.grippedby(owner, instant = TRUE) + owner.do_attack_animation(target, ATTACK_EFFECT_MECHFIRE) + +/datum/status_effect/burning_touch + id = "burning_touch" + status_type = STATUS_EFFECT_REFRESH + duration = 6 TURNS // 30 second debuff duration, so it will still affect them for a few seconds even if they escape their captors grip, as per v20 + alert_type = /atom/movable/screen/alert/status_effect/burning_touch + tick_interval = 2 TURNS // how frequently the pain messages will tick + var/list/pain_messages = list( + "It burns!", + "It hurts!", + "Dear god, make it stop!", + "FIRE! FIRE!", + "Stop, please, STOP!", + "My skin is on fire!", + "I can't think! It hurts so much!", + "Let go, let GO!", + "It's in my bones!", + "I can't breathe through the pain!", + "Why won't it stop?!", + ) + +/datum/status_effect/burning_touch/on_apply() + . = ..() + if(!.) + return + owner.st_add_stat_mod(STAT_DEXTERITY, -2, "burning_touch") // you're in searing pain, so you're a little less dextrous + owner.st_add_stat_mod(STAT_TEMPORARY_WILLPOWER, -2, "burning_touch") + var/resist_scream = SSroll.storyteller_roll(owner.st_get_stat(STAT_TEMPORARY_WILLPOWER), 6, owner, FALSE) + if(!resist_scream) + owner.emote("scream") + RegisterSignal(owner, COMSIG_POWER_TRY_ACTIVATE, PROC_REF(on_discipline_activate)) + +/datum/status_effect/burning_touch/on_remove() + . = ..() + owner.st_remove_stat_mod(STAT_DEXTERITY, "burning_touch") + owner.st_remove_stat_mod(STAT_TEMPORARY_WILLPOWER, "burning_touch") + UnregisterSignal(owner, COMSIG_POWER_TRY_ACTIVATE) + +// crispy victims must roll willpower at difficulty 6 to focus through the burning pain +/datum/status_effect/burning_touch/proc/on_discipline_activate(mob/living/source, datum/discipline_power/power, atom/target) + SIGNAL_HANDLER + var/success = SSroll.storyteller_roll(source.st_get_stat(STAT_TEMPORARY_WILLPOWER), 6, source, FALSE) + if(!success) + to_chat(source, span_userdanger("Burning agony overwhelms your concentration. You cannot focus enough to use your Disciplines!")) + return POWER_PREVENT_ACTIVATE + +/datum/status_effect/burning_touch/tick(seconds_between_ticks) + to_chat(owner, span_userdanger(pick(pain_messages))) + playsound(get_turf(owner), SFX_SIZZLE, 80, TRUE) + +/atom/movable/screen/alert/status_effect/burning_touch + name = "Burning Touch" + desc = "Your body burns with supernatural fire! Using Disciplines requires a Willpower roll at difficulty 6 to focus through the pain." + icon_state = "fire" + +// Armor of Caine’s Fury +/* +The Salubri antitribu is surrounded by a shining, +crimson halo. This phantom armor protects the vampire +against most physical injury, as well as against Rötschreck. + +System: The player spends one blood point and rolls +Stamina + Melee (difficulty 7). For each success, the +character gains one point of armor protection against +bashing and lethal damage, to a maximum of five points +of protection. + +Additionally, for every two successes rolled, +she gains an additional die to resist Rötschreck +from the effects of battle (but not fire or sunlight). This +power works for one scene. +*/ +/datum/discipline_power/valeren/armor_of_caines_fury + name = "Armor of Caine's Fury" + desc = "The Salubri antitribu is surrounded by a shining, crimson halo. This phantom armor protects the vampire against most physical injury, as well as against Rötschreck." + level = 4 + check_flags = DISC_CHECK_CONSCIOUS | DISC_CHECK_CAPABLE + cooldown_length = 1 SCENES + toggled = TRUE + duration_length = 2 TURNS + vitae_cost = 1 + var/successes = 0 + violates_masquerade = TRUE + +/datum/discipline_power/valeren/armor_of_caines_fury/pre_activation_checks(mob/living/target) + . = ..() + successes = SSroll.storyteller_roll(owner.st_get_stat(STAT_STAMINA) + owner.st_get_stat(STAT_MELEE), 7, owner, TRUE) + if(successes >= 1) + return TRUE + else + return FALSE + +/datum/discipline_power/valeren/armor_of_caines_fury/activate(mob/living/target) + . = ..() + // TODO: once frenzy is in, add a status effect to reduce frenzy difficulty as per the book's 'resist Rötschreck' + owner.apply_status_effect(/datum/status_effect/armor_of_caines_fury, clamp(successes, 1, 5)) + return TRUE + +/datum/discipline_power/valeren/armor_of_caines_fury/deactivate() + . = ..() + owner.remove_status_effect(/datum/status_effect/armor_of_caines_fury) + +#define CAINES_FURY_PROTECTION 15 // borrowed from fortitude + +/datum/status_effect/armor_of_caines_fury + id = "armor_of_caines_fury" + status_type = STATUS_EFFECT_REPLACE + alert_type = null + var/successes = 1 + +/datum/status_effect/armor_of_caines_fury/on_creation(mob/living/new_owner, successes_count = 1) + successes = successes_count + . = ..() + +/datum/status_effect/armor_of_caines_fury/on_apply() + . = ..() + if (!.) + return + + if (ishuman(owner)) + var/mob/living/carbon/human/H = owner + RegisterSignal(H, COMSIG_MOB_APPLY_DAMAGE_MODIFIERS, PROC_REF(reduce_damage)) + H.AddElement(/datum/element/armor_of_caines_fury_halo, initial_delay = 0 SECONDS) + ADD_TRAIT(owner, TRAIT_MASQUERADE_VIOLATING_FACE, DISCIPLINE_TRAIT(type)) + +/datum/status_effect/armor_of_caines_fury/on_remove() + . = ..() + + if (ishuman(owner)) + var/mob/living/carbon/human/H = owner + UnregisterSignal(H, COMSIG_MOB_APPLY_DAMAGE_MODIFIERS) + H.RemoveElement(/datum/element/armor_of_caines_fury_halo) + REMOVE_TRAIT(owner, TRAIT_MASQUERADE_VIOLATING_FACE, DISCIPLINE_TRAIT(type)) + +/datum/status_effect/armor_of_caines_fury/proc/reduce_damage(datum/source, list/damage_mods, damage_amount, damagetype, def_zone, sharpness, attack_direction, obj/item/attacking_item) + SIGNAL_HANDLER + if (damagetype != BRUTE) + return + + var/protection = clamp(successes * CAINES_FURY_PROTECTION, 0, 90) // we don't yet have a comparison for what 1 point of armor means in v20 vs ingame, so this is just a percent reduction for now + damage_mods += (100 - protection) / 100 + +#undef CAINES_FURY_PROTECTION + +// Halo stuff for Armor of Caine's Fury +/datum/element/armor_of_caines_fury_halo + +/datum/element/armor_of_caines_fury_halo/Attach(datum/target, initial_delay = 20 SECONDS) + . = ..() + if (!isliving(target)) + return ELEMENT_INCOMPATIBLE + + addtimer(CALLBACK(src, PROC_REF(set_halo), target), initial_delay) + +/datum/element/armor_of_caines_fury_halo/proc/set_halo(mob/living/target) + SIGNAL_HANDLER + var/mutable_appearance/new_halo_overlay = mutable_appearance('icons/mob/effects/halo.dmi', "halo[rand(1, 6)]", -HALO_LAYER) + if (ishuman(target)) + var/mob/living/carbon/human/human_parent = target + new /obj/effect/temp_visual/cult/sparks(get_turf(human_parent), human_parent.dir) + human_parent.overlays_standing[HALO_LAYER] = new_halo_overlay + human_parent.apply_overlay(HALO_LAYER) + else + target.add_overlay(new_halo_overlay) + +/datum/element/armor_of_caines_fury_halo/Detach(mob/living/target, ...) + if (ishuman(target)) + var/mob/living/carbon/human/human_parent = target + human_parent.remove_overlay(HALO_LAYER) + human_parent.update_body() + else + target.cut_overlay(HALO_LAYER) + return ..() + +//VENGEANCE OF SAMIEL +/* +The Salubri antitribu strikes his foe with superhu- +man accuracy and strength, as his third eye opens and +changes to a furious, icy blue. Some Furies invoke the +names of ancient Salubri warriors, while others sim- +ply close their normal eyes and let Samiel guide their +hands. + +System: This power costs three blood points. Any +single attack made by the vampire automatically hits +the target as mystic forces guide the blow. Attacks +made in this manner may not be dodged, though they +may be blocked, parried, and soaked as normal. The +blow strikes as if the Salubri antitribu had succeeded +with all of his Dexterity + Melee or Brawling dice pool +(which makes for significant damage). + +This power maybe used only once per turn, and only then the Salubri +antitribu’s sole action is the attack. Additionally, this +power does not work for ranged weapons; only bare +hands or melee weapons. +*/ +// this is basically just potence 5 with stat bonuses, used potence as a baseline because of the 'makes for significant damage' wording in v20 above +/datum/discipline_power/valeren/vengeance_of_samiel + name = "Vengeance of Samiel" + desc = "The Salubri antitribu strikes his foe with superhu-man accuracy and strength, as his third eye opens and changes to a furious, icy blue. Some Furies invoke the names of ancient Salubri warriors, while others simply close their normal eyes and let Samiel guide their hands." + level = 5 + check_flags = DISC_CHECK_CAPABLE + toggled = TRUE + duration_length = 1 TURNS + +/datum/discipline_power/valeren/vengeance_of_samiel/activate() + . = ..() + owner.apply_status_effect(/datum/status_effect/vengeance_of_samiel) + +/datum/discipline_power/valeren/vengeance_of_samiel/deactivate() + . = ..() + owner.remove_status_effect(/datum/status_effect/vengeance_of_samiel) + +/datum/status_effect/vengeance_of_samiel + id = "vengeance_of_samiel" + status_type = STATUS_EFFECT_REPLACE + alert_type = null + + var/bonus = 5 + var/datum/component/tackler/tackler + var/list/obj/item/bodypart/affected_bodyparts + +/datum/status_effect/vengeance_of_samiel/on_apply() + . = ..() + if (!.) + return + owner.st_add_stat_mod(STAT_DEXTERITY, bonus, "vengeance_of_samiel") + owner.st_add_stat_mod(STAT_MELEE, bonus, "vengeance_of_samiel") + owner.st_add_stat_mod(STAT_BRAWL, bonus, "vengeance_of_samiel") + if (iscarbon(owner)) + var/mob/living/carbon/carbon_owner = owner + for (var/obj/item/bodypart/limb as anything in carbon_owner.bodyparts) + if (!istype(limb, /obj/item/bodypart/arm) && !istype(limb, /obj/item/bodypart/leg)) + continue + LAZYADD(affected_bodyparts, limb) + limb.unarmed_damage_low += 8 * bonus + limb.unarmed_damage_high += 8 * bonus + limb.unarmed_attack_sound = pick(list('sound/items/weapons/cqchit2.ogg', 'sound/items/weapons/cqchit1.ogg')) // i know kung fu + else if (isbasicmob(owner)) + var/mob/living/basic/basic_owner = owner + basic_owner.melee_damage_lower += 8 * bonus + basic_owner.melee_damage_upper += 8 * bonus + basic_owner.attack_sound = pick(list('sound/items/weapons/cqchit2.ogg', 'sound/items/weapons/cqchit1.ogg')) + RegisterSignal(owner, COMSIG_MOB_ITEM_ATTACK, PROC_REF(apply_melee_modifier)) + tackler = owner.AddComponent(/datum/component/tackler, stamina_cost=0, base_knockdown = 1 SECONDS, range = 2 + bonus, speed = 1, skill_mod = 0, min_distance = 0) + +/datum/status_effect/vengeance_of_samiel/on_remove() + . = ..() + owner.st_remove_stat_mod(STAT_DEXTERITY, bonus, "vengeance_of_samiel") + owner.st_remove_stat_mod(STAT_MELEE, bonus, "vengeance_of_samiel") + owner.st_remove_stat_mod(STAT_BRAWL, bonus, "vengeance_of_samiel") + if (iscarbon(owner)) + for (var/obj/item/bodypart/limb in affected_bodyparts) + limb.unarmed_damage_low -= 8 * bonus + limb.unarmed_damage_high -= 8 * bonus + limb.unarmed_attack_sound = initial(limb.unarmed_attack_sound) + else if (isbasicmob(owner)) + var/mob/living/basic/basic_owner = owner + basic_owner.melee_damage_lower -= 8 * bonus + basic_owner.melee_damage_upper -= 8 * bonus + basic_owner.attack_sound = initial(basic_owner.attack_sound) + LAZYCLEARLIST(affected_bodyparts) + UnregisterSignal(owner, COMSIG_MOB_ITEM_ATTACK) + qdel(tackler) + +/datum/status_effect/vengeance_of_samiel/proc/apply_melee_modifier(mob/source, mob/M, mob/user, list/modifiers, list/attack_modifiers) + SIGNAL_HANDLER + attack_modifiers[FORCE_MULTIPLIER] += 0.4 * bonus diff --git a/modular_darkpack/modules/powers/code/discipline_actions.dm b/modular_darkpack/modules/powers/code/discipline_actions.dm index d94ef451dc99..ac3b2e09b327 100644 --- a/modular_darkpack/modules/powers/code/discipline_actions.dm +++ b/modular_darkpack/modules/powers/code/discipline_actions.dm @@ -1,7 +1,7 @@ /datum/action/discipline check_flags = NONE background_icon_state = "bg_discipline" - button_icon = 'modular_darkpack/modules/deprecated/icons/ui/actions.dmi' + button_icon = 'modular_darkpack/modules/powers/icons/actions.dmi' button_icon_state = "bloodheal" overlay_icon = 'modular_darkpack/master_files/icons/mob/actions/backgrounds.dmi' diff --git a/modular_darkpack/modules/powers/icons/actions.dmi b/modular_darkpack/modules/powers/icons/actions.dmi new file mode 100644 index 000000000000..d40175e706b1 Binary files /dev/null and b/modular_darkpack/modules/powers/icons/actions.dmi differ diff --git a/modular_darkpack/modules/powers/icons/images/da_vinci_vitruve_luc_viatour.webp b/modular_darkpack/modules/powers/icons/images/da_vinci_vitruve_luc_viatour.webp new file mode 100644 index 000000000000..ae972ef0bc7e Binary files /dev/null and b/modular_darkpack/modules/powers/icons/images/da_vinci_vitruve_luc_viatour.webp differ diff --git a/modular_darkpack/modules/deprecated/sounds/valeren.ogg b/modular_darkpack/modules/powers/sounds/obeah.ogg similarity index 100% rename from modular_darkpack/modules/deprecated/sounds/valeren.ogg rename to modular_darkpack/modules/powers/sounds/obeah.ogg diff --git a/modular_darkpack/modules/ritual_thaumaturgy/rituals/bloodwalk.dm b/modular_darkpack/modules/ritual_thaumaturgy/rituals/bloodwalk.dm index d17852990fe0..008c33fc8c12 100644 --- a/modular_darkpack/modules/ritual_thaumaturgy/rituals/bloodwalk.dm +++ b/modular_darkpack/modules/ritual_thaumaturgy/rituals/bloodwalk.dm @@ -75,10 +75,10 @@ message += "Potent... deadly... and cursed. You know well the curse laid by Tremere on the assassins.\n" if(VAMPIRE_CLAN_TRUE_BRUJAH) message += "The blood is cold and static... It's hard to feel any emotion within it.\n" - if(VAMPIRE_CLAN_SALUBRI) + if(VAMPIRE_CLAN_HEALER_SALUBRI) message += "The cursed blood of the Salubri! The owner of this blood must be slain.\n" - //if(VAMPIRE_CLAN_SALUBRI_WARRIOR) - //message += "The avatar of Samiel's vengeance stands before you, do you dare return their bitter hatred?\n" + if(VAMPIRE_CLAN_WARRIOR_SALUBRI) + message += "The avatar of Samiel's vengeance stands before you, do you dare return their bitter hatred?\n" if(VAMPIRE_CLAN_GIOVANNI, VAMPIRE_CLAN_CAPPADOCIAN) message += "The blood is very cold and filled with death. The owner must be a necromancer.\n" if(VAMPIRE_CLAN_KIASYD) @@ -87,8 +87,8 @@ message += "The blood of our stone servants.\n" if(VAMPIRE_CLAN_SETITE) message += "Seduction and allure are in the blood. Ah, one of the snakes.\n" - //if(VAMPIRE_CLAN_NAGARAJA) - //message += "This blood has an unsettling hunger to it, cold and stained with death.\n" + if(VAMPIRE_CLAN_NAGARAJA) + message += "This blood has an unsettling hunger to it, cold and stained with death.\n" else message += "The blood's origin is hard to trace. Perhaps it is one of the clanless?\n" diff --git a/modular_darkpack/modules/vampire_the_masquerade/code/blood_power.dm b/modular_darkpack/modules/vampire_the_masquerade/code/blood_power.dm index f22123070fe3..ea77bc128a11 100644 --- a/modular_darkpack/modules/vampire_the_masquerade/code/blood_power.dm +++ b/modular_darkpack/modules/vampire_the_masquerade/code/blood_power.dm @@ -1,7 +1,7 @@ /datum/action/cooldown/blood_power name = "Blood Power" desc = "Use vitae to gain supernatural abilities." - button_icon = 'modular_darkpack/modules/deprecated/icons/ui/actions.dmi' + button_icon = 'modular_darkpack/modules/powers/icons/actions.dmi' button_icon_state = "bloodpower" background_icon = 'modular_darkpack/master_files/icons/mob/actions/backgrounds.dmi' background_icon_state = "bg_discipline" @@ -60,7 +60,7 @@ human_owner.adjust_blood_pool(-current_bp_cost(human_owner)) - ADD_TRAIT(human_owner, TRAIT_IGNORESLOWDOWN, MAGIC_TRAIT) + ADD_TRAIT(human_owner, TRAIT_IGNORESLOWDOWN, DISCIPLINE_TRAIT(type)) addtimer(CALLBACK(src, PROC_REF(end_bloodpower)), cooldown_time) @@ -84,7 +84,7 @@ human_owner.st_remove_stat_mod(STAT_DEXTERITY, "blood_power") human_owner.st_remove_stat_mod(STAT_STAMINA, "blood_power") - REMOVE_TRAIT(human_owner, TRAIT_IGNORESLOWDOWN, MAGIC_TRAIT) + REMOVE_TRAIT(human_owner, TRAIT_IGNORESLOWDOWN, DISCIPLINE_TRAIT(type)) /datum/action/cooldown/blood_power/proc/set_usage() var/turns = tgui_input_number(owner, "Set turns ([1 TURNS / 10] seconds per turn) to use blood for.", "Set Bloodpower Turns", turns_activated, TURNS_PER_SCENE, 1) diff --git a/modular_darkpack/modules/vampire_the_masquerade/code/vampire_clan/clan_pref.dm b/modular_darkpack/modules/vampire_the_masquerade/code/vampire_clan/clan_pref.dm index e0eb7a7a9c54..4f7413c91f6b 100644 --- a/modular_darkpack/modules/vampire_the_masquerade/code/vampire_clan/clan_pref.dm +++ b/modular_darkpack/modules/vampire_the_masquerade/code/vampire_clan/clan_pref.dm @@ -8,7 +8,7 @@ return assoc_to_keys(GLOB.vampire_clan_list) /datum/preference/choiced/subsplat/vampire_clan/icon_for(value) - return uni_icon('modular_darkpack/modules/vampire_the_masquerade/icons/vampire_clans.dmi', get_vampire_clan(value).id) + return uni_icon('modular_darkpack/modules/vampire_the_masquerade/icons/vampire_clans.dmi', get_vampire_clan(value).icon) /datum/preference/choiced/subsplat/vampire_clan/apply_to_human(mob/living/carbon/human/target, value) target.set_clan(value, TRUE) diff --git a/modular_darkpack/modules/vampire_the_masquerade/code/vampire_clan/clans/salubri.dm b/modular_darkpack/modules/vampire_the_masquerade/code/vampire_clan/clans/salubri.dm index 01265a1292e9..fefb73c2ff19 100644 --- a/modular_darkpack/modules/vampire_the_masquerade/code/vampire_clan/clans/salubri.dm +++ b/modular_darkpack/modules/vampire_the_masquerade/code/vampire_clan/clans/salubri.dm @@ -1,13 +1,13 @@ /datum/subsplat/vampire_clan/salubri - name = "Salubri" - id = VAMPIRE_CLAN_SALUBRI + name = "Healer Salubri" + id = VAMPIRE_CLAN_HEALER_SALUBRI desc = "The Salubri are one of the original 13 clans of the vampiric descendants of Caine. Salubri believe that vampiric existence is torment from which Golconda or death is the only escape. Consequently, the modern Salubri would Embrace, teach a childe the basics of the route, leave clues for the childe to follow to achieve Golconda, and then have their childe diablerize them." icon = "salubri" curse = "Hunted and consensual feeding." clan_disciplines = list( /datum/discipline/auspex, /datum/discipline/fortitude, - // /datum/discipline/valeren + /datum/discipline/obeah ) clan_traits = list( TRAIT_CONSENSUAL_FEEDING_ONLY, @@ -18,24 +18,43 @@ enlightenment = FALSE subsplat_keys = /obj/item/vamp/keys/salubri +/datum/subsplat/vampire_clan/salubri/warrior + name = "Warrior Salubri" + id = VAMPIRE_CLAN_WARRIOR_SALUBRI + icon = "salubri" + clan_disciplines = list( + /datum/discipline/auspex, + /datum/discipline/fortitude, + /datum/discipline/valeren + ) + /datum/subsplat/vampire_clan/salubri/on_gain(mob/living/carbon/human/gaining_mob, datum/splat/gaining_splat, joining_round) . = ..() + /* var/obj/item/organ/eyes/salubri/three_eyes = new() three_eyes.Insert(gaining_mob, TRUE, DELETE_IF_REPLACED) + */ /datum/subsplat/vampire_clan/salubri/on_lose(mob/living/carbon/human/losing_mob) . = ..() + /* // replace eyes var/eye_type = /obj/item/organ/eyes if(losing_mob.dna.species && losing_mob.dna.species.mutanteyes) eye_type = losing_mob.dna.species.mutanteyes var/obj/item/organ/eyes/new_eyes = new eye_type() new_eyes.Insert(losing_mob, TRUE, DELETE_IF_REPLACED) + */ +/* DARKPACK TODO: Implement salubri third eye visuals. /obj/item/organ/eyes/salubri eye_icon = 'modular_darkpack/modules/vampire_the_masquerade/icons/human_eyes.dmi' eye_icon_state = "salubri" blink_animation = FALSE +*/ + +// DARKPACK TODO: Auspex using salubri also open the third eye, causing a breach if it isn't hidden. +// If covered, it offers a penalty of -1 to all auspex, obeah or valeren roles. diff --git a/modular_darkpack/modules/vampire_the_masquerade/code/vampire_clan/clans/setite.dm b/modular_darkpack/modules/vampire_the_masquerade/code/vampire_clan/clans/setite.dm index 15c2d1d88cce..d197d5bc9337 100644 --- a/modular_darkpack/modules/vampire_the_masquerade/code/vampire_clan/clans/setite.dm +++ b/modular_darkpack/modules/vampire_the_masquerade/code/vampire_clan/clans/setite.dm @@ -2,7 +2,7 @@ name = "Setite" id = VAMPIRE_CLAN_SETITE desc = "The Followers of Set, also called the Ministry of Set, Ministry, or Setites, are a clan of vampires who believe their founder was the Egyptian god Set." - icon = "followers_of_set" + icon = "setite" curse = "Decreased moving speed in lighted areas." clan_disciplines = list( /datum/discipline/obfuscate, diff --git a/modular_darkpack/modules/vampire_the_masquerade/code/vampire_clan/clans/tzimisce/tzimisce.dm b/modular_darkpack/modules/vampire_the_masquerade/code/vampire_clan/clans/tzimisce/tzimisce.dm index 619e07f0dbc7..6bb13b9e7f28 100644 --- a/modular_darkpack/modules/vampire_the_masquerade/code/vampire_clan/clans/tzimisce/tzimisce.dm +++ b/modular_darkpack/modules/vampire_the_masquerade/code/vampire_clan/clans/tzimisce/tzimisce.dm @@ -2,6 +2,7 @@ name = "Tzimisce" id = VAMPIRE_CLAN_TZIMISCE desc = "If someone were to call a Tzimisce inhuman and sadistic, the Tzimisce would probably commend them for their perspicacity, and then demonstrate that their mortal definition of sadism was laughably inadequate. The Tzimisce have left the human condition behind gladly, and now focus on transcending the limitations of the vampiric state. At a casual glance or a brief conversation, a Tzimisce appears to be one of the more pleasant vampires. Polite, intelligent, and inquisitive, they seem a stark contrast to the howling Sabbat mobs or even the apparently more humane Brujah or Nosferatu. However, upon closer inspection, it becomes clear that this is merely a mask hiding something alien and monstrous." + icon = "tzimisce" curse = "Grounded to material domain." clan_disciplines = list( /datum/discipline/auspex, diff --git a/tgstation.dme b/tgstation.dme index 6049df783d27..dbb7ee670bbd 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -7432,6 +7432,7 @@ #include "modular_darkpack\modules\powers\code\discipline\necromancy.dm" #include "modular_darkpack\modules\powers\code\discipline\serpentis.dm" #include "modular_darkpack\modules\powers\code\discipline\torpor.dm" +#include "modular_darkpack\modules\powers\code\discipline\valeren.dm" #include "modular_darkpack\modules\powers\code\discipline\auspex\aura_component.dm" #include "modular_darkpack\modules\powers\code\discipline\auspex\auspex.dm" #include "modular_darkpack\modules\powers\code\discipline\auspex\emotion_panel.dm" @@ -7451,6 +7452,8 @@ #include "modular_darkpack\modules\powers\code\discipline\dominate\status_effects\mesmerize_status_effect.dm" #include "modular_darkpack\modules\powers\code\discipline\fortitude\fortitude.dm" #include "modular_darkpack\modules\powers\code\discipline\fortitude\fortitude_status_effect.dm" +#include "modular_darkpack\modules\powers\code\discipline\obeah\obeah.dm" +#include "modular_darkpack\modules\powers\code\discipline\obeah\shepherds_watch.dm" #include "modular_darkpack\modules\powers\code\discipline\obfuscate\obfuscate.dm" #include "modular_darkpack\modules\powers\code\discipline\obfuscate\obfuscate_helpers.dm" #include "modular_darkpack\modules\powers\code\discipline\obtenebration\creatures.dm" diff --git a/tgui/packages/tgui/interfaces/Valeren.tsx b/tgui/packages/tgui/interfaces/Valeren.tsx new file mode 100644 index 000000000000..d9dfd71a42e5 --- /dev/null +++ b/tgui/packages/tgui/interfaces/Valeren.tsx @@ -0,0 +1,77 @@ +// THIS IS A DARKPACK UI FILE +import { resolveAsset } from '../assets'; +import { useBackend } from '../backend'; +import { Window } from '../layouts'; + +type Data = { + creature: string; + damage: string; + blood: string; + disease: string; + mental: string; +}; + +const HANDWRITING: React.CSSProperties = { + fontFamily: "'Segoe Script', 'Bradley Hand ITC', cursive", + color: '#000000', + fontSize: '13px', + lineHeight: '1.3', +}; + +export function Valeren() { + const { data } = useBackend(); + const { creature, damage, blood, disease, mental } = data; + + return ( + + +
+ + {creature && ( +
+ {creature} +
+ )} + {damage && ( +
+ {damage} +
+ )} + {blood && ( +
+ {blood} +
+ )} + {disease && ( +
+ {disease} +
+ )} + {mental && ( +
+ {mental} +
+ )} +
+
+
+ ); +}