mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-23 05:00:55 +01:00
Aimed Fireball Spells! (#19030)
* Fireball Spell Changes - Changes the fireball spell to be click-to-fire. - Converted Devil and Wand fireballs as well. - Moved some code to the /proc_holder level to work across the /alien and /spell branches. * Tweaks and Fixes - Infernal Fireball is now a projectile and has the right explosion values. - Removed non-projectile spell versions of fireball, as they are unused - Fixed fireball not seeking adjacent targets. - Fixed incorrect bolding slashes. * Fix Fixes the fireball sometimes missing. * Fixes and tweak - Uses TRUE/FALSE defines instead of 0 and 1 for boolean variables. - Ranged abilities now remove themselves tries to use an ability in a disabled state. (Such as being knocked out) - Define for the click cooldown.
This commit is contained in:
@@ -121,7 +121,7 @@
|
||||
|
||||
wizmind.AddSpell(new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt)
|
||||
wizmind.AddSpell(new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile)
|
||||
wizmind.AddSpell(new /obj/effect/proc_holder/spell/dumbfire/fireball)
|
||||
wizmind.AddSpell(new /obj/effect/proc_holder/spell/fireball)
|
||||
|
||||
current_wizard = wizbody
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ Doesn't work on other aliens/AI.*/
|
||||
panel = "Alien"
|
||||
var/plasma_cost = 0
|
||||
var/check_turf = 0
|
||||
|
||||
var/has_action = 1
|
||||
var/datum/action/spell_action/alien/action = null
|
||||
var/action_icon = 'icons/mob/actions.dmi'
|
||||
@@ -191,31 +190,29 @@ Doesn't work on other aliens/AI.*/
|
||||
name = "Spit Neurotoxin"
|
||||
desc = "Spits neurotoxin at someone, paralyzing them for a short time."
|
||||
action_icon_state = "alien_neurotoxin_0"
|
||||
var/active = 0
|
||||
active = FALSE
|
||||
|
||||
/obj/effect/proc_holder/alien/neurotoxin/fire(mob/living/carbon/user)
|
||||
var/message
|
||||
if(active)
|
||||
user.ranged_ability = null
|
||||
user << "<span class='notice'>You empty your neurotoxin gland.</span>"
|
||||
active = 0
|
||||
else if(user.ranged_ability && user.ranged_ability != src)
|
||||
user << "<span class='warning'>You already have another aimed ability readied! Cancel it first."
|
||||
return
|
||||
message = "<span class='notice'>You empty your neurotoxin gland.</span>"
|
||||
remove_ranged_ability(user, message)
|
||||
else
|
||||
user.ranged_ability = src
|
||||
active = 1
|
||||
user << "<span class='notice'>You prepare your neurotoxin gland. <B>Left-click to fire at a target!</B></span>"
|
||||
message = "<span class='notice'>You prepare your neurotoxin gland. <B>Left-click to fire at a target!</B></span>"
|
||||
add_ranged_ability(user, message)
|
||||
|
||||
user.client.click_intercept = user.ranged_ability
|
||||
/obj/effect/proc_holder/alien/neurotoxin/update_icon()
|
||||
action.button_icon_state = "alien_neurotoxin_[active]"
|
||||
action.UpdateButtonIcon()
|
||||
|
||||
/obj/effect/proc_holder/alien/neurotoxin/InterceptClickOn(mob/living/carbon/user, params, atom/target)
|
||||
if(..())
|
||||
return
|
||||
var/p_cost = 50
|
||||
if(!iscarbon(user) || user.lying || user.stat)
|
||||
remove_ranged_ability(user)
|
||||
return
|
||||
user.next_click = world.time + 6
|
||||
user.face_atom(target)
|
||||
|
||||
if(user.getPlasma() < p_cost)
|
||||
user << "<span class='warning'>You need at least [p_cost] plasma to spit.</span>"
|
||||
return
|
||||
@@ -223,7 +220,7 @@ Doesn't work on other aliens/AI.*/
|
||||
var/turf/T = user.loc
|
||||
var/turf/U = get_step(user, user.dir) // Get the tile infront of the move, based on their direction
|
||||
if(!isturf(U) || !isturf(T))
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
user.visible_message("<span class='danger'>[user] spits neurotoxin!", "<span class='alertalien'>You spit neurotoxin.</span>")
|
||||
var/obj/item/projectile/bullet/neurotoxin/A = new /obj/item/projectile/bullet/neurotoxin(user.loc)
|
||||
@@ -233,7 +230,7 @@ Doesn't work on other aliens/AI.*/
|
||||
user.newtonian_move(get_dir(U, T))
|
||||
user.adjustPlasma(-p_cost)
|
||||
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/alien/neurotoxin/on_lose(mob/living/carbon/user)
|
||||
if(user.ranged_ability == src)
|
||||
@@ -308,7 +305,7 @@ Doesn't work on other aliens/AI.*/
|
||||
/obj/effect/proc_holder/alien/sneak
|
||||
name = "Sneak"
|
||||
desc = "Blend into the shadows to stalk your prey."
|
||||
var/active = 0
|
||||
active = 0
|
||||
|
||||
action_icon_state = "alien_sneak"
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
loot = list(/obj/effect/mob_spawn/human/corpse/wizard,
|
||||
/obj/item/weapon/staff)
|
||||
|
||||
var/obj/effect/proc_holder/spell/dumbfire/fireball/fireball = null
|
||||
var/obj/effect/proc_holder/spell/fireball/fireball = null
|
||||
var/obj/effect/proc_holder/spell/targeted/turf_teleport/blink/blink = null
|
||||
var/obj/effect/proc_holder/spell/targeted/projectile/magic_missile/mm = null
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/wizard/New()
|
||||
..()
|
||||
fireball = new /obj/effect/proc_holder/spell/dumbfire/fireball
|
||||
fireball = new /obj/effect/proc_holder/spell/fireball
|
||||
fireball.clothes_req = 0
|
||||
fireball.human_req = 0
|
||||
fireball.player_lock = 0
|
||||
@@ -62,7 +62,7 @@
|
||||
if(target && next_cast < world.time)
|
||||
if((get_dir(src,target) in list(SOUTH,EAST,WEST,NORTH)) && fireball.cast_check(0,src)) //Lined up for fireball
|
||||
src.setDir(get_dir(src,target))
|
||||
fireball.choose_targets(src)
|
||||
fireball.perform(list(target), user = src)
|
||||
next_cast = world.time + 10 //One spell per second
|
||||
return .
|
||||
if(mm.cast_check(0,src))
|
||||
|
||||
@@ -251,7 +251,7 @@
|
||||
/obj/item/weapon/paper/contract/infernal/magic/FulfillContract(mob/living/carbon/human/user = target.current)
|
||||
if(!istype(user) || !user.mind)
|
||||
return -1
|
||||
user.mind.AddSpell(new /obj/effect/proc_holder/spell/dumbfire/fireball(null))
|
||||
user.mind.AddSpell(new /obj/effect/proc_holder/spell/fireball(null))
|
||||
user.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/knock(null))
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -24,27 +24,46 @@
|
||||
damage_type = BRUTE
|
||||
nodamage = 0
|
||||
|
||||
//explosion values
|
||||
var/exp_heavy = 0
|
||||
var/exp_light = 2
|
||||
var/exp_flash = 3
|
||||
var/exp_fire = 2
|
||||
|
||||
/obj/item/projectile/magic/fireball/Range()
|
||||
var/turf/T1 = get_step(src,turn(dir, -45))
|
||||
var/turf/T2 = get_step(src,turn(dir, 45))
|
||||
var/turf/T3 = get_step(src,dir)
|
||||
var/mob/living/L = locate(/mob/living) in T1 //if there's a mob alive in our front right diagonal, we hit it.
|
||||
if(L && L.stat != DEAD)
|
||||
Bump(L) //Magic Bullet #teachthecontroversy
|
||||
Bump(L,1) //Magic Bullet #teachthecontroversy
|
||||
return
|
||||
L = locate(/mob/living) in T2
|
||||
if(L && L.stat != DEAD)
|
||||
Bump(L)
|
||||
Bump(L,1)
|
||||
return
|
||||
L = locate(/mob/living) in T3
|
||||
if(L && L.stat != DEAD)
|
||||
Bump(L,1)
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/projectile/magic/fireball/on_hit(target)
|
||||
. = ..()
|
||||
var/turf/T = get_turf(target)
|
||||
explosion(T, -1, 0, 2, 3, 0, flame_range = 2)
|
||||
explosion(T, -1, exp_heavy, exp_light, exp_flash, 0, flame_range = exp_fire)
|
||||
if(ismob(target)) //multiple flavors of pain
|
||||
var/mob/living/M = target
|
||||
M.take_overall_damage(0,10) //between this 10 burn, the 10 brute, the explosion brute, and the onfire burn, your at about 65 damage if you stop drop and roll immediately
|
||||
|
||||
/obj/item/projectile/magic/fireball/infernal
|
||||
name = "infernal fireball"
|
||||
exp_heavy = -1
|
||||
exp_light = -1
|
||||
exp_flash = 4
|
||||
exp_fire= 5
|
||||
|
||||
|
||||
/obj/item/projectile/magic/resurrection
|
||||
name = "bolt of resurrection"
|
||||
icon_state = "ion"
|
||||
|
||||
@@ -1,14 +1,44 @@
|
||||
#define TARGET_CLOSEST 1
|
||||
#define TARGET_RANDOM 2
|
||||
|
||||
|
||||
/obj/effect/proc_holder
|
||||
var/panel = "Debug"//What panel the proc holder needs to go on.
|
||||
var/active = FALSE //Used by toggle based abilities.
|
||||
|
||||
var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin verb for now
|
||||
|
||||
/obj/effect/proc_holder/proc/InterceptClickOn(mob/user, params, atom/A)
|
||||
return
|
||||
/obj/effect/proc_holder/proc/InterceptClickOn(mob/living/user, params, atom/A)
|
||||
if(user.ranged_ability && user.ranged_ability != src)
|
||||
user << "<span class='warning'><b>[user.ranged_ability.name]</b> has been disabled."
|
||||
user.ranged_ability.remove_ranged_ability(user)
|
||||
return TRUE //TRUE for failed, FALSE for passed.
|
||||
user.next_click = world.time + CLICK_CD_CLICK_ABILITY
|
||||
user.face_atom(A)
|
||||
return FALSE
|
||||
|
||||
/obj/effect/proc_holder/proc/add_ranged_ability(mob/living/user, var/msg)
|
||||
if(!user || !user.client)
|
||||
return
|
||||
if(user.ranged_ability && user.ranged_ability != src)
|
||||
user << "<span class='warning'><b>[user.ranged_ability.name]</b> has been replaced by <b>[name]</b>."
|
||||
user.ranged_ability.remove_ranged_ability(user)
|
||||
user.ranged_ability = src
|
||||
user.client.click_intercept = user.ranged_ability
|
||||
active = TRUE
|
||||
if(msg)
|
||||
user << msg
|
||||
update_icon()
|
||||
|
||||
/obj/effect/proc_holder/proc/remove_ranged_ability(mob/living/user, var/msg)
|
||||
if(!user || !user.client ||user.ranged_ability != src) //To avoid removing the wrong ability
|
||||
return
|
||||
user.ranged_ability = null
|
||||
user.client.click_intercept = null
|
||||
active = FALSE
|
||||
if(msg)
|
||||
user << msg
|
||||
update_icon()
|
||||
|
||||
/obj/effect/proc_holder/spell
|
||||
name = "Spell"
|
||||
@@ -61,10 +91,10 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
|
||||
var/critfailchance = 0
|
||||
var/centcom_cancast = 1 //Whether or not the spell should be allowed on z2
|
||||
|
||||
var/datum/action/spell_action/action = null
|
||||
var/action_icon = 'icons/mob/actions.dmi'
|
||||
var/action_icon_state = "spell_default"
|
||||
var/action_background_icon_state = "bg_spell"
|
||||
var/datum/action/spell_action/action
|
||||
|
||||
/obj/effect/proc_holder/spell/proc/cast_check(skipcharge = 0,mob/user = usr) //checks if the spell can be cast based on its settings; skipcharge is used when an additional cast_check is called inside the spell
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
user << "<span class='notice'>[C] seems to not be sentient. You cannot summon a contract for them.</span>"
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/dumbfire/fireball/hellish
|
||||
/obj/effect/proc_holder/spell/fireball/hellish
|
||||
name = "Hellfire"
|
||||
desc = "This spell launches hellfire at the target."
|
||||
|
||||
@@ -86,18 +86,10 @@
|
||||
invocation_type = "shout"
|
||||
range = 2
|
||||
|
||||
proj_icon_state = "fireball"
|
||||
proj_name = "a fireball"
|
||||
proj_type = /obj/effect/proc_holder/spell/turf/fireball/infernal
|
||||
|
||||
proj_lifespan = 200
|
||||
proj_step_delay = 1
|
||||
fireball_type = /obj/item/projectile/magic/fireball/infernal
|
||||
|
||||
action_background_icon_state = "bg_demon"
|
||||
|
||||
/obj/effect/proc_holder/spell/turf/fireball/infernal/cast(turf/T,mob/user = usr)
|
||||
explosion(T, -1, -1, 1, 4, 0, flame_range = 5)
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/infernal_jaunt
|
||||
name = "Infernal Jaunt"
|
||||
desc = "Use hellfire to phase out of existence."
|
||||
|
||||
@@ -250,7 +250,7 @@
|
||||
duration = 300
|
||||
sound="sound/magic/Blind.ogg"
|
||||
|
||||
/obj/effect/proc_holder/spell/dumbfire/fireball
|
||||
/obj/effect/proc_holder/spell/fireball
|
||||
name = "Fireball"
|
||||
desc = "This spell fires a fireball at a target and does not require wizard garb."
|
||||
|
||||
@@ -261,30 +261,55 @@
|
||||
invocation_type = "shout"
|
||||
range = 20
|
||||
cooldown_min = 20 //10 deciseconds reduction per rank
|
||||
|
||||
proj_icon_state = "fireball"
|
||||
proj_name = "a fireball"
|
||||
proj_type = "/obj/effect/proc_holder/spell/turf/fireball"
|
||||
|
||||
proj_lifespan = 200
|
||||
proj_step_delay = 1
|
||||
|
||||
action_icon_state = "fireball"
|
||||
var/fireball_type = /obj/item/projectile/magic/fireball
|
||||
action_icon_state = "fireball0"
|
||||
sound = "sound/magic/Fireball.ogg"
|
||||
|
||||
/obj/effect/proc_holder/spell/turf/fireball/cast(turf/T,mob/user = usr)
|
||||
explosion(T, -1, 0, 2, 3, 0, flame_range = 2)
|
||||
active = FALSE
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/inflict_handler/fireball
|
||||
amt_dam_brute = 20
|
||||
amt_dam_fire = 25
|
||||
/obj/effect/proc_holder/spell/fireball/Click()
|
||||
var/mob/living/user = usr
|
||||
if(!istype(user) || !can_cast(user))
|
||||
return
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/explosion/fireball
|
||||
ex_severe = -1
|
||||
ex_heavy = -1
|
||||
ex_light = 2
|
||||
ex_flash = 5
|
||||
var/msg
|
||||
if(active)
|
||||
msg = "<span class='notice'>You extinguish your fireball...for now.</span>"
|
||||
remove_ranged_ability(user, msg)
|
||||
else
|
||||
msg = "<span class='notice'>Your prepare to cast your fireball spell! <B>Left-click to cast at a target!</B></span>"
|
||||
add_ranged_ability(user, msg)
|
||||
|
||||
/obj/effect/proc_holder/spell/fireball/update_icon()
|
||||
action.button_icon_state = "fireball[active]"
|
||||
action.UpdateButtonIcon()
|
||||
|
||||
/obj/effect/proc_holder/spell/fireball/InterceptClickOn(mob/living/user, params, atom/target)
|
||||
if(..())
|
||||
return
|
||||
|
||||
if(!cast_check(0, user))
|
||||
remove_ranged_ability(user)
|
||||
return
|
||||
|
||||
var/list/targets = list(target)
|
||||
perform(targets,user = user)
|
||||
|
||||
/obj/effect/proc_holder/spell/fireball/cast(list/targets, mob/living/user)
|
||||
var/target = targets[1] //There is only ever one target for fireball
|
||||
var/turf/T = user.loc
|
||||
var/turf/U = get_step(user, user.dir) // Get the tile infront of the move, based on their direction
|
||||
if(!isturf(U) || !isturf(T))
|
||||
return 0
|
||||
|
||||
var/obj/item/projectile/magic/fireball/FB = new fireball_type(user.loc)
|
||||
FB.current = get_turf(user)
|
||||
FB.preparePixelProjectile(target, get_turf(target), user)
|
||||
FB.fire()
|
||||
user.newtonian_move(get_dir(U, T))
|
||||
|
||||
return 1
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/repulse
|
||||
name = "Repulse"
|
||||
@@ -315,7 +340,7 @@
|
||||
if(AM == user || AM.anchored) continue
|
||||
|
||||
// created sparkles will disappear on their own
|
||||
PoolOrNew(sparkle_path, AM)
|
||||
PoolOrNew(sparkle_path, AM)
|
||||
throwtarget = get_edge_target_turf(user, get_dir(user, get_step_away(AM, user)))
|
||||
distfromcaster = get_dist(user, AM)
|
||||
if(distfromcaster == 0)
|
||||
|
||||
Reference in New Issue
Block a user