Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds tiered Antimagic, also makes Heretic school its own thing #642

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,12 @@
#define COMSIG_MOB_RESTRICT_MAGIC "mob_cast_magic"
///from base of mob/can_block_magic(): (mob/user, casted_magic_flags, charge_cost)
#define COMSIG_MOB_RECEIVE_MAGIC "mob_receive_magic"
#define COMPONENT_MAGIC_BLOCKED (1<<0)
/// Magic is blocked, but only surface level effects
#define ANTIMAGIC_TIER_WEAK (1<<0)
/// Magic is blocked, a majority of effects are blocked but especially powerful things may still get through
#define ANTIMAGIC_TIER_STRONG (1<<1)
/// Magic is 100% blocked, no magic can get through
#define ANTIMAGIC_TIER_IMMUNE (1<<2)

///from base of mob/create_mob_hud(): ()
#define COMSIG_MOB_HUD_CREATED "mob_hud_created"
Expand Down
4 changes: 3 additions & 1 deletion code/__DEFINES/magic.dm
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@
// EVIL SPELLS (instant smite + banishment)
/// Necromancy spells, usually involves soul / evil / bad stuff
#define SCHOOL_NECROMANCY "necromancy"
/// Other forbidden magics, such as heretic spells
/// Other forbidden magics
#define SCHOOL_FORBIDDEN "forbidden"
/// Heretic magics
#define SCHOOL_ELDRITCH "eldritch"
/// Blood magic, involves vampirism, draining blood, etc.
#define SCHOOL_SANGUINE "sanguine"

Expand Down
34 changes: 27 additions & 7 deletions code/datums/components/anti_magic.dm
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
/// This provides different types of magic resistance on an object
/datum/component/anti_magic
dupe_mode = COMPONENT_DUPE_ALLOWED
/// A bitflag with the types of magic resistance on the object
var/antimagic_flags
/// The amount of times the object can protect the user from magic
/// Set to INFINITY to have, well, infinite charges.
var/charges
/// The inventory slot the object must be located at in order to activate
var/inventory_flags
/// Callback when a block is successful.
/// You can return NONE from it to have no block occur, or null to use the default block
var/datum/callback/on_block
/// The callback invoked when we have been drained a antimagic charge
var/datum/callback/drain_antimagic
/// The callback invoked when twe have been depleted of all charges
var/datum/callback/expiration
/// Whether we should, on equipping, alert the caster that this item can block any of their spells
/// This changes between true and false on equip and drop, don't set it outright to something
var/alert_caster_on_equip = TRUE
VAR_PRIVATE/alert_caster_on_equip = TRUE
/// The tier of antimagic this object provides
var/antimagic_tier = ANTIMAGIC_TIER_WEAK

