More Technomancer Work

Adds two new spells;
Track: which functions similarly to a pinpointer for technomancer objects and apprentices.  With a scepter, it will be able to track anyone as well.
Targeting Matrix: which assists in targeting with whatever is in your off-hand, for a price in instability and energy per shot.
Adds Gloves of Regeneration, which passively trades healing for hunger, as well as stabbing your hands with needles.  They also insulate your hands.
Adds Boots of Speed, which act as no-slips and make the wearer run slightly faster than normal.
Adds the new gun sounds to Audible Deception.
This commit is contained in:
Neerti
2016-07-18 22:03:02 -04:00
parent d533ef743b
commit e1e0933657
13 changed files with 279 additions and 15 deletions

View File

@@ -0,0 +1,19 @@
/datum/technomancer/equipment/boots_of_speed
name = "Boots of Speed"
desc = "What appears to be an ordinary pair of boots, is actually a bit more useful than that. These will help against slipping \
on flat surfaces, and will make you run a bit faster than if you had normal shoes or boots on."
cost = 50
obj_path = /obj/item/clothing/shoes/speed
/obj/item/clothing/shoes/speed
name = "boots of speed"
desc = "The latest in sure footing technology."
icon_state = "swat"
item_flags = NOSLIP
siemens_coefficient = 0.6
slowdown = -2 // A bit faster than normal shows.
cold_protection = FEET
min_cold_protection_temperature = SHOE_MIN_COLD_PROTECTION_TEMPERATURE
heat_protection = FEET
max_heat_protection_temperature = SHOE_MAX_HEAT_PROTECTION_TEMPERATURE

View File

@@ -0,0 +1,67 @@
/datum/technomancer/equipment/gloves_of_regen
name = "Gloves of Regeneration"
desc = "It's a pair of black gloves, with a hypodermic needle on the insides, and a small storage of a secret blend of chemicals \
designed to be slowly fed into a living person's system, increasing their metabolism greatly, resulting in accelerated healing. \
A side effect of this healing is that the wearer will generally get hungry a lot faster. Sliding the gloves on and off also \
hurts a lot. As a bonus, the gloves are more resistant to the elements than most. It should be noted that synthetics will have \
little use for these."
cost = 50
obj_path = /obj/item/clothing/gloves/regen
/obj/item/clothing/gloves/regen
name = "gloves of regeneration"
desc = "A pair of gloves with a small storage of green liquid on the outside. On the inside, a a hypodermic needle can be seen \
on each glove."
icon_state = "regen"
item_state = "graygloves"
siemens_coefficient = 0
cold_protection = HANDS
min_cold_protection_temperature = GLOVES_MIN_COLD_PROTECTION_TEMPERATURE
heat_protection = HANDS
max_heat_protection_temperature = GLOVES_MAX_HEAT_PROTECTION_TEMPERATURE
var/mob/living/carbon/human/wearer = null
/obj/item/clothing/gloves/regen/equipped(var/mob/living/carbon/human/H)
if(H && H.gloves == src)
wearer = H
if(wearer.can_feel_pain())
H << "<span class='danger'>You feel a stabbing sensation in your hands as you slide \the [src] on!</span>"
wearer.custom_pain("You feel a sharp pain in your hands!",1)
..()
/obj/item/clothing/gloves/regen/dropped(var/mob/living/carbon/human/H)
..()
if(wearer)
if(wearer.can_feel_pain())
wearer << "<span class='danger'>You feel the hypodermic needles as you slide \the [src] off!</span>"
wearer.custom_pain("Your hands hurt like hell!",1)
wearer = null
/obj/item/clothing/gloves/regen/New()
processing_objects |= src
..()
/obj/item/clothing/gloves/regen/Destroy()
wearer = null
processing_objects -= src
..()
/obj/item/clothing/gloves/regen/process()
if(!wearer || wearer.isSynthetic() || wearer.stat == DEAD || wearer.nutrition >= 10)
return // Robots and dead people don't have a metabolism.
if(wearer.getBruteLoss())
wearer.adjustBruteLoss(-0.1)
wearer.nutrition = max(wearer.nutrition - 10, 0)
if(wearer.getFireLoss())
wearer.adjustFireLoss(-0.1)
wearer.nutrition = max(wearer.nutrition - 10, 0)
if(wearer.getToxLoss())
wearer.adjustToxLoss(-0.1)
wearer.nutrition = max(wearer.nutrition - 10, 0)
if(wearer.getOxyLoss())
wearer.adjustOxyLoss(-0.1)
wearer.nutrition = max(wearer.nutrition - 10, 0)
if(wearer.getCloneLoss())
wearer.adjustCloneLoss(-0.1)
wearer.nutrition = max(wearer.nutrition - 20, 0)

