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"