diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm
index c92415d6a4a..b3f80f85d50 100644
--- a/code/__HELPERS/mobs.dm
+++ b/code/__HELPERS/mobs.dm
@@ -333,7 +333,7 @@
msg_admin_attack("[key_name_admin(user)] vs [target_info]: [what_done]", loglevel)
-/proc/do_mob(mob/user, mob/target, time = 30, uninterruptible = 0, progress = 1, list/extra_checks = list())
+/proc/do_mob(mob/user, mob/target, time = 30, progress = 1, list/extra_checks = list(), only_use_extra_checks = FALSE)
if(!user || !target)
return 0
var/user_loc = user.loc
@@ -359,7 +359,9 @@
if(!user || !target)
. = 0
break
- if(uninterruptible)
+ if(only_use_extra_checks)
+ if(check_for_true_callbacks(extra_checks))
+ break
continue
if(drifting && !user.inertia_dir)
diff --git a/code/datums/action.dm b/code/datums/action.dm
index 4ba27fb037d..42913514406 100644
--- a/code/datums/action.dm
+++ b/code/datums/action.dm
@@ -529,9 +529,6 @@
return FALSE
var/obj/effect/proc_holder/spell/spell = target
- if(spell.special_availability_check)
- return TRUE
-
if(owner)
return spell.can_cast(owner)
return FALSE
diff --git a/code/datums/spell.dm b/code/datums/spell.dm
index f4733f64349..88d26db75b7 100644
--- a/code/datums/spell.dm
+++ b/code/datums/spell.dm
@@ -124,7 +124,6 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
var/action_icon = 'icons/mob/actions/actions.dmi'
var/action_icon_state = "spell_default"
var/action_background_icon_state = "bg_spell"
- var/special_availability_check = 0//Whether the spell needs to bypass the action button's IsAvailable()
var/sound = null //The sound the spell makes when it is cast
var/gain_desc = null
diff --git a/code/datums/spells/charge_up.dm b/code/datums/spells/charge_up.dm
new file mode 100644
index 00000000000..24eba2c7d1a
--- /dev/null
+++ b/code/datums/spells/charge_up.dm
@@ -0,0 +1,81 @@
+/**
+ * A click-based spell template which starts charging up once you click the action button/verb. Click again on something to activate the actual spell
+ */
+
+/obj/effect/proc_holder/spell/charge_up
+ var/start_time = 0
+ /// The overlay used to show that you are charging. Create this in the New of the spell
+ var/image/charge_up_overlay
+ /// How long you can charge for
+ var/max_charge_time
+ /// The sound charging up your power will make. Be sure to include a channel when creating the sound
+ var/sound/charge_sound
+ /// The text shown when you start charging
+ var/start_charging_text
+ /// The text shown when you successfully stop charging
+ var/stop_charging_text
+ /// The text shown when you are over the charge limit and thus can't stop.
+ var/stop_charging_fail_text
+
+/obj/effect/proc_holder/spell/charge_up/create_new_targeting()
+ var/datum/spell_targeting/click/T = new()
+ T.allowed_type = /mob/living
+ T.try_auto_target = FALSE
+ return T
+
+/obj/effect/proc_holder/spell/charge_up/Click()
+ if(cast_check(TRUE, FALSE, usr))
+ if(!start_time)
+ INVOKE_ASYNC(src, .proc/StartChargeup, usr)
+ else
+ if(!try_stop_buildup(usr))
+ return // Don't remove the click intercept
+
+ return ..()
+
+/obj/effect/proc_holder/spell/charge_up/proc/try_stop_buildup(mob/user)
+ var/energy_perc = get_energy_charge() / max_charge_time
+ if(energy_perc < 0.5)
+ charge_counter = (1 - energy_perc) * charge_max // Give them some charge back
+ to_chat(user, "[stop_charging_text]")
+ Reset(user)
+ start_recharge()
+ return TRUE
+ else
+ to_chat(user, "[stop_charging_fail_text]")
+ return FALSE
+
+/obj/effect/proc_holder/spell/charge_up/proc/get_energy_charge()
+ return min(world.time - start_time, max_charge_time)
+
+/obj/effect/proc_holder/spell/charge_up/proc/StartChargeup(mob/user)
+ to_chat(user, "[start_charging_text]")
+ user.add_overlay(charge_up_overlay)
+ playsound(user, charge_sound, 50, FALSE, channel = charge_sound.channel)
+ start_time = world.time
+ if(do_mob(user, user, max_charge_time, extra_checks = list(CALLBACK(src, .proc/stopped_casting)), only_use_extra_checks = TRUE))
+ if(start_time)
+ Discharge(user)
+
+/obj/effect/proc_holder/spell/charge_up/proc/stopped_casting()
+ return start_time == 0
+
+/obj/effect/proc_holder/spell/charge_up/proc/Reset(mob/user)
+ start_time = 0
+ user.cut_overlay(charge_up_overlay)
+ remove_ranged_ability(user)
+ playsound(user, null, 50, FALSE, channel = charge_sound.channel)
+
+/obj/effect/proc_holder/spell/charge_up/revert_cast(mob/user)
+ Reset(user)
+ ..()
+
+/obj/effect/proc_holder/spell/charge_up/proc/Discharge(mob/user)
+ to_chat(user, "You lose control over the spell!")
+ Reset(user)
+ spend_spell_cost(user)
+ start_recharge()
+
+/obj/effect/proc_holder/spell/charge_up/after_cast(list/targets, mob/user)
+ ..()
+ Reset(user)
diff --git a/code/datums/spells/charge_up_bounce.dm b/code/datums/spells/charge_up_bounce.dm
new file mode 100644
index 00000000000..b0cb94679e4
--- /dev/null
+++ b/code/datums/spells/charge_up_bounce.dm
@@ -0,0 +1,64 @@
+/**
+ * A spell template that adds bounces to the charge_up spell template. The spell will bounce between targets once released.
+ * Don't override cast and instead override apply_bounce_effect and the other procs
+ */
+/obj/effect/proc_holder/spell/charge_up/bounce
+ var/bounce_hit_sound
+
+/obj/effect/proc_holder/spell/charge_up/bounce/cast(list/targets, mob/user = usr)
+ var/mob/living/target = targets[1]
+
+ bounce(user, target, get_bounce_energy(), get_bounce_amount(), user)
+
+/**
+ * How much energy should each bounce have?
+ */
+/obj/effect/proc_holder/spell/charge_up/bounce/proc/get_bounce_energy()
+ return
+
+/**
+ * How much bounces should there be in total?
+ */
+/obj/effect/proc_holder/spell/charge_up/bounce/proc/get_bounce_amount()
+ return
+
+/**
+ * Called when a bounce travels from one mob to another
+ *
+ * Arguments:
+ * * origin - Where the bounce came from
+ * * target - The mob that got hit
+ */
+/obj/effect/proc_holder/spell/charge_up/bounce/proc/create_beam(mob/origin, mob/target)
+ return
+
+/**
+ * The proc called when a bounce hits a target. Override this to add an effect
+ * The user itself is never hit
+ *
+ * Arguments:
+ * * origin - Where the bounce came from
+ * * target - The mob that got hit
+ * * energy - How much energy the bounce has
+ * * user - The caster of the spell
+ */
+/obj/effect/proc_holder/spell/charge_up/bounce/proc/apply_bounce_effect(mob/origin, mob/target, energy, mob/user)
+ return
+
+/obj/effect/proc_holder/spell/charge_up/bounce/proc/bounce(mob/origin, mob/target, energy, bounces, mob/user)
+ SHOULD_CALL_PARENT(TRUE)
+ create_beam(origin, target)
+ apply_bounce_effect(origin, target, energy, user)
+ add_attack_logs(user, target, "Bounce spell '[src]' bounced on")
+ playsound(get_turf(target), bounce_hit_sound, 50, 1, -1)
+
+ if(bounces >= 1)
+ var/list/possible_targets = list()
+ for(var/mob/living/M in view(targeting.range, target))
+ if(user == M || target == M && los_check(target, M))
+ continue
+ possible_targets += M
+ if(!length(possible_targets))
+ return
+ var/mob/living/next = pick(possible_targets)
+ bounce(target, next, energy, bounces - 1, user)
diff --git a/code/datums/spells/lightning.dm b/code/datums/spells/lightning.dm
index 08ad49803d4..2a3ad9eb93c 100644
--- a/code/datums/spells/lightning.dm
+++ b/code/datums/spells/lightning.dm
@@ -1,119 +1,49 @@
-/obj/effect/proc_holder/spell/lightning
+/obj/effect/proc_holder/spell/charge_up/bounce/lightning
name = "Lightning Bolt"
- desc = "Throws a lightning bolt at the nearby enemy. Classic."
+ desc = "Throws a lightning bolt at your enemies. Classic. When clicked will start to charge in power. Then click on a mob to send the bolt before it overloads with power."
charge_type = "recharge"
- charge_max = 300
- clothes_req = 1
+ charge_max = 30 SECONDS
+ clothes_req = TRUE
invocation = "UN'LTD P'WAH!"
invocation_type = "shout"
- cooldown_min = 30
- special_availability_check = 1
- var/start_time = 0
- var/ready = 0
- var/image/halo = null
+ cooldown_min = 3 SECONDS
action_icon_state = "lightning"
- var/sound/Snd // so far only way i can think of to stop a sound, thank MSO for the idea.
+ charge_sound = new /sound('sound/magic/lightning_chargeup.ogg', channel = 7)
+ max_charge_time = 10 SECONDS
+ stop_charging_text = "You stop charging the lightning around you."
+ stop_charging_fail_text = "The lightning around you is too strong to stop now!"
+ start_charging_text = "You start gathering lightning around you."
+ bounce_hit_sound = 'sound/magic/lightningshock.ogg'
var/damaging = TRUE
-/obj/effect/proc_holder/spell/lightning/create_new_targeting()
- var/datum/spell_targeting/targeted/T = new()
- T.allowed_type = /mob/living
- T.random_target = TRUE
- return T
-
-/obj/effect/proc_holder/spell/lightning/lightnian
- clothes_req = 0
- invocation_type = "none"
- damaging = 0
-
-/obj/effect/proc_holder/spell/lightning/Click()
- if(!ready && start_time == 0)
- if(cast_check(TRUE, FALSE, usr))
- StartChargeup()
- else
- if(ready && cast_check(TRUE, FALSE, usr))
- choose_targets()
- return 1
-
-/obj/effect/proc_holder/spell/lightning/proc/StartChargeup(mob/user = usr)
- ready = 1
- to_chat(user, "You start gathering the power.")
- Snd = new/sound('sound/magic/lightning_chargeup.ogg', channel = 7)
- halo = image("icon"='icons/effects/effects.dmi',"icon_state" ="electricity","layer" = EFFECTS_LAYER)
- user.overlays.Add(halo)
- playsound(get_turf(user), Snd, 50, 0)
- start_time = world.time
- if(do_mob(user, user, 100, uninterruptible=1))
- if(ready)
- Discharge()
-
-/obj/effect/proc_holder/spell/lightning/proc/Reset(mob/user = usr)
- ready = 0
- start_time = 0
- if(halo)
- user.overlays.Remove(halo)
-
-/obj/effect/proc_holder/spell/lightning/revert_cast(mob/user = usr)
- to_chat(user, "No target found in range.")
- Reset(user)
+/obj/effect/proc_holder/spell/charge_up/bounce/lightning/New()
..()
+ charge_up_overlay = image(icon = 'icons/effects/effects.dmi', icon_state = "electricity", layer = EFFECTS_LAYER)
-/obj/effect/proc_holder/spell/lightning/proc/Discharge(mob/user = usr)
- var/mob/living/M = user
- to_chat(M, "You lose control over the spell.")
- Reset(user)
- start_recharge()
+/obj/effect/proc_holder/spell/charge_up/bounce/lightning/lightnian
+ clothes_req = FALSE
+ invocation_type = "none"
+ damaging = FALSE
-
-/obj/effect/proc_holder/spell/lightning/cast(list/targets, mob/user = usr)
- ready = 0
- var/mob/living/target = targets[1]
- Snd = sound(null, repeat = 0, wait = 1, channel = Snd.channel) //byond, why you suck?
- playsound(get_turf(user), Snd, 50, 0)// Sorry MrPerson, but the other ways just didn't do it the way i needed to work, this is the only way.
-
- playsound(get_turf(user), 'sound/magic/lightningbolt.ogg', 50, 1)
- user.Beam(target,icon_state="lightning[rand(1,12)]",icon='icons/effects/effects.dmi',time=5)
-
- var/energy = min(world.time - start_time,100)
+/obj/effect/proc_holder/spell/charge_up/bounce/lightning/get_bounce_energy()
if(damaging)
- Bolt(user,target,max(15,energy/2),5,user) //5 bounces for energy/2 burn
- else
- var/bounces = round(energy/20)
- Bolt(user,target,0,bounces,user)
- Reset(user)
+ return max(15, get_energy_charge() / 2)
+ return 0
-/obj/effect/proc_holder/spell/lightning/proc/Bolt(mob/origin, mob/living/target, bolt_energy, bounces, mob/user = usr)
- origin.Beam(target,icon_state="lightning[rand(1,12)]", icon='icons/effects/effects.dmi', time=5)
- var/mob/living/current = target
- if(bounces < 1)
- if(damaging)
- current.electrocute_act(bolt_energy, "Lightning Bolt", flags = SHOCK_NOGLOVES)
- else
- current.AdjustJitter(1000) //High numbers for violent convulsions
- current.do_jitter_animation(current.jitteriness)
- current.AdjustStuttering(2)
- current.Slowed(3)
- spawn(20)
- current.AdjustJitter(-1000, bound_lower = 10) //Still jittery, but vastly less
- playsound(get_turf(current), 'sound/magic/lightningshock.ogg', 50, 1, -1)
+/obj/effect/proc_holder/spell/charge_up/bounce/lightning/get_bounce_amount()
+ if(damaging)
+ return 5
+ return round(get_energy_charge() / 20)
+
+/obj/effect/proc_holder/spell/charge_up/bounce/lightning/create_beam(mob/origin, mob/target)
+ origin.Beam(target, icon_state = "lightning[rand(1, 12)]", icon = 'icons/effects/effects.dmi', time = 5)
+
+/obj/effect/proc_holder/spell/charge_up/bounce/lightning/apply_bounce_effect(mob/origin, mob/living/target, energy, mob/user)
+ if(damaging)
+ target.electrocute_act(energy, "Lightning Bolt", flags = SHOCK_NOGLOVES)
else
- if(damaging)
- current.electrocute_act(bolt_energy, "Lightning Bolt", flags = SHOCK_NOGLOVES)
- else
- current.AdjustJitter(1000) //High numbers for violent convulsions
- current.do_jitter_animation(current.jitteriness)
- current.AdjustStuttering(2)
- current.Slowed(3)
- spawn(20)
- current.AdjustJitter(-1000, bound_lower = 10) //Still jittery, but vastly less
- playsound(get_turf(current), 'sound/magic/lightningshock.ogg', 50, 1, -1)
- var/list/possible_targets = new
- for(var/mob/living/M in view_or_range(targeting.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,bounces-1,user) // 5 max bounces
+ target.AdjustJitter(1000) //High numbers for violent convulsions
+ target.do_jitter_animation(target.jitteriness)
+ target.AdjustStuttering(2)
+ target.Slowed(3)
+ addtimer(CALLBACK(target, /mob/.proc/AdjustJitter, -1000, 10), 2 SECONDS) //Still jittery, but vastly less
diff --git a/code/datums/spells/magnet.dm b/code/datums/spells/magnet.dm
index 21bf77d35b3..ea296eb5979 100644
--- a/code/datums/spells/magnet.dm
+++ b/code/datums/spells/magnet.dm
@@ -1,124 +1,57 @@
-// Disclaimer. This ain't working. Probably never worked
-/obj/effect/proc_holder/spell/magnet
+/obj/effect/proc_holder/spell/charge_up/bounce/magnet
name = "Magnetic Pull"
desc = "Pulls metalic objects from enemies hands with the power of MAGNETS."
charge_type = "recharge"
- charge_max = 300
- clothes_req = 0
+ action_icon_state = "magnet"
+ charge_max = 30 SECONDS
+ clothes_req = FALSE
invocation = "UN'LTD P'WAH!"
invocation_type = "none"
- cooldown_min = 30
- var/energy = 0
- var/ready = 0
- var/start_time = 0
- var/image/halo = null
- var/sound/Snd // so far only way i can think of to stop a sound, thank MSO for the idea.
- action_icon_state = "tech"
+ cooldown_min = 3 SECONDS
+ charge_sound = new /sound('sound/magic/lightning_chargeup.ogg', channel = 7)
+ max_charge_time = 10 SECONDS
+ stop_charging_text = "You stop charging the magnetism around you."
+ stop_charging_fail_text = "The magnetism around you is too strong to stop now!"
+ start_charging_text = "You start gathering magnetism around you."
+ bounce_hit_sound = 'sound/machines/defib_zap.ogg'
-/obj/effect/proc_holder/spell/magnet/create_new_targeting()
- var/datum/spell_targeting/targeted/T = new()
- T.random_target = TRUE
- T.allowed_type = /mob/living
- return T
-
-/obj/effect/proc_holder/spell/magnet/Click()
- if(!ready && start_time == 0)
- if(cast_check(TRUE, FALSE, usr))
- StartChargeup()
- else
- if(ready && cast_check(TRUE, FALSE, usr))
- choose_targets(usr)
- return 1
-
-/obj/effect/proc_holder/spell/magnet/proc/StartChargeup(mob/user = usr)
- ready = 1
- to_chat(user, "You start gathering the power.")
- Snd = new/sound('sound/magic/lightning_chargeup.ogg', channel = 7)
- halo = image("icon"='icons/effects/effects.dmi',"icon_state" ="electricity","layer" = EFFECTS_LAYER)
- user.overlays.Add(halo)
- playsound(get_turf(user), Snd, 50, 0)
- start_time = world.time
- if(do_mob(user, user, 100, uninterruptible=1))
- if(ready)
- Discharge()
-
-/obj/effect/proc_holder/spell/magnet/proc/Reset(mob/user = usr)
- ready = 0
- energy = 0
- start_time = 0
- if(halo)
- user.overlays.Remove(halo)
-
-/obj/effect/proc_holder/spell/magnet/revert_cast(mob/user = usr)
- to_chat(user, "No target found in range.")
- Reset(user)
+/obj/effect/proc_holder/spell/charge_up/bounce/magnet/New()
..()
+ charge_up_overlay = image(icon = 'icons/effects/effects.dmi', icon_state = "electricity", layer = EFFECTS_LAYER)
-/obj/effect/proc_holder/spell/magnet/proc/Discharge(mob/user = usr)
- var/mob/living/M = user
- to_chat(M, "You lose control over the power.")
- Reset(user)
- start_recharge()
+/obj/effect/proc_holder/spell/charge_up/bounce/magnet/get_bounce_energy()
+ return get_energy_charge()
+/obj/effect/proc_holder/spell/charge_up/bounce/magnet/get_bounce_amount()
+ if(get_energy_charge() >= 75)
+ return 5
+ return 0
-/obj/effect/proc_holder/spell/magnet/cast(list/targets, mob/user = usr)
- ready = 0
- var/mob/living/target = targets[1]
- Snd = sound(null, repeat = 0, wait = 1, channel = Snd.channel) //byond, why you suck?
- playsound(get_turf(user), Snd, 50, 0)// Sorry MrPerson, but the other ways just didn't do it the way i needed to work, this is the only way.
-
- user.Beam(target,icon_state="lightning",icon='icons/effects/effects.dmi',time=5)
+/obj/effect/proc_holder/spell/charge_up/bounce/magnet/create_beam(mob/origin, mob/target)
+ origin.Beam(target, icon_state = "lightning[rand(1, 12)]", icon = 'icons/effects/effects.dmi', time = 5)
+/obj/effect/proc_holder/spell/charge_up/bounce/magnet/apply_bounce_effect(mob/origin, mob/target, energy, mob/user)
+ var/list/items_to_throw = list()
switch(energy)
if(0 to 25)
if(prob(50))
- for(var/obj/item/I in target.l_hand)
- if(I.flags & CONDUCT)
- I.throw_at(user, I.throw_range, 4, target)
+ if(target.l_hand)
+ items_to_throw += target.l_hand
else
- for(var/obj/item/I in target.r_hand)
- if(I.flags & CONDUCT)
- I.throw_at(user, I.throw_range, 4, target)
- playsound(get_turf(target), 'sound/machines/defib_zap.ogg', 50, 1, -1)
- if(25 to 75)
- for(var/obj/item/I in target.l_hand)
- if(I.flags & CONDUCT)
- I.throw_at(user, I.throw_range, 4, target)
- for(var/obj/item/I in target.r_hand)
- if(I.flags & CONDUCT)
- I.throw_at(user, I.throw_range, 4, target)
- playsound(get_turf(target), 'sound/machines/defib_zap.ogg', 50, 1, -1)
- if(75 to 100)
- //CHAIN magnet
- Bolt(user,target,energy,5,user)
- Reset(user)
+ if(target.r_hand)
+ items_to_throw += target.r_hand
+ if(25 to INFINITY)
+ if(target.r_hand)
+ items_to_throw += target.r_hand
+ if(target.l_hand)
+ items_to_throw += target.l_hand
+ for(var/I in items_to_throw)
+ try_throw_object(user, target, I)
-/obj/effect/proc_holder/spell/magnet/proc/Bolt(mob/origin,mob/target,bolt_energy,bounces, mob/user = usr)
- origin.Beam(target, icon_state="lightning", icon='icons/effects/effects.dmi', time=5)
- var/mob/living/carbon/current = target
- if(bounces < 1)
- for(var/obj/item/I in target.l_hand)
- if(I.flags & CONDUCT)
- I.throw_at(user, I.throw_range, 4, target)
- for(var/obj/item/I in target.r_hand)
- if(I.flags & CONDUCT)
- I.throw_at(user, I.throw_range, 4, target)
- playsound(get_turf(current), 'sound/machines/defib_zap.ogg', 50, 1, -1)
- else
- for(var/obj/item/I in target.l_hand)
- if(I.flags & CONDUCT)
- I.throw_at(user, I.throw_range, 4, target)
- for(var/obj/item/I in target.r_hand)
- if(I.flags & CONDUCT)
- I.throw_at(user, I.throw_range, 4, target)
- 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(targeting.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,bounces-1,user) // 5 max bounces
+/obj/effect/proc_holder/spell/charge_up/bounce/magnet/proc/try_throw_object(mob/user, mob/thrower, obj/item/to_throw)
+ if(!(to_throw.flags & CONDUCT) || !thrower.unEquip(to_throw, silent = TRUE))
+ return FALSE
+ thrower.visible_message("[to_throw] gets thrown out of [thrower] [thrower.p_their()] hands!",
+ "[to_throw] suddenly gets thrown out of your hands!")
+ to_throw.throw_at(user, to_throw.throw_range, 4)
+ return TRUE
diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm
index c6ebf4a3d35..5c85e5128fa 100644
--- a/code/game/gamemodes/wizard/spellbook.dm
+++ b/code/game/gamemodes/wizard/spellbook.dm
@@ -107,7 +107,7 @@
/datum/spellbook_entry/lightningbolt
name = "Lightning Bolt"
- spell_type = /obj/effect/proc_holder/spell/lightning
+ spell_type = /obj/effect/proc_holder/spell/charge_up/bounce/lightning
log_name = "LB"
category = "Offensive"
cost = 1
diff --git a/code/modules/mob/living/carbon/superheroes.dm b/code/modules/mob/living/carbon/superheroes.dm
index 220844a84d9..bf1f4e56b3b 100644
--- a/code/modules/mob/living/carbon/superheroes.dm
+++ b/code/modules/mob/living/carbon/superheroes.dm
@@ -107,7 +107,7 @@
desc = "You are LightnIan, the lord of lightning! A freak electrical accident while working in the station's kennel \
has given you mastery over lightning and a peculiar desire to sniff butts. Although you are a recent addition to the \
station's hero roster, you intend to leave your mark."
- default_spells = list(/obj/effect/proc_holder/spell/lightning/lightnian)
+ default_spells = list(/obj/effect/proc_holder/spell/charge_up/bounce/lightning/lightnian)
/datum/superheroes/lightnian/equip(mob/living/carbon/human/H)
..()
@@ -126,7 +126,7 @@
desc = "You were a roboticist, once. Now you are Electro-Negmatic, a name this station will learn to fear. You designed \
your costume to resemble E-N, your faithful dog that some callous RD destroyed because it was sparking up the plasma. You \
intend to take your revenge and make them all pay thanks to your magnetic powers."
- default_spells = list(/obj/effect/proc_holder/spell/magnet)
+ default_spells = list(/obj/effect/proc_holder/spell/charge_up/bounce/magnet)
/datum/superheroes/electro/equip(mob/living/carbon/human/H)
..()
diff --git a/icons/mob/actions/actions.dmi b/icons/mob/actions/actions.dmi
index 19fc60a03c4..8cb31fd5135 100644
Binary files a/icons/mob/actions/actions.dmi and b/icons/mob/actions/actions.dmi differ
diff --git a/paradise.dme b/paradise.dme
index e1149a50c41..b54d8813b0e 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -434,6 +434,8 @@
#include "code\datums\spells\bloodcrawl.dm"
#include "code\datums\spells\chaplain.dm"
#include "code\datums\spells\charge.dm"
+#include "code\datums\spells\charge_up.dm"
+#include "code\datums\spells\charge_up_bounce.dm"
#include "code\datums\spells\cluwne.dm"
#include "code\datums\spells\conjure.dm"
#include "code\datums\spells\conjure_item.dm"