From 865ff4fa082d890170cd4636df7ea18edf784b17 Mon Sep 17 00:00:00 2001
From: kevinz000 <2003111+kevinz000@users.noreply.github.com>
Date: Tue, 29 Oct 2019 21:26:03 -0700
Subject: [PATCH] Merge pull request #9610 from Ghommie/Ghommie-cit273
ports anti-magic component code updates (holymelon sold separately).
---
code/__DEFINES/inventory.dm | 8 ++-
code/datums/components/anti_magic.dm | 8 ++-
code/datums/status_effects/debuffs.dm | 4 +-
code/game/objects/items/devices/multitool.dm | 4 ++
code/game/objects/items/holy_weapons.dm | 2 +-
code/game/objects/items/weaponry.dm | 13 ++++
code/game/objects/structures/traps.dm | 2 +
.../abductor/equipment/abduction_gear.dm | 20 +++---
.../antagonists/abductor/machinery/console.dm | 4 +-
.../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 | 6 +-
.../revenant/revenant_abilities.dm | 5 +-
code/modules/clothing/head/misc_special.dm | 56 ++++++++++++++---
code/modules/clothing/spacesuits/hardsuit.dm | 2 +-
.../clothing/spacesuits/miscellaneous.dm | 6 +-
code/modules/fields/timestop.dm | 1 +
code/modules/hydroponics/grown/melon.dm | 13 ++--
.../carbon/alien/humanoid/alien_powers.dm | 6 ++
.../carbon/human/species_types/jellypeople.dm | 9 ++-
.../carbon/human/species_types/vampire.dm | 2 +-
code/modules/mob/living/living.dm | 2 +-
code/modules/mob/mob.dm | 8 ++-
code/modules/projectiles/guns/energy/laser.dm | 62 +++++++++++++++++++
code/modules/projectiles/guns/magic.dm | 4 ++
code/modules/projectiles/guns/magic/wand.dm | 7 ++-
code/modules/spells/spell.dm | 39 ++++++++----
code/modules/spells/spell_types/forcewall.dm | 2 +-
.../spell_types/spacetime_distortion.dm | 2 +-
code/modules/spells/spell_types/telepathy.dm | 10 +--
32 files changed, 245 insertions(+), 72 deletions(-)
diff --git a/code/__DEFINES/inventory.dm b/code/__DEFINES/inventory.dm
index 24d381d1a..eb9ed377a 100644
--- a/code/__DEFINES/inventory.dm
+++ b/code/__DEFINES/inventory.dm
@@ -28,7 +28,9 @@
#define ITEM_SLOT_POCKET (1<<11) // this is to allow items with a w_class of WEIGHT_CLASS_NORMAL or WEIGHT_CLASS_BULKY to fit in pockets.
#define ITEM_SLOT_DENYPOCKET (1<<12) // this is to deny items with a w_class of WEIGHT_CLASS_SMALL or WEIGHT_CLASS_TINY to fit in pockets.
#define ITEM_SLOT_NECK (1<<13)
-#define ITEM_SLOT_SUITSTORE (1<<14)
+#define ITEM_SLOT_HANDS (1<<14)
+#define ITEM_SLOT_BACKPACK (1<<15)
+#define ITEM_SLOT_SUITSTORE (1<<16)
//SLOTS
#define SLOT_BACK 1
@@ -86,6 +88,10 @@
. = ITEM_SLOT_ICLOTHING
if(SLOT_L_STORE, SLOT_R_STORE)
. = ITEM_SLOT_POCKET
+ if(SLOT_HANDS)
+ . = ITEM_SLOT_HANDS
+ if(SLOT_IN_BACKPACK)
+ . = ITEM_SLOT_BACKPACK
if(SLOT_S_STORE)
. = ITEM_SLOT_SUITSTORE
diff --git a/code/datums/components/anti_magic.dm b/code/datums/components/anti_magic.dm
index e91332448..6f289af1f 100644
--- a/code/datums/components/anti_magic.dm
+++ b/code/datums/components/anti_magic.dm
@@ -2,12 +2,13 @@
var/magic = FALSE
var/holy = FALSE
var/psychic = FALSE
+ var/allowed_slots = ~ITEM_SLOT_BACKPACK
var/charges = INFINITY
var/blocks_self = TRUE
var/datum/callback/reaction
var/datum/callback/expire
-/datum/component/anti_magic/Initialize(_magic = FALSE, _holy = FALSE, _psychic = FALSE, _charges, _blocks_self = TRUE, datum/callback/_reaction, datum/callback/_expire)
+/datum/component/anti_magic/Initialize(_magic = FALSE, _holy = FALSE, _psychic = FALSE, _allowed_slots, _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)
@@ -19,6 +20,8 @@
magic = _magic
holy = _holy
psychic = _psychic
+ if(_allowed_slots)
+ allowed_slots = _allowed_slots
if(!isnull(_charges))
charges = _charges
blocks_self = _blocks_self
@@ -26,6 +29,9 @@
expire = _expire
/datum/component/anti_magic/proc/on_equip(datum/source, mob/equipper, slot)
+ if(!CHECK_BITFIELD(allowed_slots, slotdefine2slotbit(slot))) //Check that the slot is valid for antimagic
+ 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)
diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm
index 237afdd55..861454097 100644
--- a/code/datums/status_effects/debuffs.dm
+++ b/code/datums/status_effects/debuffs.dm
@@ -223,7 +223,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(chargecost = 0) && number_legs)
if(force_damage || owner.m_intent != MOVE_INTENT_WALK)
if(GLOB.ratvar_awakens)
owner.Knockdown(20)
@@ -316,7 +316,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(chargecost = 0) && 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/items/devices/multitool.dm b/code/game/objects/items/devices/multitool.dm
index 463bc8090..259d43a98 100644
--- a/code/game/objects/items/devices/multitool.dm
+++ b/code/game/objects/items/devices/multitool.dm
@@ -35,6 +35,10 @@
drop_sound = 'sound/items/handling/multitool_drop.ogg'
pickup_sound = 'sound/items/handling/multitool_pickup.ogg'
+/obj/item/multitool/chaplain/Initialize()
+ . = ..()
+ AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, null, null, FALSE)
+
/obj/item/multitool/examine(mob/user)
. = ..()
if(selected_io)
diff --git a/code/game/objects/items/holy_weapons.dm b/code/game/objects/items/holy_weapons.dm
index 93da4a30f..32d19614d 100644
--- a/code/game/objects/items/holy_weapons.dm
+++ b/code/game/objects/items/holy_weapons.dm
@@ -234,7 +234,7 @@
/obj/item/nullrod/Initialize()
. = ..()
- AddComponent(/datum/component/anti_magic, TRUE, TRUE)
+ AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, null, null, FALSE)
/obj/item/nullrod/suicide_act(mob/user)
user.visible_message("[user] is killing [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to get closer to god!")
diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm
index 71a1ded2c..c4a219001 100644
--- a/code/game/objects/items/weaponry.dm
+++ b/code/game/objects/items/weaponry.dm
@@ -517,6 +517,19 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
var/homerun_able = 0
total_mass = 2.7 //a regular wooden major league baseball bat weighs somewhere between 2 to 3.4 pounds, according to google
+/obj/item/melee/baseball_bat/chaplain
+ name = "blessed baseball bat"
+ desc = "There ain't a cult in the league that can withstand a swatter."
+ force = 14
+ throwforce = 14
+ obj_flags = UNIQUE_RENAME
+ var/chaplain_spawnable = TRUE
+ total_mass = TOTAL_MASS_MEDIEVAL_WEAPON
+
+/obj/item/melee/baseball_bat/chaplain/Initialize()
+ . = ..()
+ AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, null, null, FALSE)
+
/obj/item/melee/baseball_bat/homerun
name = "home run bat"
desc = "This thing looks dangerous... Dangerously good at baseball, that is."
diff --git a/code/game/objects/structures/traps.dm b/code/game/objects/structures/traps.dm
index b3c193345..9c1859df0 100644
--- a/code/game/objects/structures/traps.dm
+++ b/code/game/objects/structures/traps.dm
@@ -65,6 +65,8 @@
var/mob/M = AM
if(M.mind in immune_minds)
return
+ if(M.anti_magic_check())
+ flare()
if(charges <= 0)
return
flare()
diff --git a/code/modules/antagonists/abductor/equipment/abduction_gear.dm b/code/modules/antagonists/abductor/equipment/abduction_gear.dm
index 603dd433d..ca336db41 100644
--- a/code/modules/antagonists/abductor/equipment/abduction_gear.dm
+++ b/code/modules/antagonists/abductor/equipment/abduction_gear.dm
@@ -343,8 +343,8 @@
if(QDELETED(G))
return
- if(istype(C.get_item_by_slot(SLOT_HEAD), /obj/item/clothing/head/foilhat))
- to_chat(user, "Your target seems to have some sort of protective headgear on, blocking the message from being sent!")
+ if(C.anti_magic_check(FALSE, FALSE, TRUE, 0))
+ to_chat(user, "Your target seems to have some sort of tinfoil protection on, blocking the message from being sent!")
return
G.mind_control(command, user)
@@ -520,10 +520,10 @@ Congratulations! You are now trained for invasive xenobiology research!"}
/obj/item/abductor_baton/proc/SleepAttack(mob/living/L,mob/living/user)
if(L.incapacitated(TRUE, TRUE))
- if(istype(L.get_item_by_slot(SLOT_HEAD), /obj/item/clothing/head/foilhat))
- to_chat(user, "The specimen's protective headgear is interfering with the sleep inducement!")
- L.visible_message("[user] tried to induced sleep in [L] with [src], but [L.p_their()] headgear protected [L.p_them()]!", \
- "You feel a strange wave of heavy drowsiness wash over you, but your headgear deflects most of it!")
+ if(L.anti_magic_check(FALSE, FALSE, TRUE, 0))
+ to_chat(user, "The specimen's tinfoil protection is interfering with the sleep inducement!")
+ L.visible_message("[user] tried to induced sleep in [L] with [src], but [L.p_their()] tinfoil protected [L.p_them()]!", \
+ "You feel a strange wave of heavy drowsiness wash over you, but your tinfoil protection deflects most of it!")
L.drowsyness += 2
return
L.visible_message("[user] has induced sleep in [L] with [src]!", \
@@ -532,10 +532,10 @@ Congratulations! You are now trained for invasive xenobiology research!"}
L.Sleeping(1200)
log_combat(user, L, "put to sleep")
else
- if(istype(L.get_item_by_slot(SLOT_HEAD), /obj/item/clothing/head/foilhat))
- to_chat(user, "The specimen's protective headgear is completely blocking our sleep inducement methods!")
- L.visible_message("[user] tried to induce sleep in [L] with [src], but [L.p_their()] headgear completely protected [L.p_them()]!", \
- "Any sense of drowsiness is quickly diminished as your headgear deflects the effects!")
+ if(L.anti_magic_check(FALSE, FALSE, TRUE, 0))
+ to_chat(user, "The specimen's tinfoil protection is completely blocking our sleep inducement methods!")
+ L.visible_message("[user] tried to induce sleep in [L] with [src], but [L.p_their()] tinfoil completely protected [L.p_them()]!", \
+ "Any sense of drowsiness is quickly diminished as your tinfoil protection deflects the effects!")
return
L.drowsyness += 1
to_chat(user, "Sleep inducement works fully only on stunned specimens! ")
diff --git a/code/modules/antagonists/abductor/machinery/console.dm b/code/modules/antagonists/abductor/machinery/console.dm
index 30b82398f..6ab1e58cb 100644
--- a/code/modules/antagonists/abductor/machinery/console.dm
+++ b/code/modules/antagonists/abductor/machinery/console.dm
@@ -178,8 +178,8 @@
c.console = src
/obj/machinery/abductor/console/proc/AddSnapshot(mob/living/carbon/human/target)
- if(istype(target.get_item_by_slot(SLOT_HEAD), /obj/item/clothing/head/foilhat))
- say("Subject wearing specialized protective headgear, unable to get a proper scan!")
+ if(target.anti_magic_check(FALSE, FALSE, TRUE, 0))
+ say("Subject wearing specialized protective tinfoil gear, unable to get a proper scan!")
return
var/datum/icon_snapshot/entry = new
entry.name = target.name
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 386a463a4..93d1e2af8 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(chargecost = 0) && !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 f44f67e9c..fe6fe72d0 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 bf50ed2bf..31632b229 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(chargecost = 0))
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 10c68b606..1158b02a4 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(chargecost = 0))
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 48a9879c5..c19931e2e 100644
--- a/code/modules/antagonists/cult/runes.dm
+++ b/code/modules/antagonists/cult/runes.dm
@@ -238,7 +238,7 @@ structure_check() searches for nearby cultist structures required for the invoca
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, FALSE, 0)) //Not chargecost because it can be spammed
+ if(convertee.anti_magic_check(TRUE, TRUE, chargecost = 0)) //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")
@@ -772,7 +772,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(chargecost = 0)
if(I)
if(isitem(I))
to_chat(L, "[I] suddenly burns hotly before returning to normal!")
@@ -802,7 +802,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(chargecost = 0))
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 2fa5306cb..a3984803d 100644
--- a/code/modules/antagonists/revenant/revenant_abilities.dm
+++ b/code/modules/antagonists/revenant/revenant_abilities.dm
@@ -65,7 +65,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)
@@ -112,7 +112,8 @@
action_background_icon_state = "bg_revenant"
notice = "revennotice"
boldnotice = "revenboldnotice"
-
+ holy_check = TRUE
+ tinfoil_check = FALSE
/obj/effect/proc_holder/spell/aoe_turf/revenant
clothes_req = 0
diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm
index 446449627..9b63fdef4 100644
--- a/code/modules/clothing/head/misc_special.dm
+++ b/code/modules/clothing/head/misc_special.dm
@@ -238,26 +238,62 @@
armor = list("melee" = 0, "bullet" = 0, "laser" = -5,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = -5, "fire" = 0, "acid" = 0)
equip_delay_other = 140
var/datum/brain_trauma/mild/phobia/paranoia
+ var/warped = FALSE
clothing_flags = IGNORE_HAT_TOSS
+/obj/item/clothing/head/foilhat/Initialize(mapload)
+ . = ..()
+ if(!warped)
+ AddComponent(/datum/component/anti_magic, FALSE, FALSE, TRUE, ITEM_SLOT_HEAD, 6, TRUE, null, CALLBACK(src, .proc/warp_up))
+ else
+ warp_up()
+
/obj/item/clothing/head/foilhat/equipped(mob/living/carbon/human/user, slot)
- ..()
- if(slot == SLOT_HEAD)
- if(paranoia)
- QDEL_NULL(paranoia)
- paranoia = new()
- user.gain_trauma(paranoia, TRAUMA_RESILIENCE_MAGIC, "conspiracies")
- to_chat(user, "As you don the foiled hat, an entire world of conspiracy theories and seemingly insane ideas suddenly rush into your mind. What you once thought unbelievable suddenly seems.. undeniable. Everything is connected and nothing happens just by accident. You know too much and now they're out to get you. ")
+ . = ..()
+ if(slot != SLOT_HEAD || warped)
+ return
+ if(paranoia)
+ QDEL_NULL(paranoia)
+ paranoia = new()
+ user.gain_trauma(paranoia, TRAUMA_RESILIENCE_MAGIC, "conspiracies")
+ to_chat(user, "As you don the foiled hat, an entire world of conspiracy theories and seemingly insane ideas suddenly rush into your mind. What you once thought unbelievable suddenly seems.. undeniable. Everything is connected and nothing happens just by accident. You know too much and now they're out to get you. ")
+
+/obj/item/clothing/head/foilhat/MouseDrop(atom/over_object)
+ //God Im sorry
+ if(!warped && iscarbon(usr))
+ var/mob/living/carbon/C = usr
+ if(src == C.head)
+ to_chat(C, "Why would you want to take this off? Do you want them to get into your mind?!")
+ return
+ return ..()
/obj/item/clothing/head/foilhat/dropped(mob/user)
- ..()
+ . = ..()
if(paranoia)
QDEL_NULL(paranoia)
+/obj/item/clothing/head/foilhat/proc/warp_up()
+ name = "scorched tinfoil hat"
+ desc = "A badly warped up hat. Quite unprobable this will still work against any of fictional and contemporary dangers it used to."
+ warped = TRUE
+ if(!isliving(loc) || !paranoia)
+ return
+ var/mob/living/target = loc
+ if(target.get_item_by_slot(SLOT_HEAD) != src)
+ return
+ QDEL_NULL(paranoia)
+ if(!target.IsUnconscious())
+ to_chat(target, "Your zealous conspirationism rapidly dissipates as the donned hat warps up into a ruined mess. All those theories starting to sound like nothing but a ridicolous fanfare.")
+
/obj/item/clothing/head/foilhat/attack_hand(mob/user)
- if(iscarbon(user))
+ if(!warped && iscarbon(user))
var/mob/living/carbon/C = user
if(src == C.head)
to_chat(user, "Why would you want to take this off? Do you want them to get into your mind?!")
return
- ..()
+ return ..()
+
+/obj/item/clothing/head/foilhat/microwave_act(obj/machinery/microwave/M)
+ . = ..()
+ if(!warped)
+ warp_up()
diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm
index 83315a40b..560455b5f 100644
--- a/code/modules/clothing/spacesuits/hardsuit.dm
+++ b/code/modules/clothing/spacesuits/hardsuit.dm
@@ -432,7 +432,7 @@
/obj/item/clothing/suit/space/hardsuit/wizard/Initialize()
. = ..()
- AddComponent(/datum/component/anti_magic, TRUE, FALSE)
+ AddComponent(/datum/component/anti_magic, TRUE, FALSE, FALSE, ITEM_SLOT_OCLOTHING, INFINITY, FALSE)
//Medical hardsuit
/obj/item/clothing/head/helmet/space/hardsuit/medical
diff --git a/code/modules/clothing/spacesuits/miscellaneous.dm b/code/modules/clothing/spacesuits/miscellaneous.dm
index dd91258fa..85b55607b 100644
--- a/code/modules/clothing/spacesuits/miscellaneous.dm
+++ b/code/modules/clothing/spacesuits/miscellaneous.dm
@@ -368,6 +368,10 @@ Contains:
resistance_flags = FIRE_PROOF
mutantrace_variation = NO_MUTANTRACE_VARIATION
+/obj/item/clothing/suit/space/hardsuit/ert/paranormal/Initialize()
+ . = ..()
+ AddComponent(/datum/component/anti_magic, FALSE, FALSE, TRUE, ITEM_SLOT_HEAD)
+
/obj/item/clothing/suit/space/hardsuit/ert/paranormal
name = "paranormal response team suit"
desc = "Powerful wards are built into this hardsuit, protecting the user from all manner of paranormal threats."
@@ -380,7 +384,7 @@ Contains:
/obj/item/clothing/suit/space/hardsuit/ert/paranormal/Initialize()
. = ..()
- AddComponent(/datum/component/anti_magic, TRUE, TRUE)
+ AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, ITEM_SLOT_OCLOTHING)
/obj/item/clothing/suit/space/hardsuit/ert/paranormal/inquisitor
name = "inquisitor's hardsuit"
diff --git a/code/modules/fields/timestop.dm b/code/modules/fields/timestop.dm
index 25c67cc34..c59a8004c 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 b3135030e..03131a016 100644
--- a/code/modules/hydroponics/grown/melon.dm
+++ b/code/modules/hydroponics/grown/melon.dm
@@ -59,22 +59,23 @@
wine_power = 70 //Water to wine, baby.
wine_flavor = "divinity"
-/*/obj/item/reagent_containers/food/snacks/grown/holymelon/Initialize()
+/*
+/obj/item/reagent_containers/food/snacks/grown/holymelon/Initialize()
. = ..()
var/uses = 1
if(seed)
uses = round(seed.potency / 20)
- AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, uses, TRUE, CALLBACK(src, .proc/block_magic), CALLBACK(src, .proc/expire)) //deliver us from evil o melon god
-*/
+ AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, ITEM_SLOT_HANDS, 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)
- visible_message("[src] hums slightly, and seems to decay a bit.")
+ to_chat(user, "[src] hums slightly, and seems to decay a bit.")
/obj/item/reagent_containers/food/snacks/grown/holymelon/proc/expire(mob/user)
- visible_message("[src] rapidly turns into ash!")
+ to_chat(user, "[src] rapidly turns into ash!")
qdel(src)
new /obj/effect/decal/cleanable/ash(drop_location())
-
+*/
//Milkmelon
/obj/item/seeds/watermelon/milk
name = "pack of milkmelon seeds"
diff --git a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm
index 509caf81a..e013137b8 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm
@@ -95,8 +95,14 @@ Doesn't work on other aliens/AI.*/
var/mob/living/M = input("Select who to whisper to:","Whisper to?",null) as null|mob in options
if(!M)
return 0
+ if(M.anti_magic_check(FALSE, FALSE, TRUE, 0))
+ to_chat(user, "As you try to communicate with [M], you're suddenly stopped by a vision of a massive tinfoil wall that streches beyond visible range. It seems you've been foiled.")
+ return FALSE
var/msg = sanitize(input("Message:", "Alien Whisper") as text|null)
if(msg)
+ if(M.anti_magic_check(FALSE, FALSE, TRUE, 0))
+ to_chat(user, "As you try to communicate with [M], you're suddenly stopped by a vision of a massive tinfoil wall that streches beyond visible range. It seems you've been foiled.")
+ return
log_directed_talk(user, M, msg, LOG_SAY, tag="alien whisper")
to_chat(M, "You hear a strange, alien voice in your head...[msg]")
to_chat(user, "You said: \"[msg]\" to [M]")
diff --git a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
index 6d811bdc6..137cca07d 100644
--- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
@@ -603,6 +603,8 @@
return FALSE
if(HAS_TRAIT(M, TRAIT_MINDSHIELD)) //mindshield implant, no dice
return FALSE
+ if(M.anti_magic_check(FALSE, FALSE, TRUE, 0))
+ return FALSE
if(M in linked_mobs)
return FALSE
linked_mobs.Add(M)
@@ -688,9 +690,14 @@
var/mob/living/M = input("Select who to send your message to:","Send thought to?",null) as null|mob in options
if(!M)
return
-
+ if(M.anti_magic_check(FALSE, FALSE, TRUE, 0))
+ to_chat(H, "As you try to communicate with [M], you're suddenly stopped by a vision of a massive tinfoil wall that streches beyond visible range. It seems you've been foiled.")
+ return
var/msg = sanitize(input("Message:", "Telepathy") as text|null)
if(msg)
+ if(M.anti_magic_check(FALSE, FALSE, TRUE, 0))
+ to_chat(H, "As you try to communicate with [M], you're suddenly stopped by a vision of a massive tinfoil wall that streches beyond visible range. It seems you've been foiled.")
+ return
log_directed_talk(H, M, msg, LOG_SAY, "slime telepathy")
to_chat(M, "You hear an alien voice in your head... [msg]")
to_chat(H, "You telepathically said: \"[msg]\" to [M]")
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 6c1ac8b11..173888258 100644
--- a/code/modules/mob/living/carbon/human/species_types/vampire.dm
+++ b/code/modules/mob/living/carbon/human/species_types/vampire.dm
@@ -88,7 +88,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, 0))
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 c36aa5356..d457a3d58 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -976,7 +976,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, chargecost = 1, self = FALSE)
. = ..()
if(.)
return
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 5c99826db..fac2f8d3a 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -804,15 +804,17 @@ mob/visible_message(message, self_message, blind_message, vision_distance = DEFA
if(client)
client << output(null, "statbrowser:check_spells")
-/mob/proc/anti_magic_check(magic = TRUE, holy = FALSE)
- if(!magic && !holy)
+/mob/proc/anti_magic_check(magic = TRUE, holy = FALSE, tinfoil = FALSE, chargecost = 1, self = FALSE)
+ if(!magic && !holy && !tinfoil)
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, tinfoil, chargecost, self, protection_sources) & COMPONENT_BLOCK_MAGIC)
if(protection_sources.len)
return pick(protection_sources)
else
return src
+ if((magic && HAS_TRAIT(src, TRAIT_ANTIMAGIC)) || (holy && HAS_TRAIT(src, 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/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm
index 353983e01..fd28694eb 100644
--- a/code/modules/projectiles/guns/energy/laser.dm
+++ b/code/modules/projectiles/guns/energy/laser.dm
@@ -159,3 +159,65 @@
/obj/item/gun/energy/laser/redtag/hitscan
ammo_type = list(/obj/item/ammo_casing/energy/laser/redtag/hitscan)
+
+/obj/item/gun/energy/laser/redtag/hitscan/chaplain
+ name = "\improper holy lasrifle"
+ desc = "A lasrifle from the old Imperium. This one seems to be blessed by techpriests."
+ icon_state = "LaserAK"
+ item_state = null
+ force = 14
+ pin = /obj/item/firing_pin/holy
+ icon = 'modular_citadel/icons/obj/guns/VGguns.dmi'
+ ammo_x_offset = 4
+ ammo_type = list(/obj/item/ammo_casing/energy/laser/redtag/hitscan/holy)
+ lefthand_file = 'modular_citadel/icons/mob/citadel/guns_lefthand.dmi'
+ righthand_file = 'modular_citadel/icons/mob/citadel/guns_righthand.dmi'
+ var/chaplain_spawnable = TRUE
+ total_mass = TOTAL_MASS_MEDIEVAL_WEAPON
+ throw_speed = 3
+ throw_range = 4
+ throwforce = 10
+ obj_flags = UNIQUE_RENAME
+
+/obj/item/gun/energy/laser/redtag/hitscan/chaplain/Initialize()
+ . = ..()
+ AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, null, null, FALSE)
+
+/obj/item/gun/energy/laser/redtag/hitscan/chaplain/handle_suicide(mob/living/carbon/human/user, mob/living/carbon/human/target, params, bypass_timer)
+ if(!ishuman(user) || !ishuman(target))
+ return
+
+ if(semicd)
+ return
+
+ if(user == target)
+ target.visible_message("[user] sticks [src] in [user.p_their()] mouth, ready to pull the trigger...", \
+ "You stick [src] in your mouth, ready to pull the trigger...")
+ else
+ target.visible_message("[user] points [src] at [target]'s head, ready to pull the trigger...", \
+ "[user] points [src] at your head, ready to pull the trigger...")
+
+ semicd = TRUE
+
+ if(!bypass_timer && (!do_mob(user, target, 120) || user.zone_selected != BODY_ZONE_PRECISE_MOUTH))
+ if(user)
+ if(user == target)
+ user.visible_message("[user] decided not to shoot.")
+ else if(target && target.Adjacent(user))
+ target.visible_message("[user] has decided to spare [target]", "[user] has decided to spare your life!")
+ semicd = FALSE
+ return
+
+ semicd = FALSE
+
+ target.visible_message("[user] pulls the trigger!", "[user] pulls the trigger!")
+
+ playsound('sound/weapons/dink.ogg', 30, 1)
+
+ if((iscultist(target)) || (is_servant_of_ratvar(target)))
+ chambered.BB.damage *= 1500
+
+ else if(chambered && chambered.BB)
+ chambered.BB.damage *= 5
+
+ process_fire(target, user, TRUE, params)
diff --git a/code/modules/projectiles/guns/magic.dm b/code/modules/projectiles/guns/magic.dm
index e62392ffc..f724f982d 100644
--- a/code/modules/projectiles/guns/magic.dm
+++ b/code/modules/projectiles/guns/magic.dm
@@ -9,6 +9,7 @@
fire_sound = 'sound/weapons/emitter.ogg'
flags_1 = CONDUCT_1
w_class = WEIGHT_CLASS_HUGE
+ var/checks_antimagic = FALSE
var/max_charges = 6
var/charges = 0
var/recharge_rate = 4
@@ -31,6 +32,9 @@
return
else
no_den_usage = 0
+ if(checks_antimagic && user.anti_magic_check(TRUE, FALSE, FALSE, 0, TRUE))
+ to_chat(user, "Something is interfering with [src].")
+ return
. = ..()
/obj/item/gun/magic/can_shoot()
diff --git a/code/modules/projectiles/guns/magic/wand.dm b/code/modules/projectiles/guns/magic/wand.dm
index d5815205d..52236ab69 100644
--- a/code/modules/projectiles/guns/magic/wand.dm
+++ b/code/modules/projectiles/guns/magic/wand.dm
@@ -87,14 +87,17 @@
max_charges = 10 //10, 5, 5, 4
/obj/item/gun/magic/wand/resurrection/zap_self(mob/living/user)
+ ..()
+ charges--
+ if(user.anti_magic_check())
+ user.visible_message("[src] has no effect on [user]!")
+ return
user.revive(full_heal = 1)
if(iscarbon(user))
var/mob/living/carbon/C = user
C.regenerate_limbs()
C.regenerate_organs()
to_chat(user, "You feel great!")
- charges--
- ..()
/obj/item/gun/magic/wand/resurrection/debug //for testing
name = "debug wand of healing"
diff --git a/code/modules/spells/spell.dm b/code/modules/spells/spell.dm
index 98eb6f56b..22dee60eb 100644
--- a/code/modules/spells/spell.dm
+++ b/code/modules/spells/spell.dm
@@ -115,6 +115,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
var/nonabstract_req = 0 //spell can only be cast by mobs that are physical entities
var/stat_allowed = 0 //see if it requires being conscious/alive, need to set to 1 for ghostpells
var/phase_allowed = 0 // If true, the spell can be cast while phased, eg. blood crawling, ethereal jaunting
+ var/antimagic_allowed = TRUE // If false, the spell cannot be cast while under the effect of antimagic
var/invocation = "HURP DURP" //what is uttered when the wizard casts the spell
var/invocation_emote_self = null
var/invocation_type = "none" //can be none, whisper, emote and shout
@@ -147,27 +148,36 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
if(player_lock)
if(!user.mind || !(src in user.mind.spell_list) && !(src in user.mob_spell_list))
to_chat(user, "You shouldn't have this spell! Something's wrong.")
- return 0
+ return FALSE
else
if(!(src in user.mob_spell_list))
- return 0
+ return FALSE
var/turf/T = get_turf(user)
if(is_centcom_level(T.z) && !centcom_cancast) //Certain spells are not allowed on the centcom zlevel
to_chat(user, "You can't cast this spell here.")
- return 0
+ return FALSE
if(!skipcharge)
if(!charge_check(user))
- return 0
+ return FALSE
if(user.stat && !stat_allowed)
to_chat(user, "Not when you're incapacitated.")
- return 0
+ return FALSE
+
+ if(!antimagic_allowed)
+ var/antimagic = user.anti_magic_check(TRUE, FALSE, chargecost = 0, self = TRUE)
+ if(antimagic)
+ if(isitem(antimagic))
+ to_chat(user, "[antimagic] is interfering with your magic.")
+ 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 0
+ return FALSE
if(ishuman(user))
@@ -175,7 +185,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
if((invocation_type == "whisper" || invocation_type == "shout") && !H.can_speak_vocal())
to_chat(user, "You can't get the words out!")
- return 0
+ return FALSE
var/list/casting_clothes = typecacheof(list(/obj/item/clothing/suit/wizrobe,
/obj/item/clothing/suit/space/hardsuit/wizard,
@@ -187,24 +197,24 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
if(clothes_req) //clothes check
if(!is_type_in_typecache(H.wear_suit, casting_clothes))
to_chat(H, "I don't feel strong enough without my robe.")
- return 0
+ return FALSE
if(!is_type_in_typecache(H.head, casting_clothes))
to_chat(H, "I don't feel strong enough without my hat.")
- return 0
+ return FALSE
if(cult_req) //CULT_REQ CLOTHES CHECK
if(!istype(H.wear_suit, /obj/item/clothing/suit/magusred) && !istype(H.wear_suit, /obj/item/clothing/suit/space/hardsuit/cult))
to_chat(H, "I don't feel strong enough without my armor.")
- return 0
+ return FALSE
if(!istype(H.head, /obj/item/clothing/head/magus) && !istype(H.head, /obj/item/clothing/head/helmet/space/hardsuit/cult))
to_chat(H, "I don't feel strong enough without my helmet.")
- return 0
+ return FALSE
else
if(clothes_req || human_req)
to_chat(user, "This spell can only be cast by humans!")
- return 0
+ return FALSE
if(nonabstract_req && (isbrain(user) || ispAI(user)))
to_chat(user, "This spell can only be cast by physical beings!")
- return 0
+ return FALSE
if(!skipcharge)
@@ -499,6 +509,9 @@ 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, chargecost = 0, self = TRUE))
+ return FALSE
+
if(!ishuman(user))
if(clothes_req || human_req)
return FALSE
diff --git a/code/modules/spells/spell_types/forcewall.dm b/code/modules/spells/spell_types/forcewall.dm
index 47d6f71f9..ed78e3315 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(chargecost = 0))
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 7fd857dc5..7a1978767 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(chargecost = 0))
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 db7e284ea..34f100f75 100644
--- a/code/modules/spells/spell_types/telepathy.dm
+++ b/code/modules/spells/spell_types/telepathy.dm
@@ -10,9 +10,11 @@
action_background_icon_state = "bg_spell"
var/notice = "notice"
var/boldnotice = "boldnotice"
- var/magic_check = TRUE
+ var/magic_check = FALSE
+ var/holy_check = FALSE
+ var/tinfoil_check = TRUE
-/obj/effect/proc_holder/spell/targeted/telepathy/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
+/obj/effect/proc_holder/spell/targeted/telepathy/cast(list/targets, mob/living/user = usr)
for(var/mob/living/M in targets)
var/msg = stripped_input(usr, "What do you wish to tell [M]?", null, "")
if(!msg)
@@ -20,11 +22,11 @@
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, tinfoil_check, 0)) //hear no evil
to_chat(M, "You hear something behind you talking... [msg]")
for(var/ded in GLOB.dead_mob_list)
if(!isobserver(ded))
continue
var/follow_rev = FOLLOW_LINK(ded, user)
var/follow_whispee = FOLLOW_LINK(ded, M)
- to_chat(ded, "[follow_rev] [user] [name]: \"[msg]\" to [follow_whispee] [M]")
\ No newline at end of file
+ to_chat(ded, "[follow_rev] [user] [name]: \"[msg]\" to [follow_whispee] [M]")