View File

@@ -71,12 +71,54 @@
new /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/combat(src)
..()
/datum/technomancer/equipment/belt_of_holding
name = "Belt of Holding"
desc = "A belt with a literal pocket which opens to a localized pocket of 'Blue-Space', allowing for more storage. \
The nature of the pocket allows for storage of larger objects than what is typical for other belts, and in larger quanities. \
It will also help keep your pants on."
cost = 100
obj_path = /obj/item/weapon/storage/belt/holding
/obj/item/weapon/storage/belt/holding
name = "Belt of Holding"
desc = "Can hold more than you'd expect."
icon_state = "emsbelt"
item_state = "emsbelt"
max_w_class = 3 // Can hold normal sized items.
storage_slots = 14 // Twice the capacity of a typical belt.
max_storage_space = 42
/datum/technomancer/equipment/thermals
name = "Thermoncle"
desc = "A fancy monocle with a thermal optics lens installed. Allows you to see people across walls."
cost = 150
obj_path = /obj/item/clothing/glasses/thermal/plain/monocle
/datum/technomancer/equipment/night_vision
name = "Night Vision Goggles"
desc = "Strategical goggles which will allow the wearer to see in the dark. Perfect for the sneaky type, just get rid of the \
lights first."
cost = 50
obj_path = /obj/item/clothing/glasses/night
/datum/technomancer/equipment/omni_sight
name = "Omnisight Scanner"
desc = "A very rare scanner worn on the face, which allows the wearer to see nearly anything across walls."
cost = 400
obj_path = /obj/item/clothing/glasses/omni
/obj/item/clothing/glasses/omni
name = "Omnisight Scanner"
desc = "A pair of goggles which, while on the surface appear to be build very poorly, reveal to be very advanced in \
capabilities. The lens appear to be multiple optical matrices layered together, allowing the wearer to see almost anything \
across physical barriers."
icon_state = "uzenwa_sissra_1"
action_button_name = "Toggle Goggles"
origin_tech = list(TECH_MAGNET = 6, TECH_ENGINEERING = 6)
toggleable = 1
vision_flags = SEE_TURFS|SEE_MOBS|SEE_OBJS
prescription = 1 // So two versions of these aren't needed.
/datum/technomancer/equipment/med_hud
name = "Medical HUD"
desc = "A commonly available HUD for medical professionals, which displays how healthy an individual is. \
@@ -84,7 +126,6 @@
cost = 30
obj_path = /obj/item/clothing/glasses/thermal/plain/monocle
/datum/technomancer/equipment/scepter
name = "Scepter of Empowerment"
desc = "A gem sometimes found in the depths of asteroids makes up the basis for this device. Energy is channeled into it from \
@@ -112,4 +153,4 @@
var/obj/item/item_to_test = user.get_other_hand(src)
if(istype(item_to_test, /obj/item/weapon/spell))
var/obj/item/weapon/spell/S = item_to_test
S.on_scepter_ranged_cast(target, user)
S.on_scepter_ranged_cast(target, user)

View File

@@ -23,4 +23,20 @@
/obj/item/weapon/spell/proc/allowed_to_teleport()
if(owner && owner.z in config.admin_levels)
return 0
return 1
return 1
// Returns a 'target' mob from a radius around T.
/obj/item/weapon/spell/proc/targeting_assist(var/turf/T, radius = 5)
var/chosen_target = null
var/potential_targets = view(T,radius)
for(var/mob/living/L in potential_targets)
if(is_ally(L)) // Don't shoot our friends.
continue
if(L.invisibility > owner.see_invisible) // Don't target ourselves or people we can't see.
continue
if(!L in viewers(owner)) // So we don't shoot at walls if someone is hiding behind one.
continue
if(!L.stat) // Don't want to target dead people or SSDs.
chosen_target = L
break
return chosen_target

View File

