diff --git a/code/datums/spell.dm b/code/datums/spell.dm
index e03f172f2a2..7aeee98f92e 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.
@@ -235,6 +238,9 @@ 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/wizard/aoe_turf //affects all turfs in view or range (depends)
var/inner_radius = -1 //for all your ring spell needs
@@ -260,7 +266,26 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
continue
possible_targets += M
- targets += input("Choose the target for the spell.", "Targeting") as mob in possible_targets
+ //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
+ 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
var/list/possible_targets = list()
for(var/mob/living/target in view_or_range(range, user, selection_type))
@@ -300,3 +325,16 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
perform(targets)
return
+
+
+/obj/effect/proc_holder/spell/wizard/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..9e4994b5b9d
--- /dev/null
+++ b/code/datums/spells/lightning.dm
@@ -0,0 +1,98 @@
+/obj/effect/proc_holder/spell/wizard/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/wizard/targeted/lightning/Click()
+ if(!ready)
+ if(cast_check())
+ StartChargeup()
+ else
+ if(cast_check(skipcharge=1))
+ choose_targets()
+ return 1
+
+/obj/effect/proc_holder/spell/wizard/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/wizard/targeted/lightning/proc/Reset(mob/user = usr)
+ ready = 0
+ energy = 0
+ if(halo)
+ user.overlays.Remove(halo)
+
+/obj/effect/proc_holder/spell/wizard/targeted/lightning/revert_cast(mob/user = usr)
+ user << "No target found in range."
+ Reset(user)
+ ..()
+
+/obj/effect/proc_holder/spell/wizard/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/wizard/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/wizard/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/icons/effects/effects.dmi b/icons/effects/effects.dmi
index 97b9a24eb2f..62998f37b7c 100644
Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ
diff --git a/paradise.dme b/paradise.dme
index 534c3eb3d2f..282559a4f76 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -167,6 +167,7 @@
#include "code\datums\spells\horsemask.dm"
#include "code\datums\spells\inflict_handler.dm"
#include "code\datums\spells\knock.dm"
+#include "code\datums\spells\lightning.dm"
#include "code\datums\spells\mind_transfer.dm"
#include "code\datums\spells\projectile.dm"
#include "code\datums\spells\summonitem.dm"