Merge pull request #3421 from Neerti/5/5/2017_technomancer_changes

More Technomancer
This commit is contained in:
Anewbe
2017-05-09 17:54:53 -05:00
committed by GitHub
36 changed files with 691 additions and 321 deletions

View File

@@ -98,8 +98,8 @@
/datum/technomancer/assistance/golem /datum/technomancer/assistance/golem
name = "Friendly GOLEM unit" 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 \ 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 \ functions. It knows Shield, Targeted Blink, Beam, Mend Life, Mend Synthetic, Lightning, Repel Missiles, Corona, Ionic Bolt, Dispel, and Chain Lightning. \
capacity for energy, and due to it's synthetic nature, instability is less of an issue for them." It also has a large storage capacity for energy, and due to it's synthetic nature, instability is less of an issue for them."
cost = 350 cost = 350
obj_path = null //TODO obj_path = null //TODO
one_use_only = 1 one_use_only = 1

View File

@@ -1,9 +1,9 @@
//An AI-controlled 'companion' for the Technomancer. It's tough, strong, and can also use spells. //An AI-controlled 'companion' for the Technomancer. It's tough, strong, and can also use spells.
/mob/living/simple_animal/hostile/technomancer_golem /mob/living/simple_animal/technomancer_golem
name = "G.O.L.E.M." name = "G.O.L.E.M."
desc = "A rather unusual looking synthetic." desc = "A rather unusual looking synthetic."
icon = 'icons/mob/robots.dmi' icon = 'icons/mob/mob.dmi'
icon_state = "Security" icon_state = "technomancer_golem"
health = 250 health = 250
maxHealth = 250 maxHealth = 250
stop_automated_movement = 1 stop_automated_movement = 1
@@ -27,46 +27,137 @@
unsuitable_atoms_damage = 0 unsuitable_atoms_damage = 0
speed = 0 speed = 0
melee_damage_lower = 10 melee_damage_lower = 30 // It has a built in esword.
melee_damage_upper = 10 melee_damage_upper = 30
attacktext = "pummeled" attacktext = "slashed"
attack_sound = null attack_sound = null
friendly = "hugs" friendly = "hugs"
resistance = 0 resistance = 0
var/obj/item/weapon/technomancer_core/core = null var/obj/item/weapon/technomancer_core/golem/core = null
var/obj/item/weapon/spell/active_spell = null var/obj/item/weapon/spell/active_spell = null // Shield and ranged spells
var/mob/living/master = null var/mob/living/master = null
/mob/living/simple_animal/hostile/technomancer_golem/New() var/list/known_spells = list(
..() "reflect" = /obj/item/weapon/spell/reflect,
core = new core(src) "shield" = /obj/item/weapon/spell/shield,
"dispel" = /obj/item/weapon/spell/dispel,
"mend life" = /obj/item/weapon/spell/modifier/mend_life,
"mend synthetic" = /obj/item/weapon/spell/modifier/mend_synthetic,
"repel missiles" = /obj/item/weapon/spell/modifier/repel_missiles,
"corona" = /obj/item/weapon/spell/modifier/corona,
"beam" = /obj/item/weapon/spell/projectile/beam,
"chain lightning" = /obj/item/weapon/spell/projectile/chain_lightning,
"force missile" = /obj/item/weapon/spell/projectile/force_missile,
"ionic bolt" = /obj/item/weapon/spell/projectile/ionic_bolt,
"lightning" = /obj/item/weapon/spell/projectile/lightning
)
/mob/living/simple_animal/hostile/technomancer_golem/Destroy() /mob/living/simple_animal/technomancer_golem/New()
..()
core = new(src)
update_icon()
/mob/living/simple_animal/technomancer_golem/Destroy()
qdel(core) qdel(core)
..() ..()
/mob/living/simple_animal/hostile/technomancer_golem/proc/bind_to_mob(mob/user) /mob/living/simple_animal/technomancer_golem/update_icon()
overlays.Cut()
overlays.Add(image(icon, src, "golem_sword"))
overlays.Add(image(icon, src, "golem_spell"))
/mob/living/simple_animal/technomancer_golem/isSynthetic()
return TRUE // So Mend Synthetic will work on them.
/mob/living/simple_animal/technomancer_golem/place_spell_in_hand(var/path)
if(!path || !ispath(path))
return 0
if(active_spell)
qdel(active_spell) // Get rid of our old spell.
var/obj/item/weapon/spell/S = new path(src)
active_spell = S
/mob/living/simple_animal/technomancer_golem/verb/test_giving_spells()
var/choice = input(usr, "What spell?", "Give spell") as null|anything in known_spells
if(choice)
place_spell_in_hand(known_spells[choice])
// Used to cast spells.
/mob/living/simple_animal/technomancer_golem/RangedAttack(var/atom/A, var/params)
if(active_spell)
if(active_spell.cast_methods & CAST_RANGED)
active_spell.on_ranged_cast(A, src)
/mob/living/simple_animal/technomancer_golem/UnarmedAttack(var/atom/A, var/proximity)
if(proximity)
if(active_spell)
if(active_spell.cast_methods & CAST_MELEE)
active_spell.on_melee_cast(A, src)
else if(active_spell.cast_methods & CAST_RANGED)
active_spell.on_ranged_cast(A, src)
var/effective_cooldown = round(active_spell.cooldown * core.cooldown_modifier, 5)
src.setClickCooldown(effective_cooldown)
else
..()
/mob/living/simple_animal/technomancer_golem/get_technomancer_core()
return core
/mob/living/simple_animal/technomancer_golem/proc/bind_to_mob(mob/user)
if(!user || master) if(!user || master)
return return
master = user master = user
name = "[master]'s [initial(name)]" name = "[master]'s [initial(name)]"
/mob/living/simple_animal/hostile/technomancer_golem/examine(mob/user) /mob/living/simple_animal/technomancer_golem/examine(mob/user)
..() ..()
if(user.mind && technomancers.is_antagonist(user.mind)) 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 \ 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..." yourself! It'll always stand by your side, ready to help you out. You have no idea what GOLEM stands for, however..."
/mob/living/simple_animal/hostile/technomancer_golem/Life() /mob/living/simple_animal/technomancer_golem/Life()
..()
handle_ai() handle_ai()
/mob/living/simple_animal/hostile/technomancer_golem/proc/handle_ai() // This is where the real spaghetti begins.
/mob/living/simple_animal/technomancer_golem/proc/handle_ai()
if(!master) if(!master)
return return
if(get_dist(src, master) > 6 || src.z != master.z) if(get_dist(src, master) > 6 || src.z != master.z)
recall_to_master() targeted_blink(master)
// Give our allies buffs and heals.
for(var/mob/living/L in view(src))
if(L in friends)
support_friend(L)
return
/mob/living/simple_animal/technomancer_golem/proc/support_friend(var/mob/living/L)
if(L.getBruteLoss() >= 10 || L.getFireLoss() >= 10)
if(L.isSynthetic() && !L.has_modifier_of_type(/datum/modifier/technomancer/mend_synthetic))
place_spell_in_hand(known_spells["mend synthetic"])
targeted_blink(L)
UnarmedAttack(L, 1)
else if(!L.has_modifier_of_type(/datum/modifier/technomancer/mend_life))
place_spell_in_hand(known_spells["mend life"])
targeted_blink(L)
UnarmedAttack(L, 1)
return
/mob/living/simple_animal/hostile/technomancer_golem/proc/recall_to_master() // Give them repel missiles if they lack it.
if(!L.has_modifier_of_type(/datum/modifier/technomancer/repel_missiles))
place_spell_in_hand(known_spells["repel missiles"])
RangedAttack(L)
return
/mob/living/simple_animal/technomancer_golem/proc/targeted_blink(var/atom/target)
var/datum/effect/effect/system/spark_spread/spark_system = PoolOrNew(/datum/effect/effect/system/spark_spread)
spark_system.set_up(5, 0, get_turf(src))
spark_system.start()
src.visible_message("<span class='notice'>\The [src] vanishes!</span>")
src.forceMove(get_turf(target))
return return

View File

