diff --git a/code/datums/spell.dm b/code/datums/spell.dm
index 7137bbf9ad1..587d5f1c646 100644
--- a/code/datums/spell.dm
+++ b/code/datums/spell.dm
@@ -1,3 +1,6 @@
+#define TARGET_CLOSEST 1
+#define TARGET_RANDOM 2
+
/obj/effect/proc_holder
var/panel = "Debug"//What panel the proc holder needs to go on.
@@ -245,6 +248,8 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
var/max_targets = 1 //leave 0 for unlimited targets in range, 1 for one selectable target in range, more for limited number of casts (can all target one guy, depends on target_ignore_prev) in range
var/target_ignore_prev = 1 //only important if max_targets > 1, affects if the spell can be cast multiple times at one person from one cast
var/include_user = 0 //if it includes usr in the target list
+ var/random_target = 0 // chooses random viable target instead of asking the caster
+ var/random_target_priority = TARGET_CLOSEST // if random_target is enabled how it will pick the target
/obj/effect/proc_holder/spell/aoe_turf //affects all turfs in view or range (depends)
var/inner_radius = -1 //for all your ring spell needs
@@ -269,7 +274,22 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
//targets += input("Choose the target for the spell.", "Targeting") as mob in possible_targets
//Adds a safety check post-input to make sure those targets are actually in range.
- var/mob/M = input("Choose the target for the spell.", "Targeting") as mob in possible_targets
+ var/mob/M
+ if(!random_target)
+ M = input("Choose the target for the spell.", "Targeting") as mob in possible_targets
+ else
+ switch(random_target_priority)
+ if(TARGET_RANDOM)
+ M = pick(possible_targets)
+ if(TARGET_CLOSEST)
+ for(var/mob/living/L in possible_targets)
+ if(M)
+ if(get_dist(user,L) < get_dist(user,M))
+ if(los_check(user,L))
+ M = L
+ else
+ if(los_check(user,L))
+ M = L
if(M in view_or_range(range, user, selection_type)) targets += M
else
@@ -315,4 +335,16 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
/obj/effect/proc_holder/spell/proc/can_be_cast_by(mob/caster)
if((human_req || clothes_req) && !ishuman(caster))
return 0
+ return 1
+
+/obj/effect/proc_holder/spell/targeted/proc/los_check(mob/A,mob/B)
+ //Checks for obstacles from A to B
+ var/obj/dummy = new(A.loc)
+ dummy.pass_flags |= PASSTABLE
+ for(var/turf/turf in getline(A,B))
+ for(var/atom/movable/AM in turf)
+ if(!AM.CanPass(dummy,turf,1))
+ qdel(dummy)
+ return 0
+ qdel(dummy)
return 1
\ No newline at end of file
diff --git a/code/datums/spells/lightning.dm b/code/datums/spells/lightning.dm
new file mode 100644
index 00000000000..b3e813c7e0e
--- /dev/null
+++ b/code/datums/spells/lightning.dm
@@ -0,0 +1,98 @@
+/obj/effect/proc_holder/spell/targeted/lightning
+ name = "Lightning Bolt"
+ desc = "Throws a lightning bolt at the nearby enemy. Classic."
+ charge_type = "recharge"
+ charge_max = 300
+ clothes_req = 1
+ invocation = "UN'LTD P'WAH!"
+ invocation_type = "shout"
+ range = 7
+ cooldown_min = 30
+ selection_type = "view"
+ random_target = 1
+ var/energy = 0
+ var/ready = 0
+ var/image/halo = null
+
+/obj/effect/proc_holder/spell/targeted/lightning/Click()
+ if(!ready)
+ if(cast_check())
+ StartChargeup()
+ else
+ if(cast_check(skipcharge=1))
+ choose_targets()
+ return 1
+
+/obj/effect/proc_holder/spell/targeted/lightning/proc/StartChargeup(mob/user = usr)
+ ready = 1
+ user << "You start gathering the power."
+ halo = image("icon"='icons/effects/effects.dmi',"icon_state" ="electricity","layer" = EFFECTS_LAYER)
+ user.overlays.Add(halo)
+ spawn(0)
+ while(ready)
+ sleep(1)
+ energy++
+ if(energy >= 100 && ready)
+ Discharge()
+
+obj/effect/proc_holder/spell/targeted/lightning/proc/Reset(mob/user = usr)
+ ready = 0
+ energy = 0
+ if(halo)
+ user.overlays.Remove(halo)
+
+/obj/effect/proc_holder/spell/targeted/lightning/revert_cast(mob/user = usr)
+ user << "No target found in range."
+ Reset(user)
+ ..()
+
+/obj/effect/proc_holder/spell/targeted/lightning/proc/Discharge(mob/user = usr)
+ var/mob/living/M = user
+ //M.electrocute_act(25,"Lightning Bolt")
+ M << "You lose control over the spell."
+ Reset(user)
+ start_recharge()
+
+
+/obj/effect/proc_holder/spell/targeted/lightning/cast(list/targets, mob/user = usr)
+
+ var/mob/living/carbon/target = targets[1]
+
+ if(get_dist(user,target)>range)
+ user << "They are too far away!"
+ Reset(user)
+ return
+
+ user.Beam(target,icon_state="lightning",icon='icons/effects/effects.dmi',time=5)
+
+ switch(energy)
+ if(0 to 25)
+ target.electrocute_act(10,"Lightning Bolt")
+ playsound(get_turf(target), 'sound/machines/defib_zap.ogg', 50, 1, -1)
+ if(25 to 75)
+ target.electrocute_act(25,"Lightning Bolt")
+ playsound(get_turf(target), 'sound/machines/defib_zap.ogg', 50, 1, -1)
+ if(75 to 100)
+ //CHAIN LIGHTNING
+ Bolt(user,target,energy,user)
+ Reset(user)
+
+/obj/effect/proc_holder/spell/targeted/lightning/proc/Bolt(mob/origin,mob/target,bolt_energy,mob/user = usr)
+ origin.Beam(target,icon_state="lightning",icon='icons/effects/effects.dmi',time=5)
+ var/mob/living/carbon/current = target
+ if(bolt_energy < 75)
+ current.electrocute_act(25,"Lightning Bolt")
+ playsound(get_turf(current), 'sound/machines/defib_zap.ogg', 50, 1, -1)
+ else
+ current.electrocute_act(25,"Lightning Bolt")
+ playsound(get_turf(current), 'sound/machines/defib_zap.ogg', 50, 1, -1)
+ var/list/possible_targets = new
+ for(var/mob/living/M in view_or_range(range,target,"view"))
+ if(user == M || target == M && los_check(current,M)) // || origin == M ? Not sure double shockings is good or not
+ continue
+ possible_targets += M
+ if(!possible_targets.len)
+ return
+ var/mob/living/next = pick(possible_targets)
+ if(next)
+ Bolt(current,next,bolt_energy-6,user) // 5 max bounces
\ No newline at end of file
diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm
index b7ff72de867..1becc5aa3d9 100644
--- a/code/game/gamemodes/wizard/spellbook.dm
+++ b/code/game/gamemodes/wizard/spellbook.dm
@@ -106,6 +106,9 @@
dat += "Flesh to Stone (60)
"
dat += "This spell will curse a person to immediately turn into an unmoving statue. The effect will eventually wear off if the statue is not destroyed.
"
+ dat += "Lightning Bolt (30)
"
+ dat += "Charge up and throw lightning bolt at the nearby enemy. Classic. The longer you charge the more powerful the spell, beware of overcharge however!
"
+
dat += "Instant Summons (10)
"
dat += "This spell can be used to bind a valuable item to you, bringing it to your hand at will. Using this spell while holding the bound item will allow you to unbind it. It does not require wizard garb.
"
if(ticker.mode.name != "ragin' mages") // we totally need summon greentext x100
@@ -220,7 +223,7 @@
uses--
/*
*/
- var/list/available_spells = list(magicmissile = "Magic Missile", fireball = "Fireball", disintegrate = "Disintegrate", disabletech = "Disable Tech", repulse = "Repulse", smoke = "Smoke", blind = "Blind", mindswap = "Mind Transfer", forcewall = "Forcewall", blink = "Blink", teleport = "Teleport", mutate = "Mutate", etherealjaunt = "Ethereal Jaunt", knock = "Knock", barnyardcurse = "The Curse of the Barnyard", fleshtostone = "Flesh to Stone", summonitem = "Instant Summons", summonguns = "Summon Guns", summonmagic = "Summon Magic", summonevents = "Summon Events", staffchange = "Staff of Change", soulstone = "Six Soul Stone Shards and the spell Artificer", necrostone = "A Necromantic Stone", armor = "Mastercrafted Armor Set", staffanimate = "Staff of Animation", staffchaos = "Staff of Chaos", staffdoor = "Staff of Door Creation", wands = "Wand Assortment")
+ var/list/available_spells = list(magicmissile = "Magic Missile", fireball = "Fireball", disintegrate = "Disintegrate", disabletech = "Disable Tech", repulse = "Repulse", smoke = "Smoke", blind = "Blind", mindswap = "Mind Transfer", forcewall = "Forcewall", blink = "Blink", teleport = "Teleport", mutate = "Mutate", etherealjaunt = "Ethereal Jaunt", knock = "Knock", barnyardcurse = "The Curse of the Barnyard", fleshtostone = "Flesh to Stone", summonitem = "Instant Summons", summonguns = "Summon Guns", summonmagic = "Summon Magic", summonevents = "Summon Events", staffchange = "Staff of Change", soulstone = "Six Soul Stone Shards and the spell Artificer", necrostone = "A Necromantic Stone", armor = "Mastercrafted Armor Set", staffanimate = "Staff of Animation", staffchaos = "Staff of Chaos", staffdoor = "Staff of Door Creation", wands = "Wand Assortment", lightningbolt = "Lightning Bolt")
var/already_knows = 0
for(var/obj/effect/proc_holder/spell/aspell in H.mind.spell_list)
if(available_spells[href_list["spell_choice"]] == initial(aspell.name))
@@ -318,6 +321,10 @@
feedback_add_details("wizard_spell_learned","IS") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
H.mind.spell_list += new /obj/effect/proc_holder/spell/targeted/summonitem(null)
temp = "You have learned instant summons."
+ if("lightningbolt")
+ feedback_add_details("wizard_spell_learned","LB") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
+ H.mind.spell_list += new /obj/effect/proc_holder/spell/targeted/lightning(null)
+ temp = "You have learned lightning bolt."
if("summonguns")
feedback_add_details("wizard_spell_learned","SG") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
rightandwrong(0, H, 0)
diff --git a/html/changelogs/AnturK-LightningBolt.yml b/html/changelogs/AnturK-LightningBolt.yml
new file mode 100644
index 00000000000..c5d672d4ab7
--- /dev/null
+++ b/html/changelogs/AnturK-LightningBolt.yml
@@ -0,0 +1,6 @@
+author: AnturK
+
+delete-after: True
+
+changes:
+ - rscadd: "Added new wizard spell : Lightning Bolt"
diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi
index d2bad4aa9dc..0b9074d181b 100644
Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ
diff --git a/tgstation.dme b/tgstation.dme
index fd36f9c265e..1c8c71dedb4 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -229,6 +229,7 @@
#include "code\datums\spells\genetic.dm"
#include "code\datums\spells\inflict_handler.dm"
#include "code\datums\spells\knock.dm"
+#include "code\datums\spells\lightning.dm"
#include "code\datums\spells\mime.dm"
#include "code\datums\spells\mind_transfer.dm"
#include "code\datums\spells\projectile.dm"