diff --git a/code/modules/antagonists/wizard/equipment/spellbook_entries/offensive.dm b/code/modules/antagonists/wizard/equipment/spellbook_entries/offensive.dm index f75f4bd8b61..d2398b01448 100644 --- a/code/modules/antagonists/wizard/equipment/spellbook_entries/offensive.dm +++ b/code/modules/antagonists/wizard/equipment/spellbook_entries/offensive.dm @@ -85,6 +85,19 @@ category = "Offensive" no_coexistance_typecache = list(/datum/action/cooldown/spell/lichdom) +/datum/spellbook_entry/sanguine_strike + name = "Exsanguinating Strike" + desc = "Sanguine spell that enchants your next weapon strike to deal more damage, heal you for damage dealt, and refill blood." + spell_type = /datum/action/cooldown/spell/sanguine_strike + category = "Offensive" + +/datum/spellbook_entry/scream_for_me + name = "Scream For Me" + desc = "Sadistic sanguine spell that inflicts numerous severe blood wounds all over the victim's body." + spell_type = /datum/action/cooldown/spell/touch/scream_for_me + cost = 1 + category = "Offensive" + /datum/spellbook_entry/item/staffchaos name = "Staff of Chaos" desc = "A caprious tool that can fire all sorts of magic without any rhyme or reason. Using it on people you care about is not recommended." diff --git a/code/modules/spells/spell_types/self/sanguine_strike.dm b/code/modules/spells/spell_types/self/sanguine_strike.dm new file mode 100644 index 00000000000..afb5860c6a6 --- /dev/null +++ b/code/modules/spells/spell_types/self/sanguine_strike.dm @@ -0,0 +1,95 @@ +/// Enchants an item to deal either double damage, or +20 damage, whichever is less, and lifesteals for that amount + steals some blood. +/// multiplication can get a little instakill-y, so capping it at + 20 damage. +/// 10 force weapon doesn't get the cap and gains 10 damage, 20 total +/// 20 force weapon gets the cap of 20 damage added for a total of 40 +/// 35 force weapon still gets the cap of 20 for a total of 55 instead of a whopping 70 damage +/// Steals 50 blood if they have enough. Splattercasting has one second of cooldown worth 5 blood, so 50 seconds cooldown of blood added! +/datum/action/cooldown/spell/sanguine_strike + name = "Sanguine Strike" + desc = "Enchants your next weapon strike to deal more damage, heal you for damage dealt, and refill blood." + button_icon_state = "charge" + + sound = 'sound/magic/charge.ogg' + // makes this spell not take blood from splattercasting + school = SCHOOL_SANGUINE + cooldown_time = 60 SECONDS + cooldown_reduction_per_rank = 10 SECONDS + + invocation = "SHAPSDAY" + invocation_type = INVOCATION_WHISPER + spell_requirements = SPELL_REQUIRES_NO_ANTIMAGIC + + ///Original force of the item enchanted. + var/original_force = 0 + +/datum/action/cooldown/spell/sanguine_strike/is_valid_target(atom/cast_on) + return isliving(cast_on) + +/datum/action/cooldown/spell/sanguine_strike/can_cast_spell(feedback) + var/obj/item/to_enchant = owner.get_active_held_item() || owner.get_inactive_held_item() + if(!to_enchant) + if(feedback) + to_chat(owner, span_warning("You need to hold something to empower it!")) + return FALSE + if(!to_enchant.force) + if(feedback) + to_chat(owner, span_warning("[to_enchant] is too weak to empower! Find something that'll hurt someone!")) + return FALSE + return ..() + +/datum/action/cooldown/spell/sanguine_strike/cast(mob/living/cast_on) + . = ..() + // Then charge their main hand item, then charge their offhand item + var/obj/item/to_enchant = cast_on.get_active_held_item() || cast_on.get_inactive_held_item() + if(!to_enchant) + //this shouldn't have passed can_cast_spell, but sanity is needed + return + to_chat(cast_on, span_notice("[to_enchant] begins to glow red...")) + apply_enchantment(to_enchant) + //true cooldown starts when you use the item or drop it + StartCooldown(INFINITY) + +/datum/action/cooldown/spell/sanguine_strike/proc/apply_enchantment(obj/item/enchanted) + original_force = enchanted.force + enchanted.add_filter("sanguine_strike", 2, list("type" = "outline", "color" = "#c41515", "size" = 2)) + enchanted.force = min(enchanted.force * 2, enchanted.force + 20) + enchanted.AddElement(/datum/element/lifesteal, enchanted.force) + RegisterSignal(enchanted, COMSIG_ITEM_AFTERATTACK, PROC_REF(on_enchanted_afterattack)) + RegisterSignal(enchanted, COMSIG_ITEM_DROPPED, PROC_REF(on_dropped)) + +/// signal called from attacking with the enchanted item +/datum/action/cooldown/spell/sanguine_strike/proc/on_enchanted_afterattack(obj/item/enchanted, atom/target, mob/user, proximity_flag, click_parameters) + SIGNAL_HANDLER + end_enchantment(enchanted) + if(!isliving(target)) + return + var/mob/living/living_target = target + if(living_target.blood_volume < BLOOD_VOLUME_SURVIVE) + return + playsound(target, "sound/effects/wounds/crackandbleed.ogg", 100) + playsound(target, 'sound/magic/charge.ogg', 100) + var/attack_direction = get_dir(user, living_target) + if(iscarbon(living_target)) + var/mob/living/carbon/carbon_target = living_target + carbon_target.spray_blood(attack_direction, 3) + living_target.blood_volume -= 50 + if(!isliving(user)) + return + var/mob/living/living_user = user + //if we blind-added blood volume to the caster, non-vampire wizards could easily kill themselves by using the spell enough + if(living_user.blood_volume < BLOOD_VOLUME_MAXIMUM) + living_user.blood_volume += 50 + +/// signal called from dropping the enchanted item +/datum/action/cooldown/spell/sanguine_strike/proc/on_dropped(obj/item/enchanted, mob/dropper) + SIGNAL_HANDLER + to_chat(dropper, span_notice("[enchanted] seems to lose its red glow.")) + end_enchantment(enchanted) + +/// ends the enchantment, starting the cooldown (which was frozen until you attacked) +/datum/action/cooldown/spell/sanguine_strike/proc/end_enchantment(obj/item/enchanted) + UnregisterSignal(enchanted, list(COMSIG_ITEM_AFTERATTACK, COMSIG_ITEM_DROPPED)) + StartCooldown() + enchanted.remove_filter("sanguine_strike") + enchanted.force = original_force + enchanted.RemoveElement(/datum/element/lifesteal, enchanted.force) diff --git a/code/modules/spells/spell_types/touch/scream_for_me.dm b/code/modules/spells/spell_types/touch/scream_for_me.dm new file mode 100644 index 00000000000..7fcee6df843 --- /dev/null +++ b/code/modules/spells/spell_types/touch/scream_for_me.dm @@ -0,0 +1,39 @@ +/// Weaker smite, not outright gibbing your target, but a lot more bloody, and Sanguine school, so doesn't get affected by splattercasting. +/datum/action/cooldown/spell/touch/scream_for_me + name = "Scream For Me" + desc = "This wicked spell inflicts many severe wounds on your target, causing them to \ + likely bleed to death unless they recieve immediate medical attention." + button_icon_state = "scream_for_me" + sound = null //trust me, you'll hear their wounds + + school = SCHOOL_SANGUINE + invocation_type = INVOCATION_SHOUT + cooldown_time = 60 SECONDS + cooldown_reduction_per_rank = 10 SECONDS + + invocation = "SCREAM FOR ME!!" + + hand_path = /obj/item/melee/touch_attack/scream_for_me + +/datum/action/cooldown/spell/touch/scream_for_me/on_antimagic_triggered(obj/item/melee/touch_attack/hand, mob/living/victim, mob/living/carbon/caster) + caster.visible_message( + span_warning("The feedback mutilates [caster]'s arm!"), + span_userdanger("The spell bounces from [victim]'s skin back into your arm!"), + ) + var/obj/item/bodypart/to_wound = caster.get_holding_bodypart_of_item(hand) + to_wound.force_wound_upwards(/datum/wound/slash/critical) + +/datum/action/cooldown/spell/touch/scream_for_me/cast_on_hand_hit(obj/item/melee/touch_attack/hand, mob/living/victim, mob/living/carbon/caster) + if(!ishuman(victim)) + return + var/mob/living/carbon/human/human_victim = victim + human_victim.emote("scream") + for(var/obj/item/bodypart/to_wound as anything in human_victim.bodyparts) + to_wound.force_wound_upwards(/datum/wound/slash/critical) + return TRUE + +/obj/item/melee/touch_attack/scream_for_me + name = "\improper bloody touch" + desc = "Guaranteed to make your victims scream, or your money back!" + icon_state = "scream_for_me" + inhand_icon_state = "disintegrate" diff --git a/icons/mob/actions/actions_spells.dmi b/icons/mob/actions/actions_spells.dmi index f4cf28ed023..b9fc18544ab 100644 Binary files a/icons/mob/actions/actions_spells.dmi and b/icons/mob/actions/actions_spells.dmi differ diff --git a/icons/obj/weapons/items_and_weapons.dmi b/icons/obj/weapons/items_and_weapons.dmi index ec0e71aa7af..584ae5f7d19 100644 Binary files a/icons/obj/weapons/items_and_weapons.dmi and b/icons/obj/weapons/items_and_weapons.dmi differ diff --git a/tgstation.dme b/tgstation.dme index 0e0aa96dde1..2e7b2ba8783 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -4686,6 +4686,7 @@ #include "code\modules\spells\spell_types\self\night_vision.dm" #include "code\modules\spells\spell_types\self\personality_commune.dm" #include "code\modules\spells\spell_types\self\rod_form.dm" +#include "code\modules\spells\spell_types\self\sanguine_strike.dm" #include "code\modules\spells\spell_types\self\smoke.dm" #include "code\modules\spells\spell_types\self\soultap.dm" #include "code\modules\spells\spell_types\self\spacetime_distortion.dm" @@ -4704,6 +4705,7 @@ #include "code\modules\spells\spell_types\touch\_touch.dm" #include "code\modules\spells\spell_types\touch\duffelbag_curse.dm" #include "code\modules\spells\spell_types\touch\flesh_to_stone.dm" +#include "code\modules\spells\spell_types\touch\scream_for_me.dm" #include "code\modules\spells\spell_types\touch\smite.dm" #include "code\modules\station_goals\bsa.dm" #include "code\modules\station_goals\dna_vault.dm"