@@ -330,6 +330,18 @@
spell_power_modifier = 1.75 spell_power_modifier = 1.75
energy_cost_modifier = 2.0 energy_cost_modifier = 2.0
// For use only for the GOLEM.
/obj/item/weapon/technomancer_core/golem
name = "integrated core"
desc = "A bewilderingly complex 'black box' that allows the wearer to accomplish amazing feats. This type is not meant \
to be worn on the back like other cores. Instead it is meant to be installed inside a synthetic shell. As a result, it's \
a lot more robust."
energy = 25000
max_energy = 25000
regen_rate = 100 //250 seconds to full
instability_modifier = 0.75
/obj/item/weapon/technomancer_core/verb/toggle_lock() /obj/item/weapon/technomancer_core/verb/toggle_lock()
set name = "Toggle Core Lock" set name = "Toggle Core Lock"
set category = "Object" set category = "Object"

View File

@@ -1,8 +1,8 @@
/datum/technomancer/equipment/tesla_armor /datum/technomancer/equipment/tesla_armor
name = "Tesla Armor" name = "Tesla Armor"
desc = "This piece of armor offers a retaliation-based defense. When the armor is 'ready', it will completely protect you from \ desc = "This piece of armor offers a retaliation-based defense. When the armor is 'ready', it will completely protect you from \
the next attack you suffer, and strike the attacker with a strong bolt of lightning. This effect requires twenty seconds to \ the next attack you suffer, and strike the attacker with a strong bolt of lightning, provided they are close enough. This effect requires \
recharge. If you are attacked while this is recharging, a weaker lightning bolt is sent out, however you won't be protected from \ fifteen seconds to recharge. If you are attacked while this is recharging, a weaker lightning bolt is sent out, however you won't be protected from \
the person beating you." the person beating you."
cost = 150 cost = 150
obj_path = /obj/item/clothing/suit/armor/tesla obj_path = /obj/item/clothing/suit/armor/tesla
@@ -10,23 +10,33 @@
/obj/item/clothing/suit/armor/tesla /obj/item/clothing/suit/armor/tesla
name = "tesla armor" name = "tesla armor"
desc = "This rather dangerous looking armor will hopefully shock your enemies, and not you in the process." desc = "This rather dangerous looking armor will hopefully shock your enemies, and not you in the process."
icon_state = "reactiveoff" //wip icon_state = "reactive" //wip
item_state = "reactiveoff" item_state = "reactive"
blood_overlay_type = "armor" blood_overlay_type = "armor"
slowdown = 1 slowdown = 1
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0) armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0)
var/ready = 1 //Determines if the next attack will be blocked, as well if a strong lightning bolt is sent out at the attacker. var/ready = 1 //Determines if the next attack will be blocked, as well if a strong lightning bolt is sent out at the attacker.
var/ready_icon_state = "reactive" //also wip var/ready_icon_state = "reactive" //also wip
var/cooldown_to_charge = 20 SECONDS var/normal_icon_state = "reactiveoff"
var/cooldown_to_charge = 15 SECONDS
/obj/item/clothing/suit/armor/tesla/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack") /obj/item/clothing/suit/armor/tesla/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
//First, some retaliation. //First, some retaliation.
if(attacker && attacker != user) if(istype(damage_source, /obj/item/projectile))
if(get_dist(user, attacker) <= 3) //Anyone farther away than three tiles is too far to shoot lightning at. var/obj/item/projectile/P = damage_source
if(P.firer && get_dist(user, P.firer) <= 3)
if(ready) if(ready)
shoot_lightning(attacker, 40) shoot_lightning(P.firer, 40)
else else
shoot_lightning(attacker, 15) shoot_lightning(P.firer, 15)
else
if(attacker && attacker != user)
if(get_dist(user, attacker) <= 3) //Anyone farther away than three tiles is too far to shoot lightning at.
if(ready)
shoot_lightning(attacker, 40)
else
shoot_lightning(attacker, 15)
//Deal with protecting our wearer now. //Deal with protecting our wearer now.
if(ready) if(ready)
@@ -45,10 +55,14 @@
if(ready) if(ready)
icon_state = ready_icon_state icon_state = ready_icon_state
else else
icon_state = initial(icon_state) icon_state = normal_icon_state
if(ishuman(loc))
var/mob/living/carbon/human/H = loc
H.update_inv_wear_suit(0)
/obj/item/clothing/suit/armor/tesla/proc/shoot_lightning(var/mob/target, var/power) /obj/item/clothing/suit/armor/tesla/proc/shoot_lightning(var/mob/target, var/power)
var/obj/item/projectile/beam/lightning/lightning = new(src) var/obj/item/projectile/beam/lightning/lightning = new(src)
lightning.power = power lightning.power = power
lightning.launch(target) lightning.launch(target)
visible_message("<span class='danger'>\The [src] strikes \the [target] with lightning!</span>") visible_message("<span class='danger'>\The [src] strikes \the [target] with lightning!</span>")
playsound(get_turf(src), 'sound/weapons/gauss_shoot.ogg', 75, 1)

View File

@@ -44,25 +44,25 @@
// Description: Makes instability decay. instability_effects() handles the bad effects for having instability. It will also hold back // Description: Makes instability decay. instability_effects() handles the bad effects for having instability. It will also hold back
// from causing bad effects more than one every ten seconds, to prevent sudden death from angry RNG. // from causing bad effects more than one every ten seconds, to prevent sudden death from angry RNG.
/mob/living/proc/handle_instability() /mob/living/proc/handle_instability()
instability = round(Clamp(instability, 0, 200)) instability = Ceiling(Clamp(instability, 0, 200))
//This should cushon against really bad luck. //This should cushon against really bad luck.
if(instability && last_instability_event < (world.time - 10 SECONDS) && prob(20)) if(instability && last_instability_event < (world.time - 10 SECONDS) && prob(20))
instability_effects() instability_effects()
switch(instability) switch(instability)
if(1 to 10) if(1 to 10)
adjust_instability(-2) adjust_instability(-1)
if(11 to 20) if(11 to 20)
adjust_instability(-4) adjust_instability(-2)
if(21 to 30) if(21 to 30)
adjust_instability(-6) adjust_instability(-3)
if(31 to 40) if(31 to 40)
adjust_instability(-8) adjust_instability(-4)
if(41 to 50) if(41 to 50)
adjust_instability(-10) adjust_instability(-5)
if(51 to 100) if(51 to 100)
adjust_instability(-20) adjust_instability(-10)
if(101 to 200) if(101 to 200)
adjust_instability(-40) adjust_instability(-20)
/mob/living/carbon/human/handle_instability() /mob/living/carbon/human/handle_instability()
..() ..()
@@ -277,12 +277,17 @@
// People next to the source take a third of the instability. Further distance decreases the amount absorbed. // People next to the source take a third of the instability. Further distance decreases the amount absorbed.
var/outgoing_instability = (instability / 3) * ( 1 / (radius**2) ) var/outgoing_instability = (instability / 3) * ( 1 / (radius**2) )
// Energy armor like from the AMI RIG can protect from this.
var/armor = getarmor(null, "energy") H.receive_radiated_instability(outgoing_instability)
var/armor_factor = abs( (armor - 100) / 100)
outgoing_instability = outgoing_instability * armor_factor
if(outgoing_instability)
to_chat(H, "<span class='warning'>The purple glow makes you feel strange...</span>")
H.adjust_instability(outgoing_instability)
set_light(distance, distance * 4, l_color = "#C26DDE") set_light(distance, distance * 4, l_color = "#C26DDE")
// This should only be used for EXTERNAL sources of instability, such as from someone or something glowing.
/mob/living/proc/receive_radiated_instability(amount)
// Energy armor like from the AMI RIG can protect from this.
var/armor = getarmor(null, "energy")
var/armor_factor = abs( (armor - 100) / 100)
amount = amount * armor_factor
if(amount && prob(10))
to_chat(src, "<span class='warning'>The purple glow makes you feel strange...</span>")
adjust_instability(amount)

View File

