Adds a new heretic path: Path of the Blades (#65718)
This PR adds a new heretic path. The Path of the Blade, a path focused on becoming a powerful one-on-one combatant with your blades. Main path: Cutting Edge: Allows them to transmute up to five knives. Knives are made with two bars of silver. Grasp of the Blade: The Mansus Grasp will stun and deal additional damage to people lying down or facing away from you. Dance of the Brand: Being attacked while wielding a blade will cause you to counter-attack whoever hit you. Mark of the Blade: Marked targets will be unable to exit their current area. Triggering the mark will give you a floating knife which will block the next attack you receive. Stance of the Scarred Duelist: Blood wounds inflicted upon you are reduced in severity greatly, and you gain immunity to dismemberment. Dropping below 50% health will grant you stun resistance and wound resistance. Swift Blades: Wielding a heretic blade in both hands will attack with both at once. The second attack has a small damage penalty. Furious Steel: A spell that grants you three orbiting blades. Each blade will block an attack upon you, and you can fire the blades at people for decent damage and bleeding. Maelstrom of Silver: Ascension ritual, surrounds you in a whirlwind of eight blades which block attacks. These regenerate over time. Heretic blades deal massively increased damage and offer lifesteal, and you become immune to stuns and wounds. Side paths: Void / blade 1: Shattered Risen. A summon like the voiceless dead, shattered risen are tankier and deal immense damage with their fists, especially to structures, but cannot hold items. Void / blade 3: Maid in the Mirror. A summon that can jaunt infinitely around the station. They can only enter and exit the jaunt around reflective surfaces, such as mirrors, windows, titanium walls, or reflective armor. Rust / blade 3: Lionhunter's rifle. A three shot rifle. When fired at a non-living or close range target, it fires like a normal weapon, however clicking on distant targets will aim at them. The projectile shot at aimed targets deal massively increased damage and cause stuns / knockdowns. It will also track them and travel through walls. Rust / blade 3+1: Additional ammo for the lionhunter's rifle. Other side path changes: Blood Siphon is now a t2 side path, between Flesh and Void. Cleave has been moved to between Flesh and Void Rusted Ritual has been moved to beween ash and rust Also refactors heretic paths a great deal, making it much easier to add new heretic paths.
@@ -33,6 +33,7 @@
|
||||
#define MEDAL_FLESH_ASCENSION "Flesh"
|
||||
#define MEDAL_RUST_ASCENSION "Rust"
|
||||
#define MEDAL_VOID_ASCENSION "Void"
|
||||
#define MEDAL_BLADE_ASCENSION "Blade"
|
||||
#define MEDAL_TOOLBOX_SOUL "Toolsoul"
|
||||
#define MEDAL_CHEM_TUT "Beginner Chemist"
|
||||
#define MEDAL_HOT_DAMN "Hot Damn!"
|
||||
|
||||
@@ -69,6 +69,7 @@
|
||||
#define PATH_RUST "Rust Path"
|
||||
#define PATH_FLESH "Flesh Path"
|
||||
#define PATH_VOID "Void Path"
|
||||
#define PATH_BLADE "Blade Path"
|
||||
|
||||
/// Defines are used in /proc/has_living_heart() to report if the heretic has no heart period, no living heart, or has a living heart.
|
||||
#define HERETIC_NO_HEART_ORGAN -1
|
||||
@@ -78,6 +79,12 @@
|
||||
/// A define used in ritual priority for heretics.
|
||||
#define MAX_KNOWLEDGE_PRIORITY 100
|
||||
|
||||
/// Checks if the passed mob can become a heretic ghoul.
|
||||
/// - Must be a human (type, not species)
|
||||
/// - Skeletons cannot be husked (they are snowflaked instead of having a trait)
|
||||
/// - Monkeys are monkeys, not quite human (balance reasons)
|
||||
#define IS_VALID_GHOUL_MOB(mob) (ishuman(mob) && !isskeleton(mob) && !ismonkey(mob))
|
||||
|
||||
/// Forces the blob to place the core where they currently are, ignoring any checks.
|
||||
#define BLOB_FORCE_PLACEMENT -1
|
||||
/// Normal blob placement, does the regular checks to make sure the blob isn't placing itself in an invalid location
|
||||
|
||||
@@ -73,8 +73,10 @@
|
||||
#define COMSIG_MOVABLE_UPDATE_GLIDE_SIZE "movable_glide_size"
|
||||
///Called when a movable is hit by a plunger in layer mode, from /obj/item/plunger/attack_atom()
|
||||
#define COMSIG_MOVABLE_CHANGE_DUCT_LAYER "movable_change_duct_layer"
|
||||
///Called when a movable is teleported from `do_teleport()`: (destination, channel)
|
||||
///Called when a movable is being teleported from `do_teleport()`: (destination, channel)
|
||||
#define COMSIG_MOVABLE_TELEPORTED "movable_teleported"
|
||||
///Called after a movable is teleported from `do_teleport()`: ()
|
||||
#define COMSIG_MOVABLE_POST_TELEPORT "movable_post_teleport"
|
||||
/// from /mob/living/can_z_move, sent to whatever the mob is buckled to. Only ridable movables should be ridden up or down btw.
|
||||
#define COMSIG_BUCKLED_CAN_Z_MOVE "ridden_pre_can_z_move"
|
||||
#define COMPONENT_RIDDEN_STOP_Z_MOVE 1
|
||||
|
||||
@@ -152,6 +152,12 @@
|
||||
database_id = MEDAL_VOID_ASCENSION
|
||||
icon = "voidascend"
|
||||
|
||||
/datum/award/achievement/misc/blade_ascension
|
||||
name = "Silver and Steel"
|
||||
desc = "You've become the master of all duellists - the paragon of blades."
|
||||
database_id = MEDAL_BLADE_ASCENSION
|
||||
icon = "bladeascend"
|
||||
|
||||
/datum/award/achievement/misc/toolbox_soul
|
||||
name = "SOUL'd Out"
|
||||
desc = "My eternal soul was destroyed to make a toolbox look funny and all I got was this achievement..."
|
||||
|
||||
@@ -25,8 +25,6 @@
|
||||
if (isnull(precision))
|
||||
precision = 0
|
||||
|
||||
SEND_SIGNAL(teleatom, COMSIG_MOVABLE_TELEPORTED, destination, channel)
|
||||
|
||||
switch(channel)
|
||||
if(TELEPORT_CHANNEL_BLUESPACE)
|
||||
if(istype(teleatom, /obj/item/storage/backpack/holding))
|
||||
@@ -65,13 +63,20 @@
|
||||
if(!destturf || !curturf || destturf.is_transition_turf())
|
||||
return FALSE
|
||||
|
||||
var/area/A = get_area(curturf)
|
||||
var/area/B = get_area(destturf)
|
||||
if(!forced && (HAS_TRAIT(teleatom, TRAIT_NO_TELEPORT) || (A.area_flags & NOTELEPORT) || (B.area_flags & NOTELEPORT)))
|
||||
return FALSE
|
||||
var/area/from_area = get_area(curturf)
|
||||
var/area/to_area = get_area(destturf)
|
||||
if(!forced)
|
||||
if(HAS_TRAIT(teleatom, TRAIT_NO_TELEPORT))
|
||||
return FALSE
|
||||
|
||||
if(SEND_SIGNAL(destturf, COMSIG_ATOM_INTERCEPT_TELEPORT, channel, curturf, destturf))
|
||||
return FALSE
|
||||
if((from_area.area_flags & NOTELEPORT) || (to_area.area_flags & NOTELEPORT))
|
||||
return FALSE
|
||||
|
||||
if(SEND_SIGNAL(teleatom, COMSIG_MOVABLE_TELEPORTED, destination, channel) & COMPONENT_BLOCK_TELEPORT)
|
||||
return FALSE
|
||||
|
||||
if(SEND_SIGNAL(destturf, COMSIG_ATOM_INTERCEPT_TELEPORT, channel, curturf, destturf) & COMPONENT_BLOCK_TELEPORT)
|
||||
return FALSE
|
||||
|
||||
if(isobserver(teleatom))
|
||||
teleatom.abstract_move(destturf)
|
||||
@@ -87,6 +92,8 @@
|
||||
var/mob/M = teleatom
|
||||
M.cancel_camera()
|
||||
|
||||
SEND_SIGNAL(teleatom, COMSIG_MOVABLE_POST_TELEPORT)
|
||||
|
||||
return TRUE
|
||||
|
||||
/proc/tele_play_specials(atom/movable/teleatom, atom/location, datum/effect_system/effect, sound)
|
||||
|
||||
@@ -464,6 +464,135 @@
|
||||
is the ultimate redemption, and wounds let you bask in eternal glory."
|
||||
icon_state = "wounded_soldier"
|
||||
|
||||
/// Summons multiple foating knives around the owner.
|
||||
/// Each knife will block an attack straight up.
|
||||
/datum/status_effect/protective_blades
|
||||
id = "Silver Knives"
|
||||
alert_type = null
|
||||
status_type = STATUS_EFFECT_MULTIPLE
|
||||
tick_interval = -1
|
||||
/// The number of blades we summon up to.
|
||||
var/max_num_blades = 4
|
||||
/// The radius of the blade's orbit.
|
||||
var/blade_orbit_radius = 20
|
||||
/// The time between spawning blades.
|
||||
var/time_between_initial_blades = 0.25 SECONDS
|
||||
/// If TRUE, we self-delete our status effect after all the blades are deleted.
|
||||
var/delete_on_blades_gone = TRUE
|
||||
/// A list of blade effects orbiting / protecting our owner
|
||||
var/list/obj/effect/floating_blade/blades = list()
|
||||
|
||||
/datum/status_effect/protective_blades/on_creation(
|
||||
mob/living/new_owner,
|
||||
new_duration = -1,
|
||||
max_num_blades = 4,
|
||||
blade_orbit_radius = 20,
|
||||
time_between_initial_blades = 0.25 SECONDS,
|
||||
)
|
||||
|
||||
src.duration = new_duration
|
||||
src.max_num_blades = max_num_blades
|
||||
src.blade_orbit_radius = blade_orbit_radius
|
||||
src.time_between_initial_blades = time_between_initial_blades
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/protective_blades/on_apply()
|
||||
RegisterSignal(owner, COMSIG_HUMAN_CHECK_SHIELDS, .proc/on_shield_reaction)
|
||||
for(var/blade_num in 1 to max_num_blades)
|
||||
var/time_until_created = (blade_num - 1) * time_between_initial_blades
|
||||
if(time_until_created <= 0)
|
||||
create_blade()
|
||||
else
|
||||
addtimer(CALLBACK(src, .proc/create_blade), time_until_created)
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/status_effect/protective_blades/on_remove()
|
||||
UnregisterSignal(owner, COMSIG_HUMAN_CHECK_SHIELDS)
|
||||
QDEL_LIST(blades)
|
||||
|
||||
return ..()
|
||||
|
||||
/// Creates a floating blade, adds it to our blade list, and makes it orbit our owner.
|
||||
/datum/status_effect/protective_blades/proc/create_blade()
|
||||
if(QDELETED(src) || QDELETED(owner))
|
||||
return
|
||||
|
||||
var/obj/effect/floating_blade/blade = new(get_turf(owner))
|
||||
blades += blade
|
||||
blade.orbit(owner, blade_orbit_radius)
|
||||
RegisterSignal(blade, COMSIG_PARENT_QDELETING, .proc/remove_blade)
|
||||
playsound(get_turf(owner), 'sound/items/unsheath.ogg', 33, TRUE)
|
||||
|
||||
/// Signal proc for [COMSIG_HUMAN_CHECK_SHIELDS].
|
||||
/// If we have a blade in our list, consume it and block the incoming attack (shield it)
|
||||
/datum/status_effect/protective_blades/proc/on_shield_reaction(
|
||||
mob/living/carbon/human/source,
|
||||
atom/movable/hitby,
|
||||
damage = 0,
|
||||
attack_text = "the attack",
|
||||
attack_type = MELEE_ATTACK,
|
||||
armour_penetration = 0,
|
||||
)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!length(blades))
|
||||
return
|
||||
|
||||
var/obj/effect/floating_blade/to_remove = blades[1]
|
||||
|
||||
playsound(get_turf(source), 'sound/weapons/parry.ogg', 100, TRUE)
|
||||
source.visible_message(
|
||||
span_warning("[to_remove] orbiting [source] snaps in front of [attack_text], blocking it before vanishing!"),
|
||||
span_warning("[to_remove] orbiting you snaps in front of [attack_text], blocking it before vanishing!"),
|
||||
span_hear("You hear a clink."),
|
||||
)
|
||||
|
||||
qdel(to_remove)
|
||||
|
||||
return SHIELD_BLOCK
|
||||
|
||||
/// Remove deleted blades from our blades list properly.
|
||||
/datum/status_effect/protective_blades/proc/remove_blade(obj/effect/floating_blade/to_remove)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!(to_remove in blades))
|
||||
CRASH("[type] called remove_blade() with a blade that was not in its blades list.")
|
||||
|
||||
to_remove.stop_orbit(owner.orbiters)
|
||||
blades -= to_remove
|
||||
|
||||
if(!length(blades) && !QDELETED(src) && delete_on_blades_gone)
|
||||
qdel(src)
|
||||
|
||||
return TRUE
|
||||
|
||||
/// A subtype that doesn't self-delete / disappear when all blades are gone
|
||||
/// It instead regenerates over time back to the max after blades are consumed
|
||||
/datum/status_effect/protective_blades/recharging
|
||||
delete_on_blades_gone = FALSE
|
||||
/// The amount of time it takes for a blade to recharge
|
||||
var/blade_recharge_time = 1 MINUTES
|
||||
|
||||
/datum/status_effect/protective_blades/recharging/on_creation(
|
||||
mob/living/new_owner,
|
||||
new_duration = -1,
|
||||
max_num_blades = 4,
|
||||
blade_orbit_radius = 20,
|
||||
time_between_initial_blades = 0.25 SECONDS,
|
||||
blade_recharge_time = 1 MINUTES,
|
||||
)
|
||||
|
||||
src.blade_recharge_time = blade_recharge_time
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/protective_blades/recharging/remove_blade(obj/effect/floating_blade/to_remove)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
|
||||
addtimer(CALLBACK(src, .proc/create_blade), blade_recharge_time)
|
||||
|
||||
/datum/status_effect/lightningorb
|
||||
id = "Lightning Orb"
|
||||
duration = 30 SECONDS
|
||||
|
||||
@@ -393,11 +393,13 @@
|
||||
on_remove_on_mob_delete = TRUE
|
||||
///underlay used to indicate that someone is marked
|
||||
var/mutable_appearance/marked_underlay
|
||||
///path for the underlay
|
||||
var/effect_sprite = ""
|
||||
/// icon file for the underlay
|
||||
var/effect_icon = 'icons/effects/eldritch.dmi'
|
||||
/// icon state for the underlay
|
||||
var/effect_icon_state = ""
|
||||
|
||||
/datum/status_effect/eldritch/on_creation(mob/living/new_owner, ...)
|
||||
marked_underlay = mutable_appearance('icons/effects/effects.dmi', effect_sprite,BELOW_MOB_LAYER)
|
||||
marked_underlay = mutable_appearance(effect_icon, effect_icon_state, BELOW_MOB_LAYER)
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/eldritch/Destroy()
|
||||
@@ -437,7 +439,7 @@
|
||||
|
||||
//Each mark has diffrent effects when it is destroyed that combine with the mansus grasp effect.
|
||||
/datum/status_effect/eldritch/flesh
|
||||
effect_sprite = "emark1"
|
||||
effect_icon_state = "emark1"
|
||||
|
||||
/datum/status_effect/eldritch/flesh/on_effect()
|
||||
if(ishuman(owner))
|
||||
@@ -449,7 +451,7 @@
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/eldritch/ash
|
||||
effect_sprite = "emark2"
|
||||
effect_icon_state = "emark2"
|
||||
/// Dictates how much stamina and burn damage the mark will cause on trigger.
|
||||
var/repetitions = 1
|
||||
|
||||
@@ -471,7 +473,7 @@
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/eldritch/rust
|
||||
effect_sprite = "emark3"
|
||||
effect_icon_state = "emark3"
|
||||
|
||||
/datum/status_effect/eldritch/rust/on_effect()
|
||||
if(iscarbon(owner))
|
||||
@@ -499,7 +501,7 @@
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/eldritch/void
|
||||
effect_sprite = "emark4"
|
||||
effect_icon_state = "emark4"
|
||||
|
||||
/datum/status_effect/eldritch/void/on_effect()
|
||||
var/turf/open/our_turf = get_turf(owner)
|
||||
@@ -512,6 +514,54 @@
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/eldritch/blade
|
||||
effect_icon_state = "emark5"
|
||||
/// If set, the owner of the status effect will not be able to leave this area.
|
||||
var/area/locked_to
|
||||
|
||||
/datum/status_effect/eldritch/blade/Destroy()
|
||||
locked_to = null
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/eldritch/blade/on_apply()
|
||||
. = ..()
|
||||
RegisterSignal(owner, COMSIG_MOVABLE_TELEPORTED, .proc/on_teleport)
|
||||
RegisterSignal(owner, COMSIG_MOVABLE_MOVED, .proc/on_move)
|
||||
|
||||
/datum/status_effect/eldritch/blade/on_remove()
|
||||
UnregisterSignal(owner, list(COMSIG_MOVABLE_TELEPORTED, COMSIG_MOVABLE_MOVED))
|
||||
return ..()
|
||||
|
||||
/// Signal proc for [COMSIG_MOVABLE_TELEPORTED] that blocks any teleports from our locked area
|
||||
/datum/status_effect/eldritch/blade/proc/on_teleport(mob/living/source, atom/destination, channel)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!locked_to)
|
||||
return
|
||||
|
||||
if(get_area(destination) == locked_to)
|
||||
return
|
||||
|
||||
to_chat(source, span_hypnophrase("An otherworldly force prevents your escape from [get_area_name(locked_to)]!"))
|
||||
|
||||
source.Stun(1 SECONDS)
|
||||
return COMPONENT_BLOCK_TELEPORT
|
||||
|
||||
/// Signal proc for [COMSIG_MOVABLE_MOVED] that blocks any movement out of our locked area
|
||||
/datum/status_effect/eldritch/blade/proc/on_move(mob/living/source, turf/old_loc, movement_dir, forced)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!locked_to)
|
||||
return
|
||||
|
||||
if(get_area(source) == locked_to)
|
||||
return
|
||||
|
||||
to_chat(source, span_hypnophrase("An otherworldly force prevents your escape from [get_area_name(locked_to)]!"))
|
||||
|
||||
source.Stun(1 SECONDS)
|
||||
source.throw_at(old_loc, 5, 1)
|
||||
|
||||
/// A status effect used for specifying confusion on a living mob.
|
||||
/// Created automatically with /mob/living/set_confusion.
|
||||
/datum/status_effect/confusion
|
||||
@@ -1121,10 +1171,94 @@
|
||||
status_type = STATUS_EFFECT_UNIQUE
|
||||
duration = -1
|
||||
alert_type = /atom/movable/screen/alert/status_effect/ghoul
|
||||
/// The new max health value set for the ghoul, if supplied
|
||||
var/new_max_health
|
||||
/// Reference to the master of the ghoul's mind
|
||||
var/datum/mind/master_mind
|
||||
/// An optional callback invoked when a ghoul is made (on_apply)
|
||||
var/datum/callback/on_made_callback
|
||||
/// An optional callback invoked when a goul is unghouled (on_removed)
|
||||
var/datum/callback/on_lost_callback
|
||||
|
||||
/datum/status_effect/ghoul/Destroy()
|
||||
master_mind = null
|
||||
QDEL_NULL(on_made_callback)
|
||||
QDEL_NULL(on_lost_callback)
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/ghoul/on_creation(
|
||||
mob/living/new_owner,
|
||||
new_max_health,
|
||||
datum/mind/master_mind,
|
||||
datum/callback/on_made_callback,
|
||||
datum/callback/on_lost_callback,
|
||||
)
|
||||
|
||||
src.new_max_health = new_max_health
|
||||
src.master_mind = master_mind
|
||||
src.on_made_callback = on_made_callback
|
||||
src.on_lost_callback = on_lost_callback
|
||||
|
||||
. = ..()
|
||||
|
||||
if(master_mind)
|
||||
linked_alert.desc += " You are an eldritch monster reanimated to serve its master, [master_mind]."
|
||||
if(isnum(new_max_health))
|
||||
if(new_max_health > initial(new_owner.maxHealth))
|
||||
linked_alert.desc += " You are stronger in this form."
|
||||
else
|
||||
linked_alert.desc += " You are more fragile in this form."
|
||||
|
||||
/datum/status_effect/ghoul/on_apply()
|
||||
if(!ishuman(owner))
|
||||
return FALSE
|
||||
|
||||
var/mob/living/carbon/human/human_target = owner
|
||||
|
||||
RegisterSignal(human_target, COMSIG_LIVING_DEATH, .proc/remove_ghoul_status)
|
||||
human_target.revive(full_heal = TRUE, admin_revive = TRUE)
|
||||
|
||||
if(new_max_health)
|
||||
human_target.setMaxHealth(new_max_health)
|
||||
human_target.health = new_max_health
|
||||
|
||||
on_made_callback?.Invoke(human_target)
|
||||
human_target.become_husk(MAGIC_TRAIT)
|
||||
human_target.faction |= FACTION_HERETIC
|
||||
|
||||
if(human_target.mind)
|
||||
var/datum/antagonist/heretic_monster/heretic_monster = human_target.mind.add_antag_datum(/datum/antagonist/heretic_monster)
|
||||
heretic_monster.set_owner(master_mind)
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/status_effect/ghoul/on_remove()
|
||||
remove_ghoul_status()
|
||||
return ..()
|
||||
|
||||
/// Removes the ghoul effects from our owner and returns them to normal.
|
||||
/datum/status_effect/ghoul/proc/remove_ghoul_status(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!ishuman(owner))
|
||||
return
|
||||
var/mob/living/carbon/human/human_target = owner
|
||||
|
||||
if(new_max_health)
|
||||
human_target.setMaxHealth(initial(human_target.maxHealth))
|
||||
|
||||
on_lost_callback?.Invoke(human_target)
|
||||
human_target.cure_husk(MAGIC_TRAIT)
|
||||
human_target.faction -= FACTION_HERETIC
|
||||
human_target.mind?.remove_antag_datum(/datum/antagonist/heretic_monster)
|
||||
|
||||
UnregisterSignal(human_target, COMSIG_LIVING_DEATH)
|
||||
if(!QDELETED(src))
|
||||
qdel(src)
|
||||
|
||||
/atom/movable/screen/alert/status_effect/ghoul
|
||||
name = "Flesh Servant"
|
||||
desc = "You are a Ghoul! A eldritch monster reanimated to serve its master."
|
||||
desc = "You are a Ghoul!"
|
||||
icon_state = ALERT_MIND_CONTROL
|
||||
|
||||
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
PATH_FLESH = "red",
|
||||
PATH_ASH = "white",
|
||||
PATH_VOID = "blue",
|
||||
PATH_BLADE = "label", // my favorite color is label
|
||||
)
|
||||
|
||||
data["charges"] = knowledge_points
|
||||
|
||||
@@ -15,6 +15,10 @@
|
||||
var/desc = "Basic knowledge of forbidden arts."
|
||||
/// What's shown to the heretic when the knowledge is aquired
|
||||
var/gain_text
|
||||
/// The abstract parent type of the knowledge, used in determine mutual exclusivity in some cases
|
||||
var/datum/heretic_knowledge/abstract_parent_type = /datum/heretic_knowledge
|
||||
/// If TRUE, populates the banned_knowledge list of every other subtype of this knowledge's abstract_parent_type
|
||||
var/mutually_exclusive = FALSE
|
||||
/// The knowledge this unlocks next after learning.
|
||||
var/list/next_knowledge = list()
|
||||
/// What knowledge is incompatible with this. Knowledge in this list cannot be researched with this current knowledge.
|
||||
@@ -32,6 +36,15 @@
|
||||
/// What path is this on. If set to "null", assumed to be unreachable (or abstract).
|
||||
var/route
|
||||
|
||||
/datum/heretic_knowledge/New()
|
||||
if(!mutually_exclusive)
|
||||
return
|
||||
|
||||
for(var/knowledge_type in subtypesof(abstract_parent_type))
|
||||
if(knowledge_type == type)
|
||||
continue
|
||||
banned_knowledge += knowledge_type
|
||||
|
||||
/**
|
||||
* Called when the knowledge is first researched.
|
||||
* This is only ever called once per heretic.
|
||||
@@ -141,7 +154,7 @@
|
||||
var/how_much_to_use = 0
|
||||
for(var/requirement in required_atoms)
|
||||
if(istype(sacrificed, requirement))
|
||||
how_much_to_use = required_atoms[requirement]
|
||||
how_much_to_use = min(required_atoms[requirement], sac_stack.amount)
|
||||
break
|
||||
|
||||
sac_stack.use(how_much_to_use)
|
||||
@@ -154,6 +167,7 @@
|
||||
* A knowledge subtype that grants the heretic a certain spell.
|
||||
*/
|
||||
/datum/heretic_knowledge/spell
|
||||
abstract_parent_type = /datum/heretic_knowledge/spell
|
||||
/// The proc holder spell we add to the heretic. Type-path, becomes an instance via on_research().
|
||||
var/obj/effect/proc_holder/spell/spell_to_add
|
||||
|
||||
@@ -178,6 +192,7 @@
|
||||
* created at once.
|
||||
*/
|
||||
/datum/heretic_knowledge/limited_amount
|
||||
abstract_parent_type = /datum/heretic_knowledge/limited_amount
|
||||
/// The limit to how many items we can create at once.
|
||||
var/limit = 1
|
||||
/// A list of weakrefs to all items we've created.
|
||||
@@ -205,10 +220,149 @@
|
||||
LAZYADD(created_items, WEAKREF(created_thing))
|
||||
return TRUE
|
||||
|
||||
/*
|
||||
* A knowledge subtype for limited_amount knowledge
|
||||
* used for base knowledge (the ones that make blades)
|
||||
*
|
||||
* A heretic can only learn one /starting type knowledge,
|
||||
* and their ascension depends on whichever they chose.
|
||||
*/
|
||||
/datum/heretic_knowledge/limited_amount/starting
|
||||
abstract_parent_type = /datum/heretic_knowledge/limited_amount/starting
|
||||
mutually_exclusive = TRUE
|
||||
limit = 2
|
||||
cost = 1
|
||||
priority = MAX_KNOWLEDGE_PRIORITY - 5
|
||||
|
||||
/datum/heretic_knowledge/limited_amount/starting/New()
|
||||
. = ..()
|
||||
// Starting path also determines the final knowledge we're limited too
|
||||
for(var/datum/heretic_knowledge/final_knowledge_type as anything in subtypesof(/datum/heretic_knowledge/final))
|
||||
if(initial(final_knowledge_type.route) == route)
|
||||
continue
|
||||
banned_knowledge += final_knowledge_type
|
||||
|
||||
/*
|
||||
* A knowledge subtype for heretic knowledge
|
||||
* that applies a mark on use.
|
||||
*
|
||||
* A heretic can only learn one /mark type knowledge.
|
||||
*/
|
||||
/datum/heretic_knowledge/mark
|
||||
abstract_parent_type = /datum/heretic_knowledge/mark
|
||||
mutually_exclusive = TRUE
|
||||
cost = 2
|
||||
/// The status effect typepath we apply on people on mansus grasp.
|
||||
var/datum/status_effect/eldritch/mark_type
|
||||
|
||||
/datum/heretic_knowledge/mark/on_gain(mob/user)
|
||||
RegisterSignal(user, COMSIG_HERETIC_MANSUS_GRASP_ATTACK, .proc/on_mansus_grasp)
|
||||
RegisterSignal(user, COMSIG_HERETIC_BLADE_ATTACK, .proc/on_eldritch_blade)
|
||||
|
||||
/datum/heretic_knowledge/mark/on_lose(mob/user)
|
||||
UnregisterSignal(user, list(COMSIG_HERETIC_MANSUS_GRASP_ATTACK, COMSIG_HERETIC_BLADE_ATTACK))
|
||||
|
||||
/**
|
||||
* Signal proc for [COMSIG_HERETIC_MANSUS_GRASP_ATTACK].
|
||||
*
|
||||
* Whenever we cast mansus grasp on someone, apply our mark.
|
||||
*/
|
||||
/datum/heretic_knowledge/mark/proc/on_mansus_grasp(mob/living/source, mob/living/target)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
create_mark(source, target)
|
||||
|
||||
/**
|
||||
* Signal proc for [COMSIG_HERETIC_BLADE_ATTACK].
|
||||
*
|
||||
* Whenever we attack someone with our blade, attempt to trigger any marks on them.
|
||||
*/
|
||||
/datum/heretic_knowledge/mark/proc/on_eldritch_blade(mob/living/source, mob/living/target, obj/item/melee/sickly_blade/blade)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
trigger_mark(source, target)
|
||||
|
||||
/**
|
||||
* Creates the mark status effect on our target.
|
||||
* This proc handles the instatiate and the application of the station effect,
|
||||
* and returns the /datum/status_effect instance that was made.
|
||||
*
|
||||
* Can be overriden to set or pass in additional vars of the status effect.
|
||||
*/
|
||||
/datum/heretic_knowledge/mark/proc/create_mark(mob/living/source, mob/living/target)
|
||||
return target.apply_status_effect(mark_type)
|
||||
|
||||
/**
|
||||
* Handles triggering the mark on the target.
|
||||
*
|
||||
* If there is no mark, returns FALSE. Returns TRUE if a mark was triggered.
|
||||
*/
|
||||
/datum/heretic_knowledge/mark/proc/trigger_mark(mob/living/source, mob/living/target)
|
||||
var/datum/status_effect/eldritch/mark = target.has_status_effect(/datum/status_effect/eldritch)
|
||||
if(!istype(mark))
|
||||
return FALSE
|
||||
|
||||
mark.on_effect()
|
||||
return TRUE
|
||||
|
||||
/*
|
||||
* A knowledge subtype for heretic knowledge that
|
||||
* upgrades their sickly blade, either on melee or range.
|
||||
*
|
||||
* A heretic can only learn one /blade_upgrade type knowledge.
|
||||
*/
|
||||
/datum/heretic_knowledge/blade_upgrade
|
||||
abstract_parent_type = /datum/heretic_knowledge/blade_upgrade
|
||||
mutually_exclusive = TRUE
|
||||
cost = 2
|
||||
|
||||
/datum/heretic_knowledge/blade_upgrade/on_gain(mob/user)
|
||||
RegisterSignal(user, COMSIG_HERETIC_BLADE_ATTACK, .proc/on_eldritch_blade)
|
||||
RegisterSignal(user, COMSIG_HERETIC_RANGED_BLADE_ATTACK, .proc/on_ranged_eldritch_blade)
|
||||
|
||||
/datum/heretic_knowledge/blade_upgrade/on_lose(mob/user)
|
||||
UnregisterSignal(user, list(COMSIG_HERETIC_BLADE_ATTACK, COMSIG_HERETIC_RANGED_BLADE_ATTACK))
|
||||
|
||||
|
||||
/**
|
||||
* Signal proc for [COMSIG_HERETIC_BLADE_ATTACK].
|
||||
*
|
||||
* Apply any melee effects from hitting someone with our blade.
|
||||
*/
|
||||
/datum/heretic_knowledge/blade_upgrade/proc/on_eldritch_blade(mob/living/source, mob/living/target, obj/item/melee/sickly_blade/blade)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
do_melee_effects(source, target, blade)
|
||||
|
||||
/**
|
||||
* Signal proc for [COMSIG_HERETIC_RANGED_BLADE_ATTACK].
|
||||
*
|
||||
* Apply any ranged effects from hitting someone with our blade.
|
||||
*/
|
||||
/datum/heretic_knowledge/blade_upgrade/proc/on_ranged_eldritch_blade(mob/living/source, mob/living/target, obj/item/melee/sickly_blade/blade)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
do_ranged_effects(source, target, blade)
|
||||
|
||||
/**
|
||||
* Overridable proc that invokes special effects
|
||||
* whenever the heretic attacks someone in melee with their heretic blade.
|
||||
*/
|
||||
/datum/heretic_knowledge/blade_upgrade/proc/do_melee_effects(mob/living/source, mob/living/target, obj/item/melee/sickly_blade/blade)
|
||||
return
|
||||
|
||||
/**
|
||||
* Overridable proc that invokes special effects
|
||||
* whenever the heretic clicks on someone at range with their heretic blade.
|
||||
*/
|
||||
/datum/heretic_knowledge/blade_upgrade/proc/do_ranged_effects(mob/living/source, mob/living/target, obj/item/melee/sickly_blade/blade)
|
||||
return
|
||||
|
||||
/*
|
||||
* A knowledge subtype lets the heretic curse someone with a ritual.
|
||||
*/
|
||||
/datum/heretic_knowledge/curse
|
||||
abstract_parent_type = /datum/heretic_knowledge/curse
|
||||
/// The duration of the curse
|
||||
var/duration = 5 MINUTES
|
||||
/// Cache list of fingerprints (actual fingerprint strings) we have from our current ritual
|
||||
@@ -272,6 +426,7 @@
|
||||
* A knowledge subtype lets the heretic summon a monster with the ritual.
|
||||
*/
|
||||
/datum/heretic_knowledge/summon
|
||||
abstract_parent_type = /datum/heretic_knowledge/summon
|
||||
/// Typepath of a mob to summon when we finish the recipe.
|
||||
var/mob/living/mob_to_summon
|
||||
|
||||
@@ -322,6 +477,8 @@
|
||||
name = "Ritual of Knowledge"
|
||||
desc = "A randomly generated transmutation ritual that rewards knowledge points and can only be completed once."
|
||||
gain_text = "Everything can be a key to unlocking the secrets behind the Gates. I must be wary and wise."
|
||||
abstract_parent_type = /datum/heretic_knowledge/knowledge_ritual
|
||||
mutually_exclusive = TRUE
|
||||
cost = 1
|
||||
priority = MAX_KNOWLEDGE_PRIORITY - 10 // A pretty important midgame ritual.
|
||||
/// Whether we've done the ritual. Only doable once.
|
||||
@@ -411,6 +568,8 @@
|
||||
* The special final tier of knowledges that unlocks ASCENSION.
|
||||
*/
|
||||
/datum/heretic_knowledge/final
|
||||
abstract_parent_type = /datum/heretic_knowledge/final
|
||||
mutually_exclusive = TRUE // I guess, but it doesn't really matter by this point
|
||||
cost = 2
|
||||
priority = MAX_KNOWLEDGE_PRIORITY + 1 // Yes, the final ritual should be ABOVE the max priority.
|
||||
required_atoms = list(/mob/living/carbon/human = 3)
|
||||
|
||||
@@ -39,5 +39,5 @@
|
||||
|
||||
objectives += master_obj
|
||||
owner.announce_objectives()
|
||||
to_chat(owner, span_boldnotice("You are a horrible creation brought to this plane through the Gates of the Mansus."))
|
||||
to_chat(owner, span_boldnotice("You are a [ishuman(owner.current) ? "shambling corpse returned":"horrible creation brought"] to this plane through the Gates of the Mansus."))
|
||||
to_chat(owner, span_notice("Your master is [master]. Assist them to all ends."))
|
||||
|
||||
@@ -46,9 +46,9 @@
|
||||
return
|
||||
|
||||
if(proximity_flag)
|
||||
SEND_SIGNAL(user, COMSIG_HERETIC_BLADE_ATTACK, target)
|
||||
SEND_SIGNAL(user, COMSIG_HERETIC_BLADE_ATTACK, target, src)
|
||||
else
|
||||
SEND_SIGNAL(user, COMSIG_HERETIC_RANGED_BLADE_ATTACK, target)
|
||||
SEND_SIGNAL(user, COMSIG_HERETIC_RANGED_BLADE_ATTACK, target, src)
|
||||
|
||||
/obj/item/melee/sickly_blade/examine(mob/user)
|
||||
. = ..()
|
||||
@@ -57,6 +57,7 @@
|
||||
|
||||
. += span_notice("You can shatter the blade to teleport to a random, (mostly) safe location by <b>activating it in-hand</b>.")
|
||||
|
||||
// Path of Rust's blade
|
||||
/obj/item/melee/sickly_blade/rust
|
||||
name = "\improper rusted blade"
|
||||
desc = "This crescent blade is decrepit, wasting to rust. \
|
||||
@@ -65,6 +66,7 @@
|
||||
inhand_icon_state = "rust_blade"
|
||||
after_use_message = "The Rusted Hills hear your call..."
|
||||
|
||||
// Path of Ash's blade
|
||||
/obj/item/melee/sickly_blade/ash
|
||||
name = "\improper ashen blade"
|
||||
desc = "Molten and unwrought, a hunk of metal warped to cinders and slag. \
|
||||
@@ -73,6 +75,7 @@
|
||||
inhand_icon_state = "ash_blade"
|
||||
after_use_message = "The Nightwater hears your call..."
|
||||
|
||||
// Path of Flesh's blade
|
||||
/obj/item/melee/sickly_blade/flesh
|
||||
name = "\improper bloody blade"
|
||||
desc = "A crescent blade born from a fleshwarped creature. \
|
||||
@@ -81,6 +84,7 @@
|
||||
inhand_icon_state = "flesh_blade"
|
||||
after_use_message = "The Marshal hears your call..."
|
||||
|
||||
// Path of Void's blade
|
||||
/obj/item/melee/sickly_blade/void
|
||||
name = "\improper void blade"
|
||||
desc = "Devoid of any substance, this blade reflects nothingness. \
|
||||
@@ -88,3 +92,12 @@
|
||||
icon_state = "void_blade"
|
||||
inhand_icon_state = "void_blade"
|
||||
after_use_message = "The Aristocrat hears your call..."
|
||||
|
||||
// Path of the Blade's... blade
|
||||
// Opting for /dark (darkened blade) instead of /blade to avoid "sickly_blade/blade".
|
||||
/obj/item/melee/sickly_blade/dark
|
||||
name = "\improper darkened blade"
|
||||
desc = "A blade made of brilliant silver that shines gloriously. Unknown rage is bottled within."
|
||||
icon_state = "dark_blade"
|
||||
inhand_icon_state = "dark_blade"
|
||||
after_use_message = "The Colonel hears your call..."
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
// The Lionhunter, a gun for heretics
|
||||
// The ammo it uses takes time to "charge" before firing,
|
||||
// releasing a homing, very damaging projectile
|
||||
/obj/item/gun/ballistic/rifle/lionhunter
|
||||
name = "\improper Lionhunter's Rifle"
|
||||
desc = "An antique looking rifle that looks immaculate despite being clearly very old."
|
||||
slot_flags = ITEM_SLOT_BACK
|
||||
icon_state = "moistprime"
|
||||
inhand_icon_state = "moistprime"
|
||||
worn_icon_state = "moistprime"
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/boltaction/lionhunter
|
||||
fire_sound = 'sound/weapons/gun/sniper/shot.ogg'
|
||||
zoomable = TRUE
|
||||
zoom_amt = 5
|
||||
zoom_out_amt = 3
|
||||
|
||||
/obj/item/ammo_box/magazine/internal/boltaction/lionhunter
|
||||
name = "lionhunter rifle internal magazine"
|
||||
ammo_type = /obj/item/ammo_casing/a762/lionhunter
|
||||
caliber = CALIBER_A762
|
||||
max_ammo = 3
|
||||
multiload = TRUE
|
||||
|
||||
/obj/item/ammo_casing/a762/lionhunter
|
||||
projectile_type = /obj/projectile/bullet/a762/lionhunter
|
||||
/// Whether we're currently aiming this casing at something
|
||||
var/currently_aiming = FALSE
|
||||
/// How many seconds it takes to aim per tile of distance between the target
|
||||
var/seconds_per_distance = 0.5 SECONDS
|
||||
/// The minimum distance required to gain a damage bonus from aiming
|
||||
var/min_distance = 4
|
||||
|
||||
/obj/item/ammo_casing/a762/lionhunter/fire_casing(atom/target, mob/living/user, params, distro, quiet, zone_override, spread, atom/fired_from)
|
||||
if(!loaded_projectile)
|
||||
return
|
||||
if(!check_fire(target, user))
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
/// Checks if we can successfully fire our projectile.
|
||||
/obj/item/ammo_casing/a762/lionhunter/proc/check_fire(atom/target, mob/living/user)
|
||||
// In case someone puts this in turrets or something wacky, just fire like normal
|
||||
if(!iscarbon(user) || !istype(loc, /obj/item/gun/ballistic/rifle/lionhunter))
|
||||
return TRUE
|
||||
|
||||
if(currently_aiming)
|
||||
user.balloon_alert(user, "already aiming!")
|
||||
return FALSE
|
||||
|
||||
var/distance = get_dist(user, target)
|
||||
var/fire_time = min(distance * seconds_per_distance, 10 SECONDS)
|
||||
|
||||
if(distance <= min_distance || !isliving(target))
|
||||
return TRUE
|
||||
|
||||
user.balloon_alert(user, "taking aim...")
|
||||
user.playsound_local(get_turf(user), 'sound/weapons/gun/general/chunkyrack.ogg', 100, TRUE)
|
||||
|
||||
var/image/reticle = image(
|
||||
icon = 'icons/mob/actions/actions_items.dmi',
|
||||
icon_state = "sniper_zoom",
|
||||
layer = ABOVE_MOB_LAYER,
|
||||
loc = target,
|
||||
)
|
||||
reticle.alpha = 0
|
||||
|
||||
var/list/mob/viewers = viewers(target)
|
||||
// The shooter might be out of view, but they should be included
|
||||
viewers |= user
|
||||
|
||||
for(var/mob/viewer as anything in viewers)
|
||||
viewer.client?.images |= reticle
|
||||
|
||||
// Animate the fade in
|
||||
animate(reticle, fire_time * 0.5, alpha = 255, transform = turn(reticle.transform, 180))
|
||||
animate(reticle, fire_time * 0.5, transform = turn(reticle.transform, 180))
|
||||
|
||||
currently_aiming = TRUE
|
||||
. = do_after(user, fire_time, target, IGNORE_TARGET_LOC_CHANGE, extra_checks = CALLBACK(src, .proc/check_fire_callback, target, user))
|
||||
currently_aiming = FALSE
|
||||
|
||||
animate(reticle, 0.5 SECONDS, alpha = 0)
|
||||
for(var/mob/viewer as anything in viewers)
|
||||
viewer.client?.images -= reticle
|
||||
|
||||
if(!.)
|
||||
user.balloon_alert(user, "interrupted!")
|
||||
|
||||
return .
|
||||
|
||||
/// Callback for the do_after within the check_fire proc to see if something will prevent us from firing while aiming
|
||||
/obj/item/ammo_casing/a762/lionhunter/proc/check_fire_callback(mob/living/target, mob/living/user)
|
||||
if(!isturf(target.loc))
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
/obj/item/ammo_casing/a762/lionhunter/ready_proj(atom/target, mob/living/user, quiet, zone_override, atom/fired_from)
|
||||
if(!loaded_projectile)
|
||||
return
|
||||
|
||||
var/distance = get_dist(user, target)
|
||||
// If we're close range, or the target's not a living, OR for some reason a non-carbon is firing the gun
|
||||
// The projectile is dry-fired, and gains no buffs
|
||||
// BUT, if we're at a decent range and the target's a living mob,
|
||||
// the projectile's been channel fired. It has full effects and homes in.
|
||||
if(distance > min_distance && isliving(target) && iscarbon(user))
|
||||
loaded_projectile.damage *= 1.33
|
||||
loaded_projectile.stamina *= 2
|
||||
loaded_projectile.knockdown = 0.5 SECONDS
|
||||
loaded_projectile.stutter = 6 SECONDS
|
||||
loaded_projectile.projectile_phasing = PASSTABLE | PASSGLASS | PASSGRILLE | PASSCLOSEDTURF | PASSMACHINE | PASSSTRUCTURE | PASSDOORS
|
||||
|
||||
loaded_projectile.homing = TRUE
|
||||
loaded_projectile.homing_turn_speed = 80
|
||||
loaded_projectile.set_homing_target(target)
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/projectile/bullet/a762/lionhunter
|
||||
name = "hunter's 7.62 bullet"
|
||||
// These stats are only applied if the weapon is fired fully aimed
|
||||
// If fired without aiming or at someone too close, it will do much less
|
||||
damage = 30
|
||||
stamina = 30
|
||||
projectile_phasing = PASSTABLE | PASSGLASS | PASSGRILLE | PASSCLOSEDTURF | PASSMACHINE | PASSSTRUCTURE | PASSDOORS
|
||||
|
||||
// Extra ammunition can be made with a heretic ritual.
|
||||
/obj/item/ammo_box/a762/lionhunter
|
||||
name = "stripper clip (7.62mm hunter)"
|
||||
desc = "A stripper clip of mysterious, atypical ammo. It doesn't fit into normal ballistic rifles."
|
||||
icon_state = "762"
|
||||
ammo_type = /obj/item/ammo_casing/a762/lionhunter
|
||||
max_ammo = 3
|
||||
multiple_sprites = AMMO_BOX_PER_BULLET
|
||||
|
||||
/obj/effect/temp_visual/bullet_target
|
||||
icon = 'icons/mob/actions/actions_items.dmi'
|
||||
icon_state = "sniper_zoom"
|
||||
layer = BELOW_MOB_LAYER
|
||||
plane = GAME_PLANE
|
||||
light_range = 2
|
||||
@@ -0,0 +1,14 @@
|
||||
// "Floating ghost blade" effect for blade heretics
|
||||
/obj/effect/floating_blade
|
||||
name = "knife"
|
||||
icon = 'icons/obj/kitchen.dmi'
|
||||
icon_state = "knife"
|
||||
plane = GAME_PLANE_FOV_HIDDEN
|
||||
/// The color the knife glows around it.
|
||||
var/glow_color = "#ececff"
|
||||
|
||||
/obj/effect/floating_blade/Initialize(mapload)
|
||||
. = ..()
|
||||
AddElement(/datum/element/movetype_handler)
|
||||
ADD_TRAIT(src, TRAIT_MOVE_FLYING, INNATE_TRAIT)
|
||||
add_filter("knife", 2, list("type" = "outline", "color" = glow_color, "size" = 1))
|
||||
@@ -11,6 +11,7 @@
|
||||
* Ashen Eyes
|
||||
*
|
||||
* Mark of Ash
|
||||
* Ritual of Knowledge
|
||||
* Mask of Madness
|
||||
* > Sidepaths:
|
||||
* Curse of Corrosion
|
||||
@@ -20,36 +21,25 @@
|
||||
* Nightwater's Rebirth
|
||||
* > Sidepaths:
|
||||
* Ashen Ritual
|
||||
* Blood Cleave
|
||||
* Rusted Ritual
|
||||
*
|
||||
* Ashlord's Rite
|
||||
*/
|
||||
/datum/heretic_knowledge/limited_amount/base_ash
|
||||
/datum/heretic_knowledge/limited_amount/starting/base_ash
|
||||
name = "Nightwatcher's Secret"
|
||||
desc = "Opens up the Path of Ash to you. \
|
||||
Allows you to transmute a match and a knife into an Ashen Blade. \
|
||||
You can only create two at a time."
|
||||
gain_text = "The City Guard know their watch. If you ask them at night, they may tell you about the ashy lantern."
|
||||
next_knowledge = list(/datum/heretic_knowledge/ashen_grasp)
|
||||
banned_knowledge = list(
|
||||
/datum/heretic_knowledge/limited_amount/base_rust,
|
||||
/datum/heretic_knowledge/limited_amount/base_flesh,
|
||||
/datum/heretic_knowledge/limited_amount/base_void,
|
||||
/datum/heretic_knowledge/final/rust_final,
|
||||
/datum/heretic_knowledge/final/flesh_final,
|
||||
/datum/heretic_knowledge/final/void_final,
|
||||
)
|
||||
required_atoms = list(
|
||||
/obj/item/knife = 1,
|
||||
/obj/item/match = 1,
|
||||
)
|
||||
result_atoms = list(/obj/item/melee/sickly_blade/ash)
|
||||
limit = 2
|
||||
cost = 1
|
||||
priority = MAX_KNOWLEDGE_PRIORITY - 5
|
||||
route = PATH_ASH
|
||||
|
||||
/datum/heretic_knowledge/limited_amount/base_ash/on_research(mob/user)
|
||||
/datum/heretic_knowledge/limited_amount/starting/base_ash/on_research(mob/user)
|
||||
. = ..()
|
||||
var/datum/antagonist/heretic/our_heretic = IS_HERETIC(user)
|
||||
our_heretic.heretic_path = route
|
||||
@@ -87,7 +77,7 @@
|
||||
desc = "Grants you Ashen Passage, a silent but short range jaunt."
|
||||
gain_text = "He knew how to walk between the planes."
|
||||
next_knowledge = list(
|
||||
/datum/heretic_knowledge/ash_mark,
|
||||
/datum/heretic_knowledge/mark/ash_mark,
|
||||
/datum/heretic_knowledge/codex_cicatrix,
|
||||
/datum/heretic_knowledge/essence,
|
||||
/datum/heretic_knowledge/medallion,
|
||||
@@ -96,7 +86,7 @@
|
||||
cost = 1
|
||||
route = PATH_ASH
|
||||
|
||||
/datum/heretic_knowledge/ash_mark
|
||||
/datum/heretic_knowledge/mark/ash_mark
|
||||
name = "Mark of Ash"
|
||||
desc = "Your Mansus Grasp now applies the Mark of Ash. The mark is triggered from an attack with your Ashen Blade. \
|
||||
When triggered, the victim takes additional stamina and burn damage, and the mark is transferred to any nearby heathens. \
|
||||
@@ -105,46 +95,20 @@
|
||||
But in spite of his duty, he regularly tranced through the Manse with his blazing lantern held high. \
|
||||
He shone brightly in the darkness, until the blaze begin to die."
|
||||
next_knowledge = list(/datum/heretic_knowledge/knowledge_ritual/ash)
|
||||
banned_knowledge = list(
|
||||
/datum/heretic_knowledge/rust_mark,
|
||||
/datum/heretic_knowledge/flesh_mark,
|
||||
/datum/heretic_knowledge/void_mark,
|
||||
)
|
||||
cost = 2
|
||||
route = PATH_ASH
|
||||
mark_type = /datum/status_effect/eldritch/ash
|
||||
|
||||
/datum/heretic_knowledge/ash_mark/on_gain(mob/user)
|
||||
RegisterSignal(user, COMSIG_HERETIC_MANSUS_GRASP_ATTACK, .proc/on_mansus_grasp)
|
||||
RegisterSignal(user, COMSIG_HERETIC_BLADE_ATTACK, .proc/on_eldritch_blade)
|
||||
|
||||
/datum/heretic_knowledge/ash_mark/on_lose(mob/user)
|
||||
UnregisterSignal(user, list(COMSIG_HERETIC_MANSUS_GRASP_ATTACK, COMSIG_HERETIC_BLADE_ATTACK))
|
||||
|
||||
/datum/heretic_knowledge/ash_mark/proc/on_mansus_grasp(mob/living/source, mob/living/target)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
target.apply_status_effect(/datum/status_effect/eldritch/ash)
|
||||
|
||||
/datum/heretic_knowledge/ash_mark/proc/on_eldritch_blade(mob/living/user, mob/living/target)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
var/datum/status_effect/eldritch/mark = target.has_status_effect(/datum/status_effect/eldritch)
|
||||
if(!istype(mark))
|
||||
/datum/heretic_knowledge/mark/ash_mark/trigger_mark(mob/living/source, mob/living/target)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
|
||||
mark.on_effect()
|
||||
|
||||
// Also refunds 75% of charge!
|
||||
for(var/obj/effect/proc_holder/spell/targeted/touch/mansus_grasp/grasp in user.mind.spell_list)
|
||||
for(var/obj/effect/proc_holder/spell/targeted/touch/mansus_grasp/grasp in source.mind.spell_list)
|
||||
grasp.charge_counter = min(round(grasp.charge_counter + grasp.charge_max * 0.75), grasp.charge_max)
|
||||
|
||||
/datum/heretic_knowledge/knowledge_ritual/ash
|
||||
next_knowledge = list(/datum/heretic_knowledge/mad_mask)
|
||||
banned_knowledge = list(
|
||||
/datum/heretic_knowledge/knowledge_ritual/flesh,
|
||||
/datum/heretic_knowledge/knowledge_ritual/void,
|
||||
/datum/heretic_knowledge/knowledge_ritual/rust,
|
||||
)
|
||||
route = PATH_ASH
|
||||
|
||||
/datum/heretic_knowledge/mad_mask
|
||||
@@ -154,7 +118,7 @@
|
||||
It can also be forced onto a heathen, to make them unable to take it off..."
|
||||
gain_text = "The Nightwater was lost. That's what the Watch believed. Yet he walked the world, unnoticed by the masses."
|
||||
next_knowledge = list(
|
||||
/datum/heretic_knowledge/ash_blade_upgrade,
|
||||
/datum/heretic_knowledge/blade_upgrade/ash,
|
||||
/datum/heretic_knowledge/reroll_targets,
|
||||
/datum/heretic_knowledge/curse/corrosion,
|
||||
/datum/heretic_knowledge/curse/paralysis,
|
||||
@@ -169,32 +133,16 @@
|
||||
cost = 1
|
||||
route = PATH_ASH
|
||||
|
||||
/datum/heretic_knowledge/ash_blade_upgrade
|
||||
/datum/heretic_knowledge/blade_upgrade/ash
|
||||
name = "Fiery Blade"
|
||||
desc = "Your blade now lights enemies ablaze on attack."
|
||||
gain_text = "He returned, blade in hand, he swung and swung as the ash fell from the skies. \
|
||||
His city, the people he swore to watch... and watch he did, as they all burnt to cinders."
|
||||
next_knowledge = list(/datum/heretic_knowledge/spell/flame_birth)
|
||||
banned_knowledge = list(
|
||||
/datum/heretic_knowledge/rust_blade_upgrade,
|
||||
/datum/heretic_knowledge/flesh_blade_upgrade,
|
||||
/datum/heretic_knowledge/void_blade_upgrade,
|
||||
)
|
||||
cost = 2
|
||||
route = PATH_ASH
|
||||
|
||||
/datum/heretic_knowledge/ash_blade_upgrade/on_gain(mob/user)
|
||||
. = ..()
|
||||
RegisterSignal(user, COMSIG_HERETIC_BLADE_ATTACK, .proc/on_eldritch_blade)
|
||||
|
||||
/datum/heretic_knowledge/ash_blade_upgrade/on_lose(mob/user)
|
||||
. = ..()
|
||||
UnregisterSignal(user, COMSIG_HERETIC_BLADE_ATTACK)
|
||||
|
||||
/datum/heretic_knowledge/ash_blade_upgrade/proc/on_eldritch_blade(mob/living/user, mob/living/target)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(user == target)
|
||||
/datum/heretic_knowledge/blade_upgrade/ash/do_melee_effects(mob/living/source, mob/living/target, obj/item/melee/sickly_blade/blade)
|
||||
if(source == target)
|
||||
return
|
||||
|
||||
target.adjust_fire_stacks(1)
|
||||
@@ -210,7 +158,7 @@
|
||||
next_knowledge = list(
|
||||
/datum/heretic_knowledge/final/ash_final,
|
||||
/datum/heretic_knowledge/summon/ashy,
|
||||
/datum/heretic_knowledge/spell/cleave,
|
||||
/datum/heretic_knowledge/summon/rusty,
|
||||
)
|
||||
spell_to_add = /obj/effect/proc_holder/spell/targeted/fiery_rebirth
|
||||
cost = 1
|
||||
|
||||
@@ -0,0 +1,400 @@
|
||||
/**
|
||||
* # The path of Blades. Stab stab.
|
||||
*
|
||||
* Goes as follows:
|
||||
*
|
||||
* The Cutting Edge
|
||||
* Grasp of the Blade
|
||||
* Dance of the Brand
|
||||
* > Sidepaths:
|
||||
* Shattered Risen
|
||||
* Armorer's Ritual
|
||||
*
|
||||
* Mark of the Blade
|
||||
* Ritual of Knowledge
|
||||
* Stance of the Scarred Duelist
|
||||
* > Sidepaths:
|
||||
* Carving Knife
|
||||
* Mawed Crucible
|
||||
*
|
||||
* Swift Blades
|
||||
* Furious Steel
|
||||
* > Sidepaths:
|
||||
* Maid in the Mirror
|
||||
* Lionhunter Rifle
|
||||
*
|
||||
* Maelstrom of Silver
|
||||
*/
|
||||
/datum/heretic_knowledge/limited_amount/starting/base_blade
|
||||
name = "The Cutting Edge"
|
||||
desc = "Opens up the path of blades to you. \
|
||||
Allows you to transmute a knife with a bar of silver to create a Darkened Blade. \
|
||||
You can create up to five at a time."
|
||||
gain_text = "Our great ancestors forged swords and practiced sparring on the even of great battles."
|
||||
next_knowledge = list(/datum/heretic_knowledge/blade_grasp)
|
||||
required_atoms = list(
|
||||
/obj/item/knife = 1,
|
||||
/obj/item/stack/sheet/mineral/silver = 2,
|
||||
)
|
||||
result_atoms = list(/obj/item/melee/sickly_blade/dark)
|
||||
limit = 5 // It's the blade path, it's a given
|
||||
route = PATH_BLADE
|
||||
|
||||
/datum/heretic_knowledge/blade_grasp
|
||||
name = "Grasp of the Blade"
|
||||
desc = "Your Mansus Grasp will cause a short stun when used on someone lying down or facing away from you."
|
||||
gain_text = "The story of the footsoldier has been told since antiquity. It is one of blood and valor, \
|
||||
and is championed by sword, steel and silver."
|
||||
next_knowledge = list(/datum/heretic_knowledge/blade_dance)
|
||||
cost = 1
|
||||
route = PATH_BLADE
|
||||
|
||||
/datum/heretic_knowledge/blade_grasp/on_gain(mob/user)
|
||||
RegisterSignal(user, COMSIG_HERETIC_MANSUS_GRASP_ATTACK, .proc/on_mansus_grasp)
|
||||
|
||||
/datum/heretic_knowledge/blade_grasp/on_lose(mob/user)
|
||||
UnregisterSignal(user, COMSIG_HERETIC_MANSUS_GRASP_ATTACK)
|
||||
|
||||
/datum/heretic_knowledge/blade_grasp/proc/on_mansus_grasp(mob/living/source, mob/living/target)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
// Let's see if source is behind target
|
||||
// "Behind" is defined as 3 tiles directly to the back of the target
|
||||
// x . .
|
||||
// x > .
|
||||
// x . .
|
||||
|
||||
var/are_we_behind = FALSE
|
||||
// No tactical spinning allowed
|
||||
if(target.flags_1 & IS_SPINNING_1)
|
||||
are_we_behind = TRUE
|
||||
|
||||
// We'll take "same tile" as "behind" for ease
|
||||
if(target.loc == source.loc)
|
||||
are_we_behind = TRUE
|
||||
|
||||
// We'll also assume lying down is behind, as mob directions when lying are unclear
|
||||
if(target.body_position == LYING_DOWN)
|
||||
are_we_behind = TRUE
|
||||
|
||||
// Exceptions aside, let's actually check if they're, yknow, behind
|
||||
var/dir_target_to_source = get_dir(target, source)
|
||||
if(target.dir & REVERSE_DIR(dir_target_to_source))
|
||||
are_we_behind = TRUE
|
||||
|
||||
if(!are_we_behind)
|
||||
return
|
||||
|
||||
// We're officially behind them, apply effects
|
||||
target.AdjustParalyzed(1.5 SECONDS)
|
||||
target.apply_damage(10, BRUTE, wound_bonus = CANT_WOUND)
|
||||
target.balloon_alert(source, "backstab!")
|
||||
playsound(get_turf(target), 'sound/weapons/guillotine.ogg', 100, TRUE)
|
||||
|
||||
/// The cooldown duration between trigers of blade dance
|
||||
#define BLADE_DANCE_COOLDOWN 20 SECONDS
|
||||
|
||||
/datum/heretic_knowledge/blade_dance
|
||||
name = "Dance of the Brand"
|
||||
desc = "Being attacked while wielding a Darkened Blade in either hand will deliver a riposte \
|
||||
towards your attacker. This effect can only trigger once every 20 seconds."
|
||||
gain_text = "Having the prowess to wield such a thing requires great dedication and terror."
|
||||
next_knowledge = list(
|
||||
/datum/heretic_knowledge/limited_amount/risen_corpse,
|
||||
/datum/heretic_knowledge/mark/blade_mark,
|
||||
/datum/heretic_knowledge/codex_cicatrix,
|
||||
/datum/heretic_knowledge/armor,
|
||||
)
|
||||
cost = 1
|
||||
route = PATH_BLADE
|
||||
/// Whether the counter-attack is ready or not.
|
||||
/// Used instead of cooldowns, so we can give feedback when it's ready again
|
||||
var/riposte_ready = TRUE
|
||||
|
||||
/datum/heretic_knowledge/blade_dance/on_gain(mob/user)
|
||||
RegisterSignal(user, COMSIG_HUMAN_CHECK_SHIELDS, .proc/on_shield_reaction)
|
||||
|
||||
/datum/heretic_knowledge/blade_dance/on_lose(mob/user)
|
||||
UnregisterSignal(user, COMSIG_HUMAN_CHECK_SHIELDS)
|
||||
|
||||
/datum/heretic_knowledge/blade_dance/proc/on_shield_reaction(
|
||||
mob/living/carbon/human/source,
|
||||
atom/movable/hitby,
|
||||
damage = 0,
|
||||
attack_text = "the attack",
|
||||
attack_type = MELEE_ATTACK,
|
||||
armour_penetration = 0,
|
||||
)
|
||||
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(attack_type != MELEE_ATTACK)
|
||||
return
|
||||
|
||||
if(!riposte_ready)
|
||||
return
|
||||
|
||||
if(source.incapacitated(IGNORE_GRAB))
|
||||
return
|
||||
|
||||
var/mob/living/attacker = hitby.loc
|
||||
if(!istype(attacker))
|
||||
return
|
||||
|
||||
if(!source.Adjacent(attacker))
|
||||
return
|
||||
|
||||
// Let's check their held items to see if we can do a riposte
|
||||
var/obj/item/main_hand = source.get_active_held_item()
|
||||
var/obj/item/off_hand = source.get_inactive_held_item()
|
||||
// This is the item that ends up doing the "blocking" (flavor)
|
||||
var/obj/item/striking_with
|
||||
|
||||
// First we'll check if the offhand is valid
|
||||
if(!QDELETED(off_hand) && istype(off_hand, /obj/item/melee/sickly_blade))
|
||||
striking_with = off_hand
|
||||
|
||||
// Then we'll check the mainhand
|
||||
// We do mainhand second, because we want to prioritize it over the offhand
|
||||
if(!QDELETED(main_hand) && istype(main_hand, /obj/item/melee/sickly_blade))
|
||||
striking_with = main_hand
|
||||
|
||||
// No valid item in either slot? No riposte
|
||||
if(!striking_with)
|
||||
return
|
||||
|
||||
// If we made it here, deliver the strike
|
||||
INVOKE_ASYNC(src, .proc/counter_attack, source, attacker, striking_with, attack_text)
|
||||
|
||||
// And reset after a bit
|
||||
riposte_ready = FALSE
|
||||
addtimer(CALLBACK(src, .proc/reset_riposte, source), BLADE_DANCE_COOLDOWN)
|
||||
|
||||
/datum/heretic_knowledge/blade_dance/proc/counter_attack(mob/living/carbon/human/source, mob/living/target, obj/item/melee/sickly_blade/weapon, attack_text)
|
||||
playsound(get_turf(source), 'sound/weapons/parry.ogg', 100, TRUE)
|
||||
source.balloon_alert(source, "riposte used")
|
||||
source.visible_message(
|
||||
span_warning("[source] leans into [attack_text] and delivers a sudden riposte back at [target]!"),
|
||||
span_warning("You lean into [attack_text] and deliver a sudden riposte back at [target]!"),
|
||||
span_hear("You hear a clink, followed by a stab."),
|
||||
)
|
||||
weapon.melee_attack_chain(source, target)
|
||||
|
||||
/datum/heretic_knowledge/blade_dance/proc/reset_riposte(mob/living/carbon/human/source)
|
||||
riposte_ready = TRUE
|
||||
source.balloon_alert(source, "riposte ready")
|
||||
|
||||
#undef BLADE_DANCE_COOLDOWN
|
||||
|
||||
/datum/heretic_knowledge/mark/blade_mark
|
||||
name = "Mark of the Blade"
|
||||
desc = "Your Mansus Grasp now applies the Mark of the Blade. While marked, \
|
||||
the victim will be unable to leave their current room until it expires or is triggered. \
|
||||
Triggering the mark will summon a knife that will orbit you for a short time. \
|
||||
The knife will block any attack directed towards you, but is consumed on use."
|
||||
gain_text = "There was no room for cowardace here. Those who ran were scolded. \
|
||||
That is how I met them. Their name was The Colonel."
|
||||
next_knowledge = list(/datum/heretic_knowledge/knowledge_ritual/blade)
|
||||
route = PATH_BLADE
|
||||
mark_type = /datum/status_effect/eldritch/blade
|
||||
|
||||
/datum/heretic_knowledge/mark/blade_mark/create_mark(mob/living/source, mob/living/target)
|
||||
var/datum/status_effect/eldritch/blade/blade_mark = ..()
|
||||
if(!istype(blade_mark))
|
||||
return
|
||||
|
||||
var/area/to_lock_to = get_area(target)
|
||||
blade_mark.locked_to = to_lock_to
|
||||
to_chat(target, span_hypnophrase("An otherworldly force is compelling you to stay in [get_area_name(to_lock_to)]!"))
|
||||
|
||||
/datum/heretic_knowledge/mark/blade_mark/trigger_mark(mob/living/source, mob/living/target)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
source.apply_status_effect(/datum/status_effect/protective_blades, 60 SECONDS, 1, 20, 0 SECONDS)
|
||||
|
||||
/datum/heretic_knowledge/knowledge_ritual/blade
|
||||
next_knowledge = list(/datum/heretic_knowledge/duel_stance)
|
||||
route = PATH_BLADE
|
||||
|
||||
/// The amount of blood flow reduced per level of severity of gained bleeding wounds for Stance of the Scarred Duelist.
|
||||
#define BLOOD_FLOW_PER_SEVEIRTY 1
|
||||
|
||||
/datum/heretic_knowledge/duel_stance
|
||||
name = "Stance of the Scarred Duelist"
|
||||
desc = "Grants resilience to blood loss from wounds and immunity to having your limbs dismembered. \
|
||||
Additionally, when damaged below 50% of your maximum health, \
|
||||
you gain increased resistance to gaining wounds and stun resistance."
|
||||
gain_text = "The Colonel was many things though out the age. But now, he is blind; he is deaf; \
|
||||
he cannot be wounded; and he cannot be denied. His methods ensure that."
|
||||
next_knowledge = list(
|
||||
/datum/heretic_knowledge/blade_upgrade/blade,
|
||||
/datum/heretic_knowledge/reroll_targets,
|
||||
/datum/heretic_knowledge/rune_carver,
|
||||
/datum/heretic_knowledge/crucible,
|
||||
)
|
||||
cost = 1
|
||||
route = PATH_BLADE
|
||||
/// Whether we're currently in duelist stance, gaining certain buffs (low health)
|
||||
var/in_duelist_stance = FALSE
|
||||
|
||||
/datum/heretic_knowledge/duel_stance/on_gain(mob/user)
|
||||
ADD_TRAIT(user, TRAIT_NODISMEMBER, type)
|
||||
RegisterSignal(user, COMSIG_PARENT_EXAMINE, .proc/on_examine)
|
||||
RegisterSignal(user, COMSIG_CARBON_GAIN_WOUND, .proc/on_wound_gain)
|
||||
RegisterSignal(user, COMSIG_CARBON_HEALTH_UPDATE, .proc/on_health_update)
|
||||
|
||||
on_health_update(user) // Run this once, so if the knowledge is learned while hurt it activates properly
|
||||
|
||||
/datum/heretic_knowledge/duel_stance/on_lose(mob/user)
|
||||
REMOVE_TRAIT(user, TRAIT_NODISMEMBER, type)
|
||||
if(in_duelist_stance)
|
||||
REMOVE_TRAIT(user, TRAIT_HARDLY_WOUNDED, type)
|
||||
REMOVE_TRAIT(user, TRAIT_STUNRESISTANCE, type)
|
||||
|
||||
UnregisterSignal(user, list(COMSIG_PARENT_EXAMINE, COMSIG_CARBON_GAIN_WOUND, COMSIG_CARBON_HEALTH_UPDATE))
|
||||
|
||||
/datum/heretic_knowledge/duel_stance/proc/on_examine(mob/living/source, mob/user, list/examine_list)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
var/obj/item/held_item = source.get_active_held_item()
|
||||
if(in_duelist_stance)
|
||||
examine_list += span_warning("[source] looks unnaturally poised[held_item?.force >= 15 ? " and ready to strike out":""].")
|
||||
|
||||
/datum/heretic_knowledge/duel_stance/proc/on_wound_gain(mob/living/source, datum/wound/gained_wound, obj/item/bodypart/limb)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(gained_wound.blood_flow <= 0)
|
||||
return
|
||||
|
||||
gained_wound.blood_flow -= (gained_wound.severity * BLOOD_FLOW_PER_SEVEIRTY)
|
||||
|
||||
/datum/heretic_knowledge/duel_stance/proc/on_health_update(mob/living/source)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(in_duelist_stance && source.health > source.maxHealth * 0.5)
|
||||
source.balloon_alert(source, "exited duelist stance")
|
||||
in_duelist_stance = FALSE
|
||||
REMOVE_TRAIT(source, TRAIT_HARDLY_WOUNDED, type)
|
||||
REMOVE_TRAIT(source, TRAIT_STUNRESISTANCE, type)
|
||||
return
|
||||
|
||||
if(!in_duelist_stance && source.health <= source.maxHealth * 0.5)
|
||||
source.balloon_alert(source, "entered duelist stance")
|
||||
in_duelist_stance = TRUE
|
||||
ADD_TRAIT(source, TRAIT_HARDLY_WOUNDED, type)
|
||||
ADD_TRAIT(source, TRAIT_STUNRESISTANCE, type)
|
||||
return
|
||||
|
||||
#undef BLOOD_FLOW_PER_SEVEIRTY
|
||||
|
||||
/datum/heretic_knowledge/blade_upgrade/blade
|
||||
name = "Swift Blades"
|
||||
desc = "Attacking someone with a Darkened Blade in both hands \
|
||||
will now deliver a blow with both at once, dealing two attacks in rapid succession. \
|
||||
The second blow will be slightly weaker."
|
||||
gain_text = "From here, I began to learn the Colonel's arts. The prowess was finally mine to have."
|
||||
next_knowledge = list(/datum/heretic_knowledge/spell/furious_steel)
|
||||
route = PATH_BLADE
|
||||
|
||||
/datum/heretic_knowledge/blade_upgrade/blade/do_melee_effects(mob/living/source, mob/living/target, obj/item/melee/sickly_blade/blade)
|
||||
if(target == source)
|
||||
return
|
||||
|
||||
var/obj/item/off_hand = source.get_inactive_held_item()
|
||||
if(QDELETED(off_hand) || !istype(off_hand, /obj/item/melee/sickly_blade))
|
||||
return
|
||||
// If our off-hand is the blade that's attacking,
|
||||
// quit out now to avoid an infinite stab combo
|
||||
if(off_hand == blade)
|
||||
return
|
||||
|
||||
// Give it a short delay (for style, also lets people dodge it I guess)
|
||||
addtimer(CALLBACK(src, .proc/follow_up_attack, source, target, off_hand), 0.25 SECONDS)
|
||||
|
||||
/datum/heretic_knowledge/blade_upgrade/blade/proc/follow_up_attack(mob/living/source, mob/living/target, obj/item/melee/sickly_blade/blade)
|
||||
if(QDELETED(source) || QDELETED(target) || QDELETED(blade))
|
||||
return
|
||||
// Sanity to ensure that the blade we're delivering
|
||||
// an offhand attack with is actually our offhand
|
||||
if(blade != source.get_inactive_held_item())
|
||||
return
|
||||
if(!source.Adjacent(target))
|
||||
return
|
||||
|
||||
// Blade are 17 force: 17 + 17 = 34 (3 hits to crit, unarmored)
|
||||
// So, -5 force is put on the offhand blade: 17 + 12 = 29 (4 hits to crit, unarmored)
|
||||
blade.force -= 5
|
||||
blade.melee_attack_chain(source, target)
|
||||
blade.force += 5
|
||||
|
||||
/datum/heretic_knowledge/spell/furious_steel
|
||||
name = "Furious Steel"
|
||||
desc = "Grants you Furious Steel, a targeted spell. Using it will summon three \
|
||||
orbiting blades around you. These blades will protect you from all attacks, \
|
||||
but are consumed on use. Additionally, you can click to fire the blades \
|
||||
at a target, dealing damage and causing bleeding."
|
||||
gain_text = "His arts were those that ensured an ending."
|
||||
next_knowledge = list(
|
||||
/datum/heretic_knowledge/summon/maid_in_mirror,
|
||||
/datum/heretic_knowledge/final/blade_final,
|
||||
/datum/heretic_knowledge/rifle,
|
||||
)
|
||||
spell_to_add = /obj/effect/proc_holder/spell/aimed/furious_steel
|
||||
cost = 1
|
||||
route = PATH_BLADE
|
||||
|
||||
/datum/heretic_knowledge/final/blade_final
|
||||
name = "Maelstrom of Silver"
|
||||
desc = "The ascension ritual of the Path of Blades. \
|
||||
Bring 3 headless corpses to a transmutation rune to complete the ritual. \
|
||||
When completed, you will be surrounded in a constant, regenerating orbit of blades. \
|
||||
These blades will protect you from all attacks, but are consumed on use. \
|
||||
Your Furious Steel spell will also have a shorter cooldown. \
|
||||
Additionally, you become a master of combat, gaining full wound and stun immunity. \
|
||||
Your Darkened Blades deal bonus damage and healing you on attack for a portion of the damage dealt."
|
||||
gain_text = "The Colonel, in all of his expertise, revealed to me the three roots of victory. \
|
||||
Cunning. Strength. And agony! This was their secret doctrine! With this knowledge in my potential, \
|
||||
I AM UNMATCHED! A STORM OF STEEL AND SILVER IS UPON US! WITNESS MY ASCENSION!"
|
||||
route = PATH_BLADE
|
||||
|
||||
/datum/heretic_knowledge/final/blade_final/is_valid_sacrifice(mob/living/carbon/human/sacrifice)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
|
||||
return !sacrifice.get_bodypart(BODY_ZONE_HEAD)
|
||||
|
||||
/datum/heretic_knowledge/final/blade_final/on_finished_recipe(mob/living/user, list/selected_atoms, turf/loc)
|
||||
. = ..()
|
||||
priority_announce("[generate_heretic_text()] Master of blades, the Colonel's disciple, [user.real_name] has ascended! Their steel is that which will cut reality in a maelstom of silver! [generate_heretic_text()]","[generate_heretic_text()]", ANNOUNCER_SPANOMALIES)
|
||||
user.client?.give_award(/datum/award/achievement/misc/blade_ascension, user)
|
||||
ADD_TRAIT(user, TRAIT_STUNIMMUNE, name)
|
||||
ADD_TRAIT(user, TRAIT_NEVER_WOUNDED, name)
|
||||
RegisterSignal(user, COMSIG_HERETIC_BLADE_ATTACK, .proc/on_eldritch_blade)
|
||||
user.apply_status_effect(/datum/status_effect/protective_blades/recharging, null, 8, 30, 0.25 SECONDS, 1 MINUTES)
|
||||
|
||||
var/obj/effect/proc_holder/spell/aimed/furious_steel/steel_spell = locate() in user.mind.spell_list
|
||||
steel_spell?.charge_max /= 3
|
||||
|
||||
/datum/heretic_knowledge/final/blade_final/proc/on_eldritch_blade(mob/living/source, mob/living/target, obj/item/melee/sickly_blade/blade)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(target == source)
|
||||
return
|
||||
|
||||
// Turns your heretic blades into eswords, pretty much.
|
||||
var/bonus_damage = clamp(30 - blade.force, 0, 12)
|
||||
|
||||
target.apply_damage(
|
||||
damage = bonus_damage,
|
||||
damagetype = BRUTE,
|
||||
spread_damage = TRUE,
|
||||
wound_bonus = 5,
|
||||
sharpness = SHARP_EDGED,
|
||||
attack_direction = get_dir(source, target),
|
||||
)
|
||||
|
||||
if(target.stat != DEAD)
|
||||
// And! Get some free healing for a portion of the bonus damage dealt.
|
||||
source.heal_overall_damage(bonus_damage / 2, bonus_damage / 2)
|
||||
@@ -16,45 +16,36 @@
|
||||
* Ashen Eyes
|
||||
*
|
||||
* Mark of Flesh
|
||||
* Ritual of Knowledge
|
||||
* Raw Ritual
|
||||
* > Sidepaths:
|
||||
* Carving Knife
|
||||
* Blood Siphon
|
||||
* Curse of Paralysis
|
||||
*
|
||||
* Bleeding Steel
|
||||
* Lonely Ritual
|
||||
* > Sidepaths:
|
||||
* Ashen Ritual
|
||||
* Blood Siphon
|
||||
* Cleave
|
||||
*
|
||||
* Priest's Final Hymn
|
||||
*/
|
||||
/datum/heretic_knowledge/limited_amount/base_flesh
|
||||
/datum/heretic_knowledge/limited_amount/starting/base_flesh
|
||||
name = "Principle of Hunger"
|
||||
desc = "Opens up the Path of Flesh to you. \
|
||||
Allows you to transmute a knife and a pool of blood into a Bloody Blade. \
|
||||
You can only create three at a time."
|
||||
gain_text = "Hundreds of us starved, but not me... I found strength in my greed."
|
||||
next_knowledge = list(/datum/heretic_knowledge/limited_amount/flesh_grasp)
|
||||
banned_knowledge = list(
|
||||
/datum/heretic_knowledge/limited_amount/base_ash,
|
||||
/datum/heretic_knowledge/limited_amount/base_rust,
|
||||
/datum/heretic_knowledge/limited_amount/base_void,
|
||||
/datum/heretic_knowledge/final/ash_final,
|
||||
/datum/heretic_knowledge/final/rust_final,
|
||||
/datum/heretic_knowledge/final/void_final,
|
||||
)
|
||||
required_atoms = list(
|
||||
/obj/item/knife = 1,
|
||||
/obj/effect/decal/cleanable/blood = 1,
|
||||
)
|
||||
result_atoms = list(/obj/item/melee/sickly_blade/flesh)
|
||||
limit = 3 // Bumped up so they can arm up their ghouls too.
|
||||
cost = 1
|
||||
priority = MAX_KNOWLEDGE_PRIORITY - 5
|
||||
route = PATH_FLESH
|
||||
|
||||
/datum/heretic_knowledge/limited_amount/base_flesh/on_research(mob/user)
|
||||
/datum/heretic_knowledge/limited_amount/starting/base_flesh/on_research(mob/user)
|
||||
. = ..()
|
||||
var/datum/antagonist/heretic/our_heretic = IS_HERETIC(user)
|
||||
our_heretic.heretic_path = route
|
||||
@@ -68,8 +59,9 @@
|
||||
|
||||
/datum/heretic_knowledge/limited_amount/flesh_grasp
|
||||
name = "Grasp of Flesh"
|
||||
desc = "Your Mansus Grasp gains the ability to create a single ghoul out of corpse with a soul. \
|
||||
Ghouls have only 25 health and look like husks to the heathens' eyes, but can use Bloody Blades effectively."
|
||||
desc = "Your Mansus Grasp gains the ability to create a ghoul out of corpse with a soul. \
|
||||
Ghouls have only 25 health and look like husks to the heathens' eyes, but can use Bloody Blades effectively. \
|
||||
You can only create one at a time by this method."
|
||||
gain_text = "My new found desires drove me to greater and greater heights."
|
||||
next_knowledge = list(/datum/heretic_knowledge/limited_amount/flesh_ghoul)
|
||||
limit = 1
|
||||
@@ -88,57 +80,56 @@
|
||||
if(target.stat != DEAD)
|
||||
return
|
||||
|
||||
// Skeletons can't become husks, and monkeys are monkeys.
|
||||
if(!ishuman(target) || isskeleton(target) || ismonkey(target))
|
||||
target.balloon_alert(source, "invalid body!")
|
||||
return COMPONENT_BLOCK_CHARGE_USE
|
||||
|
||||
var/mob/living/carbon/human/human_target = target
|
||||
human_target.grab_ghost()
|
||||
if(!human_target.mind || !human_target.client)
|
||||
target.balloon_alert(source, "no soul!")
|
||||
return COMPONENT_BLOCK_CHARGE_USE
|
||||
if(HAS_TRAIT(human_target, TRAIT_HUSK))
|
||||
target.balloon_alert(source, "husked!")
|
||||
return COMPONENT_BLOCK_CHARGE_USE
|
||||
if(LAZYLEN(created_items) >= limit)
|
||||
target.balloon_alert(source, "at ghoul limit!")
|
||||
return COMPONENT_BLOCK_CHARGE_USE
|
||||
|
||||
LAZYADD(created_items, WEAKREF(human_target))
|
||||
log_game("[key_name(source)] created a ghoul, controlled by [key_name(human_target)].")
|
||||
message_admins("[ADMIN_LOOKUPFLW(source)] created a ghoul, [ADMIN_LOOKUPFLW(human_target)].")
|
||||
if(!IS_VALID_GHOUL_MOB(target))
|
||||
target.balloon_alert(source, "invalid body!")
|
||||
return COMPONENT_BLOCK_CHARGE_USE
|
||||
|
||||
RegisterSignal(human_target, COMSIG_LIVING_DEATH, .proc/remove_ghoul)
|
||||
human_target.revive(full_heal = TRUE, admin_revive = TRUE)
|
||||
human_target.setMaxHealth(GHOUL_MAX_HEALTH)
|
||||
human_target.health = GHOUL_MAX_HEALTH
|
||||
human_target.become_husk(MAGIC_TRAIT)
|
||||
human_target.apply_status_effect(/datum/status_effect/ghoul)
|
||||
human_target.faction |= FACTION_HERETIC
|
||||
// Get their ghost in here so we can raise them
|
||||
target.grab_ghost()
|
||||
|
||||
var/datum/antagonist/heretic_monster/heretic_monster = human_target.mind.add_antag_datum(/datum/antagonist/heretic_monster)
|
||||
heretic_monster.set_owner(source.mind)
|
||||
if(!target.mind || !target.client)
|
||||
target.balloon_alert(source, "no soul!")
|
||||
return COMPONENT_BLOCK_CHARGE_USE
|
||||
|
||||
/datum/heretic_knowledge/limited_amount/flesh_grasp/proc/remove_ghoul(mob/living/carbon/human/source)
|
||||
SIGNAL_HANDLER
|
||||
if(HAS_TRAIT(target, TRAIT_HUSK))
|
||||
target.balloon_alert(source, "husked!")
|
||||
return COMPONENT_BLOCK_CHARGE_USE
|
||||
|
||||
LAZYREMOVE(created_items, WEAKREF(source))
|
||||
source.setMaxHealth(initial(source.maxHealth))
|
||||
source.cure_husk(MAGIC_TRAIT)
|
||||
source.remove_status_effect(/datum/status_effect/ghoul)
|
||||
source.mind.remove_antag_datum(/datum/antagonist/heretic_monster)
|
||||
make_ghoul(source, target)
|
||||
|
||||
UnregisterSignal(source, COMSIG_LIVING_DEATH)
|
||||
/// Makes [victim] into a ghoul.
|
||||
/datum/heretic_knowledge/limited_amount/flesh_grasp/proc/make_ghoul(mob/living/user, mob/living/carbon/human/victim)
|
||||
log_game("[key_name(user)] created a ghoul, controlled by [key_name(victim)].")
|
||||
message_admins("[ADMIN_LOOKUPFLW(user)] created a ghoul, [ADMIN_LOOKUPFLW(victim)].")
|
||||
|
||||
victim.apply_status_effect(
|
||||
/datum/status_effect/ghoul,
|
||||
GHOUL_MAX_HEALTH,
|
||||
user.mind,
|
||||
CALLBACK(src, .proc/apply_to_ghoul),
|
||||
CALLBACK(src, .proc/remove_from_ghoul),
|
||||
)
|
||||
|
||||
/// Callback for the ghoul status effect - Tracking all of our ghouls
|
||||
/datum/heretic_knowledge/limited_amount/flesh_grasp/proc/apply_to_ghoul(mob/living/ghoul)
|
||||
LAZYADD(created_items, WEAKREF(ghoul))
|
||||
|
||||
/// Callback for the ghoul status effect - Tracking all of our ghouls
|
||||
/datum/heretic_knowledge/limited_amount/flesh_grasp/proc/remove_from_ghoul(mob/living/ghoul)
|
||||
LAZYREMOVE(created_items, WEAKREF(ghoul))
|
||||
|
||||
/datum/heretic_knowledge/limited_amount/flesh_ghoul
|
||||
name = "Imperfect Ritual"
|
||||
desc = "Allows you to transmute a corpse and a poppy to create a Voiceless Dead. \
|
||||
Voiceless Dead are mute ghouls and only have 50 health, but can use Bloody Blades effectively. \
|
||||
You can only create two at a time. "
|
||||
You can only create two at a time."
|
||||
gain_text = "I found notes of a dark ritual, unfinished... yet still, I pushed forward."
|
||||
next_knowledge = list(
|
||||
/datum/heretic_knowledge/flesh_mark,
|
||||
/datum/heretic_knowledge/mark/flesh_mark,
|
||||
/datum/heretic_knowledge/codex_cicatrix,
|
||||
/datum/heretic_knowledge/void_cloak,
|
||||
/datum/heretic_knowledge/medallion,
|
||||
@@ -152,16 +143,19 @@
|
||||
route = PATH_FLESH
|
||||
|
||||
/datum/heretic_knowledge/limited_amount/flesh_ghoul/recipe_snowflake_check(mob/living/user, list/atoms, list/selected_atoms, turf/loc)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
|
||||
for(var/mob/living/carbon/human/body in atoms)
|
||||
// Skeletons can't become husks, and monkeys because they're monkeys.
|
||||
if(body.stat != DEAD || isskeleton(body) || ismonkey(body) || HAS_TRAIT(body, TRAIT_HUSK))
|
||||
if(body.stat != DEAD || !IS_VALID_GHOUL_MOB(body) || HAS_TRAIT(body, TRAIT_HUSK))
|
||||
atoms -= body
|
||||
|
||||
if(!(locate(/mob/living/carbon/human) in atoms))
|
||||
loc.balloon_alert(user, "ritual failed, no valid body!")
|
||||
return FALSE
|
||||
|
||||
return ..()
|
||||
return TRUE
|
||||
|
||||
/datum/heretic_knowledge/limited_amount/flesh_ghoul/on_finished_recipe(mob/living/user, list/selected_atoms, turf/loc)
|
||||
var/mob/living/carbon/human/soon_to_be_ghoul = locate() in selected_atoms
|
||||
@@ -184,77 +178,43 @@
|
||||
soon_to_be_ghoul.ghostize(FALSE)
|
||||
soon_to_be_ghoul.key = chosen_candidate.key
|
||||
|
||||
ADD_TRAIT(soon_to_be_ghoul, TRAIT_MUTE, MAGIC_TRAIT)
|
||||
log_game("[key_name(user)] created a voiceless dead, controlled by [key_name(soon_to_be_ghoul)].")
|
||||
message_admins("[ADMIN_LOOKUPFLW(user)] created a voiceless dead, [ADMIN_LOOKUPFLW(soon_to_be_ghoul)].")
|
||||
soon_to_be_ghoul.revive(full_heal = TRUE, admin_revive = TRUE)
|
||||
soon_to_be_ghoul.setMaxHealth(MUTE_MAX_HEALTH)
|
||||
soon_to_be_ghoul.health = MUTE_MAX_HEALTH // Voiceless dead are much tougher than ghouls
|
||||
soon_to_be_ghoul.become_husk()
|
||||
soon_to_be_ghoul.faction |= FACTION_HERETIC
|
||||
soon_to_be_ghoul.apply_status_effect(/datum/status_effect/ghoul)
|
||||
|
||||
var/datum/antagonist/heretic_monster/heretic_monster = soon_to_be_ghoul.mind.add_antag_datum(/datum/antagonist/heretic_monster)
|
||||
heretic_monster.set_owner(user.mind)
|
||||
|
||||
selected_atoms -= soon_to_be_ghoul
|
||||
LAZYADD(created_items, WEAKREF(soon_to_be_ghoul))
|
||||
make_ghoul(user, soon_to_be_ghoul)
|
||||
|
||||
RegisterSignal(soon_to_be_ghoul, COMSIG_LIVING_DEATH, .proc/remove_ghoul)
|
||||
return TRUE
|
||||
/// Makes [victim] into a ghoul.
|
||||
/datum/heretic_knowledge/limited_amount/flesh_ghoul/proc/make_ghoul(mob/living/user, mob/living/carbon/human/victim)
|
||||
log_game("[key_name(user)] created a voiceless dead, controlled by [key_name(victim)].")
|
||||
message_admins("[ADMIN_LOOKUPFLW(user)] created a voiceless dead, [ADMIN_LOOKUPFLW(victim)].")
|
||||
|
||||
/datum/heretic_knowledge/limited_amount/flesh_ghoul/proc/remove_ghoul(mob/living/carbon/human/source)
|
||||
SIGNAL_HANDLER
|
||||
victim.apply_status_effect(
|
||||
/datum/status_effect/ghoul,
|
||||
MUTE_MAX_HEALTH,
|
||||
user.mind,
|
||||
CALLBACK(src, .proc/apply_to_ghoul),
|
||||
CALLBACK(src, .proc/remove_from_ghoul),
|
||||
)
|
||||
|
||||
LAZYREMOVE(created_items, WEAKREF(source))
|
||||
source.setMaxHealth(initial(source.maxHealth))
|
||||
source.remove_status_effect(/datum/status_effect/ghoul)
|
||||
source.mind.remove_antag_datum(/datum/antagonist/heretic_monster)
|
||||
/// Callback for the ghoul status effect - Tracks all of our ghouls and applies effects
|
||||
/datum/heretic_knowledge/limited_amount/flesh_ghoul/proc/apply_to_ghoul(mob/living/ghoul)
|
||||
LAZYADD(created_items, WEAKREF(ghoul))
|
||||
ADD_TRAIT(ghoul, TRAIT_MUTE, MAGIC_TRAIT)
|
||||
|
||||
UnregisterSignal(source, COMSIG_LIVING_DEATH)
|
||||
/// Callback for the ghoul status effect - Tracks all of our ghouls and applies effects
|
||||
/datum/heretic_knowledge/limited_amount/flesh_ghoul/proc/remove_from_ghoul(mob/living/ghoul)
|
||||
LAZYREMOVE(created_items, WEAKREF(ghoul))
|
||||
REMOVE_TRAIT(ghoul, TRAIT_MUTE, MAGIC_TRAIT)
|
||||
|
||||
/datum/heretic_knowledge/flesh_mark
|
||||
/datum/heretic_knowledge/mark/flesh_mark
|
||||
name = "Mark of Flesh"
|
||||
desc = "Your Mansus Grasp now applies the Mark of Flesh. The mark is triggered from an attack with your Bloody Blade. \
|
||||
When triggered, the victim begins to bleed significantly."
|
||||
gain_text = "That's when I saw them, the marked ones. They were out of reach. They screamed, and screamed."
|
||||
next_knowledge = list(/datum/heretic_knowledge/knowledge_ritual/flesh)
|
||||
banned_knowledge = list(
|
||||
/datum/heretic_knowledge/rust_mark,
|
||||
/datum/heretic_knowledge/ash_mark,
|
||||
/datum/heretic_knowledge/void_mark,
|
||||
)
|
||||
cost = 2
|
||||
route = PATH_FLESH
|
||||
|
||||
/datum/heretic_knowledge/flesh_mark/on_gain(mob/user)
|
||||
RegisterSignal(user, COMSIG_HERETIC_MANSUS_GRASP_ATTACK, .proc/on_mansus_grasp)
|
||||
RegisterSignal(user, COMSIG_HERETIC_BLADE_ATTACK, .proc/on_eldritch_blade)
|
||||
|
||||
/datum/heretic_knowledge/flesh_mark/on_lose(mob/user)
|
||||
UnregisterSignal(user, list(COMSIG_HERETIC_MANSUS_GRASP_ATTACK, COMSIG_HERETIC_BLADE_ATTACK))
|
||||
|
||||
/datum/heretic_knowledge/flesh_mark/proc/on_mansus_grasp(mob/living/source, mob/living/target)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
target.apply_status_effect(/datum/status_effect/eldritch/flesh)
|
||||
|
||||
/datum/heretic_knowledge/flesh_mark/proc/on_eldritch_blade(mob/living/user, mob/living/target)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
var/datum/status_effect/eldritch/mark = target.has_status_effect(/datum/status_effect/eldritch)
|
||||
if(!istype(mark))
|
||||
return
|
||||
|
||||
mark.on_effect()
|
||||
mark_type = /datum/status_effect/eldritch/flesh
|
||||
|
||||
/datum/heretic_knowledge/knowledge_ritual/flesh
|
||||
next_knowledge = list(/datum/heretic_knowledge/summon/raw_prophet)
|
||||
banned_knowledge = list(
|
||||
/datum/heretic_knowledge/knowledge_ritual/ash,
|
||||
/datum/heretic_knowledge/knowledge_ritual/void,
|
||||
/datum/heretic_knowledge/knowledge_ritual/rust,
|
||||
)
|
||||
route = PATH_FLESH
|
||||
|
||||
/datum/heretic_knowledge/summon/raw_prophet
|
||||
@@ -265,9 +225,9 @@
|
||||
gain_text = "I could not continue alone. I was able to summon The Uncanny Man to help me see more. \
|
||||
The screams... once constant, now silenced by their wretched appearance. Nothing was out of reach."
|
||||
next_knowledge = list(
|
||||
/datum/heretic_knowledge/flesh_blade_upgrade,
|
||||
/datum/heretic_knowledge/blade_upgrade/flesh,
|
||||
/datum/heretic_knowledge/reroll_targets,
|
||||
/datum/heretic_knowledge/rune_carver,
|
||||
/datum/heretic_knowledge/spell/blood_siphon,
|
||||
/datum/heretic_knowledge/curse/paralysis,
|
||||
)
|
||||
required_atoms = list(
|
||||
@@ -279,36 +239,22 @@
|
||||
cost = 1
|
||||
route = PATH_FLESH
|
||||
|
||||
/datum/heretic_knowledge/flesh_blade_upgrade
|
||||
/datum/heretic_knowledge/blade_upgrade/flesh
|
||||
name = "Bleeding Steel"
|
||||
desc = "Your Bloody Blade now causes enemies to bleed heavily on attack."
|
||||
gain_text = "The Uncanny Man was not alone. They led me to the Marshal. \
|
||||
I finally began to understand. And then, blood rained from the heavens."
|
||||
next_knowledge = list(/datum/heretic_knowledge/summon/stalker)
|
||||
banned_knowledge = list(
|
||||
/datum/heretic_knowledge/ash_blade_upgrade,
|
||||
/datum/heretic_knowledge/rust_blade_upgrade,
|
||||
/datum/heretic_knowledge/void_blade_upgrade,
|
||||
)
|
||||
cost = 2
|
||||
route = PATH_FLESH
|
||||
|
||||
/datum/heretic_knowledge/flesh_blade_upgrade/on_gain(mob/user)
|
||||
RegisterSignal(user, COMSIG_HERETIC_BLADE_ATTACK, .proc/on_eldritch_blade)
|
||||
|
||||
/datum/heretic_knowledge/flesh_blade_upgrade/on_lose(mob/user)
|
||||
UnregisterSignal(user, COMSIG_HERETIC_BLADE_ATTACK)
|
||||
|
||||
/datum/heretic_knowledge/flesh_blade_upgrade/proc/on_eldritch_blade(mob/living/user, mob/living/target)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!iscarbon(target) || user == target)
|
||||
/datum/heretic_knowledge/blade_upgrade/flesh/do_melee_effects(mob/living/source, mob/living/target, obj/item/melee/sickly_blade/blade)
|
||||
if(!iscarbon(target) || source == target)
|
||||
return
|
||||
|
||||
var/mob/living/carbon/carbon_target = target
|
||||
var/obj/item/bodypart/bodypart = pick(carbon_target.bodyparts)
|
||||
var/datum/wound/slash/severe/crit_wound = new()
|
||||
crit_wound.apply_wound(bodypart, attack_direction = get_dir(user, target))
|
||||
crit_wound.apply_wound(bodypart, attack_direction = get_dir(source, target))
|
||||
|
||||
/datum/heretic_knowledge/summon/stalker
|
||||
name = "Lonely Ritual"
|
||||
@@ -319,7 +265,7 @@
|
||||
next_knowledge = list(
|
||||
/datum/heretic_knowledge/final/flesh_final,
|
||||
/datum/heretic_knowledge/summon/ashy,
|
||||
/datum/heretic_knowledge/spell/blood_siphon,
|
||||
/datum/heretic_knowledge/spell/cleave,
|
||||
)
|
||||
required_atoms = list(
|
||||
/obj/item/organ/tail = 1,
|
||||
@@ -359,7 +305,7 @@
|
||||
grasp_ghoul.limit *= 3
|
||||
var/datum/heretic_knowledge/limited_amount/flesh_ghoul/ritual_ghoul = heretic_datum.get_knowledge(/datum/heretic_knowledge/limited_amount/flesh_ghoul)
|
||||
ritual_ghoul.limit *= 3
|
||||
var/datum/heretic_knowledge/limited_amount/base_flesh/blade_ritual = heretic_datum.get_knowledge(/datum/heretic_knowledge/limited_amount/base_flesh)
|
||||
var/datum/heretic_knowledge/limited_amount/starting/base_flesh/blade_ritual = heretic_datum.get_knowledge(/datum/heretic_knowledge/limited_amount/starting/base_flesh)
|
||||
blade_ritual.limit = 999
|
||||
|
||||
#undef GHOUL_MAX_HEALTH
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
* Armorer's Ritual
|
||||
*
|
||||
* Mark of Rust
|
||||
* Ritual of Knowledge
|
||||
* Aggressive Spread
|
||||
* > Sidepaths:
|
||||
* Curse of Corrosion
|
||||
@@ -24,32 +25,21 @@
|
||||
*
|
||||
* Rustbringer's Oath
|
||||
*/
|
||||
/datum/heretic_knowledge/limited_amount/base_rust
|
||||
/datum/heretic_knowledge/limited_amount/starting/base_rust
|
||||
name = "Blacksmith's Tale"
|
||||
desc = "Opens up the Path of Rust to you. \
|
||||
Allows you to transmute a knife with any trash item into a Rusty Blade. \
|
||||
You can only create two at a time."
|
||||
gain_text = "\"Let me tell you a story\", said the Blacksmith, as he gazed deep into his rusty blade."
|
||||
next_knowledge = list(/datum/heretic_knowledge/rust_fist)
|
||||
banned_knowledge = list(
|
||||
/datum/heretic_knowledge/limited_amount/base_ash,
|
||||
/datum/heretic_knowledge/limited_amount/base_flesh,
|
||||
/datum/heretic_knowledge/final/ash_final,
|
||||
/datum/heretic_knowledge/final/flesh_final,
|
||||
/datum/heretic_knowledge/final/void_final,
|
||||
/datum/heretic_knowledge/limited_amount/base_void,
|
||||
)
|
||||
required_atoms = list(
|
||||
/obj/item/knife = 1,
|
||||
/obj/item/trash = 1,
|
||||
)
|
||||
result_atoms = list(/obj/item/melee/sickly_blade/rust)
|
||||
limit = 2
|
||||
cost = 1
|
||||
priority = MAX_KNOWLEDGE_PRIORITY - 5
|
||||
route = PATH_RUST
|
||||
|
||||
/datum/heretic_knowledge/limited_amount/base_rust/on_research(mob/user)
|
||||
/datum/heretic_knowledge/limited_amount/starting/base_rust/on_research(mob/user)
|
||||
. = ..()
|
||||
var/datum/antagonist/heretic/our_heretic = IS_HERETIC(user)
|
||||
our_heretic.heretic_path = route
|
||||
@@ -89,7 +79,7 @@
|
||||
desc = "Grants you passive healing and stun resistance while standing over rust."
|
||||
gain_text = "The speed was unparalleled, the strength unnatural. The Blacksmith was smiling."
|
||||
next_knowledge = list(
|
||||
/datum/heretic_knowledge/rust_mark,
|
||||
/datum/heretic_knowledge/mark/rust_mark,
|
||||
/datum/heretic_knowledge/codex_cicatrix,
|
||||
/datum/heretic_knowledge/armor,
|
||||
/datum/heretic_knowledge/essence,
|
||||
@@ -139,48 +129,17 @@
|
||||
source.adjustStaminaLoss(-2)
|
||||
source.AdjustAllImmobility(-5)
|
||||
|
||||
/datum/heretic_knowledge/rust_mark
|
||||
/datum/heretic_knowledge/mark/rust_mark
|
||||
name = "Mark of Rust"
|
||||
desc = "Your Mansus Grasp now applies the Mark of Rust. The mark is triggered from an attack with your Rusty Blade. \
|
||||
When triggered, the victim's organs and equipment will have a 75% chance to sustain damage and may be destroyed."
|
||||
gain_text = "The Blacksmith looks away. To a place lost long ago. \"Rusted Hills help those in dire need... at a cost.\""
|
||||
next_knowledge = list(/datum/heretic_knowledge/knowledge_ritual/rust)
|
||||
banned_knowledge = list(
|
||||
/datum/heretic_knowledge/ash_mark,
|
||||
/datum/heretic_knowledge/flesh_mark,
|
||||
/datum/heretic_knowledge/void_mark,
|
||||
)
|
||||
cost = 2
|
||||
route = PATH_RUST
|
||||
|
||||
/datum/heretic_knowledge/rust_mark/on_gain(mob/user)
|
||||
RegisterSignal(user, COMSIG_HERETIC_MANSUS_GRASP_ATTACK, .proc/on_mansus_grasp)
|
||||
RegisterSignal(user, COMSIG_HERETIC_BLADE_ATTACK, .proc/on_eldritch_blade)
|
||||
|
||||
/datum/heretic_knowledge/rust_mark/on_lose(mob/user)
|
||||
UnregisterSignal(user, list(COMSIG_HERETIC_MANSUS_GRASP_ATTACK, COMSIG_HERETIC_BLADE_ATTACK))
|
||||
|
||||
/datum/heretic_knowledge/rust_mark/proc/on_mansus_grasp(mob/living/source, mob/living/target)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
target.apply_status_effect(/datum/status_effect/eldritch/rust)
|
||||
|
||||
/datum/heretic_knowledge/rust_mark/proc/on_eldritch_blade(mob/living/user, mob/living/target)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
var/datum/status_effect/eldritch/mark = target.has_status_effect(/datum/status_effect/eldritch)
|
||||
if(!istype(mark))
|
||||
return
|
||||
|
||||
mark.on_effect()
|
||||
mark_type = /datum/status_effect/eldritch/rust
|
||||
|
||||
/datum/heretic_knowledge/knowledge_ritual/rust
|
||||
next_knowledge = list(/datum/heretic_knowledge/spell/area_conversion)
|
||||
banned_knowledge = list(
|
||||
/datum/heretic_knowledge/knowledge_ritual/ash,
|
||||
/datum/heretic_knowledge/knowledge_ritual/void,
|
||||
/datum/heretic_knowledge/knowledge_ritual/flesh,
|
||||
)
|
||||
route = PATH_RUST
|
||||
|
||||
/datum/heretic_knowledge/spell/area_conversion
|
||||
@@ -189,7 +148,7 @@
|
||||
Already rusted surfaces are destroyed."
|
||||
gain_text = "All wise men know well not to visit the Rusted Hills... Yet the Blacksmith's tale was inspiring."
|
||||
next_knowledge = list(
|
||||
/datum/heretic_knowledge/rust_blade_upgrade,
|
||||
/datum/heretic_knowledge/blade_upgrade/rust,
|
||||
/datum/heretic_knowledge/reroll_targets,
|
||||
/datum/heretic_knowledge/curse/corrosion,
|
||||
/datum/heretic_knowledge/crucible,
|
||||
@@ -198,29 +157,15 @@
|
||||
cost = 1
|
||||
route = PATH_RUST
|
||||
|
||||
/datum/heretic_knowledge/rust_blade_upgrade
|
||||
/datum/heretic_knowledge/blade_upgrade/rust
|
||||
name = "Toxic Blade"
|
||||
desc = "Your Rusty Blade now poisons enemies on attack."
|
||||
gain_text = "The Blacksmith hands you their blade. \"The Blade will guide you through the flesh, should you let it.\" \
|
||||
The heavy rust weights it down. You stare deeply into it. The Rusted Hills call for you, now."
|
||||
next_knowledge = list(/datum/heretic_knowledge/spell/entropic_plume)
|
||||
banned_knowledge = list(
|
||||
/datum/heretic_knowledge/ash_blade_upgrade,
|
||||
/datum/heretic_knowledge/flesh_blade_upgrade,
|
||||
/datum/heretic_knowledge/void_blade_upgrade,
|
||||
)
|
||||
cost = 2
|
||||
route = PATH_RUST
|
||||
|
||||
/datum/heretic_knowledge/rust_blade_upgrade/on_gain(mob/user)
|
||||
RegisterSignal(user, COMSIG_HERETIC_BLADE_ATTACK, .proc/on_eldritch_blade)
|
||||
|
||||
/datum/heretic_knowledge/rust_blade_upgrade/on_lose(mob/user)
|
||||
UnregisterSignal(user, COMSIG_HERETIC_BLADE_ATTACK)
|
||||
|
||||
/datum/heretic_knowledge/rust_blade_upgrade/proc/on_eldritch_blade(mob/living/user, mob/living/target)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
/datum/heretic_knowledge/blade_upgrade/rust/do_melee_effects(mob/living/source, mob/living/target, obj/item/melee/sickly_blade/blade)
|
||||
// No user == target check here, cause it's technically good for the heretic?
|
||||
target.reagents?.add_reagent(/datum/reagent/eldritch, 5)
|
||||
|
||||
@@ -232,7 +177,7 @@
|
||||
gain_text = "The corrosion was unstoppable. The rust was unpleasable. \
|
||||
The Blacksmith was gone, and you hold their blade. Champions of hope, the Rustbringer is nigh!"
|
||||
next_knowledge = list(
|
||||
/datum/heretic_knowledge/spell/cleave,
|
||||
/datum/heretic_knowledge/rifle,
|
||||
/datum/heretic_knowledge/final/rust_final,
|
||||
/datum/heretic_knowledge/summon/rusty,
|
||||
)
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
// Sidepaths for knowledge between Rust and Blade.
|
||||
/datum/heretic_knowledge/armor
|
||||
name = "Armorer's Ritual"
|
||||
desc = "Allows you to transmute a table and a gas mask to create Eldritch Armor. \
|
||||
Eldritch Armor provides great protection while also acting as a focus when hooded."
|
||||
gain_text = "The Rusted Hills welcomed the Blacksmith in their generosity. And the Blacksmith \
|
||||
returned their generosity in kind."
|
||||
next_knowledge = list(
|
||||
/datum/heretic_knowledge/rust_regen,
|
||||
/datum/heretic_knowledge/blade_dance,
|
||||
)
|
||||
required_atoms = list(
|
||||
/obj/structure/table = 1,
|
||||
/obj/item/clothing/mask/gas = 1,
|
||||
)
|
||||
result_atoms = list(/obj/item/clothing/suit/hooded/cultrobes/eldritch)
|
||||
cost = 1
|
||||
route = PATH_SIDE
|
||||
|
||||
/datum/heretic_knowledge/crucible
|
||||
name = "Mawed Crucible"
|
||||
desc = "Allows you to transmute a portable water tank and a table to create a Mawed Crucible. \
|
||||
The Mawed Crubile can brew powerful potions for combat and utility, but must be fed bodyparts and organs between uses."
|
||||
gain_text = "This is pure agony. I wasn't able to summon the figure of the Aristocrat, \
|
||||
but with the Priest's attention I stumbled upon a different recipe..."
|
||||
next_knowledge = list(
|
||||
/datum/heretic_knowledge/duel_stance,
|
||||
/datum/heretic_knowledge/spell/area_conversion,
|
||||
)
|
||||
required_atoms = list(
|
||||
/obj/structure/reagent_dispensers/watertank = 1,
|
||||
/obj/structure/table = 1,
|
||||
)
|
||||
result_atoms = list(/obj/structure/destructible/eldritch_crucible)
|
||||
cost = 1
|
||||
route = PATH_SIDE
|
||||
|
||||
/datum/heretic_knowledge/rifle
|
||||
name = "Lionhunter's Rifle"
|
||||
desc = "Allows you to transmute any ballistic weapon, such as a pipegun, with hide \
|
||||
from any animal, a plank of wood, and a camera to create the Lionhunter's rifle. \
|
||||
The Lionhunter's Rifle is a long ranged ballistic weapon with three shots. \
|
||||
These shots function as normal, albiet weak high caliber mutitions when fired from \
|
||||
close range or at inanimate objects. You can aim the rifle at distant foes, \
|
||||
causing the shot to deal massively increased damage and hone in on them."
|
||||
gain_text = "I met an old man in an anique shop who wielded a very unusual weapon. \
|
||||
I could not purchase it at the time, but they showed me how they made it ages ago."
|
||||
next_knowledge = list(
|
||||
/datum/heretic_knowledge/spell/furious_steel,
|
||||
/datum/heretic_knowledge/spell/entropic_plume,
|
||||
/datum/heretic_knowledge/rifle_ammo,
|
||||
)
|
||||
required_atoms = list(
|
||||
/obj/item/gun/ballistic = 1,
|
||||
/obj/item/stack/sheet/animalhide = 1,
|
||||
/obj/item/stack/sheet/mineral/wood = 1,
|
||||
/obj/item/camera = 1,
|
||||
)
|
||||
result_atoms = list(/obj/item/gun/ballistic/rifle/lionhunter)
|
||||
cost = 1
|
||||
route = PATH_SIDE
|
||||
|
||||
/datum/heretic_knowledge/rifle_ammo
|
||||
name = "Lionhunter Rifle Ammunition"
|
||||
desc = "Allows you to transmute 3 ballistic ammo casings (used or unused) of any caliber, \
|
||||
including shotgun shot, with any animal hide to create an extra clip of ammunition for the Lionhunter Rifle."
|
||||
gain_text = "The weapon came with three rough iron balls, intended to be used as ammunition. \
|
||||
They were very effective, for simple iron, but used up quickly. I soon ran out. \
|
||||
No replacement munitions worked in their stead. It was peculiar in what it wanted."
|
||||
required_atoms = list(
|
||||
/obj/item/stack/sheet/animalhide = 1,
|
||||
/obj/item/ammo_casing = 3,
|
||||
)
|
||||
cost = 1
|
||||
route = PATH_SIDE
|
||||
/// A list of calibers we will accept for "ballistic ammo casings".
|
||||
var/static/list/acceptable_calibers = list(
|
||||
CALIBER_10MM,
|
||||
CALIBER_357,
|
||||
CALIBER_38,
|
||||
CALIBER_45,
|
||||
CALIBER_46X30MM,
|
||||
CALIBER_50,
|
||||
CALIBER_712X82MM,
|
||||
CALIBER_75,
|
||||
CALIBER_9MM,
|
||||
CALIBER_A556,
|
||||
CALIBER_A762,
|
||||
CALIBER_N762,
|
||||
CALIBER_SHOTGUN,
|
||||
)
|
||||
|
||||
/datum/heretic_knowledge/rifle_ammo/recipe_snowflake_check(mob/living/user, list/atoms, list/selected_atoms, turf/loc)
|
||||
for(var/obj/item/ammo_casing/casing in atoms)
|
||||
if(casing.caliber in acceptable_calibers)
|
||||
continue
|
||||
|
||||
// Remove any casings not in in the acceptable_calibers list from atoms
|
||||
atoms -= casing
|
||||
|
||||
// We removed any invalid casings from the atoms list,
|
||||
// return to allow the ritual to fill out selected atoms with the new list
|
||||
return TRUE
|
||||
@@ -18,35 +18,29 @@
|
||||
cost = 1
|
||||
route = PATH_SIDE
|
||||
|
||||
/datum/heretic_knowledge/rune_carver
|
||||
name = "Carving Knife"
|
||||
desc = "Allows you to transmute a knife, a shard of glass, and a piece of paper to create a Carving Knife. \
|
||||
The Carving Knife allows you to etch difficult to see traps that trigger on heathens who walk overhead. \
|
||||
Also makes for a handy throwing weapon."
|
||||
gain_text = "Etched, carved... eternal. There is power hidden in everything. I can unveil it! \
|
||||
I can carve the monolith to reveal the chains!"
|
||||
next_knowledge = list(
|
||||
/datum/heretic_knowledge/spell/void_phase,
|
||||
/datum/heretic_knowledge/summon/raw_prophet,
|
||||
)
|
||||
required_atoms = list(
|
||||
/obj/item/knife = 1,
|
||||
/obj/item/shard = 1,
|
||||
/obj/item/paper = 1,
|
||||
)
|
||||
result_atoms = list(/obj/item/melee/rune_carver)
|
||||
cost = 1
|
||||
route = PATH_SIDE
|
||||
|
||||
/datum/heretic_knowledge/spell/blood_siphon
|
||||
name = "Blood Siphon"
|
||||
desc = "Grants you Blood Siphon, a spell that drains a victim of blood and health, transferring it to you. \
|
||||
Also has a chance to transfer wounds from you to the victim."
|
||||
gain_text = "\"No matter the man, we bleed all the same.\" That's what the Marshal told me."
|
||||
next_knowledge = list(
|
||||
/datum/heretic_knowledge/summon/stalker,
|
||||
/datum/heretic_knowledge/spell/voidpull,
|
||||
/datum/heretic_knowledge/spell/void_phase,
|
||||
/datum/heretic_knowledge/summon/raw_prophet,
|
||||
)
|
||||
spell_to_add = /obj/effect/proc_holder/spell/pointed/blood_siphon
|
||||
cost = 1
|
||||
route = PATH_SIDE
|
||||
|
||||
/datum/heretic_knowledge/spell/cleave
|
||||
name = "Blood Cleave"
|
||||
desc = "Grants you Cleave, an area-of-effect targeted spell \
|
||||
that causes heavy bleeding and blood loss to anyone afflicted."
|
||||
gain_text = "At first I didn't understand these instruments of war, but the Priest \
|
||||
told me to use them regardless. Soon, he said, I would know them well."
|
||||
next_knowledge = list(
|
||||
/datum/heretic_knowledge/summon/stalker,
|
||||
/datum/heretic_knowledge/spell/void_pull,
|
||||
)
|
||||
spell_to_add = /obj/effect/proc_holder/spell/pointed/cleave
|
||||
cost = 1
|
||||
route = PATH_SIDE
|
||||
|
||||
@@ -46,16 +46,29 @@
|
||||
chosen_mob.remove_status_effect(/datum/status_effect/corrosion_curse)
|
||||
to_chat(chosen_mob, span_notice("You start to feel better."))
|
||||
|
||||
/datum/heretic_knowledge/spell/cleave
|
||||
name = "Blood Cleave"
|
||||
desc = "Grants you Cleave, an area-of-effect targeted spell \
|
||||
that causes heavy bleeding and blood loss to anyone afflicted."
|
||||
gain_text = "At first I didn't understand these instruments of war, but the Priest \
|
||||
told me to use them regardless. Soon, he said, I would know them well."
|
||||
/datum/heretic_knowledge/summon/rusty
|
||||
name = "Rusted Ritual"
|
||||
desc = "Allows you to transmute a pool of vomit, a book, and a head into a Rust Walker. \
|
||||
Rust Walkers excel at spreading rust and are moderately strong in combat."
|
||||
gain_text = "I combined my principle of hunger with my desire for corruption. The Marshal knew my name, and the Rusted Hills echoed out."
|
||||
next_knowledge = list(
|
||||
/datum/heretic_knowledge/spell/entropic_plume,
|
||||
/datum/heretic_knowledge/spell/flame_birth,
|
||||
)
|
||||
spell_to_add = /obj/effect/proc_holder/spell/pointed/cleave
|
||||
required_atoms = list(
|
||||
/obj/effect/decal/cleanable/vomit = 1,
|
||||
/obj/item/book = 1,
|
||||
/obj/item/bodypart/head = 1,
|
||||
)
|
||||
mob_to_summon = /mob/living/simple_animal/hostile/heretic_summon/rust_spirit
|
||||
cost = 1
|
||||
route = PATH_SIDE
|
||||
|
||||
/datum/heretic_knowledge/summon/rusty/cleanup_atoms(list/selected_atoms)
|
||||
var/obj/item/bodypart/head/ritual_head = locate() in selected_atoms
|
||||
if(!ritual_head)
|
||||
CRASH("[type] required a head bodypart, yet did not have one in selected_atoms when it reached cleanup_atoms.")
|
||||
|
||||
// Spill out any brains or stuff before we delete it.
|
||||
ritual_head.drop_organs()
|
||||
return ..()
|
||||
|
||||
@@ -0,0 +1,174 @@
|
||||
// Sidepaths for knowledge between Void and Blade.
|
||||
|
||||
/// The max health given to Shattered Risen
|
||||
#define RISEN_MAX_HEALTH 125
|
||||
|
||||
/datum/heretic_knowledge/limited_amount/risen_corpse
|
||||
name = "Shattered Ritual"
|
||||
desc = "Allows you to transmute a corpse with a soul, a pair of latex or nitrile gloves, and \
|
||||
and any exosuit clothing (such as armor) to create a Shattered Risen. \
|
||||
Shattered Risen are strong ghouls that have 125 health, but cannot hold items, \
|
||||
instead having two brutal weapons for hands. You can only create one at a time."
|
||||
gain_text = "I witnessed a cold, rending force drag this corpse back to near-life. \
|
||||
When it moves, it crunches like broken glass. Its hands are no longer recognizable as human - \
|
||||
each clenched fist contains a brutal nest of sharp bone-shards instead."
|
||||
next_knowledge = list(
|
||||
/datum/heretic_knowledge/cold_snap,
|
||||
/datum/heretic_knowledge/blade_dance,
|
||||
)
|
||||
required_atoms = list(
|
||||
/obj/item/clothing/suit = 1,
|
||||
/obj/item/clothing/gloves/color/latex = 1,
|
||||
)
|
||||
limit = 1
|
||||
cost = 1
|
||||
route = PATH_SIDE
|
||||
|
||||
/datum/heretic_knowledge/limited_amount/risen_corpse/recipe_snowflake_check(mob/living/user, list/atoms, list/selected_atoms, turf/loc)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
|
||||
for(var/mob/living/carbon/human/body in atoms)
|
||||
if(body.stat != DEAD || !IS_VALID_GHOUL_MOB(body) || HAS_TRAIT(body, TRAIT_HUSK))
|
||||
continue
|
||||
|
||||
if(body.mind?.get_ghost(ghosts_with_clients = TRUE))
|
||||
selected_atoms += body
|
||||
return TRUE
|
||||
|
||||
loc.balloon_alert(user, "ritual failed, no valid body!")
|
||||
return FALSE
|
||||
|
||||
/datum/heretic_knowledge/limited_amount/risen_corpse/on_finished_recipe(mob/living/user, list/selected_atoms, turf/loc)
|
||||
var/mob/living/carbon/human/soon_to_be_ghoul = locate() in selected_atoms
|
||||
if(QDELETED(soon_to_be_ghoul)) // No body? No ritual
|
||||
stack_trace("[type] reached on_finished_recipe without a human in selected_atoms to make a ghoul out of.")
|
||||
loc.balloon_alert(user, "ritual failed, no valid body!")
|
||||
return FALSE
|
||||
|
||||
soon_to_be_ghoul.grab_ghost()
|
||||
if(!soon_to_be_ghoul.mind || !soon_to_be_ghoul.client)
|
||||
stack_trace("[type] reached on_finished_recipe without a minded / cliented human in selected_atoms to make a ghoul out of.")
|
||||
loc.balloon_alert(user, "ritual failed, no valid body!")
|
||||
return FALSE
|
||||
|
||||
selected_atoms -= soon_to_be_ghoul
|
||||
make_risen(user, soon_to_be_ghoul)
|
||||
|
||||
/// Make [victim] into a shattered risen ghoul.
|
||||
/datum/heretic_knowledge/limited_amount/risen_corpse/proc/make_risen(mob/living/user, mob/living/carbon/human/victim)
|
||||
log_game("[key_name(user)] created a shattered risen out of [key_name(victim)].")
|
||||
message_admins("[ADMIN_LOOKUPFLW(user)] shattered risen out of [ADMIN_LOOKUPFLW(victim)].")
|
||||
|
||||
victim.apply_status_effect(
|
||||
/datum/status_effect/ghoul,
|
||||
RISEN_MAX_HEALTH,
|
||||
user.mind,
|
||||
CALLBACK(src, .proc/apply_to_risen),
|
||||
CALLBACK(src, .proc/remove_from_risen),
|
||||
)
|
||||
|
||||
/// Callback for the ghoul status effect - what effects are applied to the ghoul.
|
||||
/datum/heretic_knowledge/limited_amount/risen_corpse/proc/apply_to_risen(mob/living/risen)
|
||||
LAZYADD(created_items, WEAKREF(risen))
|
||||
|
||||
for(var/obj/item/held as anything in risen.held_items)
|
||||
if(istype(held))
|
||||
risen.dropItemToGround(held)
|
||||
|
||||
risen.put_in_hands(new /obj/item/risen_hand(), del_on_fail = TRUE)
|
||||
|
||||
/// Callback for the ghoul status effect - cleaning up effects after the ghoul status is removed.
|
||||
/datum/heretic_knowledge/limited_amount/risen_corpse/proc/remove_from_risen(mob/living/risen)
|
||||
LAZYREMOVE(created_items, WEAKREF(risen))
|
||||
|
||||
for(var/obj/item/risen_hand/hand in risen.held_items)
|
||||
qdel(hand)
|
||||
|
||||
#undef RISEN_MAX_HEALTH
|
||||
|
||||
/// The "hand" "weapon" used by shattered risen
|
||||
/obj/item/risen_hand
|
||||
name = "bone-shards"
|
||||
desc = "What once appeared to be a normal human fist, now holds a maulled nest of sharp bone-shards."
|
||||
icon = 'icons/effects/blood.dmi'
|
||||
base_icon_state = "bloodhand"
|
||||
color = "#001aff"
|
||||
item_flags = ABSTRACT | DROPDEL | HAND_ITEM
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
hitsound = SFX_SHATTER
|
||||
force = 16
|
||||
sharpness = SHARP_EDGED
|
||||
wound_bonus = -30
|
||||
bare_wound_bonus = 15
|
||||
|
||||
/obj/item/risen_hand/Initialize(mapload)
|
||||
. = ..()
|
||||
ADD_TRAIT(src, TRAIT_NODROP, HAND_REPLACEMENT_TRAIT)
|
||||
|
||||
/obj/item/risen_hand/visual_equipped(mob/user, slot)
|
||||
. = ..()
|
||||
|
||||
// Even hand indexes are right hands,
|
||||
// Odd hand indexes are left hand
|
||||
// ...But also, we swap it intentionally here,
|
||||
// so right icon is shown on the left (Because hands)
|
||||
if(user.get_held_index_of_item(src) % 2 == 1)
|
||||
icon_state = "[base_icon_state]_right"
|
||||
else
|
||||
icon_state = "[base_icon_state]_left"
|
||||
|
||||
/obj/item/risen_hand/pre_attack(atom/hit, mob/living/user, params)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
// If it's a structure or machine, we get a damage bonus (allowing us to break down doors)
|
||||
if(isstructure(hit) || ismachinery(hit))
|
||||
force = initial(force) * 1.5
|
||||
|
||||
// If it's another other item make sure we're at normal force
|
||||
else
|
||||
force = initial(force)
|
||||
|
||||
/datum/heretic_knowledge/rune_carver
|
||||
name = "Carving Knife"
|
||||
desc = "Allows you to transmute a knife, a shard of glass, and a piece of paper to create a Carving Knife. \
|
||||
The Carving Knife allows you to etch difficult to see traps that trigger on heathens who walk overhead. \
|
||||
Also makes for a handy throwing weapon."
|
||||
gain_text = "Etched, carved... eternal. There is power hidden in everything. I can unveil it! \
|
||||
I can carve the monolith to reveal the chains!"
|
||||
next_knowledge = list(
|
||||
/datum/heretic_knowledge/spell/void_phase,
|
||||
/datum/heretic_knowledge/duel_stance,
|
||||
)
|
||||
required_atoms = list(
|
||||
/obj/item/knife = 1,
|
||||
/obj/item/shard = 1,
|
||||
/obj/item/paper = 1,
|
||||
)
|
||||
result_atoms = list(/obj/item/melee/rune_carver)
|
||||
cost = 1
|
||||
route = PATH_SIDE
|
||||
|
||||
/datum/heretic_knowledge/summon/maid_in_mirror
|
||||
name = "Maid in the Mirror"
|
||||
desc = "Allows you to transmute five sheets of titanium, a flash, a suit of armor, and a pair of lungs \
|
||||
to create a Maid in the Mirror. Maid in the Mirrors are decent combatants that can become incorporeal by \
|
||||
phasing in and out of the mirror realm, serving as powerful scouts and ambushers."
|
||||
gain_text = "Within each reflection, lies a gateway into an unimaginable world of colors never seen and \
|
||||
people never met. The ascent is glass, and the walls are knives. Each step is blood, if you do not have a guide."
|
||||
next_knowledge = list(
|
||||
/datum/heretic_knowledge/spell/void_pull,
|
||||
/datum/heretic_knowledge/spell/furious_steel,
|
||||
)
|
||||
required_atoms = list(
|
||||
/obj/item/stack/sheet/mineral/titanium = 5,
|
||||
/obj/item/clothing/suit/armor = 1,
|
||||
/obj/item/assembly/flash = 1,
|
||||
/obj/item/organ/lungs = 1,
|
||||
)
|
||||
cost = 1
|
||||
route = PATH_SIDE
|
||||
mob_to_summon = /mob/living/simple_animal/hostile/heretic_summon/maid_in_the_mirror
|
||||
@@ -1,64 +0,0 @@
|
||||
// Sidepaths for knowledge between Void and Rust.
|
||||
|
||||
/datum/heretic_knowledge/armor
|
||||
name = "Armorer's Ritual"
|
||||
desc = "Allows you to transmute a table and a gas mask to create Eldritch Armor. \
|
||||
Eldritch Armor provides great protection while also acting as a focus when hooded."
|
||||
gain_text = "The Rusted Hills welcomed the Blacksmith in their generosity. And the Blacksmith \
|
||||
returned their generosity in kind."
|
||||
next_knowledge = list(
|
||||
/datum/heretic_knowledge/rust_regen,
|
||||
/datum/heretic_knowledge/cold_snap,
|
||||
)
|
||||
required_atoms = list(
|
||||
/obj/structure/table = 1,
|
||||
/obj/item/clothing/mask/gas = 1,
|
||||
)
|
||||
result_atoms = list(/obj/item/clothing/suit/hooded/cultrobes/eldritch)
|
||||
cost = 1
|
||||
route = PATH_SIDE
|
||||
|
||||
/datum/heretic_knowledge/crucible
|
||||
name = "Mawed Crucible"
|
||||
desc = "Allows you to transmute a portable water tank and a table to create a Mawed Crucible. \
|
||||
The Mawed Crubile can brew powerful potions for combat and utility, but must be fed bodyparts and organs between uses."
|
||||
gain_text = "This is pure agony. I wasn't able to summon the figure of the Aristocrat, \
|
||||
but with the Priest's attention I stumbled upon a different recipe..."
|
||||
next_knowledge = list(
|
||||
/datum/heretic_knowledge/spell/void_phase,
|
||||
/datum/heretic_knowledge/spell/area_conversion,
|
||||
)
|
||||
required_atoms = list(
|
||||
/obj/structure/reagent_dispensers/watertank = 1,
|
||||
/obj/structure/table = 1,
|
||||
)
|
||||
result_atoms = list(/obj/structure/destructible/eldritch_crucible)
|
||||
cost = 1
|
||||
route = PATH_SIDE
|
||||
|
||||
/datum/heretic_knowledge/summon/rusty
|
||||
name = "Rusted Ritual"
|
||||
desc = "Allows you to transmute a pool of vomit, a book, and a head into a Rust Walker. \
|
||||
Rust Walkers excel at spreading rust and are moderately strong in combat."
|
||||
gain_text = "I combined my principle of hunger with my desire for corruption. The Marshal knew my name, and the Rusted Hills echoed out."
|
||||
next_knowledge = list(
|
||||
/datum/heretic_knowledge/spell/voidpull,
|
||||
/datum/heretic_knowledge/spell/entropic_plume,
|
||||
)
|
||||
required_atoms = list(
|
||||
/obj/effect/decal/cleanable/vomit = 1,
|
||||
/obj/item/book = 1,
|
||||
/obj/item/bodypart/head = 1,
|
||||
)
|
||||
mob_to_summon = /mob/living/simple_animal/hostile/heretic_summon/rust_spirit
|
||||
cost = 1
|
||||
route = PATH_SIDE
|
||||
|
||||
/datum/heretic_knowledge/summon/rusty/cleanup_atoms(list/selected_atoms)
|
||||
var/obj/item/bodypart/head/ritual_head = locate() in selected_atoms
|
||||
if(!ritual_head)
|
||||
CRASH("[type] required a head bodypart, yet did not have one in selected_atoms when it reached cleanup_atoms.")
|
||||
|
||||
// Spill out any brains or stuff before we delete it.
|
||||
ritual_head.drop_organs()
|
||||
return ..()
|
||||
@@ -21,16 +21,14 @@ GLOBAL_LIST_INIT(heretic_start_knowledge, initialize_starting_knowledge())
|
||||
desc = "Starts your journey into the Mansus. \
|
||||
Grants you the Mansus Grasp, a powerful and upgradable \
|
||||
disabling spell that can be cast regardless of having a focus."
|
||||
next_knowledge = list(
|
||||
/datum/heretic_knowledge/limited_amount/base_rust,
|
||||
/datum/heretic_knowledge/limited_amount/base_ash,
|
||||
/datum/heretic_knowledge/limited_amount/base_flesh,
|
||||
/datum/heretic_knowledge/limited_amount/base_void,
|
||||
)
|
||||
spell_to_add = /obj/effect/proc_holder/spell/targeted/touch/mansus_grasp
|
||||
cost = 0
|
||||
route = PATH_START
|
||||
|
||||
/datum/heretic_knowledge/spell/basic/New()
|
||||
. = ..()
|
||||
next_knowledge = subtypesof(/datum/heretic_knowledge/limited_amount/starting)
|
||||
|
||||
/**
|
||||
* The Living Heart heretic knowledge.
|
||||
*
|
||||
|
||||
@@ -8,23 +8,24 @@
|
||||
* Aristocrat's Way
|
||||
* > Sidepaths:
|
||||
* Void Cloak
|
||||
* Armorer's Ritual
|
||||
* Shattered Ritual
|
||||
*
|
||||
* Mark of Void
|
||||
* Ritual of Knowledge
|
||||
* Void Phase
|
||||
* > Sidepaths:
|
||||
* Carving Knife
|
||||
* Mawed Crucible
|
||||
* Blood Siphon
|
||||
*
|
||||
* Seeking blade
|
||||
* Void Pull
|
||||
* > Sidepaths:
|
||||
* Rusted Ritual
|
||||
* Blood Siphon
|
||||
* Cleave
|
||||
* Maid in the Mirror
|
||||
*
|
||||
* Waltz at the End of Time
|
||||
*/
|
||||
/datum/heretic_knowledge/limited_amount/base_void
|
||||
/datum/heretic_knowledge/limited_amount/starting/base_void
|
||||
name = "Glimmer of Winter"
|
||||
desc = "Opens up the path of void to you. \
|
||||
Allows you to transmute a knife in sub-zero temperatures into a Void Blade. \
|
||||
@@ -32,27 +33,16 @@
|
||||
gain_text = "I feel a shimmer in the air, the air around me gets colder. \
|
||||
I start to realize the emptiness of existance. Something's watching me."
|
||||
next_knowledge = list(/datum/heretic_knowledge/void_grasp)
|
||||
banned_knowledge = list(
|
||||
/datum/heretic_knowledge/limited_amount/base_ash,
|
||||
/datum/heretic_knowledge/limited_amount/base_flesh,
|
||||
/datum/heretic_knowledge/limited_amount/base_rust,
|
||||
/datum/heretic_knowledge/final/ash_final,
|
||||
/datum/heretic_knowledge/final/flesh_final,
|
||||
/datum/heretic_knowledge/final/rust_final,
|
||||
)
|
||||
required_atoms = list(/obj/item/knife = 1)
|
||||
result_atoms = list(/obj/item/melee/sickly_blade/void)
|
||||
limit = 2
|
||||
cost = 1
|
||||
priority = MAX_KNOWLEDGE_PRIORITY - 5
|
||||
route = PATH_VOID
|
||||
|
||||
/datum/heretic_knowledge/limited_amount/base_void/on_research(mob/user)
|
||||
/datum/heretic_knowledge/limited_amount/starting/base_void/on_research(mob/user)
|
||||
. = ..()
|
||||
var/datum/antagonist/heretic/our_heretic = IS_HERETIC(user)
|
||||
our_heretic.heretic_path = route
|
||||
|
||||
/datum/heretic_knowledge/limited_amount/base_void/recipe_snowflake_check(mob/living/user, list/atoms, list/selected_atoms, turf/loc)
|
||||
/datum/heretic_knowledge/limited_amount/starting/base_void/recipe_snowflake_check(mob/living/user, list/atoms, list/selected_atoms, turf/loc)
|
||||
if(!isopenturf(loc))
|
||||
loc.balloon_alert(user, "ritual failed, invalid location!")
|
||||
return FALSE
|
||||
@@ -66,7 +56,7 @@
|
||||
|
||||
/datum/heretic_knowledge/void_grasp
|
||||
name = "Grasp of Void"
|
||||
desc = "Your Masus Grasp will temporarily mute and chill the victim."
|
||||
desc = "Your Mansus Grasp will temporarily mute and chill the victim."
|
||||
gain_text = "I saw the cold watcher who observes me. The chill mounts within me. \
|
||||
They are quiet. This isn't the end of the mystery."
|
||||
next_knowledge = list(/datum/heretic_knowledge/cold_snap)
|
||||
@@ -98,10 +88,10 @@
|
||||
gain_text = "I found a thread of cold breath. It lead me to a strange shrine, all made of crystals. \
|
||||
Translucent and white, a depiction of a nobleman stood before me."
|
||||
next_knowledge = list(
|
||||
/datum/heretic_knowledge/void_mark,
|
||||
/datum/heretic_knowledge/mark/void_mark,
|
||||
/datum/heretic_knowledge/codex_cicatrix,
|
||||
/datum/heretic_knowledge/void_cloak,
|
||||
/datum/heretic_knowledge/armor,
|
||||
/datum/heretic_knowledge/limited_amount/risen_corpse,
|
||||
)
|
||||
cost = 1
|
||||
route = PATH_VOID
|
||||
@@ -114,49 +104,18 @@
|
||||
REMOVE_TRAIT(user, TRAIT_RESISTCOLD, type)
|
||||
REMOVE_TRAIT(user, TRAIT_NOBREATH, type)
|
||||
|
||||
/datum/heretic_knowledge/void_mark
|
||||
/datum/heretic_knowledge/mark/void_mark
|
||||
name = "Mark of Void"
|
||||
desc = "Your Mansus Grasp now applies the Mark of Void. The mark is triggered from an attack with your Void Blade. \
|
||||
When triggered, silences the victim and lowers their body temperature significantly."
|
||||
gain_text = "A gust of wind? A shimmer in the air? The presence is overwhelming, \
|
||||
my senses began to betray me. My mind is my own enemy."
|
||||
next_knowledge = list(/datum/heretic_knowledge/knowledge_ritual/void)
|
||||
banned_knowledge = list(
|
||||
/datum/heretic_knowledge/rust_mark,
|
||||
/datum/heretic_knowledge/ash_mark,
|
||||
/datum/heretic_knowledge/flesh_mark,
|
||||
)
|
||||
cost = 2
|
||||
route = PATH_VOID
|
||||
|
||||
/datum/heretic_knowledge/void_mark/on_gain(mob/user)
|
||||
RegisterSignal(user, COMSIG_HERETIC_MANSUS_GRASP_ATTACK, .proc/on_mansus_grasp)
|
||||
RegisterSignal(user, COMSIG_HERETIC_BLADE_ATTACK, .proc/on_eldritch_blade)
|
||||
|
||||
/datum/heretic_knowledge/void_mark/on_lose(mob/user)
|
||||
UnregisterSignal(user, list(COMSIG_HERETIC_MANSUS_GRASP_ATTACK, COMSIG_HERETIC_BLADE_ATTACK))
|
||||
|
||||
/datum/heretic_knowledge/void_mark/proc/on_mansus_grasp(mob/living/source, mob/living/target)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
target.apply_status_effect(/datum/status_effect/eldritch/void)
|
||||
|
||||
/datum/heretic_knowledge/void_mark/proc/on_eldritch_blade(mob/living/user, mob/living/target)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
var/datum/status_effect/eldritch/mark = target.has_status_effect(/datum/status_effect/eldritch)
|
||||
if(!istype(mark))
|
||||
return
|
||||
|
||||
mark.on_effect()
|
||||
mark_type = /datum/status_effect/eldritch/void
|
||||
|
||||
/datum/heretic_knowledge/knowledge_ritual/void
|
||||
next_knowledge = list(/datum/heretic_knowledge/spell/void_phase)
|
||||
banned_knowledge = list(
|
||||
/datum/heretic_knowledge/knowledge_ritual/ash,
|
||||
/datum/heretic_knowledge/knowledge_ritual/rust,
|
||||
/datum/heretic_knowledge/knowledge_ritual/flesh,
|
||||
)
|
||||
route = PATH_VOID
|
||||
|
||||
/datum/heretic_knowledge/spell/void_phase
|
||||
@@ -166,59 +125,43 @@
|
||||
gain_text = "The entity calls themself the Aristocrat. They effortlessly walk through air like\
|
||||
nothing leaving a harsh, cold breeze in their wake. They disappear, and I am left in the snow."
|
||||
next_knowledge = list(
|
||||
/datum/heretic_knowledge/void_blade_upgrade,
|
||||
/datum/heretic_knowledge/blade_upgrade/void,
|
||||
/datum/heretic_knowledge/reroll_targets,
|
||||
/datum/heretic_knowledge/spell/blood_siphon,
|
||||
/datum/heretic_knowledge/rune_carver,
|
||||
/datum/heretic_knowledge/crucible,
|
||||
)
|
||||
spell_to_add = /obj/effect/proc_holder/spell/pointed/void_phase
|
||||
cost = 1
|
||||
route = PATH_VOID
|
||||
|
||||
/datum/heretic_knowledge/void_blade_upgrade
|
||||
/datum/heretic_knowledge/blade_upgrade/void
|
||||
name = "Seeking blade"
|
||||
desc = "You can now attack distant marked targets with your Void Blade, teleporting directly next to them."
|
||||
gain_text = "Fleeting memories, fleeting feet. I mark my way with frozen blood upon the snow. Covered and forgotten."
|
||||
next_knowledge = list(/datum/heretic_knowledge/spell/voidpull)
|
||||
banned_knowledge = list(
|
||||
/datum/heretic_knowledge/ash_blade_upgrade,
|
||||
/datum/heretic_knowledge/flesh_blade_upgrade,
|
||||
/datum/heretic_knowledge/rust_blade_upgrade,
|
||||
)
|
||||
cost = 2
|
||||
next_knowledge = list(/datum/heretic_knowledge/spell/void_pull)
|
||||
route = PATH_VOID
|
||||
|
||||
|
||||
/datum/heretic_knowledge/void_blade_upgrade/on_gain(mob/user)
|
||||
RegisterSignal(user, COMSIG_HERETIC_RANGED_BLADE_ATTACK, .proc/on_ranged_eldritch_blade)
|
||||
|
||||
/datum/heretic_knowledge/void_blade_upgrade/on_lose(mob/user)
|
||||
UnregisterSignal(user, COMSIG_HERETIC_RANGED_BLADE_ATTACK)
|
||||
|
||||
/datum/heretic_knowledge/void_blade_upgrade/proc/on_ranged_eldritch_blade(mob/living/user, mob/living/target)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
/datum/heretic_knowledge/blade_upgrade/void/do_ranged_effects(mob/living/user, mob/living/target, obj/item/melee/sickly_blade/blade)
|
||||
if(!target.has_status_effect(/datum/status_effect/eldritch))
|
||||
return
|
||||
|
||||
var/dir = angle2dir(dir2angle(get_dir(user, target)) + 180)
|
||||
user.forceMove(get_step(target, dir))
|
||||
|
||||
INVOKE_ASYNC(src, .proc/follow_up_attack, user, target)
|
||||
INVOKE_ASYNC(src, .proc/follow_up_attack, user, target, blade)
|
||||
|
||||
/datum/heretic_knowledge/void_blade_upgrade/proc/follow_up_attack(mob/living/user, mob/living/target)
|
||||
var/obj/item/melee/sickly_blade/blade = user.get_active_held_item()
|
||||
blade?.melee_attack_chain(user, target)
|
||||
/datum/heretic_knowledge/blade_upgrade/void/proc/follow_up_attack(mob/living/user, mob/living/target, obj/item/melee/sickly_blade/blade)
|
||||
blade.melee_attack_chain(user, target)
|
||||
|
||||
/datum/heretic_knowledge/spell/voidpull
|
||||
/datum/heretic_knowledge/spell/void_pull
|
||||
name = "Void Pull"
|
||||
desc = "Grants you Void Pull, a spell that pulls all nearby heathens towards you, stunning them briefly."
|
||||
gain_text = "All is fleeting, but what else stays? I'm close to ending what was started. \
|
||||
The Aristocrat reveals themself to me again. They tell me I am late. Their pull is immense, I cannot turn back."
|
||||
next_knowledge = list(
|
||||
/datum/heretic_knowledge/final/void_final,
|
||||
/datum/heretic_knowledge/spell/blood_siphon,
|
||||
/datum/heretic_knowledge/summon/rusty
|
||||
/datum/heretic_knowledge/spell/cleave,
|
||||
/datum/heretic_knowledge/summon/maid_in_mirror,
|
||||
)
|
||||
spell_to_add = /obj/effect/proc_holder/spell/targeted/void_pull
|
||||
cost = 1
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/obj/effect/proc_holder/spell/aimed/furious_steel
|
||||
name = "Furious Steel"
|
||||
desc = "Summon three silver blades which orbit you. \
|
||||
While orbiting you, these blades will protect you from from attacks, but will be consumed on use. \
|
||||
Additionally, you can click to fire the blades at a target, dealing damage and causing bleeding."
|
||||
action_icon = 'icons/mob/actions/actions_ecult.dmi'
|
||||
action_icon_state = "furious_steel0"
|
||||
action_background_icon_state = "bg_ecult"
|
||||
base_icon_state = "furious_steel"
|
||||
invocation = "F'LSH'NG S'LV'R!"
|
||||
invocation_type = INVOCATION_SHOUT
|
||||
school = SCHOOL_FORBIDDEN
|
||||
clothes_req = FALSE
|
||||
charge_max = 30 SECONDS
|
||||
range = 20
|
||||
projectile_amount = 3
|
||||
projectiles_per_fire = 1
|
||||
projectile_type = /obj/projectile/floating_blade
|
||||
sound = 'sound/weapons/guillotine.ogg'
|
||||
active_msg = "You summon forth three blades of furious silver."
|
||||
deactive_msg = "You conceal the blades of furious silver."
|
||||
/// A ref to the status effect surrounding our heretic on activation.
|
||||
var/datum/status_effect/protective_blades/blade_effect
|
||||
|
||||
/obj/effect/proc_holder/spell/aimed/furious_steel/Destroy()
|
||||
QDEL_NULL(blade_effect)
|
||||
return ..()
|
||||
|
||||
/obj/effect/proc_holder/spell/aimed/furious_steel/on_activation(mob/user)
|
||||
if(!isliving(user))
|
||||
return
|
||||
var/mob/living/living_user = user
|
||||
// Aimed spells snowflake and activate without checking cast_check, very cool
|
||||
var/datum/antagonist/heretic/our_heretic = IS_HERETIC(living_user)
|
||||
if(our_heretic && !our_heretic.ascended && !HAS_TRAIT(living_user, TRAIT_ALLOW_HERETIC_CASTING))
|
||||
user.balloon_alert(living_user, "you need a focus!")
|
||||
return
|
||||
|
||||
. = ..()
|
||||
blade_effect = living_user.apply_status_effect(/datum/status_effect/protective_blades, null, 3, 25, 0.66 SECONDS)
|
||||
RegisterSignal(blade_effect, COMSIG_PARENT_QDELETING, .proc/on_status_effect_deleted)
|
||||
|
||||
/obj/effect/proc_holder/spell/aimed/furious_steel/on_deactivation(mob/user)
|
||||
. = ..()
|
||||
QDEL_NULL(blade_effect)
|
||||
|
||||
/obj/effect/proc_holder/spell/aimed/furious_steel/InterceptClickOn(mob/living/caller, params, atom/target)
|
||||
if(get_dist(caller, target) <= 1) // Let the caster prioritize melee attacks over blade casts
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/effect/proc_holder/spell/aimed/furious_steel/cast(list/targets, mob/living/user)
|
||||
if(isnull(blade_effect) || !length(blade_effect.blades))
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/effect/proc_holder/spell/aimed/furious_steel/ready_projectile(obj/projectile/to_launch, atom/target, mob/user, iteration)
|
||||
. = ..()
|
||||
to_launch.def_zone = check_zone(user.zone_selected)
|
||||
|
||||
/obj/effect/proc_holder/spell/aimed/furious_steel/fire_projectile(mob/living/user, atom/target)
|
||||
. = ..()
|
||||
qdel(blade_effect.blades[1])
|
||||
|
||||
/obj/effect/proc_holder/spell/aimed/furious_steel/proc/on_status_effect_deleted(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
blade_effect = null
|
||||
on_deactivation()
|
||||
|
||||
/obj/projectile/floating_blade
|
||||
name = "blade"
|
||||
icon = 'icons/obj/kitchen.dmi'
|
||||
icon_state = "knife"
|
||||
speed = 2
|
||||
damage = 25
|
||||
armour_penetration = 100
|
||||
sharpness = SHARP_EDGED
|
||||
wound_bonus = 15
|
||||
pass_flags = PASSTABLE | PASSFLAPS
|
||||
|
||||
/obj/projectile/floating_blade/Initialize(mapload)
|
||||
. = ..()
|
||||
add_filter("knife", 2, list("type" = "outline", "color" = "#f8f8ff", "size" = 1))
|
||||
|
||||
/obj/projectile/floating_blade/prehit_pierce(atom/hit)
|
||||
if(isliving(hit) && isliving(firer))
|
||||
var/mob/living/caster = firer
|
||||
var/mob/living/victim = hit
|
||||
if(caster == victim)
|
||||
return PROJECTILE_PIERCE_PHASE
|
||||
|
||||
if(caster.mind)
|
||||
var/datum/antagonist/heretic_monster/monster = victim.mind?.has_antag_datum(/datum/antagonist/heretic_monster)
|
||||
if(monster?.master == caster.mind)
|
||||
return PROJECTILE_PIERCE_PHASE
|
||||
|
||||
return ..()
|
||||
@@ -3,7 +3,7 @@
|
||||
desc = "A touch spell that lets you channel the power of the Old Gods through your grip."
|
||||
hand_path = /obj/item/melee/touch_attack/mansus_fist
|
||||
school = SCHOOL_EVOCATION
|
||||
charge_max = 100
|
||||
charge_max = 10 SECONDS
|
||||
clothes_req = FALSE
|
||||
action_icon = 'icons/mob/actions/actions_ecult.dmi'
|
||||
action_icon_state = "mansus_grasp"
|
||||
@@ -79,7 +79,7 @@
|
||||
if(SEND_SIGNAL(heretic, COMSIG_HERETIC_MANSUS_GRASP_ATTACK, hit) & COMPONENT_BLOCK_CHARGE_USE)
|
||||
return FALSE
|
||||
|
||||
hit.adjustBruteLoss(10)
|
||||
hit.apply_damage(10, BRUTE, wound_bonus = CANT_WOUND)
|
||||
if(iscarbon(hit))
|
||||
var/mob/living/carbon/carbon_hit = hit
|
||||
carbon_hit.adjust_timed_status_effect(4 SECONDS, /datum/status_effect/speech/slurring/heretic)
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
/// Macro to check if the passed mob is currently in jaunting "in the mirror".
|
||||
#define IS_MIRROR_PHASED(mob) istype(user.loc, /obj/effect/dummy/phased_mob/mirror_walk)
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/mirror_walk
|
||||
name = "Mirror Walk"
|
||||
desc = "Allows you to traverse invisibly and freely across the station within the realm of the mirror. \
|
||||
You can only enter and exit the realm of mirrors when nearby reflective surfaces and items, \
|
||||
such as windows, mirrors, and reflective walls or equipment."
|
||||
action_icon = 'icons/mob/actions/actions_minor_antag.dmi'
|
||||
action_icon_state = "ninja_cloak"
|
||||
action_background_icon_state = "bg_ecult"
|
||||
charge_max = 6 SECONDS
|
||||
cooldown_min = 0
|
||||
clothes_req = FALSE
|
||||
antimagic_flags = NONE
|
||||
phase_allowed = TRUE
|
||||
range = -1
|
||||
include_user = TRUE
|
||||
overlay = null
|
||||
|
||||
/// The time it takes to enter the mirror / phase out / enter jaunt.
|
||||
var/phase_out_time = 1.5 SECONDS
|
||||
/// The time it takes to exit a mirror / phase in / exit jaunt.
|
||||
var/phase_in_time = 2 SECONDS
|
||||
/// Static typecache of types that are counted as reflective.
|
||||
var/static/list/special_reflective_surfaces = typecacheof(list(
|
||||
/obj/structure/window,
|
||||
/obj/structure/mirror,
|
||||
))
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/mirror_walk/on_lose(mob/living/user)
|
||||
if(IS_MIRROR_PHASED(user))
|
||||
var/obj/effect/dummy/phased_mob/mirror_walk/phase = user.loc
|
||||
phase.eject_user()
|
||||
qdel(phase)
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/mirror_walk/cast_check(skipcharge = FALSE, mob/user = usr)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
|
||||
var/we_are_phasing = IS_MIRROR_PHASED(user)
|
||||
var/turf/user_turf = get_turf(user)
|
||||
var/area/user_area = get_area(user)
|
||||
if(!user_turf || !user_area)
|
||||
return FALSE // nullspaced?
|
||||
|
||||
if(user_area.area_flags & NOTELEPORT)
|
||||
to_chat(user, span_warning("An otherwordly force is preventing you from [we_are_phasing ? "exiting":"entering"] the mirror's realm here!"))
|
||||
return FALSE
|
||||
|
||||
if(user_turf.turf_flags & NOJAUNT)
|
||||
to_chat(user, span_warning("An otherwordly force is preventing you from [we_are_phasing ? "exiting":"entering"] the mirror's realm here!"))
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/mirror_walk/cast(list/targets, mob/living/user = usr)
|
||||
var/we_are_phasing = IS_MIRROR_PHASED(user)
|
||||
var/turf/user_turf = get_turf(user)
|
||||
|
||||
if(!is_reflection_nearby(user_turf))
|
||||
to_chat(user, span_warning("There are no reflective surfaces nearby to [we_are_phasing ? "exit":"enter"] the mirror's realm here!"))
|
||||
return FALSE
|
||||
|
||||
if(user_turf.is_blocked_turf(exclude_mobs = TRUE))
|
||||
to_chat(user, span_warning("Something is blocking you from [we_are_phasing ? "exiting":"entering"] the mirror's realm here!"))
|
||||
return FALSE
|
||||
|
||||
// If our loc is a phased mob, we're currently jaunting so we should exit
|
||||
if(we_are_phasing)
|
||||
try_exit_phase(user)
|
||||
return
|
||||
|
||||
// Otherwise try to enter like normal
|
||||
try_enter_phase(user)
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/mirror_walk/proc/try_exit_phase(mob/living/user)
|
||||
var/obj/effect/dummy/phased_mob/mirror_walk/phase = user.loc
|
||||
var/atom/nearby_reflection = is_reflection_nearby(phase)
|
||||
if(!nearby_reflection)
|
||||
to_chat(user, span_warning("There are no reflective surfaces nearby to exit from the mirror's realm!"))
|
||||
return FALSE
|
||||
|
||||
var/turf/phase_turf = get_turf(phase)
|
||||
|
||||
// It would likely be a bad idea to teleport into an ai monitored area (ai sat)
|
||||
var/area/phase_area = get_area(phase_turf)
|
||||
if(istype(phase_area, /area/ai_monitored))
|
||||
to_chat(user, span_warning("It's probably not a very wise idea to exit the mirror's realm here."))
|
||||
return FALSE
|
||||
|
||||
nearby_reflection.Beam(phase_turf, icon_state = "light_beam", time = phase_in_time)
|
||||
nearby_reflection.visible_message(span_warning("[nearby_reflection] begins to shimmer and shake slightly!"))
|
||||
if(!do_after(user, phase_in_time, nearby_reflection))
|
||||
return
|
||||
|
||||
playsound(get_turf(user), 'sound/magic/ethereal_exit.ogg', 50, TRUE, -1)
|
||||
user.visible_message(
|
||||
span_boldwarning("[user] phases into reality before your very eyes!"),
|
||||
span_notice("You jump out of the reflection coming off of [nearby_reflection], exiting the mirror's realm."),
|
||||
)
|
||||
|
||||
// We can move around while phasing in,
|
||||
// but we'll always end up where we started it.
|
||||
phase.forceMove(phase_turf)
|
||||
phase.eject_user()
|
||||
qdel(phase)
|
||||
|
||||
// Chilly!
|
||||
phase_turf.TakeTemperature(-20)
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/mirror_walk/proc/try_enter_phase(mob/living/user)
|
||||
var/atom/nearby_reflection = is_reflection_nearby(user)
|
||||
if(!nearby_reflection)
|
||||
to_chat(user, span_warning("There are no reflective surfaces nearby to enter the mirror's realm!"))
|
||||
return
|
||||
|
||||
user.Beam(nearby_reflection, icon_state = "light_beam", time = phase_out_time)
|
||||
nearby_reflection.visible_message(span_warning("[nearby_reflection] begins to shimmer and shake slightly!"))
|
||||
if(!do_after(user, phase_out_time, nearby_reflection, IGNORE_USER_LOC_CHANGE|IGNORE_INCAPACITATED))
|
||||
return
|
||||
|
||||
playsound(get_turf(user), 'sound/magic/ethereal_enter.ogg', 50, TRUE, -1)
|
||||
user.visible_message(
|
||||
span_boldwarning("[user] phases out of reality, vanishing before your very eyes!"),
|
||||
span_notice("You jump into the reflection coming off of [nearby_reflection], entering the mirror's realm."),
|
||||
)
|
||||
|
||||
user.SetAllImmobility(0)
|
||||
user.setStaminaLoss(0)
|
||||
|
||||
var/obj/effect/dummy/phased_mob/mirror_walk/phase = new(get_turf(nearby_reflection))
|
||||
user.forceMove(phase)
|
||||
|
||||
/**
|
||||
* Goes through all nearby atoms in sight of the
|
||||
* passed caster and determines if they are "reflective"
|
||||
* for the purpose of us being able to utilize it to enter or exit.
|
||||
*
|
||||
* Returns an object reference to a "reflective" object in view if one was found,
|
||||
* or null if no object was found that was determined to be "reflective".
|
||||
*/
|
||||
/obj/effect/proc_holder/spell/targeted/mirror_walk/proc/is_reflection_nearby(atom/caster)
|
||||
for(var/atom/thing as anything in view(2, caster))
|
||||
if(isitem(thing))
|
||||
var/obj/item/item_thing = thing
|
||||
if(item_thing.IsReflect())
|
||||
return thing
|
||||
|
||||
if(ishuman(thing))
|
||||
var/mob/living/carbon/human/human_thing = thing
|
||||
if(human_thing.check_reflect())
|
||||
return thing
|
||||
|
||||
if(isturf(thing))
|
||||
var/turf/turf_thing = thing
|
||||
if(turf_thing.turf_flags & NOJAUNT)
|
||||
continue
|
||||
if(turf_thing.flags_ricochet & RICOCHET_SHINY)
|
||||
return thing
|
||||
|
||||
if(is_type_in_typecache(thing, special_reflective_surfaces))
|
||||
return thing
|
||||
|
||||
return null
|
||||
|
||||
/obj/effect/dummy/phased_mob/mirror_walk
|
||||
name = "reflection"
|
||||
|
||||
/obj/effect/dummy/phased_mob/mirror_walk/proc/eject_user()
|
||||
var/mob/living/jaunter = locate() in contents
|
||||
if(QDELETED(jaunter))
|
||||
CRASH("[type] called eject_user() without a mob/living within its contents.")
|
||||
|
||||
jaunter.forceMove(drop_location())
|
||||
@@ -0,0 +1,78 @@
|
||||
// A summon which floats around the station incorporeally, and can appear in any mirror
|
||||
/mob/living/simple_animal/hostile/heretic_summon/maid_in_the_mirror
|
||||
name = "Maid in the Mirror"
|
||||
real_name = "Maid in the Mirror"
|
||||
desc = "A floating and flowing wisp of chilled air. Glancing at it causes it to shimmer slightly."
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
icon_state = "stand"
|
||||
icon_living = "stand" // Placeholder sprite
|
||||
speak_emote = list("whispers")
|
||||
movement_type = FLOATING
|
||||
status_flags = CANSTUN | CANPUSH
|
||||
attack_sound = SFX_SHATTER
|
||||
maxHealth = 80
|
||||
health = 80
|
||||
melee_damage_lower = 12
|
||||
melee_damage_upper = 16
|
||||
sight = SEE_MOBS | SEE_OBJS | SEE_TURFS
|
||||
deathmessage = "shatters and vanishes, releasing a gust of cold air."
|
||||
loot = list(
|
||||
/obj/item/shard,
|
||||
/obj/effect/decal/cleanable/ash,
|
||||
/obj/item/clothing/suit/armor,
|
||||
/obj/item/organ/lungs,
|
||||
)
|
||||
spells_to_add = list(/obj/effect/proc_holder/spell/targeted/mirror_walk)
|
||||
|
||||
/// Whether we take damage when we're examined
|
||||
var/weak_on_examine = TRUE
|
||||
/// The cooldown after being examined that the same mob cannot trigger it again
|
||||
var/recent_examine_damage_cooldown = 10 SECONDS
|
||||
/// A list of REFs to people who recently examined us
|
||||
var/list/recent_examiner_refs = list()
|
||||
|
||||
/mob/living/simple_animal/hostile/heretic_summon/maid_in_the_mirror/death(gibbed)
|
||||
var/turf/death_turf = get_turf(src)
|
||||
death_turf.TakeTemperature(-40)
|
||||
return ..()
|
||||
|
||||
// Examining them will harm them, on a cooldown.
|
||||
/mob/living/simple_animal/hostile/heretic_summon/maid_in_the_mirror/examine(mob/user)
|
||||
. = ..()
|
||||
if(!weak_on_examine)
|
||||
return
|
||||
|
||||
if(IS_HERETIC_OR_MONSTER(user) || user == src)
|
||||
return
|
||||
|
||||
var/user_ref = REF(user)
|
||||
if(user_ref in recent_examiner_refs)
|
||||
return
|
||||
|
||||
// If we have health, we take some damage
|
||||
if(health > (maxHealth * 0.125))
|
||||
visible_message(
|
||||
span_warning("[src] seems to fade in and out slightly."),
|
||||
span_userdanger("[user]'s gaze pierces your every being!"),
|
||||
)
|
||||
|
||||
recent_examiner_refs += user_ref
|
||||
apply_damage(maxHealth * 0.1) // We take 10% of our health as damage upon being examined
|
||||
playsound(src, 'sound/effects/ghost2.ogg', 40, TRUE)
|
||||
addtimer(CALLBACK(src, .proc/clear_recent_examiner, user_ref), recent_examine_damage_cooldown)
|
||||
|
||||
// If we're examined on low enough health we die straight up
|
||||
else
|
||||
visible_message(
|
||||
span_danger("[src] vanishes from existence!"),
|
||||
span_userdanger("[user]'s gaze shatters your form, destroying you!"),
|
||||
)
|
||||
|
||||
death()
|
||||
|
||||
/mob/living/simple_animal/hostile/heretic_summon/maid_in_the_mirror/proc/clear_recent_examiner(mob_ref)
|
||||
if(!(mob_ref in recent_examiner_refs))
|
||||
return
|
||||
|
||||
recent_examiner_refs -= mob_ref
|
||||
heal_overall_damage(5)
|
||||
@@ -40,7 +40,7 @@
|
||||
//arena conditions
|
||||
RegisterSignal(sparring, COMSIG_MOVABLE_MOVED, .proc/arena_violation)
|
||||
//severe violations (insta violation win for other party) conditions
|
||||
RegisterSignal(sparring, COMSIG_MOVABLE_TELEPORTED, .proc/teleport_violation)
|
||||
RegisterSignal(sparring, COMSIG_MOVABLE_POST_TELEPORT, .proc/teleport_violation)
|
||||
//win conditions
|
||||
RegisterSignal(sparring, COMSIG_MOB_STATCHANGE, .proc/check_for_victory)
|
||||
//flub conditions
|
||||
@@ -62,7 +62,7 @@
|
||||
COMSIG_MOB_GRENADE_ARMED,
|
||||
COMSIG_MOB_ITEM_ATTACK,
|
||||
COMSIG_MOVABLE_MOVED,
|
||||
COMSIG_MOVABLE_TELEPORTED,
|
||||
COMSIG_MOVABLE_POST_TELEPORT,
|
||||
COMSIG_MOB_STATCHANGE,
|
||||
COMSIG_PARENT_ATTACKBY,
|
||||
COMSIG_ATOM_HULK_ATTACK,
|
||||
|
||||
@@ -15,30 +15,36 @@
|
||||
var/mob/living/user = usr
|
||||
if(!istype(user))
|
||||
return
|
||||
var/msg
|
||||
if(!can_cast(user))
|
||||
msg = span_warning("You can no longer cast [name]!")
|
||||
remove_ranged_ability(msg)
|
||||
remove_ranged_ability(span_warning("You can no longer cast [name]!"))
|
||||
return
|
||||
|
||||
if(active)
|
||||
msg = span_notice("[deactive_msg]")
|
||||
if(charge_type == "recharge")
|
||||
var/refund_percent = current_amount/projectile_amount
|
||||
charge_counter = charge_max * refund_percent
|
||||
start_recharge()
|
||||
remove_ranged_ability(msg)
|
||||
on_deactivation(user)
|
||||
else
|
||||
msg = span_notice("[active_msg] <B>Left-click to shoot it at a target!</B>")
|
||||
current_amount = projectile_amount
|
||||
add_ranged_ability(user, msg, TRUE)
|
||||
on_activation(user)
|
||||
|
||||
/**
|
||||
* Activate the spell for user.
|
||||
*/
|
||||
/obj/effect/proc_holder/spell/aimed/proc/on_activation(mob/user)
|
||||
return
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
|
||||
current_amount = projectile_amount
|
||||
add_ranged_ability(user, span_notice("[active_msg] <B>Left-click to shoot it at a target!</B>"), TRUE)
|
||||
|
||||
/**
|
||||
* Deactivate the spell from user.
|
||||
*/
|
||||
/obj/effect/proc_holder/spell/aimed/proc/on_deactivation(mob/user)
|
||||
return
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
|
||||
if(charge_type == "recharge")
|
||||
var/refund_percent = current_amount / projectile_amount
|
||||
charge_counter = charge_max * refund_percent
|
||||
start_recharge()
|
||||
remove_ranged_ability(span_notice("[deactive_msg]"))
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/aimed/update_icon()
|
||||
if(!action)
|
||||
@@ -156,6 +162,7 @@
|
||||
ranged_clickcd_override = TRUE
|
||||
|
||||
/obj/effect/proc_holder/spell/aimed/spell_cards/on_activation(mob/M)
|
||||
. = ..()
|
||||
QDEL_NULL(lockon_component)
|
||||
lockon_component = M.AddComponent(/datum/component/lockon_aiming, 5, GLOB.typecache_living, 1, null, CALLBACK(src, .proc/on_lockon_component))
|
||||
|
||||
@@ -170,6 +177,7 @@
|
||||
M.face_atom(A)
|
||||
|
||||
/obj/effect/proc_holder/spell/aimed/spell_cards/on_deactivation(mob/M)
|
||||
. = ..()
|
||||
QDEL_NULL(lockon_component)
|
||||
|
||||
/obj/effect/proc_holder/spell/aimed/spell_cards/ready_projectile(obj/projectile/P, atom/target, mob/user, iteration)
|
||||
|
||||
|
Before Width: | Height: | Size: 907 KiB After Width: | Height: | Size: 890 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 71 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 196 KiB After Width: | Height: | Size: 202 KiB |
@@ -2078,6 +2078,7 @@
|
||||
#include "code\modules\antagonists\heretic\heretic_living_heart.dm"
|
||||
#include "code\modules\antagonists\heretic\heretic_monsters.dm"
|
||||
#include "code\modules\antagonists\heretic\influences.dm"
|
||||
#include "code\modules\antagonists\heretic\knife_effect.dm"
|
||||
#include "code\modules\antagonists\heretic\rust_effect.dm"
|
||||
#include "code\modules\antagonists\heretic\transmutation_rune.dm"
|
||||
#include "code\modules\antagonists\heretic\items\eldritch_flask.dm"
|
||||
@@ -2085,15 +2086,18 @@
|
||||
#include "code\modules\antagonists\heretic\items\heretic_armor.dm"
|
||||
#include "code\modules\antagonists\heretic\items\heretic_blades.dm"
|
||||
#include "code\modules\antagonists\heretic\items\heretic_necks.dm"
|
||||
#include "code\modules\antagonists\heretic\items\hunter_rifle.dm"
|
||||
#include "code\modules\antagonists\heretic\items\madness_mask.dm"
|
||||
#include "code\modules\antagonists\heretic\knowledge\ash_lore.dm"
|
||||
#include "code\modules\antagonists\heretic\knowledge\blade_lore.dm"
|
||||
#include "code\modules\antagonists\heretic\knowledge\flesh_lore.dm"
|
||||
#include "code\modules\antagonists\heretic\knowledge\general_side.dm"
|
||||
#include "code\modules\antagonists\heretic\knowledge\rust_lore.dm"
|
||||
#include "code\modules\antagonists\heretic\knowledge\side_ash_flesh.dm"
|
||||
#include "code\modules\antagonists\heretic\knowledge\side_blade_rust.dm"
|
||||
#include "code\modules\antagonists\heretic\knowledge\side_flesh_void.dm"
|
||||
#include "code\modules\antagonists\heretic\knowledge\side_rust_ash.dm"
|
||||
#include "code\modules\antagonists\heretic\knowledge\side_void_rust.dm"
|
||||
#include "code\modules\antagonists\heretic\knowledge\side_void_blade.dm"
|
||||
#include "code\modules\antagonists\heretic\knowledge\starting_lore.dm"
|
||||
#include "code\modules\antagonists\heretic\knowledge\void_lore.dm"
|
||||
#include "code\modules\antagonists\heretic\knowledge\sacrifice_knowledge\sacrifice_buff.dm"
|
||||
@@ -2111,13 +2115,16 @@
|
||||
#include "code\modules\antagonists\heretic\magic\eldritch_telepathy.dm"
|
||||
#include "code\modules\antagonists\heretic\magic\expand_sight.dm"
|
||||
#include "code\modules\antagonists\heretic\magic\flesh_ascension.dm"
|
||||
#include "code\modules\antagonists\heretic\magic\furious_steel.dm"
|
||||
#include "code\modules\antagonists\heretic\magic\madness_touch.dm"
|
||||
#include "code\modules\antagonists\heretic\magic\manse_link.dm"
|
||||
#include "code\modules\antagonists\heretic\magic\mansus_grasp.dm"
|
||||
#include "code\modules\antagonists\heretic\magic\mirror_walk.dm"
|
||||
#include "code\modules\antagonists\heretic\magic\nightwater_rebirth.dm"
|
||||
#include "code\modules\antagonists\heretic\magic\rust_wave.dm"
|
||||
#include "code\modules\antagonists\heretic\magic\void_phase.dm"
|
||||
#include "code\modules\antagonists\heretic\magic\void_pull.dm"
|
||||
#include "code\modules\antagonists\heretic\mobs\maid_in_mirror.dm"
|
||||
#include "code\modules\antagonists\heretic\structures\carving_knife.dm"
|
||||
#include "code\modules\antagonists\heretic\structures\mawed_crucible.dm"
|
||||
#include "code\modules\antagonists\highlander\highlander.dm"
|
||||
|
||||
@@ -326,7 +326,7 @@ export const AntagInfoHeretic = (props, context) => {
|
||||
return (
|
||||
<Window
|
||||
width={675}
|
||||
height={575}>
|
||||
height={600}>
|
||||
<Window.Content
|
||||
style={{
|
||||
// 'font-family': 'Times New Roman',
|
||||
|
||||