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"