/**
* Adds magic resistances to an object
Expand All @@ -37,8 +43,10 @@
antimagic_flags = MAGIC_RESISTANCE,
charges = INFINITY,
inventory_flags = ~ITEM_SLOT_BACKPACK, // items in a backpack won't activate, anywhere else is fine
datum/callback/on_block,
datum/callback/drain_antimagic,
datum/callback/expiration,
anti_magic_tier = ANTIMAGIC_TIER_IMMUNE,
)

if(isitem(parent))
Expand All @@ -53,10 +61,13 @@
src.antimagic_flags = antimagic_flags
src.charges = charges
src.inventory_flags = inventory_flags
src.on_block = on_block
src.drain_antimagic = drain_antimagic
src.expiration = expiration
src.antimagic_tier = anti_magic_tier

/datum/component/anti_magic/Destroy(force)
on_block = null
drain_antimagic = null
expiration = null
return ..()
Expand Down Expand Up @@ -107,11 +118,16 @@
return NONE

// We have already blocked this spell
if(parent in antimagic_sources)
if(antimagic_sources[parent])
return NONE

// Check on_block for custom block behavior, stop if we explicitly return NONE
var/block_tier = on_block?.Invoke(source, parent, casted_magic_flags, charge_cost)
if(block_tier == NONE)
return NONE

// Block success! Add this parent to the list of antimagic sources
antimagic_sources += parent
antimagic_sources[parent] = antimagic_flags

if((charges != INFINITY) && charge_cost > 0)
drain_antimagic?.Invoke(source, parent)
Expand All @@ -120,16 +136,20 @@
expiration?.Invoke(source, parent)
qdel(src) // no more antimagic

return COMPONENT_MAGIC_BLOCKED
// Return whatever the callback returns, or just the base antimagic tier
return block_tier || antimagic_tier

/// cannot cast magic with the same type of antimagic present
/datum/component/anti_magic/proc/restrict_casting_magic(mob/user, magic_flags)
/datum/component/anti_magic/proc/restrict_casting_magic(mob/source, magic_flags)
SIGNAL_HANDLER

if(magic_flags & antimagic_flags)
if(HAS_TRAIT(user, TRAIT_ANTIMAGIC_NO_SELFBLOCK)) // this trait bypasses magic casting restrictions
if(HAS_TRAIT(source, TRAIT_ANTIMAGIC_NO_SELFBLOCK)) // this trait bypasses magic casting restrictions
return NONE
var/block_tier = on_block?.Invoke(source, parent, magic_flags, 0)
if(block_tier == NONE)
return NONE
return COMPONENT_MAGIC_BLOCKED
return block_tier || antimagic_tier

return NONE

Expand Down
1 change: 1 addition & 0 deletions code/datums/components/chuunibyou.dm
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@

SCHOOL_NECROMANCY = "I am the Lord of the Dead, the Master of Bones, the Ruler of Shadows. I command the legions of the damned to rise from their graves and serve me!",
SCHOOL_FORBIDDEN = "I renounce the laws of this world and embrace the chaos of the old gods! Let the forbidden power flow through me and destroy everything in its path!",
SCHOOL_ELDRITCH = "I am the harbinger of the end times, the herald of the apocalypse, the bringer of eternal darkness. Bow before me, mortals, and despair!",
SCHOOL_SANGUINE = "I cover my eye with an eyepatch to seal my true power, but now I will unleash it upon you. I feast on the life force of my prey and grow stronger with every drop!",
)

Expand Down
4 changes: 2 additions & 2 deletions code/datums/components/smooth_tunes.dm
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
if(viable_for_final_effect)
if(finished && linked_songtuner_rite && linked_song)
for(var/mob/living/carbon/human/listener in linked_song.hearing_mobs)
if(listener == parent || listener.can_block_magic(MAGIC_RESISTANCE_HOLY, charge_cost = 1))
if(listener == parent || listener.can_block_magic(MAGIC_RESISTANCE_MIND, charge_cost = 1))
continue

linked_songtuner_rite.finish_effect(listener, parent)
Expand All @@ -105,7 +105,7 @@
/datum/component/smooth_tunes/process(seconds_per_tick = SSOBJ_DT)
if(linked_songtuner_rite && linked_song)
for(var/mob/living/carbon/human/listener in linked_song.hearing_mobs)
if(listener == parent || listener.can_block_magic(MAGIC_RESISTANCE_HOLY, charge_cost = 0))
if(listener == parent || listener.can_block_magic(MAGIC_RESISTANCE_MIND, charge_cost = 0))
continue

linked_songtuner_rite.song_effect(listener, parent)
Expand Down
2 changes: 1 addition & 1 deletion code/datums/mutations/antenna.dm
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@

/datum/action/cooldown/spell/pointed/mindread/cast(mob/living/cast_on)
. = ..()
if(cast_on.can_block_magic(MAGIC_RESISTANCE_MIND, charge_cost = 0))
if(cast_on.can_block_magic(MAGIC_RESISTANCE_MIND, charge_cost = 0) & ANTIMAGIC_TIER_STRONG)
to_chat(owner, span_warning("As you reach into [cast_on]'s mind, \
you are stopped by a mental blockage. It seems you've been foiled."))
return
Expand Down
2 changes: 1 addition & 1 deletion code/datums/proximity_monitor/fields/timestop.dm
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@
return FALSE
if(ismob(A))
var/mob/M = A
if(M.can_block_magic(antimagic_flags))
if(M.can_block_magic(antimagic_flags) & ANTIMAGIC_TIER_IMMUNE)
immune[A] = TRUE
return
var/frozen = TRUE
Expand Down
4 changes: 2 additions & 2 deletions code/game/objects/effects/forcefields.dm
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
return TRUE
if(isliving(mover))
var/mob/living/living_mover = mover
if(living_mover.can_block_magic(antimagic_flags, charge_cost = 0))
if(living_mover.can_block_magic(antimagic_flags, charge_cost = 0) & ANTIMAGIC_TIER_STRONG)
return TRUE

return ..()
Expand Down Expand Up @@ -99,7 +99,7 @@
if(!isliving(mover))
return ..()
var/mob/living/living_mover = mover
if(living_mover.can_block_magic(antimagic_flags, charge_cost = 0))
if(living_mover.can_block_magic(antimagic_flags, charge_cost = 0) & ANTIMAGIC_TIER_STRONG)
return ..()
if(living_mover.has_status_effect(/datum/status_effect/star_mark))
return FALSE
Expand Down
2 changes: 1 addition & 1 deletion code/game/objects/structures/traps.dm
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
var/mob/mob_victim = victim
if(mob_victim.mind in immune_minds)
return
if(mob_victim.can_block_magic(antimagic_flags))
if(mob_victim.can_block_magic(antimagic_flags) & ANTIMAGIC_TIER_STRONG)
flare()
return
if(charges <= 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@
if(QDELETED(target_gland))
return

if(carbon_target.can_block_magic(MAGIC_RESISTANCE_MIND, charge_cost = 0))
if(carbon_target.can_block_magic(MAGIC_RESISTANCE_MIND, charge_cost = 0) & ANTIMAGIC_TIER_IMMUNE)
user.balloon_alert(user, "foiled!")
to_chat(user, span_warning("Your target seems to have some sort of mental blockage, preventing the message from being sent! It seems you've been foiled."))
return
Expand Down Expand Up @@ -399,7 +399,7 @@ Congratulations! You are now trained for invasive xenobiology research!"}
/obj/item/melee/baton/abductor/proc/SleepAttack(mob/living/target, mob/living/user)
playsound(src, on_stun_sound, 50, TRUE, -1)
if(target.incapacitated(IGNORE_RESTRAINTS|IGNORE_GRAB))
if(target.can_block_magic(MAGIC_RESISTANCE_MIND))
if(target.can_block_magic(MAGIC_RESISTANCE_MIND) & ANTIMAGIC_TIER_STRONG)
to_chat(user, span_warning("The specimen has some kind of mental protection that is interfering with the sleep inducement! It seems you've been foiled."))
target.visible_message(span_danger("[user] tried to induced sleep in [target] with [src], but is unsuccessful!"), \
span_userdanger("You feel a strange wave of heavy drowsiness wash over you!"))
Expand All @@ -410,7 +410,7 @@ Congratulations! You are now trained for invasive xenobiology research!"}
target.Sleeping(sleep_time)
log_combat(user, target, "put to sleep")
else
if(target.can_block_magic(MAGIC_RESISTANCE_MIND, charge_cost = 0))
if(target.can_block_magic(MAGIC_RESISTANCE_MIND, charge_cost = 0) & ANTIMAGIC_TIER_STRONG)
to_chat(user, span_warning("The specimen has some kind of mental protection that is completely blocking our sleep inducement methods! It seems you've been foiled."))
target.visible_message(span_danger("[user] tried to induce sleep in [target] with [src], but is unsuccessful!"), \
span_userdanger("Any sense of drowsiness is quickly diminished!"))
Expand Down
2 changes: 1 addition & 1 deletion code/modules/antagonists/abductor/machinery/console.dm
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@
c.console = src

/obj/machinery/abductor/console/proc/AddSnapshot(mob/living/carbon/human/target)
if(target.can_block_magic(MAGIC_RESISTANCE_MIND, charge_cost = 0))
if(target.can_block_magic(MAGIC_RESISTANCE_MIND, charge_cost = 0) & ANTIMAGIC_TIER_STRONG)
say("Unable to get a proper scan of subject! Something is shielding [target]'s mind!")
return
var/datum/icon_snapshot/entry = new
Expand Down
2 changes: 1 addition & 1 deletion code/modules/antagonists/cult/blood_magic.dm
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@
var/old_color = target.color
target.color = rgb(0, 128, 0)
animate(target, color = old_color, time = 1 SECONDS, easing = EASE_IN)
else if(target.can_block_magic())
else if(target.can_block_magic(MAGIC_RESISTANCE_HOLY) & ANTIMAGIC_TIER_IMMUNE)
to_chat(user, span_warning("The spell had no effect!"))
else
to_chat(user, span_cultitalic("In a brilliant flash of red, [target] falls to the ground!"))
Expand Down
4 changes: 2 additions & 2 deletions code/modules/antagonists/cult/cult_items.dm
Original file line number Diff line number Diff line change
Expand Up @@ -736,7 +736,7 @@ Striking a noncultist, however, will tear their flesh."}
playsound(src, 'sound/weapons/throwtap.ogg', 50)
target.visible_message(span_warning("[target] catches [src] out of the air!"))
return
if(target.can_block_magic() || IS_CULTIST(target))
if((target.can_block_magic(MAGIC_RESISTANCE|MAGIC_RESISTANCE_HOLY) & ANTIMAGIC_TIER_IMMUNE) || IS_CULTIST(target))
target.visible_message(span_warning("[src] bounces off of [target], as if repelled by an unseen force!"))
return
if(!..())
Expand Down Expand Up @@ -1029,7 +1029,7 @@ Striking a noncultist, however, will tear their flesh."}
if(isliving(hit_atom))
var/mob/living/target = hit_atom

if(target.can_block_magic() || IS_CULTIST(target))
if((target.can_block_magic(MAGIC_RESISTANCE|MAGIC_RESISTANCE_HOLY) & ANTIMAGIC_TIER_IMMUNE) || IS_CULTIST(target))
target.visible_message(span_warning("[src] bounces off of [target], as if repelled by an unseen force!"))
return
if(IS_CULTIST(target) && target.put_in_active_hand(src))
Expand Down
6 changes: 3 additions & 3 deletions code/modules/antagonists/cult/runes.dm
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ structure_check() searches for nearby cultist structures required for the invoca
to_chat(invoker, span_warning("You need at least two invokers to convert [convertee]!"))
return FALSE

if(convertee.can_block_magic(MAGIC_RESISTANCE|MAGIC_RESISTANCE_HOLY, charge_cost = 0)) //No charge_cost because it can be spammed
if(convertee.can_block_magic(ALL, charge_cost = 0) & ANTIMAGIC_TIER_IMMUNE) //No charge_cost because it can be spammed
for(var/invoker in invokers)
to_chat(invoker, span_warning("Something is shielding [convertee]'s mind!"))
return FALSE
Expand Down Expand Up @@ -898,7 +898,7 @@ GLOBAL_VAR_INIT(narsie_summon_count, 0)
set_light(6, 1, color)
for(var/mob/living/target in viewers(T))
if(!IS_CULTIST(target) && !HAS_TRAIT(target, TRAIT_NOBLOOD)) // NON-MODULE CHANGE
if(target.can_block_magic(charge_cost = 0))
if(target.can_block_magic(MAGIC_RESISTANCE|MAGIC_RESISTANCE_HOLY, charge_cost = 0) & ANTIMAGIC_TIER_STRONG)
continue
to_chat(target, span_cultlarge("Your blood boils in your veins!"))
animate(src, color = "#FCB56D", time = 4)
Expand All @@ -923,7 +923,7 @@ GLOBAL_VAR_INIT(narsie_summon_count, 0)
set_light(6, 1, color)
for(var/mob/living/target in viewers(T))
if(!IS_CULTIST(target) && !HAS_TRAIT(target, TRAIT_NOBLOOD)) // NON-MODULE CHANGE
if(target.can_block_magic(charge_cost = 0))
if(target.can_block_magic(MAGIC_RESISTANCE|MAGIC_RESISTANCE_HOLY, charge_cost = 0) & ANTIMAGIC_TIER_STRONG)
continue
target.take_overall_damage(tick_damage*multiplier, tick_damage*multiplier)

Expand Down
2 changes: 1 addition & 1 deletion code/modules/antagonists/heretic/heretic_antag.dm
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@
SIGNAL_HANDLER

// Heretic spells are of the forbidden school, otherwise we don't care
if(spell.school != SCHOOL_FORBIDDEN)
if(spell.school != SCHOOL_ELDRITCH)
return

// If we've got the trait, we don't care
Expand Down
2 changes: 1 addition & 1 deletion code/modules/antagonists/heretic/heretic_knowledge.dm
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@
loc.balloon_alert(user, "ritual failed, too far!")
return FALSE

if(to_curse.can_block_magic(MAGIC_RESISTANCE|MAGIC_RESISTANCE_HOLY, charge_cost = 0))
if(to_curse.can_block_magic(MAGIC_RESISTANCE|MAGIC_RESISTANCE_HOLY, charge_cost = 0) & ANTIMAGIC_TIER_IMMUNE)
to_chat(to_curse, span_warning("You feel a ghastly chill, but the feeling passes shortly."))
return TRUE

Expand Down
4 changes: 2 additions & 2 deletions code/modules/antagonists/heretic/items/eldritch_painting.dm
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,15 @@
return
if(IS_HERETIC(viewer))
return
if(viewer.can_block_magic(MAGIC_RESISTANCE))
if(viewer.can_block_magic(MAGIC_RESISTANCE|MAGIC_RESISTANCE_MIND) & ANTIMAGIC_TIER_STRONG)
return
to_chat(viewer, span_notice(text_to_display))
viewer.gain_trauma(applied_trauma, TRAUMA_RESILIENCE_SURGERY)
INVOKE_ASYNC(viewer, TYPE_PROC_REF(/mob, emote), "scream")
to_chat(viewer, span_hypnophrase("As you gaze upon the painting, your mind rends to its truth!"))

/obj/structure/sign/painting/eldritch/wirecutter_act(mob/living/user, obj/item/I)
if(!user.can_block_magic(MAGIC_RESISTANCE))
if(!(user.can_block_magic(MAGIC_RESISTANCE|MAGIC_RESISTANCE_MIND) & ANTIMAGIC_TIER_STRONG))
user.add_mood_event("ripped_eldritch_painting", /datum/mood_event/eldritch_painting)
to_chat(user, span_hypnophrase("Laughter echoes through your mind...."))
qdel(src)
Expand Down
2 changes: 1 addition & 1 deletion code/modules/antagonists/heretic/items/heretic_necks.dm
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
user.add_mood_event("Moon Amulette Insanity", /datum/mood_event/amulette_insanity)
user.mob_mood.set_sanity(user.mob_mood.sanity - 50)
return
if(hit.can_block_magic())
if(hit.can_block_magic(ALL) & ANTIMAGIC_TIER_STRONG)
return
if(!hit.mob_mood)
return
Expand Down
7 changes: 3 additions & 4 deletions code/modules/antagonists/heretic/knowledge/moon_lore.dm
Original file line number Diff line number Diff line change
Expand Up @@ -209,11 +209,10 @@
ADD_TRAIT(user, TRAIT_MADNESS_IMMUNE, REF(src))

RegisterSignal(user, COMSIG_LIVING_LIFE, PROC_REF(on_life))

// How many lunatics we have
var/amount_of_lunatics = 0
// Roughly 1/5th of the station will rise up as lunatics to the heretic
for (var/mob/living/carbon/human/crewmate as anything in GLOB.human_list)
// How many lunatics we have
var/amount_of_lunatics = 0
// Where the crewmate is, used to check their z-level
var/turf/crewmate_turf = get_turf(crewmate)
var/crewmate_z = crewmate_turf?.z
Expand All @@ -228,7 +227,7 @@
to_chat(crewmate, span_boldwarning("[user]'s rise is influencing those who are weak willed. Their minds shall rend." ))
continue
// Mindshielded and anti-magic folks are immune against this effect because this is a magical mind effect
if(HAS_TRAIT(crewmate, TRAIT_MINDSHIELD) || crewmate.can_block_magic(MAGIC_RESISTANCE))
if(HAS_TRAIT(crewmate, TRAIT_MINDSHIELD) || (crewmate.can_block_magic(ALL) & ANTIMAGIC_TIER_STRONG))
to_chat(crewmate, span_boldwarning("You feel shielded from something." ))
continue
if(amount_of_lunatics > length(GLOB.human_list) * 0.2)
Expand Down
3 changes: 2 additions & 1 deletion code/modules/antagonists/heretic/magic/aggressive_spread.dm
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@
button_icon_state = "corrode"
sound = 'sound/items/welder.ogg'

school = SCHOOL_FORBIDDEN
school = SCHOOL_ELDRITCH
cooldown_time = 30 SECONDS

invocation = "A'GRSV SPR'D"
invocation_type = INVOCATION_WHISPER
spell_requirements = NONE
antimagic_flags = MAGIC_RESISTANCE|MAGIC_RESISTANCE_HOLY

aoe_radius = 3

Expand Down
5 changes: 3 additions & 2 deletions code/modules/antagonists/heretic/magic/apetravulnera.dm
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@
button_icon = 'icons/mob/actions/actions_ecult.dmi'
button_icon_state = "cleave"

school = SCHOOL_FORBIDDEN
school = SCHOOL_ELDRITCH
cooldown_time = 45 SECONDS

invocation = "AP'TRA VULN'RA!"
invocation_type = INVOCATION_WHISPER
spell_requirements = NONE
antimagic_flags = MAGIC_RESISTANCE|MAGIC_RESISTANCE_HOLY

cast_range = 4
/// What type of wound we apply
Expand All @@ -30,7 +31,7 @@
if(HAS_TRAIT(cast_on, TRAIT_NOBLOOD)) // NON-MODULE CHANGE
return FALSE

if(cast_on.can_block_magic(antimagic_flags))
if(cast_on.can_block_magic(antimagic_flags) & ANTIMAGIC_TIER_IMMUNE)
cast_on.visible_message(
span_danger("[cast_on]'s bruises briefly glow, but repels the effect!"),
span_danger("Your bruises sting a little, but you are protected!")
Expand Down
Loading
Loading