@@ -31,10 +31,20 @@
"Flash" = 'sound/weapons/flash.ogg',
"Bite" = 'sound/weapons/bite.ogg',
"Gun Firing" = 'sound/weapons/gunshot.ogg',
"Desert Eagle Firing" = 'sound/weapons/deagle.ogg',
"Rifle Firing" = 'sound/weapons/rifleshot.ogg',
"Rifle Firing 2" = 'sound/weapons/svd_shot.ogg',
"Sniper Firing" = 'sound/weapons/sniper.ogg',
"Shotgun Firing" = 'sound/weapons/shotgun.ogg',
"Semi-automatic Firing" = 'sound/weapons/semiauto.ogg',
"Machinegun Firing" = 'sound/weapons/machinegun.ogg',
"Rocket Launcher Firing"= 'sound/weapons/rpg.ogg',
"Taser Firing" = 'sound/weapons/Taser.ogg',
"Laser Gun Firing" = 'sound/weapons/laser.ogg',
"E-Luger Firing" = 'sound/weapons/eLuger.ogg',
"Xray Gun Firing" = 'sound/weapons/laser3.ogg',
"Pulse Gun Firing" = 'sound/weapons/pulse.ogg',
"Gauss Gun Firing" = 'sound/weapons/gauss_shoot.ogg',
"Emitter Firing" = 'sound/weapons/emitter.ogg',
"Energy Blade On" = 'sound/weapons/saberon.ogg',
"Energy Blade Off" = 'sound/weapons/saberoff.ogg',

View File

@@ -2,6 +2,7 @@
name = "Beam"
desc = "Fires a laser at your target. Cheap, reliable, and a bit boring."
cost = 150
ability_icon_state = "tech_beam"
obj_path = /obj/item/weapon/spell/projectile/beam
/obj/item/weapon/spell/projectile/beam

View File

@@ -0,0 +1,35 @@
/datum/technomancer/spell/targeting_matrix
name = "Targeting Matrix"
desc = "Automatically targets and fires a ranged weapon or function at a non-friendly target near a targeted tile. \
Each target assisted attack costs some energy and instability."
cost = 150
ability_icon_state = "tech_targetingmatrix"
obj_path = /obj/item/weapon/spell/targeting_matrix
/obj/item/weapon/spell/targeting_matrix
name = "targeting matrix"
desc = "Aiming is too much effort for you."
icon_state = "targeting_matrix"
cast_methods = CAST_RANGED
aspect = ASPECT_FORCE //idk?
/obj/item/weapon/spell/targeting_matrix/on_ranged_cast(atom/hit_atom, mob/user)
var/turf/T = get_turf(hit_atom)
if(T)
var/mob/living/chosen_target = targeting_assist(T,5) //The person who's about to get attacked.
if(!chosen_target)
return 0
var/obj/item/I = user.get_inactive_hand()
if(I && pay_energy(200))
var/prox = user.Adjacent(chosen_target)
if(prox) // Needed or else they can attack with melee from afar.
I.attack(chosen_target,owner)
I.afterattack(chosen_target,owner, prox)
adjust_instability(2)
var/image/target_image = image(icon = 'icons/obj/spells.dmi', loc = get_turf(chosen_target), icon_state = "target")
user << target_image
sleep(5)
qdel(target_image)

View File

@@ -0,0 +1,74 @@
/datum/technomancer/spell/track
name = "Track"
desc = "Acts as directional guidance towards an object that belongs to you or your team. It can also point towards your allies. \
Wonderful if you're worried someone will steal your valuables, like a certain shiny Scepter..."
enhancement_desc = "You will be able to track most other entities in addition to your belongings and allies."
cost = 30
obj_path = /obj/item/weapon/spell/track
ability_icon_state = "tech_track"
// This stores a ref to all important items that belong to a Technomancer, in case of theft. Used by the spell below.
// I feel dirty for adding yet another global list used by one thing, but the only alternative is to loop through world, and yeahhh.
var/list/technomancer_belongings = list()
/obj/item/weapon/spell/track
name = "track"
icon_state = "track"
desc = "Never lose your stuff again!"
cast_methods = CAST_USE
aspect = ASPECT_TELE
var/atom/movable/tracked = null // The thing to point towards.
var/tracking = 0 // If one, points towards tracked.
/obj/item/weapon/spell/track/Destroy()
tracked = null
tracking = 0
/obj/item/weapon/spell/track/on_use_cast(mob/user)
if(tracking)
tracking = 0
user << "<span class='notice'>You stop tracking for \the [tracked]'s whereabouts.</span>"
tracked = null
return
var/can_track_non_allies = 0
var/list/object_choices = technomancer_belongings.Copy()
if(check_for_scepter())
can_track_non_allies = 1
var/list/mob_choices = list()
for(var/mob/living/L in mob_list)
if(!is_ally(L) && !can_track_non_allies)
continue
mob_choices += L
var/choice = input(user,"Decide what or who to track.","Tracking") as null|anything in object_choices + mob_choices
if(choice)
tracked = choice
tracking = 1
track()
/obj/item/weapon/spell/track/proc/track()
if(!tracking)
icon_state = "track"
return
if(!tracked)
icon_state = "track_unknown"
if(tracked.z != owner.z)
icon_state = "track_unknown"
else
set_dir(get_dir(src,tracked))
switch(get_dist(src,tracked))
if(0)
icon_state = "track_direct"
if(1 to 8)
icon_state = "track_close"
if(9 to 16)
icon_state = "track_medium"
if(16 to INFINITY)
icon_state = "track_far"
spawn(5)
.()

