diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm
index 35c250abc32..fb5d53f773f 100644
--- a/code/_onclick/hud/alert.dm
+++ b/code/_onclick/hud/alert.dm
@@ -308,6 +308,11 @@ or shoot a gun to move around via Newton's 3rd Law of Motion."
var/mob/living/L = usr
return L.resist()
+//Constructs
+/obj/screen/alert/holy_fire
+ name = "Holy Fire"
+ desc = "Your body is crumbling from the holy energies. Get out."
+ icon_state = "fire"
//ALIENS
diff --git a/code/datums/spell.dm b/code/datums/spell.dm
index db668cd609a..96216c017de 100644
--- a/code/datums/spell.dm
+++ b/code/datums/spell.dm
@@ -121,6 +121,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
var/critfailchance = 0
var/centcom_cancast = TRUE //Whether or not the spell should be allowed on the admin zlevel
+ var/holy_cancast = TRUE //Whether or not the spell functions in a holy place
var/datum/action/spell_action/action = null
var/action_icon = 'icons/mob/actions/actions.dmi'
@@ -561,6 +562,9 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
if(is_admin_level(user.z) && !centcom_cancast) //Certain spells are not allowed on the centcom zlevel
return 0
+ if(!holy_cancast && user.holy_check())
+ return 0
+
if(charge_check)
switch(charge_type)
if("recharge")
diff --git a/code/datums/spells/construct_spells.dm b/code/datums/spells/construct_spells.dm
index afc91f922ab..d49a2cfb8e6 100644
--- a/code/datums/spells/construct_spells.dm
+++ b/code/datums/spells/construct_spells.dm
@@ -18,6 +18,7 @@
range = 0
summon_type = list(/turf/simulated/floor/engine/cult)
centcom_cancast = FALSE //Stop crashing the server by spawning turfs on transit tiles
+ holy_cancast = FALSE //Stops cult magic from working on holy ground eg: chapel
/obj/effect/proc_holder/spell/aoe_turf/conjure/wall
name = "Summon Cult Wall"
@@ -32,6 +33,7 @@
range = 0
summon_type = list(/turf/simulated/wall/cult/artificer) //we don't want artificer-based runed metal farms
centcom_cancast = FALSE //Stop crashing the server by spawning turfs on transit tiles
+ holy_cancast = FALSE //Stops cult magic from working on holy ground eg: chapel
/obj/effect/proc_holder/spell/aoe_turf/conjure/wall/reinforced
name = "Greater Construction"
@@ -43,6 +45,7 @@
invocation_type = "none"
range = 0
centcom_cancast = FALSE //Stop crashing the server by spawning turfs on transit tiles
+ holy_cancast = FALSE //Stops cult magic from working on holy ground eg: chapel
delay = 50
summon_type = list(/turf/simulated/wall/r_wall)
@@ -58,6 +61,7 @@
invocation = "none"
invocation_type = "none"
range = 0
+ holy_cancast = FALSE //Stops cult magic from working on holy ground eg: chapel
summon_type = list(/obj/item/soulstone)
@@ -77,6 +81,7 @@
invocation = "none"
invocation_type = "none"
range = 0
+ holy_cancast = FALSE //Stops cult magic from working on holy ground eg: chapel
summon_type = list(/obj/structure/cult/functional/pylon)
@@ -92,6 +97,7 @@
invocation = "none"
invocation_type = "none"
range = 0
+ holy_cancast = FALSE //Stops cult magic from working on holy ground eg: chapel
summon_type = list(/obj/effect/forcefield/cult)
summon_lifespan = 200
@@ -111,6 +117,7 @@
clothes_req = FALSE
invocation = "none"
invocation_type = "none"
+ holy_cancast = FALSE //Stops cult magic from working on holy ground eg: chapel
jaunt_in_time = 12
jaunt_in_type = /obj/effect/temp_visual/dir_setting/wraith
jaunt_out_type = /obj/effect/temp_visual/dir_setting/wraith/out
@@ -132,6 +139,7 @@
clothes_req = FALSE
invocation = "none"
invocation_type = "none"
+ holy_cancast = FALSE //Stops cult magic from working on holy ground eg: chapel
proj_lifespan = 10
max_targets = 6
@@ -145,6 +153,7 @@
clothes_req = FALSE
invocation = "none"
invocation_type = "none"
+ holy_cancast = FALSE //Stops cult magic from working on holy ground eg: chapel
range = -1
include_user = 1
cooldown_min = 20 //25 deciseconds reduction per rank
diff --git a/code/game/area/ss13_areas.dm b/code/game/area/ss13_areas.dm
index 736a6d84447..d3a0659d3a8 100644
--- a/code/game/area/ss13_areas.dm
+++ b/code/game/area/ss13_areas.dm
@@ -949,6 +949,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
ambientsounds = HOLY_SOUNDS
is_haunted = TRUE
sound_environment = SOUND_AREA_LARGE_ENCLOSED
+ valid_territory = FALSE
/area/chapel/main
name = "\improper Chapel"
diff --git a/code/game/gamemodes/cult/blood_magic.dm b/code/game/gamemodes/cult/blood_magic.dm
index 2583fd693d3..c34ab872b53 100644
--- a/code/game/gamemodes/cult/blood_magic.dm
+++ b/code/game/gamemodes/cult/blood_magic.dm
@@ -123,6 +123,8 @@
return ..()
/datum/action/innate/cult/blood_spell/Activate()
+ if(owner.holy_check())
+ return
if(magic_path) // If this spell flows from the hand
if(!hand_magic) // If you don't already have the spell active
hand_magic = new magic_path(owner, src)
@@ -387,9 +389,13 @@
..()
/obj/item/melee/blood_magic/attack_self(mob/living/user)
+ if(user.holy_check())
+ return
afterattack(user, user, TRUE)
/obj/item/melee/blood_magic/attack(mob/living/M, mob/living/carbon/user)
+ if(user.holy_check())
+ return
if(!iscarbon(user) || !iscultist(user))
uses = 0
qdel(src)
@@ -703,6 +709,8 @@
// This should really be split into multiple procs
/obj/item/melee/blood_magic/manipulator/afterattack(atom/target, mob/living/carbon/human/user, proximity)
+ if(user.holy_check())
+ return
if(proximity)
if(ishuman(target))
var/mob/living/carbon/human/H = target
@@ -843,6 +851,8 @@
uses += max(1, temp)
/obj/item/melee/blood_magic/manipulator/attack_self(mob/living/user)
+ if(user.holy_check())
+ return
var/list/options = list("Blood Orb (50)", "Blood Recharge (75)", "Blood Spear (150)", "Blood Bolt Barrage (300)")
var/choice = input(user, "Choose a greater blood rite...", "Greater Blood Rites") as null|anything in options
switch(choice)
diff --git a/code/game/gamemodes/cult/cult_actions.dm b/code/game/gamemodes/cult/cult_actions.dm
index ab81f253a32..25a9275f684 100644
--- a/code/game/gamemodes/cult/cult_actions.dm
+++ b/code/game/gamemodes/cult/cult_actions.dm
@@ -27,6 +27,10 @@
/datum/action/innate/cult/comm/proc/cultist_commune(mob/living/user, message)
if(!user || !message)
return
+
+ if(user.holy_check())
+ return
+
if(!user.can_speak())
to_chat(user, "You can't speak!")
return
diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm
index ca1938a76ea..74c69140831 100644
--- a/code/game/gamemodes/cult/cult_items.dm
+++ b/code/game/gamemodes/cult/cult_items.dm
@@ -159,7 +159,7 @@
user.Weaken(5)
/obj/item/clothing/suit/hooded/cultrobes/cult_shield/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
- if(current_charges)
+ if(current_charges && !owner.holy_check())
owner.visible_message("[attack_text] is deflected in a burst of blood-red sparks!")
current_charges--
playsound(loc, "sparks", 100, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
@@ -320,6 +320,7 @@
. = pulled
/obj/item/cult_shift/attack_self(mob/user)
+
if(!uses || !iscarbon(user))
to_chat(user, "[src] is dull and unmoving in your hands.")
return
@@ -328,7 +329,8 @@
step(src, pick(GLOB.alldirs))
to_chat(user, "[src] flickers out of your hands, too eager to move!")
return
-
+ if(user.holy_check())
+ return
var/outer_tele_radius = 9
var/mob/living/carbon/C = user
@@ -443,7 +445,7 @@
* The illusion has a 60% chance to be hostile and attack non-cultists, and a 40% chance to just run away from the user.
*/
/obj/item/shield/mirror/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
- if(iscultist(owner)) // Cultist holding the shield
+ if(iscultist(owner) && !owner.holy_check()) // Cultist holding the shield
// Hit by a projectile
if(istype(hitby, /obj/item/projectile))
@@ -603,7 +605,7 @@
spear = blood_spear
/datum/action/innate/cult/spear/Activate()
- if(owner == spear.loc || cooldown > world.time)
+ if(owner == spear.loc || cooldown > world.time || owner.holy_check())
return
var/ST = get_turf(spear)
var/OT = get_turf(owner)
@@ -629,6 +631,12 @@
fire_sound = 'sound/magic/wand_teleport.ogg'
flags = NOBLUDGEON | DROPDEL
+/obj/item/gun/projectile/shotgun/boltaction/enchanted/arcane_barrage/blood/afterattack(atom/target, mob/living/user, flag, params)
+ if(user.holy_check())
+ return
+ ..()
+
+
/obj/item/ammo_box/magazine/internal/boltaction/enchanted/arcane_barrage/blood
ammo_type = /obj/item/ammo_casing/magic/arcane_barrage/blood
diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm
index 4c98a3c59d3..96874208e79 100644
--- a/code/game/gamemodes/cult/runes.dm
+++ b/code/game/gamemodes/cult/runes.dm
@@ -139,6 +139,8 @@ fail_invoke() is called when the rune fails, via not enough people around or oth
structure_check() searches for nearby cultist structures required for the invocation. Proper structures are pylons, forges, archives, and altars.
*/
/obj/effect/rune/proc/can_invoke(mob/living/user)
+ if(user.holy_check())
+ return
//This proc determines if the rune can be invoked at the time. If there are multiple required cultists, it will find all nearby cultists.
var/list/invokers = list() //people eligible to invoke the rune
var/list/chanters = list() //people who will actually chant the rune when passed to invoke()
diff --git a/code/game/gamemodes/miniantags/revenant/revenant.dm b/code/game/gamemodes/miniantags/revenant/revenant.dm
index fb46533b817..3aa87c78016 100644
--- a/code/game/gamemodes/miniantags/revenant/revenant.dm
+++ b/code/game/gamemodes/miniantags/revenant/revenant.dm
@@ -234,6 +234,8 @@
/mob/living/simple_animal/revenant/proc/castcheck(essence_cost)
if(!src)
return
+ if(holy_check(src))
+ return
var/turf/T = get_turf(src)
if(istype(T, /turf/simulated/wall))
to_chat(src, "You cannot use abilities from inside of a wall.")
diff --git a/code/game/gamemodes/vampire/vampire_powers.dm b/code/game/gamemodes/vampire/vampire_powers.dm
index 4e06cb02df1..6f61663c972 100644
--- a/code/game/gamemodes/vampire/vampire_powers.dm
+++ b/code/game/gamemodes/vampire/vampire_powers.dm
@@ -9,6 +9,7 @@
action_background_icon_state = "bg_vampire"
var/required_blood = 0
var/gain_desc = null
+ holy_cancast = FALSE //Stops cult magic from working on holy ground eg: chapel
/obj/effect/proc_holder/spell/vampire/New()
..()
@@ -39,10 +40,6 @@
if(vampire.bloodusable < required_blood)
to_chat(user, "You require at least [required_blood] units of usable blood to do that!")
return 0
- //chapel check
- if(istype(loc.loc, /area/chapel) && !fullpower)
- to_chat(user, "Your powers are useless on this holy ground.")
- return 0
return ..()
/obj/effect/proc_holder/spell/vampire/can_cast(mob/user = usr, charge_check = TRUE, show_message = FALSE)
diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm
index a004cfd0de8..2317c71d72f 100644
--- a/code/game/objects/items/stacks/sheets/sheet_types.dm
+++ b/code/game/objects/items/stacks/sheets/sheet_types.dm
@@ -380,6 +380,8 @@ GLOBAL_LIST_INIT(cult_recipes, list ( \
if(!iscultist(user))
to_chat(user, "Only one with forbidden knowledge could hope to work this metal...")
return
+ if(user.holy_check())
+ return
if(!is_level_reachable(user.z))
to_chat(user, "The energies of this place interfere with the metal shaping!")
return
diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm
index e45f8e311fd..fc1afda7ffb 100644
--- a/code/modules/mob/living/simple_animal/constructs.dm
+++ b/code/modules/mob/living/simple_animal/constructs.dm
@@ -90,6 +90,17 @@
/mob/living/simple_animal/hostile/construct/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
return FALSE
+/mob/living/simple_animal/hostile/construct/Life(seconds, times_fired)
+ if(holy_check(src))
+ throw_alert("holy_fire", /obj/screen/alert/holy_fire, override = TRUE)
+ visible_message("[src] slowly crumbles to dust in this holy place!", \
+ "Your shell burns as you crumble to dust in this holy place!")
+ playsound(loc, 'sound/items/welder.ogg', 150, TRUE)
+ adjustBruteLoss(maxHealth/8)
+ else
+ clear_alert("holy_fire", clear_override = TRUE)
+ return ..()
+
/////////////////Juggernaut///////////////
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 95538b18995..55c74e1a6ef 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -1456,3 +1456,27 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
*/
/mob/proc/update_runechat_msg_location()
return
+
+GLOBAL_LIST_INIT(holy_areas, typecacheof(list(
+ /area/chapel)))
+
+/mob/proc/holy_check()
+ if(!is_type_in_typecache(loc.loc, GLOB.holy_areas))
+ return FALSE
+
+ //Allows fullpower vampires to bypass holy areas
+ var/datum/vampire/vampire = mind.vampire
+ if(vampire && vampire.get_ability(/datum/vampire_passive/full))
+ return FALSE
+
+ //Allows cult to bypass holy areas once they summon
+ var/datum/game_mode/gamemode = SSticker.mode
+ if(iscultist(src) && gamemode.cult_objs.cult_status == NARSIE_HAS_RISEN)
+ return FALSE
+
+ //Execption for Holy Constructs
+ if(istype(src, /mob/living/simple_animal/hostile/construct) && !iscultist(src))
+ return FALSE
+
+ to_chat(src, "Your powers are useless on this holy ground.")
+ return TRUE