@@ -31,7 +31,8 @@
) )
throwforce = 0 throwforce = 0
force = 0 force = 0
var/mob/living/carbon/human/owner = null // var/mob/living/carbon/human/owner = null
var/mob/living/owner = null
var/obj/item/weapon/technomancer_core/core = null var/obj/item/weapon/technomancer_core/core = null
var/cast_methods = null // Controls how the spell is casted. var/cast_methods = null // Controls how the spell is casted.
var/aspect = null // Used for combining spells. var/aspect = null // Used for combining spells.
@@ -115,16 +116,33 @@
amount = round(amount * core.instability_modifier, 0.1) amount = round(amount * core.instability_modifier, 0.1)
owner.adjust_instability(amount) owner.adjust_instability(amount)
// Proc: get_technomancer_core()
// Parameters: 0
// Description: Returns the technomancer's core, assuming it is being worn properly.
/mob/living/proc/get_technomancer_core()
return null
/mob/living/carbon/human/get_technomancer_core()
var/obj/item/weapon/technomancer_core/core = back
if(istype(core))
return core
return null
// Proc: New() // Proc: New()
// Parameters: 0 // Parameters: 0
// Description: Sets owner to equal its loc, links to the owner's core, then applies overlays if needed. // Description: Sets owner to equal its loc, links to the owner's core, then applies overlays if needed.
/obj/item/weapon/spell/New() /obj/item/weapon/spell/New()
..() ..()
if(ishuman(loc)) if(isliving(loc))
owner = loc owner = loc
if(owner) if(owner)
if(istype(/obj/item/weapon/technomancer_core, owner.back)) core = owner.get_technomancer_core()
core = owner.back if(!core)
to_chat(owner, "<span class='warning'>You need a Core to do that.</span>")
qdel(src)
return
// if(istype(/obj/item/weapon/technomancer_core, owner.back))
// core = owner.back
update_icon() update_icon()
// Proc: Destroy() // Proc: Destroy()

View File

@@ -13,17 +13,18 @@
/obj/item/weapon/spell/aura/fire /obj/item/weapon/spell/aura/fire
name = "Fire Storm" name = "Fire Storm"
desc = "Things are starting to heat up." desc = "Things are starting to heat up."
icon_state = "generic" icon_state = "fire_bolt"
aspect = ASPECT_FIRE aspect = ASPECT_FIRE
glow_color = "#FF6A00" glow_color = "#FF6A00"
/obj/item/weapon/spell/aura/fire/process() /obj/item/weapon/spell/aura/fire/process()
if(!pay_energy(100)) if(!pay_energy(100))
qdel(src) qdel(src)
var/list/nearby_things = range(calculate_spell_power(4),owner) var/list/nearby_things = range(round(calculate_spell_power(4)),owner)
var/temp_change = calculate_spell_power(80) var/temp_change = calculate_spell_power(150)
var/temp_cap = calculate_spell_power(600) var/datum/species/baseline = all_species["Human"]
var/temp_cap = baseline.heat_level_3 * 2
var/fire_power = calculate_spell_power(2) var/fire_power = calculate_spell_power(2)
if(check_for_scepter()) if(check_for_scepter())
@@ -38,7 +39,8 @@
var/protection = H.get_heat_protection(1000) var/protection = H.get_heat_protection(1000)
if(protection < 1) if(protection < 1)
var/heat_factor = abs(protection - 1) var/heat_factor = abs(protection - 1)
H.bodytemperature = min( (H.bodytemperature + temp_change) * heat_factor, temp_cap) temp_change *= heat_factor
H.bodytemperature = min(H.bodytemperature + temp_change, temp_cap)
turf_check: turf_check:
for(var/turf/simulated/T in nearby_things) for(var/turf/simulated/T in nearby_things)

View File

@@ -2,7 +2,7 @@
name = "Chilling Aura" name = "Chilling Aura"
desc = "Lowers the core body temperature of everyone around you (except for your friends), causing them to become very slow if \ desc = "Lowers the core body temperature of everyone around you (except for your friends), causing them to become very slow if \
they stay within four meters of you." they stay within four meters of you."
enhancement_desc = "The chill becomes lethal." enhancement_desc = "Will make nearby entities even slower."
spell_power_desc = "Radius and rate of cooling are scaled." spell_power_desc = "Radius and rate of cooling are scaled."
cost = 100 cost = 100
obj_path = /obj/item/weapon/spell/aura/frost obj_path = /obj/item/weapon/spell/aura/frost
@@ -20,14 +20,16 @@
/obj/item/weapon/spell/aura/frost/process() /obj/item/weapon/spell/aura/frost/process()
if(!pay_energy(100)) if(!pay_energy(100))
qdel(src) qdel(src)
var/list/nearby_mobs = range(calculate_spell_power(4),owner) var/list/nearby_mobs = range(round(calculate_spell_power(4)),owner)
var/temp_change = calculate_spell_power(40) var/temp_change = calculate_spell_power(40)
var/temp_cap = 260 // Just above the damage threshold, for humans. Unathi are less fortunate. var/datum/species/baseline = all_species["Human"]
var/temp_cap = baseline.cold_level_2 - 5
if(check_for_scepter()) if(check_for_scepter())
temp_change *= 2 temp_change *= 2
temp_cap = 200 temp_cap = baseline.cold_level_3 - 5
for(var/mob/living/carbon/human/H in nearby_mobs) for(var/mob/living/carbon/human/H in nearby_mobs)
if(is_ally(H)) if(is_ally(H))
continue continue
@@ -35,6 +37,7 @@
var/protection = H.get_cold_protection(1000) var/protection = H.get_cold_protection(1000)
if(protection < 1) if(protection < 1)
var/cold_factor = abs(protection - 1) var/cold_factor = abs(protection - 1)
H.bodytemperature = max( (H.bodytemperature - temp_change) * cold_factor, temp_cap) temp_change *= cold_factor
H.bodytemperature = max(H.bodytemperature - temp_change, temp_cap)
adjust_instability(1) adjust_instability(1)

View File

@@ -18,9 +18,6 @@
/obj/item/weapon/spell/dispel/on_ranged_cast(atom/hit_atom, mob/living/user) /obj/item/weapon/spell/dispel/on_ranged_cast(atom/hit_atom, mob/living/user)
if(isliving(hit_atom) && within_range(hit_atom) && pay_energy(1000)) if(isliving(hit_atom) && within_range(hit_atom) && pay_energy(1000))
var/mob/living/target = hit_atom var/mob/living/target = hit_atom
for(var/obj/item/weapon/inserted_spell/I in target)
I.on_expire(dispelled = 1)
log_and_message_admins("dispelled [I] on [target].")
target.remove_modifiers_of_type(/datum/modifier/technomancer) target.remove_modifiers_of_type(/datum/modifier/technomancer)
user.adjust_instability(10) user.adjust_instability(10)
qdel(src) qdel(src)

View File

