diff --git a/baystation12.dme b/baystation12.dme index aef205a4e00..5715667ade5 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -3150,6 +3150,7 @@ #include "code\modules\spells\aimed\flamethrower.dm" #include "code\modules\spells\aimed\healing.dm" #include "code\modules\spells\aimed\mana_burn.dm" +#include "code\modules\spells\aimed\mana_drain.dm" #include "code\modules\spells\aimed\onrush.dm" #include "code\modules\spells\aimed\passage.dm" #include "code\modules\spells\aimed\restore_limbs.dm" diff --git a/code/modules/spells/_spell.dm b/code/modules/spells/_spell.dm index ee987b15fef..c60c47df9e3 100644 --- a/code/modules/spells/_spell.dm +++ b/code/modules/spells/_spell.dm @@ -402,14 +402,13 @@ if(level_max[UPGRADE_TOTAL] <= up_count) // Too many levels, can't do it return FALSE - //if(upgrade_type && spell_levels[upgrade_type] && level_max[upgrade_type]) if(upgrade_type && spell_levels[upgrade_type] >= level_max[upgrade_type]) return FALSE return TRUE -/datum/spell/proc/ImproveSpell(upgrade_type) - if(!CanImprove(upgrade_type)) +/datum/spell/proc/ImproveSpell(upgrade_type, ignore_limit = FALSE) + if(!CanImprove(upgrade_type) && !ignore_limit) return FALSE spell_levels[upgrade_type]++ diff --git a/code/modules/spells/aimed/flamethrower.dm b/code/modules/spells/aimed/flamethrower.dm index d7589558702..a143ea0ac58 100644 --- a/code/modules/spells/aimed/flamethrower.dm +++ b/code/modules/spells/aimed/flamethrower.dm @@ -58,4 +58,8 @@ flame_power += 20 flame_color = flame_power >= 60 ? COLOR_PURPLE : COLOR_RED + // This is generally only available with spell steal + if(flame_power >= 80) + flame_distance += 1 + return "The [src] spell is now [flame_power >= 60 ? "much " : ""]more powerful." diff --git a/code/modules/spells/aimed/mana_burn.dm b/code/modules/spells/aimed/mana_burn.dm index 630e618266c..f0f22753e09 100644 --- a/code/modules/spells/aimed/mana_burn.dm +++ b/code/modules/spells/aimed/mana_burn.dm @@ -38,7 +38,7 @@ /datum/spell/aimed/mana_burn/fire_projectile(mob/living/user, mob/living/target) . = ..() var/datum/mana/M = GetManaDatum(target) - if(!istype(M) || M.mana_level <= 5) + if(!istype(M) || M.mana_level <= min_mana_burnt) to_chat(user, SPAN_WARNING("\The [target] did not possess enough mana to experience the burn.")) return diff --git a/code/modules/spells/aimed/mana_drain.dm b/code/modules/spells/aimed/mana_drain.dm new file mode 100644 index 00000000000..4b0d968a826 --- /dev/null +++ b/code/modules/spells/aimed/mana_drain.dm @@ -0,0 +1,91 @@ +/datum/spell/aimed/mana_drain + name = "Mana Drain" + desc = "This spell drains the mana out of the target, giving it to you instead." + deactive_msg = "You discharge the mana drain spell..." + active_msg = "You charge the mana drain spell!" + + charge_max = 25 SECONDS + cooldown_reduc = 5 SECONDS + + invocation = "Exhaurire!" + invocation_type = INVOKE_SHOUT + + level_max = list(UPGRADE_TOTAL = 2, UPGRADE_SPEED = 1, UPGRADE_POWER = 2) + + range = 5 + + hud_state = "wiz_mana_drain" + + cast_sound = 'sound/magic/drain.ogg' + + spell_cost = 3 + mana_cost = 5 + categories = list(SPELL_CATEGORY_ANTIMAGIC) + + /// Amount of mana drained every second; If target's mana is below this - the spell will end. + var/mana_drain_rate = 2 + /// How far can the target be away once the drain has started + var/mana_drain_range = 7 + /// Cannot drain mana for more than this amount of times + var/max_iterations = 100 + var/datum/beam/current_beam = null + +/datum/spell/aimed/mana_drain/Destroy() + QDEL_NULL(current_beam) + return ..() + +/datum/spell/aimed/mana_drain/TargetCastCheck(mob/living/user, mob/living/target) + if(!GetManaDatum(target)) + to_chat(user, SPAN_WARNING("The target must be capable of holding mana!")) + return FALSE + if(get_dist(user, target) > range) + to_chat(user, SPAN_WARNING("The target is too far away!")) + return FALSE + return ..() + +/datum/spell/aimed/mana_drain/fire_projectile(mob/living/user, mob/living/target) + . = ..() + to_chat(user, SPAN_NOTICE("You begin draining mana from \the [target]")) + to_chat(target, SPAN_DANGER("Your mana is being drained by \the [user]!")) + playsound(target, 'sound/magic/drain.ogg', 50, TRUE) + + QDEL_NULL(current_beam) + current_beam = user.Beam(target, icon_state = "drainbeam") + current_beam.visuals.color = COLOR_MANA + DoTheDrain(user, target) + +/datum/spell/aimed/mana_drain/ImproveSpellPower() + mana_drain_rate += initial(mana_drain_rate) + + return "The [src] spell now drains [mana_drain_rate * 2] mana per second." + +/datum/spell/aimed/mana_drain/proc/DoTheDrain(mob/living/user, atom/movable/target, iteration = 1) + if(QDELETED(target) || QDELETED(user) || !istype(target) || !istype(user)) + QDEL_NULL(current_beam) + return + + if(get_dist(user, target) > mana_drain_range) + QDEL_NULL(current_beam) + to_chat(user, SPAN_WARNING("\The [target] is too far away to continue the mana drain!")) + return + + var/datum/mana/user_mana = GetManaDatum(user) + var/datum/mana/target_mana = GetManaDatum(target) + if(!istype(user_mana) || !istype(target_mana)) + QDEL_NULL(current_beam) + return + + if(iteration >= max_iterations || target_mana.mana_level < mana_drain_rate) + QDEL_NULL(current_beam) + to_chat(user, SPAN_NOTICE("You finish draining mana out of \the [target].")) + return + + user_mana.AddMana(mana_drain_rate) + target_mana.UseMana(target, mana_drain_rate) + + var/obj/effect/temp_visual/decoy/D = new /obj/effect/temp_visual/decoy(get_turf(target), target.dir, target) + D.alpha = 125 + D.color = COLOR_MANA + animate(D, alpha = 0, pixel_x = rand(-16, 16), pixel_y = rand(-16, 16), time = rand(8, 18)) + + addtimer(CALLBACK(src, .proc/DoTheDrain, user, target, iteration + 1), (0.5 SECONDS)) diff --git a/code/modules/spells/aimed/spell_steal.dm b/code/modules/spells/aimed/spell_steal.dm index a31ef9e50af..ea7d8fb914f 100644 --- a/code/modules/spells/aimed/spell_steal.dm +++ b/code/modules/spells/aimed/spell_steal.dm @@ -12,7 +12,8 @@ invocation = "Furtum!" invocation_type = INVOKE_SHOUT - level_max = list(UPGRADE_TOTAL = 3, UPGRADE_SPEED = 2, UPGRADE_STEAL_DURATION = 2) + level_max = list(UPGRADE_TOTAL = 4, UPGRADE_SPEED = 2, UPGRADE_POWER = 2, UPGRADE_STEAL_DURATION = 2) + upgrade_cost = list(UPGRADE_SPEED = 5, UPGRADE_POWER = 10, UPGRADE_STEAL_DURATION = 5) range = 5 @@ -68,8 +69,9 @@ // Do the upgrades! for(var/up_type in S.spell_levels) if(target.mind.last_used_spell.spell_levels[up_type]) - for(var/i = 1 to target.mind.last_used_spell.spell_levels[up_type]) - S.ImproveSpell(up_type) + // Stolen spells will be upgraded to the same level as that of the original + our own power upgrade level + for(var/i = 1 to target.mind.last_used_spell.spell_levels[up_type] + spell_levels[UPGRADE_POWER]) + S.ImproveSpell(up_type, TRUE) // To prevent shenanigans with "Consume Magic" S.total_points_used = 0 user.add_spell(S) @@ -84,6 +86,9 @@ if(upgrade_type == UPGRADE_STEAL_DURATION) return ImproveSpellStealDuration() +/datum/spell/aimed/spell_steal/ImproveSpellPower() + return "The stolen spells are now stronger." + /datum/spell/aimed/spell_steal/proc/ImproveSpellStealDuration() stolen_spell_duration += 30 SECONDS return "The stolen spells now remain under your control for [stolen_spell_duration / 10] seconds!" diff --git a/icons/effects/beam.dmi b/icons/effects/beam.dmi index 2362c6743ea..0e588d2a457 100644 Binary files a/icons/effects/beam.dmi and b/icons/effects/beam.dmi differ diff --git a/icons/mob/screen_spells.dmi b/icons/mob/screen_spells.dmi index f5ff6a2db10..a60dcdbea5d 100644 Binary files a/icons/mob/screen_spells.dmi and b/icons/mob/screen_spells.dmi differ