diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index eead73d666b..c6430d4654f 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -152,6 +152,7 @@ #define CLICK_CD_MELEE 8 #define CLICK_CD_RANGE 4 +#define CLICK_CD_CLICK_ABILITY 6 #define CLICK_CD_BREAKOUT 100 #define CLICK_CD_HANDCUFFED 10 #define CLICK_CD_RESIST 20 diff --git a/code/datums/mind.dm b/code/datums/mind.dm index e53f4a1f432..c4e2e6eb515 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -1180,7 +1180,7 @@ special_role = null current << "Your infernal link has been severed! You are no longer a devil!" RemoveSpell(/obj/effect/proc_holder/spell/targeted/infernal_jaunt) - RemoveSpell(/obj/effect/proc_holder/spell/dumbfire/fireball/hellish) + RemoveSpell(/obj/effect/proc_holder/spell/fireball/hellish) RemoveSpell(/obj/effect/proc_holder/spell/targeted/summon_contract) RemoveSpell(/obj/effect/proc_holder/spell/targeted/summon_pitchfork) message_admins("[key_name_admin(usr)] has de-devil'ed [current].") diff --git a/code/game/gamemodes/antag_spawner.dm b/code/game/gamemodes/antag_spawner.dm index d4a54fb86b3..cbc03db8e52 100644 --- a/code/game/gamemodes/antag_spawner.dm +++ b/code/game/gamemodes/antag_spawner.dm @@ -75,7 +75,7 @@ switch(type) if("destruction") M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile(null)) - M.mind.AddSpell(new /obj/effect/proc_holder/spell/dumbfire/fireball(null)) + M.mind.AddSpell(new /obj/effect/proc_holder/spell/fireball(null)) M << "Your service has not gone unrewarded, however. Studying under [usr.real_name], you have learned powerful, destructive spells. You are able to cast magic missile and fireball." if("bluespace") M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/area_teleport/teleport(null)) diff --git a/code/game/gamemodes/changeling/powers/augmented_eyesight.dm b/code/game/gamemodes/changeling/powers/augmented_eyesight.dm index f5b496cf6a7..ca45e620da4 100644 --- a/code/game/gamemodes/changeling/powers/augmented_eyesight.dm +++ b/code/game/gamemodes/changeling/powers/augmented_eyesight.dm @@ -7,7 +7,7 @@ helptext = "Grants us thermal vision or flash protection. We will become a lot more vulnerable to flash-based devices while thermal vision is active." chemical_cost = 0 dna_cost = 2 //Would be 1 without thermal vision - var/active = 0 //Whether or not vision is enhanced + active = 0 //Whether or not vision is enhanced /obj/effect/proc_holder/changeling/augmented_eyesight/sting_action(mob/living/carbon/human/user) if(!istype(user)) diff --git a/code/game/gamemodes/changeling/powers/strained_muscles.dm b/code/game/gamemodes/changeling/powers/strained_muscles.dm index 94c96ad30bc..f2d4d98fccd 100644 --- a/code/game/gamemodes/changeling/powers/strained_muscles.dm +++ b/code/game/gamemodes/changeling/powers/strained_muscles.dm @@ -9,7 +9,7 @@ dna_cost = 1 req_human = 1 var/stacks = 0 //Increments every 5 seconds; damage increases over time - var/active = 0 //Whether or not you are a hedgehog + active = 0 //Whether or not you are a hedgehog /obj/effect/proc_holder/changeling/strained_muscles/sting_action(mob/living/carbon/user) active = !active diff --git a/code/game/gamemodes/devil/devilinfo.dm b/code/game/gamemodes/devil/devilinfo.dm index d0d0429d433..b512422ef5c 100644 --- a/code/game/gamemodes/devil/devilinfo.dm +++ b/code/game/gamemodes/devil/devilinfo.dm @@ -297,7 +297,7 @@ var/global/list/lawlorify = list ( /datum/devilinfo/proc/give_base_spells(give_summon_contract = 0) remove_spells() - owner.AddSpell(new /obj/effect/proc_holder/spell/dumbfire/fireball/hellish(null)) + owner.AddSpell(new /obj/effect/proc_holder/spell/fireball/hellish(null)) owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/summon_pitchfork(null)) if(give_summon_contract) give_summon_contract() @@ -305,13 +305,13 @@ var/global/list/lawlorify = list ( /datum/devilinfo/proc/give_lizard_spells() remove_spells() owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/summon_pitchfork(null)) - owner.AddSpell(new /obj/effect/proc_holder/spell/dumbfire/fireball/hellish(null)) + owner.AddSpell(new /obj/effect/proc_holder/spell/fireball/hellish(null)) owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/infernal_jaunt(null)) /datum/devilinfo/proc/give_true_spells() remove_spells() owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/summon_pitchfork/greater(null)) - owner.AddSpell(new /obj/effect/proc_holder/spell/dumbfire/fireball/hellish(null)) + owner.AddSpell(new /obj/effect/proc_holder/spell/fireball/hellish(null)) owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/infernal_jaunt(null)) owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/sintouch(null)) diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm index ee3965287d1..2c370f47da9 100644 --- a/code/game/gamemodes/wizard/spellbook.dm +++ b/code/game/gamemodes/wizard/spellbook.dm @@ -95,7 +95,7 @@ /datum/spellbook_entry/fireball name = "Fireball" - spell_type = /obj/effect/proc_holder/spell/dumbfire/fireball + spell_type = /obj/effect/proc_holder/spell/fireball log_name = "FB" /datum/spellbook_entry/magicm @@ -738,7 +738,7 @@ return /obj/item/weapon/spellbook/oneuse/fireball - spell = /obj/effect/proc_holder/spell/dumbfire/fireball + spell = /obj/effect/proc_holder/spell/fireball spellname = "fireball" icon_state ="bookfireball" desc = "This book feels warm to the touch." diff --git a/code/modules/awaymissions/mission_code/Academy.dm b/code/modules/awaymissions/mission_code/Academy.dm index 0c4ab1dd76a..b4b537285f7 100644 --- a/code/modules/awaymissions/mission_code/Academy.dm +++ b/code/modules/awaymissions/mission_code/Academy.dm @@ -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 diff --git a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm index 7b151fbc73c..5f4d11a7112 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm @@ -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 << "You empty your neurotoxin gland." - active = 0 - else if(user.ranged_ability && user.ranged_ability != src) - user << "You already have another aimed ability readied! Cancel it first." - return + message = "You empty your neurotoxin gland." + remove_ranged_ability(user, message) else - user.ranged_ability = src - active = 1 - user << "You prepare your neurotoxin gland. Left-click to fire at a target!" + message = "You prepare your neurotoxin gland. Left-click to fire at a target!" + 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 << "You need at least [p_cost] plasma to spit." 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("[user] spits neurotoxin!", "You spit neurotoxin.") 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" diff --git a/code/modules/mob/living/simple_animal/hostile/wizard.dm b/code/modules/mob/living/simple_animal/hostile/wizard.dm index df6a4be30be..bf5c614d637 100644 --- a/code/modules/mob/living/simple_animal/hostile/wizard.dm +++ b/code/modules/mob/living/simple_animal/hostile/wizard.dm @@ -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)) diff --git a/code/modules/paperwork/contract.dm b/code/modules/paperwork/contract.dm index b45217d6970..df21427279d 100644 --- a/code/modules/paperwork/contract.dm +++ b/code/modules/paperwork/contract.dm @@ -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 ..() diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm index 638b38d4faf..a94abf7243c 100644 --- a/code/modules/projectiles/projectile/magic.dm +++ b/code/modules/projectiles/projectile/magic.dm @@ -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" diff --git a/code/modules/spells/spell.dm b/code/modules/spells/spell.dm index e5b58e577a4..ce77ac1c1ef 100644 --- a/code/modules/spells/spell.dm +++ b/code/modules/spells/spell.dm @@ -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 << "[user.ranged_ability.name] 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 << "[user.ranged_ability.name] has been replaced by [name]." + 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 diff --git a/code/modules/spells/spell_types/devil.dm b/code/modules/spells/spell_types/devil.dm index 2622770da09..90de8e124df 100644 --- a/code/modules/spells/spell_types/devil.dm +++ b/code/modules/spells/spell_types/devil.dm @@ -75,7 +75,7 @@ user << "[C] seems to not be sentient. You cannot summon a contract for them." -/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." diff --git a/code/modules/spells/spell_types/wizard.dm b/code/modules/spells/spell_types/wizard.dm index c24d6b52909..ad4ffe90678 100644 --- a/code/modules/spells/spell_types/wizard.dm +++ b/code/modules/spells/spell_types/wizard.dm @@ -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 = "You extinguish your fireball...for now." + remove_ranged_ability(user, msg) + else + msg = "Your prepare to cast your fireball spell! Left-click to cast at a target!" + 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) diff --git a/icons/mob/actions.dmi b/icons/mob/actions.dmi index d41fc220901..18a190d88d3 100644 Binary files a/icons/mob/actions.dmi and b/icons/mob/actions.dmi differ