@@ -1,6 +1,9 @@
/datum/technomancer/spell/gambit /datum/technomancer/spell/gambit
name = "Gambit" name = "Gambit"
desc = "This function causes you to receive a random function, including those which you haven't purchased." desc = "This function causes you to receive a random function, including those which you haven't purchased."
// enhancement_desc = "Makes results less random and more biased towards what the function thinks you need in your current situation."
enhancement_desc = "Instead of a purely random spell, it will give you a \"random\" spell."
spell_power_desc = "Makes certain rare functions possible to acquire via Gambit which cannot be obtained otherwise, if above 100%."
ability_icon_state = "tech_gambit" ability_icon_state = "tech_gambit"
cost = 50 cost = 50
obj_path = /obj/item/weapon/spell/gambit obj_path = /obj/item/weapon/spell/gambit
@@ -11,9 +14,10 @@
/obj/item/weapon/spell/gambit, /obj/item/weapon/spell/gambit,
/obj/item/weapon/spell/projectile, /obj/item/weapon/spell/projectile,
/obj/item/weapon/spell/aura, /obj/item/weapon/spell/aura,
/obj/item/weapon/spell/insert, // /obj/item/weapon/spell/insert,
/obj/item/weapon/spell/spawner, /obj/item/weapon/spell/spawner,
/obj/item/weapon/spell/summon) /obj/item/weapon/spell/summon,
/obj/item/weapon/spell/modifier)
/obj/item/weapon/spell/gambit /obj/item/weapon/spell/gambit
name = "gambit" name = "gambit"
@@ -21,12 +25,110 @@
icon_state = "gambit" icon_state = "gambit"
cast_methods = CAST_USE cast_methods = CAST_USE
aspect = ASPECT_UNSTABLE aspect = ASPECT_UNSTABLE
var/list/rare_spells = list(
/obj/item/weapon/spell/modifier/mend_all
)
/obj/item/weapon/spell/gambit/on_use_cast(mob/living/carbon/human/user) /obj/item/weapon/spell/gambit/on_use_cast(mob/living/carbon/human/user)
if(pay_energy(200)) if(pay_energy(200))
adjust_instability(3) adjust_instability(3)
var/obj/item/weapon/spell/random_spell = pick(all_technomancer_gambit_spells) if(check_for_scepter())
if(random_spell) give_new_spell(biased_random_spell())
user.drop_from_inventory(src, null) else
user.place_spell_in_hand(random_spell) give_new_spell(random_spell())
qdel(src) qdel(src)
/obj/item/weapon/spell/gambit/proc/give_new_spell(var/spell_type)
owner.drop_from_inventory(src, null)
owner.place_spell_in_hand(spell_type)
// Gives a random spell.
/obj/item/weapon/spell/gambit/proc/random_spell()
var/list/potential_spells = all_technomancer_gambit_spells.Copy()
var/rare_spell_chance = between(0, calculate_spell_power(100) - 100, 100) // Having 120% spellpower means a 20% chance to get to roll for rare spells.
if(prob(rare_spell_chance))
potential_spells += rare_spells.Copy()
to_chat(owner, "<span class='notice'>You feel a bit luckier...</span>")
return pick(potential_spells)
// Gives a "random" spell.
/obj/item/weapon/spell/gambit/proc/biased_random_spell()
var/list/potential_spells = list()
var/rare_spell_chance = between(0, calculate_spell_power(100) - 100, 100)
var/give_rare_spells = FALSE
if(prob(rare_spell_chance))
give_rare_spells = TRUE
to_chat(owner, "<span class='notice'>You feel a bit luckier...</span>")
// First the spell will concern itself with the health of the technomancer.
if(prob(owner.getBruteLoss() + owner.getBruteLoss() * 2)) // Having 20 brute means a 40% chance of being added to the pool.
if(!owner.isSynthetic())
potential_spells |= /obj/item/weapon/spell/modifier/mend_life
else
potential_spells |= /obj/item/weapon/spell/modifier/mend_synthetic
if(give_rare_spells)
potential_spells |= /obj/item/weapon/spell/modifier/mend_all
// Second, the spell will try to prepare the technomancer for threats.
var/hostile_mobs = 0 // Counts how many hostile mobs. Higher numbers make it more likely for AoE spells to be chosen.
for(var/mob/living/L in view(owner))
// Spiders, carp... bears.
if(istype(L, /mob/living/simple_animal))
var/mob/living/simple_animal/SM = L
if(!is_ally(SM) && SM.hostile)
hostile_mobs++
if(SM.summoned || SM.supernatural) // Our creations might be trying to kill us.
potential_spells |= /obj/item/weapon/spell/abjuration
// Always assume borgs are hostile.
if(istype(L, /mob/living/silicon/robot))
if(!istype(L, /mob/living/silicon/robot/drone)) // Drones are okay, however.
hostile_mobs++
potential_spells |= /obj/item/weapon/spell/projectile/ionic_bolt
// Finally we get to humanoids.
if(istype(L, /mob/living/carbon/human))
var/mob/living/carbon/human/H = L
if(is_ally(H)) // Don't get scared by our apprentice.
continue
for(var/obj/item/I in list(H.l_hand, H.r_hand))
// Guns are scary.
if(istype(I, /obj/item/weapon/gun)) // Toy guns will count as well but oh well.
hostile_mobs++
continue
// Strong melee weapons are scary as well.
else if(I.force >= 15)
hostile_mobs++
continue
if(hostile_mobs)
potential_spells |= /obj/item/weapon/spell/shield
potential_spells |= /obj/item/weapon/spell/reflect
potential_spells |= /obj/item/weapon/spell/targeting_matrix
potential_spells |= /obj/item/weapon/spell/warp_strike
if(hostile_mobs >= 3) // Lots of baddies, give them AoE.
potential_spells |= /obj/item/weapon/spell/projectile/chain_lightning
potential_spells |= /obj/item/weapon/spell/projectile/chain_lightning/lesser
potential_spells |= /obj/item/weapon/spell/spawner/fire_blast
potential_spells |= /obj/item/weapon/spell/condensation
potential_spells |= /obj/item/weapon/spell/aura/frost
else
potential_spells |= /obj/item/weapon/spell/projectile/beam
potential_spells |= /obj/item/weapon/spell/projectile/overload
potential_spells |= /obj/item/weapon/spell/projectile/force_missile
potential_spells |= /obj/item/weapon/spell/projectile/lightning
// Third priority is recharging the core.
if(core.energy / core.max_energy <= 0.5)
potential_spells |= /obj/item/weapon/spell/energy_siphon
potential_spells |= /obj/item/weapon/spell/instability_tap
// Fallback method in case nothing gets added.
if(!potential_spells.len)
potential_spells = all_technomancer_gambit_spells.Copy()
return pick(potential_spells)

View File

@@ -1,30 +0,0 @@
/datum/technomancer/spell/mend_burns
name = "Mend Burns"
desc = "Heals minor burns, such as from exposure to flame, electric shock, or lasers."
spell_power_desc = "Healing amount increased."
cost = 50
obj_path = /obj/item/weapon/spell/insert/mend_burns
ability_icon_state = "tech_mendburns"
category = SUPPORT_SPELLS
/obj/item/weapon/spell/insert/mend_burns
name = "mend burns"
desc = "Ointment is a thing of the past."
icon_state = "mend_burns"
cast_methods = CAST_MELEE
aspect = ASPECT_BIOMED
light_color = "#FF5C5C"
inserting = /obj/item/weapon/inserted_spell/mend_burns
/obj/item/weapon/inserted_spell/mend_burns/on_insert()
spawn(1)
if(ishuman(host))
var/mob/living/carbon/human/H = host
var/heal_power = host == origin ? 10 : 30
heal_power = round(heal_power * spell_power_at_creation, 1)
origin.adjust_instability(10)
for(var/i = 0, i<5,i++)
if(H)
H.adjustFireLoss(-heal_power / 5)
sleep(1 SECOND)
on_expire()

View File

@@ -1,33 +0,0 @@
/datum/technomancer/spell/mend_metal
name = "Mend Metal"
desc = "Restores integrity to external robotic components."
spell_power_desc = "Healing amount increased."
cost = 50
obj_path = /obj/item/weapon/spell/insert/mend_metal
ability_icon_state = "tech_mendwounds"
category = SUPPORT_SPELLS
/obj/item/weapon/spell/insert/mend_metal
name = "mend metal"
desc = "A roboticist is now obsolete."
icon_state = "mend_wounds"
cast_methods = CAST_MELEE
aspect = ASPECT_BIOMED
light_color = "#FF5C5C"
inserting = /obj/item/weapon/inserted_spell/mend_metal
/obj/item/weapon/inserted_spell/mend_metal/on_insert()
spawn(1)
if(ishuman(host))
var/mob/living/carbon/human/H = host
var/heal_power = host == origin ? 10 : 30
heal_power = round(heal_power * spell_power_at_creation, 1)
origin.adjust_instability(10)
for(var/i = 0, i<5,i++)
if(H)
for(var/obj/item/organ/external/O in H.organs)
if(O.robotic < ORGAN_ROBOT) // Robot parts only.
continue
O.heal_damage(heal_power / 5, 0, internal = 1, robo_repair = 1)
sleep(1 SECOND)
on_expire()

View File

@@ -1,56 +0,0 @@
/datum/technomancer/spell/mend_organs
name = "Great Mend Wounds"
desc = "Greatly heals the target's wounds, both external and internal. Restores internal organs to functioning states, even if \
robotic, reforms bones, patches internal bleeding, and restores missing blood."
spell_power_desc = "Healing amount increased."
cost = 100
obj_path = /obj/item/weapon/spell/insert/mend_organs
ability_icon_state = "tech_mendwounds"
category = SUPPORT_SPELLS
/obj/item/weapon/spell/insert/mend_organs
name = "great mend wounds"
desc = "A walking medbay is now you!"
icon_state = "mend_wounds"
cast_methods = CAST_MELEE
aspect = ASPECT_BIOMED
light_color = "#FF5C5C"
inserting = /obj/item/weapon/inserted_spell/mend_organs
/obj/item/weapon/inserted_spell/mend_organs/on_insert()
spawn(1)
if(ishuman(host))
var/mob/living/carbon/human/H = host
var/heal_power = host == origin ? 2 : 5
heal_power = round(heal_power * spell_power_at_creation, 1)
origin.adjust_instability(15)
for(var/i = 0, i<5,i++)
if(H)
for(var/obj/item/organ/O in H.internal_organs)
if(O.damage > 0) // Fix internal damage
O.damage = max(O.damage - (heal_power / 5), 0)
if(O.damage <= 5 && O.organ_tag == O_EYES) // Fix eyes
H.sdisabilities &= ~BLIND
for(var/obj/item/organ/external/O in H.organs) // Fix limbs
if(!O.robotic < ORGAN_ROBOT) // No robot parts for this.
continue
O.heal_damage(0, heal_power / 5, internal = 1, robo_repair = 0)
for(var/obj/item/organ/E in H.bad_external_organs) // Fix bones
var/obj/item/organ/external/affected = E
if((affected.damage < affected.min_broken_damage * config.organ_health_multiplier) && (affected.status & ORGAN_BROKEN))
affected.status &= ~ORGAN_BROKEN
for(var/datum/wound/W in affected.wounds) // Fix IB
if(istype(W, /datum/wound/internal_bleeding))
affected.wounds -= W
affected.update_damages()
H.restore_blood() // Fix bloodloss
H.adjustBruteLoss(-heal_power)
sleep(1 SECOND)
on_expire()

