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