More work done!

This commit is contained in:
Neerti
2016-02-07 23:41:02 -05:00
parent be43fd1d9e
commit a67b544acd
47 changed files with 802 additions and 290 deletions
@@ -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."
@@ -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
+45 -20
View File
@@ -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 += "<a href='byond://?src=\ref[src];tab_choice=3'>Assistance</a> | "
dat += "<a href='byond://?src=\ref[src];tab_choice=4'>Presets</a></align><br>"
dat += "You currently have a budget of <b>[budget]/[max_budget]</b>.<br><br>"
for(var/datum/power/technomancer/spell in spell_instances)
dat += "<a href='byond://?src=\ref[src];refund_functions=1'>Refund Functions</a><br><br>"
for(var/datum/technomancer/spell in spell_instances)
if(spell.hidden)
continue
dat += "<b>[spell.name]</b><br>"
@@ -90,7 +92,6 @@ var/list/all_technomancer_presets = typesof(/datum/technomancer_equipment/preset
dat += "<a href='byond://?src=\ref[src];spell_choice=[spell.name]'>Purchase</a> ([spell.cost])<br><br>"
else
dat += "<font color='red'><b>Cannot afford!</b></font><br><br>"
dat += "<a href='byond://?src=\ref[src];refund_functions=1'>Refund Functions</a>"
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 += "<a href='byond://?src=\ref[src];tab_choice=3'>Assistance</a> | "
dat += "<a href='byond://?src=\ref[src];tab_choice=4'>Presets</a></align><br>"
dat += "You currently have a budget of <b>[budget]/[max_budget]</b>.<br><br>"
for(var/datum/technomancer_equipment/equipment/E in equipment_instances)
for(var/datum/technomancer/equipment/E in equipment_instances)
dat += "<b>[E.name]</b><br>"
dat += "<i>[E.desc]</i><br>"
if(E.cost <= budget)
@@ -120,7 +121,7 @@ var/list/all_technomancer_presets = typesof(/datum/technomancer_equipment/preset
dat += "<a href='byond://?src=\ref[src];tab_choice=3'>Assistance</a> | "
dat += "<a href='byond://?src=\ref[src];tab_choice=4'>Presets</a></align><br>"
dat += "You currently have a budget of <b>[budget]/[max_budget]</b>.<br><br>"
for(var/datum/technomancer_equipment/consumable/C in consumable_instances)
for(var/datum/technomancer/consumable/C in consumable_instances)
dat += "<b>[C.name]</b><br>"
dat += "<i>[C.desc]</i><br>"
if(C.cost <= budget)
@@ -138,7 +139,7 @@ var/list/all_technomancer_presets = typesof(/datum/technomancer_equipment/preset
dat += "<b>Assistance</b> | "
dat += "<a href='byond://?src=\ref[src];tab_choice=4'>Presets</a></align><br>"
dat += "You currently have a budget of <b>[budget]/[max_budget]</b>.<br><br>"
for(var/datum/technomancer_equipment/assistance/A in assistance_instances)
for(var/datum/technomancer/assistance/A in assistance_instances)
dat += "<b>[A.name]</b><br>"
dat += "<i>[A.desc]</i><br>"
if(A.cost <= budget)
@@ -156,7 +157,7 @@ var/list/all_technomancer_presets = typesof(/datum/technomancer_equipment/preset
dat += "<a href='byond://?src=\ref[src];tab_choice=3'>Assistance</a> | "
dat += "<b>Presets</b></align><br>"
dat += "You currently have a budget of <b>[budget]/[max_budget]</b>.<br><br>"
for(var/datum/technomancer_equipment/presets/P in preset_instances)
for(var/datum/technomancer/presets/P in preset_instances)
dat += "<b>[P.name]</b><br>"
dat += "<i>[P.desc]</i><br>"
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 << "<span class='notice'>You have just bought [new_spell.name].</span>"
else
if(!core.has_spell(new_spell))
budget -= new_spell.cost
H << "<span class='notice'>You have just bought [new_spell.name].</span>"
core.add_spell(new_spell.obj_path, new_spell.name)
else //We already own it.
H << "<span class='danger'>You already have [new_spell.name]!</span>"
return
else //Can't afford.
H << "<span class='danger'>You can't afford that!</span>"
return
if(href_list["refund_functions"])
if(H.z != 2)
H << "<span class='danger'>You can only refund at your base, it's too late now!</span>"
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)
+66 -1
View File
@@ -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()
@@ -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."
@@ -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
+11 -4
View File
@@ -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 \
+19 -141
View File
@@ -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 << "<span class='warning'>You require a free hand to use this function.</span>"
return 0
var/obj/item/weapon/spell/S = PoolOrNew(path, src)
if(S.run_checks())
put_in_hands(S)
return 1
@@ -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("<span class='danger'>\The [I] vanishes into thin air!</span>")
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
@@ -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 << "<span class='warning'>You cannot combine \the [spell] with \the [src], as the aspects are incompatable.</span>"
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)
@@ -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("<span class='danger'>\The [user] lands a devastating blow on \the [target]!</span>")
force = force * 2
attack(target, user)
force = initial(force)
user.adjust_instability(2)
@@ -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)
@@ -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)
@@ -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"
@@ -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)
@@ -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"
@@ -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)
@@ -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("<span class='danger'>\The [user] reaches out towards \the [L] with the flaming hand, and they ignite!</span>")
@@ -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("<span class='warning'>You start to glow very brightly!</span>")
spawn(1 MINUTE)
L.evasion += 2
L << "<span class='notice'>Your glow has ended.</span>"
qdel(src)
@@ -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 << "<span class='warning'>\The [L] is already affected by \the [src].</span>"
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)
@@ -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"
@@ -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"
@@ -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)
@@ -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 << "<span class='notice'>You have a repulsion field around you, which will attempt to deflect projectiles.</span>"
spawn(2 MINUTES)
L.evasion -= 2
L << "<span class='warning'>Your repulsion field has expired.</span>"
qdel(src)
@@ -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)
@@ -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 << "<span class='notice'>You mark \the [get_turf(user)] under you.</span>"
else
mark_spell_ref.forceMove(get_turf(user))
user << "<span class='notice'>Your mark is moved from its old position to \the [get_turf(user)] under you.</span>"
owner.adjust_instability(5)
return 1
else
user << "<span class='warning'>You can't afford the energy cost!</span>"
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 << "<span class='danger'>There's no Mark!</span>"
return 0
else
visible_message("<span class='warning'>\The [user] starts glowing!</span>")
var/light_intensity = 2
var/time_left = 3
while(time_left)
if(user.incapacitated())
visible_message("<span class='notice'>\The [user]'s glow fades.</span>")
user << "<span class='danger'>You cannot Recall while incapacitated!</span>"
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 << "<span class='notice'>You are teleported to your Mark.</span>"
owner.adjust_instability(25)
qdel(src)
return 1
else
user << "<span class='warning'>You can't afford the energy cost!</span>"
return 0
@@ -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)
@@ -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 << "<span class='warning'>You need to stand still in order to phase through the wall.</span>"
return 0
visible_message("<span class='warning'>[user] appears to phase through \the [T]!</span>")
user << "<span class='info'>You find a destination on the other side of \the [T], and phase through it.</span>"
spark_system.start()
user.forceMove(found_turf)
qdel(src)
return 1
if(pay_energy(total_cost) && !user.incapacitated() )
visible_message("<span class='warning'>[user] appears to phase through \the [T]!</span>")
user << "<span class='info'>You find a destination on the other side of \the [T], and phase through it.</span>"
spark_system.start()
user.forceMove(found_turf)
qdel(src)
return 1
else
user << "<span class='warning'>You don't have enough energy to phase through these walls!</span>"
busy = 0
else
user << "<span class='info'>You weren't able to find an open space to go to.</span>"
busy = 0
@@ -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"
@@ -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("<span class='danger'>\The [src] bounces to \the [new_target]!</span>")
redirect(new_target.x, new_target.y, curloc, firer)
bounces--
return 0
return 1
@@ -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
@@ -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)
@@ -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"
@@ -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"
@@ -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 << "<span class='notice'>Your shield will expire in 20 seconds.</span>"
spawn(20 SECONDS)
if(src)
owner << "<span class='danger'>Your shield expires!</span>"
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 << "<span class='danger'>Your shield fades due to lack of energy!</span>"
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("<span class='danger'>\The [user]'s [src.name] reflects [attack_text]!</span>")
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 << "<span class='danger'>Your shield fades due being used up!</span>"
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("<span class='danger'>\The [user]'s [src.name] reflects [attack_text]!</span>")
// 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
*/
@@ -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"
@@ -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"
@@ -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"
@@ -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"
@@ -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.
+1 -1
View File
@@ -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())
+12
View File
@@ -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"
+1 -1
View File
@@ -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
Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 560 B

After

Width:  |  Height:  |  Size: 910 B

+11
View File
@@ -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"