View File

@@ -1,33 +0,0 @@
/datum/technomancer/spell/mend_wires
name = "Mend Wires"
desc = "Binds the internal wiring of robotic limbs and components over time."
spell_power_desc = "Healing amount increased."
cost = 50
obj_path = /obj/item/weapon/spell/insert/mend_wires
ability_icon_state = "tech_mendwounds"
category = SUPPORT_SPELLS
/obj/item/weapon/spell/insert/mend_wires
name = "mend wires"
desc = "A roboticist is now obsolete."
icon_state = "mend_wounds"
cast_methods = CAST_MELEE
aspect = ASPECT_BIOMED
light_color = "#FF5C5C"
inserting = /obj/item/weapon/inserted_spell/mend_wires
/obj/item/weapon/inserted_spell/mend_wires/on_insert()
spawn(1)
if(ishuman(host))
var/mob/living/carbon/human/H = host
var/heal_power = host == origin ? 10 : 30
heal_power = round(heal_power * spell_power_at_creation, 1)
origin.adjust_instability(10)
for(var/i = 0, i<5,i++)
if(H)
for(var/obj/item/organ/external/O in H.organs)
if(O.robotic < ORGAN_ROBOT) // Robot parts only.
continue
O.heal_damage(0, heal_power / 5, internal = 1, robo_repair = 1)
sleep(1 SECOND)
on_expire()

View File

@@ -1,31 +0,0 @@
/datum/technomancer/spell/mend_wounds
name = "Mend Wounds"
desc = "Heals minor wounds, such as cuts, bruises, and other non-lifethreatening injuries. \
Instability is split between the target and technomancer, if seperate."
spell_power_desc = "Healing amount increased."
cost = 50
obj_path = /obj/item/weapon/spell/insert/mend_wounds
ability_icon_state = "tech_mendwounds"
category = SUPPORT_SPELLS
/obj/item/weapon/spell/insert/mend_wounds
name = "mend wounds"
desc = "Watch your wounds close up before your eyes."
icon_state = "mend_wounds"
cast_methods = CAST_MELEE
aspect = ASPECT_BIOMED
light_color = "#FF5C5C"
inserting = /obj/item/weapon/inserted_spell/mend_wounds
/obj/item/weapon/inserted_spell/mend_wounds/on_insert()
spawn(1)
if(ishuman(host))
var/mob/living/carbon/human/H = host
var/heal_power = host == origin ? 10 : 30
heal_power = round(heal_power * spell_power_at_creation, 1)
origin.adjust_instability(10)
for(var/i = 0, i<5,i++)
if(H)
H.adjustBruteLoss(-heal_power / 5)
sleep(1 SECOND)
on_expire()

View File

@@ -1,49 +0,0 @@
/datum/technomancer/spell/purify
name = "Purify"
desc = "Clenses the body of harmful impurities, such as toxins, radiation, viruses, genetic damage, and such."
spell_power_desc = "Healing amount increased."
cost = 25
obj_path = /obj/item/weapon/spell/insert/purify
ability_icon_state = "tech_purify"
category = SUPPORT_SPELLS
/obj/item/weapon/spell/insert/purify
name = "purify"
desc = "Illness and toxins will be no more."
icon_state = "purify"
cast_methods = CAST_MELEE
aspect = ASPECT_BIOMED
light_color = "#03A728"
inserting = /obj/item/weapon/inserted_spell/purify
/obj/item/weapon/inserted_spell/purify/on_insert()
spawn(1)
if(ishuman(host))
var/mob/living/carbon/human/H = host
H.sdisabilities = 0
H.disabilities = 0
// for(var/datum/disease/D in H.viruses)
// D.cure()
var/heal_power = host == origin ? 10 : 30
heal_power = round(heal_power * spell_power_at_creation, 1)
origin.adjust_instability(10)
for(var/i = 0, i<5,i++)
if(H)
H.adjustToxLoss(-heal_power / 5)
H.adjustCloneLoss(-heal_power / 5)
H.radiation = max(host.radiation - ( (heal_power * 2) / 5), 0)
for(var/obj/item/organ/external/E in H.organs)
var/obj/item/organ/external/G = E
if(G.germ_level)
var/germ_heal = heal_power * 10
G.germ_level = min(0, G.germ_level - germ_heal)
for(var/obj/item/organ/internal/I in H.internal_organs)
var/obj/item/organ/internal/G = I
if(G.germ_level)
var/germ_heal = heal_power * 10
G.germ_level = min(0, G.germ_level - germ_heal)
sleep(1 SECOND)
on_expire()

View File

@@ -1,8 +1,8 @@
/datum/technomancer/spell/instability_tap /datum/technomancer/spell/instability_tap
name = "Instability Tap" name = "Instability Tap"
desc = "Creates a large sum of energy, at the cost of a very large amount of instability afflicting you." desc = "Creates a large sum of energy (5,000 at normal spell power), at the cost of a very large amount of instability afflicting you."
enhancement_desc = "50% more energy gained, 20% less instability gained." enhancement_desc = "50% more energy gained, 20% less instability gained."
spell_power_desc = "Amount of energy gained scaled up with spell power." spell_power_desc = "Amount of energy gained scaled with spell power."
cost = 100 cost = 100
obj_path = /obj/item/weapon/spell/instability_tap obj_path = /obj/item/weapon/spell/instability_tap
ability_icon_state = "tech_instabilitytap" ability_icon_state = "tech_instabilitytap"
@@ -26,4 +26,5 @@
else else
core.give_energy(amount) core.give_energy(amount)
adjust_instability(50) adjust_instability(50)
playsound(get_turf(src), 'sound/effects/supermatter.ogg', 75, 1)
qdel(src) qdel(src)

View File

@@ -0,0 +1,56 @@
/datum/technomancer/spell/mend_organs
name = "Mend Internals"
desc = "Greatly heals the target's wounds, both external and internal. Restores internal organs to functioning states, even if \
robotic, reforms bones, patches internal bleeding, and restores missing blood."
spell_power_desc = "Healing amount increased."
cost = 100
obj_path = /obj/item/weapon/spell/mend_organs
ability_icon_state = "tech_mendwounds"
category = SUPPORT_SPELLS
/obj/item/weapon/spell/mend_organs
name = "great mend wounds"
desc = "A walking medbay is now you!"
icon_state = "mend_wounds"
cast_methods = CAST_MELEE
aspect = ASPECT_BIOMED
light_color = "#FF5C5C"
/obj/item/weapon/spell/mend_organs/on_melee_cast(atom/hit_atom, mob/living/user, def_zone)
if(isliving(hit_atom))
var/mob/living/L = hit_atom
var/heal_power = calculate_spell_power(40)
L.adjustBruteLoss(-heal_power)
L.adjustFireLoss(-heal_power)
user.adjust_instability(5)
L.adjust_instability(5)
if(ishuman(hit_atom))
var/mob/living/carbon/human/H = hit_atom
user.adjust_instability(5)
L.adjust_instability(5)
for(var/obj/item/organ/O in H.internal_organs)
if(O.damage > 0) // Fix internal damage
O.damage = max(O.damage - (heal_power / 2), 0)
if(O.damage <= 5 && O.organ_tag == O_EYES) // Fix eyes
H.sdisabilities &= ~BLIND
for(var/obj/item/organ/external/O in H.organs) // Fix limbs
if(!O.robotic < ORGAN_ROBOT) // No robot parts for this.
continue
O.heal_damage(0, heal_power / 4, internal = 1, robo_repair = 0)
for(var/obj/item/organ/E in H.bad_external_organs) // Fix bones
var/obj/item/organ/external/affected = E
if((affected.damage < affected.min_broken_damage * config.organ_health_multiplier) && (affected.status & ORGAN_BROKEN))
affected.status &= ~ORGAN_BROKEN
for(var/datum/wound/W in affected.wounds) // Fix IB
if(istype(W, /datum/wound/internal_bleeding))
affected.wounds -= W
affected.update_damages()
H.restore_blood() // Fix bloodloss
qdel(src)

