diff --git a/code/game/gamemodes/technomancer/assistance/assistance.dm b/code/game/gamemodes/technomancer/assistance/assistance.dm
index d46a0d001e..12da7d6c13 100644
--- a/code/game/gamemodes/technomancer/assistance/assistance.dm
+++ b/code/game/gamemodes/technomancer/assistance/assistance.dm
@@ -1,7 +1,7 @@
-/datum/technomancer_equipment/assistance/
+/datum/technomancer/assistance
var/one_use_only = 0
-/datum/technomancer_equipment/assistance/apprentice
+/datum/technomancer/assistance/apprentice
name = "Friendly Apprentice"
desc = "A one-time use teleporter that sends a less powerful manipulator of space to you, who will do their best to protect \
and serve you. They get their own catalog and can buy spells for themselves, however they have a smaller pool to buy with. \
@@ -10,7 +10,7 @@
cost = 300
obj_path = null //TODO
-/datum/technomancer_equipment/assistance/golem
+/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 \
@@ -19,7 +19,7 @@
obj_path = null //TODO
one_use_only = 1
-/datum/technomancer_equipment/assistance/ninja
+/datum/technomancer/assistance/ninja
name = "Neutral Cyberassassin"
desc = "Someone almost as enigmatic as you will also arrive at your destination, with their own goals and motivations. \
This could prove to be a problem if they decide to go against you, so this is only recommended as a challenge."
diff --git a/code/game/gamemodes/technomancer/assistance/golem.dm b/code/game/gamemodes/technomancer/assistance/golem.dm
index eb90636a47..8bb6ef2ea0 100644
--- a/code/game/gamemodes/technomancer/assistance/golem.dm
+++ b/code/game/gamemodes/technomancer/assistance/golem.dm
@@ -2,6 +2,8 @@
/mob/living/simple_animal/hostile/technomancer_golem
name = "G.O.L.E.M."
desc = "A rather unusual looking synthetic."
+ icon = 'icons/mob/robots.dmi'
+ icon_state = "Security"
health = 250
maxHealth = 250
stop_automated_movement = 1
@@ -34,27 +36,37 @@
var/obj/item/weapon/technomancer_core/core = null
var/obj/item/weapon/spell/active_spell = null
- var/mob/living/owner = null
+ var/mob/living/master = null
-/mob/living/simple_animal/technomancer_golem/New()
+/mob/living/simple_animal/hostile/technomancer_golem/New()
..()
core = new core(src)
-/mob/living/simple_animal/technomancer_golem/Destroy()
+/mob/living/simple_animal/hostile/technomancer_golem/Destroy()
qdel(core)
..()
-/mob/living/simple_animal/technomancer_golem/proc/bind_to_mob(mob/user)
- if(!user || owner)
+/mob/living/simple_animal/hostile/technomancer_golem/proc/bind_to_mob(mob/user)
+ if(!user || master)
return
- owner = user
- name = "[owner]'s [initial(name)]"
+ master = user
+ name = "[master]'s [initial(name)]"
-/mob/living/simple_animal/technomancer_golem/examine(mob/user)
+/mob/living/simple_animal/hostile/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/technomancer_golem/Life()
+/mob/living/simple_animal/hostile/technomancer_golem/Life()
+ handle_ai()
+
+/mob/living/simple_animal/hostile/technomancer_golem/proc/handle_ai()
+ if(!master)
+ return
+ if(get_dist(src, master) > 6 || src.z != master.z)
+ recall_to_master()
+
+
+/mob/living/simple_animal/hostile/technomancer_golem/proc/recall_to_master()
return
\ No newline at end of file
diff --git a/code/game/gamemodes/technomancer/catalog.dm b/code/game/gamemodes/technomancer/catalog.dm
index 3517929f2f..3abd65080f 100644
--- a/code/game/gamemodes/technomancer/catalog.dm
+++ b/code/game/gamemodes/technomancer/catalog.dm
@@ -1,14 +1,15 @@
-var/list/all_technomancer_spells = typesof(/datum/power/technomancer) - /datum/power/technomancer
-var/list/all_technomancer_equipment = typesof(/datum/technomancer_equipment/equipment) - /datum/technomancer_equipment/equipment
-var/list/all_technomancer_consumables = typesof(/datum/technomancer_equipment/consumable) - /datum/technomancer_equipment/consumable
-var/list/all_technomancer_assistance = typesof(/datum/technomancer_equipment/assistance) - /datum/technomancer_equipment/assistance
-var/list/all_technomancer_presets = typesof(/datum/technomancer_equipment/presets) - /datum/technomancer_equipment/presets
+var/list/all_technomancer_spells = typesof(/datum/technomancer/spell) - /datum/technomancer/spell
+var/list/all_technomancer_equipment = typesof(/datum/technomancer/equipment) - /datum/technomancer/equipment
+var/list/all_technomancer_consumables = typesof(/datum/technomancer/consumable) - /datum/technomancer/consumable
+var/list/all_technomancer_assistance = typesof(/datum/technomancer/assistance) - /datum/technomancer/assistance
+var/list/all_technomancer_presets = typesof(/datum/technomancer/presets) - /datum/technomancer/presets
-/datum/power/technomancer/
- name = "technomancer function"
- desc = "If you can see this, something broke."
+/datum/technomancer
+ var/name = "technomancer thing"
+ var/desc = "If you can see this, something broke."
var/cost = 100
var/hidden = 0
+ var/obj_path = null
/obj/item/weapon/technomancer_catalog
name = "catalog"
@@ -81,7 +82,8 @@ var/list/all_technomancer_presets = typesof(/datum/technomancer_equipment/preset
dat += "Assistance | "
dat += "Presets
"
dat += "You currently have a budget of [budget]/[max_budget].
"
- for(var/datum/power/technomancer/spell in spell_instances)
+ dat += "Refund Functions
"
+ for(var/datum/technomancer/spell in spell_instances)
if(spell.hidden)
continue
dat += "[spell.name]
"
@@ -90,7 +92,6 @@ var/list/all_technomancer_presets = typesof(/datum/technomancer_equipment/preset
dat += "Purchase ([spell.cost])
"
else
dat += "Cannot afford!
"
- dat += "Refund Functions"
user << browse(dat, "window=radio")
onclose(user, "radio")
if(1) //Equipment
@@ -102,7 +103,7 @@ var/list/all_technomancer_presets = typesof(/datum/technomancer_equipment/preset
dat += "Assistance | "
dat += "Presets
"
dat += "You currently have a budget of [budget]/[max_budget].
"
- for(var/datum/technomancer_equipment/equipment/E in equipment_instances)
+ for(var/datum/technomancer/equipment/E in equipment_instances)
dat += "[E.name]
"
dat += "[E.desc]
"
if(E.cost <= budget)
@@ -120,7 +121,7 @@ var/list/all_technomancer_presets = typesof(/datum/technomancer_equipment/preset
dat += "Assistance | "
dat += "Presets
"
dat += "You currently have a budget of [budget]/[max_budget].
"
- for(var/datum/technomancer_equipment/consumable/C in consumable_instances)
+ for(var/datum/technomancer/consumable/C in consumable_instances)
dat += "[C.name]
"
dat += "[C.desc]
"
if(C.cost <= budget)
@@ -138,7 +139,7 @@ var/list/all_technomancer_presets = typesof(/datum/technomancer_equipment/preset
dat += "Assistance | "
dat += "Presets
"
dat += "You currently have a budget of [budget]/[max_budget].
"
- for(var/datum/technomancer_equipment/assistance/A in assistance_instances)
+ for(var/datum/technomancer/assistance/A in assistance_instances)
dat += "[A.name]
"
dat += "[A.desc]
"
if(A.cost <= budget)
@@ -156,7 +157,7 @@ var/list/all_technomancer_presets = typesof(/datum/technomancer_equipment/preset
dat += "Assistance | "
dat += "Presets
"
dat += "You currently have a budget of [budget]/[max_budget].
"
- for(var/datum/technomancer_equipment/presets/P in preset_instances)
+ for(var/datum/technomancer/presets/P in preset_instances)
dat += "[P.name]
"
dat += "[P.desc]
"
if(P.cost <= budget)
@@ -184,17 +185,41 @@ var/list/all_technomancer_presets = typesof(/datum/technomancer_equipment/preset
if(href_list["tab_choice"])
tab = text2num(href_list["tab_choice"])
if(href_list["spell_choice"])
- var/datum/power/technomancer/new_spell = null
+ var/datum/technomancer/new_spell = null
//Locate the spell.
- for(var/datum/power/technomancer/spell in spell_instances)
+ for(var/datum/technomancer/spell/spell in spell_instances)
if(spell.name == href_list["spell_choice"])
new_spell = spell
break
- if(new_spell)
+
+ var/obj/item/weapon/technomancer_core/core = null
+ if(istype(H.back, /obj/item/weapon/technomancer_core))
+ core = H.back
+
+ if(new_spell && core)
if(new_spell.cost <= budget)
- budget -= new_spell.cost
- H << "You have just bought [new_spell.name]."
- else
+ if(!core.has_spell(new_spell))
+ budget -= new_spell.cost
+ H << "You have just bought [new_spell.name]."
+ core.add_spell(new_spell.obj_path, new_spell.name)
+ else //We already own it.
+ H << "You already have [new_spell.name]!"
+ return
+ else //Can't afford.
H << "You can't afford that!"
return
+
+ if(href_list["refund_functions"])
+ if(H.z != 2)
+ H << "You can only refund at your base, it's too late now!"
+ return
+ var/obj/item/weapon/technomancer_core/core = null
+ if(istype(H.back, /obj/item/weapon/technomancer_core))
+ core = H.back
+ for(var/obj/spellbutton/spell in core.spells)
+ for(var/datum/technomancer/spell/spell_datum in spell_instances)
+ if(spell_datum.obj_path == spell.spellpath && !spell.was_bought_by_preset)
+ budget += spell_datum.cost
+ core.remove_spell(spell)
+ break
attack_self(H)
\ 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 bb2400cb0b..2cce8fd41b 100644
--- a/code/game/gamemodes/technomancer/core_obj.dm
+++ b/code/game/gamemodes/technomancer/core_obj.dm
@@ -16,6 +16,7 @@
var/max_energy = 10000
var/regen_rate = 50 //200 seconds to full
var/mob/living/wearer = null
+ var/list/spells = list()
/obj/item/weapon/technomancer_core/New()
..()
@@ -39,6 +40,10 @@
return 1
return 0
+/obj/item/weapon/technomancer_core/proc/give_energy(amount)
+ energy = max(energy + amount, max_energy)
+ return 1
+
/obj/item/weapon/technomancer_core/process()
regenerate()
@@ -48,6 +53,66 @@
var/mob/living/carbon/human/H = wearer
H.wiz_energy_update_hud()
+/obj/spellbutton
+ name = "generic spellbutton"
+ var/spellpath = null
+ var/was_bought_by_preset = 0
+
+/obj/spellbutton/New(loc, var/path, var/new_name)
+ if(!path || !ispath(path))
+ message_admins("ERROR: /obj/spellbutton/New() was not given a proper path!")
+ qdel(src)
+ src.name = new_name
+ src.spellpath = path
+ src.loc = loc
+
+/obj/spellbutton/Click()
+ if(ishuman(usr))
+ var/mob/living/carbon/human/H = usr
+ H.place_spell_in_hand(spellpath)
+
+/obj/spellbutton/DblClick()
+ return Click()
+
+/mob/living/carbon/human/Stat()
+ . = ..()
+
+ if(. && istype(back,/obj/item/weapon/technomancer_core))
+ var/obj/item/weapon/technomancer_core/core = back
+ setup_technomancer_stat(core)
+
+/mob/living/carbon/human/proc/setup_technomancer_stat(var/obj/item/weapon/technomancer_core/core)
+ if(core && statpanel("Spell Core"))
+ var/charge_status = "[core.energy]/[core.max_energy] ([round( (core.energy / core.max_energy) * 100)]%)"
+ var/instability_status = "[src.instability]"
+ stat("Core charge", charge_status)
+ stat("User instability", instability_status)
+ for(var/obj/spellbutton/button in core.spells)
+ stat(button)
+
+/obj/item/weapon/technomancer_core/proc/add_spell(var/path, var/new_name)
+ if(!path || !ispath(path))
+ message_admins("/obj/item/weapon/technomancer_core/add_spell() was not given a proper path! The path supplied was [path].")
+ return
+ var/obj/spellbutton/spell = new(src, path, new_name)
+ spells.Add(spell)
+
+/obj/item/weapon/technomancer_core/proc/remove_spell(var/obj/spellbutton/spell_to_remove)
+ if(spell_to_remove in spells)
+ spells.Remove(spell_to_remove)
+ qdel(spell_to_remove)
+
+/obj/item/weapon/technomancer_core/proc/remove_all_spells()
+ for(var/obj/spellbutton/spell in spells)
+ spells.Remove(spell)
+ qdel(spell)
+
+/obj/item/weapon/technomancer_core/proc/has_spell(var/datum/technomancer/spell_to_check)
+ for(var/obj/spellbutton/spell in spells)
+ if(spell.spellpath == spell_to_check.obj_path)
+ return 1
+ return 0
+
/mob
var/obj/screen/wizard/energy/wiz_energy_display = null //Unfortunately, this needs to be a mob var due to HUD code.
@@ -88,7 +153,7 @@
if(loc && ishuman(loc))
var/mob/living/carbon/human/H = loc
instability_bonus = H.instability * 1.5
- energy += min(energy + regen_rate + instability_bonus, max_energy)
+ energy = min(energy + regen_rate + instability_bonus, max_energy)
if(loc && ishuman(loc))
var/mob/living/carbon/human/H = loc
H.wiz_energy_update_hud()
diff --git a/code/game/gamemodes/technomancer/devices/disposable_teleporter.dm b/code/game/gamemodes/technomancer/devices/disposable_teleporter.dm
index aeb7a6b93b..063e642c42 100644
--- a/code/game/gamemodes/technomancer/devices/disposable_teleporter.dm
+++ b/code/game/gamemodes/technomancer/devices/disposable_teleporter.dm
@@ -1,4 +1,4 @@
-/datum/technomancer_equipment/consumable/disposable_teleporter
+/datum/technomancer/consumable/disposable_teleporter
name = "Disposable Teleporter"
desc = "An ultra-safe teleportation device that can directly teleport you to a number of locations at minimal risk, however \
it has a limited amount of charges."
diff --git a/code/game/gamemodes/technomancer/equipment.dm b/code/game/gamemodes/technomancer/equipment.dm
index 6ada16d6c7..8c988f1acb 100644
--- a/code/game/gamemodes/technomancer/equipment.dm
+++ b/code/game/gamemodes/technomancer/equipment.dm
@@ -1,11 +1,11 @@
-/datum/technomancer_equipment/equipment/classic_core
+/datum/technomancer.equipment/classic_core
name = "Classic Core"
desc = "A core cleverly disguised as an ordinary cloth cape, perfect for those wanting to make others think they are a \
real magician. This version has the same performance as the default core."
cost = 100
obj_path = /obj/item/weapon/technomancer_core/classic
-/datum/technomancer_equipment/equipment/default_core
+/datum/technomancer/equipment/default_core
name = "Manipulation Core"
desc = "The default core that you most likely already have. This is here in-case you change your mind after buying \
another core, don't forget to refund the old core. This has a capacity of 10,000 units of energy, and recharges at a \
@@ -13,14 +13,14 @@
cost = 100
obj_path = /obj/item/weapon/technomancer_core
-/datum/technomancer_equipment/equipment/rapid_core
+/datum/technomancer/equipment/rapid_core
name = "Rapid Core"
desc = "A core optimized for passive regeneration, however at the cost of capacity. Has a capacity of 7,000 units of energy, and \
recharges at a rate of 70 units."
cost = 150
obj_path = /obj/item/weapon/technomancer_core/rapid
-/datum/technomancer_equipment/equipment/bulky_core
+/datum/technomancer/equipment/bulky_core
name = "Bulky Core"
desc = "This core has very large capacitors, however it also has a subpar fractal reactor. The user is recommended to \
purchase one or more energy-generating Functions as well if using this core. Has a capacity of 20,000 units of energy, \
@@ -28,7 +28,7 @@
cost = 150
obj_path = /obj/item/weapon/technomancer_core/bulky
-/datum/technomancer_equipment/equipment/unstable
+/datum/technomancer/equipment/unstable
name = "Unstable Core"
desc = "This core feeds off unstable energies around the user in addition to a fractal reactor. This means that it performs \
better as the user has more instability, which could prove dangerous to the inexperienced or unprepared. Has a capacity of 13,000 \
@@ -37,7 +37,7 @@
cost = 150
obj_path = /obj/item/weapon/technomancer_core/unstable
-/datum/technomancer_equipment/equipment/hypo_belt
+/datum/technomancer/equipment/hypo_belt
name = "Hypo Belt"
desc = "A medical belt designed to carry autoinjectors and other medical equipment. Comes with one of each hypo."
cost = 100
@@ -58,7 +58,7 @@
new /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/combat(src)
..()
-/datum/technomancer_equipment/equipment/thermals
+/datum/technomancer/equipment/thermals
name = "Thermoncle"
desc = "A fancy monocle with a thermal optics lens installed. Allows you to see people across walls."
cost = 150
diff --git a/code/game/gamemodes/technomancer/presets.dm b/code/game/gamemodes/technomancer/presets.dm
index 9bc29e141d..1752490cb5 100644
--- a/code/game/gamemodes/technomancer/presets.dm
+++ b/code/game/gamemodes/technomancer/presets.dm
@@ -1,10 +1,10 @@
-/datum/technomancer_equipment/presets
+/datum/technomancer/presets
name = "Preset Template"
desc = "If you see me, I'm broken."
obj_path = null
var/list/bundled = list()
-/datum/technomancer_equipment/presets/summoner
+/datum/technomancer/presets/summoner
name = "Summoner"
desc = "This preset includes a few functions to teleport creatures to you, if you can't find any when you leave, as well as \
the Control function, to command said creatures. It also includes Aspect Aura and Mend Wounds to allow for an area of effect \
@@ -12,14 +12,21 @@
over your creatures."
cost = 600
-/datum/technomancer_equipment/presets/healer
+/datum/technomancer/presets/healer
name = "Healer"
desc = "This preset is recommended for apprentices who wish to support their master. It contains many healing and support \
functions, such as Mend Wounds, Mend Burns, Purify, Oxygenate, Aspect Aura, Shared Burden, Link, Resurrect, and Great Mend Wounds. \
Be aware that a lot of these functions create a lot of instability, so prepare for that if you can."
cost = 600
-/datum/technomancer_equipment/presets/rainbow
+/datum/technomancer/presets/support
+ name = "Support"
+ desc = "This preset is recommended for apprentices who wish to support their master. It contains many functions focused on \
+ augmenting you and your master's survival and capabilities, with functions such as Repel Missiles, Aspect Aura, Shared Burden, \
+ ."
+ cost = 600
+
+/datum/technomancer/presets/rainbow
name = "Rainbow Mage"
desc = "This preset includes many Aspect functions, such as Aspect Aura, Aspect Bolt, Aspect Cloud, Aspect Weapon, etc, as well as \
cheap functions beloning to each aspect, for the purposes of combining with an aspect function. This allows you to be \
diff --git a/code/game/gamemodes/technomancer/spell_objs.dm b/code/game/gamemodes/technomancer/spell_objs.dm
index f985f66e11..a7f8125d75 100644
--- a/code/game/gamemodes/technomancer/spell_objs.dm
+++ b/code/game/gamemodes/technomancer/spell_objs.dm
@@ -20,7 +20,6 @@
#define ASPECT_UNSTABLE "unstable" //Heavily RNG-based, causes instability to the victim.
#define ASPECT_CHROMATIC "chromatic" //Used to combine with other spells.
-
/obj/item/weapon/spell
name = "glowing particles"
desc = "Your hands appear to be glowing brightly."
@@ -38,6 +37,7 @@
var/cast_methods = null
var/aspect = null
var/toggled = 0 //Mainly used for overlays
+ var/cooldown = 0 //If set, will add a cooldown overlay and adjust click delay. Must be a multiple of 5 for overlays.
/obj/item/weapon/spell/proc/on_use_cast(mob/user)
return
@@ -54,6 +54,9 @@
/obj/item/weapon/spell/proc/on_combine_cast(obj/item/W, mob/user)
return
+/obj/item/weapon/spell/proc/on_innate_cast(mob/user)
+ return
+
//TODO
/obj/item/weapon/spell/proc/pay_energy(var/amount)
if(!core)
@@ -146,162 +149,37 @@
else if(cast_methods & CAST_RANGED) //Try to use a ranged method if a melee one doesn't exist.
on_ranged_cast(target, user)
world << "range cast called"
+ if(cooldown)
+ user.setClickCooldown(cooldown)
+ flick("cooldown_[cooldown]",src)
-/obj/spellbutton
- name = "generic spellbutton"
- var/spellpath = null
+/mob/living/proc/place_spell_in_hand(var/path)
+ return
-//debug test verbs, kill Neerti if this makes it live.
-/mob/verb/apportation()
- set category = "Functions"
- set name = "Apportation()"
- set src = usr
- if(!ishuman(src))
- return 0
-
- var/mob/living/carbon/human/H = src
-
- H.place_spell_in_hand(/obj/item/weapon/spell/apportation)
-
-/mob/verb/blink()
- set category = "Functions"
- set name = "Blink()"
- set src = usr
- if(!ishuman(src))
- return 0
-
- var/mob/living/carbon/human/H = src
-
- H.place_spell_in_hand(/obj/item/weapon/spell/blink)
-
-/mob/verb/darkness()
- set category = "Functions"
- set name = "Darkness()"
- set src = usr
- if(!ishuman(src))
- return 0
-
- var/mob/living/carbon/human/H = src
-
- H.place_spell_in_hand(/obj/item/weapon/spell/darkness)
-
-/mob/verb/radiance()
- set category = "Functions"
- set name = "Radiance()"
- set src = usr
- if(!ishuman(src))
- return 0
-
- var/mob/living/carbon/human/H = src
-
- H.place_spell_in_hand(/obj/item/weapon/spell/radiance)
-
-/mob/verb/purify()
- set category = "Functions"
- set name = "Purify()"
- set src = usr
- if(!ishuman(src))
- return 0
-
- var/mob/living/carbon/human/H = src
-
- H.place_spell_in_hand(/obj/item/weapon/spell/insert/purify)
-
-/mob/verb/disable_technology()
- set category = "Functions"
- set name = "Disable_Technology()"
- set src = usr
- if(!ishuman(src))
- return 0
-
- var/mob/living/carbon/human/H = src
-
- H.place_spell_in_hand(/obj/item/weapon/spell/pulsar)
-
-/mob/verb/passwall()
- set category = "Functions"
- set name = "Passwall()"
- set src = usr
- if(!ishuman(src))
- return 0
-
- var/mob/living/carbon/human/H = src
-
- H.place_spell_in_hand(/obj/item/weapon/spell/passwall)
-
-/mob/verb/phase_shift()
- set category = "Functions"
- set name = "Phase_Shift()"
- set src = usr
- if(!ishuman(src))
- return 0
-
- var/mob/living/carbon/human/H = src
-
- H.place_spell_in_hand(/obj/item/weapon/spell/phase_shift)
-
-/mob/verb/warp_strike()
- set category = "Functions"
- set name = "Warp_Strike()"
- set src = usr
- if(!ishuman(src))
- return 0
-
- var/mob/living/carbon/human/H = src
-
- H.place_spell_in_hand(/obj/item/weapon/spell/warp_strike)
-
-/mob/verb/discharge()
- set category = "Functions"
- set name = "Discharge()"
- set src = usr
- if(!ishuman(src))
- return 0
-
- var/mob/living/carbon/human/H = src
-
- H.place_spell_in_hand(/obj/item/weapon/spell/discharge)
-
-/mob/verb/aspect_aura()
- set category = "Functions"
- set name = "Aspect Aura()"
- set src = usr
- if(!ishuman(src))
- return 0
-
- var/mob/living/carbon/human/H = src
-
- H.place_spell_in_hand(/obj/item/weapon/spell/aspect_aura)
-
-/mob/verb/control()
- set category = "Functions"
- set name = "Control()"
- set src = usr
- if(!ishuman(src))
- return 0
-
- var/mob/living/carbon/human/H = src
-
- H.place_spell_in_hand(/obj/item/weapon/spell/control)
-
-/mob/living/carbon/human/proc/place_spell_in_hand(var/path)
+/mob/living/carbon/human/place_spell_in_hand(var/path)
if(!path || !ispath(path))
return 0
+
+ var/obj/item/weapon/spell/S = PoolOrNew(path, src)
+
+ //No hands needed for innate casts.
+ if(S.cast_methods & CAST_INNATE)
+ if(S.run_checks())
+ S.on_innate_cast(src)
+
if(l_hand && r_hand) //Make sure our hands aren't full.
if(istype(r_hand, /obj/item/weapon/spell)) //If they are full, perhaps we can still be useful.
var/obj/item/weapon/spell/r_spell = r_hand
if(r_spell.aspect == ASPECT_CHROMATIC) //Check if we can combine the new spell with one in our hands.
- var/obj/item/weapon/spell/S = PoolOrNew(path, src)
r_spell.on_combine_cast(S, src)
else if(istype(l_hand, /obj/item/weapon/spell))
var/obj/item/weapon/spell/l_spell = l_hand
if(l_spell.aspect == ASPECT_CHROMATIC) //Check the other hand too.
- var/obj/item/weapon/spell/S = PoolOrNew(path, src)
l_spell.on_combine_cast(S, src)
else //Welp
src << "You require a free hand to use this function."
return 0
- var/obj/item/weapon/spell/S = PoolOrNew(path, src)
+
if(S.run_checks())
put_in_hands(S)
return 1
diff --git a/code/game/gamemodes/technomancer/spells/apportation.dm b/code/game/gamemodes/technomancer/spells/apportation.dm
index 1c7d1da230..e4aaf1c969 100644
--- a/code/game/gamemodes/technomancer/spells/apportation.dm
+++ b/code/game/gamemodes/technomancer/spells/apportation.dm
@@ -1,12 +1,9 @@
-/datum/power/technomancer/apportation
+/datum/technomancer/spell/apportation
name = "Apportation"
desc = "This allows you to teleport objects into your hand, or to pull people towards you. If they're close enough, the function \
will grab them automatically."
cost = 50
- verbpath = /mob/living/carbon/human/proc/technomancer_apportation
-
-/mob/living/carbon/human/proc/technomancer_apportation()
- place_spell_in_hand(/obj/item/weapon/spell/apportation)
+ obj_path = /obj/item/weapon/spell/apportation
/obj/item/weapon/spell/apportation
name = "apportation"
@@ -34,8 +31,6 @@
s2.set_up(2, 1, I)
s1.start()
s2.start()
-// new /obj/effect/effect/sparks(get_turf(I))
-// new /obj/effect/effect/sparks(get_turf(user))
I.visible_message("\The [I] vanishes into thin air!")
I.forceMove(get_turf(user))
user.drop_item(src)
@@ -53,8 +48,6 @@
s2.set_up(2, 1, L)
s1.start()
s2.start()
-// new /obj/effect/effect/sparks(get_turf(L))
-// new /obj/effect/effect/sparks(get_turf(user))
L.throw_at(get_step(get_turf(src),get_turf(L)), 4, 1, src)
user.drop_item(src)
src.loc = null
diff --git a/code/game/gamemodes/technomancer/spells/aspect/aspect.dm b/code/game/gamemodes/technomancer/spells/aspect/aspect.dm
new file mode 100644
index 0000000000..dd2d2cce5f
--- /dev/null
+++ b/code/game/gamemodes/technomancer/spells/aspect/aspect.dm
@@ -0,0 +1,46 @@
+/obj/item/weapon/spell/aspect
+ name = "aspect template"
+ desc = "Combine this with another spell to finish the function."
+ cast_methods = CAST_COMBINE
+ aspect = ASPECT_CHROMATIC
+ var/fire_result = null
+ var/frost_result = null
+ var/shock_result = null
+ var/air_result = null
+ var/force_result = null
+ var/tele_result = null
+ var/biomed_result = null
+ var/dark_result = null
+ var/light_result = null
+ var/unstable_result = null
+
+/obj/item/weapon/spell/aspect/on_combine_cast(obj/item/W, mob/user)
+ if(istype(W, /obj/item/weapon/spell))
+ var/obj/item/weapon/spell/spell = W
+ if(!spell.aspect || spell.aspect == ASPECT_CHROMATIC)
+ user << "You cannot combine \the [spell] with \the [src], as the aspects are incompatable."
+ return
+ user.drop_item(src)
+ src.loc = null
+ switch(spell.aspect)
+ if(ASPECT_FIRE)
+ user.put_in_hands(fire_result)
+ if(ASPECT_FROST)
+ user.put_in_hands(frost_result)
+ if(ASPECT_SHOCK)
+ user.put_in_hands(shock_result)
+ if(ASPECT_AIR)
+ user.put_in_hands(air_result)
+ if(ASPECT_FORCE)
+ user.put_in_hands(force_result)
+ if(ASPECT_TELE)
+ user.put_in_hands(tele_result)
+ if(ASPECT_BIOMED)
+ user.put_in_hands(biomed_result)
+ if(ASPECT_DARK)
+ user.put_in_hands(dark_result)
+ if(ASPECT_LIGHT)
+ user.put_in_hands(light_result)
+ if(ASPECT_UNSTABLE)
+ user.put_in_hands(unstable_result)
+ qdel(src)
\ No newline at end of file
diff --git a/code/game/gamemodes/technomancer/spells/aspect/aspect_weapon.dm b/code/game/gamemodes/technomancer/spells/aspect/aspect_weapon.dm
new file mode 100644
index 0000000000..3efc5c1f05
--- /dev/null
+++ b/code/game/gamemodes/technomancer/spells/aspect/aspect_weapon.dm
@@ -0,0 +1,69 @@
+/datum/technomancer/spell/aspect_weapon
+ name = "Aspect Weapon"
+ desc = "This bolt function takes on the properties of other functions based on which aspect is introduced to it, making a temporary \
+ weapon that has the properties of the aspect introduced to it."
+ cost = 200
+ obj_path = /obj/item/weapon/spell/aspect/weapon
+
+/obj/item/weapon/spell/aspect/weapon
+ name = "aspect weapon"
+ desc = "Combine this with another spell to finish the function."
+ fire_result = null
+ frost_result = null
+ shock_result = null
+ air_result = null
+ force_result = null
+ tele_result = null
+ biomed_result = null
+ dark_result = null
+ light_result = null
+ unstable_result = /obj/item/weapon/conjured/unstable_blade
+
+/obj/item/weapon/conjured
+ anchored = 1
+ throwforce = 0
+ throw_range = 0
+ throw_speed = 0
+ var/mob/living/carbon/human/user = null
+
+/obj/item/weapon/conjured/New(location)
+ ..()
+ if(ishuman(loc))
+ user = loc
+
+/obj/item/weapon/conjured/Destroy(location)
+ user = null
+ ..()
+
+/obj/item/weapon/conjured/dropped()
+ qdel(src)
+
+/obj/item/weapon/conjured/unstable_blade
+ name = "unstable blade"
+ desc = "This thing seems to warp before your eyes. Perhaps this can enable you to land stronger hits, if you feel lucky."
+ force = 20
+ sharp = 1
+ edge = 1
+ attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
+
+/obj/item/weapon/conjured/unstable_blade/New(location)
+ ..()
+ processing_objects |= src
+
+/obj/item/weapon/conjured/unstable_blade/Destroy()
+ processing_objects -= src
+ ..()
+
+/obj/item/weapon/conjured/unstable_blade/process()
+ if(user)
+ user.adjust_instability(1)
+
+
+//The only weapon in SS13 with the ability for 'critical hits', to tie in with the theme for randomness for the Unstable aspect.
+/obj/item/weapon/conjured/unstable_blade/afterattack(atom/target, var/mob/living/carbon/human/user, proximity_flag, click_parameters)
+ if(prob(20) && proximity_flag)
+ visible_message("\The [user] lands a devastating blow on \the [target]!")
+ force = force * 2
+ attack(target, user)
+ force = initial(force)
+ user.adjust_instability(2)
diff --git a/code/game/gamemodes/technomancer/spells/aspect_aura.dm b/code/game/gamemodes/technomancer/spells/aspect_aura.dm
index a613d1bf29..0315ee3465 100644
--- a/code/game/gamemodes/technomancer/spells/aspect_aura.dm
+++ b/code/game/gamemodes/technomancer/spells/aspect_aura.dm
@@ -1,9 +1,9 @@
-/datum/power/technomancer/aspect_aura
+/datum/technomancer/spell/aspect_aura
name = "Aspect Aura"
desc = "This aura function takes on the properties of other functions based on which aspect is introduced to it, applying \
it to everyone nearby."
cost = 200
- verbpath = /mob/living/carbon/human/proc/technomancer_aspect_aura
+ obj_path = /mob/living/carbon/human/proc/technomancer_aspect_aura
/mob/living/carbon/human/proc/technomancer_aspect_aura()
place_spell_in_hand(/obj/item/weapon/spell/aspect_aura)
diff --git a/code/game/gamemodes/technomancer/spells/aspect_bolt.dm b/code/game/gamemodes/technomancer/spells/aspect_bolt.dm
index 11d992a130..19d278297c 100644
--- a/code/game/gamemodes/technomancer/spells/aspect_bolt.dm
+++ b/code/game/gamemodes/technomancer/spells/aspect_bolt.dm
@@ -1,9 +1,9 @@
-/datum/power/technomancer/aspect_bolt
+/datum/technomancer/spell/aspect_bolt
name = "Aspect Bolt"
desc = "This bolt function takes on the properties of other functions based on which aspect is introduced to it, with the \
delivery method being a projectile."
cost = 150
- verbpath = /mob/living/carbon/human/proc/technomancer_aspect_bolt
+ obj_path = /mob/living/carbon/human/proc/technomancer_aspect_bolt
/mob/living/carbon/human/proc/technomancer_aspect_bolt()
place_spell_in_hand(/obj/item/weapon/spell/aspect_bolt)
diff --git a/code/game/gamemodes/technomancer/spells/blink.dm b/code/game/gamemodes/technomancer/spells/blink.dm
index b1896ba262..8e544e9220 100644
--- a/code/game/gamemodes/technomancer/spells/blink.dm
+++ b/code/game/gamemodes/technomancer/spells/blink.dm
@@ -1,12 +1,9 @@
-/datum/power/technomancer/blink
+/datum/technomancer/spell/blink
name = "Blink"
desc = "Force the target to teleport a short distance away. This target could be anything from something lying on the ground, to someone trying to \
fight you, or even yourself."
cost = 100
- verbpath = /mob/living/carbon/human/proc/technomancer_blink
-
-/mob/living/carbon/human/proc/technomancer_blink()
- place_spell_in_hand(/obj/item/weapon/spell/blink)
+ obj_path = /obj/item/weapon/spell/blink
/obj/item/weapon/spell/blink
name = "blink"
diff --git a/code/game/gamemodes/technomancer/spells/control.dm b/code/game/gamemodes/technomancer/spells/control.dm
index 7ee1c8a12a..638f4359d2 100644
--- a/code/game/gamemodes/technomancer/spells/control.dm
+++ b/code/game/gamemodes/technomancer/spells/control.dm
@@ -1,4 +1,4 @@
-/datum/power/technomancer/control
+/datum/technomancer/spell/control
name = "Control"
desc = "This function allows you to exert control over simple-minded entities to an extent, such as spiders and carp. \
Controlled entities will not be hostile towards you, and you may direct them to move to specific areas or to attack specific \
@@ -6,7 +6,7 @@
not true mind control, but merely pheromone synthesis for living animals, and electronic hacking for simple robots. The green web \
around the entity is merely a hologram used to allow the user to know if the creature is safe or not."
cost = 200
- verbpath = /mob/living/carbon/human/proc/technomancer_resurrect
+ obj_path = /obj/item/weapon/spell/control
/mob/living/carbon/human/proc/technomancer_control()
place_spell_in_hand(/obj/item/weapon/spell/control)
diff --git a/code/game/gamemodes/technomancer/spells/darkness.dm b/code/game/gamemodes/technomancer/spells/darkness.dm
index 0b58239e61..a632bc084b 100644
--- a/code/game/gamemodes/technomancer/spells/darkness.dm
+++ b/code/game/gamemodes/technomancer/spells/darkness.dm
@@ -1,11 +1,8 @@
-/datum/power/technomancer/darkness
+/datum/technomancer/spell/darkness
name = "Darkness"
desc = "Disrupts photons moving in a local area, causing darkness to shroud yourself or a position of your choosing."
cost = 30
- verbpath = /mob/living/carbon/human/proc/technomancer_darkness
-
-/mob/living/carbon/human/proc/technomancer_darkness()
- place_spell_in_hand(/obj/item/weapon/spell/darkness)
+ obj_path = /obj/item/weapon/spell/darkness
/obj/item/weapon/spell/darkness
name = "darkness"
diff --git a/code/game/gamemodes/technomancer/spells/discharge.dm b/code/game/gamemodes/technomancer/spells/discharge.dm
index 0aa5c7e40c..638ec34601 100644
--- a/code/game/gamemodes/technomancer/spells/discharge.dm
+++ b/code/game/gamemodes/technomancer/spells/discharge.dm
@@ -1,8 +1,8 @@
-/datum/power/technomancer/discharge
+/datum/technomancer/spell/discharge
name = "Discharge"
desc = "Attempts to steal energy from your target, electrocuting it and anyone holding it."
cost = 70
- verbpath = /mob/living/carbon/human/proc/technomancer_discharge
+ obj_path = /obj/item/weapon/spell/discharge
/mob/living/carbon/human/proc/technomancer_discharge()
place_spell_in_hand(/obj/item/weapon/spell/discharge)
diff --git a/code/game/gamemodes/technomancer/spells/flame_tongue.dm b/code/game/gamemodes/technomancer/spells/flame_tongue.dm
index 6ff4c1545f..e5c22e0e2f 100644
--- a/code/game/gamemodes/technomancer/spells/flame_tongue.dm
+++ b/code/game/gamemodes/technomancer/spells/flame_tongue.dm
@@ -1,11 +1,8 @@
-/datum/power/technomancer/flame_tongue
+/datum/technomancer/spell/flame_tongue
name = "Flame Tongue"
desc = "Using a miniturized flamethrower in your gloves, you can emit a flame strong enough to melt both your enemies and walls."
cost = 100
- verbpath = /mob/living/carbon/human/proc/technomancer_flame_tongue
-
-/mob/living/carbon/human/proc/technomancer_flame_tongue()
- place_spell_in_hand(/obj/item/weapon/spell/flame_tongue)
+ obj_path = /obj/item/weapon/spell/flame_tongue
/obj/item/weapon/spell/flame_tongue
name = "flame tongue"
@@ -41,7 +38,7 @@
return
/obj/item/weapon/spell/flame_tongue/on_melee_cast(atom/hit_atom, mob/living/user, def_zone)
- if(isliving(hit_atom))
+ if(isliving(hit_atom) && user.a_intent != I_HELP)
var/mob/living/L = hit_atom
if(pay_energy(1000))
visible_message("\The [user] reaches out towards \the [L] with the flaming hand, and they ignite!")
diff --git a/code/game/gamemodes/technomancer/spells/insert/corona.dm b/code/game/gamemodes/technomancer/spells/insert/corona.dm
new file mode 100644
index 0000000000..f29164f43a
--- /dev/null
+++ b/code/game/gamemodes/technomancer/spells/insert/corona.dm
@@ -0,0 +1,28 @@
+/datum/technomancer/spell/corona
+ name = "Corona"
+ desc = "Causes the victim to glow very brightly, which while harmless in itself, makes it easier for them to be hit. The \
+ bright glow also makes it very difficult to be stealthy. The effect lasts for one minute."
+ cost = 100
+ obj_path = /obj/item/weapon/spell/insert/corona
+
+/obj/item/weapon/spell/insert/corona
+ name = "corona"
+ desc = "How brillient!"
+ icon_state = "radiance"
+ cast_methods = CAST_RANGED
+ aspect = ASPECT_LIGHT
+ light_color = "#D9D900"
+ spell_light_intensity = 5
+ spell_light_range = 3
+ inserting = /obj/item/weapon/inserted_spell/corona
+
+/obj/item/weapon/inserted_spell/corona/on_insert()
+ spawn(1)
+ if(isliving(host))
+ var/mob/living/L = host
+ L.evasion -= 2
+ L.visible_message("You start to glow very brightly!")
+ spawn(1 MINUTE)
+ L.evasion += 2
+ L << "Your glow has ended."
+ qdel(src)
\ No newline at end of file
diff --git a/code/game/gamemodes/technomancer/spells/insert/insert.dm b/code/game/gamemodes/technomancer/spells/insert/insert.dm
index cc1e872aef..d7500e1aeb 100644
--- a/code/game/gamemodes/technomancer/spells/insert/insert.dm
+++ b/code/game/gamemodes/technomancer/spells/insert/insert.dm
@@ -1,25 +1,32 @@
+//Template for spells which put something inside someone else, good for buffs/debuffs, damage over times and heals over time.
+
/obj/item/weapon/spell/insert
name = "insert template"
desc = "Tell a coder if you can read this in-game."
icon_state = "purify"
cast_methods = CAST_MELEE
var/spell_color = "#03A728"
+ var/spell_light_intensity = 2
+ var/spell_light_range = 3
var/obj/item/weapon/inserted_spell/inserting = null
+ var/allow_stacking = 0
/obj/item/weapon/spell/insert/New()
..()
- set_light(3, 2, l_color = light_color)
+ set_light(spell_light_range, spell_light_intensity, l_color = light_color)
/obj/item/weapon/inserted_spell
var/mob/living/carbon/human/origin = null
var/mob/living/host = null
-/obj/item/weapon/inserted_spell/New(var/newloc, var/user, var/spell_color)
+/obj/item/weapon/inserted_spell/New(var/newloc, var/user, var/obj/item/weapon/spell/insert/inserter)
..(newloc)
host = newloc
origin = user
if(light_color)
- set_light(3, 2, l_color = spell_color)
+ spawn(1)
+ world << "Woo!"
+ set_light(inserter.spell_light_range, inserter.spell_light_intensity, inserter.spell_color)
on_insert()
/obj/item/weapon/inserted_spell/proc/on_insert()
@@ -28,10 +35,20 @@
/obj/item/weapon/spell/insert/proc/insert(var/mob/living/L, mob/user)
world << "insert() called"
if(inserting)
- new inserting(L,user,light_color)
+ if(!allow_stacking)
+ for(var/obj/item/weapon/inserted_spell/IS in L.contents)
+ if(IS.type == inserting)
+ user << "\The [L] is already affected by \the [src]."
+ return
+ new inserting(L,user,src)
qdel(src)
/obj/item/weapon/spell/insert/on_melee_cast(atom/hit_atom, mob/user)
+ if(istype(hit_atom, /mob/living))
+ var/mob/living/L = hit_atom
+ insert(L,user)
+
+/obj/item/weapon/spell/insert/on_ranged_cast(atom/hit_atom, mob/user)
if(istype(hit_atom, /mob/living))
var/mob/living/L = hit_atom
insert(L,user)
\ 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
index 081f83461c..9b45c1be44 100644
--- a/code/game/gamemodes/technomancer/spells/insert/mend_burns.dm
+++ b/code/game/gamemodes/technomancer/spells/insert/mend_burns.dm
@@ -1,11 +1,8 @@
-/datum/power/technomancer/mend_burns
+/datum/technomancer/spell/mend_burns
name = "Mend Burns"
desc = "Heals minor burns, such as from exposure to flame, electric shock, or lasers."
cost = 120
- verbpath = /mob/living/carbon/human/proc/technomancer_mend_wounds
-
-/mob/living/carbon/human/proc/technomancer_mend_burns()
- place_spell_in_hand(/obj/item/weapon/spell/insert/mend_wounds)
+ obj_path = /obj/item/weapon/spell/insert/mend_burns
/obj/item/weapon/spell/insert/mend_burns
name = "mend burns"
diff --git a/code/game/gamemodes/technomancer/spells/insert/mend_wounds.dm b/code/game/gamemodes/technomancer/spells/insert/mend_wounds.dm
index 79e685d02d..c684a2361f 100644
--- a/code/game/gamemodes/technomancer/spells/insert/mend_wounds.dm
+++ b/code/game/gamemodes/technomancer/spells/insert/mend_wounds.dm
@@ -1,11 +1,8 @@
-/datum/power/technomancer/mend_wounds
+/datum/technomancer/spell/mend_wounds
name = "Mend Wounds"
desc = "Heals minor wounds, such as cuts, bruises, and other non-lifethreatening injuries."
cost = 120
- verbpath = /mob/living/carbon/human/proc/technomancer_mend_wounds
-
-/mob/living/carbon/human/proc/technomancer_mend_wounds()
- place_spell_in_hand(/obj/item/weapon/spell/insert/mend_wounds)
+ obj_path = /obj/item/weapon/spell/insert/mend_wounds
/obj/item/weapon/spell/insert/mend_wounds
name = "mend wounds"
diff --git a/code/game/gamemodes/technomancer/spells/insert/purify.dm b/code/game/gamemodes/technomancer/spells/insert/purify.dm
index 32cbd57a32..61078d84b8 100644
--- a/code/game/gamemodes/technomancer/spells/insert/purify.dm
+++ b/code/game/gamemodes/technomancer/spells/insert/purify.dm
@@ -1,11 +1,8 @@
-/datum/power/technomancer/purify
+/datum/technomancer/spell/purify
name = "Purify"
desc = "Clenses the body of harmful impurities, such as toxins, radiation, viruses, and such."
cost = 100
- verbpath = /mob/living/carbon/human/proc/technomancer_purify
-
-/mob/living/carbon/human/proc/technomancer_purify()
- place_spell_in_hand(/obj/item/weapon/spell/insert/purify)
+ obj_path = /obj/item/weapon/spell/insert/purify
/obj/item/weapon/spell/insert/purify
name = "purify"
@@ -22,8 +19,8 @@
var/mob/living/carbon/human/H = host
H.sdisabilities = 0
H.disabilities = 0
- for(var/datum/disease/D in H.viruses)
- D.cure()
+// for(var/datum/disease/D in H.viruses)
+// D.cure()
for(var/i = 0, i<25,i++)
if(H)
H.adjustToxLoss(-1)
diff --git a/code/game/gamemodes/technomancer/spells/insert/repel_missiles.dm b/code/game/gamemodes/technomancer/spells/insert/repel_missiles.dm
new file mode 100644
index 0000000000..ecda82462f
--- /dev/null
+++ b/code/game/gamemodes/technomancer/spells/insert/repel_missiles.dm
@@ -0,0 +1,26 @@
+/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 \
+ to hit you. The field lasts for two minutes and can be granted to yourself or an ally."
+ cost = 60
+ obj_path = /obj/item/weapon/spell/insert/repel_missiles
+
+/obj/item/weapon/spell/insert/repel_missiles
+ name = "repel missiles"
+ desc = "Use it before they start shooting at you!"
+ icon_state = "generic"
+ cast_methods = CAST_RANGED
+ aspect = ASPECT_FORCE
+ light_color = "#FF5C5C"
+ inserting = /obj/item/weapon/inserted_spell/repel_missiles
+
+/obj/item/weapon/inserted_spell/repel_missiles/on_insert()
+ spawn(1)
+ if(isliving(host))
+ var/mob/living/L = host
+ L.evasion += 2
+ L << "You have a repulsion field around you, which will attempt to deflect projectiles."
+ spawn(2 MINUTES)
+ L.evasion -= 2
+ L << "Your repulsion field has expired."
+ qdel(src)
\ No newline at end of file
diff --git a/code/game/gamemodes/technomancer/spells/instability_tap.dm b/code/game/gamemodes/technomancer/spells/instability_tap.dm
new file mode 100644
index 0000000000..c28f8c4583
--- /dev/null
+++ b/code/game/gamemodes/technomancer/spells/instability_tap.dm
@@ -0,0 +1,20 @@
+/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."
+ cost = 120
+ obj_path = /obj/item/weapon/spell/instability_tap
+
+/obj/item/weapon/spell/instability_tap
+ name = "instability tap"
+ desc = "Short term gain for long term consequences never end bad, right?"
+ cast_methods = CAST_USE
+ aspect = ASPECT_UNSTABLE
+
+/obj/item/weapon/spell/instability_tap/New()
+ ..()
+ set_light(3, 2, l_color = "#FA58F4")
+
+/obj/item/weapon/spell/instability_tap/on_use_cast(mob/user)
+ core.give_energy(5000)
+ owner.adjust_instability(50)
+ qdel(src)
\ No newline at end of file
diff --git a/code/game/gamemodes/technomancer/spells/mark_recall.dm b/code/game/gamemodes/technomancer/spells/mark_recall.dm
new file mode 100644
index 0000000000..468bf45608
--- /dev/null
+++ b/code/game/gamemodes/technomancer/spells/mark_recall.dm
@@ -0,0 +1,83 @@
+/datum/technomancer/spell/mark
+ name = "Mark"
+ desc = "This function places a specific 'mark' beacon under you, which is used by the Recall function as a destination. \
+ Note that using Mark again will move the destination instead of creating a second destination, and only one destination \
+ can exist, regardless of who casted Mark."
+ cost = 50
+ obj_path = /obj/item/weapon/spell/mark
+
+//The object to teleport to when Recall is used.
+/obj/effect/mark_spell
+ name = "mark"
+ desc = "This is a strange looking disturbance."
+ opacity = 0
+ density = 0
+ anchored = 1
+
+//This is global, to avoid looping through a list of all objects, or god forbid, looping through world.
+/var/global/obj/effect/mark_spell/mark_spell_ref = null
+
+/obj/item/weapon/spell/mark
+ name = "mark"
+ icon_state = "mark"
+ desc = "Marks a specific location to be used by Recall."
+ cast_methods = CAST_USE
+ aspect = ASPECT_TELE
+
+/obj/item/weapon/spell/mark/on_use_cast(mob/living/user)
+ if(pay_energy(1000))
+ if(!mark_spell_ref)
+ mark_spell_ref = new(get_turf(user))
+ user << "You mark \the [get_turf(user)] under you."
+ else
+ mark_spell_ref.forceMove(get_turf(user))
+ user << "Your mark is moved from its old position to \the [get_turf(user)] under you."
+ owner.adjust_instability(5)
+ return 1
+ else
+ user << "You can't afford the energy cost!"
+ return 0
+
+//Recall
+
+/datum/technomancer/spell/recall
+ name = "Recall"
+ desc = "This function teleports you to where you placed a mark using the Mark function. Without the Mark function, this \
+ function is useless. Note that teleporting takes three seconds. Being incapacitated while teleporting will cancel it."
+ cost = 50
+ obj_path = /obj/item/weapon/spell/recall
+
+/obj/item/weapon/spell/recall
+ name = "recall"
+ icon_state = "recall"
+ desc = "This will bring you to your Mark."
+ cast_methods = CAST_USE
+ aspect = ASPECT_TELE
+
+/obj/item/weapon/spell/recall/on_use_cast(mob/living/user)
+ if(pay_energy(3000))
+ if(!mark_spell_ref)
+ user << "There's no Mark!"
+ return 0
+ else
+ visible_message("\The [user] starts glowing!")
+ var/light_intensity = 2
+ var/time_left = 3
+ while(time_left)
+ if(user.incapacitated())
+ visible_message("\The [user]'s glow fades.")
+ user << "You cannot Recall while incapacitated!"
+ return 0
+ light_intensity++
+ set_light(light_intensity, light_intensity, l_color = "#006AFF")
+ time_left--
+ sleep(1 SECOND)
+ user.forceMove(get_turf(mark_spell_ref))
+ user << "You are teleported to your Mark."
+ owner.adjust_instability(25)
+ qdel(src)
+ return 1
+ else
+ user << "You can't afford the energy cost!"
+ return 0
+
diff --git a/code/game/gamemodes/technomancer/spells/oxygenate.dm b/code/game/gamemodes/technomancer/spells/oxygenate.dm
new file mode 100644
index 0000000000..13439383e6
--- /dev/null
+++ b/code/game/gamemodes/technomancer/spells/oxygenate.dm
@@ -0,0 +1,29 @@
+/datum/technomancer/spell/darkness
+ 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 = 70
+ obj_path = /obj/item/weapon/spell/oxygenate
+
+/obj/item/weapon/spell/oxygenate
+ name = "oxygenate"
+ desc = "Atmospherics is obsolete."
+ icon_state = "darkness" //wip
+ cast_methods = CAST_RANGED
+ aspect = ASPECT_AIR
+ cooldown = 30
+
+/obj/item/weapon/spell/oxygenate/on_ranged_cast(atom/hit_atom, mob/user)
+ if(ishuman(hit_atom))
+ var/mob/living/carbon/human/H = hit_atom
+ if(pay_energy(1500))
+ H.adjustOxyLoss(-35)
+ owner.adjust_instability(10)
+ return
+ else if(isturf(hit_atom))
+ var/turf/T = hit_atom
+ if(pay_energy(1500))
+ T.assume_gas("oxygen", 200)
+ T.assume_gas("nitrogen", 800)
+ playsound(src.loc, 'sound/effects/spray.ogg', 50, 1, -3)
+ owner.adjust_instability(10)
\ No newline at end of file
diff --git a/code/game/gamemodes/technomancer/spells/passwall.dm b/code/game/gamemodes/technomancer/spells/passwall.dm
index 20bfbb7bfe..cc54f2b287 100644
--- a/code/game/gamemodes/technomancer/spells/passwall.dm
+++ b/code/game/gamemodes/technomancer/spells/passwall.dm
@@ -1,12 +1,9 @@
-/datum/power/technomancer/passwall
+/datum/technomancer/spell/passwall
name = "Passwall"
desc = "An uncommon function that allows the user to phase through matter (usually walls) in order to enter or exit a room. Be careful you don't pass into \
somewhere dangerous."
cost = 100
- verbpath = /mob/living/carbon/human/proc/technomancer_passwall
-
-/mob/living/carbon/human/proc/technomancer_passwall()
- place_spell_in_hand(/obj/item/weapon/spell/passwall)
+ obj_path = /obj/item/weapon/spell/passwall
/obj/item/weapon/spell/passwall
name = "passwall"
@@ -39,7 +36,7 @@
while(i)
checked_turf = get_step(checked_turf, direction) //Advance in the given direction
- total_cost += 1000 //Phasing through matter's expensive, you know.
+ total_cost += 800 //Phasing through matter's expensive, you know.
i--
if(!checked_turf.density) //If we found a destination (a non-dense turf), then we can stop.
var/dense_objs_on_turf = 0
@@ -56,11 +53,16 @@
if(user.loc != our_turf)
user << "You need to stand still in order to phase through the wall."
return 0
- visible_message("[user] appears to phase through \the [T]!")
- user << "You find a destination on the other side of \the [T], and phase through it."
- spark_system.start()
- user.forceMove(found_turf)
- qdel(src)
- return 1
+ if(pay_energy(total_cost) && !user.incapacitated() )
+ visible_message("[user] appears to phase through \the [T]!")
+ user << "You find a destination on the other side of \the [T], and phase through it."
+ spark_system.start()
+ user.forceMove(found_turf)
+ qdel(src)
+ return 1
+ else
+ user << "You don't have enough energy to phase through these walls!"
+ busy = 0
else
user << "You weren't able to find an open space to go to."
+ busy = 0
diff --git a/code/game/gamemodes/technomancer/spells/phase_shift.dm b/code/game/gamemodes/technomancer/spells/phase_shift.dm
index f366c46164..cd6a87df1f 100644
--- a/code/game/gamemodes/technomancer/spells/phase_shift.dm
+++ b/code/game/gamemodes/technomancer/spells/phase_shift.dm
@@ -1,12 +1,9 @@
-/datum/power/technomancer/phase_shift
+/datum/technomancer/spell/phase_shift
name = "Phase Shift"
desc = "Hides you in the safest possible place, where no harm can come to you. Unfortunately you can only stay inside for a few moments before \
draining your powercell."
cost = 80
- verbpath = /mob/living/carbon/human/proc/technomancer_phase_shift
-
-/mob/living/carbon/human/proc/technomancer_phase_shift()
- place_spell_in_hand(/obj/item/weapon/spell/phase_shift)
+ obj_path = /obj/item/weapon/spell/phase_shift
/obj/item/weapon/spell/phase_shift
name = "phase shift"
diff --git a/code/game/gamemodes/technomancer/spells/projectile/chain_lightning.dm b/code/game/gamemodes/technomancer/spells/projectile/chain_lightning.dm
new file mode 100644
index 0000000000..0ce0b8a141
--- /dev/null
+++ b/code/game/gamemodes/technomancer/spells/projectile/chain_lightning.dm
@@ -0,0 +1,77 @@
+/datum/technomancer/spell/chain_lightning
+ name = "Chain Lightning"
+ desc = "This dangerous function shoots lightning that will strike someone, then bounce to a nearby person. Be careful that \
+ it does not bounce to you. The lighting prefers to bounce to people with the least resistance to electricity. It will \
+ strike up to four targets, including yourself if conditions allow it to occur."
+ cost = 150
+ obj_path = /obj/item/weapon/spell/projectile/chain_lightning
+
+/obj/item/weapon/spell/projectile/chain_lightning
+ name = "chain lightning"
+ icon_state = "chain_lightning"
+ desc = "Fry the whole security team! Just don't kill yourself in the process.."
+ cast_methods = CAST_RANGED
+ aspect = ASPECT_SHOCK
+ spell_projectile = /obj/item/projectile/beam/chain_lightning
+ energy_cost_per_shot = 3000
+ instability_per_shot = 10
+ cooldown = 20
+
+/obj/item/projectile/beam/chain_lightning
+ name = "lightning"
+ icon_state = "lightning"
+ nodamage = 1
+ damage_type = HALLOSS
+
+ muzzle_type = /obj/effect/projectile/lightning/muzzle
+ tracer_type = /obj/effect/projectile/lightning/tracer
+ impact_type = /obj/effect/projectile/lightning/impact
+
+ 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 = 30 //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.
+ if(ishuman(target_mob))
+ var/mob/living/carbon/human/H = target_mob
+ var/obj/item/organ/external/affected = H.get_organ(check_zone(BP_TORSO))
+ H.electrocute_act(power, src, H.get_siemens_coefficient_organ(affected), affected)
+ else
+ target_mob.electrocute_act(power, src, 1.0, BP_TORSO)
+ hit_mobs |= target_mob
+
+ //Each bounce reduces the damage of the bolt.
+ power = power * 0.80
+ if(bounces)
+ //All possible targets.
+ var/list/potential_targets = view(target_mob, 3)
+
+ //Filtered targets, so we don't hit the same person twice.
+ var/list/filtered_targets = list()
+ for(var/mob/living/L in potential_targets)
+ if(L in hit_mobs)
+ continue
+ filtered_targets |= L
+
+ var/mob/living/new_target = null
+ var/siemens_comparison = 0
+
+ for(var/mob/living/carbon/human/H in filtered_targets)
+ var/obj/item/organ/external/affected = H.get_organ(check_zone(BP_TORSO))
+ var/their_siemens = H.get_siemens_coefficient_organ(affected)
+ if(their_siemens > siemens_comparison) //We want as conductive as possible, so higher is better.
+ new_target = H
+ siemens_comparison = their_siemens
+
+ if(new_target)
+ var/turf/curloc = get_turf(target_mob)
+ curloc.visible_message("\The [src] bounces to \the [new_target]!")
+ redirect(new_target.x, new_target.y, curloc, firer)
+ bounces--
+
+ return 0
+ return 1
+
+
+
diff --git a/code/game/gamemodes/technomancer/spells/projectile/lightning.dm b/code/game/gamemodes/technomancer/spells/projectile/lightning.dm
new file mode 100644
index 0000000000..40d1dba4d9
--- /dev/null
+++ b/code/game/gamemodes/technomancer/spells/projectile/lightning.dm
@@ -0,0 +1,40 @@
+/datum/technomancer/spell/lightning
+ name = "Lightning"
+ desc = "This uses a hidden electrolaser, which creates a laser beam to ionize the enviroment, allowing for ideal conditions \
+ for a directed lightning strike to occur. The lightning is very strong, however it requires a few seconds to prepare a \
+ strike."
+ cost = 150
+ obj_path = /obj/item/weapon/spell/projectile/lightning
+
+/obj/item/weapon/spell/projectile/lightning
+ name = "lightning"
+ icon_state = "lightning"
+ desc = "Send instability from the target to you, for whatever reason you'd want to."
+ cast_methods = CAST_RANGED
+ aspect = ASPECT_SHOCK
+ spell_projectile = /obj/item/projectile/beam/lightning
+ energy_cost_per_shot = 2500
+ instability_per_shot = 10
+ cooldown = 20
+ pre_shot_delay = 2
+
+/obj/item/projectile/beam/lightning
+ name = "lightning"
+ icon_state = "lightning"
+ nodamage = 1
+ damage_type = HALLOSS
+
+ muzzle_type = /obj/effect/projectile/lightning/muzzle
+ tracer_type = /obj/effect/projectile/lightning/tracer
+ impact_type = /obj/effect/projectile/lightning/impact
+
+ var/power = 40 //How hard it will hit for with electrocute_act().
+
+/obj/item/projectile/beam/lightning/attack_mob(var/mob/living/target_mob, var/distance, var/miss_modifier=0)
+ if(ishuman(target_mob))
+ var/mob/living/carbon/human/H = target_mob
+ var/obj/item/organ/external/affected = H.get_organ(check_zone(BP_TORSO))
+ H.electrocute_act(power, src, H.get_siemens_coefficient_organ(affected), affected)
+ else
+ target_mob.electrocute_act(power, src, 1.0, BP_TORSO)
+ return 1
\ No newline at end of file
diff --git a/code/game/gamemodes/technomancer/spells/projectile/projectile.dm b/code/game/gamemodes/technomancer/spells/projectile/projectile.dm
new file mode 100644
index 0000000000..0327bc542d
--- /dev/null
+++ b/code/game/gamemodes/technomancer/spells/projectile/projectile.dm
@@ -0,0 +1,19 @@
+/obj/item/weapon/spell/projectile
+ name = "projectile template"
+ icon_state = "generic"
+ desc = "This is a generic template that shoots projectiles. If you can read this, the game broke!"
+ cast_methods = CAST_RANGED
+ var/obj/item/projectile/spell_projectile = null
+ var/energy_cost_per_shot = 0
+ var/instability_per_shot = 0
+ var/pre_shot_delay = 0 //Mesured in seconds
+
+/obj/item/weapon/spell/projectile/on_ranged_cast(atom/hit_atom, mob/living/user)
+ if(spell_projectile)
+ if(pay_energy(energy_cost_per_shot))
+ if(pre_shot_delay)
+ user.Stun(pre_shot_delay)
+ sleep(pre_shot_delay SECONDS)
+ var/obj/item/projectile/new_projectile = new spell_projectile(get_turf(user))
+ new_projectile.launch(hit_atom)
+ owner.adjust_instability(instability_per_shot)
\ No newline at end of file
diff --git a/code/game/gamemodes/technomancer/spells/pulsar.dm b/code/game/gamemodes/technomancer/spells/pulsar.dm
index 0e616fde7b..dff8e4399c 100644
--- a/code/game/gamemodes/technomancer/spells/pulsar.dm
+++ b/code/game/gamemodes/technomancer/spells/pulsar.dm
@@ -1,11 +1,8 @@
-/datum/power/technomancer/pulsar
+/datum/technomancer/spell/pulsar
name = "Pulsar"
desc = "Emits electronic pulses to destroy, disable, or otherwise harm devices and machines. Be sure to not hit yourself with this."
cost = 150
- verbpath = /mob/living/carbon/human/proc/technomancer_pulsar
-
-/mob/living/carbon/human/proc/technomancer_pulsar()
- place_spell_in_hand(/obj/item/weapon/spell/pulsar)
+ obj_path = /obj/item/weapon/spell/pulsar
/obj/item/weapon/spell/pulsar
name = "pulsar"
diff --git a/code/game/gamemodes/technomancer/spells/radiance.dm b/code/game/gamemodes/technomancer/spells/radiance.dm
index 03b9b81bba..b8eb1401f1 100644
--- a/code/game/gamemodes/technomancer/spells/radiance.dm
+++ b/code/game/gamemodes/technomancer/spells/radiance.dm
@@ -1,11 +1,8 @@
-/datum/power/technomancer/radiance
+/datum/technomancer/spell/radiance
name = "Radiance"
desc = "Causes you to be very radiant, glowing brightly in visible light, thermal energy, and deadly ionizing radiation."
cost = 180
- verbpath = /mob/living/carbon/human/proc/technomancer_radiance
-
-/mob/living/carbon/human/proc/technomancer_radiance()
- place_spell_in_hand(/obj/item/weapon/spell/darkness)
+ obj_path = /obj/item/weapon/spell/radiance
/obj/item/weapon/spell/radiance
name = "radiance"
diff --git a/code/game/gamemodes/technomancer/spells/reflect.dm b/code/game/gamemodes/technomancer/spells/reflect.dm
new file mode 100644
index 0000000000..9e82efea40
--- /dev/null
+++ b/code/game/gamemodes/technomancer/spells/reflect.dm
@@ -0,0 +1,90 @@
+/datum/technomancer/spell/reflect
+ name = "Reflect"
+ desc = "Emits a protective shield fron your hand in front of you, which will reflect one attack back at the attacker."
+ cost = 120
+ obj_path = /obj/item/weapon/spell/reflect
+
+/obj/item/weapon/spell/reflect
+ name = "\proper reflect shield"
+ icon_state = "shield"
+ desc = "A very protective combat shield that'll reflect the next attack at the unfortunate person who tried to shoot you."
+ aspect = ASPECT_FORCE
+ toggled = 1
+ var/damage_to_energy_multiplier = 60.0 //Determines how much energy to charge for blocking, e.g. 20 damage attack = 1200 energy cost
+ var/datum/effect/effect/system/spark_spread/spark_system = null
+
+/obj/item/weapon/spell/reflect/New()
+ ..()
+ set_light(3, 2, l_color = "#006AFF")
+ spark_system = PoolOrNew(/datum/effect/effect/system/spark_spread)
+ spark_system.set_up(5, 0, src)
+ owner << "Your shield will expire in 20 seconds."
+ spawn(20 SECONDS)
+ if(src)
+ owner << "Your shield expires!"
+ qdel(src)
+
+/obj/item/weapon/spell/reflect/Destroy()
+ spark_system = null
+ ..()
+
+/obj/item/weapon/spell/reflect/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
+ if(user.incapacitated())
+ return 0
+
+ var/damage_to_energy_cost = (damage_to_energy_multiplier * damage)
+
+ if(!pay_energy(damage_to_energy_cost))
+ owner << "Your shield fades due to lack of energy!"
+ qdel(src)
+ return 0
+
+ //block as long as they are not directly behind us
+ var/bad_arc = reverse_direction(user.dir) //arc of directions from which we cannot block
+ if(check_shield_arc(user, bad_arc, damage_source, attacker))
+
+ if(istype(damage_source, /obj/item/projectile))
+ var/obj/item/projectile/P = damage_source
+
+ if(P.starting)
+ visible_message("\The [user]'s [src.name] reflects [attack_text]!")
+
+ var/turf/curloc = get_turf(user)
+
+ // redirect the projectile
+ P.redirect(P.starting.x, P.starting.y, curloc, user)
+
+ spark_system.start()
+ playsound(user.loc, 'sound/weapons/blade1.ogg', 50, 1)
+
+ spawn(1 SECOND) //To ensure that most or all of a burst fire cycle is reflected.
+ owner << "Your shield fades due being used up!"
+ qdel(src)
+
+ return PROJECTILE_CONTINUE // complete projectile permutation
+
+
+ return 1
+ return 0
+
+/*
+/obj/item/clothing/suit/armor/laserproof/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
+ if(istype(damage_source, /obj/item/projectile/energy) || istype(damage_source, /obj/item/projectile/beam))
+ var/obj/item/projectile/P = damage_source
+
+ var/reflectchance = 40 - round(damage/3)
+ if(!(def_zone in list(BP_TORSO, BP_GROIN)))
+ reflectchance /= 2
+ if(P.starting && prob(reflectchance))
+ visible_message("\The [user]'s [src.name] reflects [attack_text]!")
+
+ // Find a turf near or on the original location to bounce to
+ var/new_x = P.starting.x + pick(0, 0, 0, 0, 0, -1, 1, -2, 2)
+ var/new_y = P.starting.y + pick(0, 0, 0, 0, 0, -1, 1, -2, 2)
+ var/turf/curloc = get_turf(user)
+
+ // redirect the projectile
+ P.redirect(new_x, new_y, curloc, user)
+
+ return PROJECTILE_CONTINUE // complete projectile permutation
+*/
diff --git a/code/game/gamemodes/technomancer/spells/resurrect.dm b/code/game/gamemodes/technomancer/spells/resurrect.dm
index d8dab0b305..512e9e4db9 100644
--- a/code/game/gamemodes/technomancer/spells/resurrect.dm
+++ b/code/game/gamemodes/technomancer/spells/resurrect.dm
@@ -1,13 +1,10 @@
-/datum/power/technomancer/resurrect
+/datum/technomancer/spell/resurrect
name = "Resurrect"
desc = "This function injects various regenetive medical compounds and nanomachines, in an effort to restart the body, \
however this must be done soon after they die, as this will have no effect on people who have died long ago. It also doesn't \
resolve whatever caused them to die originally."
cost = 250
- verbpath = /mob/living/carbon/human/proc/technomancer_resurrect
-
-/mob/living/carbon/human/proc/technomancer_resurrect()
- place_spell_in_hand(/obj/item/weapon/spell/resurrect)
+ obj_path = /obj/item/weapon/spell/resurrect
/obj/item/weapon/spell/resurrect
name = "resurrect"
diff --git a/code/game/gamemodes/technomancer/spells/shared_burden.dm b/code/game/gamemodes/technomancer/spells/shared_burden.dm
index dd96e3c835..c7e8e35107 100644
--- a/code/game/gamemodes/technomancer/spells/shared_burden.dm
+++ b/code/game/gamemodes/technomancer/spells/shared_burden.dm
@@ -1,11 +1,8 @@
-/datum/power/technomancer/shared_burden
+/datum/technomancer/spell/shared_burden
name = "Shared Burden"
desc = "One of the few functions able to adjust instability, this allows you to take someone else's instability."
cost = 50
- verbpath = /mob/living/carbon/human/proc/technomancer_shared_burden
-
-/mob/living/carbon/human/proc/technomancer_shared_burden()
- place_spell_in_hand(/obj/item/weapon/spell/shared_burden)
+ obj_path = /obj/item/weapon/spell/shared_burden
/obj/item/weapon/spell/shared_burden
name = "shared burden"
diff --git a/code/game/gamemodes/technomancer/spells/shield.dm b/code/game/gamemodes/technomancer/spells/shield.dm
index 2a573d62c4..5661a9cac5 100644
--- a/code/game/gamemodes/technomancer/spells/shield.dm
+++ b/code/game/gamemodes/technomancer/spells/shield.dm
@@ -1,12 +1,9 @@
-/datum/power/technomancer/shield
+/datum/technomancer/spell/shield
name = "Shield"
desc = "Emits a protective shield fron your hand in front of you, which will protect you from almost anything able to harm \
you, so long as you can power it."
cost = 120
- verbpath = /mob/living/carbon/human/proc/technomancer_shield
-
-/mob/living/carbon/human/proc/technomancer_shield()
- place_spell_in_hand(/obj/item/weapon/spell/shield)
+ obj_path = /obj/item/weapon/spell/shield
/obj/item/weapon/spell/shield
name = "\proper energy shield"
diff --git a/code/game/gamemodes/technomancer/spells/warp_strike.dm b/code/game/gamemodes/technomancer/spells/warp_strike.dm
index 4751e50a93..9b57789e89 100644
--- a/code/game/gamemodes/technomancer/spells/warp_strike.dm
+++ b/code/game/gamemodes/technomancer/spells/warp_strike.dm
@@ -1,11 +1,8 @@
-/datum/power/technomancer/warp_strike
+/datum/technomancer/spell/warp_strike
name = "Warp Strike"
desc = "Teleports you next to your target, and attacks them with whatever is in your off-hand, spell or object."
cost = 200
- verbpath = /mob/living/carbon/human/proc/technomancer_warp_strike
-
-/mob/living/carbon/human/proc/technomancer_warp_strike()
- place_spell_in_hand(/obj/item/weapon/spell/warp_strike)
+ obj_path = /obj/item/weapon/spell/warp_strike
/obj/item/weapon/spell/warp_strike
name = "warp strike"
diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm
index c547211ecf..7cfe5f34b5 100644
--- a/code/modules/mob/living/living_defines.dm
+++ b/code/modules/mob/living/living_defines.dm
@@ -44,3 +44,5 @@
var/failed_last_breath = 0 //This is used to determine if the mob failed a breath. If they did fail a brath, they will attempt to breathe each tick, otherwise just once per 4 ticks.
var/lastpuke = 0
+
+ var/evasion = 0 //Makes attacks harder to land. Each number equals 15% more likely to miss. Negative numbers increase hit chance.
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 01a0e9105a..7927178dd9 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -157,7 +157,7 @@
return buckled ? FULLY_BUCKLED : UNBUCKLED
/mob/proc/incapacitated(var/incapacitation_flags = INCAPACITATION_DEFAULT)
- if (stat || paralysis || stunned || weakened || resting || sleeping || (status_flags & FAKEDEATH))
+ if (stat || paralysis || weakened || resting || sleeping || (status_flags & FAKEDEATH))
return 1
if((incapacitation_flags & INCAPACITATION_RESTRAINED) && restrained())
diff --git a/code/modules/projectiles/effects.dm b/code/modules/projectiles/effects.dm
index 7874eeb383..2235f188e7 100644
--- a/code/modules/projectiles/effects.dm
+++ b/code/modules/projectiles/effects.dm
@@ -124,3 +124,15 @@
//----------------------------
/obj/effect/projectile/bullet/muzzle
icon_state = "muzzle_bullet"
+
+//----------------------------
+// Lightning beam
+//----------------------------
+/obj/effect/projectile/lightning/tracer
+ icon_state = "lightning"
+
+/obj/effect/projectile/lightning/muzzle
+ icon_state = "muzzle_lightning"
+
+/obj/effect/projectile/lightning/impact
+ icon_state = "impact_lightning"
\ No newline at end of file
diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm
index ff561b5250..f4fbc6989e 100644
--- a/code/modules/projectiles/projectile.dm
+++ b/code/modules/projectiles/projectile.dm
@@ -169,7 +169,7 @@
return
//roll to-hit
- miss_modifier = max(15*(distance-2) - round(15*accuracy) + miss_modifier, 0)
+ miss_modifier = max(15*(distance-2) - round(15*accuracy) + miss_modifier + round(15*target_mob.evasion), 0)
var/hit_zone = get_zone_with_miss_chance(def_zone, target_mob, miss_modifier, ranged_attack=(distance > 1 || original != target_mob)) //if the projectile hits a target we weren't originally aiming at then retain the chance to miss
var/result = PROJECTILE_FORCE_MISS
diff --git a/icons/effects/projectiles.dmi b/icons/effects/projectiles.dmi
index 703d8f8c3d..5598cf6f84 100644
Binary files a/icons/effects/projectiles.dmi and b/icons/effects/projectiles.dmi differ
diff --git a/icons/obj/spells.dmi b/icons/obj/spells.dmi
index 256cd5f00b..d1062ef884 100644
Binary files a/icons/obj/spells.dmi and b/icons/obj/spells.dmi differ
diff --git a/icons/obj/technomancer.dmi b/icons/obj/technomancer.dmi
index 7fc48d0a75..668ee5f06c 100644
Binary files a/icons/obj/technomancer.dmi and b/icons/obj/technomancer.dmi differ
diff --git a/polaris.dme b/polaris.dme
index fe46804c7e..bf4d3b3eaf 100644
--- a/polaris.dme
+++ b/polaris.dme
@@ -356,18 +356,29 @@
#include "code\game\gamemodes\technomancer\spells\darkness.dm"
#include "code\game\gamemodes\technomancer\spells\discharge.dm"
#include "code\game\gamemodes\technomancer\spells\flame_tongue.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\oxygenate.dm"
#include "code\game\gamemodes\technomancer\spells\passwall.dm"
#include "code\game\gamemodes\technomancer\spells\phase_shift.dm"
#include "code\game\gamemodes\technomancer\spells\pulsar.dm"
#include "code\game\gamemodes\technomancer\spells\radiance.dm"
+#include "code\game\gamemodes\technomancer\spells\reflect.dm"
#include "code\game\gamemodes\technomancer\spells\resurrect.dm"
#include "code\game\gamemodes\technomancer\spells\shared_burden.dm"
#include "code\game\gamemodes\technomancer\spells\shield.dm"
#include "code\game\gamemodes\technomancer\spells\warp_strike.dm"
+#include "code\game\gamemodes\technomancer\spells\aspect\aspect.dm"
+#include "code\game\gamemodes\technomancer\spells\aspect\aspect_weapon.dm"
+#include "code\game\gamemodes\technomancer\spells\insert\corona.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_wounds.dm"
#include "code\game\gamemodes\technomancer\spells\insert\purify.dm"
+#include "code\game\gamemodes\technomancer\spells\insert\repel_missiles.dm"
+#include "code\game\gamemodes\technomancer\spells\projectile\chain_lightning.dm"
+#include "code\game\gamemodes\technomancer\spells\projectile\lightning.dm"
+#include "code\game\gamemodes\technomancer\spells\projectile\projectile.dm"
#include "code\game\gamemodes\traitor\traitor.dm"
#include "code\game\gamemodes\wizard\wizard.dm"
#include "code\game\jobs\_access_defs.dm"