diff --git a/code/game/objects/items/granters.dm b/code/game/objects/items/granters.dm
index d9cd4c15d1b..bec7b165019 100644
--- a/code/game/objects/items/granters.dm
+++ b/code/game/objects/items/granters.dm
@@ -260,7 +260,7 @@
user.Paralyze(40)
/obj/item/book/granter/spell/barnyard
- spell = /obj/effect/proc_holder/spell/targeted/barnyardcurse
+ spell = /obj/effect/proc_holder/spell/pointed/barnyardcurse
spellname = "barnyard"
icon_state ="bookhorses"
desc = "This book is more horse than your mind has room for."
diff --git a/code/modules/antagonists/wizard/equipment/spellbook.dm b/code/modules/antagonists/wizard/equipment/spellbook.dm
index be5a4f9fcf3..d9b88d3bc7c 100644
--- a/code/modules/antagonists/wizard/equipment/spellbook.dm
+++ b/code/modules/antagonists/wizard/equipment/spellbook.dm
@@ -237,7 +237,7 @@
/datum/spellbook_entry/barnyard
name = "Barnyard Curse"
- spell_type = /obj/effect/proc_holder/spell/targeted/barnyardcurse
+ spell_type = /obj/effect/proc_holder/spell/pointed/barnyardcurse
/datum/spellbook_entry/charge
name = "Charge"
diff --git a/code/modules/spells/spell.dm b/code/modules/spells/spell.dm
index ff88b3cca1e..9ff6da7d7f1 100644
--- a/code/modules/spells/spell.dm
+++ b/code/modules/spells/spell.dm
@@ -283,7 +283,15 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
/obj/effect/proc_holder/spell/proc/choose_targets(mob/user = usr) //depends on subtype - /targeted or /aoe_turf
return
-/obj/effect/proc_holder/spell/proc/can_target(mob/living/target)
+/**
+ * can_target: Checks if we are allowed to cast the spell on a target.
+ *
+ * Arguments:
+ * * target The atom that is being targeted by the spell.
+ * * user The mob using the spell.
+ * * silent If the checks should not give any feedback messages.
+ */
+/obj/effect/proc_holder/spell/proc/can_target(atom/target, mob/user, silent = FALSE)
return TRUE
/obj/effect/proc_holder/spell/proc/start_recharge()
@@ -415,7 +423,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
switch(max_targets)
if(0) //unlimited
for(var/mob/living/target in view_or_range(range, user, selection_type))
- if(!can_target(target))
+ if(!can_target(target, user, TRUE))
continue
targets += target
if(1) //single target can be picked
@@ -427,7 +435,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
for(var/mob/living/M in view_or_range(range, user, selection_type))
if(!include_user && user == M)
continue
- if(!can_target(M))
+ if(!can_target(M, user, TRUE))
continue
possible_targets += M
@@ -455,7 +463,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
else
var/list/possible_targets = list()
for(var/mob/living/target in view_or_range(range, user, selection_type))
- if(!can_target(target))
+ if(!can_target(target, user, TRUE))
continue
possible_targets += target
for(var/i=1,i<=max_targets,i++)
@@ -476,11 +484,12 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
return
perform(targets,user=user)
+
/obj/effect/proc_holder/spell/aoe_turf/choose_targets(mob/user = usr)
var/list/targets = list()
for(var/turf/target in view_or_range(range,user,selection_type))
- if(!can_target(target))
+ if(!can_target(target, user, TRUE))
continue
if(!(target in view_or_range(inner_radius,user,selection_type)))
targets += target
diff --git a/code/modules/spells/spell_types/barnyard.dm b/code/modules/spells/spell_types/barnyard.dm
deleted file mode 100644
index 61d7b08aaf6..00000000000
--- a/code/modules/spells/spell_types/barnyard.dm
+++ /dev/null
@@ -1,51 +0,0 @@
-/obj/effect/proc_holder/spell/targeted/barnyardcurse
- name = "Curse of the Barnyard"
- desc = "This spell dooms an unlucky soul to possess the speech and facial attributes of a barnyard animal."
- school = "transmutation"
- charge_type = "recharge"
- charge_max = 150
- charge_counter = 0
- clothes_req = FALSE
- stat_allowed = FALSE
- invocation = "KN'A FTAGHU, PUCK 'BTHNK!"
- invocation_type = "shout"
- range = 7
- cooldown_min = 30
- selection_type = "range"
- var/static/list/compatible_mobs_typecache = typecacheof(list(/mob/living/carbon/human, /mob/living/carbon/monkey))
-
- action_icon_state = "barn"
-
-/obj/effect/proc_holder/spell/targeted/barnyardcurse/cast(list/targets, mob/user = usr)
- if(!targets.len)
- to_chat(user, "No target found in range!")
- return
-
- var/mob/living/carbon/target = targets[1]
-
-
- if(!is_type_in_typecache(target, compatible_mobs_typecache))
- to_chat(user, "You are unable to curse [target]'s head!")
- return
-
- if(!(target in oview(range)))
- to_chat(user, "[target.p_theyre(TRUE)] too far away!")
- return
-
- if(target.anti_magic_check())
- to_chat(user, "The spell had no effect!")
- target.visible_message("[target]'s face bursts into flames, which instantly burst outward, leaving [target] unharmed!", \
- "Your face starts burning up, but the flames are repulsed by your anti-magic protection!")
- return
-
- var/list/masks = list(/obj/item/clothing/mask/pig/cursed, /obj/item/clothing/mask/cowmask/cursed, /obj/item/clothing/mask/horsehead/cursed)
-
- var/choice = pick(masks)
- var/obj/item/clothing/mask/magichead = new choice(get_turf(target))
- target.visible_message("[target]'s face bursts into flames, and a barnyard animal's head takes its place!", \
- "Your face burns up, and shortly after the fire you realise you have the face of a barnyard animal!")
- if(!target.dropItemToGround(target.wear_mask))
- qdel(target.wear_mask)
- target.equip_to_slot_if_possible(magichead, ITEM_SLOT_MASK, 1, 1)
-
- target.flash_act()
diff --git a/code/modules/spells/spell_types/construct_spells.dm b/code/modules/spells/spell_types/construct_spells.dm
index 3835c3fa252..0b577f70b99 100644
--- a/code/modules/spells/spell_types/construct_spells.dm
+++ b/code/modules/spells/spell_types/construct_spells.dm
@@ -275,10 +275,23 @@
playsound(get_turf(S), 'sound/effects/ghost.ogg', 100, TRUE)
new /obj/effect/temp_visual/cult/sac(get_turf(S))
-/obj/effect/proc_holder/spell/targeted/dominate/can_target(mob/living/target)
- if(!isanimal(target) || target.stat)
+/obj/effect/proc_holder/spell/targeted/dominate/can_target(atom/target, mob/user, silent)
+ . = ..()
+ if(!.)
return FALSE
- if("cult" in target.faction)
+ if(!isanimal(target))
+ if(!silent)
+ to_chat(user, "Target is not a lesser creature!")
+ return FALSE
+
+ var/mob/living/simple_animal/animal = target
+ if(animal.stat)
+ if(!silent)
+ to_chat(user, "Target is dead!")
+ return FALSE
+ if("cult" in animal.faction)
+ if(!silent)
+ to_chat(user, "Target is already serving Nar'Sie!")
return FALSE
return TRUE
diff --git a/code/modules/spells/spell_types/pointed.dm b/code/modules/spells/spell_types/pointed.dm
index bb1608c5902..e1cb7b5d016 100644
--- a/code/modules/spells/spell_types/pointed.dm
+++ b/code/modules/spells/spell_types/pointed.dm
@@ -6,6 +6,8 @@
var/deactive_msg = "You dispel the magic..."
/// Message showing to the spell owner upon activating pointed spell.
var/active_msg = "You prepare to use the spell on a target..."
+ /// Variable dictating if the user is allowed to cast a spell on himself.
+ var/self_castable = FALSE
/obj/effect/proc_holder/spell/pointed/Click()
var/mob/living/user = usr
@@ -23,6 +25,9 @@
msg = "[active_msg] Left-click to activate spell on a target!"
add_ranged_ability(user, msg, TRUE)
+/obj/effect/proc_holder/spell/pointed/on_lose(mob/living/user)
+ remove_ranged_ability()
+
/obj/effect/proc_holder/spell/pointed/remove_ranged_ability(msg)
. = ..()
on_deactivation(ranged_ability_user)
@@ -61,14 +66,9 @@
/obj/effect/proc_holder/spell/pointed/InterceptClickOn(mob/living/caller, params, atom/target)
if(..())
return TRUE
- if(!(target in view_or_range(range, ranged_ability_user, selection_type)))
- to_chat(ranged_ability_user, "[target.p_theyre(TRUE)] too far away!")
+ if(!intercept_check(caller, target))
return TRUE
- if(!intercept_check(ranged_ability_user, target))
- return TRUE
- if(!cast_check(user = ranged_ability_user))
- return TRUE
- perform(list(target), user = ranged_ability_user)
+ perform(list(target), user = caller)
remove_ranged_ability()
return TRUE // Do not do any underlying actions after the spell cast
@@ -80,7 +80,14 @@
* * target The atom that is being targeted by the spell via intercept.
*/
/obj/effect/proc_holder/spell/pointed/proc/intercept_check(mob/user, atom/target)
- if(!can_target(target))
- to_chat(user, "Invalid target!")
+ if(!self_castable && target == user)
+ to_chat(user, "You cannot cast the spell on yourself!")
+ return FALSE
+ if(!(target in view_or_range(range, user, selection_type)))
+ to_chat(user, "[target.p_theyre(TRUE)] too far away!")
+ return FALSE
+ if(!can_target(target, user))
+ return FALSE
+ if(!cast_check(FALSE, user))
return FALSE
return TRUE
diff --git a/code/modules/spells/spell_types/pointed/barnyard.dm b/code/modules/spells/spell_types/pointed/barnyard.dm
new file mode 100644
index 00000000000..b527ccec0eb
--- /dev/null
+++ b/code/modules/spells/spell_types/pointed/barnyard.dm
@@ -0,0 +1,70 @@
+/obj/effect/proc_holder/spell/pointed/barnyardcurse
+ name = "Curse of the Barnyard"
+ desc = "This spell dooms an unlucky soul to possess the speech and facial attributes of a barnyard animal."
+ school = "transmutation"
+ charge_type = "recharge"
+ charge_max = 150
+ charge_counter = 0
+ clothes_req = FALSE
+ stat_allowed = FALSE
+ invocation = "KN'A FTAGHU, PUCK 'BTHNK!"
+ invocation_type = "shout"
+ range = 7
+ cooldown_min = 30
+ ranged_mousepointer = 'icons/effects/mouse_pointers/barn_target.dmi'
+ action_icon_state = "barn"
+ active_msg = "You prepare to curse a target..."
+ deactive_msg = "You dispel the curse..."
+ /// List of mobs which are allowed to be a target of the spell
+ var/static/list/compatible_mobs_typecache = typecacheof(list(/mob/living/carbon/human, /mob/living/carbon/monkey))
+
+/obj/effect/proc_holder/spell/pointed/barnyardcurse/cast(list/targets, mob/user)
+ if(!targets.len)
+ to_chat(user, "No target found in range!")
+ return FALSE
+ if(!curse_check(user, targets[1]))
+ return FALSE
+
+ var/mob/living/carbon/target = targets[1]
+
+ var/list/masks = list(/obj/item/clothing/mask/pig/cursed, /obj/item/clothing/mask/cowmask/cursed, /obj/item/clothing/mask/horsehead/cursed)
+ var/choice = pick(masks)
+ var/obj/item/clothing/mask/magichead = new choice(get_turf(target))
+
+ target.visible_message("[target]'s face bursts into flames, and a barnyard animal's head takes its place!", \
+ "Your face burns up, and shortly after the fire you realise you have the face of a barnyard animal!")
+ if(!target.dropItemToGround(target.wear_mask))
+ qdel(target.wear_mask)
+ target.equip_to_slot_if_possible(magichead, ITEM_SLOT_MASK, 1, 1)
+ target.flash_act()
+
+/**
+ * curse_check: Checks if we are allowed and able to curse the target
+ *
+ * Arguments:
+ * * user - caster of the spell
+ * * target - target of the spell
+ * * silent - if set to TRUE, the spell will not produce any feedback messages
+ */
+/obj/effect/proc_holder/spell/pointed/barnyardcurse/proc/curse_check(mob/user, atom/target, silent = FALSE)
+ if(!is_type_in_typecache(target, compatible_mobs_typecache))
+ if(!silent)
+ to_chat(user, "You are unable to curse [target]!")
+ return FALSE
+
+ var/mob/living/carbon/victim = target
+ if(victim.anti_magic_check())
+ if(!silent)
+ to_chat(user, "The spell had no effect!")
+ victim.visible_message("[victim]'s face bursts into flames, which instantly burst outward, leaving [victim] unharmed!", \
+ "Your face starts burning up, but the flames are repulsed by your anti-magic protection!")
+ return FALSE
+ return TRUE
+
+/obj/effect/proc_holder/spell/pointed/barnyardcurse/can_target(atom/target, mob/user, silent)
+ . = ..()
+ if(!.)
+ return FALSE
+ if(!curse_check(user, target, silent))
+ return FALSE
+ return TRUE
diff --git a/code/modules/spells/spell_types/blind.dm b/code/modules/spells/spell_types/pointed/blind.dm
similarity index 85%
rename from code/modules/spells/spell_types/blind.dm
rename to code/modules/spells/spell_types/pointed/blind.dm
index aaccefc745d..a773c5ad8d8 100644
--- a/code/modules/spells/spell_types/blind.dm
+++ b/code/modules/spells/spell_types/pointed/blind.dm
@@ -24,11 +24,12 @@
charge_max = 400 // needs to be higher than the duration or it'll be permanent
sound = 'sound/magic/blind.ogg'
-/obj/effect/proc_holder/spell/pointed/trigger/blind/intercept_check(mob/user, atom/target)
+/obj/effect/proc_holder/spell/pointed/trigger/blind/can_target(atom/target, mob/user, silent)
. = ..()
if(!.)
return FALSE
if(!isliving(target))
- to_chat(user, "You can only blind living beings!")
+ if(!silent)
+ to_chat(user, "You can only blind living beings!")
return FALSE
return TRUE
diff --git a/code/modules/spells/spell_types/mind_transfer.dm b/code/modules/spells/spell_types/pointed/mind_transfer.dm
similarity index 94%
rename from code/modules/spells/spell_types/mind_transfer.dm
rename to code/modules/spells/spell_types/pointed/mind_transfer.dm
index 723fdb20b4f..4a7fcda2e48 100644
--- a/code/modules/spells/spell_types/mind_transfer.dm
+++ b/code/modules/spells/spell_types/pointed/mind_transfer.dm
@@ -109,10 +109,10 @@
return TRUE
-/obj/effect/proc_holder/spell/pointed/mind_transfer/intercept_check(mob/user, atom/target)
+/obj/effect/proc_holder/spell/pointed/mind_transfer/can_target(atom/target, mob/user, silent)
. = ..()
if(!.)
return FALSE
- if(!swap_check(user, target))
+ if(!swap_check(user, target, silent))
return FALSE
return TRUE
diff --git a/icons/effects/mouse_pointers/barn_target.dmi b/icons/effects/mouse_pointers/barn_target.dmi
new file mode 100644
index 00000000000..475a2b88b19
Binary files /dev/null and b/icons/effects/mouse_pointers/barn_target.dmi differ
diff --git a/icons/mob/actions/actions_spells.dmi b/icons/mob/actions/actions_spells.dmi
index da4416370a8..3d31cddb6af 100644
Binary files a/icons/mob/actions/actions_spells.dmi and b/icons/mob/actions/actions_spells.dmi differ
diff --git a/tgstation.dme b/tgstation.dme
index 75cff146110..929c9224358 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -2863,8 +2863,6 @@
#include "code\modules\spells\spell.dm"
#include "code\modules\spells\spell_types\aimed.dm"
#include "code\modules\spells\spell_types\area_teleport.dm"
-#include "code\modules\spells\spell_types\barnyard.dm"
-#include "code\modules\spells\spell_types\blind.dm"
#include "code\modules\spells\spell_types\bloodcrawl.dm"
#include "code\modules\spells\spell_types\charge.dm"
#include "code\modules\spells\spell_types\conjure.dm"
@@ -2884,7 +2882,6 @@
#include "code\modules\spells\spell_types\lichdom.dm"
#include "code\modules\spells\spell_types\lightning.dm"
#include "code\modules\spells\spell_types\mime.dm"
-#include "code\modules\spells\spell_types\mind_transfer.dm"
#include "code\modules\spells\spell_types\personality_commune.dm"
#include "code\modules\spells\spell_types\pointed.dm"
#include "code\modules\spells\spell_types\projectile.dm"
@@ -2903,6 +2900,9 @@
#include "code\modules\spells\spell_types\turf_teleport.dm"
#include "code\modules\spells\spell_types\voice_of_god.dm"
#include "code\modules\spells\spell_types\wizard.dm"
+#include "code\modules\spells\spell_types\pointed\barnyard.dm"
+#include "code\modules\spells\spell_types\pointed\blind.dm"
+#include "code\modules\spells\spell_types\pointed\mind_transfer.dm"
#include "code\modules\station_goals\bsa.dm"
#include "code\modules\station_goals\dna_vault.dm"
#include "code\modules\station_goals\shield.dm"