From 1ed9522a30d871ac84e704be90d3f9d5703ad578 Mon Sep 17 00:00:00 2001 From: dwinters99 <65516417+dwinters99@users.noreply.github.com> Date: Tue, 27 Jan 2026 01:06:56 -0500 Subject: [PATCH 1/7] start --- code/__DEFINES/atom_hud.dm | 1 + .../powers/code/discipline/mytherceria.dm | 474 ++++-------------- 2 files changed, 102 insertions(+), 373 deletions(-) diff --git a/code/__DEFINES/atom_hud.dm b/code/__DEFINES/atom_hud.dm index a935a575d99e..c8381b844e30 100644 --- a/code/__DEFINES/atom_hud.dm +++ b/code/__DEFINES/atom_hud.dm @@ -73,6 +73,7 @@ #define DATA_HUD_MALF_APC 10 #define DATA_HUD_BLOOD 11 #define DATA_HUD_AUSPEX_AURAS 12 // DARKPACK EDIT ADD +#define DATA_HUD_FAE_SIGHT 12 // DARKPACK EDIT ADD /// cooldown for being shown the images for any particular data hud #define ADD_HUD_TO_COOLDOWN 20 diff --git a/modular_darkpack/modules/powers/code/discipline/mytherceria.dm b/modular_darkpack/modules/powers/code/discipline/mytherceria.dm index f1533f97c251..13c0a801dd0e 100644 --- a/modular_darkpack/modules/powers/code/discipline/mytherceria.dm +++ b/modular_darkpack/modules/powers/code/discipline/mytherceria.dm @@ -1,9 +1,8 @@ /datum/discipline/mytherceria name = "Mytherceria" - desc = "Mytherceria is a Discipline that manifests in faerie-blooded vampires such as the Kiasyd and Maeghar. It grants the vampire mystical senses, the ability to steal knowledge, and other powers attributed to fae." - icon_state = "mytherceria" - clan_restricted = TRUE - power_type = /datum/discipline_power/mytherceria + desc = "Command fae-like powers to beguile and ensorcell your foes." + icon_state = "obfuscate" + power_type = /datum/discipline_power/obfuscate /datum/discipline_power/mytherceria name = "Mytherceria power name" @@ -11,17 +10,71 @@ activate_sound = 'modular_darkpack/modules/deprecated/sounds/kiasyd.ogg' -//FEY SIGHT -/datum/discipline_power/mytherceria/fey_sight - name = "Fey Sight" - desc = "Sense magical items on another person." +/** + * • Folderol + * + * The Kiasyd can cleave truth from lies. The exact effect varies from vampire to vampire. + * Some Kiasyd experience bleeding from the eyes or ears when they hear + * a lie, while some Weirdlings’ eyes glow when told a falsehood. Whatever the effect, this power detects lies, + * not mistakes, meaning that a target has to know he is lying in order for this power to work. + * + * The character knows when a target is deliberately lying. No roll or cost associated with this power, but it must be activated + * by the Kiasyd deliberately. Does not in any way give hints to the truth. Has no effect on people who are not lying intentionally. + */ +/datum/discipline_power/mytherceria/folderol + name = "Folderol" + desc = "Detect if a target is deliberately lying." level = 1 + check_flags = DISC_CHECK_CONSCIOUS + target_type = TARGET_LIVING + vitae_cost = 0 + cooldown_length = 1 TURNS + range = 7 + +/datum/discipline_power/auspex/telepathy/activate(mob/living/target) + . = ..() + var/mob/living/L = target + + SEND_SOUND(L, sound(activate_sound, 0, 0, 50)) // LOOK OUT! THERE'S A FAIRY! + + var/response_w = input(L, "Does your character believe your last statement to be the truth?") in list("Yes", "No") + + if(response_w == "Yes") // Telling the truth! + to_chat(user, "[L] is not intentionally lying.") + else if(response_w == "No") // Lying! + to_chat(user, "[L] is LYING!") + else // Dunno + to_chat(user, "[L]'s truthfulness is difficult to determine.") + + log_directed_talk(owner, target, "[owner] used Folderol on [target]. Response: [response_w]", LOG_SAY, "Folderol") + return + +/** + * •• Fae Sight + * + * The Kiasyd’s knowledge of magic isn’t just theoretical. Their strangely-colored eyes are capable of + * detecting the arcane energies of the fae, as well as magic from other, more esoteric sources. + * They are not, however, capable of using this power to detect the residue of ghosts or vampiric magic. + * + * The Kiasyd sees faeries and other faetouched mortals for what they really are, no roll required. + * Additionally, the player can detect ANY magic that is not undead in nature (including ghosts, wraiths, vampires, etc.) + * This is functionally Scent of the True Form but it can detect magical items and spells as well. + * + * TODO: Crinos beast HUD overlay + * + *//* +/datum/discipline_power/mytherceria/fae_sight + name = "Fae Sight" + desc = "Sense magical residue and see magical beings for what they really are." + + level = 1 + vitae_cost = 0 check_flags = DISC_CHECK_CONSCIOUS | DISC_CHECK_CAPABLE target_type = TARGET_MOB range = 7 - - cooldown_length = 10 SECONDS + duration_length = 1 SCENES + cooldown_length = 1 SCENES /datum/discipline_power/mytherceria/fey_sight/activate(mob/living/target) . = ..() @@ -30,373 +83,48 @@ if(istype(item, /obj/item/storage)) total_list |= item.contents total_list |= item - to_chat(owner, span_purple("Your fae senses reach out to detect what they're carrying...")) + to_chat(owner, "Your fae senses reach out to detect what they're carrying...") for(var/obj/item/item in total_list) - if(item.is_magic) - to_chat(owner, "- [span_nicegreen("[item.name]")]") - else if(item.is_iron) - to_chat(owner, "- [span_danger("[item.name]")]") - else - to_chat(owner, "- [item.name]") - -//DARKLING TRICKERY -/datum/discipline_power/mytherceria/darkling_trickery - name = "Darkling Trickery" - desc = "Steal trinkets from your victims from afar." - - level = 2 - check_flags = DISC_CHECK_CONSCIOUS | DISC_CHECK_CAPABLE | DISC_CHECK_IMMOBILE | DISC_CHECK_FREE_HAND | DISC_CHECK_LYING - target_type = TARGET_MOB - range = 3 - - duration_length = 10 SECONDS - cooldown_length = 10 SECONDS - -/datum/discipline_power/mytherceria/darkling_trickery/activate(mob/living/target) + if(item) + if(item.is_magic) + to_chat(owner, "- [item.name]") + else if(item.is_iron) + to_chat(owner, "- [item.name]") + else + to_chat(owner, "- [item.name]") + +/datum/discipline_power/auspex/aura_perception/activate() . = ..() - target.show_inv(owner) + var/datum/atom_hud/data/auspex_aura/target_hud = GLOB.huds[DATA_HUD_FAE_SIGHT] + target_hud.show_to(owner) -/datum/discipline_power/mytherceria/darkling_trickery/deactivate(mob/living/target) +/datum/discipline_power/auspex/aura_perception/deactivate() . = ..() - -//GOBLINISM -/datum/discipline_power/mytherceria/goblinism - name = "Goblinism" - desc = "Summon a mischievous goblin to latch onto your enemies' faces." + var/datum/atom_hud/data/auspex_aura/target_hud = GLOB.huds[DATA_HUD_FAE_SIGHT] + target_hud.hide_from(owner)*/ + #warn MYTHERCERIA 2 COMMENTED OUT +/** + * ••• Aura Absorption + * + * The Kiasyd is capable of seeing images of events and emotions past by touching an object or an area. + * However, unlike the Auspex Power The Spirit’s Touch, this power absorbs the images, making them harder for + * other beings with similar powers to access. Anyone attempting to use this power, Spirit’s Touch, + * or a similar ability to see what the Kiasyd has seen finds that the images are hard to hold, + * slipping through his mind’s eye like minnows through a stream. + * + * Perception + Empathy roll. Functionally spirits touch but erases whatever's discovered. + * + * TODO: If we aver add Natures and/or Demeanors, make them temporarily undetectable unless someone beats the first roll. + * TODO: "The first Kiasyd’s successes subtract from the number of successes scored by anyone trying to read the object thereafter." + */ +/datum/discipline_power/mytherceria/aura_absorption + name = "Aura Absorption" + desc = "Find out something about an object and absorb it's resonance." level = 3 - check_flags = DISC_CHECK_CONSCIOUS | DISC_CHECK_CAPABLE | DISC_CHECK_IMMOBILE | DISC_CHECK_FREE_HAND - target_type = TARGET_MOB - range = 5 - - aggravating = TRUE - hostile = TRUE - violates_masquerade = TRUE - - cooldown_length = 10 SECONDS - -/datum/discipline_power/mytherceria/goblinism/activate(mob/living/target) - . = ..() - var/obj/item/clothing/mask/facehugger/kiasyd/goblin = new (get_turf(owner)) - goblin.throw_at(target, 10, 14, owner) - -/datum/discipline_power/mytherceria/goblinism/post_gain() - . = ..() - var/datum/action/mytherceria/changeling_rune = new() - changeling_rune.Grant(owner) - -/obj/item/clothing/mask/facehugger/kiasyd - name = "goblin" - desc = "A green changeling creature." - worn_icon = 'modular_darkpack/modules/clothes/icons/worn.dmi' - icon = 'modular_darkpack/modules/deprecated/icons/icons.dmi' - icon_state = "goblin" - sterile = TRUE - -/obj/item/clothing/mask/facehugger/kiasyd/attack_hand(mob/user) - if(iscarbon(user)) - var/mob/living/carbon/C = user - C.adjust_brute_loss(5) - to_chat(user, span_warning("[src] bites!")) - return - . = ..() - -/obj/item/clothing/mask/facehugger/kiasyd/Die() - qdel(src) - -/obj/item/clothing/mask/facehugger/kiasyd/Leap(mob/living/M) - if(iscarbon(M)) - var/mob/living/carbon/target = M - if(target.wear_mask && istype(target.wear_mask, /obj/item/clothing/mask/facehugger/kiasyd)) - return FALSE - M.visible_message(span_danger("[src] leaps at [M]'s face!"), \ - span_userdanger("[src] leaps at your face!")) - if(iscarbon(M)) - var/mob/living/carbon/target = M - - if(target.head) - var/obj/item/clothing/W = target.head - target.dropItemToGround(W, TRUE) - - if(target.wear_mask) - var/obj/item/clothing/W = target.wear_mask - if(target.dropItemToGround(W, TRUE)) - target.visible_message( - span_danger("[src] tears [W] off of [target]'s face!"), \ - span_userdanger("[src] tears [W] off of your face!")) - target.equip_to_slot_if_possible(src, ITEM_SLOT_MASK, 0, 1, 1) - var/datum/cb = CALLBACK(src,/obj/item/clothing/mask/facehugger/kiasyd/proc/eat_head) - for(var/i in 1 to 10) - addtimer(cb, (i - 1) * 1.5 SECONDS) - spawn(16 SECONDS) - qdel(src) - return TRUE - -/obj/item/clothing/mask/facehugger/kiasyd/proc/eat_head() - if(iscarbon(loc)) - var/mob/living/carbon/C = loc - to_chat(C, span_warning("[src] is eating your face!")) - C.apply_damage(5, BRUTE) - -/datum/action/mytherceria - name = "Mytherceria Traps" - desc = "Create a trap." - button_icon_state = "mytherceria" - check_flags = AB_CHECK_HANDS_BLOCKED|AB_CHECK_IMMOBILE|AB_CHECK_LYING|AB_CHECK_CONSCIOUS - vampiric = TRUE - -/datum/action/mytherceria/Trigger() - . = ..() - var/mob/living/carbon/human/H = owner - var/try_trap = input(H, "Select a Trap:", "Trap") as null|anything in list("Brutal", "Spin", "Drop") - if(try_trap) - if(H.bloodpool < 1) - to_chat(owner, span_warning("You don't have enough BLOOD to do that!")) - return - H.adjust_blood_pool(-1) - switch(try_trap) - if("Brutal") - var/obj/mytherceria_trap/trap = new (get_turf(owner)) - trap.owner = owner - if("Spin") - var/obj/mytherceria_trap/disorient/trap = new (get_turf(owner)) - trap.owner = owner - if("Drop") - var/obj/mytherceria_trap/drop/trap = new (get_turf(owner)) - trap.owner = owner - to_chat(owner, span_notice("You've created a trap!")) - -/obj/mytherceria_trap - name = "mytherceria trap" - desc = "Creates the Changeling Trap to protect kiasyd or his domain." - anchored = TRUE - density = FALSE - alpha = 64 - icon = 'modular_darkpack/modules/deprecated/icons/icons.dmi' - icon_state = "rune1" - color = "#4182ad" - var/unique = FALSE - var/mob/owner - -/obj/mytherceria_trap/Crossed(atom/movable/AM) - . = ..() - if(isliving(AM) && owner) - if(AM != owner) - playsound(get_turf(src), 'modular_darkpack/modules/deprecated/sounds/kiasyd.ogg', 100, FALSE) - if(!unique) - var/mob/living/L = AM - var/atom/throw_target = get_edge_target_turf(AM, get_dir(src, AM)) - L.apply_damage(30, BRUTE) - AM.throw_at(throw_target, rand(8,10), 14, owner) - qdel(src) - -/obj/mytherceria_trap/disorient - name = "mytherceria trap" - desc = "Creates the Changeling Trap to protect kiasyd or his domain." - anchored = TRUE - density = FALSE - unique = TRUE - icon_state = "rune2" - -/obj/mytherceria_trap/disorient/Crossed(atom/movable/AM) - . = ..() - if(isliving(AM) && owner) - if(AM != owner) - var/mob/living/L = AM - var/list/screens = list(L.hud_used.plane_masters["[FLOOR_PLANE]"], L.hud_used.plane_masters["[GAME_PLANE]"], L.hud_used.plane_masters["[LIGHTING_PLANE]"]) - var/rotation = 50 - for(var/whole_screen in screens) - animate(whole_screen, transform = matrix(rotation, MATRIX_ROTATE), time = 0.5 SECONDS, easing = QUAD_EASING, loop = -1) - animate(transform = matrix(-rotation, MATRIX_ROTATE), time = 0.5 SECONDS, easing = QUAD_EASING) - spawn(15 SECONDS) - for(var/whole_screen in screens) - animate(whole_screen, transform = matrix(), time = 0.5 SECONDS, easing = QUAD_EASING) - qdel(src) - -/obj/mytherceria_trap/drop - name = "mytherceria trap" - desc = "Creates the Changeling Trap to protect kiasyd or his domain." - anchored = TRUE - density = FALSE - unique = TRUE - icon_state = "rune3" - -/obj/mytherceria_trap/drop/Crossed(atom/movable/AM) - . = ..() - if(iscarbon(AM) && owner) - if(AM != owner) - var/mob/living/carbon/L = AM - for(var/obj/item/I in L.get_equipped_items(include_pockets = TRUE)) - L.dropItemToGround(I, TRUE) - qdel(src) - -//CHANJELIN WARD -/datum/discipline_power/mytherceria/chanjelin_ward - name = "Chanjelin Ward" - desc = "Create a symbol that disorientates your victim." - - level = 4 - check_flags = DISC_CHECK_CONSCIOUS | DISC_CHECK_CAPABLE | DISC_CHECK_IMMOBILE - target_type = TARGET_MOB - range = 5 - - aggravating = TRUE - hostile = TRUE - - duration_length = 5 SECONDS - cooldown_length = 10 SECONDS - -/datum/discipline_power/mytherceria/chanjelin_ward/activate(mob/living/target) - . = ..() - var/list/screens = list(target.hud_used.plane_masters["[FLOOR_PLANE]"], target.hud_used.plane_masters["[GAME_PLANE]"], target.hud_used.plane_masters["[LIGHTING_PLANE]"]) - var/rotation = 50 - for(var/whole_screen in screens) - animate(whole_screen, transform = matrix(rotation, MATRIX_ROTATE), time = 0.5 SECONDS, easing = QUAD_EASING, loop = -1) - animate(transform = matrix(-rotation, MATRIX_ROTATE), time = 0.5 SECONDS, easing = QUAD_EASING) - -/datum/discipline_power/mytherceria/chanjelin_ward/deactivate(mob/living/target) - . = ..() - var/list/screens = list(target.hud_used.plane_masters["[FLOOR_PLANE]"], target.hud_used.plane_masters["[GAME_PLANE]"], target.hud_used.plane_masters["[LIGHTING_PLANE]"]) - for(var/whole_screen in screens) - animate(whole_screen, transform = matrix(), time = 0.5 SECONDS, easing = QUAD_EASING) - -/datum/discipline_power/mytherceria/chanjelin_ward/can_activate(mob/living/target, alert) - . = ..() - if (!.) - return . - - if (!target.client) - to_chat(owner, span_warning("You cannot cast [src] on mindless entities!")) - return FALSE - - return . - -//RIDDLE PHANTASTIQUE -/datum/discipline_power/mytherceria/riddle_phantastique - name = "Riddle Phantastique" - desc = "Pose a confounding riddle to your victim, forcing them to answer it before they can do anything else." - - level = 5 - check_flags = DISC_CHECK_CONSCIOUS | DISC_CHECK_CAPABLE | DISC_CHECK_IMMOBILE | DISC_CHECK_SPEAK - target_type = TARGET_LIVING - range = 7 - - cooldown_length = 0 - - var/list/datum/riddle/stored_riddles = list() - -/datum/discipline_power/mytherceria/riddle_phantastique/activate(mob/living/target) - . = ..() - if(length(stored_riddles)) - var/list/riddle_list = list("Create a new riddle...") - for(var/datum/riddle/riddle in stored_riddles) - riddle_list += riddle.riddle_text - var/try_riddle = input(owner, "Select a Riddle:", "Riddle") as null|anything in riddle_list - if(try_riddle) - if(try_riddle == "Create a new riddle...") - var/datum/riddle/riddle = new () - if(riddle.create_riddle(owner)) - stored_riddles += riddle - riddle.ask(target) - owner.say(riddle.riddle_text) - return - var/datum/riddle/actual_riddle - for(var/datum/riddle/RIDDLE in stored_riddles) - if(RIDDLE.riddle_text == try_riddle) - actual_riddle = RIDDLE - target.add_movespeed_modifier(/datum/movespeed_modifier/riddle) - actual_riddle.ask(target) - owner.say(actual_riddle.riddle_text) - else - var/datum/riddle/riddle = new () - if(riddle.create_riddle(owner)) - stored_riddles += riddle - riddle.ask(target) - owner.say(riddle.riddle_text) - else - qdel(riddle) - -/datum/movespeed_modifier/riddle - multiplicative_slowdown = 5 - -/datum/riddle - var/riddle_text - var/list/riddle_options = list() - var/riddle_answer - -/atom/movable/screen/alert/riddle - name = "Riddle" - desc = "You have a riddle to solve!" - icon_state = "riddle" - - var/datum/riddle/riddle - var/bad_answers = 0 - -/atom/movable/screen/alert/riddle/Click() - if(iscarbon(usr) && (usr == owner)) - var/mob/living/carbon/M = usr - if(riddle) - riddle.try_answer(M, src) - -/datum/riddle/proc/try_answer(mob/living/answerer, atom/movable/screen/alert/riddle/new_alert) - var/try_answer = input(answerer, riddle_text, "Riddle") as null|anything in riddle_options - if(try_answer) - answer_riddle(answerer, try_answer, new_alert) - -/datum/riddle/proc/ask(mob/living/asking) - var/atom/movable/screen/alert/riddle/alert = asking.throw_alert("riddle", /atom/movable/screen/alert/riddle) - alert.riddle = src - -/datum/riddle/proc/create_riddle(mob/living/carbon/human/riddler) - var/proceed = FALSE - var/text_riddle = input(riddler, "Create a riddle:", "Riddle", "Is it something?") as null|text - if(text_riddle) - riddle_text = trim(copytext_char(sanitize(text_riddle), 1, MAX_MESSAGE_LEN)) - var/right_answer = input(riddler, "Create a right answer:", "Riddle", "Something") as null|text - if(right_answer) - riddle_answer = trim(copytext_char(sanitize(right_answer), 1, MAX_MESSAGE_LEN)) - riddle_options += trim(copytext_char(sanitize(right_answer), 1, MAX_MESSAGE_LEN)) - proceed = TRUE - var/answer1 = input(riddler, "Create another answer:", "Riddle", "Anything") as null|text - if(answer1) - riddle_options += trim(copytext_char(sanitize(answer1), 1, MAX_MESSAGE_LEN)) - var/answer2 = input(riddler, "Create another answer:", "Riddle", "Anything") as null|text - if(answer2) - riddle_options += trim(copytext_char(sanitize(answer2), 1, MAX_MESSAGE_LEN)) - var/answer3 = input(riddler, "Create another answer:", "Riddle", "Anything") as null|text - if(answer3) - riddle_options += trim(copytext_char(sanitize(answer3), 1, MAX_MESSAGE_LEN)) - var/answer4 = input(riddler, "Create another answer:", "Riddle", "Anything") as null|text - if(answer4) - riddle_options += trim(copytext_char(sanitize(answer4), 1, MAX_MESSAGE_LEN)) - if(proceed) - to_chat(riddler, "New riddle created.") - return src - else - to_chat(riddler, span_danger("Your riddle is too complicated.")) - return FALSE + check_flags = DISC_CHECK_CONSCIOUS + vitae_cost = 0 + cooldown_length = 1 TURNS -/datum/riddle/proc/answer_riddle(mob/living/answerer, the_answer, atom/movable/screen/alert/riddle/alert) - if(the_answer != riddle_answer) - alert.bad_answers++ - to_chat(answerer, - span_danger("WRONG ANSWER.")) - if(alert.bad_answers >= round(length(riddle_options)/2)) - if(iscarbon(answerer)) - var/mob/living/carbon/C = answerer - var/obj/item/organ/tongue/tongue = locate(/obj/item/organ/tongue) in C.internal_organs - if(tongue) - tongue.Remove(C) - to_chat(answerer, - span_danger("THE RIDDLE REMOVES YOUR LYING TONGUE AS IT FLEES.")) - answerer.remove_movespeed_modifier(/datum/movespeed_modifier/riddle) - alert.bad_answers = 0 - alert.riddle = null - answerer.clear_alert("riddle") - else - to_chat(answerer, - span_nicegreen("You feel the riddle's hold over you vanish.")) - alert.riddle = null - answerer.remove_movespeed_modifier(/datum/movespeed_modifier/riddle) - answerer.say(the_answer) - answerer.clear_alert("riddle") + toggled = TRUE +#warn MYTHERCERIA 3 UNIMPLEMENTED From 455adb14f3fb9d00df840404ffd2c83cad2e3600 Mon Sep 17 00:00:00 2001 From: dwinters99 <65516417+dwinters99@users.noreply.github.com> Date: Tue, 27 Jan 2026 03:14:00 -0500 Subject: [PATCH 2/7] nice. --- code/__DEFINES/atom_hud.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/__DEFINES/atom_hud.dm b/code/__DEFINES/atom_hud.dm index c8381b844e30..5893571ac6d1 100644 --- a/code/__DEFINES/atom_hud.dm +++ b/code/__DEFINES/atom_hud.dm @@ -73,7 +73,7 @@ #define DATA_HUD_MALF_APC 10 #define DATA_HUD_BLOOD 11 #define DATA_HUD_AUSPEX_AURAS 12 // DARKPACK EDIT ADD -#define DATA_HUD_FAE_SIGHT 12 // DARKPACK EDIT ADD +#define DATA_HUD_FAE_SIGHT 13 // DARKPACK EDIT ADD /// cooldown for being shown the images for any particular data hud #define ADD_HUD_TO_COOLDOWN 20 From 253a47bffbdae24803097b1624737562c2f5d9fb Mon Sep 17 00:00:00 2001 From: dwinters99 <65516417+dwinters99@users.noreply.github.com> Date: Fri, 30 Jan 2026 04:24:33 -0500 Subject: [PATCH 3/7] i don't like how snowflake this is --- .../master_files/code/game/atom/_atom.dm | 5 + .../powers/code/discipline/auspex/auspex.dm | 12 ++ .../powers/code/discipline/mytherceria.dm | 114 +++++++++++++++++- tgstation.dme | 1 + 4 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 modular_darkpack/master_files/code/game/atom/_atom.dm diff --git a/modular_darkpack/master_files/code/game/atom/_atom.dm b/modular_darkpack/master_files/code/game/atom/_atom.dm new file mode 100644 index 000000000000..1035d904843d --- /dev/null +++ b/modular_darkpack/master_files/code/game/atom/_atom.dm @@ -0,0 +1,5 @@ +/atom + // DARKPACK Module - discipline - Used by Mytherceria 3 to determine who scanned us. + var/mob/aura_scanner + // What our scanner rolled, and what we must beat. DARKPACK TODO: Make Auspex 3 tabletop accurate so this isn't a binary + var/aura_difficulty = 0 diff --git a/modular_darkpack/modules/powers/code/discipline/auspex/auspex.dm b/modular_darkpack/modules/powers/code/discipline/auspex/auspex.dm index fe37e1b9d5f5..f9abb3f4b234 100644 --- a/modular_darkpack/modules/powers/code/discipline/auspex/auspex.dm +++ b/modular_darkpack/modules/powers/code/discipline/auspex/auspex.dm @@ -148,6 +148,18 @@ UnregisterSignal(owner, COMSIG_MOB_EXAMINING) /datum/discipline_power/auspex/the_spirits_touch/proc/scan(mob/user, atom/scanned_atom, list/examine_strings) + if(scanned_atom.aura_scanner != user && !isnull(scanned_atom.aura_scanner)) + var/our_power = SSroll.storyteller_roll(owner.st_get_stat(STAT_EMPATHY) + owner.st_get_stat(STAT_PERCEPTION), 6, user, scanned_atom, numerical = TRUE) + to_chat(user, span_warning("The energy coming from this object is faint... you begin trying to focus on it.")) + if(!do_after(user, max((2 TURNS - our_power SECONDS), 1 SECONDS), scanned_atom, max_interact_count = 1)) + to_chat(user, span_warning("You find it hard to focus on [scanned_atom].")) + return + if(scanned_atom.aura_difficulty > our_power) + to_chat(user, span_warning("You find it hard to focus on [scanned_atom]... like the thoughts are slipping through your mind.")) + return + else + to_chat(user, span_nicegreen("[scanned_atom]'s secrets are revealed to you.")) + // Can scan items we hold and store if(!(scanned_atom in user.get_all_contents())) // Can remotely scan objects and mobs. diff --git a/modular_darkpack/modules/powers/code/discipline/mytherceria.dm b/modular_darkpack/modules/powers/code/discipline/mytherceria.dm index 13c0a801dd0e..223588d364f3 100644 --- a/modular_darkpack/modules/powers/code/discipline/mytherceria.dm +++ b/modular_darkpack/modules/powers/code/discipline/mytherceria.dm @@ -116,6 +116,8 @@ * * TODO: If we aver add Natures and/or Demeanors, make them temporarily undetectable unless someone beats the first roll. * TODO: "The first Kiasyd’s successes subtract from the number of successes scored by anyone trying to read the object thereafter." + * + * TODO: Came back to this a few days later (1/30/26) to find that our implementation of Spirit's Touch isn't robust enough to make this TTRPG accurate. Fix that. */ /datum/discipline_power/mytherceria/aura_absorption name = "Aura Absorption" @@ -127,4 +129,114 @@ cooldown_length = 1 TURNS toggled = TRUE -#warn MYTHERCERIA 3 UNIMPLEMENTED + +/datum/discipline_power/auspex/the_spirits_touch/activate() + . = ..() + + var/datum/atom_hud/health_hud = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED] + health_hud.show_to(owner) + owner.update_sight() + + RegisterSignal(owner, COMSIG_MOB_EXAMINING, PROC_REF(scan)) + +/datum/discipline_power/auspex/the_spirits_touch/deactivate() + . = ..() + + var/datum/atom_hud/health_hud = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED] + health_hud.hide_from(owner) + owner.update_sight() + + UnregisterSignal(owner, COMSIG_MOB_EXAMINING) + +/datum/discipline_power/mytherceria/aura_absorption/proc/scan(mob/user, atom/scanned_atom, list/examine_strings) // Copypasta + var/our_power = SSroll.storyteller_roll(owner.st_get_stat(STAT_EMPATHY) + owner.st_get_stat(STAT_PERCEPTION), 6, user, scanned_atom, numerical = TRUE) + if(isnull(scanned_atom.aura_scanner)) + scanned_atom.aura_scanner = user + scanned_atom.aura_difficulty = our_power + else if(!scanned_atom.aura_scanner == user) + to_chat(user, span_warning("The energy coming from this object is faint... you begin trying to focus on it.")) + if(!do_after(user, max((1 TURNS - our_power SECONDS), 1 SECONDS), scanned_atom, max_interact_count = 1)) + to_chat(user, span_warning("You find it hard to focus on [scanned_atom].")) + return + if(scanned_atom.aura_difficulty > our_power) + to_chat(user, span_warning("You find it hard to focus on [scanned_atom]... like the thoughts are slipping through your mind.")) + return + else + to_chat(user, span_nicegreen("[scanned_atom]'s secrets are revealed to you.")) + scanned_atom.aura_scanner = user + scanned_atom.aura_difficulty = our_power + + // Can scan items we hold and store + if(!(scanned_atom in user.get_all_contents())) + // Can remotely scan objects and mobs. + if((get_dist(scanned_atom, user) > 8) || (!(scanned_atom in view(8, user)))) + return TRUE + playsound(owner, SFX_INDUSTRIAL_SCAN, 20, TRUE, -2, TRUE, FALSE) + + // GATHER INFORMATION + + var/datum/detective_scanner_log/log_entry = new + + // Start gathering + + log_entry.scan_target = scanned_atom.name + + var/list/atom_fibers = GET_ATOM_FIBRES(scanned_atom) + if(length(atom_fibers)) + log_entry.add_data_entry(DETSCAN_CATEGORY_FIBER, atom_fibers.Copy()) + + var/list/blood = GET_ATOM_BLOOD_DNA(scanned_atom) + if(length(blood)) + log_entry.add_data_entry(DETSCAN_CATEGORY_BLOOD, blood.Copy()) + + if(ishuman(scanned_atom)) + var/mob/living/carbon/human/scanned_human = scanned_atom + if(!scanned_human.gloves) + log_entry.add_data_entry( + DETSCAN_CATEGORY_FINGERS, + rustg_hash_string(RUSTG_HASH_MD5, scanned_human.dna?.unique_identity) + ) + + else if(!ismob(scanned_atom)) + + var/list/atom_fingerprints = GET_ATOM_FINGERPRINTS(scanned_atom) + if(length(atom_fingerprints)) + log_entry.add_data_entry(DETSCAN_CATEGORY_FINGERS, atom_fingerprints.Copy()) + + // Only get reagents from non-mobs. + for(var/datum/reagent/present_reagent as anything in scanned_atom.reagents?.reagent_list) + log_entry.add_data_entry(DETSCAN_CATEGORY_REAGENTS, list(present_reagent.name = present_reagent.volume)) + + // Get blood data from the blood reagent. + if(!istype(present_reagent, /datum/reagent/blood)) + continue + + var/blood_DNA = present_reagent.data["blood_DNA"] + var/blood_type = present_reagent.data["blood_type"] + if(!blood_DNA || !blood_type) + continue + + log_entry.add_data_entry(DETSCAN_CATEGORY_BLOOD, list(blood_DNA = blood_type)) + + if(istype(scanned_atom, /obj/item/card/id)) + var/obj/item/card/id/user_id = scanned_atom + for(var/region in DETSCAN_ACCESS_ORDER()) + var/access_in_region = SSid_access.accesses_by_region[region] & user_id.GetAccess() + if(!length(access_in_region)) + continue + var/list/access_names = list() + for(var/access_num in access_in_region) + access_names += SSid_access.get_access_desc(access_num) + + log_entry.add_data_entry(DETSCAN_CATEGORY_ACCESS, list("[region]" = english_list(access_names))) + + // sends it off to be modified by the items + SEND_SIGNAL(scanned_atom, COMSIG_DETECTIVE_SCANNED, user, log_entry) + + // Perform sorting now, because probably this will be never modified + log_entry.sort_data_entries() + var/list/generated_report_text = log_entry.generate_report_text() + var/output_report = generated_report_text.Join() + + examine_strings += boxed_message(output_report) + return TRUE diff --git a/tgstation.dme b/tgstation.dme index 10f3e94f3947..0d363a4d9e2e 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -6911,6 +6911,7 @@ #include "modular_darkpack\master_files\code\datums\mind\_mind.dm" #include "modular_darkpack\master_files\code\datums\station_traits\_station_trait.dm" #include "modular_darkpack\master_files\code\game\area\areas.dm" +#include "modular_darkpack\master_files\code\game\atom\_atom.dm" #include "modular_darkpack\master_files\code\game\objects\items.dm" #include "modular_darkpack\master_files\code\game\objects\items\trash.dm" #include "modular_darkpack\master_files\code\game\objects\items\weaponry.dm" From 02150da44e28e424ce35ea831b09aac206b422a6 Mon Sep 17 00:00:00 2001 From: dwinters99 <65516417+dwinters99@users.noreply.github.com> Date: Fri, 30 Jan 2026 19:48:37 -0500 Subject: [PATCH 4/7] moe it to a folder --- .../powers/code/discipline/{ => mytherceria}/mytherceria.dm | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename modular_darkpack/modules/powers/code/discipline/{ => mytherceria}/mytherceria.dm (100%) diff --git a/modular_darkpack/modules/powers/code/discipline/mytherceria.dm b/modular_darkpack/modules/powers/code/discipline/mytherceria/mytherceria.dm similarity index 100% rename from modular_darkpack/modules/powers/code/discipline/mytherceria.dm rename to modular_darkpack/modules/powers/code/discipline/mytherceria/mytherceria.dm From 693a749973601ee7f0426a6892110b1335252926 Mon Sep 17 00:00:00 2001 From: dwinters99 <65516417+dwinters99@users.noreply.github.com> Date: Fri, 30 Jan 2026 19:51:42 -0500 Subject: [PATCH 5/7] aura stuff v0.1 --- code/__DEFINES/~darkpack/auras.dm | 62 +++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/code/__DEFINES/~darkpack/auras.dm b/code/__DEFINES/~darkpack/auras.dm index 514c44e06e60..4cabf96b5535 100644 --- a/code/__DEFINES/~darkpack/auras.dm +++ b/code/__DEFINES/~darkpack/auras.dm @@ -66,3 +66,65 @@ GLOBAL_LIST_INIT(aura_list, sort_list(list( "Confused" = AURA_CONFUSED, "Daydreaming" = AURA_DAYDREAMING, "Psychotic" = AURA_PSYCHOTIC))) + +// MYTHERCERIA AURAS START HERE // DARKPACK TODO: replace everything commented "placeholder" with real icons. Some will be base_icon_states (i.e. crinos, mage, fae) +#define FAESIGHT_GENERIC "generic" // everything not below +// Splat detectors +// +#define FAESIGHT_GAROU "brown" // Werewolves // Replace this and other fera with grabbing the mob's breed form (or crinos if in breed form) sprite +#define FAESIGHT_CORAX "black" // Corax // Placeholder - modular_darkpack/modules/npc/icons/corvid.dmi +#define FAESIGHT_KITSUNE "fox" // Kitsune // Placeholder - icons/mob/simple/pets.dmi +#define FAESIGHT_BASTET "cat" // Bastet // Placeholder - icons/mob/simple/pets.dmi +#define FAESIGHT_NUWISHA "bullterrier" // Coyotes // Placeholder - icons/mob/simple/pets.dmi +#define FAESIGHT_GURAHL "bear" // Bears // Placeholder - modular_darkpack/modules/npc/icons/bear.dmi +#define FAESIGHT_MOKOLE "raptor" // Lizards of ALMOST all kinds // Placeholder - icons/mob/simple/lavaland/raptor_big.dmi +#define FAESIGHT_ROKEA "blahaj" // Sharks // Placeholder - icons/obj/toys/plushes.dmi +#define FAESIGHT_ANANASI "tank" // Spoder // Placeholder - icons/mob/simple/arachnoid.dmi +#define FAESIGHT_CAMAZOTZ "bat" // Bats // Placeholder - icons/mob/simple/animal.dmi +#define FAESIGHT_LEPIX "rabbit_white" // Rabbits. Joke fera. // Placeholder - icons/mob/simple/rabbit.dmi +#define FAESIGHT_NAGAH "snake" // Super secret snakes // Placeholder - icons/mob/simple/animal.dmi +#define FAESIGHT_AJABA "pug" // Hyenas // Placeholder - icons/mob/simple/pets.dmi +#define FAESIGHT_RATKIN "regalrat" // Terrorism rats // Placeholder - icons/mob/simple/animal.dmi +#define FAESIGHT_APIS "cow" // Hyper-extinct cows. Useful for spirits maybe. // Placeholder - icons/mob/simple/cows.dmi +#define FAESIGHT_GRONDR "pig" // Hyper-extinct pigs // Placeholder - icons/mob/simple/animal.dmi +#define FAESIGHT_ANURANA "frog" // Mockery frogs // Placeholder - icons/mob/simple/animal.dmi +#define FAESIGHT_KERASI "unicorn" // Mockery rhinos // Placeholder - icons/obj/toys/plushes.dmi +#define FAESIGHT_SAMSA "cockroach" // Mockery roaches <3 <3 <3 // Placeholder - icons/mob/simple/animal.dmi +#define FAESIGHT_WARWOLVES "beast_crinos" // Mockery Garou, like the crinos_beast basic mob - modular_darkpack/modules/npc/icons/werewolf.dmi +#define FAESIGHT_YEREN "monkey" // Mockery apes // Placeholder - icons/mob/human/human.dmi +// + +#define FAESIGHT_MAGE "nim" // mages and some sorcerers - if we ever get mages, replace this with their chosen Avatar // Placeholder - icons/mob/simple/mob.dmi +#define FAESIGHT_FAE "god" // all things fairy (not inculding ourselves) // Placeholder - icons/mob/simple/mob.dmi +#define FAESIGHT_DEMON "slaughter_demon" // DEMON!!! // Placeholder - icons/mob/simple/demon.dmi +#define FAESIGHT_TRUEFAITH "god" // may not need to exist. but whatever. // Placeholder - icons/mob/simple/mob.dmi +#define FAESIGHT_UMBRA "ghost1" // spirits, banes, etc. Replace with actual spirit sprites one day // Placeholder - icons/mob/simple/mob.dmi + +GLOBAL_LIST_INIT(fae_sight_auras, sort_list(list( +"Lupine" = FAESIGHT_GAROU, +"Avian" = FAESIGHT_CORAX, +"Vulpine" = FAESIGHT_KITSUNE, +"Feline" = FAESIGHT_BASTET, +"Latran" = FAESIGHT_NUWISHA, +"Ursine" = FAESIGHT_GURAHL, +"Reptilian" = FAESIGHT_MOKOLE, +"Selachian" = FAESIGHT_ROKEA, +"Arachnid" = FAESIGHT_ANANASI, +"Chiropteran" = FAESIGHT_CAMAZOTZ, +"Lagomorph" = FAESIGHT_LEPIX, +"Serpent" = FAESIGHT_NAGAH, +"Hyena" = FAESIGHT_AJABA, +"Rodent" = FAESIGHT_RATKIN, +"Bovine" = FAESIGHT_APIS, +"Porcine" = FAESIGHT_GRONDR, +"Ranine" = FAESIGHT_ANURANA, +"Rhino" = FAESIGHT_KERASI, +"Roach" = FAESIGHT_SAMSA, +"Feral Lupine" = FAESIGHT_WARWOLVES, +"Monkey" = FAESIGHT_YEREN, +"Mage" = FAESIGHT_MAGE, +"Fae" = FAESIGHT_FAE, +"Believer" = FAESIGHT_TRUEFAITH, +"Spiritual" = FAESIGHT_UMBRA, +"Magic" = FAESIGHT_GENERIC, +))) From 3865ceb7ced365fe071c84588ec98bc57c92f435 Mon Sep 17 00:00:00 2001 From: dwinters99 <65516417+dwinters99@users.noreply.github.com> Date: Fri, 30 Jan 2026 23:41:17 -0500 Subject: [PATCH 6/7] takinga break bc owie --- .../mytherceria/chanjelin_ward_element.dm | 23 +++++++++++ .../discipline/mytherceria/mytherceria.dm | 41 +++++++++++++++++-- tgstation.dme | 1 + 3 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 modular_darkpack/modules/powers/code/discipline/mytherceria/chanjelin_ward_element.dm diff --git a/modular_darkpack/modules/powers/code/discipline/mytherceria/chanjelin_ward_element.dm b/modular_darkpack/modules/powers/code/discipline/mytherceria/chanjelin_ward_element.dm new file mode 100644 index 000000000000..f3f3b39680f3 --- /dev/null +++ b/modular_darkpack/modules/powers/code/discipline/mytherceria/chanjelin_ward_element.dm @@ -0,0 +1,23 @@ +/datum/element/chanjelin_ward + element_flags = ELEMENT_BESPOKE + argument_hash_start_idx = 1 + // The guy who placed the ward + var/mob/warder + +/datum/element/chanjelin_ward/Attach(mob/placed_by, datum/target) + . = ..() + if(!isatom(target)) + return ELEMENT_INCOMPATIBLE + + RegisterSignal(target, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) + + + if(isturf(target)) + RegisterSignal(target, COMSIG_ATOM_ENTERED, PROC_REF(on_entered)) + +/datum/element/chanjelin_ward/Detach(datum/target) + UnregisterSignal(target, list(COMSIG_ATOM_EXAMINE)) + if(isturf(target)) + UnregisterSignal(target, list(COMSIG_ATOM_ENTERED)) + + return ..() diff --git a/modular_darkpack/modules/powers/code/discipline/mytherceria/mytherceria.dm b/modular_darkpack/modules/powers/code/discipline/mytherceria/mytherceria.dm index 223588d364f3..08b428680053 100644 --- a/modular_darkpack/modules/powers/code/discipline/mytherceria/mytherceria.dm +++ b/modular_darkpack/modules/powers/code/discipline/mytherceria/mytherceria.dm @@ -27,12 +27,12 @@ level = 1 check_flags = DISC_CHECK_CONSCIOUS - target_type = TARGET_LIVING + target_type = TARGET_PLAYER vitae_cost = 0 cooldown_length = 1 TURNS range = 7 -/datum/discipline_power/auspex/telepathy/activate(mob/living/target) +/datum/discipline_power/mytherceria/folderol/activate(mob/living/target) . = ..() var/mob/living/L = target @@ -61,7 +61,7 @@ * Additionally, the player can detect ANY magic that is not undead in nature (including ghosts, wraiths, vampires, etc.) * This is functionally Scent of the True Form but it can detect magical items and spells as well. * - * TODO: Crinos beast HUD overlay + * TODO: HUD overlays - code/__DEFINES/~darkpack/auras.dm * *//* /datum/discipline_power/mytherceria/fae_sight @@ -240,3 +240,38 @@ examine_strings += boxed_message(output_report) return TRUE + +/** + * •••• Chanjelin Ward + * + * The vampire inscribes a ward on an object, a location, or a person. That ward disorients and befuddles anyone that sees it, + * meaning that even if an intruder can penetrate a Weirdling’s security and steal an object of value, he’s unlikely to be able to find his way to the exit. + * Spiteful Kiasyd use these wards as punishment — one story tells of a Weirdling that drew a ward on an enemy’s shirt as dawn approached, + * and then watched (from safety) as the unfortunate vampire burned in the sun, unable to remember which way to run. + * + * When activated, select a target that you can physically touch including an object, a mob, or a turf. The Ward takes 10 seconds if the users + * Dexterity + Occult is equal to or greater than 5, and takes a mere 5 seconds when the user's Dexterity + Occult is equal to or greater than 8. + * When placed on an object, anyone coming into contact with that object (such as picking it up or otherwise touching it) suffer a severe movement speed penalty + * and a short period of randomized controls. When placed on a mob, they also suffer from this penalty. When placed on a turf, it functions as a tripmine. + */ +/datum/discipline_power/mytherceria/chanjelin_ward + name = "Chanjelin Ward" + desc = "Place a ward that confuses and befuddles your foes." + + level = 4 + check_flags = DISC_CHECK_CAPABLE | DISC_CHECK_DIRECT_SEE + target_type = TARGET_MOB | TARGET_OBJ | TARGET_TURF | TARGET_SELF + vitae_cost = 0 + cooldown_length = 4 TURNS + +/datum/discipline_power/mytherceria/chanjelin_ward/pre_activation_checks(atom/target) + . = ..() + var/activate_time = max(3 TURNS - (owner.st_get_stat(STAT_DEXTERITY) + owner.st_get_stat(STAT_OCCULT)), 1 SECONDS) + to_chat(owner, span_notice("You begin inscribing a ward on [target].")) + if(!do_after(owner, activation_time, target, interaction_key = "chanjelin_ward", max_interact_count = 1)) + to_chat(owner, span_warning("You decide not to finish the ward and erase your progress.")) + return FALSE + +/datum/discipline_power/mytherceria/chanjelin_ward/activate(atom/target) + . = ..() + AddElement(/datum/element/chanjelin_ward, user, target) diff --git a/tgstation.dme b/tgstation.dme index 0d363a4d9e2e..e9e159ea4a69 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -7381,6 +7381,7 @@ #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\mytherceria\chanjelin_ward_element.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\potence\potence.dm" From f4f41d90ce203d3b2cfa958786e63865b61a9211 Mon Sep 17 00:00:00 2001 From: dwinters99 <65516417+dwinters99@users.noreply.github.com> Date: Thu, 19 Feb 2026 01:10:59 -0500 Subject: [PATCH 7/7] riddles initial --- .../discipline/mytherceria/mytherceria.dm | 46 ++++++++++++++++--- .../code/discipline/mytherceria/riddle.dm | 28 +++++++++++ tgstation.dme | 2 + 3 files changed, 70 insertions(+), 6 deletions(-) create mode 100644 modular_darkpack/modules/powers/code/discipline/mytherceria/riddle.dm diff --git a/modular_darkpack/modules/powers/code/discipline/mytherceria/mytherceria.dm b/modular_darkpack/modules/powers/code/discipline/mytherceria/mytherceria.dm index 08b428680053..fa1c003d9019 100644 --- a/modular_darkpack/modules/powers/code/discipline/mytherceria/mytherceria.dm +++ b/modular_darkpack/modules/powers/code/discipline/mytherceria/mytherceria.dm @@ -11,7 +11,7 @@ activate_sound = 'modular_darkpack/modules/deprecated/sounds/kiasyd.ogg' /** - * • Folderol + * • Folderol - p.455 * * The Kiasyd can cleave truth from lies. The exact effect varies from vampire to vampire. * Some Kiasyd experience bleeding from the eyes or ears when they hear @@ -51,7 +51,7 @@ return /** - * •• Fae Sight + * •• Fae Sight - p.455 * * The Kiasyd’s knowledge of magic isn’t just theoretical. Their strangely-colored eyes are capable of * detecting the arcane energies of the fae, as well as magic from other, more esoteric sources. @@ -104,7 +104,7 @@ target_hud.hide_from(owner)*/ #warn MYTHERCERIA 2 COMMENTED OUT /** - * ••• Aura Absorption + * ••• Aura Absorption - p.455-456 * * The Kiasyd is capable of seeing images of events and emotions past by touching an object or an area. * However, unlike the Auspex Power The Spirit’s Touch, this power absorbs the images, making them harder for @@ -242,7 +242,7 @@ return TRUE /** - * •••• Chanjelin Ward + * •••• Chanjelin Ward - p.455 * * The vampire inscribes a ward on an object, a location, or a person. That ward disorients and befuddles anyone that sees it, * meaning that even if an intruder can penetrate a Weirdling’s security and steal an object of value, he’s unlikely to be able to find his way to the exit. @@ -265,13 +265,47 @@ cooldown_length = 4 TURNS /datum/discipline_power/mytherceria/chanjelin_ward/pre_activation_checks(atom/target) - . = ..() var/activate_time = max(3 TURNS - (owner.st_get_stat(STAT_DEXTERITY) + owner.st_get_stat(STAT_OCCULT)), 1 SECONDS) to_chat(owner, span_notice("You begin inscribing a ward on [target].")) if(!do_after(owner, activation_time, target, interaction_key = "chanjelin_ward", max_interact_count = 1)) to_chat(owner, span_warning("You decide not to finish the ward and erase your progress.")) return FALSE - + . = ..() +/* /datum/discipline_power/mytherceria/chanjelin_ward/activate(atom/target) . = ..() AddElement(/datum/element/chanjelin_ward, user, target) +*/ + +/** + * ••••• The Riddle Phantastique - p.456 + * + * The Kiasyd whispers a riddle to an opponent, and the riddle consumes his mind. + * The target can do nothing until he solves the riddle, and no one can help him — answers provided by others, + * even correct answers, fail to counteract this affliction. + * + * When possessed, add an action button to open the riddle manager. Create a new riddle with up to 5 answers. + * Select a riddle as "active" and when clicking on a target that can hear the Weirdling ask them that riddle aloud. + * They roll Wits + Occult (difficulty 8) once per turn until they accumulate 3x the successes of the riddler, who rolls Manipulation + Occult.. + * The riddle wears off after 6 turns. If the victim botches a roll, take a large amount of brute damage (30?) and lose all accumulated successes. + * This damage cannot be healed until the riddle is solved. If a non-victim says the correct answer aloud, the victim is rendered unconcious and + * is dealt a tremendous amount of brute damage. The riddle can be ended early if the Riddler says the correct answer aloud. + */ +/datum/discipline_power/mytherceria/the_riddle_phantastique + name = "The Riddle Phantastique" + desc = "Ensorcel your foe with a riddle that one can do nothing but ponder." + + level = 4 + check_flags = DISC_CHECK_CAPABLE | DISC_CHECK_DIRECT_SEE | DISC_CHECK_SPEAK + target_type = TARGET_MOB + vitae_cost = 0 + cooldown_length = 4 TURNS + range = 3 + +/datum/discipline_power/mytherceria/the_riddle_phantastique/pre_activation_checks(atom/target) + if(ismob(target)) + var/mob/guy = target + if(guy.can_hear()) + return TRUE + + return FALSE diff --git a/modular_darkpack/modules/powers/code/discipline/mytherceria/riddle.dm b/modular_darkpack/modules/powers/code/discipline/mytherceria/riddle.dm new file mode 100644 index 000000000000..058a473531b2 --- /dev/null +++ b/modular_darkpack/modules/powers/code/discipline/mytherceria/riddle.dm @@ -0,0 +1,28 @@ +/datum/riddle + name = "riddle" + desc = "A riddle created with The Riddle Phantastique, Mytherceria 5." + + // The question to ask as a string. Seperate from name so we can modify it more freely. + var/question = "Who made the mistake of letting this error get on to the live server?" + // The answers indexed in the order they will appear to the victim + var/list/answers = list( + "Maintainers", + "Maptainers", + "Spritetainers", + "Flavrius", + "5th answer to demonstrate the maximum amount of answers allowed in a riddle, which is 5 by the way. We should probably put a character limit on this." + ) + // A subset of var/answers that contains only answers that will break the curse + var/list/correct_answers = list( + "Maintainers", + "Flavrius" + ) + + // The 'owner' of this riddle. If they say the correct answer, the curse is broken. + var/mob/living/carbon/riddler + // The amount of successes the riddler got when rolling. The victim must triple this number to break the curse without answering. + var/riddle_successes = 1 + // The victim of the riddle. If they say anything other than the correct answer they take damage. + var/mob/living/carbon/victim + // The amount of successes the victim currently has. They must triple var/riddle_successes to break the curse without answering. Reset to 0 on botch. + var/riddle_successes = 0 diff --git a/tgstation.dme b/tgstation.dme index e9e159ea4a69..ee5f501906f9 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -7382,6 +7382,8 @@ #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\mytherceria\chanjelin_ward_element.dm" +#include "modular_darkpack\modules\powers\code\discipline\mytherceria\mytherceria.dm" +#include "modular_darkpack\modules\powers\code\discipline\mytherceria\riddle.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\potence\potence.dm"