View File

@@ -0,0 +1,35 @@
// Gambit only spell. Heals everything unconditionally.
/obj/item/weapon/spell/modifier/mend_all
name = "mend all"
desc = "One function to heal them all."
icon_state = "mend_all"
cast_methods = CAST_MELEE
aspect = ASPECT_BIOMED
light_color = "#FF5C5C"
modifier_type = /datum/modifier/technomancer/mend_life
modifier_duration = 1 MINUTE
/datum/modifier/technomancer/mend_all
name = "mend all"
desc = "You feel serene and well rested."
mob_overlay_state = "green_sparkles"
on_created_text = "<span class='warning'>Sparkles begin to appear around you, and all your ills seem to fade away.</span>"
on_expired_text = "<span class='notice'>The sparkles have faded, although you feel much healthier than before.</span>"
stacks = MODIFIER_STACK_EXTEND
/datum/modifier/technomancer/mend_all/tick()
if(!holder.getBruteLoss() && !holder.getFireLoss() && !holder.getToxLoss() && !holder.getOxyLoss() && !holder.getCloneLoss()) // No point existing if the spell can't heal.
expire()
return
holder.adjustBruteLoss(-4 * spell_power) // Should heal roughly 120 damage over 1 minute, as tick() is run every 2 seconds.
holder.adjustFireLoss(-4 * spell_power)
holder.adjustToxLoss(-4 * spell_power)
holder.adjustOxyLoss(-4 * spell_power)
holder.adjustCloneLoss(-2 * spell_power) // 60 cloneloss
holder.adjust_instability(1)
if(origin)
var/mob/living/L = origin.resolve()
if(istype(L))
L.adjust_instability(1)

View File

@@ -0,0 +1,44 @@
/datum/technomancer/spell/mend_life
name = "Mend Life"
desc = "Heals minor wounds, such as cuts, bruises, burns, and other non-lifethreatening injuries. \
Instability is split between the target and technomancer, if seperate. The function will end prematurely \
if the target is completely healthy, preventing further instability."
spell_power_desc = "Healing amount increased."
cost = 50
obj_path = /obj/item/weapon/spell/modifier/mend_life
ability_icon_state = "tech_mendwounds"
category = SUPPORT_SPELLS
/obj/item/weapon/spell/modifier/mend_life
name = "mend life"
desc = "Watch your wounds close up before your eyes."
icon_state = "mend_life"
cast_methods = CAST_MELEE
aspect = ASPECT_BIOMED
light_color = "#FF5C5C"
modifier_type = /datum/modifier/technomancer/mend_life
modifier_duration = 10 SECONDS
/datum/modifier/technomancer/mend_life
name = "mend life"
desc = "You feel rather refreshed."
mob_overlay_state = "green_sparkles"
on_created_text = "<span class='warning'>Sparkles begin to appear around you, and you feel really.. refreshed.</span>"
on_expired_text = "<span class='notice'>The sparkles have faded, although you feel healthier than before.</span>"
stacks = MODIFIER_STACK_EXTEND
/datum/modifier/technomancer/mend_life/tick()
if(holder.isSynthetic()) // Don't heal synths!
expire()
return
if(!holder.getBruteLoss() && !holder.getFireLoss()) // No point existing if the spell can't heal.
expire()
return
holder.adjustBruteLoss(-4 * spell_power) // Should heal roughly 20 burn/brute over 10 seconds, as tick() is run every 2 seconds.
holder.adjustFireLoss(-4 * spell_power) // Ditto.
holder.adjust_instability(1)
if(origin)
var/mob/living/L = origin.resolve()
if(istype(L))
L.adjust_instability(1)

View File

@@ -0,0 +1,44 @@
/datum/technomancer/spell/mend_synthetic
name = "Mend Synthetic"
desc = "Repairs minor damages to robotic entities. \
Instability is split between the target and technomancer, if seperate. The function will end prematurely \
if the target is completely healthy, preventing further instability."
spell_power_desc = "Healing amount increased."
cost = 50
obj_path = /obj/item/weapon/spell/modifier/mend_synthetic
ability_icon_state = "tech_mendwounds"
category = SUPPORT_SPELLS
/obj/item/weapon/spell/modifier/mend_synthetic
name = "mend synthetic"
desc = "You are the Robotics lab"
icon_state = "mend_synthetic"
cast_methods = CAST_MELEE
aspect = ASPECT_BIOMED // sorta??
light_color = "#FF5C5C"
modifier_type = /datum/modifier/technomancer/mend_synthetic
modifier_duration = 10 SECONDS
/datum/modifier/technomancer/mend_synthetic
name = "mend synthetic"
desc = "Something seems to be repairing you."
mob_overlay_state = "cyan_sparkles"
on_created_text = "<span class='warning'>Sparkles begin to appear around you, and your systems report integrity rising.</span>"
on_expired_text = "<span class='notice'>The sparkles have faded, although your systems seem to be better than before.</span>"
stacks = MODIFIER_STACK_EXTEND
/datum/modifier/technomancer/mend_synthetic/tick()
if(!holder.isSynthetic()) // Don't heal biologicals!
expire()
return
if(!holder.getBruteLoss() && !holder.getFireLoss()) // No point existing if the spell can't heal.
expire()
return
holder.adjustBruteLoss(-4 * spell_power) // Should heal roughly 20 burn/brute over 10 seconds, as tick() is run every 2 seconds.
holder.adjustFireLoss(-4 * spell_power) // Ditto.
holder.adjust_instability(1)
if(origin)
var/mob/living/L = origin.resolve()
if(istype(L))
L.adjust_instability(1)

View File

@@ -26,6 +26,13 @@
var/duration = modifier_duration var/duration = modifier_duration
if(duration) if(duration)
duration = round(duration * calculate_spell_power(1.0), 1) duration = round(duration * calculate_spell_power(1.0), 1)
L.add_modifier(modifier_type, duration) var/datum/modifier/M = L.add_modifier(modifier_type, duration, owner)
if(istype(M, /datum/modifier/technomancer))
var/datum/modifier/technomancer/MT = M
MT.spell_power = calculate_spell_power(1)
log_and_message_admins("has casted [src] on [L].") log_and_message_admins("has casted [src] on [L].")
qdel(src) qdel(src)
// Technomancer specific subtype which keeps track of spell power and gets targeted specificially by Dispel.
/datum/modifier/technomancer
var/spell_power = null // Set by on_add_modifier.

View File

@@ -0,0 +1,40 @@
/datum/technomancer/spell/purify
name = "Purify"
desc = "Clenses the body of harmful impurities, such as toxins, radiation, viruses, genetic damage, and such. \
Instability is split between the target and technomancer, if seperate. The function will end prematurely \
if the target is completely healthy, preventing further instability."
spell_power_desc = "Healing amount increased."
cost = 25
obj_path = /obj/item/weapon/spell/modifier/purify
ability_icon_state = "tech_purify"
category = SUPPORT_SPELLS
/obj/item/weapon/spell/modifier/purify
name = "mend life"
desc = "Watch your wounds close up before your eyes."
icon_state = "mend_life"
cast_methods = CAST_MELEE
aspect = ASPECT_BIOMED
light_color = "#FF5C5C"
modifier_type = /datum/modifier/technomancer/purify
modifier_duration = 10 SECONDS
/datum/modifier/technomancer/purify
name = "purify"
desc = "You feel rather clean and pure."
mob_overlay_state = "green_sparkles"
on_created_text = "<span class='warning'>Sparkles begin to appear around you, and you feel really.. pure.</span>"
on_expired_text = "<span class='notice'>The sparkles have faded, although you feel healthier than before.</span>"
stacks = MODIFIER_STACK_EXTEND
/datum/modifier/technomancer/purify/tick()
if(!holder.getToxLoss()) // No point existing if the spell can't heal.
expire()
return
holder.adjustToxLoss(-4 * spell_power) // Should heal roughly 120 damage over 1 minute, as tick() is run every 2 seconds.
holder.adjust_instability(1)
if(origin)
var/mob/living/L = origin.resolve()
if(istype(L))
L.adjust_instability(1)

