diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm
index fce08761514..1c4fe8344c1 100644
--- a/code/__DEFINES/components.dm
+++ b/code/__DEFINES/components.dm
@@ -131,7 +131,7 @@
#define COMSIG_MOB_CLICKON "mob_clickon" //from base of mob/clickon(): (atom/A, params)
#define COMSIG_MOB_CANCEL_CLICKON 1
#define COMSIG_MOB_ALLOWED "mob_allowed" //from base of obj/allowed(mob/M): (/obj) returns bool, if TRUE the mob has id access to the obj
-#define COMSIG_MOB_RECEIVE_MAGIC "mob_receive_magic" //from base of mob/anti_magic_check(): (magic, holy, protection_sources)
+#define COMSIG_MOB_RECEIVE_MAGIC "mob_receive_magic" //from base of mob/anti_magic_check(): (mob/user, magic, holy, major, self, protection_sources)
#define COMPONENT_BLOCK_MAGIC 1
#define COMSIG_MOB_HUD_CREATED "mob_hud_created" //from base of mob/create_mob_hud(): ()
#define COMSIG_MOB_ATTACK_HAND "mob_attack_hand" //from base of
diff --git a/code/datums/components/anti_magic.dm b/code/datums/components/anti_magic.dm
index df03918c5d6..908aef45115 100644
--- a/code/datums/components/anti_magic.dm
+++ b/code/datums/components/anti_magic.dm
@@ -1,26 +1,44 @@
/datum/component/anti_magic
var/magic = FALSE
var/holy = FALSE
+ var/charges = INFINITY
+ var/blocks_self = TRUE
+ var/datum/callback/reaction
+ var/datum/callback/expire
-/datum/component/anti_magic/Initialize(_magic = FALSE, _holy = FALSE)
+/datum/component/anti_magic/Initialize(_magic = FALSE, _holy = FALSE, _charges, _blocks_self = TRUE, datum/callback/_reaction, datum/callback/_expire)
if(isitem(parent))
RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/on_equip)
RegisterSignal(parent, COMSIG_ITEM_DROPPED, .proc/on_drop)
else if(ismob(parent))
- RegisterSignal(parent, COMSIG_MOB_RECEIVE_MAGIC, .proc/can_protect)
+ RegisterSignal(parent, COMSIG_MOB_RECEIVE_MAGIC, .proc/protect)
else
return COMPONENT_INCOMPATIBLE
magic = _magic
holy = _holy
+ if(!isnull(_charges))
+ charges = _charges
+ blocks_self = _blocks_self
+ reaction = _reaction
+ expire = _expire
/datum/component/anti_magic/proc/on_equip(datum/source, mob/equipper, slot)
- RegisterSignal(equipper, COMSIG_MOB_RECEIVE_MAGIC, .proc/can_protect, TRUE)
+ if(slot == SLOT_IN_BACKPACK)
+ UnregisterSignal(equipper, COMSIG_MOB_RECEIVE_MAGIC)
+ return
+ RegisterSignal(equipper, COMSIG_MOB_RECEIVE_MAGIC, .proc/protect, TRUE)
/datum/component/anti_magic/proc/on_drop(datum/source, mob/user)
UnregisterSignal(user, COMSIG_MOB_RECEIVE_MAGIC)
-/datum/component/anti_magic/proc/can_protect(datum/source, _magic, _holy, list/protection_sources)
- if((_magic && magic) || (_holy && holy))
+/datum/component/anti_magic/proc/protect(datum/source, mob/user, _magic, _holy, major, self, list/protection_sources)
+ if(((_magic && magic) || (_holy && holy)) && (self && blocks_self))
protection_sources += parent
+ reaction.Invoke(user, major)
+ if(major)
+ charges--
+ if(charges <= 0)
+ expire.Invoke(user)
return COMPONENT_BLOCK_MAGIC
+
diff --git a/code/datums/mutations/actions.dm b/code/datums/mutations/actions.dm
index a24db4666d3..c41fd7f13c2 100644
--- a/code/datums/mutations/actions.dm
+++ b/code/datums/mutations/actions.dm
@@ -5,7 +5,7 @@
text_gain_indication = "You can hear your own voice echoing in your mind!"
text_lose_indication = "You don't hear your mind echo anymore."
difficulty = 12
- power = /obj/effect/proc_holder/spell/targeted/telepathy/genetic
+ power = /obj/effect/proc_holder/spell/targeted/telepathy
instability = 10
/datum/mutation/human/telepathy/on_acquiring(mob/living/carbon/human/owner)
@@ -14,9 +14,6 @@
/datum/mutation/human/telepathy/on_losing(mob/living/carbon/human/owner)
. = ..()
-/obj/effect/proc_holder/spell/targeted/telepathy/genetic
- magic_check = FALSE
-
/datum/mutation/human/firebreath
name = "Fire Breath"
desc = "An ancient mutation that gives lizards breath of fire."
diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm
index eb8e1044497..f719af523b3 100644
--- a/code/datums/status_effects/debuffs.dm
+++ b/code/datums/status_effects/debuffs.dm
@@ -146,7 +146,7 @@
/datum/status_effect/belligerent/proc/do_movement_toggle(force_damage)
var/number_legs = owner.get_num_legs(FALSE)
- if(iscarbon(owner) && !is_servant_of_ratvar(owner) && !owner.anti_magic_check() && number_legs)
+ if(iscarbon(owner) && !is_servant_of_ratvar(owner) && !owner.anti_magic_check(major = FALSE) && number_legs)
if(force_damage || owner.m_intent != MOVE_INTENT_WALK)
if(GLOB.ratvar_awakens)
owner.Paralyze(20)
@@ -239,7 +239,7 @@
if(owner.confused)
owner.confused = 0
severity = 0
- else if(!owner.anti_magic_check() && owner.stat != DEAD && severity)
+ else if(!owner.anti_magic_check(major = FALSE) && owner.stat != DEAD && severity)
var/static/hum = get_sfx('sound/effects/screech.ogg') //same sound for every proc call
if(owner.getToxLoss() > MANIA_DAMAGE_TO_CONVERT)
if(is_eligible_servant(owner))
diff --git a/code/game/objects/structures/traps.dm b/code/game/objects/structures/traps.dm
index 414f7efeef0..fe531ae6673 100644
--- a/code/game/objects/structures/traps.dm
+++ b/code/game/objects/structures/traps.dm
@@ -63,7 +63,10 @@
return
if(ismob(AM))
var/mob/M = AM
- if(M.mind in immune_minds || M.anti_magic_check())
+ if(M.mind in immune_minds)
+ return
+ if(M.anti_magic_check())
+ flare()
return
if(charges <= 0)
return
diff --git a/code/modules/antagonists/clockcult/clock_items/clock_weapons/ratvarian_spear.dm b/code/modules/antagonists/clockcult/clock_items/clock_weapons/ratvarian_spear.dm
index 15882472ac7..7140bb607df 100644
--- a/code/modules/antagonists/clockcult/clock_items/clock_weapons/ratvarian_spear.dm
+++ b/code/modules/antagonists/clockcult/clock_items/clock_weapons/ratvarian_spear.dm
@@ -35,7 +35,7 @@
/obj/item/clockwork/weapon/ratvarian_spear/attack(mob/living/target, mob/living/carbon/human/user)
. = ..()
- if(!QDELETED(target) && target.stat != DEAD && !target.anti_magic_check() && !is_servant_of_ratvar(target)) //we do bonus damage on attacks unless they're a servant, have a null rod, or are dead
+ if(!QDELETED(target) && target.stat != DEAD && !target.anti_magic_check(major = FALSE) && !is_servant_of_ratvar(target)) //we do bonus damage on attacks unless they're a servant, have a null rod, or are dead
var/bonus_damage = bonus_burn //normally a total of 20 damage, 30 with ratvar
if(issilicon(target))
target.visible_message("[target] shudders violently at [src]'s touch!", "ERROR: Temperature rising!")
diff --git a/code/modules/antagonists/clockcult/clock_items/judicial_visor.dm b/code/modules/antagonists/clockcult/clock_items/judicial_visor.dm
index 554384b3d30..ec324cc0f0e 100644
--- a/code/modules/antagonists/clockcult/clock_items/judicial_visor.dm
+++ b/code/modules/antagonists/clockcult/clock_items/judicial_visor.dm
@@ -190,8 +190,8 @@
for(var/mob/living/L in range(1, src))
if(is_servant_of_ratvar(L))
continue
- if(L.anti_magic_check())
- var/atom/I = L.anti_magic_check()
+ var/atom/I = L.anti_magic_check()
+ if(I)
if(isitem(I))
L.visible_message("Strange energy flows into [L]'s [I.name]!", \
"Your [I.name] shields you from [src]!")
diff --git a/code/modules/antagonists/clockcult/clock_structures/ocular_warden.dm b/code/modules/antagonists/clockcult/clock_structures/ocular_warden.dm
index 04159639110..8e54ea144f5 100644
--- a/code/modules/antagonists/clockcult/clock_structures/ocular_warden.dm
+++ b/code/modules/antagonists/clockcult/clock_structures/ocular_warden.dm
@@ -60,7 +60,7 @@
else
if(isliving(target))
var/mob/living/L = target
- if(!L.anti_magic_check())
+ if(!L.anti_magic_check(major = FALSE))
if(isrevenant(L))
var/mob/living/simple_animal/revenant/R = L
if(R.revealed)
diff --git a/code/modules/antagonists/clockcult/clock_structures/taunting_trail.dm b/code/modules/antagonists/clockcult/clock_structures/taunting_trail.dm
index 5c323b2dda5..22f5ccf3d45 100644
--- a/code/modules/antagonists/clockcult/clock_structures/taunting_trail.dm
+++ b/code/modules/antagonists/clockcult/clock_structures/taunting_trail.dm
@@ -53,7 +53,7 @@
/obj/structure/destructible/clockwork/taunting_trail/proc/affect_mob(mob/living/L)
if(istype(L) && !is_servant_of_ratvar(L))
- if(!L.anti_magic_check())
+ if(!L.anti_magic_check(major = FALSE))
L.confused = min(L.confused + 15, 50)
L.dizziness = min(L.dizziness + 15, 50)
if(L.confused >= 25)
diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm
index 4a6c3da348a..a38331394c6 100644
--- a/code/modules/antagonists/cult/runes.dm
+++ b/code/modules/antagonists/cult/runes.dm
@@ -230,13 +230,14 @@ structure_check() searches for nearby cultist structures required for the invoca
addtimer(CALLBACK(src, /atom/proc/update_atom_colour), 5)
Cult_team.check_size() // Triggers the eye glow or aura effects if the cult has grown large enough relative to the crew
rune_in_use = FALSE
+
/obj/effect/rune/convert/proc/do_convert(mob/living/convertee, list/invokers)
if(invokers.len < 2)
for(var/M in invokers)
to_chat(M, "You need at least two invokers to convert [convertee]!")
log_game("Offer rune failed - tried conversion with one invoker")
return 0
- if(convertee.anti_magic_check(TRUE, TRUE))
+ if(convertee.anti_magic_check(TRUE, TRUE, major = FALSE)) //Not major because it can be spammed
for(var/M in invokers)
to_chat(M, "Something is shielding [convertee]'s mind!")
log_game("Offer rune failed - convertee had anti-magic")
@@ -764,7 +765,7 @@ structure_check() searches for nearby cultist structures required for the invoca
set_light(6, 1, color)
for(var/mob/living/L in viewers(T))
if(!iscultist(L) && L.blood_volume)
- var/atom/I = L.anti_magic_check()
+ var/atom/I = L.anti_magic_check(major = FALSE)
if(I)
if(isitem(I))
to_chat(L, "[I] suddenly burns hotly before returning to normal!")
@@ -794,7 +795,7 @@ structure_check() searches for nearby cultist structures required for the invoca
set_light(6, 1, color)
for(var/mob/living/L in viewers(T))
if(!iscultist(L) && L.blood_volume)
- if(L.anti_magic_check())
+ if(L.anti_magic_check(major = FALSE))
continue
L.take_overall_damage(tick_damage*multiplier, tick_damage*multiplier)
if(is_servant_of_ratvar(L))
diff --git a/code/modules/antagonists/revenant/revenant_abilities.dm b/code/modules/antagonists/revenant/revenant_abilities.dm
index 51d48697276..631a259b40b 100644
--- a/code/modules/antagonists/revenant/revenant_abilities.dm
+++ b/code/modules/antagonists/revenant/revenant_abilities.dm
@@ -67,7 +67,7 @@
if(target.anti_magic_check(FALSE, TRUE))
to_chat(src, "Something's wrong! [target] seems to be resisting the siphoning, leaving you vulnerable!")
target.visible_message("[target] slumps onto the ground.", \
- "Violets lights, dancing in your vision, receding--")
+ "Violet lights, dancing in your vision, receding--")
draining = FALSE
return
var/datum/beam/B = Beam(target,icon_state="drain_life",time=INFINITY)
@@ -114,6 +114,7 @@
action_background_icon_state = "bg_revenant"
notice = "revennotice"
boldnotice = "revenboldnotice"
+ holy_check = TRUE
/obj/effect/proc_holder/spell/aoe_turf/revenant
clothes_req = 0
diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm
index 8ded4e45497..debd092fd1b 100644
--- a/code/modules/clothing/spacesuits/hardsuit.dm
+++ b/code/modules/clothing/spacesuits/hardsuit.dm
@@ -423,7 +423,7 @@
/obj/item/clothing/suit/space/hardsuit/wizard/Initialize()
. = ..()
- AddComponent(/datum/component/anti_magic, TRUE, FALSE)
+ AddComponent(/datum/component/anti_magic, TRUE, FALSE, _blocks_self = FALSE)
//Medical hardsuit
diff --git a/code/modules/fields/timestop.dm b/code/modules/fields/timestop.dm
index 11a5d416e70..a063296edfc 100644
--- a/code/modules/fields/timestop.dm
+++ b/code/modules/fields/timestop.dm
@@ -133,6 +133,7 @@
/datum/proximity_monitor/advanced/timestop/proc/freeze_mob(mob/living/L)
if(L.anti_magic_check(check_anti_magic, check_holy))
+ immune += L
return
L.Stun(20, 1, 1)
frozen_mobs[L] = L.anchored
diff --git a/code/modules/hydroponics/grown/melon.dm b/code/modules/hydroponics/grown/melon.dm
index 29691c32891..8d23089818f 100644
--- a/code/modules/hydroponics/grown/melon.dm
+++ b/code/modules/hydroponics/grown/melon.dm
@@ -60,4 +60,16 @@
/obj/item/reagent_containers/food/snacks/grown/holymelon/Initialize()
. = ..()
- AddComponent(/datum/component/anti_magic, TRUE, TRUE) //deliver us from evil o melon god
+ var/uses = 1
+ if(seed)
+ uses = round(seed.potency / 20)
+ AddComponent(/datum/component/anti_magic, TRUE, TRUE, uses, TRUE, CALLBACK(src, .proc/block_magic), CALLBACK(src, .proc/expire)) //deliver us from evil o melon god
+
+/obj/item/reagent_containers/food/snacks/grown/holymelon/proc/block_magic(mob/user, major)
+ if(major)
+ to_chat(user, "[src] hums slightly, and seems to decay a bit.")
+
+/obj/item/reagent_containers/food/snacks/grown/holymelon/proc/expire(mob/user)
+ to_chat(user, "[src] rapidly turns into ash!")
+ qdel(src)
+ new /obj/effect/decal/cleanable/ash(drop_location())
diff --git a/code/modules/mob/living/carbon/human/species_types/vampire.dm b/code/modules/mob/living/carbon/human/species_types/vampire.dm
index 10710096231..12a887e3b84 100644
--- a/code/modules/mob/living/carbon/human/species_types/vampire.dm
+++ b/code/modules/mob/living/carbon/human/species_types/vampire.dm
@@ -90,7 +90,7 @@
to_chat(H, "[victim] doesn't have blood!")
return
V.drain_cooldown = world.time + 30
- if(victim.anti_magic_check(FALSE, TRUE))
+ if(victim.anti_magic_check(FALSE, TRUE, FALSE))
to_chat(victim, "[H] tries to bite you, but stops before touching you!")
to_chat(H, "[victim] is blessed! You stop just in time to avoid catching fire.")
return
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 52a1d9e1933..2be289d840b 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -941,7 +941,7 @@
apply_effect((amount*RAD_MOB_COEFFICIENT)/max(1, (radiation**2)*RAD_OVERDOSE_REDUCTION), EFFECT_IRRADIATE, blocked)
-/mob/living/anti_magic_check(magic = TRUE, holy = FALSE)
+/mob/living/anti_magic_check(magic = TRUE, holy = FALSE, major = TRUE, self = FALSE)
. = ..()
if(.)
return
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 121e30e9675..5285d9301df 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -691,15 +691,17 @@
mob_spell_list -= S
qdel(S)
-/mob/proc/anti_magic_check(magic = TRUE, holy = FALSE)
+/mob/proc/anti_magic_check(magic = TRUE, holy = FALSE, major = TRUE, self = FALSE)
if(!magic && !holy)
return
var/list/protection_sources = list()
- if(SEND_SIGNAL(src, COMSIG_MOB_RECEIVE_MAGIC, magic, holy, protection_sources) & COMPONENT_BLOCK_MAGIC)
+ if(SEND_SIGNAL(src, COMSIG_MOB_RECEIVE_MAGIC, src, magic, holy, major, self, protection_sources) & COMPONENT_BLOCK_MAGIC)
if(protection_sources.len)
return pick(protection_sources)
else
return src
+ if((magic && has_trait(TRAIT_ANTIMAGIC)) || (holy && has_trait(TRAIT_HOLY)))
+ return src
//You can buckle on mobs if you're next to them since most are dense
/mob/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE)
diff --git a/code/modules/projectiles/guns/magic.dm b/code/modules/projectiles/guns/magic.dm
index 2cb1e8a404e..5a15a74b7eb 100644
--- a/code/modules/projectiles/guns/magic.dm
+++ b/code/modules/projectiles/guns/magic.dm
@@ -32,7 +32,7 @@
return
else
no_den_usage = 0
- if(checks_antimagic && user.anti_magic_check(TRUE, FALSE))
+ if(checks_antimagic && user.anti_magic_check(TRUE, FALSE, major = FALSE, self = TRUE))
to_chat(user, "Something is interfering with [src].")
return
. = ..()
diff --git a/code/modules/spells/spell.dm b/code/modules/spells/spell.dm
index a855a20f50b..cb2af17e1e4 100644
--- a/code/modules/spells/spell.dm
+++ b/code/modules/spells/spell.dm
@@ -165,16 +165,16 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
if(user.stat && !stat_allowed)
to_chat(user, "Not when you're incapacitated.")
return FALSE
-
+
if(!antimagic_allowed)
- var/antimagic = user.anti_magic_check(TRUE, FALSE)
+ var/antimagic = user.anti_magic_check(TRUE, FALSE, major = FALSE, self = TRUE)
if(antimagic)
if(isitem(antimagic))
to_chat(user, "[antimagic] is interfering with your magic.")
- else
+ else
to_chat(user, "Magic seems to flee from you, you can't gather enough power to cast this spell.")
return FALSE
-
+
if(!phase_allowed && istype(user.loc, /obj/effect/dummy))
to_chat(user, "[name] cannot be cast unless you are completely manifested in the material plane.")
return FALSE
@@ -512,8 +512,8 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
if(user.stat && !stat_allowed)
return FALSE
-
- if(!antimagic_allowed && user.anti_magic_check(TRUE, FALSE))
+
+ if(!antimagic_allowed && user.anti_magic_check(TRUE, FALSE, major = FALSE, self = TRUE))
return FALSE
if(!ishuman(user))
diff --git a/code/modules/spells/spell_types/forcewall.dm b/code/modules/spells/spell_types/forcewall.dm
index d5cbcdb96bf..652242ea999 100644
--- a/code/modules/spells/spell_types/forcewall.dm
+++ b/code/modules/spells/spell_types/forcewall.dm
@@ -35,6 +35,6 @@
return TRUE
if(ismob(mover))
var/mob/M = mover
- if(M.anti_magic_check())
+ if(M.anti_magic_check(major = FALSE))
return TRUE
return FALSE
diff --git a/code/modules/spells/spell_types/spacetime_distortion.dm b/code/modules/spells/spell_types/spacetime_distortion.dm
index b241458eada..b38d44a3af4 100644
--- a/code/modules/spells/spell_types/spacetime_distortion.dm
+++ b/code/modules/spells/spell_types/spacetime_distortion.dm
@@ -86,7 +86,7 @@
/obj/effect/cross_action/spacetime_dist/proc/walk_link(atom/movable/AM)
if(ismob(AM))
var/mob/M = AM
- if(M.anti_magic_check())
+ if(M.anti_magic_check(major = FALSE))
return
if(linked_dist && walks_left > 0)
flick("purplesparkles", src)
diff --git a/code/modules/spells/spell_types/telepathy.dm b/code/modules/spells/spell_types/telepathy.dm
index db7e284ea29..2925c1636fd 100644
--- a/code/modules/spells/spell_types/telepathy.dm
+++ b/code/modules/spells/spell_types/telepathy.dm
@@ -10,7 +10,8 @@
action_background_icon_state = "bg_spell"
var/notice = "notice"
var/boldnotice = "boldnotice"
- var/magic_check = TRUE
+ var/magic_check = FALSE
+ var/holy_check = FALSE
/obj/effect/proc_holder/spell/targeted/telepathy/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
for(var/mob/living/M in targets)
@@ -20,7 +21,7 @@
return
log_directed_talk(user, M, msg, LOG_SAY, "[name]")
to_chat(user, "You transmit to [M]: [msg]")
- if(!magic_check || !M.anti_magic_check(FALSE, TRUE)) //hear no evil
+ if(!M.anti_magic_check(magic_check, holy_check)) //hear no evil
to_chat(M, "You hear something behind you talking... [msg]")
for(var/ded in GLOB.dead_mob_list)
if(!isobserver(ded))