diff --git a/code/game/gamemodes/technomancer/assistance/assistance.dm b/code/game/gamemodes/technomancer/assistance/assistance.dm
index 3cdf7014ad..7301677e32 100644
--- a/code/game/gamemodes/technomancer/assistance/assistance.dm
+++ b/code/game/gamemodes/technomancer/assistance/assistance.dm
@@ -98,8 +98,8 @@
/datum/technomancer/assistance/golem
name = "Friendly GOLEM unit"
desc = "Teleports a specially designed synthetic unit to you, which is very durable, has an advanced AI, and can also use \
- functions. It knows Shield, Targeted Blink, Beam, Flame Tongue, Mend Wounds, and Mend Burns. It also has a large storage \
- capacity for energy, and due to it's synthetic nature, instability is less of an issue for them."
+ functions. It knows Shield, Targeted Blink, Beam, Mend Life, Mend Synthetic, Lightning, Repel Missiles, Corona, Ionic Bolt, Dispel, and Chain Lightning. \
+ It also has a large storage capacity for energy, and due to it's synthetic nature, instability is less of an issue for them."
cost = 350
obj_path = null //TODO
one_use_only = 1
diff --git a/code/game/gamemodes/technomancer/assistance/golem.dm b/code/game/gamemodes/technomancer/assistance/golem.dm
index 8bb6ef2ea0..4bec09940d 100644
--- a/code/game/gamemodes/technomancer/assistance/golem.dm
+++ b/code/game/gamemodes/technomancer/assistance/golem.dm
@@ -1,9 +1,9 @@
//An AI-controlled 'companion' for the Technomancer. It's tough, strong, and can also use spells.
-/mob/living/simple_animal/hostile/technomancer_golem
+/mob/living/simple_animal/technomancer_golem
name = "G.O.L.E.M."
desc = "A rather unusual looking synthetic."
- icon = 'icons/mob/robots.dmi'
- icon_state = "Security"
+ icon = 'icons/mob/mob.dmi'
+ icon_state = "technomancer_golem"
health = 250
maxHealth = 250
stop_automated_movement = 1
@@ -27,46 +27,137 @@
unsuitable_atoms_damage = 0
speed = 0
- melee_damage_lower = 10
- melee_damage_upper = 10
- attacktext = "pummeled"
+ melee_damage_lower = 30 // It has a built in esword.
+ melee_damage_upper = 30
+ attacktext = "slashed"
attack_sound = null
friendly = "hugs"
resistance = 0
- var/obj/item/weapon/technomancer_core/core = null
- var/obj/item/weapon/spell/active_spell = null
+ var/obj/item/weapon/technomancer_core/golem/core = null
+ var/obj/item/weapon/spell/active_spell = null // Shield and ranged spells
var/mob/living/master = null
-/mob/living/simple_animal/hostile/technomancer_golem/New()
- ..()
- core = new core(src)
+ var/list/known_spells = list(
+ "reflect" = /obj/item/weapon/spell/reflect,
+ "shield" = /obj/item/weapon/spell/shield,
+ "dispel" = /obj/item/weapon/spell/dispel,
+ "mend life" = /obj/item/weapon/spell/modifier/mend_life,
+ "mend synthetic" = /obj/item/weapon/spell/modifier/mend_synthetic,
+ "repel missiles" = /obj/item/weapon/spell/modifier/repel_missiles,
+ "corona" = /obj/item/weapon/spell/modifier/corona,
+ "beam" = /obj/item/weapon/spell/projectile/beam,
+ "chain lightning" = /obj/item/weapon/spell/projectile/chain_lightning,
+ "force missile" = /obj/item/weapon/spell/projectile/force_missile,
+ "ionic bolt" = /obj/item/weapon/spell/projectile/ionic_bolt,
+ "lightning" = /obj/item/weapon/spell/projectile/lightning
+ )
-/mob/living/simple_animal/hostile/technomancer_golem/Destroy()
+/mob/living/simple_animal/technomancer_golem/New()
+ ..()
+ core = new(src)
+ update_icon()
+
+/mob/living/simple_animal/technomancer_golem/Destroy()
qdel(core)
..()
-/mob/living/simple_animal/hostile/technomancer_golem/proc/bind_to_mob(mob/user)
+/mob/living/simple_animal/technomancer_golem/update_icon()
+ overlays.Cut()
+ overlays.Add(image(icon, src, "golem_sword"))
+ overlays.Add(image(icon, src, "golem_spell"))
+
+/mob/living/simple_animal/technomancer_golem/isSynthetic()
+ return TRUE // So Mend Synthetic will work on them.
+
+/mob/living/simple_animal/technomancer_golem/place_spell_in_hand(var/path)
+ if(!path || !ispath(path))
+ return 0
+
+ if(active_spell)
+ qdel(active_spell) // Get rid of our old spell.
+
+ var/obj/item/weapon/spell/S = new path(src)
+ active_spell = S
+
+/mob/living/simple_animal/technomancer_golem/verb/test_giving_spells()
+ var/choice = input(usr, "What spell?", "Give spell") as null|anything in known_spells
+ if(choice)
+ place_spell_in_hand(known_spells[choice])
+
+// Used to cast spells.
+/mob/living/simple_animal/technomancer_golem/RangedAttack(var/atom/A, var/params)
+ if(active_spell)
+ if(active_spell.cast_methods & CAST_RANGED)
+ active_spell.on_ranged_cast(A, src)
+
+/mob/living/simple_animal/technomancer_golem/UnarmedAttack(var/atom/A, var/proximity)
+ if(proximity)
+ if(active_spell)
+ if(active_spell.cast_methods & CAST_MELEE)
+ active_spell.on_melee_cast(A, src)
+ else if(active_spell.cast_methods & CAST_RANGED)
+ active_spell.on_ranged_cast(A, src)
+ var/effective_cooldown = round(active_spell.cooldown * core.cooldown_modifier, 5)
+ src.setClickCooldown(effective_cooldown)
+ else
+ ..()
+
+/mob/living/simple_animal/technomancer_golem/get_technomancer_core()
+ return core
+
+/mob/living/simple_animal/technomancer_golem/proc/bind_to_mob(mob/user)
if(!user || master)
return
master = user
name = "[master]'s [initial(name)]"
-/mob/living/simple_animal/hostile/technomancer_golem/examine(mob/user)
+/mob/living/simple_animal/technomancer_golem/examine(mob/user)
..()
if(user.mind && technomancers.is_antagonist(user.mind))
user << "Your pride and joy. It's a very special synthetic robot, capable of using functions similar to you, and you built it \
yourself! It'll always stand by your side, ready to help you out. You have no idea what GOLEM stands for, however..."
-/mob/living/simple_animal/hostile/technomancer_golem/Life()
+/mob/living/simple_animal/technomancer_golem/Life()
+ ..()
handle_ai()
-/mob/living/simple_animal/hostile/technomancer_golem/proc/handle_ai()
+// This is where the real spaghetti begins.
+/mob/living/simple_animal/technomancer_golem/proc/handle_ai()
if(!master)
return
if(get_dist(src, master) > 6 || src.z != master.z)
- recall_to_master()
+ targeted_blink(master)
+
+ // Give our allies buffs and heals.
+ for(var/mob/living/L in view(src))
+ if(L in friends)
+ support_friend(L)
+ return
+
+/mob/living/simple_animal/technomancer_golem/proc/support_friend(var/mob/living/L)
+ if(L.getBruteLoss() >= 10 || L.getFireLoss() >= 10)
+ if(L.isSynthetic() && !L.has_modifier_of_type(/datum/modifier/technomancer/mend_synthetic))
+ place_spell_in_hand(known_spells["mend synthetic"])
+ targeted_blink(L)
+ UnarmedAttack(L, 1)
+ else if(!L.has_modifier_of_type(/datum/modifier/technomancer/mend_life))
+ place_spell_in_hand(known_spells["mend life"])
+ targeted_blink(L)
+ UnarmedAttack(L, 1)
+ return
-/mob/living/simple_animal/hostile/technomancer_golem/proc/recall_to_master()
+ // Give them repel missiles if they lack it.
+ if(!L.has_modifier_of_type(/datum/modifier/technomancer/repel_missiles))
+ place_spell_in_hand(known_spells["repel missiles"])
+ RangedAttack(L)
+ return
+
+/mob/living/simple_animal/technomancer_golem/proc/targeted_blink(var/atom/target)
+ var/datum/effect/effect/system/spark_spread/spark_system = PoolOrNew(/datum/effect/effect/system/spark_spread)
+ spark_system.set_up(5, 0, get_turf(src))
+ spark_system.start()
+ src.visible_message("\The [src] vanishes!")
+ src.forceMove(get_turf(target))
return
\ No newline at end of file
diff --git a/code/game/gamemodes/technomancer/core_obj.dm b/code/game/gamemodes/technomancer/core_obj.dm
index 079db9a90b..7cea66660e 100644
--- a/code/game/gamemodes/technomancer/core_obj.dm
+++ b/code/game/gamemodes/technomancer/core_obj.dm
@@ -330,6 +330,18 @@
spell_power_modifier = 1.75
energy_cost_modifier = 2.0
+// For use only for the GOLEM.
+/obj/item/weapon/technomancer_core/golem
+ name = "integrated core"
+ desc = "A bewilderingly complex 'black box' that allows the wearer to accomplish amazing feats. This type is not meant \
+ to be worn on the back like other cores. Instead it is meant to be installed inside a synthetic shell. As a result, it's \
+ a lot more robust."
+ energy = 25000
+ max_energy = 25000
+ regen_rate = 100 //250 seconds to full
+ instability_modifier = 0.75
+
+
/obj/item/weapon/technomancer_core/verb/toggle_lock()
set name = "Toggle Core Lock"
set category = "Object"
diff --git a/code/game/gamemodes/technomancer/devices/tesla_armor.dm b/code/game/gamemodes/technomancer/devices/tesla_armor.dm
index 6b981aa8eb..2e9a60a8e6 100644
--- a/code/game/gamemodes/technomancer/devices/tesla_armor.dm
+++ b/code/game/gamemodes/technomancer/devices/tesla_armor.dm
@@ -1,8 +1,8 @@
/datum/technomancer/equipment/tesla_armor
name = "Tesla Armor"
desc = "This piece of armor offers a retaliation-based defense. When the armor is 'ready', it will completely protect you from \
- the next attack you suffer, and strike the attacker with a strong bolt of lightning. This effect requires twenty seconds to \
- recharge. If you are attacked while this is recharging, a weaker lightning bolt is sent out, however you won't be protected from \
+ the next attack you suffer, and strike the attacker with a strong bolt of lightning, provided they are close enough. This effect requires \
+ fifteen seconds to recharge. If you are attacked while this is recharging, a weaker lightning bolt is sent out, however you won't be protected from \
the person beating you."
cost = 150
obj_path = /obj/item/clothing/suit/armor/tesla
@@ -10,23 +10,33 @@
/obj/item/clothing/suit/armor/tesla
name = "tesla armor"
desc = "This rather dangerous looking armor will hopefully shock your enemies, and not you in the process."
- icon_state = "reactiveoff" //wip
- item_state = "reactiveoff"
+ icon_state = "reactive" //wip
+ item_state = "reactive"
blood_overlay_type = "armor"
slowdown = 1
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0)
var/ready = 1 //Determines if the next attack will be blocked, as well if a strong lightning bolt is sent out at the attacker.
var/ready_icon_state = "reactive" //also wip
- var/cooldown_to_charge = 20 SECONDS
+ var/normal_icon_state = "reactiveoff"
+ var/cooldown_to_charge = 15 SECONDS
/obj/item/clothing/suit/armor/tesla/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
//First, some retaliation.
- if(attacker && attacker != user)
- if(get_dist(user, attacker) <= 3) //Anyone farther away than three tiles is too far to shoot lightning at.
+ if(istype(damage_source, /obj/item/projectile))
+ var/obj/item/projectile/P = damage_source
+ if(P.firer && get_dist(user, P.firer) <= 3)
if(ready)
- shoot_lightning(attacker, 40)
+ shoot_lightning(P.firer, 40)
else
- shoot_lightning(attacker, 15)
+ shoot_lightning(P.firer, 15)
+
+ else
+ if(attacker && attacker != user)
+ if(get_dist(user, attacker) <= 3) //Anyone farther away than three tiles is too far to shoot lightning at.
+ if(ready)
+ shoot_lightning(attacker, 40)
+ else
+ shoot_lightning(attacker, 15)
//Deal with protecting our wearer now.
if(ready)
@@ -45,10 +55,14 @@
if(ready)
icon_state = ready_icon_state
else
- icon_state = initial(icon_state)
+ icon_state = normal_icon_state
+ if(ishuman(loc))
+ var/mob/living/carbon/human/H = loc
+ H.update_inv_wear_suit(0)
/obj/item/clothing/suit/armor/tesla/proc/shoot_lightning(var/mob/target, var/power)
var/obj/item/projectile/beam/lightning/lightning = new(src)
lightning.power = power
lightning.launch(target)
- visible_message("\The [src] strikes \the [target] with lightning!")
\ No newline at end of file
+ visible_message("\The [src] strikes \the [target] with lightning!")
+ playsound(get_turf(src), 'sound/weapons/gauss_shoot.ogg', 75, 1)
\ No newline at end of file
diff --git a/code/game/gamemodes/technomancer/instability.dm b/code/game/gamemodes/technomancer/instability.dm
index 453469619c..80664f4c62 100644
--- a/code/game/gamemodes/technomancer/instability.dm
+++ b/code/game/gamemodes/technomancer/instability.dm
@@ -44,25 +44,25 @@
// Description: Makes instability decay. instability_effects() handles the bad effects for having instability. It will also hold back
// from causing bad effects more than one every ten seconds, to prevent sudden death from angry RNG.
/mob/living/proc/handle_instability()
- instability = round(Clamp(instability, 0, 200))
+ instability = Ceiling(Clamp(instability, 0, 200))
//This should cushon against really bad luck.
if(instability && last_instability_event < (world.time - 10 SECONDS) && prob(20))
instability_effects()
switch(instability)
if(1 to 10)
- adjust_instability(-2)
+ adjust_instability(-1)
if(11 to 20)
- adjust_instability(-4)
+ adjust_instability(-2)
if(21 to 30)
- adjust_instability(-6)
+ adjust_instability(-3)
if(31 to 40)
- adjust_instability(-8)
+ adjust_instability(-4)
if(41 to 50)
- adjust_instability(-10)
+ adjust_instability(-5)
if(51 to 100)
- adjust_instability(-20)
+ adjust_instability(-10)
if(101 to 200)
- adjust_instability(-40)
+ adjust_instability(-20)
/mob/living/carbon/human/handle_instability()
..()
@@ -277,12 +277,17 @@
// People next to the source take a third of the instability. Further distance decreases the amount absorbed.
var/outgoing_instability = (instability / 3) * ( 1 / (radius**2) )
- // Energy armor like from the AMI RIG can protect from this.
- var/armor = getarmor(null, "energy")
- var/armor_factor = abs( (armor - 100) / 100)
- outgoing_instability = outgoing_instability * armor_factor
- if(outgoing_instability)
- to_chat(H, "The purple glow makes you feel strange...")
- H.adjust_instability(outgoing_instability)
+
+ H.receive_radiated_instability(outgoing_instability)
set_light(distance, distance * 4, l_color = "#C26DDE")
+
+// This should only be used for EXTERNAL sources of instability, such as from someone or something glowing.
+/mob/living/proc/receive_radiated_instability(amount)
+ // Energy armor like from the AMI RIG can protect from this.
+ var/armor = getarmor(null, "energy")
+ var/armor_factor = abs( (armor - 100) / 100)
+ amount = amount * armor_factor
+ if(amount && prob(10))
+ to_chat(src, "The purple glow makes you feel strange...")
+ adjust_instability(amount)
diff --git a/code/game/gamemodes/technomancer/spell_objs.dm b/code/game/gamemodes/technomancer/spell_objs.dm
index fb22001d30..61b831ac86 100644
--- a/code/game/gamemodes/technomancer/spell_objs.dm
+++ b/code/game/gamemodes/technomancer/spell_objs.dm
@@ -31,7 +31,8 @@
)
throwforce = 0
force = 0
- var/mob/living/carbon/human/owner = null
+// var/mob/living/carbon/human/owner = null
+ var/mob/living/owner = null
var/obj/item/weapon/technomancer_core/core = null
var/cast_methods = null // Controls how the spell is casted.
var/aspect = null // Used for combining spells.
@@ -115,16 +116,33 @@
amount = round(amount * core.instability_modifier, 0.1)
owner.adjust_instability(amount)
+// Proc: get_technomancer_core()
+// Parameters: 0
+// Description: Returns the technomancer's core, assuming it is being worn properly.
+/mob/living/proc/get_technomancer_core()
+ return null
+
+/mob/living/carbon/human/get_technomancer_core()
+ var/obj/item/weapon/technomancer_core/core = back
+ if(istype(core))
+ return core
+ return null
+
// Proc: New()
// Parameters: 0
// Description: Sets owner to equal its loc, links to the owner's core, then applies overlays if needed.
/obj/item/weapon/spell/New()
..()
- if(ishuman(loc))
+ if(isliving(loc))
owner = loc
if(owner)
- if(istype(/obj/item/weapon/technomancer_core, owner.back))
- core = owner.back
+ core = owner.get_technomancer_core()
+ if(!core)
+ to_chat(owner, "You need a Core to do that.")
+ qdel(src)
+ return
+// if(istype(/obj/item/weapon/technomancer_core, owner.back))
+// core = owner.back
update_icon()
// Proc: Destroy()
diff --git a/code/game/gamemodes/technomancer/spells/aura/fire_aura.dm b/code/game/gamemodes/technomancer/spells/aura/fire_aura.dm
index 952fd5d43d..6111784d6f 100644
--- a/code/game/gamemodes/technomancer/spells/aura/fire_aura.dm
+++ b/code/game/gamemodes/technomancer/spells/aura/fire_aura.dm
@@ -13,17 +13,18 @@
/obj/item/weapon/spell/aura/fire
name = "Fire Storm"
desc = "Things are starting to heat up."
- icon_state = "generic"
+ icon_state = "fire_bolt"
aspect = ASPECT_FIRE
glow_color = "#FF6A00"
/obj/item/weapon/spell/aura/fire/process()
if(!pay_energy(100))
qdel(src)
- var/list/nearby_things = range(calculate_spell_power(4),owner)
+ var/list/nearby_things = range(round(calculate_spell_power(4)),owner)
- var/temp_change = calculate_spell_power(80)
- var/temp_cap = calculate_spell_power(600)
+ var/temp_change = calculate_spell_power(150)
+ var/datum/species/baseline = all_species["Human"]
+ var/temp_cap = baseline.heat_level_3 * 2
var/fire_power = calculate_spell_power(2)
if(check_for_scepter())
@@ -38,7 +39,8 @@
var/protection = H.get_heat_protection(1000)
if(protection < 1)
var/heat_factor = abs(protection - 1)
- H.bodytemperature = min( (H.bodytemperature + temp_change) * heat_factor, temp_cap)
+ temp_change *= heat_factor
+ H.bodytemperature = min(H.bodytemperature + temp_change, temp_cap)
turf_check:
for(var/turf/simulated/T in nearby_things)
diff --git a/code/game/gamemodes/technomancer/spells/aura/frost_aura.dm b/code/game/gamemodes/technomancer/spells/aura/frost_aura.dm
index c2106d5aa3..7e788de96e 100644
--- a/code/game/gamemodes/technomancer/spells/aura/frost_aura.dm
+++ b/code/game/gamemodes/technomancer/spells/aura/frost_aura.dm
@@ -2,7 +2,7 @@
name = "Chilling Aura"
desc = "Lowers the core body temperature of everyone around you (except for your friends), causing them to become very slow if \
they stay within four meters of you."
- enhancement_desc = "The chill becomes lethal."
+ enhancement_desc = "Will make nearby entities even slower."
spell_power_desc = "Radius and rate of cooling are scaled."
cost = 100
obj_path = /obj/item/weapon/spell/aura/frost
@@ -20,14 +20,16 @@
/obj/item/weapon/spell/aura/frost/process()
if(!pay_energy(100))
qdel(src)
- var/list/nearby_mobs = range(calculate_spell_power(4),owner)
+ var/list/nearby_mobs = range(round(calculate_spell_power(4)),owner)
var/temp_change = calculate_spell_power(40)
- var/temp_cap = 260 // Just above the damage threshold, for humans. Unathi are less fortunate.
+ var/datum/species/baseline = all_species["Human"]
+ var/temp_cap = baseline.cold_level_2 - 5
if(check_for_scepter())
temp_change *= 2
- temp_cap = 200
+ temp_cap = baseline.cold_level_3 - 5
+
for(var/mob/living/carbon/human/H in nearby_mobs)
if(is_ally(H))
continue
@@ -35,6 +37,7 @@
var/protection = H.get_cold_protection(1000)
if(protection < 1)
var/cold_factor = abs(protection - 1)
- H.bodytemperature = max( (H.bodytemperature - temp_change) * cold_factor, temp_cap)
+ temp_change *= cold_factor
+ H.bodytemperature = max(H.bodytemperature - temp_change, temp_cap)
adjust_instability(1)
\ No newline at end of file
diff --git a/code/game/gamemodes/technomancer/spells/dispel.dm b/code/game/gamemodes/technomancer/spells/dispel.dm
index 10f258bf58..60266426cb 100644
--- a/code/game/gamemodes/technomancer/spells/dispel.dm
+++ b/code/game/gamemodes/technomancer/spells/dispel.dm
@@ -18,9 +18,6 @@
/obj/item/weapon/spell/dispel/on_ranged_cast(atom/hit_atom, mob/living/user)
if(isliving(hit_atom) && within_range(hit_atom) && pay_energy(1000))
var/mob/living/target = hit_atom
- for(var/obj/item/weapon/inserted_spell/I in target)
- I.on_expire(dispelled = 1)
- log_and_message_admins("dispelled [I] on [target].")
target.remove_modifiers_of_type(/datum/modifier/technomancer)
user.adjust_instability(10)
qdel(src)
\ No newline at end of file
diff --git a/code/game/gamemodes/technomancer/spells/gambit.dm b/code/game/gamemodes/technomancer/spells/gambit.dm
index 0541e5473e..e0116073dc 100644
--- a/code/game/gamemodes/technomancer/spells/gambit.dm
+++ b/code/game/gamemodes/technomancer/spells/gambit.dm
@@ -1,6 +1,9 @@
/datum/technomancer/spell/gambit
name = "Gambit"
desc = "This function causes you to receive a random function, including those which you haven't purchased."
+// enhancement_desc = "Makes results less random and more biased towards what the function thinks you need in your current situation."
+ enhancement_desc = "Instead of a purely random spell, it will give you a \"random\" spell."
+ spell_power_desc = "Makes certain rare functions possible to acquire via Gambit which cannot be obtained otherwise, if above 100%."
ability_icon_state = "tech_gambit"
cost = 50
obj_path = /obj/item/weapon/spell/gambit
@@ -11,9 +14,10 @@
/obj/item/weapon/spell/gambit,
/obj/item/weapon/spell/projectile,
/obj/item/weapon/spell/aura,
- /obj/item/weapon/spell/insert,
+// /obj/item/weapon/spell/insert,
/obj/item/weapon/spell/spawner,
- /obj/item/weapon/spell/summon)
+ /obj/item/weapon/spell/summon,
+ /obj/item/weapon/spell/modifier)
/obj/item/weapon/spell/gambit
name = "gambit"
@@ -21,12 +25,110 @@
icon_state = "gambit"
cast_methods = CAST_USE
aspect = ASPECT_UNSTABLE
+ var/list/rare_spells = list(
+ /obj/item/weapon/spell/modifier/mend_all
+ )
+
/obj/item/weapon/spell/gambit/on_use_cast(mob/living/carbon/human/user)
if(pay_energy(200))
adjust_instability(3)
- var/obj/item/weapon/spell/random_spell = pick(all_technomancer_gambit_spells)
- if(random_spell)
- user.drop_from_inventory(src, null)
- user.place_spell_in_hand(random_spell)
+ if(check_for_scepter())
+ give_new_spell(biased_random_spell())
+ else
+ give_new_spell(random_spell())
qdel(src)
+
+/obj/item/weapon/spell/gambit/proc/give_new_spell(var/spell_type)
+ owner.drop_from_inventory(src, null)
+ owner.place_spell_in_hand(spell_type)
+
+// Gives a random spell.
+/obj/item/weapon/spell/gambit/proc/random_spell()
+ var/list/potential_spells = all_technomancer_gambit_spells.Copy()
+ var/rare_spell_chance = between(0, calculate_spell_power(100) - 100, 100) // Having 120% spellpower means a 20% chance to get to roll for rare spells.
+ if(prob(rare_spell_chance))
+ potential_spells += rare_spells.Copy()
+ to_chat(owner, "You feel a bit luckier...")
+ return pick(potential_spells)
+
+// Gives a "random" spell.
+/obj/item/weapon/spell/gambit/proc/biased_random_spell()
+ var/list/potential_spells = list()
+ var/rare_spell_chance = between(0, calculate_spell_power(100) - 100, 100)
+ var/give_rare_spells = FALSE
+ if(prob(rare_spell_chance))
+ give_rare_spells = TRUE
+ to_chat(owner, "You feel a bit luckier...")
+
+ // First the spell will concern itself with the health of the technomancer.
+ if(prob(owner.getBruteLoss() + owner.getBruteLoss() * 2)) // Having 20 brute means a 40% chance of being added to the pool.
+ if(!owner.isSynthetic())
+ potential_spells |= /obj/item/weapon/spell/modifier/mend_life
+ else
+ potential_spells |= /obj/item/weapon/spell/modifier/mend_synthetic
+ if(give_rare_spells)
+ potential_spells |= /obj/item/weapon/spell/modifier/mend_all
+
+ // Second, the spell will try to prepare the technomancer for threats.
+ var/hostile_mobs = 0 // Counts how many hostile mobs. Higher numbers make it more likely for AoE spells to be chosen.
+
+ for(var/mob/living/L in view(owner))
+ // Spiders, carp... bears.
+ if(istype(L, /mob/living/simple_animal))
+ var/mob/living/simple_animal/SM = L
+ if(!is_ally(SM) && SM.hostile)
+ hostile_mobs++
+ if(SM.summoned || SM.supernatural) // Our creations might be trying to kill us.
+ potential_spells |= /obj/item/weapon/spell/abjuration
+
+ // Always assume borgs are hostile.
+ if(istype(L, /mob/living/silicon/robot))
+ if(!istype(L, /mob/living/silicon/robot/drone)) // Drones are okay, however.
+ hostile_mobs++
+ potential_spells |= /obj/item/weapon/spell/projectile/ionic_bolt
+
+ // Finally we get to humanoids.
+ if(istype(L, /mob/living/carbon/human))
+ var/mob/living/carbon/human/H = L
+ if(is_ally(H)) // Don't get scared by our apprentice.
+ continue
+
+ for(var/obj/item/I in list(H.l_hand, H.r_hand))
+ // Guns are scary.
+ if(istype(I, /obj/item/weapon/gun)) // Toy guns will count as well but oh well.
+ hostile_mobs++
+ continue
+ // Strong melee weapons are scary as well.
+ else if(I.force >= 15)
+ hostile_mobs++
+ continue
+
+ if(hostile_mobs)
+ potential_spells |= /obj/item/weapon/spell/shield
+ potential_spells |= /obj/item/weapon/spell/reflect
+ potential_spells |= /obj/item/weapon/spell/targeting_matrix
+ potential_spells |= /obj/item/weapon/spell/warp_strike
+
+ if(hostile_mobs >= 3) // Lots of baddies, give them AoE.
+ potential_spells |= /obj/item/weapon/spell/projectile/chain_lightning
+ potential_spells |= /obj/item/weapon/spell/projectile/chain_lightning/lesser
+ potential_spells |= /obj/item/weapon/spell/spawner/fire_blast
+ potential_spells |= /obj/item/weapon/spell/condensation
+ potential_spells |= /obj/item/weapon/spell/aura/frost
+ else
+ potential_spells |= /obj/item/weapon/spell/projectile/beam
+ potential_spells |= /obj/item/weapon/spell/projectile/overload
+ potential_spells |= /obj/item/weapon/spell/projectile/force_missile
+ potential_spells |= /obj/item/weapon/spell/projectile/lightning
+
+ // Third priority is recharging the core.
+ if(core.energy / core.max_energy <= 0.5)
+ potential_spells |= /obj/item/weapon/spell/energy_siphon
+ potential_spells |= /obj/item/weapon/spell/instability_tap
+
+ // Fallback method in case nothing gets added.
+ if(!potential_spells.len)
+ potential_spells = all_technomancer_gambit_spells.Copy()
+
+ return pick(potential_spells)
\ No newline at end of file
diff --git a/code/game/gamemodes/technomancer/spells/insert/mend_burns.dm b/code/game/gamemodes/technomancer/spells/insert/mend_burns.dm
deleted file mode 100644
index 2201787d34..0000000000
--- a/code/game/gamemodes/technomancer/spells/insert/mend_burns.dm
+++ /dev/null
@@ -1,30 +0,0 @@
-/datum/technomancer/spell/mend_burns
- name = "Mend Burns"
- desc = "Heals minor burns, such as from exposure to flame, electric shock, or lasers."
- spell_power_desc = "Healing amount increased."
- cost = 50
- obj_path = /obj/item/weapon/spell/insert/mend_burns
- ability_icon_state = "tech_mendburns"
- category = SUPPORT_SPELLS
-
-/obj/item/weapon/spell/insert/mend_burns
- name = "mend burns"
- desc = "Ointment is a thing of the past."
- icon_state = "mend_burns"
- cast_methods = CAST_MELEE
- aspect = ASPECT_BIOMED
- light_color = "#FF5C5C"
- inserting = /obj/item/weapon/inserted_spell/mend_burns
-
-/obj/item/weapon/inserted_spell/mend_burns/on_insert()
- spawn(1)
- if(ishuman(host))
- var/mob/living/carbon/human/H = host
- var/heal_power = host == origin ? 10 : 30
- heal_power = round(heal_power * spell_power_at_creation, 1)
- origin.adjust_instability(10)
- for(var/i = 0, i<5,i++)
- if(H)
- H.adjustFireLoss(-heal_power / 5)
- sleep(1 SECOND)
- on_expire()
\ No newline at end of file
diff --git a/code/game/gamemodes/technomancer/spells/insert/mend_metal.dm b/code/game/gamemodes/technomancer/spells/insert/mend_metal.dm
deleted file mode 100644
index 376ab8df1c..0000000000
--- a/code/game/gamemodes/technomancer/spells/insert/mend_metal.dm
+++ /dev/null
@@ -1,33 +0,0 @@
-/datum/technomancer/spell/mend_metal
- name = "Mend Metal"
- desc = "Restores integrity to external robotic components."
- spell_power_desc = "Healing amount increased."
- cost = 50
- obj_path = /obj/item/weapon/spell/insert/mend_metal
- ability_icon_state = "tech_mendwounds"
- category = SUPPORT_SPELLS
-
-/obj/item/weapon/spell/insert/mend_metal
- name = "mend metal"
- desc = "A roboticist is now obsolete."
- icon_state = "mend_wounds"
- cast_methods = CAST_MELEE
- aspect = ASPECT_BIOMED
- light_color = "#FF5C5C"
- inserting = /obj/item/weapon/inserted_spell/mend_metal
-
-/obj/item/weapon/inserted_spell/mend_metal/on_insert()
- spawn(1)
- if(ishuman(host))
- var/mob/living/carbon/human/H = host
- var/heal_power = host == origin ? 10 : 30
- heal_power = round(heal_power * spell_power_at_creation, 1)
- origin.adjust_instability(10)
- for(var/i = 0, i<5,i++)
- if(H)
- for(var/obj/item/organ/external/O in H.organs)
- if(O.robotic < ORGAN_ROBOT) // Robot parts only.
- continue
- O.heal_damage(heal_power / 5, 0, internal = 1, robo_repair = 1)
- sleep(1 SECOND)
- on_expire()
\ No newline at end of file
diff --git a/code/game/gamemodes/technomancer/spells/insert/mend_organs.dm b/code/game/gamemodes/technomancer/spells/insert/mend_organs.dm
deleted file mode 100644
index 4ac29658ed..0000000000
--- a/code/game/gamemodes/technomancer/spells/insert/mend_organs.dm
+++ /dev/null
@@ -1,56 +0,0 @@
-/datum/technomancer/spell/mend_organs
- name = "Great Mend Wounds"
- desc = "Greatly heals the target's wounds, both external and internal. Restores internal organs to functioning states, even if \
- robotic, reforms bones, patches internal bleeding, and restores missing blood."
- spell_power_desc = "Healing amount increased."
- cost = 100
- obj_path = /obj/item/weapon/spell/insert/mend_organs
- ability_icon_state = "tech_mendwounds"
- category = SUPPORT_SPELLS
-
-/obj/item/weapon/spell/insert/mend_organs
- name = "great mend wounds"
- desc = "A walking medbay is now you!"
- icon_state = "mend_wounds"
- cast_methods = CAST_MELEE
- aspect = ASPECT_BIOMED
- light_color = "#FF5C5C"
- inserting = /obj/item/weapon/inserted_spell/mend_organs
-
-/obj/item/weapon/inserted_spell/mend_organs/on_insert()
- spawn(1)
- if(ishuman(host))
- var/mob/living/carbon/human/H = host
- var/heal_power = host == origin ? 2 : 5
- heal_power = round(heal_power * spell_power_at_creation, 1)
- origin.adjust_instability(15)
-
- for(var/i = 0, i<5,i++)
- if(H)
- for(var/obj/item/organ/O in H.internal_organs)
- if(O.damage > 0) // Fix internal damage
- O.damage = max(O.damage - (heal_power / 5), 0)
- if(O.damage <= 5 && O.organ_tag == O_EYES) // Fix eyes
- H.sdisabilities &= ~BLIND
-
- for(var/obj/item/organ/external/O in H.organs) // Fix limbs
- if(!O.robotic < ORGAN_ROBOT) // No robot parts for this.
- continue
- O.heal_damage(0, heal_power / 5, internal = 1, robo_repair = 0)
-
- for(var/obj/item/organ/E in H.bad_external_organs) // Fix bones
- var/obj/item/organ/external/affected = E
- if((affected.damage < affected.min_broken_damage * config.organ_health_multiplier) && (affected.status & ORGAN_BROKEN))
- affected.status &= ~ORGAN_BROKEN
-
- for(var/datum/wound/W in affected.wounds) // Fix IB
- if(istype(W, /datum/wound/internal_bleeding))
- affected.wounds -= W
- affected.update_damages()
-
- H.restore_blood() // Fix bloodloss
-
- H.adjustBruteLoss(-heal_power)
-
- sleep(1 SECOND)
- on_expire()
\ No newline at end of file
diff --git a/code/game/gamemodes/technomancer/spells/insert/mend_wires.dm b/code/game/gamemodes/technomancer/spells/insert/mend_wires.dm
deleted file mode 100644
index aad59dc7c4..0000000000
--- a/code/game/gamemodes/technomancer/spells/insert/mend_wires.dm
+++ /dev/null
@@ -1,33 +0,0 @@
-/datum/technomancer/spell/mend_wires
- name = "Mend Wires"
- desc = "Binds the internal wiring of robotic limbs and components over time."
- spell_power_desc = "Healing amount increased."
- cost = 50
- obj_path = /obj/item/weapon/spell/insert/mend_wires
- ability_icon_state = "tech_mendwounds"
- category = SUPPORT_SPELLS
-
-/obj/item/weapon/spell/insert/mend_wires
- name = "mend wires"
- desc = "A roboticist is now obsolete."
- icon_state = "mend_wounds"
- cast_methods = CAST_MELEE
- aspect = ASPECT_BIOMED
- light_color = "#FF5C5C"
- inserting = /obj/item/weapon/inserted_spell/mend_wires
-
-/obj/item/weapon/inserted_spell/mend_wires/on_insert()
- spawn(1)
- if(ishuman(host))
- var/mob/living/carbon/human/H = host
- var/heal_power = host == origin ? 10 : 30
- heal_power = round(heal_power * spell_power_at_creation, 1)
- origin.adjust_instability(10)
- for(var/i = 0, i<5,i++)
- if(H)
- for(var/obj/item/organ/external/O in H.organs)
- if(O.robotic < ORGAN_ROBOT) // Robot parts only.
- continue
- O.heal_damage(0, heal_power / 5, internal = 1, robo_repair = 1)
- sleep(1 SECOND)
- on_expire()
\ No newline at end of file
diff --git a/code/game/gamemodes/technomancer/spells/insert/mend_wounds.dm b/code/game/gamemodes/technomancer/spells/insert/mend_wounds.dm
deleted file mode 100644
index 38f5b5dc55..0000000000
--- a/code/game/gamemodes/technomancer/spells/insert/mend_wounds.dm
+++ /dev/null
@@ -1,31 +0,0 @@
-/datum/technomancer/spell/mend_wounds
- name = "Mend Wounds"
- desc = "Heals minor wounds, such as cuts, bruises, and other non-lifethreatening injuries. \
- Instability is split between the target and technomancer, if seperate."
- spell_power_desc = "Healing amount increased."
- cost = 50
- obj_path = /obj/item/weapon/spell/insert/mend_wounds
- ability_icon_state = "tech_mendwounds"
- category = SUPPORT_SPELLS
-
-/obj/item/weapon/spell/insert/mend_wounds
- name = "mend wounds"
- desc = "Watch your wounds close up before your eyes."
- icon_state = "mend_wounds"
- cast_methods = CAST_MELEE
- aspect = ASPECT_BIOMED
- light_color = "#FF5C5C"
- inserting = /obj/item/weapon/inserted_spell/mend_wounds
-
-/obj/item/weapon/inserted_spell/mend_wounds/on_insert()
- spawn(1)
- if(ishuman(host))
- var/mob/living/carbon/human/H = host
- var/heal_power = host == origin ? 10 : 30
- heal_power = round(heal_power * spell_power_at_creation, 1)
- origin.adjust_instability(10)
- for(var/i = 0, i<5,i++)
- if(H)
- H.adjustBruteLoss(-heal_power / 5)
- sleep(1 SECOND)
- on_expire()
diff --git a/code/game/gamemodes/technomancer/spells/insert/purify.dm b/code/game/gamemodes/technomancer/spells/insert/purify.dm
deleted file mode 100644
index 6ba36d44c6..0000000000
--- a/code/game/gamemodes/technomancer/spells/insert/purify.dm
+++ /dev/null
@@ -1,49 +0,0 @@
-/datum/technomancer/spell/purify
- name = "Purify"
- desc = "Clenses the body of harmful impurities, such as toxins, radiation, viruses, genetic damage, and such."
- spell_power_desc = "Healing amount increased."
- cost = 25
- obj_path = /obj/item/weapon/spell/insert/purify
- ability_icon_state = "tech_purify"
- category = SUPPORT_SPELLS
-
-/obj/item/weapon/spell/insert/purify
- name = "purify"
- desc = "Illness and toxins will be no more."
- icon_state = "purify"
- cast_methods = CAST_MELEE
- aspect = ASPECT_BIOMED
- light_color = "#03A728"
- inserting = /obj/item/weapon/inserted_spell/purify
-
-/obj/item/weapon/inserted_spell/purify/on_insert()
- spawn(1)
- if(ishuman(host))
- var/mob/living/carbon/human/H = host
- H.sdisabilities = 0
- H.disabilities = 0
-// for(var/datum/disease/D in H.viruses)
-// D.cure()
- var/heal_power = host == origin ? 10 : 30
- heal_power = round(heal_power * spell_power_at_creation, 1)
- origin.adjust_instability(10)
- for(var/i = 0, i<5,i++)
- if(H)
- H.adjustToxLoss(-heal_power / 5)
- H.adjustCloneLoss(-heal_power / 5)
- H.radiation = max(host.radiation - ( (heal_power * 2) / 5), 0)
-
- for(var/obj/item/organ/external/E in H.organs)
- var/obj/item/organ/external/G = E
- if(G.germ_level)
- var/germ_heal = heal_power * 10
- G.germ_level = min(0, G.germ_level - germ_heal)
-
- for(var/obj/item/organ/internal/I in H.internal_organs)
- var/obj/item/organ/internal/G = I
- if(G.germ_level)
- var/germ_heal = heal_power * 10
- G.germ_level = min(0, G.germ_level - germ_heal)
-
- sleep(1 SECOND)
- on_expire()
diff --git a/code/game/gamemodes/technomancer/spells/instability_tap.dm b/code/game/gamemodes/technomancer/spells/instability_tap.dm
index 9092039165..13a2b5e318 100644
--- a/code/game/gamemodes/technomancer/spells/instability_tap.dm
+++ b/code/game/gamemodes/technomancer/spells/instability_tap.dm
@@ -1,8 +1,8 @@
/datum/technomancer/spell/instability_tap
name = "Instability Tap"
- desc = "Creates a large sum of energy, at the cost of a very large amount of instability afflicting you."
+ desc = "Creates a large sum of energy (5,000 at normal spell power), at the cost of a very large amount of instability afflicting you."
enhancement_desc = "50% more energy gained, 20% less instability gained."
- spell_power_desc = "Amount of energy gained scaled up with spell power."
+ spell_power_desc = "Amount of energy gained scaled with spell power."
cost = 100
obj_path = /obj/item/weapon/spell/instability_tap
ability_icon_state = "tech_instabilitytap"
@@ -26,4 +26,5 @@
else
core.give_energy(amount)
adjust_instability(50)
+ playsound(get_turf(src), 'sound/effects/supermatter.ogg', 75, 1)
qdel(src)
\ No newline at end of file
diff --git a/code/game/gamemodes/technomancer/spells/mend_organs.dm b/code/game/gamemodes/technomancer/spells/mend_organs.dm
new file mode 100644
index 0000000000..16c212f084
--- /dev/null
+++ b/code/game/gamemodes/technomancer/spells/mend_organs.dm
@@ -0,0 +1,56 @@
+/datum/technomancer/spell/mend_organs
+ name = "Mend Internals"
+ desc = "Greatly heals the target's wounds, both external and internal. Restores internal organs to functioning states, even if \
+ robotic, reforms bones, patches internal bleeding, and restores missing blood."
+ spell_power_desc = "Healing amount increased."
+ cost = 100
+ obj_path = /obj/item/weapon/spell/mend_organs
+ ability_icon_state = "tech_mendwounds"
+ category = SUPPORT_SPELLS
+
+/obj/item/weapon/spell/mend_organs
+ name = "great mend wounds"
+ desc = "A walking medbay is now you!"
+ icon_state = "mend_wounds"
+ cast_methods = CAST_MELEE
+ aspect = ASPECT_BIOMED
+ light_color = "#FF5C5C"
+
+/obj/item/weapon/spell/mend_organs/on_melee_cast(atom/hit_atom, mob/living/user, def_zone)
+ if(isliving(hit_atom))
+ var/mob/living/L = hit_atom
+ var/heal_power = calculate_spell_power(40)
+ L.adjustBruteLoss(-heal_power)
+ L.adjustFireLoss(-heal_power)
+ user.adjust_instability(5)
+ L.adjust_instability(5)
+
+ if(ishuman(hit_atom))
+ var/mob/living/carbon/human/H = hit_atom
+
+ user.adjust_instability(5)
+ L.adjust_instability(5)
+
+ for(var/obj/item/organ/O in H.internal_organs)
+ if(O.damage > 0) // Fix internal damage
+ O.damage = max(O.damage - (heal_power / 2), 0)
+ if(O.damage <= 5 && O.organ_tag == O_EYES) // Fix eyes
+ H.sdisabilities &= ~BLIND
+
+ for(var/obj/item/organ/external/O in H.organs) // Fix limbs
+ if(!O.robotic < ORGAN_ROBOT) // No robot parts for this.
+ continue
+ O.heal_damage(0, heal_power / 4, internal = 1, robo_repair = 0)
+
+ for(var/obj/item/organ/E in H.bad_external_organs) // Fix bones
+ var/obj/item/organ/external/affected = E
+ if((affected.damage < affected.min_broken_damage * config.organ_health_multiplier) && (affected.status & ORGAN_BROKEN))
+ affected.status &= ~ORGAN_BROKEN
+
+ for(var/datum/wound/W in affected.wounds) // Fix IB
+ if(istype(W, /datum/wound/internal_bleeding))
+ affected.wounds -= W
+ affected.update_damages()
+
+ H.restore_blood() // Fix bloodloss
+ qdel(src)
diff --git a/code/game/gamemodes/technomancer/spells/modifier/mend_all.dm b/code/game/gamemodes/technomancer/spells/modifier/mend_all.dm
new file mode 100644
index 0000000000..1da3554573
--- /dev/null
+++ b/code/game/gamemodes/technomancer/spells/modifier/mend_all.dm
@@ -0,0 +1,35 @@
+// Gambit only spell. Heals everything unconditionally.
+
+/obj/item/weapon/spell/modifier/mend_all
+ name = "mend all"
+ desc = "One function to heal them all."
+ icon_state = "mend_all"
+ cast_methods = CAST_MELEE
+ aspect = ASPECT_BIOMED
+ light_color = "#FF5C5C"
+ modifier_type = /datum/modifier/technomancer/mend_life
+ modifier_duration = 1 MINUTE
+
+/datum/modifier/technomancer/mend_all
+ name = "mend all"
+ desc = "You feel serene and well rested."
+ mob_overlay_state = "green_sparkles"
+
+ on_created_text = "Sparkles begin to appear around you, and all your ills seem to fade away."
+ on_expired_text = "The sparkles have faded, although you feel much healthier than before."
+ stacks = MODIFIER_STACK_EXTEND
+
+/datum/modifier/technomancer/mend_all/tick()
+ if(!holder.getBruteLoss() && !holder.getFireLoss() && !holder.getToxLoss() && !holder.getOxyLoss() && !holder.getCloneLoss()) // No point existing if the spell can't heal.
+ expire()
+ return
+ holder.adjustBruteLoss(-4 * spell_power) // Should heal roughly 120 damage over 1 minute, as tick() is run every 2 seconds.
+ holder.adjustFireLoss(-4 * spell_power)
+ holder.adjustToxLoss(-4 * spell_power)
+ holder.adjustOxyLoss(-4 * spell_power)
+ holder.adjustCloneLoss(-2 * spell_power) // 60 cloneloss
+ holder.adjust_instability(1)
+ if(origin)
+ var/mob/living/L = origin.resolve()
+ if(istype(L))
+ L.adjust_instability(1)
\ No newline at end of file
diff --git a/code/game/gamemodes/technomancer/spells/modifier/mend_life.dm b/code/game/gamemodes/technomancer/spells/modifier/mend_life.dm
new file mode 100644
index 0000000000..a766767b18
--- /dev/null
+++ b/code/game/gamemodes/technomancer/spells/modifier/mend_life.dm
@@ -0,0 +1,44 @@
+/datum/technomancer/spell/mend_life
+ name = "Mend Life"
+ desc = "Heals minor wounds, such as cuts, bruises, burns, and other non-lifethreatening injuries. \
+ Instability is split between the target and technomancer, if seperate. The function will end prematurely \
+ if the target is completely healthy, preventing further instability."
+ spell_power_desc = "Healing amount increased."
+ cost = 50
+ obj_path = /obj/item/weapon/spell/modifier/mend_life
+ ability_icon_state = "tech_mendwounds"
+ category = SUPPORT_SPELLS
+
+/obj/item/weapon/spell/modifier/mend_life
+ name = "mend life"
+ desc = "Watch your wounds close up before your eyes."
+ icon_state = "mend_life"
+ cast_methods = CAST_MELEE
+ aspect = ASPECT_BIOMED
+ light_color = "#FF5C5C"
+ modifier_type = /datum/modifier/technomancer/mend_life
+ modifier_duration = 10 SECONDS
+
+/datum/modifier/technomancer/mend_life
+ name = "mend life"
+ desc = "You feel rather refreshed."
+ mob_overlay_state = "green_sparkles"
+
+ on_created_text = "Sparkles begin to appear around you, and you feel really.. refreshed."
+ on_expired_text = "The sparkles have faded, although you feel healthier than before."
+ stacks = MODIFIER_STACK_EXTEND
+
+/datum/modifier/technomancer/mend_life/tick()
+ if(holder.isSynthetic()) // Don't heal synths!
+ expire()
+ return
+ if(!holder.getBruteLoss() && !holder.getFireLoss()) // No point existing if the spell can't heal.
+ expire()
+ return
+ holder.adjustBruteLoss(-4 * spell_power) // Should heal roughly 20 burn/brute over 10 seconds, as tick() is run every 2 seconds.
+ holder.adjustFireLoss(-4 * spell_power) // Ditto.
+ holder.adjust_instability(1)
+ if(origin)
+ var/mob/living/L = origin.resolve()
+ if(istype(L))
+ L.adjust_instability(1)
\ No newline at end of file
diff --git a/code/game/gamemodes/technomancer/spells/modifier/mend_synthetic.dm b/code/game/gamemodes/technomancer/spells/modifier/mend_synthetic.dm
new file mode 100644
index 0000000000..d91530b0c9
--- /dev/null
+++ b/code/game/gamemodes/technomancer/spells/modifier/mend_synthetic.dm
@@ -0,0 +1,44 @@
+/datum/technomancer/spell/mend_synthetic
+ name = "Mend Synthetic"
+ desc = "Repairs minor damages to robotic entities. \
+ Instability is split between the target and technomancer, if seperate. The function will end prematurely \
+ if the target is completely healthy, preventing further instability."
+ spell_power_desc = "Healing amount increased."
+ cost = 50
+ obj_path = /obj/item/weapon/spell/modifier/mend_synthetic
+ ability_icon_state = "tech_mendwounds"
+ category = SUPPORT_SPELLS
+
+/obj/item/weapon/spell/modifier/mend_synthetic
+ name = "mend synthetic"
+ desc = "You are the Robotics lab"
+ icon_state = "mend_synthetic"
+ cast_methods = CAST_MELEE
+ aspect = ASPECT_BIOMED // sorta??
+ light_color = "#FF5C5C"
+ modifier_type = /datum/modifier/technomancer/mend_synthetic
+ modifier_duration = 10 SECONDS
+
+/datum/modifier/technomancer/mend_synthetic
+ name = "mend synthetic"
+ desc = "Something seems to be repairing you."
+ mob_overlay_state = "cyan_sparkles"
+
+ on_created_text = "Sparkles begin to appear around you, and your systems report integrity rising."
+ on_expired_text = "The sparkles have faded, although your systems seem to be better than before."
+ stacks = MODIFIER_STACK_EXTEND
+
+/datum/modifier/technomancer/mend_synthetic/tick()
+ if(!holder.isSynthetic()) // Don't heal biologicals!
+ expire()
+ return
+ if(!holder.getBruteLoss() && !holder.getFireLoss()) // No point existing if the spell can't heal.
+ expire()
+ return
+ holder.adjustBruteLoss(-4 * spell_power) // Should heal roughly 20 burn/brute over 10 seconds, as tick() is run every 2 seconds.
+ holder.adjustFireLoss(-4 * spell_power) // Ditto.
+ holder.adjust_instability(1)
+ if(origin)
+ var/mob/living/L = origin.resolve()
+ if(istype(L))
+ L.adjust_instability(1)
\ No newline at end of file
diff --git a/code/game/gamemodes/technomancer/spells/modifier/modifier.dm b/code/game/gamemodes/technomancer/spells/modifier/modifier.dm
index b0a5c93747..a8b9306945 100644
--- a/code/game/gamemodes/technomancer/spells/modifier/modifier.dm
+++ b/code/game/gamemodes/technomancer/spells/modifier/modifier.dm
@@ -26,6 +26,13 @@
var/duration = modifier_duration
if(duration)
duration = round(duration * calculate_spell_power(1.0), 1)
- L.add_modifier(modifier_type, duration)
+ var/datum/modifier/M = L.add_modifier(modifier_type, duration, owner)
+ if(istype(M, /datum/modifier/technomancer))
+ var/datum/modifier/technomancer/MT = M
+ MT.spell_power = calculate_spell_power(1)
log_and_message_admins("has casted [src] on [L].")
- qdel(src)
\ No newline at end of file
+ qdel(src)
+
+// Technomancer specific subtype which keeps track of spell power and gets targeted specificially by Dispel.
+/datum/modifier/technomancer
+ var/spell_power = null // Set by on_add_modifier.
\ No newline at end of file
diff --git a/code/game/gamemodes/technomancer/spells/modifier/purify.dm b/code/game/gamemodes/technomancer/spells/modifier/purify.dm
new file mode 100644
index 0000000000..ae90a04cb1
--- /dev/null
+++ b/code/game/gamemodes/technomancer/spells/modifier/purify.dm
@@ -0,0 +1,40 @@
+/datum/technomancer/spell/purify
+ name = "Purify"
+ desc = "Clenses the body of harmful impurities, such as toxins, radiation, viruses, genetic damage, and such. \
+ Instability is split between the target and technomancer, if seperate. The function will end prematurely \
+ if the target is completely healthy, preventing further instability."
+ spell_power_desc = "Healing amount increased."
+ cost = 25
+ obj_path = /obj/item/weapon/spell/modifier/purify
+ ability_icon_state = "tech_purify"
+ category = SUPPORT_SPELLS
+
+/obj/item/weapon/spell/modifier/purify
+ name = "mend life"
+ desc = "Watch your wounds close up before your eyes."
+ icon_state = "mend_life"
+ cast_methods = CAST_MELEE
+ aspect = ASPECT_BIOMED
+ light_color = "#FF5C5C"
+ modifier_type = /datum/modifier/technomancer/purify
+ modifier_duration = 10 SECONDS
+
+/datum/modifier/technomancer/purify
+ name = "purify"
+ desc = "You feel rather clean and pure."
+ mob_overlay_state = "green_sparkles"
+
+ on_created_text = "Sparkles begin to appear around you, and you feel really.. pure."
+ on_expired_text = "The sparkles have faded, although you feel healthier than before."
+ stacks = MODIFIER_STACK_EXTEND
+
+/datum/modifier/technomancer/purify/tick()
+ if(!holder.getToxLoss()) // No point existing if the spell can't heal.
+ expire()
+ return
+ holder.adjustToxLoss(-4 * spell_power) // Should heal roughly 120 damage over 1 minute, as tick() is run every 2 seconds.
+ holder.adjust_instability(1)
+ if(origin)
+ var/mob/living/L = origin.resolve()
+ if(istype(L))
+ L.adjust_instability(1)
\ No newline at end of file
diff --git a/code/game/gamemodes/technomancer/spells/modifier/repel_missiles.dm b/code/game/gamemodes/technomancer/spells/modifier/repel_missiles.dm
index d267ecce88..6ead04f30c 100644
--- a/code/game/gamemodes/technomancer/spells/modifier/repel_missiles.dm
+++ b/code/game/gamemodes/technomancer/spells/modifier/repel_missiles.dm
@@ -1,6 +1,6 @@
/datum/technomancer/spell/repel_missiles
name = "Repel Missiles"
- desc = "Places a repulsion field around you, which attempts to deflect incoming bullets and lasers, making them 30% less likely \
+ desc = "Places a repulsion field around you, which attempts to deflect incoming bullets and lasers, making them 45% less likely \
to hit you. The field lasts for 10 minutes and can be granted to yourself or an ally."
cost = 25
obj_path = /obj/item/weapon/spell/modifier/repel_missiles
diff --git a/code/game/gamemodes/technomancer/spells/oxygenate.dm b/code/game/gamemodes/technomancer/spells/oxygenate.dm
index b121e6f4d4..fcc2cbcecf 100644
--- a/code/game/gamemodes/technomancer/spells/oxygenate.dm
+++ b/code/game/gamemodes/technomancer/spells/oxygenate.dm
@@ -2,7 +2,7 @@
name = "Oxygenate"
desc = "This function creates oxygen at a location of your chosing. If used on a humanoid entity, it heals oxygen deprivation. \
If casted on the envirnment, air (oxygen and nitrogen) is moved from a distant location to your target."
- cost = 50
+ cost = 25
obj_path = /obj/item/weapon/spell/oxygenate
ability_icon_state = "oxygenate"
category = SUPPORT_SPELLS
diff --git a/code/game/gamemodes/technomancer/spells/projectile/chain_lightning.dm b/code/game/gamemodes/technomancer/spells/projectile/chain_lightning.dm
index acb00a2c7f..5614d04a88 100644
--- a/code/game/gamemodes/technomancer/spells/projectile/chain_lightning.dm
+++ b/code/game/gamemodes/technomancer/spells/projectile/chain_lightning.dm
@@ -32,7 +32,7 @@
var/bounces = 3 //How many times it 'chains'. Note that the first hit is not counted as it counts /bounces/.
var/list/hit_mobs = list() //Mobs which were already hit.
- var/power = 20 //How hard it will hit for with electrocute_act(), decreases with each bounce.
+ var/power = 35 //How hard it will hit for with electrocute_act(), decreases with each bounce.
/obj/item/projectile/beam/chain_lightning/attack_mob(var/mob/living/target_mob, var/distance, var/miss_modifier=0)
//First we shock the guy we just hit.
diff --git a/code/game/gamemodes/technomancer/spells/projectile/ionic_bolt.dm b/code/game/gamemodes/technomancer/spells/projectile/ionic_bolt.dm
index 68070d15c1..d6665b2ee0 100644
--- a/code/game/gamemodes/technomancer/spells/projectile/ionic_bolt.dm
+++ b/code/game/gamemodes/technomancer/spells/projectile/ionic_bolt.dm
@@ -2,7 +2,7 @@
name = "Ionic Bolt"
desc = "Shoots a bolt of ion energy at the target. If it hits something, it will generally drain energy, corrupt electronics, \
or otherwise ruin complex machinery."
- cost = 100
+ cost = 50
obj_path = /obj/item/weapon/spell/projectile/ionic_bolt
category = OFFENSIVE_SPELLS
diff --git a/code/game/gamemodes/technomancer/spells/projectile/lesser_chain_lightning.dm b/code/game/gamemodes/technomancer/spells/projectile/lesser_chain_lightning.dm
new file mode 100644
index 0000000000..85881fefb0
--- /dev/null
+++ b/code/game/gamemodes/technomancer/spells/projectile/lesser_chain_lightning.dm
@@ -0,0 +1,23 @@
+/datum/technomancer/spell/lesser_chain_lightning
+ name = "Lesser Chain Lightning"
+ desc = "This is very similar to the function Chain Lightning, however it is considerably less powerful. As a result, it's a lot \
+ more economical in terms of energy cost, as well as instability generation. Lightning functions cannot miss due to distance."
+ cost = 100
+ obj_path = /obj/item/weapon/spell/projectile/chain_lightning/lesser
+ ability_icon_state = "tech_chain_lightning"
+ category = OFFENSIVE_SPELLS
+
+/obj/item/weapon/spell/projectile/chain_lightning/lesser
+ name = "lesser chain lightning"
+ icon_state = "chain_lightning"
+ desc = "Now you can throw around lightning like it's nobody's business."
+ cast_methods = CAST_RANGED
+ aspect = ASPECT_SHOCK
+ spell_projectile = /obj/item/projectile/beam/chain_lightning
+ energy_cost_per_shot = 1000
+ instability_per_shot = 5
+ cooldown = 10
+
+/obj/item/projectile/beam/chain_lightning/lesser
+ bounces = 2
+ power = 20
\ No newline at end of file
diff --git a/code/game/gamemodes/technomancer/spells/shield.dm b/code/game/gamemodes/technomancer/spells/shield.dm
index a9514aaa29..1569b005c0 100644
--- a/code/game/gamemodes/technomancer/spells/shield.dm
+++ b/code/game/gamemodes/technomancer/spells/shield.dm
@@ -37,8 +37,10 @@
if(issmall(user)) // Smaller shields are more efficent.
damage_to_energy_cost *= 0.75
- if(istype(owner.get_other_hand(src), src.type)) // Two shields in both hands.
- damage_to_energy_cost *= 0.75
+ if(ishuman(owner))
+ var/mob/living/carbon/human/H = owner
+ if(istype(H.get_other_hand(src), src.type)) // Two shields in both hands.
+ damage_to_energy_cost *= 0.75
else if(check_for_scepter())
damage_to_energy_cost *= 0.50
diff --git a/code/game/gamemodes/technomancer/spells/spawner/destablize.dm b/code/game/gamemodes/technomancer/spells/spawner/destablize.dm
new file mode 100644
index 0000000000..38172b0d14
--- /dev/null
+++ b/code/game/gamemodes/technomancer/spells/spawner/destablize.dm
@@ -0,0 +1,53 @@
+/datum/technomancer/spell/destablize
+ name = "Destablize"
+ desc = "Creates an unstable disturbance at the targeted tile, which will afflict anyone nearby with instability who remains nearby. This can affect you \
+ and your allies as well. The disturbance lasts for twenty seconds."
+ cost = 100
+ obj_path = /obj/item/weapon/spell/spawner/destablize
+ category = OFFENSIVE_SPELLS
+
+/obj/item/weapon/spell/spawner/destablize
+ name = "destablize"
+ desc = "Now your enemies can feel what you go through when you have too much fun."
+ icon_state = "destablize"
+ cast_methods = CAST_RANGED
+ aspect = ASPECT_UNSTABLE
+ spawner_type = /obj/effect/temporary_effect/destablize
+
+/obj/item/weapon/spell/spawner/destablize/New()
+ ..()
+ set_light(3, 2, l_color = "#C26DDE")
+
+/obj/item/weapon/spell/spawner/destablize/on_ranged_cast(atom/hit_atom, mob/user)
+ if(within_range(hit_atom) && pay_energy(2000))
+ adjust_instability(15)
+ ..()
+
+/obj/effect/temporary_effect/destablize
+ name = "destablizing disturbance"
+ desc = "This can't be good..."
+ icon = 'icons/effects/effects.dmi'
+ icon_state = "blueshatter"
+ time_to_die = null
+ invisibility = 0
+ new_light_range = 6
+ new_light_power = 20
+ new_light_color = "#C26DDE"
+ var/pulses_remaining = 40 // Lasts 20 seconds.
+ var/instability_power = 5
+ var/instability_range = 6
+
+/obj/effect/temporary_effect/destablize/New()
+ ..()
+ radiate_loop()
+
+/obj/effect/temporary_effect/destablize/proc/radiate_loop()
+ while(pulses_remaining)
+ sleep(5)
+ for(var/mob/living/L in range(src, instability_range) )
+ var/radius = max(get_dist(L, src), 1)
+ // Being farther away lessens the amount of instabity received.
+ var/outgoing_instability = instability_power * ( 1 / (radius**2) )
+ L.receive_radiated_instability(outgoing_instability)
+ pulses_remaining--
+ qdel(src)
\ No newline at end of file
diff --git a/code/modules/mob/modifiers.dm b/code/modules/mob/modifiers.dm
index 8e1f9e2f6f..f67ffc374b 100644
--- a/code/modules/mob/modifiers.dm
+++ b/code/modules/mob/modifiers.dm
@@ -7,6 +7,7 @@
var/desc = null // Ditto.
var/icon_state = null // See above.
var/mob/living/holder = null // The mob that this datum is affecting.
+ var/weakref/origin = null // A weak reference to whatever caused the modifier to appear. THIS NEEDS TO BE A MOB/LIVING. It's a weakref to not interfere with qdel().
var/expire_at = null // world.time when holder's Life() will remove the datum. If null, it lasts forever or until it gets deleted by something else.
var/on_created_text = null // Text to show to holder upon being created.
var/on_expired_text = null // Text to show to holder when it expires.
@@ -37,8 +38,12 @@
var/haste // If set to 1, the mob will be 'hasted', which makes it ignore slowdown and go really fast.
var/evasion // Positive numbers reduce the odds of being hit by 15% each. Negative numbers increase the odds.
-/datum/modifier/New(var/new_holder)
+/datum/modifier/New(var/new_holder, var/new_origin)
holder = new_holder
+ if(new_origin)
+ origin = weakref(new_origin)
+ else // We assume the holder caused the modifier if not told otherwise.
+ origin = weakref(holder)
..()
// Checks to see if this datum should continue existing.
@@ -82,8 +87,9 @@
M.tick()
// Call this to add a modifier to a mob. First argument is the modifier type you want, second is how long it should last, in ticks.
+// Third argument is the 'source' of the modifier, if it's from someone else. If null, it will default to the mob being applied to.
// The SECONDS/MINUTES macro is very helpful for this. E.g. M.add_modifier(/datum/modifier/example, 5 MINUTES)
-/mob/living/proc/add_modifier(var/modifier_type, var/expire_at = null)
+/mob/living/proc/add_modifier(var/modifier_type, var/expire_at = null, var/mob/living/origin = null)
// First, check if the mob already has this modifier.
for(var/datum/modifier/M in modifiers)
if(istype(modifier_type, M))
@@ -99,7 +105,7 @@
return
// If we're at this point, the mob doesn't already have it, or it does but stacking is allowed.
- var/datum/modifier/mod = new modifier_type(src)
+ var/datum/modifier/mod = new modifier_type(src, origin)
if(expire_at)
mod.expire_at = world.time + expire_at
if(mod.on_created_text)
@@ -108,6 +114,8 @@
if(mod.mob_overlay_state)
update_modifier_visuals()
+ return mod
+
// Removes a specific instance of modifier
/mob/living/proc/remove_specific_modifier(var/datum/modifier/M, var/silent = FALSE)
M.expire(silent)
diff --git a/icons/mob/mob.dmi b/icons/mob/mob.dmi
index c20a2cbc0f..94028db1fa 100644
Binary files a/icons/mob/mob.dmi and b/icons/mob/mob.dmi differ
diff --git a/icons/mob/modifier_effects.dmi b/icons/mob/modifier_effects.dmi
index ecb575c673..e0fe0b1697 100644
Binary files a/icons/mob/modifier_effects.dmi and b/icons/mob/modifier_effects.dmi differ
diff --git a/icons/obj/spells.dmi b/icons/obj/spells.dmi
index 7c040983c1..01ced38851 100644
Binary files a/icons/obj/spells.dmi and b/icons/obj/spells.dmi differ
diff --git a/polaris.dme b/polaris.dme
index 23fc2fc0c4..19187683a4 100644
--- a/polaris.dme
+++ b/polaris.dme
@@ -454,6 +454,7 @@
#include "code\game\gamemodes\technomancer\spells\illusion.dm"
#include "code\game\gamemodes\technomancer\spells\instability_tap.dm"
#include "code\game\gamemodes\technomancer\spells\mark_recall.dm"
+#include "code\game\gamemodes\technomancer\spells\mend_organs.dm"
#include "code\game\gamemodes\technomancer\spells\oxygenate.dm"
#include "code\game\gamemodes\technomancer\spells\passwall.dm"
#include "code\game\gamemodes\technomancer\spells\phase_shift.dm"
@@ -471,24 +472,24 @@
#include "code\game\gamemodes\technomancer\spells\aura\frost_aura.dm"
#include "code\game\gamemodes\technomancer\spells\aura\shock_aura.dm"
#include "code\game\gamemodes\technomancer\spells\aura\unstable_aura.dm"
-#include "code\game\gamemodes\technomancer\spells\insert\insert.dm"
-#include "code\game\gamemodes\technomancer\spells\insert\mend_burns.dm"
-#include "code\game\gamemodes\technomancer\spells\insert\mend_metal.dm"
-#include "code\game\gamemodes\technomancer\spells\insert\mend_organs.dm"
-#include "code\game\gamemodes\technomancer\spells\insert\mend_wires.dm"
-#include "code\game\gamemodes\technomancer\spells\insert\mend_wounds.dm"
-#include "code\game\gamemodes\technomancer\spells\insert\purify.dm"
#include "code\game\gamemodes\technomancer\spells\modifier\corona.dm"
#include "code\game\gamemodes\technomancer\spells\modifier\haste.dm"
+#include "code\game\gamemodes\technomancer\spells\modifier\mend_all.dm"
+#include "code\game\gamemodes\technomancer\spells\modifier\mend_life.dm"
+#include "code\game\gamemodes\technomancer\spells\modifier\mend_synthetic.dm"
#include "code\game\gamemodes\technomancer\spells\modifier\modifier.dm"
+#include "code\game\gamemodes\technomancer\spells\modifier\purify.dm"
#include "code\game\gamemodes\technomancer\spells\modifier\repel_missiles.dm"
#include "code\game\gamemodes\technomancer\spells\projectile\beam.dm"
#include "code\game\gamemodes\technomancer\spells\projectile\chain_lightning.dm"
#include "code\game\gamemodes\technomancer\spells\projectile\force_missile.dm"
+#include "code\game\gamemodes\technomancer\spells\projectile\ionic_bolt.dm"
+#include "code\game\gamemodes\technomancer\spells\projectile\lesser_chain_lightning.dm"
#include "code\game\gamemodes\technomancer\spells\projectile\lightning.dm"
#include "code\game\gamemodes\technomancer\spells\projectile\overload.dm"
#include "code\game\gamemodes\technomancer\spells\projectile\projectile.dm"
#include "code\game\gamemodes\technomancer\spells\spawner\darkness.dm"
+#include "code\game\gamemodes\technomancer\spells\spawner\destablize.dm"
#include "code\game\gamemodes\technomancer\spells\spawner\fire_blast.dm"
#include "code\game\gamemodes\technomancer\spells\spawner\pulsar.dm"
#include "code\game\gamemodes\technomancer\spells\spawner\spawner.dm"