Splattercasting, an offensive, sanguine equivalent to Lichdom. (#70637)

A spell similar to lichdom, though with different conditions.

Dramatically reduces your cooldowns
Cooldown saved is converted into blood lost
You are now a vampire, drinking blood refills your bloodwell, and you're naturally slowly running out.
New school, Sanguine spells, which aren't affected by splattercasting and generally involve blood.
Species change allowed by @SuperNovaa41
This commit is contained in:
tralezab
2022-10-21 20:51:38 +01:00
committed by GitHub
parent 8cfcb98b88
commit fc8d84a3ae
12 changed files with 160 additions and 1 deletions
@@ -33,6 +33,8 @@
// Spell type signals
// Pointed projectiles
// Sent from /datum/action/cooldown/spell/pointed/projectile/fire_projectile() to the caster: (datum/action/cooldown/spell/spell, atom/cast_on, obj/projectile/to_fire)
#define COMSIG_MOB_SPELL_PROJECTILE "mob_spell_projectile"
/// Sent from /datum/action/cooldown/spell/pointed/projectile/on_cast_hit: (atom/firer, atom/target, atom/hit, angle, hit_limb)
#define COMSIG_SPELL_PROJECTILE_HIT "spell_projectile_hit"
+2
View File
@@ -26,6 +26,8 @@
#define SCHOOL_NECROMANCY "necromancy"
/// Other forbidden magics, such as heretic spells
#define SCHOOL_FORBIDDEN "forbidden"
/// Blood magic, involves vampirism, draining blood, etc.
#define SCHOOL_SANGUINE "sanguine"
// Invocation types - what does the wizard need to do to invoke (cast) the spell?
/// Allows being able to cast the spell without saying or doing anything.
+97
View File
@@ -0,0 +1,97 @@
///how much we multiply cooldown (deciseconds) by to get the amount of blood to remove.
///BLOOD_VOLUME_NORMAL is 560, expensive spells max out at around 60 seconds which is 600 deciseconds
///removing 9/10ths of the cooldown from that puts us at 540 deciseconds, mult by 0.5 gives 270 blood taken
///one second is worth 5 blood, roughly half of your normal amount of blood taken for a huge spell, seems fair
#define COOLDOWN_TO_BLOOD_RATIO 0.5
/**
* # splattercasting component!
*
* Component that makes casted spells cost blood from the user and dramatically lowers their cooldown.
*/
/datum/component/splattercasting
/datum/component/splattercasting/Initialize()
if(!iscarbon(parent))
return COMPONENT_INCOMPATIBLE
/datum/component/splattercasting/RegisterWithParent()
. = ..()
RegisterSignal(parent, COMSIG_SPECIES_LOSS, .proc/on_species_change)
RegisterSignal(parent, COMSIG_MOB_SPELL_PROJECTILE, .proc/on_spell_projectile)
RegisterSignal(parent, COMSIG_MOB_BEFORE_SPELL_CAST, .proc/on_before_spell_cast)
RegisterSignal(parent, COMSIG_MOB_AFTER_SPELL_CAST, .proc/on_after_spell_cast)
/datum/component/splattercasting/UnregisterFromParent()
. = ..()
UnregisterSignal(parent, list(COMSIG_SPECIES_LOSS, COMSIG_MOB_SPELL_PROJECTILE, COMSIG_MOB_BEFORE_SPELL_CAST, COMSIG_MOB_AFTER_SPELL_CAST))
///signal sent when a spell casts a projectile
/datum/component/splattercasting/proc/on_species_change(mob/living/carbon/source, datum/species/lost_species)
SIGNAL_HANDLER
qdel(src)
///signal sent when the parent casts a spell that has a projectile
/datum/component/splattercasting/proc/on_spell_projectile(mob/living/carbon/source, datum/action/cooldown/spell/spell, atom/cast_on, obj/projectile/to_fire)
SIGNAL_HANDLER
if(spell.school == SCHOOL_SANGUINE)
//already has blood themed projectiles
return
playsound(source, 'sound/effects/wounds/splatter.ogg', 60, TRUE, -1)
to_fire.color = "#ff7070"
to_fire.name = "blood-[to_fire.name]"
to_fire.set_light(2, 2, LIGHT_COLOR_BLOOD_MAGIC, TRUE)
///signal sent before parent casts a spell
/datum/component/splattercasting/proc/on_before_spell_cast(mob/living/carbon/source, datum/action/cooldown/spell/spell, atom/cast_on)
SIGNAL_HANDLER
var/changed_spell = FALSE
if(!(spell.spell_requirements & SPELL_REQUIRES_NO_ANTIMAGIC))
spell.spell_requirements |= SPELL_REQUIRES_NO_ANTIMAGIC
changed_spell = TRUE
if(!(spell.antimagic_flags & MAGIC_RESISTANCE_HOLY))
spell.antimagic_flags |= MAGIC_RESISTANCE_HOLY
changed_spell = TRUE
if(changed_spell)
//we changed some kind of antimagic so we should check if the new version of the spell is still valid.
//since can_cast_spell has already been checked before "before spell cast" only antimagic check should fail
if(!spell.can_cast_spell(feedback = TRUE))
return SPELL_CANCEL_CAST
///signal sent after parent casts a spell
/datum/component/splattercasting/proc/on_after_spell_cast(mob/living/carbon/source, datum/action/cooldown/spell/spell, atom/cast_on)
SIGNAL_HANDLER
if(spell.school == SCHOOL_SANGUINE)
//allows for sanguine spells that work specially with blood to not interact with splattercasting.
//might sound weird, but maybe in the future we'll have a spell that adds blood to the user when it hits a target
//we wouldn't want that to cost blood.
return
//normal cooldown spell has
var/cooldown_remaining = spell.next_use_time - world.time
//how much we discount, we make the spell cost 1/10th of its actual cooldown
var/new_cooldown = cooldown_remaining / 10
//convert how much cooldown that spell saved into blood cost
var/blood_cost = (cooldown_remaining - new_cooldown ) * COOLDOWN_TO_BLOOD_RATIO
spell.StartCooldown(new_cooldown)
source.blood_volume -= blood_cost
var/cost_desc
switch(blood_cost)
if(1 to 50)
cost_desc = "trickle"
if(51 to 100)
cost_desc = "stream"
if(101 to 200)
cost_desc = "river"
if(201 to INFINITY)
cost_desc = "torrent"
to_chat(source, span_danger("You feel a [cost_desc] of your blood drained into the spell you just cast."))
@@ -189,7 +189,7 @@
switch(school)
if(SCHOOL_HOLY, SCHOOL_MIME, SCHOOL_RESTORATION)
return
if(SCHOOL_NECROMANCY, SCHOOL_FORBIDDEN)
if(SCHOOL_NECROMANCY, SCHOOL_FORBIDDEN, SCHOOL_SANGUINE)
to_chat(user, span_userdanger("[GLOB.deity] is enraged by your use of forbidden magic!"))
lightningbolt(user)
owner.add_mood_event("honorbound", /datum/mood_event/banished)
@@ -54,6 +54,7 @@
it will become easier for others to find your item of power."
spell_type = /datum/action/cooldown/spell/lichdom
category = "Defensive"
no_coexistance_typecache = list(/datum/action/cooldown/spell/splattercasting)
/datum/spellbook_entry/spacetime_dist
name = "Spacetime Distortion"
@@ -77,6 +77,14 @@
spell_type = /datum/action/cooldown/spell/pointed/barnyardcurse
category = "Offensive"
/datum/spellbook_entry/splattercasting
name = "Splattercasting"
desc = "Dramatically lowers the cooldown on all spells, but each one will cost blood, as well as it naturally \
draining from you over time. You can replenish it from your victims, specifically their necks."
spell_type = /datum/action/cooldown/spell/splattercasting
category = "Offensive"
no_coexistance_typecache = list(/datum/action/cooldown/spell/lichdom)
/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."
@@ -32,6 +32,7 @@
/datum/action/cooldown/spell/aoe/magic_missile/proc/fire_projectile(atom/victim, mob/caster)
var/obj/projectile/to_fire = new projectile_type()
to_fire.preparePixelProjectile(victim, caster)
SEND_SIGNAL(caster, COMSIG_MOB_SPELL_PROJECTILE, src, victim, to_fire)
to_fire.fire()
/datum/action/cooldown/spell/aoe/magic_missile/lesser
@@ -160,6 +160,7 @@
for(var/i in 1 to projectiles_per_fire)
var/obj/projectile/to_fire = new projectile_type()
ready_projectile(to_fire, target, owner, i)
SEND_SIGNAL(owner, COMSIG_MOB_SPELL_PROJECTILE, src, target, to_fire)
to_fire.fire()
return TRUE
@@ -26,4 +26,5 @@
/datum/action/cooldown/spell/basic_projectile/proc/fire_projectile(atom/target, atom/caster)
var/obj/projectile/to_fire = new projectile_type()
to_fire.preparePixelProjectile(target, caster)
SEND_SIGNAL(caster, COMSIG_MOB_SPELL_PROJECTILE, src, target, to_fire)
to_fire.fire()
@@ -0,0 +1,44 @@
/datum/action/cooldown/spell/splattercasting
name = "Marrabbio's Splattercasting"
desc = "A spell invented by a banished wizard, who obsessed over aligning \
the primal essences of life and magic into one. Dramatically lowers the \
cooldown on all spells, but each one will cost blood, as well as it naturally \
draining from you. You can replenish it from your victims."
button_icon_state = "splattercasting"
school = SCHOOL_SANGUINE
cooldown_time = 1 SECONDS
invocation = "THE STARS ALIGN! THE COSMOS BLEEDS!"
invocation_type = INVOCATION_SHOUT
spell_requirements = SPELL_REQUIRES_NO_ANTIMAGIC|SPELL_REQUIRES_OFF_CENTCOM|SPELL_REQUIRES_MIND
antimagic_flags = MAGIC_RESISTANCE|MAGIC_RESISTANCE_HOLY
spell_max_level = 1
/datum/action/cooldown/spell/splattercasting/cast(mob/living/cast_on)
. = ..()
to_chat(cast_on, span_green("You focus your arcane knowledge into your lifeforce, your blood simmering with new potential..."))
if(!do_after(cast_on, 5 SECONDS))
to_chat(cast_on, span_warning("Your focus is broken, and the simmering slowly fades."))
return
playsound(cast_on, 'sound/effects/pope_entry.ogg', 100)
to_chat(cast_on, span_danger("You feel your very essense binding to your magic! A stabbing pain within \
brings unimaginable momentary torment as your heart stops, and your skin grows cold. You are now \
merely a vessel for the arcane flow. Soon, all that is left is not pain, but hunger."))
cast_on.set_species(/datum/species/vampire)
cast_on.AddComponent(/datum/component/splattercasting)
if(ishuman(cast_on))
var/mob/living/carbon/human/human_cast_on = cast_on
human_cast_on.dropItemToGround(human_cast_on.w_uniform)
human_cast_on.dropItemToGround(human_cast_on.wear_suit)
human_cast_on.dropItemToGround(human_cast_on.head)
human_cast_on.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe/red(human_cast_on), ITEM_SLOT_OCLOTHING)
human_cast_on.equip_to_slot_or_del(new /obj/item/clothing/head/wizard/red(human_cast_on), ITEM_SLOT_HEAD)
human_cast_on.equip_to_slot_or_del(new /obj/item/clothing/under/color/red(human_cast_on), ITEM_SLOT_ICLOTHING)
qdel(src)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

+2
View File
@@ -884,6 +884,7 @@
#include "code\datums\components\spin2win.dm"
#include "code\datums\components\spinny.dm"
#include "code\datums\components\spirit_holding.dm"
#include "code\datums\components\splattercasting.dm"
#include "code\datums\components\squashable.dm"
#include "code\datums\components\squeak.dm"
#include "code\datums\components\stationloving.dm"
@@ -4424,6 +4425,7 @@
#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"
#include "code\modules\spells\spell_types\self\splattercasting_spell.dm"
#include "code\modules\spells\spell_types\self\stop_time.dm"
#include "code\modules\spells\spell_types\self\summonitem.dm"
#include "code\modules\spells\spell_types\self\voice_of_god.dm"