View File

@@ -3,11 +3,12 @@
desc = "Teleports you next to your target, and attacks them with whatever is in your off-hand, spell or object."
cost = 200
obj_path = /obj/item/weapon/spell/warp_strike
ability_icon_state = "tech_warpstrike"
/obj/item/weapon/spell/warp_strike
name = "warp strike"
desc = "The answer to the problem of bringing a knife to a gun fight."
icon_state = "tech_warpstrike"
icon_state = "warp_strike"
cast_methods = CAST_RANGED
aspect = ASPECT_TELE
var/datum/effect/effect/system/spark_spread/sparks
@@ -23,16 +24,7 @@
if(T)
//First, we handle who to teleport to.
user.setClickCooldown(5)
var/list/potential_targets = view(T, 2) //Everyone in a 5x5 range of the tile we clicked on.
var/mob/living/chosen_target = null //The person who's about to get attacked.
//Find us someone to robust.
for(var/mob/living/L in potential_targets)
if(L == user || L.invisibility > user.see_invisible) //Don't target ourselves or people we can't see.
continue
if(!L.stat) //Don't want to target dead people or SSDs.
chosen_target = L
break
var/mob/living/chosen_target = targeting_assist(T,5) //The person who's about to get attacked.
if(!chosen_target)
return 0
@@ -60,7 +52,12 @@
//Finally, we handle striking the victim with whatever's in the user's offhand.
var/obj/item/I = user.get_inactive_hand()
var/list/blacklisted_items = list(/obj/item/weapon/gun) //We don't want these items to be used, likely because it would break balance.
// List of items we don't want used, for balance reasons or to avoid infinite loops.
var/list/blacklisted_items = list(
/obj/item/weapon/gun,
/obj/item/weapon/spell/warp_strike,
/obj/item/weapon/spell/targeting_matrix
)
if(I)
if(is_path_in_list(I.type, blacklisted_items))

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

@@ -416,7 +416,9 @@
#include "code\game\gamemodes\technomancer\technomancer.dm"
#include "code\game\gamemodes\technomancer\assistance\assistance.dm"
#include "code\game\gamemodes\technomancer\assistance\golem.dm"
#include "code\game\gamemodes\technomancer\devices\boots_of_speed.dm"
#include "code\game\gamemodes\technomancer\devices\disposable_teleporter.dm"
#include "code\game\gamemodes\technomancer\devices\gloves_of_regen.dm"
#include "code\game\gamemodes\technomancer\devices\hypos.dm"
#include "code\game\gamemodes\technomancer\devices\shield_armor.dm"
#include "code\game\gamemodes\technomancer\devices\tesla_armor.dm"
@@ -441,6 +443,8 @@
#include "code\game\gamemodes\technomancer\spells\resurrect.dm"
#include "code\game\gamemodes\technomancer\spells\shared_burden.dm"
#include "code\game\gamemodes\technomancer\spells\shield.dm"
#include "code\game\gamemodes\technomancer\spells\targeting_matrix.dm"
#include "code\game\gamemodes\technomancer\spells\track.dm"
#include "code\game\gamemodes\technomancer\spells\warp_strike.dm"
#include "code\game\gamemodes\technomancer\spells\aura\aura.dm"
#include "code\game\gamemodes\technomancer\spells\aura\biomed_aura.dm"