View File

@@ -1,6 +1,6 @@
/datum/technomancer/spell/repel_missiles /datum/technomancer/spell/repel_missiles
name = "Repel Missiles" name = "Repel Missiles"
desc = "Places a repulsion field around you, which attempts to deflect incoming bullets and lasers, making them 30% less likely \ desc = "Places a repulsion field around you, which attempts to deflect incoming bullets and lasers, making them 45% less likely \
to hit you. The field lasts for 10 minutes and can be granted to yourself or an ally." to hit you. The field lasts for 10 minutes and can be granted to yourself or an ally."
cost = 25 cost = 25
obj_path = /obj/item/weapon/spell/modifier/repel_missiles obj_path = /obj/item/weapon/spell/modifier/repel_missiles

View File

@@ -2,7 +2,7 @@
name = "Oxygenate" name = "Oxygenate"
desc = "This function creates oxygen at a location of your chosing. If used on a humanoid entity, it heals oxygen deprivation. \ 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." If casted on the envirnment, air (oxygen and nitrogen) is moved from a distant location to your target."
cost = 50 cost = 25
obj_path = /obj/item/weapon/spell/oxygenate obj_path = /obj/item/weapon/spell/oxygenate
ability_icon_state = "oxygenate" ability_icon_state = "oxygenate"
category = SUPPORT_SPELLS category = SUPPORT_SPELLS

View File

@@ -32,7 +32,7 @@
var/bounces = 3 //How many times it 'chains'. Note that the first hit is not counted as it counts /bounces/. var/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/list/hit_mobs = list() //Mobs which were already hit.
var/power = 20 //How hard it will hit for with electrocute_act(), decreases with each bounce. var/power = 35 //How hard it will hit for with electrocute_act(), decreases with each bounce.
/obj/item/projectile/beam/chain_lightning/attack_mob(var/mob/living/target_mob, var/distance, var/miss_modifier=0) /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. //First we shock the guy we just hit.

View File

@@ -2,7 +2,7 @@
name = "Ionic Bolt" name = "Ionic Bolt"
desc = "Shoots a bolt of ion energy at the target. If it hits something, it will generally drain energy, corrupt electronics, \ desc = "Shoots a bolt of ion energy at the target. If it hits something, it will generally drain energy, corrupt electronics, \
or otherwise ruin complex machinery." or otherwise ruin complex machinery."
cost = 100 cost = 50
obj_path = /obj/item/weapon/spell/projectile/ionic_bolt obj_path = /obj/item/weapon/spell/projectile/ionic_bolt
category = OFFENSIVE_SPELLS category = OFFENSIVE_SPELLS

View File

@@ -0,0 +1,23 @@
/datum/technomancer/spell/lesser_chain_lightning
name = "Lesser Chain Lightning"
desc = "This is very similar to the function Chain Lightning, however it is considerably less powerful. As a result, it's a lot \
more economical in terms of energy cost, as well as instability generation. Lightning functions cannot miss due to distance."
cost = 100
obj_path = /obj/item/weapon/spell/projectile/chain_lightning/lesser
ability_icon_state = "tech_chain_lightning"
category = OFFENSIVE_SPELLS
/obj/item/weapon/spell/projectile/chain_lightning/lesser
name = "lesser chain lightning"
icon_state = "chain_lightning"
desc = "Now you can throw around lightning like it's nobody's business."
cast_methods = CAST_RANGED
aspect = ASPECT_SHOCK
spell_projectile = /obj/item/projectile/beam/chain_lightning
energy_cost_per_shot = 1000
instability_per_shot = 5
cooldown = 10
/obj/item/projectile/beam/chain_lightning/lesser
bounces = 2
power = 20

View File

@@ -37,8 +37,10 @@
if(issmall(user)) // Smaller shields are more efficent. if(issmall(user)) // Smaller shields are more efficent.
damage_to_energy_cost *= 0.75 damage_to_energy_cost *= 0.75
if(istype(owner.get_other_hand(src), src.type)) // Two shields in both hands. if(ishuman(owner))
damage_to_energy_cost *= 0.75 var/mob/living/carbon/human/H = owner
if(istype(H.get_other_hand(src), src.type)) // Two shields in both hands.
damage_to_energy_cost *= 0.75
else if(check_for_scepter()) else if(check_for_scepter())
damage_to_energy_cost *= 0.50 damage_to_energy_cost *= 0.50

View File

@@ -0,0 +1,53 @@
/datum/technomancer/spell/destablize
name = "Destablize"
desc = "Creates an unstable disturbance at the targeted tile, which will afflict anyone nearby with instability who remains nearby. This can affect you \
and your allies as well. The disturbance lasts for twenty seconds."
cost = 100
obj_path = /obj/item/weapon/spell/spawner/destablize
category = OFFENSIVE_SPELLS
/obj/item/weapon/spell/spawner/destablize
name = "destablize"
desc = "Now your enemies can feel what you go through when you have too much fun."
icon_state = "destablize"
cast_methods = CAST_RANGED
aspect = ASPECT_UNSTABLE
spawner_type = /obj/effect/temporary_effect/destablize
/obj/item/weapon/spell/spawner/destablize/New()
..()
set_light(3, 2, l_color = "#C26DDE")
/obj/item/weapon/spell/spawner/destablize/on_ranged_cast(atom/hit_atom, mob/user)
if(within_range(hit_atom) && pay_energy(2000))
adjust_instability(15)
..()
/obj/effect/temporary_effect/destablize
name = "destablizing disturbance"
desc = "This can't be good..."
icon = 'icons/effects/effects.dmi'
icon_state = "blueshatter"
time_to_die = null
invisibility = 0
new_light_range = 6
new_light_power = 20
new_light_color = "#C26DDE"
var/pulses_remaining = 40 // Lasts 20 seconds.
var/instability_power = 5
var/instability_range = 6
/obj/effect/temporary_effect/destablize/New()
..()
radiate_loop()
/obj/effect/temporary_effect/destablize/proc/radiate_loop()
while(pulses_remaining)
sleep(5)
for(var/mob/living/L in range(src, instability_range) )
var/radius = max(get_dist(L, src), 1)
// Being farther away lessens the amount of instabity received.
var/outgoing_instability = instability_power * ( 1 / (radius**2) )
L.receive_radiated_instability(outgoing_instability)
pulses_remaining--
qdel(src)

View File

