mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 10:12:45 +00:00
Merge pull request #3421 from Neerti/5/5/2017_technomancer_changes
More Technomancer
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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("<span class='notice'>\The [src] vanishes!</span>")
|
||||
src.forceMove(get_turf(target))
|
||||
return
|
||||
@@ -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"
|
||||
|
||||
@@ -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("<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)
|
||||
@@ -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, "<span class='warning'>The purple glow makes you feel strange...</span>")
|
||||
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, "<span class='warning'>The purple glow makes you feel strange...</span>")
|
||||
adjust_instability(amount)
|
||||
|
||||
@@ -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, "<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()
|
||||
|
||||
// Proc: Destroy()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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, "<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)
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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)
|
||||
56
code/game/gamemodes/technomancer/spells/mend_organs.dm
Normal file
56
code/game/gamemodes/technomancer/spells/mend_organs.dm
Normal 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)
|
||||
35
code/game/gamemodes/technomancer/spells/modifier/mend_all.dm
Normal file
35
code/game/gamemodes/technomancer/spells/modifier/mend_all.dm
Normal 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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
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.
|
||||
40
code/game/gamemodes/technomancer/spells/modifier/purify.dm
Normal file
40
code/game/gamemodes/technomancer/spells/modifier/purify.dm
Normal 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)
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user