From 37c61983f43e410229ecfd557f710d66b4dd34e4 Mon Sep 17 00:00:00 2001 From: XDTM Date: Tue, 18 Dec 2018 01:09:35 +0100 Subject: [PATCH] Allows the antimagic component to react to spells, limits holymelon uses (#41739) --- code/__DEFINES/components.dm | 2 +- code/datums/components/anti_magic.dm | 28 +++++++++++++++---- code/datums/mutations/actions.dm | 5 +--- code/datums/status_effects/debuffs.dm | 4 +-- code/game/objects/structures/traps.dm | 5 +++- .../clock_weapons/ratvarian_spear.dm | 2 +- .../clockcult/clock_items/judicial_visor.dm | 4 +-- .../clock_structures/ocular_warden.dm | 2 +- .../clock_structures/taunting_trail.dm | 2 +- code/modules/antagonists/cult/runes.dm | 7 +++-- .../revenant/revenant_abilities.dm | 3 +- code/modules/clothing/spacesuits/hardsuit.dm | 2 +- code/modules/fields/timestop.dm | 1 + code/modules/hydroponics/grown/melon.dm | 14 +++++++++- .../carbon/human/species_types/vampire.dm | 2 +- code/modules/mob/living/living.dm | 2 +- code/modules/mob/mob.dm | 6 ++-- code/modules/projectiles/guns/magic.dm | 2 +- code/modules/spells/spell.dm | 12 ++++---- code/modules/spells/spell_types/forcewall.dm | 2 +- .../spell_types/spacetime_distortion.dm | 2 +- code/modules/spells/spell_types/telepathy.dm | 5 ++-- 22 files changed, 75 insertions(+), 39 deletions(-) diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm index fce08761514f..1c4fe8344c17 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 df03918c5d6e..908aef451154 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 a24db4666d30..c41fd7f13c22 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 eb8e10444978..f719af523b3c 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 414f7efeef03..fe531ae66733 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 15882472ac75..7140bb607df6 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 554384b3d30e..ec324cc0f0e4 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 1772de0c856e..9667373a66f8 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 5c323b2dda55..22f5ccf3d45f 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 5c789a498256..63d818e2b5df 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 51d486972765..631a259b40be 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 8ded4e454971..debd092fd1bb 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 11a5d416e70f..a063296edfc6 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 29691c32891a..8d23089818fa 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 10710096231f..12a887e3b842 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 93072762a60c..845d6c575f61 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -911,7 +911,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 9a1755459cd4..fdf0adc0063f 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -694,15 +694,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 2cb1e8a404e1..5a15a74b7eb9 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 a855a20f50bf..cb2af17e1e4b 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 d5cbcdb96bfb..652242ea9990 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 b241458eadae..b38d44a3af40 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 db7e284ea293..2925c1636fdf 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))