@@ -7,6 +7,7 @@
var/desc = null // Ditto. var/desc = null // Ditto.
var/icon_state = null // See above. var/icon_state = null // See above.
var/mob/living/holder = null // The mob that this datum is affecting. var/mob/living/holder = null // The mob that this datum is affecting.
var/weakref/origin = null // A weak reference to whatever caused the modifier to appear. THIS NEEDS TO BE A MOB/LIVING. It's a weakref to not interfere with qdel().
var/expire_at = null // world.time when holder's Life() will remove the datum. If null, it lasts forever or until it gets deleted by something else. var/expire_at = null // world.time when holder's Life() will remove the datum. If null, it lasts forever or until it gets deleted by something else.
var/on_created_text = null // Text to show to holder upon being created. var/on_created_text = null // Text to show to holder upon being created.
var/on_expired_text = null // Text to show to holder when it expires. var/on_expired_text = null // Text to show to holder when it expires.
@@ -37,8 +38,12 @@
var/haste // If set to 1, the mob will be 'hasted', which makes it ignore slowdown and go really fast. var/haste // If set to 1, the mob will be 'hasted', which makes it ignore slowdown and go really fast.
var/evasion // Positive numbers reduce the odds of being hit by 15% each. Negative numbers increase the odds. var/evasion // Positive numbers reduce the odds of being hit by 15% each. Negative numbers increase the odds.
/datum/modifier/New(var/new_holder) /datum/modifier/New(var/new_holder, var/new_origin)
holder = new_holder holder = new_holder
if(new_origin)
origin = weakref(new_origin)
else // We assume the holder caused the modifier if not told otherwise.
origin = weakref(holder)
..() ..()
// Checks to see if this datum should continue existing. // Checks to see if this datum should continue existing.
@@ -82,8 +87,9 @@
M.tick() M.tick()
// Call this to add a modifier to a mob. First argument is the modifier type you want, second is how long it should last, in ticks. // Call this to add a modifier to a mob. First argument is the modifier type you want, second is how long it should last, in ticks.
// Third argument is the 'source' of the modifier, if it's from someone else. If null, it will default to the mob being applied to.
// The SECONDS/MINUTES macro is very helpful for this. E.g. M.add_modifier(/datum/modifier/example, 5 MINUTES) // The SECONDS/MINUTES macro is very helpful for this. E.g. M.add_modifier(/datum/modifier/example, 5 MINUTES)
/mob/living/proc/add_modifier(var/modifier_type, var/expire_at = null) /mob/living/proc/add_modifier(var/modifier_type, var/expire_at = null, var/mob/living/origin = null)
// First, check if the mob already has this modifier. // First, check if the mob already has this modifier.
for(var/datum/modifier/M in modifiers) for(var/datum/modifier/M in modifiers)
if(istype(modifier_type, M)) if(istype(modifier_type, M))
@@ -99,7 +105,7 @@
return return
// If we're at this point, the mob doesn't already have it, or it does but stacking is allowed. // If we're at this point, the mob doesn't already have it, or it does but stacking is allowed.
var/datum/modifier/mod = new modifier_type(src) var/datum/modifier/mod = new modifier_type(src, origin)
if(expire_at) if(expire_at)
mod.expire_at = world.time + expire_at mod.expire_at = world.time + expire_at
if(mod.on_created_text) if(mod.on_created_text)
@@ -108,6 +114,8 @@
if(mod.mob_overlay_state) if(mod.mob_overlay_state)
update_modifier_visuals() update_modifier_visuals()
return mod
// Removes a specific instance of modifier // Removes a specific instance of modifier
/mob/living/proc/remove_specific_modifier(var/datum/modifier/M, var/silent = FALSE) /mob/living/proc/remove_specific_modifier(var/datum/modifier/M, var/silent = FALSE)
M.expire(silent) M.expire(silent)

View File

@@ -0,0 +1,44 @@
################################
# Example Changelog File
#
# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
#
# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
# When it is, any changes listed below will disappear.
#
# Valid Prefixes:
# bugfix
# wip (For works in progress)
# tweak
# soundadd
# sounddel
# rscadd (general adding of nice things)
# rscdel (general deleting of nice things)
# imageadd
# imagedel
# maptweak
# spellcheck (typo fixes)
# experiment
#################################
# Your name.
author: Neerti
# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
delete-after: True
# Any changes you've made. See valid prefix list above.
# INDENT WITH TWO SPACES. NOT TABS. SPACES.
# SCREW THIS UP AND IT WON'T WORK.
# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
changes:
- tweak: "Tesla armor now retaliates against ranged attacks if within 3 tiles, and recharges in 15 seconds, from 20."
- tweak: "Technomancer Instability fades away slower."
- tweak: "Fire and frost auras made more potent."
- rscadd: "Gambit can now give rare spells unobtainable by other means, based on spell power."
- tweak: "Mend Wounds and Mend Burns combined into Mend Life. Mend Metal and Mend Wires combined into Mend Synthetic."
- rscadd: "Adds Lesser Chain Lightning, a more spammable version, but weaker."
- rscadd: "Adds Destabilize, which makes an area glow with instability for 20 seconds."
- rscadd: "Adds Ionic Bolt, which ruins the lives of synthetics."
- tweak: "Oxygenate made cheaper."

Binary file not shown.

Before

Width:  |  Height:  |  Size: 194 KiB

After

Width:  |  Height:  |  Size: 198 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

@@ -454,6 +454,7 @@
#include "code\game\gamemodes\technomancer\spells\illusion.dm" #include "code\game\gamemodes\technomancer\spells\illusion.dm"
#include "code\game\gamemodes\technomancer\spells\instability_tap.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\mark_recall.dm"
#include "code\game\gamemodes\technomancer\spells\mend_organs.dm"
#include "code\game\gamemodes\technomancer\spells\oxygenate.dm" #include "code\game\gamemodes\technomancer\spells\oxygenate.dm"
#include "code\game\gamemodes\technomancer\spells\passwall.dm" #include "code\game\gamemodes\technomancer\spells\passwall.dm"
#include "code\game\gamemodes\technomancer\spells\phase_shift.dm" #include "code\game\gamemodes\technomancer\spells\phase_shift.dm"
@@ -471,24 +472,24 @@
#include "code\game\gamemodes\technomancer\spells\aura\frost_aura.dm" #include "code\game\gamemodes\technomancer\spells\aura\frost_aura.dm"
#include "code\game\gamemodes\technomancer\spells\aura\shock_aura.dm" #include "code\game\gamemodes\technomancer\spells\aura\shock_aura.dm"
#include "code\game\gamemodes\technomancer\spells\aura\unstable_aura.dm" #include "code\game\gamemodes\technomancer\spells\aura\unstable_aura.dm"
#include "code\game\gamemodes\technomancer\spells\insert\insert.dm"
#include "code\game\gamemodes\technomancer\spells\insert\mend_burns.dm"
#include "code\game\gamemodes\technomancer\spells\insert\mend_metal.dm"
#include "code\game\gamemodes\technomancer\spells\insert\mend_organs.dm"
#include "code\game\gamemodes\technomancer\spells\insert\mend_wires.dm"
#include "code\game\gamemodes\technomancer\spells\insert\mend_wounds.dm"
#include "code\game\gamemodes\technomancer\spells\insert\purify.dm"
#include "code\game\gamemodes\technomancer\spells\modifier\corona.dm" #include "code\game\gamemodes\technomancer\spells\modifier\corona.dm"
#include "code\game\gamemodes\technomancer\spells\modifier\haste.dm" #include "code\game\gamemodes\technomancer\spells\modifier\haste.dm"
#include "code\game\gamemodes\technomancer\spells\modifier\mend_all.dm"
#include "code\game\gamemodes\technomancer\spells\modifier\mend_life.dm"
#include "code\game\gamemodes\technomancer\spells\modifier\mend_synthetic.dm"
#include "code\game\gamemodes\technomancer\spells\modifier\modifier.dm" #include "code\game\gamemodes\technomancer\spells\modifier\modifier.dm"
#include "code\game\gamemodes\technomancer\spells\modifier\purify.dm"
#include "code\game\gamemodes\technomancer\spells\modifier\repel_missiles.dm" #include "code\game\gamemodes\technomancer\spells\modifier\repel_missiles.dm"
#include "code\game\gamemodes\technomancer\spells\projectile\beam.dm" #include "code\game\gamemodes\technomancer\spells\projectile\beam.dm"
#include "code\game\gamemodes\technomancer\spells\projectile\chain_lightning.dm" #include "code\game\gamemodes\technomancer\spells\projectile\chain_lightning.dm"
#include "code\game\gamemodes\technomancer\spells\projectile\force_missile.dm" #include "code\game\gamemodes\technomancer\spells\projectile\force_missile.dm"
#include "code\game\gamemodes\technomancer\spells\projectile\ionic_bolt.dm"
#include "code\game\gamemodes\technomancer\spells\projectile\lesser_chain_lightning.dm"
#include "code\game\gamemodes\technomancer\spells\projectile\lightning.dm" #include "code\game\gamemodes\technomancer\spells\projectile\lightning.dm"
#include "code\game\gamemodes\technomancer\spells\projectile\overload.dm" #include "code\game\gamemodes\technomancer\spells\projectile\overload.dm"
#include "code\game\gamemodes\technomancer\spells\projectile\projectile.dm" #include "code\game\gamemodes\technomancer\spells\projectile\projectile.dm"
#include "code\game\gamemodes\technomancer\spells\spawner\darkness.dm" #include "code\game\gamemodes\technomancer\spells\spawner\darkness.dm"
#include "code\game\gamemodes\technomancer\spells\spawner\destablize.dm"
#include "code\game\gamemodes\technomancer\spells\spawner\fire_blast.dm" #include "code\game\gamemodes\technomancer\spells\spawner\fire_blast.dm"
#include "code\game\gamemodes\technomancer\spells\spawner\pulsar.dm" #include "code\game\gamemodes\technomancer\spells\spawner\pulsar.dm"
#include "code\game\gamemodes\technomancer\spells\spawner\spawner.dm" #include "code\game\gamemodes\technomancer\spells\spawner\spawner.dm"