Merge pull request #2768 from Anewbe/wizbiz

Technomancer changes
This commit is contained in:
MagmaRam
2016-11-24 14:40:36 -06:00
committed by GitHub
21 changed files with 132 additions and 56 deletions
@@ -78,7 +78,7 @@
H << "<b>You are the Technomancer's apprentice! Your goal is to assist them in their mission at the [station_name()].</b>"
H << "<b>Your service has not gone unrewarded, however. Studying under them, you have learned how to use a Manipulation Core \
of your own. You also have a Catelog, to purchase your own functions and equipment as you see fit.</b>"
of your own. You also have a catalog, to purchase your own functions and equipment as you see fit.</b>"
H << "<b>It would be wise to speak to your master, and learn what their plans are for today.</b>"
spawn(1)
+11 -11
View File
@@ -42,33 +42,33 @@ var/list/all_technomancer_assistance = typesof(/datum/technomancer/assistance) -
var/show_scepter_text = 0
/obj/item/weapon/technomancer_catalog/apprentice
name = "apprentice's catelog"
name = "apprentice's catalog"
budget = 700
max_budget = 700
/obj/item/weapon/technomancer_catalog/master //for badmins, I suppose
name = "master's catelog"
name = "master's catalog"
budget = 2000
max_budget = 2000
// Proc: bind_to_owner()
// Parameters: 1 (new_owner - mob that the book is trying to bind to)
// Description: Links the catelog to hopefully the technomancer, so that only they can access it.
// Description: Links the catalog to hopefully the technomancer, so that only they can access it.
/obj/item/weapon/technomancer_catalog/proc/bind_to_owner(var/mob/living/carbon/human/new_owner)
if(!owner && technomancers.is_antagonist(new_owner.mind))
owner = new_owner
// Proc: New()
// Parameters: 0
// Description: Sets up the catelog, as shown below.
// Description: Sets up the catalog, as shown below.
/obj/item/weapon/technomancer_catalog/New()
..()
set_up()
// Proc: set_up()
// Parameters: 0
// Description: Instantiates all the catelog datums for everything that can be bought.
// Description: Instantiates all the catalog datums for everything that can be bought.
/obj/item/weapon/technomancer_catalog/proc/set_up()
if(!spell_instances.len)
for(var/S in all_technomancer_spells)
@@ -100,7 +100,7 @@ var/list/all_technomancer_assistance = typesof(/datum/technomancer/assistance) -
return "<b>[category]</b>"
// Proc: attack_self()
// Parameters: 1 (user - the mob clicking on the catelog)
// Parameters: 1 (user - the mob clicking on the catalog)
// Description: Shows an HTML window, to buy equipment and spells, if the user is the legitimate owner. Otherwise it cannot be used.
/obj/item/weapon/technomancer_catalog/attack_self(mob/user)
if(!user)
@@ -207,12 +207,12 @@ var/list/all_technomancer_assistance = typesof(/datum/technomancer/assistance) -
dat += "You currently have a budget of <b>[budget]/[max_budget]</b>.<br><br>"
dat += "<br>"
dat += "<h1>Manipulation Core Owner's Manual</h1><br>"
dat += "This brief entry in your catelog will try to explain what everything does. For starters, the thing you're \
dat += "This brief entry in your catalog will try to explain what everything does. For starters, the thing you're \
probably wearing on your back is known as a <b>Manipulation Core</b>, or just a 'Core'. It allows you to do amazing \
things with almost no effort, depending on what <b>functions</b> you've purchased for it. Don't lose your core!<br>"
dat += "<br>"
dat += "There are a few things you need to keep in mind as you use your Core to manipulate the universe. The core \
requires a special type of <b>energy</b>, that is referred to as just 'Energy' in the catelog. All cores generate \
requires a special type of <b>energy</b>, that is referred to as just 'Energy' in the catalog. All cores generate \
their own energy, some more than others. Most functions require energy be spent in order to work, so make sure not \
to run out in a critical moment. Besides waiting for your Core to recharge, you can buy certain functions which \
do something to generate energy.<br>"
@@ -242,13 +242,13 @@ var/list/all_technomancer_assistance = typesof(/datum/technomancer/assistance) -
dat += "<b>You can refund functions, equipment items, and assistance items, so long as you are in your base.</b> \
Once you leave, you can't refund anything, however you can still buy things if you still have points remaining. \
To refund functions, just click the 'Refund Functions' button on the top, when in the functions tabs. \
For equipment items, you need to hit it against the catelog.<br>"
For equipment items, you need to hit it against the catalog.<br>"
dat += "<br>"
dat += "Your blue robes and hat are both stylish, and somewhat protective against hostile energies, which includes \
EXTERNAL instability sources (like Glow), and mundane electricity. If you're looking for protection against other \
things, it's suggested you purchase or otherwise obtain armor.<br>"
dat += "<br>"
dat += "There are a few terms you may not understand in the catelog, so this will try to explain them.<br>"
dat += "There are a few terms you may not understand in the catalog, so this will try to explain them.<br>"
dat += "A function can be thought of as a 'spell', that you use by holding in your hands and trying to use it on \
a target of your choice.<br>"
dat += "Some functions can have their abilities enhanced by a special rod called the Scepter of Enhancement. \
@@ -265,7 +265,7 @@ var/list/all_technomancer_assistance = typesof(/datum/technomancer/assistance) -
// Proc: Topic()
// Parameters: 2 (href - don't know, href_list - the choice that the person using the interface above clicked on.)
// Description: Acts upon clicks on links for the catelog, if they are the rightful owner.
// Description: Acts upon clicks on links for the catalog, if they are the rightful owner.
/obj/item/weapon/technomancer_catalog/Topic(href, href_list)
..()
var/mob/living/carbon/human/H = usr
+7 -1
View File
@@ -23,6 +23,7 @@
var/instability_modifier = 0.8 // Multiplier on how much instability is added.
var/energy_cost_modifier = 1.0 // Multiplier on how much spells will cost.
var/spell_power_modifier = 1.0 // Multiplier on how strong spells are.
var/cooldown_modifier = 1.0 // Multiplier on cooldowns for spells.
var/list/spells = list() // This contains the buttons used to make spells in the user's hand.
var/list/appearances = list( // Assoc list containing possible icon_states that the wiz can change the core to.
"default" = "technomancer_core",
@@ -118,7 +119,11 @@
var/mob/living/L = A
if(L.stat == DEAD)
summoned_mobs -= L
qdel(L)
spawn(1)
L.visible_message("<span class='notice'>\The [L] begins to fade away...</span>")
animate(L, alpha = 255, alpha = 0, time = 30) // Makes them fade into nothingness.
sleep(30)
qdel(L)
// Deletes all the summons and wards from the core, so that Destroy() won't have issues.
/obj/item/weapon/technomancer_core/proc/dismiss_all_summons()
@@ -248,6 +253,7 @@
regen_rate = 70 //100 seconds to full
slowdown = -1
instability_modifier = 0.9
cooldown_modifier = 0.9
//Big batteries but slow regen, buying energy spells is highly recommended.
/obj/item/weapon/technomancer_core/bulky
@@ -60,6 +60,10 @@
var/obj/item/projectile/P = damage_source
P.sharp = 0
P.edge = 0
P.embed_chance = 0
if(P.agony)
var/agony_blocked = P.agony * (modified_block_percentage / 100)
P.agony -= agony_blocked
P.damage = P.damage - damage_blocked
user.visible_message("<span class='danger'>\The [user]'s [src] absorbs [attack_text]!</span>")
@@ -230,8 +230,9 @@
else if(cast_methods & CAST_RANGED) //Try to use a ranged method if a melee one doesn't exist.
on_ranged_cast(target, user)
if(cooldown)
user.setClickCooldown(cooldown)
flick("cooldown_[cooldown]",src)
var/effective_cooldown = round(cooldown * core.cooldown_modifier, 5)
user.setClickCooldown(effective_cooldown)
flick("cooldown_[effective_cooldown]",src)
// Proc: place_spell_in_hand()
// Parameters: 1 (path - the type path for the spell that is desired.)
@@ -8,7 +8,7 @@
/obj/item/weapon/spell/aura/New()
..()
set_light(7, calculate_spell_power(4), l_color = glow_color)
set_light(calculate_spell_power(7), calculate_spell_power(4), l_color = glow_color)
processing_objects |= src
log_and_message_admins("has started casting [src].")
@@ -11,7 +11,7 @@
name = "restoration aura"
desc = "Allows everyone, or just your allies, to slowly regenerate."
icon_state = "generic"
cast_methods = null
cast_methods = CAST_USE
aspect = ASPECT_BIOMED
glow_color = "#33CC33"
var/regen_tick = 0
@@ -31,8 +31,8 @@
else
mobs_to_heal |= L // Heal everyone!
for(var/mob/living/L in mobs_to_heal)
L.adjustBruteLoss(calculate_spell_power(-2))
L.adjustFireLoss(calculate_spell_power(-2))
L.adjustBruteLoss(calculate_spell_power(-5))
L.adjustFireLoss(calculate_spell_power(-5))
adjust_instability(2)
/obj/item/weapon/spell/aura/biomed/on_use_cast(mob/living/user)
@@ -22,14 +22,14 @@
qdel(src)
var/list/nearby_things = range(calculate_spell_power(4),owner)
var/temp_change = calculate_spell_power(40)
var/temp_change = calculate_spell_power(80)
var/temp_cap = calculate_spell_power(600)
var/fire_power = calculate_spell_power(2)
if(check_for_scepter())
temp_change = calculate_spell_power(80)
temp_cap = calculate_spell_power(1000)
fire_power = calculate_spell_power(4)
temp_change *= 2
temp_cap *= 2
fire_power *= 2
for(var/mob/living/carbon/human/H in nearby_things)
if(is_ally(H))
@@ -22,11 +22,11 @@
qdel(src)
var/list/nearby_mobs = range(calculate_spell_power(4),owner)
var/temp_change = calculate_spell_power(25)
var/temp_change = calculate_spell_power(40)
var/temp_cap = 260 // Just above the damage threshold, for humans. Unathi are less fortunate.
if(check_for_scepter())
temp_change = calculate_spell_power(50)
temp_change *= 2
temp_cap = 200
for(var/mob/living/carbon/human/H in nearby_mobs)
if(is_ally(H))
@@ -17,7 +17,7 @@
glow_color = "#0000FF" //TODO
/obj/item/weapon/spell/aura/shock/process()
if(!pay_energy(1000))
if(!pay_energy(500))
qdel(src)
var/list/nearby_mobs = range(calculate_spell_power(4),owner)
var/power = calculate_spell_power(7)
@@ -1,7 +1,8 @@
/datum/technomancer/spell/blink
name = "Blink"
desc = "Force the target to teleport a short distance away. This target could be anything from something lying on the ground, to someone trying to \
fight you, or even yourself. Using this on someone next to you makes their potential distance after teleportation greater."
desc = "Force the target to teleport a short distance away. This target could be anything from something lying on the ground, \
to someone trying to fight you, or even yourself. Using this on someone next to you makes their potential distance after \
teleportation greater. Self casting has the greatest potential for distance, as well as the cheapest cost."
enhancement_desc = "Blink distance is increased greatly."
spell_power_desc = "Blink distance is scaled up with more spell power."
cost = 50
@@ -54,25 +55,37 @@
if(!within_range(AM))
user << "<span class='warning'>\The [AM] is too far away to blink.</span>"
return
if(check_for_scepter())
safe_blink(AM, calculate_spell_power(6))
if(pay_energy(400))
if(check_for_scepter())
safe_blink(AM, calculate_spell_power(6))
else
safe_blink(AM, calculate_spell_power(3))
adjust_instability(3)
log_and_message_admins("has blinked [AM] away.")
else
safe_blink(AM, calculate_spell_power(3))
log_and_message_admins("has blinked [AM] away.")
to_chat(user, "<span class='warning'>You need more energy to blink [AM] away!</span>")
/obj/item/weapon/spell/blink/on_use_cast(mob/user)
if(check_for_scepter())
safe_blink(user, calculate_spell_power(10))
if(pay_energy(200))
if(check_for_scepter())
safe_blink(user, calculate_spell_power(10))
else
safe_blink(user, calculate_spell_power(6))
adjust_instability(1)
log_and_message_admins("has blinked themselves away.")
else
safe_blink(user, calculate_spell_power(6))
log_and_message_admins("has blinked themselves away.")
to_chat(user, "<span class='warning'>You need more energy to blink yourself away!</span>")
/obj/item/weapon/spell/blink/on_melee_cast(atom/hit_atom, mob/living/user, def_zone)
if(istype(hit_atom, /atom/movable))
var/atom/movable/AM = hit_atom
visible_message("<span class='danger'>\The [user] reaches out towards \the [AM] with a glowing hand.</span>")
if(check_for_scepter())
safe_blink(AM, 10)
if(pay_energy(300))
visible_message("<span class='danger'>\The [user] reaches out towards \the [AM] with a glowing hand.</span>")
if(check_for_scepter())
safe_blink(AM, 10)
else
safe_blink(AM, 6)
adjust_instability(2)
log_and_message_admins("has blinked [AM] away.")
else
safe_blink(AM, 6)
log_and_message_admins("has blinked [AM] away.")
to_chat(user, "<span class='warning'>You need more energy to blink [AM] away!</span>")
@@ -30,7 +30,7 @@
W.set_color()
W.set_up(desired_turf)
flick(initial(icon_state),W) // Otherwise pooling causes the animation to stay stuck at the end.
log_and_message_admins("has wetted the floor with [src] at [T.x],[T.y],[T.z].")
log_and_message_admins("has wetted the floor with [src] at [T.x],[T.y],[T.z].")
else if(hit_atom.reagents && !ismob(hit_atom))
hit_atom.reagents.add_reagent(id = "water", amount = 60, data = null, safety = 0)
adjust_instability(5)
@@ -133,7 +133,7 @@
if(L.client)
user << "<span class='danger'>\The [L] seems to resist you!</span>"
return 0
if(pay_energy(1000))
if(pay_energy(500))
select(L)
user << "<span class='notice'>\The [L] is now under your (limited) control.</span>"
else //Deselect them
@@ -144,7 +144,7 @@
if(!controlled_mobs.len)
user << "<span class='warning'>You have no entities under your control to command.</span>"
return 0
if(pay_energy(50 * controlled_mobs.len))
if(pay_energy(25 * controlled_mobs.len))
attack_all(L)
log_and_message_admins("has commanded their army of [controlled_mobs.len] to attack [L].")
user << "<span class='notice'>You command your [controlled_mobs.len > 1 ? "entities" : "[controlled_mobs[1]]"] to \
@@ -158,7 +158,7 @@
if(!controlled_mobs.len)
user << "<span class='warning'>You have no entities under your control to command.</span>"
return 0
if(pay_energy(50 * controlled_mobs.len))
if(pay_energy(10 * controlled_mobs.len))
move_all(T)
adjust_instability(controlled_mobs.len)
user << "<span class='notice'>You command your [controlled_mobs.len > 1 ? "entities" : "[controlled_mobs[1]]"] to move \
@@ -19,7 +19,7 @@
/obj/item/weapon/spell/illusion/on_ranged_cast(atom/hit_atom, mob/user)
if(istype(hit_atom, /atom/movable))
var/atom/movable/AM = hit_atom
if(pay_energy(500))
if(pay_energy(100))
copied = AM
update_icon()
user << "<span class='notice'>You've copied \the [AM]'s appearance.</span>"
@@ -30,7 +30,7 @@
if(!illusion)
if(!copied)
copied = user
if(pay_energy(1000)) // 4
if(pay_energy(500))
illusion = new(T)
illusion.copy_appearance(copied)
if(ishuman(copied))
@@ -41,7 +41,7 @@
user << 'sound/effects/pop.ogg'
return 1
else
if(pay_energy(300))
if(pay_energy(100))
spawn(1)
illusion.walk_loop(T)
@@ -50,5 +50,7 @@
H.restore_blood() // Fix bloodloss
H.adjustBruteLoss(-heal_power)
sleep(1 SECOND)
on_expire()
@@ -1,14 +1,15 @@
/datum/technomancer/spell/phase_shift
name = "Phase Shift"
desc = "Hides you in the safest possible place, where no harm can come to you. Unfortunately you can only stay inside for a few moments before \
draining your powercell."
desc = "Hides you in the safest possible place, where no harm can come to you. Unfortunately, a prolonged stay inside the \
rift you create will afflict you with instability."
cost = 50
obj_path = /obj/item/weapon/spell/phase_shift
category = DEFENSIVE_SPELLS
/obj/item/weapon/spell/phase_shift
name = "phase shift"
desc = "Allows you to dodge your untimely fate by shifting your location somewhere else, so long as you can sustain the energy to do so."
desc = "Allows you to dodge your untimely fate by shifting your location somewhere else, so long as you can survive inside the \
rift."
cast_methods = CAST_USE
aspect = ASPECT_TELE
@@ -0,0 +1,20 @@
/datum/technomancer/spell/ionic_bolt
name = "Ionic Bolt"
desc = "Shoots a bolt of ion energy at the target. If it hits something, it will generally drain energy, corrupt electronics, \
or otherwise ruin complex machinery."
cost = 100
obj_path = /obj/item/weapon/spell/projectile/ionic_bolt
category = OFFENSIVE_SPELLS
/obj/item/weapon/spell/projectile/ionic_bolt
name = "ionic bolt"
icon_state = "ionic bolt"
desc = "For those pesky security units."
cast_methods = CAST_RANGED
aspect = ASPECT_EMP
spell_projectile = /obj/item/projectile/ion
energy_cost_per_shot = 500
instability_per_shot = 6
cooldown = 10
pre_shot_delay = 0
fire_sound = 'sound/effects/supermatter.ogg'
@@ -3,6 +3,7 @@
desc = "Fires a bolt of highly unstable energy, that does damaged equal to 0.3% of the technomancer's current reserve of energy. \
This energy pierces all known armor. Energy cost is equal to 10% of maximum core charge."
enhancement_desc = "Will do damage equal to 0.4% of current energy."
spell_power_desc = "Increases damage dealt, up to a cap of 80 damage per shot."
cost = 100
obj_path = /obj/item/weapon/spell/projectile/overload
category = OFFENSIVE_SPELLS
@@ -26,9 +27,19 @@
damage_type = BURN
armor_penetration = 100
/obj/item/weapon/spell/projectile/overload/make_projectile(obj/item/projectile/projectile_type, mob/living/user)
var/obj/item/projectile/overload/P = new projectile_type(get_turf(user))
var/energy_before_firing = core.energy
if(check_for_scepter())
P.damage = round(energy_before_firing * 0.004) // .4% of their current energy pool.
else
P.damage = round(energy_before_firing * 0.003) // .3% of their current energy pool.
P.damage = min(calculate_spell_power(P.damage), 80)
return P
/obj/item/weapon/spell/projectile/overload/on_ranged_cast(atom/hit_atom, mob/living/user)
energy_cost_per_shot = round(core.max_energy * 0.10)
var/energy_before_firing = core.energy
/* var/energy_before_firing = core.energy
if(set_up(hit_atom, user))
var/obj/item/projectile/overload/P = new spell_projectile(get_turf(user))
P.launch(hit_atom)
@@ -37,4 +48,5 @@
else
P.damage = round(energy_before_firing * 0.003) // .3% of their current energy pool.
adjust_instability(instability_per_shot)
return 1
return 1
*/
@@ -11,8 +11,7 @@
/obj/item/weapon/spell/projectile/on_ranged_cast(atom/hit_atom, mob/living/user)
if(set_up(hit_atom, user))
var/obj/item/projectile/new_projectile = new spell_projectile(get_turf(user))
new_projectile.damage = calculate_spell_power(new_projectile.damage)
var/obj/item/projectile/new_projectile = make_projectile(spell_projectile, user)
new_projectile.launch(hit_atom)
log_and_message_admins("has casted [src] at \the [hit_atom].")
if(fire_sound)
@@ -21,6 +20,11 @@
return 1
return 0
/obj/item/weapon/spell/projectile/proc/make_projectile(obj/item/projectile/projectile_type, mob/living/user)
var/obj/item/projectile/P = new projectile_type(get_turf(user))
P.damage = calculate_spell_power(P.damage)
return P
/obj/item/weapon/spell/projectile/proc/set_up(atom/hit_atom, mob/living/user)
if(spell_projectile)
if(pay_energy(energy_cost_per_shot))
@@ -37,7 +37,7 @@
dead_mob_list -= SM
living_mob_list += SM
SM.icon_state = SM.icon_living
adjust_instability(30)
adjust_instability(15)
else if(ishuman(L))
var/mob/living/carbon/human/H = L
@@ -49,6 +49,9 @@
(Verbs -> Ghost -> Re-enter corpse)</font></font>"
break
H.adjustBruteLoss(-40)
H.adjustFireLoss(-40)
sleep(10 SECONDS)
if(H.client)
L.stat = CONSCIOUS //Note that if whatever killed them in the first place wasn't fixed, they're likely to die again.
@@ -50,6 +50,16 @@
summoned.health = calculate_spell_power(summoned.health)
summoned.melee_damage_lower = calculate_spell_power(summoned.melee_damage_lower)
summoned.melee_damage_upper = calculate_spell_power(summoned.melee_damage_upper)
// This makes the summon slower, so the crew has a chance to flee from massive monsters.
summoned.move_to_delay = calculate_spell_power(round(summoned.move_to_delay))
var/new_size = calculate_spell_power(1)
if(new_size != 1)
var/matrix/M = matrix()
M.Scale(new_size)
M.Translate(0, 16*(new_size-1))
summoned.transform = M
// Now we hurt their new pal, because being forcefully abducted by teleportation can't be healthy.
summoned.health = round(summoned.maxHealth * 0.7)