heretics from tg (with changes)

This commit is contained in:
kiwedespars
2020-08-10 19:17:26 -07:00
parent 828f701c9b
commit eb8574d6d6
99 changed files with 3802 additions and 185 deletions
+21 -6
View File
@@ -224,7 +224,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()
@@ -296,6 +304,13 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
/obj/effect/proc_holder/spell/proc/cast(list/targets,mob/user = usr)
return
/obj/effect/proc_holder/spell/proc/view_or_range(distance = world.view, center=usr, type="view")
switch(type)
if("view")
. = view(distance,center)
if("range")
. = range(distance,center)
/obj/effect/proc_holder/spell/proc/revert_cast(mob/user = usr) //resets recharge or readds a charge
switch(charge_type)
if("recharge")
@@ -345,7 +360,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
@@ -357,7 +372,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
@@ -365,7 +380,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
//Adds a safety check post-input to make sure those targets are actually in range.
var/mob/M
if(!random_target)
M = input("Choose the target for the spell.", "Targeting") as null|mob in possible_targets
M = input("Choose the target for the spell.", "Targeting") as null|mob in sortNames(possible_targets)
else
switch(random_target_priority)
if(TARGET_RANDOM)
@@ -385,7 +400,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++)
@@ -411,7 +426,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
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
@@ -0,0 +1,117 @@
/obj/effect/proc_holder/spell/cone
name = "Cone of Nothing"
desc = "Does nothing in a cone! Wow!"
school = "evocation"
charge_max = 100
clothes_req = FALSE
invocation = "FUKAN NOTHAN"
invocation_type = "shout"
sound = 'sound/magic/forcewall.ogg'
action_icon_state = "shield"
range = -1
cooldown_min = 0.5 SECONDS
///This controls how many levels the cone has, increase this value to make a bigger cone.
var/cone_levels = 3
///This value determines if the cone penetrates walls.
var/respect_density = FALSE
/obj/effect/proc_holder/spell/cone/choose_targets(mob/user = usr)
perform(null, user=user)
///This proc creates a list of turfs that are hit by the cone
/obj/effect/proc_holder/spell/cone/proc/cone_helper(var/turf/starter_turf, var/dir_to_use, var/cone_levels = 3)
var/list/turfs_to_return = list()
var/turf/turf_to_use = starter_turf
var/turf/left_turf
var/turf/right_turf
var/right_dir
var/left_dir
switch(dir_to_use)
if(NORTH)
left_dir = WEST
right_dir = EAST
if(SOUTH)
left_dir = EAST
right_dir = WEST
if(EAST)
left_dir = NORTH
right_dir = SOUTH
if(WEST)
left_dir = SOUTH
right_dir = NORTH
for(var/i in 1 to cone_levels)
var/list/level_turfs = list()
turf_to_use = get_step(turf_to_use, dir_to_use)
level_turfs += turf_to_use
if(i != 1)
left_turf = get_step(turf_to_use, left_dir)
level_turfs += left_turf
right_turf = get_step(turf_to_use, right_dir)
level_turfs += right_turf
for(var/left_i in 1 to i -calculate_cone_shape(i))
if(left_turf.density && respect_density)
break
left_turf = get_step(left_turf, left_dir)
level_turfs += left_turf
for(var/right_i in 1 to i -calculate_cone_shape(i))
if(right_turf.density && respect_density)
break
right_turf = get_step(right_turf, right_dir)
level_turfs += right_turf
turfs_to_return += list(level_turfs)
if(i == cone_levels)
continue
if(turf_to_use.density && respect_density)
break
return turfs_to_return
/obj/effect/proc_holder/spell/cone/cast(list/targets,mob/user = usr)
var/list/cone_turfs = cone_helper(get_turf(user), user.dir, cone_levels)
for(var/list/turf_list in cone_turfs)
do_cone_effects(turf_list)
///This proc does obj, mob and turf cone effects on all targets in a list
/obj/effect/proc_holder/spell/cone/proc/do_cone_effects(list/target_turf_list, level)
for(var/target_turf in target_turf_list)
if(!target_turf) //if turf is no longer there
continue
do_turf_cone_effect(target_turf, level)
if(isopenturf(target_turf))
var/turf/open/open_turf = target_turf
for(var/movable_content in open_turf)
if(isobj(movable_content))
do_obj_cone_effect(movable_content, level)
else if(isliving(movable_content))
do_mob_cone_effect(movable_content, level)
///This proc deterimines how the spell will affect turfs.
/obj/effect/proc_holder/spell/cone/proc/do_turf_cone_effect(turf/target_turf, level)
return
///This proc deterimines how the spell will affect objects.
/obj/effect/proc_holder/spell/cone/proc/do_obj_cone_effect(obj/target_obj, level)
return
///This proc deterimines how the spell will affect mobs.
/obj/effect/proc_holder/spell/cone/proc/do_mob_cone_effect(mob/living/target_mob, level)
return
///This proc adjusts the cones width depending on the level.
/obj/effect/proc_holder/spell/cone/proc/calculate_cone_shape(current_level)
var/end_taper_start = round(cone_levels * 0.8)
if(current_level > end_taper_start)
return (current_level % end_taper_start) * 2 //someone more talented and probably come up with a better formula.
else
return 2
///This type of cone gradually affects each level of the cone instead of affecting the entire area at once.
/obj/effect/proc_holder/spell/cone/staggered
/obj/effect/proc_holder/spell/cone/staggered/cast(list/targets,mob/user = usr)
var/level_counter = 0
var/list/cone_turfs = cone_helper(get_turf(user), user.dir, cone_levels)
for(var/list/turf_list in cone_turfs)
level_counter++
addtimer(CALLBACK(src, .proc/do_cone_effects, turf_list, level_counter), 2 * level_counter)
+2 -2
View File
@@ -49,8 +49,8 @@
var/projectile_type = text2path(proj_type)
projectile = new projectile_type(user)
else if(istype(proj_type, /obj/effect/proc_holder/spell))
projectile = new /obj/effect/proc_holder/spell/targeted/trigger(user)
var/obj/effect/proc_holder/spell/targeted/trigger/T = projectile
projectile = new /obj/effect/proc_holder/spell/pointed/trigger(user)
var/obj/effect/proc_holder/spell/pointed/trigger/T = projectile
T.linked_spells += proj_type
else
projectile = new proj_type(user)
@@ -17,7 +17,7 @@
action_icon_state = "jaunt"
/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/cast(list/targets,mob/user = usr) //magnets, so mostly hardcoded
playsound(get_turf(user), 'sound/magic/ethereal_enter.ogg', 50, 1, -1)
play_sound("enter",user)
for(var/mob/living/target in targets)
INVOKE_ASYNC(src, .proc/do_jaunt, target)
@@ -42,7 +42,7 @@
ADD_TRAIT(target, TRAIT_MOBILITY_NOMOVE, src)
target.update_mobility()
holder.reappearing = 1
playsound(get_turf(target), 'sound/magic/ethereal_exit.ogg', 50, 1, -1)
play_sound("exit",target)
sleep(25 - jaunt_in_time)
new jaunt_in_type(mobloc, holder.dir)
target.setDir(holder.dir)
@@ -63,6 +63,13 @@
steam.set_up(10, 0, mobloc)
steam.start()
/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/proc/play_sound(type,mob/living/target)
switch(type)
if("enter")
playsound(get_turf(target), 'sound/magic/ethereal_enter.ogg', 50, TRUE, -1)
if("exit")
playsound(get_turf(target), 'sound/magic/ethereal_exit.ogg', 50, TRUE, -1)
/obj/effect/dummy/phased_mob/spell_jaunt
name = "water"
icon = 'icons/effects/effects.dmi'
@@ -1,88 +0,0 @@
/obj/effect/proc_holder/spell/targeted/mind_transfer
name = "Mind Transfer"
desc = "This spell allows the user to switch bodies with a target."
school = "transmutation"
charge_max = 600
clothes_req = NONE
invocation = "GIN'YU CAPAN"
invocation_type = "whisper"
range = 1
cooldown_min = 200 //100 deciseconds reduction per rank
var/unconscious_amount_caster = 400 //how much the caster is stunned for after the spell
var/unconscious_amount_victim = 400 //how much the victim is stunned for after the spell
action_icon_state = "mindswap"
/*
Urist: I don't feel like figuring out how you store object spells so I'm leaving this for you to do.
Make sure spells that are removed from spell_list are actually removed and deleted when mind transferring.
Also, you never added distance checking after target is selected. I've went ahead and did that.
*/
/obj/effect/proc_holder/spell/targeted/mind_transfer/cast(list/targets, mob/living/user = usr, distanceoverride, silent = FALSE)
if(!targets.len)
if(!silent)
to_chat(user, "<span class='warning'>No mind found!</span>")
return
if(targets.len > 1)
if(!silent)
to_chat(user, "<span class='warning'>Too many minds! You're not a hive damnit!</span>")
return
var/mob/living/target = targets[1]
var/t_He = target.p_they(TRUE)
var/t_is = target.p_are()
if(!(target in oview(range)) && !distanceoverride)//If they are not in overview after selection. Do note that !() is necessary for in to work because ! takes precedence over it.
if(!silent)
to_chat(user, "<span class='warning'>[t_He] [t_is] too far away!</span>")
return
if(ismegafauna(target))
if(!silent)
to_chat(user, "<span class='warning'>This creature is too powerful to control!</span>")
return
if(target.stat == DEAD)
if(!silent)
to_chat(user, "<span class='warning'>You don't particularly want to be dead!</span>")
return
if(!target.key || !target.mind)
if(!silent)
to_chat(user, "<span class='warning'>[t_He] appear[target.p_s()] to be catatonic! Not even magic can affect [target.p_their()] vacant mind.</span>")
return
if(user.suiciding)
if(!silent)
to_chat(user, "<span class='warning'>You're killing yourself! You can't concentrate enough to do this!</span>")
return
var/datum/mind/TM = target.mind
if(target.anti_magic_check(TRUE, FALSE) || TM.has_antag_datum(/datum/antagonist/wizard) || TM.has_antag_datum(/datum/antagonist/cult) || TM.has_antag_datum(/datum/antagonist/clockcult) || TM.has_antag_datum(/datum/antagonist/changeling) || TM.has_antag_datum(/datum/antagonist/rev) || target.key[1] == "@")
if(!silent)
to_chat(user, "<span class='warning'>[target.p_their(TRUE)] mind is resisting your spell!</span>")
return
var/mob/living/victim = target//The target of the spell whos body will be transferred to.
var/mob/living/caster = user//The wizard/whomever doing the body transferring.
//MIND TRANSFER BEGIN
var/mob/dead/observer/ghost = victim.ghostize(FALSE, TRUE)
caster.mind.transfer_to(victim)
ghost.mind.transfer_to(caster)
if(ghost.key)
ghost.transfer_ckey(caster) //have to transfer the key since the mind was not active
qdel(ghost)
//MIND TRANSFER END
//Here we knock both mobs out for a time.
caster.Unconscious(unconscious_amount_caster)
victim.Unconscious(unconscious_amount_victim)
SEND_SOUND(caster, sound('sound/magic/mandswap.ogg'))
SEND_SOUND(victim, sound('sound/magic/mandswap.ogg'))// only the caster and victim hear the sounds, that way no one knows for sure if the swap happened
return TRUE
@@ -1,51 +1,54 @@
/obj/effect/proc_holder/spell/targeted/barnyardcurse
/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 = NONE
stat_allowed = 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/list/compatible_mobs = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
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/targeted/barnyardcurse/cast(list/targets, mob/user = usr)
/obj/effect/proc_holder/spell/pointed/barnyardcurse/cast(list/targets, mob/user)
if(!targets.len)
to_chat(user, "<span class='notice'>No target found in range.</span>")
return
to_chat(user, "<span class='warning'>No target found in range!</span>")
return FALSE
if(!can_target(targets[1], user))
return FALSE
var/mob/living/carbon/target = targets[1]
if(!(target.type in compatible_mobs))
to_chat(user, "<span class='notice'>You are unable to curse [target]'s head!</span>")
return
if(!(target in oview(range)))
to_chat(user, "<span class='notice'>[target.p_theyre(TRUE)] too far away!</span>")
return
if(target.anti_magic_check())
to_chat(user, "<span class='warning'>The spell had no effect!</span>")
target.visible_message("<span class='danger'>[target]'s face bursts into flames, which instantly burst outward, leaving [target] unharmed!</span>", \
"<span class='danger'>Your face starts burning up, but the flames are repulsed by your anti-magic protection!</span>")
return
"<span class='danger'>Your face starts burning up, but the flames are repulsed by your anti-magic protection!</span>")
return FALSE
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))
magichead.flags_inv = null
target.visible_message("<span class='danger'>[target]'s face bursts into flames, and a barnyard animal's head takes its place!</span>", \
"<span class='danger'>Your face burns up, and shortly after the fire you realise you have the face of a barnyard animal!</span>")
if(!target.dropItemToGround(target.wear_mask))
qdel(target.wear_mask)
target.equip_to_slot_if_possible(magichead, SLOT_WEAR_MASK, 1, 1)
target.equip_to_slot_if_possible(magichead, ITEM_SLOT_MASK, 1, 1)
target.flash_act()
/obj/effect/proc_holder/spell/pointed/barnyardcurse/can_target(atom/target, mob/user, silent)
. = ..()
if(!.)
return FALSE
if(!is_type_in_typecache(target, compatible_mobs_typecache))
if(!silent)
to_chat(user, "<span class='warning'>You are unable to curse [target]!</span>")
return FALSE
return TRUE
@@ -0,0 +1,35 @@
/obj/effect/proc_holder/spell/pointed/trigger/blind
name = "Blind"
desc = "This spell temporarily blinds a single target."
school = "transmutation"
charge_max = 300
clothes_req = FALSE
invocation = "STI KALY"
invocation_type = "whisper"
message = "<span class='notice'>Your eyes cry out in pain!</span>"
cooldown_min = 50 //12 deciseconds reduction per rank
starting_spells = list("/obj/effect/proc_holder/spell/targeted/inflict_handler/blind", "/obj/effect/proc_holder/spell/targeted/genetic/blind")
ranged_mousepointer = 'icons/effects/mouse_pointers/blind_target.dmi'
action_icon_state = "blind"
active_msg = "You prepare to blind a target..."
/obj/effect/proc_holder/spell/targeted/inflict_handler/blind
amt_eye_blind = 10
amt_eye_blurry = 20
sound = 'sound/magic/blind.ogg'
/obj/effect/proc_holder/spell/targeted/genetic/blind
mutations = list(BLINDMUT)
duration = 300
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/can_target(atom/target, mob/user, silent)
. = ..()
if(!.)
return FALSE
if(!isliving(target))
if(!silent)
to_chat(user, "<span class='warning'>You can only blind living beings!</span>")
return FALSE
return TRUE
@@ -0,0 +1,103 @@
/obj/effect/proc_holder/spell/pointed/mind_transfer
name = "Mind Transfer"
desc = "This spell allows the user to switch bodies with a target next to him."
school = "transmutation"
charge_max = 600
clothes_req = FALSE
invocation = "GIN'YU CAPAN"
invocation_type = "whisper"
range = 1
cooldown_min = 200 //100 deciseconds reduction per rank
ranged_mousepointer = 'icons/effects/mouse_pointers/mindswap_target.dmi'
action_icon_state = "mindswap"
active_msg = "You prepare to swap minds with a target..."
/// For how long is the caster stunned for after the spell
var/unconscious_amount_caster = 40 SECONDS
/// For how long is the victim stunned for after the spell
var/unconscious_amount_victim = 40 SECONDS
/obj/effect/proc_holder/spell/pointed/mind_transfer/cast(list/targets, mob/living/user, silent = FALSE)
if(!targets.len)
if(!silent)
to_chat(user, "<span class='warning'>No mind found!</span>")
return FALSE
if(targets.len > 1)
if(!silent)
to_chat(user, "<span class='warning'>Too many minds! You're not a hive damnit!</span>")
return FALSE
if(!can_target(targets[1], user, silent))
return FALSE
var/mob/living/victim = targets[1] //The target of the spell whos body will be transferred to.
var/datum/mind/VM = victim.mind
if(victim.anti_magic_check(TRUE, FALSE) || VM.has_antag_datum(/datum/antagonist/wizard) || VM.has_antag_datum(/datum/antagonist/cult) || VM.has_antag_datum(/datum/antagonist/changeling) || VM.has_antag_datum(/datum/antagonist/rev) || victim.key[1] == "@")
if(!silent)
to_chat(user, "<span class='warning'>[victim.p_their(TRUE)] mind is resisting your spell!</span>")
return FALSE
if(istype(victim, /mob/living/simple_animal/hostile/guardian))
var/mob/living/simple_animal/hostile/guardian/stand = victim
if(stand.summoner)
victim = stand.summoner
//You should not be able to enter one of the most powerful side-antags as a fucking wizard.
if(istype(victim,/mob/living/simple_animal/slaughter))
to_chat(user, "<span class='warning'>The devilish contract doesn't include the 'mind swappable' package, please try again another lifetime.</span>")
return
//MIND TRANSFER BEGIN
var/mob/dead/observer/ghost = victim.ghostize()
user.mind.transfer_to(victim)
ghost.mind.transfer_to(user)
if(ghost.key)
user.key = ghost.key //have to transfer the key since the mind was not active
qdel(ghost)
//MIND TRANSFER END
//Here we knock both mobs out for a time.
user.Unconscious(unconscious_amount_caster)
victim.Unconscious(unconscious_amount_victim)
SEND_SOUND(user, sound('sound/magic/mandswap.ogg'))
SEND_SOUND(victim, sound('sound/magic/mandswap.ogg')) // only the caster and victim hear the sounds, that way no one knows for sure if the swap happened
return TRUE
/obj/effect/proc_holder/spell/pointed/mind_transfer/can_target(atom/target, mob/user, silent)
. = ..()
if(!.)
return FALSE
if(!isliving(target))
if(!silent)
to_chat(user, "<span class='warning'>You can only swap minds with living beings!</span>")
return FALSE
if(user == target)
if(!silent)
to_chat(user, "<span class='warning'>You can't swap minds with yourself!</span>")
return FALSE
var/mob/living/victim = target
var/t_He = victim.p_they(TRUE)
if(ismegafauna(victim))
if(!silent)
to_chat(user, "<span class='warning'>This creature is too powerful to control!</span>")
return FALSE
if(victim.stat == DEAD)
if(!silent)
to_chat(user, "<span class='warning'>You don't particularly want to be dead!</span>")
return FALSE
if(!victim.key || !victim.mind)
if(!silent)
to_chat(user, "<span class='warning'>[t_He] appear[victim.p_s()] to be catatonic! Not even magic can affect [victim.p_their()] vacant mind.</span>")
return FALSE
if(user.suiciding)
if(!silent)
to_chat(user, "<span class='warning'>You're killing yourself! You can't concentrate enough to do this!</span>")
return FALSE
if(istype(victim, /mob/living/simple_animal/hostile/guardian))
var/mob/living/simple_animal/hostile/guardian/stand = victim
if(stand.summoner)
if(stand.summoner == user)
if(!silent)
to_chat(user, "<span class='warning'>Swapping minds with your own guardian would just put you back into your own head!</span>")
return FALSE
return TRUE
@@ -0,0 +1,105 @@
/obj/effect/proc_holder/spell/pointed
name = "pointed spell"
ranged_mousepointer = 'icons/effects/mouse_pointers/throw_target.dmi'
action_icon_state = "projectile"
/// Message showing to the spell owner upon deactivating pointed spell.
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
/// Variable dictating if the spell will use turf based aim assist
var/aim_assist = TRUE
/obj/effect/proc_holder/spell/pointed/Trigger(mob/user, skip_can_cast = TRUE)
if(!istype(user))
return
var/msg
if(!can_cast(user))
msg = "<span class='warning'>You can no longer cast [name]!</span>"
remove_ranged_ability(msg)
return
if(active)
msg = "<span class='notice'>[deactive_msg]</span>"
remove_ranged_ability(msg)
else
msg = "<span class='notice'>[active_msg] <B>Left-click to activate spell on a target!</B></span>"
add_ranged_ability(user, msg, TRUE)
on_activation(user)
/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)
/obj/effect/proc_holder/spell/pointed/add_ranged_ability(mob/living/user, msg, forced)
. = ..()
on_activation(user)
/**
* on_activation: What happens upon pointed spell activation.
*
* Arguments:
* * user The mob interacting owning the spell.
*/
/obj/effect/proc_holder/spell/pointed/proc/on_activation(mob/user)
return
/**
* on_activation: What happens upon pointed spell deactivation.
*
* Arguments:
* * user The mob interacting owning the spell.
*/
/obj/effect/proc_holder/spell/pointed/proc/on_deactivation(mob/user)
return
/obj/effect/proc_holder/spell/pointed/update_icon()
if(!action)
return
if(active)
action.button_icon_state = "[action_icon_state]1"
else
action.button_icon_state = "[action_icon_state]"
action.UpdateButtonIcon()
/obj/effect/proc_holder/spell/pointed/InterceptClickOn(mob/living/caller, params, atom/target)
if(..())
return TRUE
if(aim_assist && isturf(target))
var/list/possible_targets = list()
for(var/A in target)
if(intercept_check(caller, A, TRUE))
possible_targets += A
if(possible_targets.len == 1)
target = possible_targets[1]
if(!intercept_check(caller, target))
return TRUE
if(!cast_check(FALSE, caller))
return TRUE
perform(list(target), user = caller)
remove_ranged_ability()
return TRUE // Do not do any underlying actions after the spell cast
/**
* intercept_check: Specific spell checks for InterceptClickOn() targets.
*
* Arguments:
* * user The mob using the ranged spell via intercept.
* * target The atom that is being targeted by the spell via intercept.
* * silent If the checks should produce not any feedback messages for the user.
*/
/obj/effect/proc_holder/spell/pointed/proc/intercept_check(mob/user, atom/target, silent = FALSE)
if(!self_castable && target == user)
if(!silent)
to_chat(user, "<span class='warning'>You cannot cast the spell on yourself!</span>")
return FALSE
if(!(target in view_or_range(range, user, selection_type)))
if(!silent)
to_chat(user, "<span class='warning'>[target.p_theyre(TRUE)] too far away!</span>")
return FALSE
if(!can_target(target, user, silent))
return FALSE
return TRUE
@@ -37,8 +37,8 @@
var/projectile_type = text2path(proj_type)
projectile = new projectile_type(user)
if(istype(proj_type, /obj/effect/proc_holder/spell))
projectile = new /obj/effect/proc_holder/spell/targeted/trigger(user)
var/obj/effect/proc_holder/spell/targeted/trigger/T = projectile
projectile = new /obj/effect/proc_holder/spell/pointed/trigger(user)
var/obj/effect/proc_holder/spell/pointed/trigger/T = projectile
T.linked_spells += proj_type
projectile.icon = proj_icon
projectile.icon_state = proj_icon_state
+4 -8
View File
@@ -1,30 +1,26 @@
/obj/effect/proc_holder/spell/targeted/trigger
/obj/effect/proc_holder/spell/pointed/trigger
name = "Trigger"
desc = "This spell triggers another spell or a few."
var/list/linked_spells = list() //those are just referenced by the trigger spell and are unaffected by it directly
var/list/starting_spells = list() //those are added on New() to contents from default spells and are deleted when the trigger spell is deleted to prevent memory leaks
/obj/effect/proc_holder/spell/targeted/trigger/Initialize()
/obj/effect/proc_holder/spell/pointed/trigger/Initialize()
. = ..()
for(var/spell in starting_spells)
var/spell_to_add = text2path(spell)
new spell_to_add(src) //should result in adding to contents, needs testing
/obj/effect/proc_holder/spell/targeted/trigger/Destroy()
/obj/effect/proc_holder/spell/pointed/trigger/Destroy()
for(var/spell in contents)
qdel(spell)
linked_spells = null
starting_spells = null
return ..()
/obj/effect/proc_holder/spell/targeted/trigger/cast(list/targets,mob/user = usr)
/obj/effect/proc_holder/spell/pointed/trigger/cast(list/targets,mob/user = usr)
playMagSound()
for(var/mob/living/target in targets)
for(var/obj/effect/proc_holder/spell/spell in contents)
spell.perform(list(target),0)
for(var/obj/effect/proc_holder/spell/spell in linked_spells)
spell.perform(list(target),0)
return
-28
View File
@@ -207,40 +207,12 @@
summon_type = list(/mob/living/simple_animal/hostile/netherworld)
cast_sound = 'sound/magic/summonitems_generic.ogg'
/obj/effect/proc_holder/spell/targeted/trigger/blind
name = "Blind"
desc = "This spell temporarily blinds a single person and does not require wizard garb."
school = "transmutation"
charge_max = 300
clothes_req = NONE
invocation = "STI KALY"
invocation_type = "whisper"
message = "<span class='notice'>Your eyes cry out in pain!</span>"
cooldown_min = 50 //12 deciseconds reduction per rank
starting_spells = list("/obj/effect/proc_holder/spell/targeted/inflict_handler/blind","/obj/effect/proc_holder/spell/targeted/genetic/blind")
action_icon_state = "blind"
/obj/effect/proc_holder/spell/aoe_turf/conjure/creature/cult
name = "Summon Creatures (DANGEROUS)"
clothes_req = SPELL_CULT_GARB
charge_max = 5000
summon_amt = 2
/obj/effect/proc_holder/spell/targeted/inflict_handler/blind
amt_eye_blind = 10
amt_eye_blurry = 20
sound = 'sound/magic/blind.ogg'
/obj/effect/proc_holder/spell/targeted/genetic/blind
mutations = list(BLINDMUT)
duration = 300
sound = 'sound/magic/blind.ogg'
/obj/effect/proc_holder/spell/aoe_turf/repulse
name = "Repulse"
desc = "This spell throws everything around the user away."