More work on new wizard.

This commit is contained in:
Neerti
2015-12-26 21:11:35 -05:00
parent 835b11d8ab
commit 19603db5dc
33 changed files with 1122 additions and 29 deletions

View File

@@ -73,6 +73,7 @@ var/list/be_special_flags = list(
#define MODE_NINJA "ninja" #define MODE_NINJA "ninja"
#define MODE_RAIDER "raider" #define MODE_RAIDER "raider"
#define MODE_WIZARD "wizard" #define MODE_WIZARD "wizard"
#define MODE_TECHNOMANCER "technomancer"
#define MODE_CHANGELING "changeling" #define MODE_CHANGELING "changeling"
#define MODE_CULTIST "cultist" #define MODE_CULTIST "cultist"
#define MODE_HIGHLANDER "highlander" #define MODE_HIGHLANDER "highlander"

View File

@@ -122,6 +122,8 @@ var/list/global_huds = list(
var/hotkey_ui_hidden = 0 //This is to hide the buttons that can be used via hotkeys. (hotkeybuttons list of buttons) var/hotkey_ui_hidden = 0 //This is to hide the buttons that can be used via hotkeys. (hotkeybuttons list of buttons)
var/obj/screen/lingchemdisplay var/obj/screen/lingchemdisplay
var/obj/screen/wiz_instability_display
var/obj/screen/wiz_energy_display
var/obj/screen/blobpwrdisplay var/obj/screen/blobpwrdisplay
var/obj/screen/blobhealthdisplay var/obj/screen/blobhealthdisplay
var/obj/screen/r_hand_hud_object var/obj/screen/r_hand_hud_object
@@ -148,6 +150,8 @@ datum/hud/New(mob/owner)
disarm_intent = null disarm_intent = null
help_intent = null help_intent = null
lingchemdisplay = null lingchemdisplay = null
wiz_instability_display = null
wiz_energy_display = null
blobpwrdisplay = null blobpwrdisplay = null
blobhealthdisplay = null blobhealthdisplay = null
r_hand_hud_object = null r_hand_hud_object = null

View File

@@ -303,6 +303,11 @@
mymob.ling_chem_display.icon_state = "ling_chems" mymob.ling_chem_display.icon_state = "ling_chems"
hud_elements |= mymob.ling_chem_display hud_elements |= mymob.ling_chem_display
mymob.wiz_instability_display = new /obj/screen/wizard/instability()
mymob.wiz_instability_display.screen_loc = ui_ling_chemical_display
mymob.wiz_instability_display.icon_state = "wiz_instability_none"
hud_elements |= mymob.wiz_instability_display
mymob.blind = new /obj/screen() mymob.blind = new /obj/screen()
mymob.blind.icon = 'icons/mob/screen1_full.dmi' mymob.blind.icon = 'icons/mob/screen1_full.dmi'
mymob.blind.icon_state = "blackimageoverlay" mymob.blind.icon_state = "blackimageoverlay"
@@ -398,3 +403,7 @@
/obj/screen/ling/chems /obj/screen/ling/chems
name = "chemical storage" name = "chemical storage"
icon_state = "power_display" icon_state = "power_display"
/obj/screen/wizard/instability
name = "instability"
icon_state = "instability_none"

View File

@@ -1,14 +1,14 @@
var/datum/antagonist/technomancer/technomancers var/datum/antagonist/technomancer/technomancers
/datum/antagonist/technomancer /datum/antagonist/technomancer
id = MODE_WIZARD id = MODE_TECHNOMANCER
role_type = BE_WIZARD role_type = BE_WIZARD
role_text = "Technomancer" role_text = "Technomancer"
role_text_plural = "Technomancers" role_text_plural = "Technomancers"
bantype = "wizard" bantype = "wizard"
landmark_id = "wizard" landmark_id = "wizard"
welcome_text = "To be written" welcome_text = "To be written"
flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_SET_APPEARANCE flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_SET_APPEARANCE | ANTAG_VOTABLE
antaghud_indicator = "hudwizard" antaghud_indicator = "hudwizard"
hard_cap = 1 hard_cap = 1
@@ -16,13 +16,15 @@ var/datum/antagonist/technomancer/technomancers
initial_spawn_req = 1 initial_spawn_req = 1
initial_spawn_target = 1 initial_spawn_target = 1
id_type = /obj/item/weapon/card/id/syndicate
/datum/antagonist/technomancer/New() /datum/antagonist/technomancer/New()
..() ..()
technomancers = src technomancers = src
/datum/antagonist/technomancer/update_antag_mob(var/datum/mind/technomancer) /datum/antagonist/technomancer/update_antag_mob(var/datum/mind/technomancer)
..() ..()
technomancer.store_memory("<B>Remember:</B> do not forget to prepare your functions.") technomancer.store_memory("<B>Remember:</B> do not forget to prepare your RIG.")
technomancer.current.real_name = "[pick(wizard_first)] [pick(wizard_second)]" technomancer.current.real_name = "[pick(wizard_first)] [pick(wizard_second)]"
technomancer.current.name = technomancer.current.real_name technomancer.current.name = technomancer.current.real_name
@@ -31,17 +33,22 @@ var/datum/antagonist/technomancer/technomancers
if(!..()) if(!..())
return 0 return 0
technomancer_mob.equip_to_slot_or_del(new /obj/item/clothing/under/color/black(technomancer_mob), slot_w_uniform)
create_id("Technomage", technomancer_mob)
var/obj/item/weapon/rig/light/technomancer/magesuit = new(get_turf(technomancer_mob))
magesuit.seal_delay = 0
technomancer_mob.put_in_hands(magesuit)
technomancer_mob.equip_to_slot_or_del(magesuit,slot_back)
if(magesuit)
magesuit.toggle_seals(src,1)
magesuit.seal_delay = initial(magesuit.seal_delay)
technomancer_mob.equip_to_slot_or_del(new /obj/item/device/radio/headset(technomancer_mob), slot_l_ear) technomancer_mob.equip_to_slot_or_del(new /obj/item/device/radio/headset(technomancer_mob), slot_l_ear)
technomancer_mob.equip_to_slot_or_del(new /obj/item/clothing/under/psysuit(technomancer_mob), slot_w_uniform)
technomancer_mob.equip_to_slot_or_del(new /obj/item/clothing/shoes/laceup(technomancer_mob), slot_shoes)
technomancer_mob.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe/psypurple(technomancer_mob), slot_wear_suit)
technomancer_mob.equip_to_slot_or_del(new /obj/item/clothing/head/wizard/amp(technomancer_mob), slot_head)
if(technomancer_mob.backbag == 2) technomancer_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(technomancer_mob), slot_back) if(technomancer_mob.backbag == 2) technomancer_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(technomancer_mob), slot_back)
if(technomancer_mob.backbag == 3) technomancer_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_norm(technomancer_mob), slot_back) if(technomancer_mob.backbag == 3) technomancer_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_norm(technomancer_mob), slot_back)
if(technomancer_mob.backbag == 4) technomancer_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(technomancer_mob), slot_back) if(technomancer_mob.backbag == 4) technomancer_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(technomancer_mob), slot_back)
technomancer_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/box(technomancer_mob), slot_in_backpack) technomancer_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/box(technomancer_mob), slot_in_backpack)
// technomancer_mob.equip_to_slot_or_del(new /obj/item/weapon/teleportation_scroll(technomancer_mob), slot_r_store) technomancer_mob.equip_to_slot_or_del(new /obj/item/device/flashlight(technomancer_mob), slot_belt)
// technomancer_mob.equip_to_slot_or_del(new /obj/item/weapon/spellbook(technomancer_mob), slot_r_hand)
technomancer_mob.update_icons() technomancer_mob.update_icons()
return 1 return 1
@@ -55,4 +62,4 @@ var/datum/antagonist/technomancer/technomancers
if(!survivor) if(!survivor)
feedback_set_details("round_end_result","loss - technomancer killed") feedback_set_details("round_end_result","loss - technomancer killed")
world << "<span class='danger'><font size = 3>The [(current_antagonists.len>1)?"[role_text_plural] have":"[role_text] has"] been \ world << "<span class='danger'><font size = 3>The [(current_antagonists.len>1)?"[role_text_plural] have":"[role_text] has"] been \
killed by the crew!</font></span>" killed!</font></span>"

View File

@@ -0,0 +1,85 @@
//The base core object, worn on the wizard's back.
/obj/item/weapon/technomancer_core
name = "manipulation core"
desc = "A bewilderingly complex 'black box' that allows the wearer to accomplish amazing feats."
icon_state = "technomancer_core"
item_state = "technomancer_core"
w_class = 5
slot_flags = SLOT_BACK
unacidable = 1
var/energy = 10000
var/max_energy = 10000
var/regen_rate = 50 //200 seconds to full
/obj/item/weapon/technomancer_core/New()
..()
processing_objects |= src
/obj/item/weapon/technomancer_core/Destroy()
processing_objects.Remove(src)
..()
/obj/item/weapon/technomancer_core/proc/pay_energy(amount)
if(amount <= energy)
energy = max(energy - amount, 0)
return 1
return 0
/obj/item/weapon/technomancer_core/process()
regenerate()
/obj/item/weapon/technomancer_core/proc/regenerate()
energy += min(energy + regen_rate, max_energy)
//Resonance Aperture
//Variants which the wizard can buy.
//For those wanting to look like a classic wizard.
/obj/item/weapon/technomancer_core/classic
name = "wizard's cloak"
desc = "It appears to be a simple cloak, however it is actually a deceptively hidden manipulation core. For those who wish to \
fool the Lessers into believing that you are a real magician."
icon_state = "wizard_cloak"
item_state = "wizard_cloak"
//High risk, high reward core.
/obj/item/weapon/technomancer_core/unstable
name = "unstable core"
desc = "A bewilderingly complex 'black box' that allows the wearer to accomplish amazing feats. This one is rather unstable, \
and could prove dangerous to the user, as it feeds off unstable energies that can occur with overuse of this machine."
icon_state = "backpack"
item_state = null
energy = 13000
max_energy = 13000
regen_rate = 35 //~371 seconds to full, 118 seconds to full at 50 instability (rate of 110)
/obj/item/weapon/technomancer_core/unstable/regenerate()
var/instability_bonus = 0
if(loc && ishuman(loc))
var/mob/living/carbon/human/H = loc
instability_bonus = H.instability * 1.5
energy += min(energy + regen_rate + instability_bonus, max_energy)
//Lower capacity but safer core.
/obj/item/weapon/technomancer_core/rapid
name = "rapid core"
desc = "A bewilderingly complex 'black box' that allows the wearer to accomplish amazing feats. This one has a superior \
recharge rate, at the price of storage capacity."
icon_state = "backpack"
item_state = null
energy = 7000
max_energy = 7000
regen_rate = 70 //100 seconds to full
//Big batteries but slow regen, buying energy spells is highly recommended.
/obj/item/weapon/technomancer_core/bulky
name = "bulky core"
desc = "A bewilderingly complex 'black box' that allows the wearer to accomplish amazing feats. This variant is more \
cumbersome and bulky, due to the additional energy capacitors installed. It also comes at a price of a subpar fractal \
reactor."
icon_state = "backpack"
item_state = null
energy = 15000
max_energy = 15000
regen_rate = 25 //600 seconds to full

View File

@@ -0,0 +1,148 @@
/mob
var/obj/screen/wizard/instability/wiz_instability_display = null //Unfortunately, this needs to be a mob var due to HUD code.
/mob/living/carbon/human
var/instability = 0
var/last_instability_event = null
/mob/living/carbon/human/proc/adjust_instability(var/amount)
instability = min(max(instability + amount, 0), 200)
instability_update_hud()
/mob/living/carbon/human/proc/instability_update_hud()
if(client && hud_used)
if(istype(back, /obj/item/weapon/technomancer_core)) //I reckon there's a better way of doing this.
wiz_instability_display.invisibility = 0
wiz_instability_display.maptext = instability
switch(instability)
if(0)
wiz_instability_display.icon_state = "wiz_instability_none"
if(1 to 14)
wiz_instability_display.icon_state = "wiz_instability_minor-l"
if(15 to 29)
wiz_instability_display.icon_state = "wiz_instability_minor-h"
if(30 to 39)
wiz_instability_display.icon_state = "wiz_instability_moderate-l"
if(40 to 49)
wiz_instability_display.icon_state = "wiz_instability_moderate-h"
if(50 to 74)
wiz_instability_display.icon_state = "wiz_instability_severe-l"
if(75 to 99)
wiz_instability_display.icon_state = "wiz_instability_severe-h"
if(100 to 149)
wiz_instability_display.icon_state = "wiz_instability_lethal-l"
if(150 to 200)
wiz_instability_display.icon_state = "wiz_instability_lethal-h"
else
wiz_instability_display.invisibility = 101
/mob/living/carbon/human/Life()
. = ..()
handle_instability()
/mob/living/carbon/human/proc/handle_instability()
instability = Clamp(instability, 0, 200)
instability_update_hud()
//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(-1)
if(11 to 20)
adjust_instability(-2)
if(21 to 30)
adjust_instability(-3)
if(31 to 40)
adjust_instability(-4)
if(41 to 50)
adjust_instability(-5)
if(51 to 100)
adjust_instability(-10)
if(101 to 200)
adjust_instability(-20)
/mob/living/carbon/human/proc/instability_effects()
if(instability)
var/rng = 0
last_instability_event = world.time
spawn(1)
var/image/instability_flash = image('icons/obj/spells.dmi',"instability")
overlays |= instability_flash
sleep(4)
overlays.Remove(instability_flash)
qdel(instability_flash)
switch(instability)
if(1 to 10) //Harmless
return
if(11 to 30) //Minor
rng = rand(0,1)
switch(rng)
if(0)
var/datum/effect/effect/system/spark_spread/spark_system = PoolOrNew(/datum/effect/effect/system/spark_spread)
spark_system.set_up(5, 0, src)
spark_system.start()
visible_message("<span class='warning'>Electrical sparks manifest from nowhere around \the [src]!</span>")
qdel(spark_system)
if(1)
safe_blink(src, range = 3)
src << "<span class='warning'>You're teleported against your will!</span>"
if(31 to 50) //Moderate
rng = rand(0,8)
switch(rng)
if(0)
apply_effect(instability * 0.5, IRRADIATE)
if(1)
visible_message("<span class='warning'>\The [src] suddenly collapses!</span>",
"<span class='danger'>You suddenly feel very weak, and you fall down!</span>")
Weaken(instability * 0.1)
if(2)
if(can_feel_pain())
apply_effect(instability * 0.5, AGONY)
src << "<span class='danger'>You feel a sharp pain!</span>"
if(3)
apply_effect(instability * 0.5, EYE_BLUR)
src << "<span class='danger'>Your eyes start to get cloudy!</span>"
if(4)
electrocute_act(instability * 0.5, "unstable energies")
if(5)
adjustFireLoss(instability * 0.2) //10 burn @ 50 instability
src << "<span class='danger'>You feel your skin burn!</span>"
if(6)
adjustBruteLoss(instability * 0.2) //10 brute @ 50 instability
src << "<span class='danger'>You feel a sharp pain as an unseen force harms your body!</span>"
if(7)
adjustToxLoss(instability * 0.2) //10 tox @ 50 instability
if(8)
safe_blink(src, range = 6)
src << "<span class='warning'>You're teleported against your will!</span>"
if(51 to 100) //Severe
rng = rand(0,8)
switch(rng)
if(0)
apply_effect(instability * 0.7, IRRADIATE)
if(1)
visible_message("<span class='warning'>\The [src] suddenly collapses!</span>",
"<span class='danger'>You suddenly feel very light-headed, and faint!</span>")
Paralyse(instability * 0.1)
if(2)
if(can_feel_pain())
apply_effect(instability * 0.7, AGONY)
src << "<span class='danger'>You feel an extremly angonizing pain from all over your body!</span>"
if(3)
apply_effect(instability * 0.5, EYE_BLUR)
src << "<span class='danger'>Your eyes start to get cloudy!</span>"
if(4)
electrocute_act(instability * 0.7, "extremely unstable energies")
if(5)
fire_act()
src << "<span class='danger'>You spontaneously combust!</span>"
if(6)
adjustCloneLoss(instability * 0.05) //5 cloneloss @ 100 instability
src << "<span class='danger'>You feel your body slowly degenerating.</span>"
if(7)
adjustToxLoss(instability * 0.25) //25 tox @ 100 instability
if(101 to 200) //Lethal
return

View File

@@ -1,8 +1,24 @@
#define CAST_USE 1 //cast_method flags
#define CAST_MELEE 2 #define CAST_USE 1 //Clicking the spell in your hand.
#define CAST_RANGED 4 #define CAST_MELEE 2 //Clicking an atom in melee range.
#define CAST_THROW 8 #define CAST_RANGED 4 //Clicking an atom beyond melee range.
#define CAST_COMBINE 16 #define CAST_THROW 8 //Throwing the spell and hitting an atom.
#define CAST_COMBINE 16 //Clicking another spell with this spell.
#define CAST_INNATE 32 //Activates upon verb usage, used for mobs without hands.
//Aspects
#define ASPECT_FIRE "fire" //Damage over time and raising body-temp. Firesuits protect from this.
#define ASPECT_FROST "frost" //Slows down the affected, also involves imbedding with icicles. Winter coats protect from this.
#define ASPECT_SHOCK "shock" //Energy-expensive, usually stuns. Insulated armor protects from this.
#define ASPECT_AIR "air" //Mostly involves manipulation of atmos, useless in a vacuum. Magboots protect from this.
#define ASPECT_FORCE "force" //Manipulates gravity to push things away or towards a location.
#define ASPECT_TELE "tele" //Teleportation of self, other objects, or other people.
#define ASPECT_DARK "dark" //Makes all those photons vanish using magic-- WITH SCIENCE. Used for sneaky stuff.
#define ASPECT_LIGHT "light" //The opposite of dark, usually blinds, makes holo-illusions, or makes laser lightshows.
#define ASPECT_EMP "emp" //Self explainitory.
#define ASPECT_CHAOS "chaos" //Heavily RNG-based, causes instability to the victim.
#define ASPECT_CHROMATIC "chromatic" //Used to combine with other spells.
/obj/item/weapon/spell /obj/item/weapon/spell
name = "glowing particles" name = "glowing particles"
@@ -10,14 +26,17 @@
icon = 'icons/obj/spells.dmi' icon = 'icons/obj/spells.dmi'
icon_state = "generic" icon_state = "generic"
item_icons = list( item_icons = list(
slot_l_hand_str = 'icons/mob/items/lefthand_spells.dmi', slot_l_hand_str = 'icons/mob/items/lefthand_spells.dmi',
slot_r_hand_str = 'icons/mob/items/righthand_spells.dmi', slot_r_hand_str = 'icons/mob/items/righthand_spells.dmi',
) )
throwforce = 0 throwforce = 0
force = 0 force = 0
var/mob/living/carbon/human/owner = null var/mob/living/carbon/human/owner = null
var/obj/item/weapon/technomancer_core/core = null
var/cost = 0 var/cost = 0
var/cast_methods = null var/cast_methods = null
var/aspect = null
var/toggled = 0 //Mainly used for overlays
/obj/item/weapon/spell/proc/on_use_cast(mob/user) /obj/item/weapon/spell/proc/on_use_cast(mob/user)
return return
@@ -34,18 +53,52 @@
/obj/item/weapon/spell/proc/on_combine_cast(obj/item/W, mob/user) /obj/item/weapon/spell/proc/on_combine_cast(obj/item/W, mob/user)
return return
//TODO
/obj/item/weapon/spell/proc/pay_energy(var/amount)
if(!core)
return 0
return core.pay_energy(amount)
/obj/item/weapon/spell/proc/give_energy(var/amount)
return 1
/obj/item/weapon/spell/proc/adjust_instability(var/amount)
if(!owner)
return 0
owner.adjust_instability(amount)
/obj/item/weapon/spell/New() /obj/item/weapon/spell/New()
..() ..()
if(ishuman(loc)) if(ishuman(loc))
owner = loc owner = loc
if(owner)
if(istype(/obj/item/weapon/technomancer_core, owner.back))
core = owner.back
update_icon()
/obj/item/weapon/spell/Destroy() /obj/item/weapon/spell/Destroy()
owner = null owner = null
..() ..()
/obj/item/weapon/spell/update_icon()
if(toggled)
var/image/new_overlay = image('icons/obj/spells.dmi',"toggled")
overlays |= new_overlay
else
overlays.Cut()
..()
/obj/item/weapon/spell/proc/run_checks() /obj/item/weapon/spell/proc/run_checks()
if(!owner) if(!owner)
return 0 return 0
if(!core)
core = locate(/obj/item/weapon/technomancer_core) in owner
if(!core)
owner << "<span class='danger'>You need to be wearing a core on your back!</span>"
return 0
if(core.loc != owner || owner.back != core) //Make sure the core's being worn.
owner << "<span class='danger'>You need to be wearing a core on your back!</span>"
return 0
return 1 return 1
/obj/item/weapon/spell/attack_self(mob/user) /obj/item/weapon/spell/attack_self(mob/user)
@@ -56,8 +109,9 @@
/obj/item/weapon/spell/attackby(obj/item/W, mob/user) /obj/item/weapon/spell/attackby(obj/item/W, mob/user)
if(istype(W, /obj/item/weapon/spell)) if(istype(W, /obj/item/weapon/spell))
var/obj/item/weapon/spell/spell = W
if(run_checks() & (cast_methods & CAST_COMBINE)) if(run_checks() & (cast_methods & CAST_COMBINE))
on_combine_cast(W, user) spell.on_combine_cast(src, user)
else else
..() ..()
@@ -70,11 +124,16 @@
on_ranged_cast(target, user) on_ranged_cast(target, user)
world << "range cast called" world << "range cast called"
else else
if(cast_methods & CAST_COMBINE) //For some reason attackby() won't work for this.
if(istype(target, /obj/item/weapon/spell))
var/obj/item/weapon/spell/spell = target
spell.on_combine_cast(src, user)
return
if(cast_methods & CAST_MELEE) if(cast_methods & CAST_MELEE)
if(..()) //Check that we didn't miss. // if(..()) //Check that we didn't miss.
on_melee_cast(target, user) on_melee_cast(target, user)
world << "melee cast called" world << "melee cast called"
else if(cast_methods & CAST_RANGED) else if(cast_methods & CAST_RANGED) //Try to use a ranged method if a melee one doesn't exist.
on_ranged_cast(target, user) on_ranged_cast(target, user)
world << "range cast called" world << "range cast called"
@@ -112,13 +171,105 @@
H.place_spell_in_hand(/obj/item/weapon/spell/darkness) H.place_spell_in_hand(/obj/item/weapon/spell/darkness)
/mob/verb/radiance()
set category = "Functions"
set name = "Radiance()"
set src = usr
if(!ishuman(src))
return 0
var/mob/living/carbon/human/H = src
H.place_spell_in_hand(/obj/item/weapon/spell/radiance)
/mob/verb/purify()
set category = "Functions"
set name = "Purify()"
set src = usr
if(!ishuman(src))
return 0
var/mob/living/carbon/human/H = src
H.place_spell_in_hand(/obj/item/weapon/spell/purify)
/mob/verb/disable_technology()
set category = "Functions"
set name = "Disable_Technology()"
set src = usr
if(!ishuman(src))
return 0
var/mob/living/carbon/human/H = src
H.place_spell_in_hand(/obj/item/weapon/spell/pulsar)
/mob/verb/passwall()
set category = "Functions"
set name = "Passwall()"
set src = usr
if(!ishuman(src))
return 0
var/mob/living/carbon/human/H = src
H.place_spell_in_hand(/obj/item/weapon/spell/passwall)
/mob/verb/phase_shift()
set category = "Functions"
set name = "Phase_Shift()"
set src = usr
if(!ishuman(src))
return 0
var/mob/living/carbon/human/H = src
H.place_spell_in_hand(/obj/item/weapon/spell/phase_shift)
/mob/verb/warp_strike()
set category = "Functions"
set name = "Warp_Strike()"
set src = usr
if(!ishuman(src))
return 0
var/mob/living/carbon/human/H = src
H.place_spell_in_hand(/obj/item/weapon/spell/warp_strike)
/mob/verb/discharge()
set category = "Functions"
set name = "Discharge()"
set src = usr
if(!ishuman(src))
return 0
var/mob/living/carbon/human/H = src
H.place_spell_in_hand(/obj/item/weapon/spell/discharge)
/mob/verb/aspect_bolt()
set category = "Functions"
set name = "Aspect Bolt()"
set src = usr
if(!ishuman(src))
return 0
var/mob/living/carbon/human/H = src
H.place_spell_in_hand(/obj/item/weapon/spell/aspect_bolt)
/mob/living/carbon/human/proc/place_spell_in_hand(var/path) /mob/living/carbon/human/proc/place_spell_in_hand(var/path)
if(!path || !ispath(path))
return 0
if(src.l_hand && src.r_hand) //Make sure our hands aren't full. if(src.l_hand && src.r_hand) //Make sure our hands aren't full.
src << "<span class='warning'>You require a free hand to use a function.</span>" src << "<span class='warning'>You require a free hand to use a function.</span>"
return 0 return 0
var/obj/item/weapon/spell/S = PoolOrNew(path, src) var/obj/item/weapon/spell/S = PoolOrNew(path, src)
src.put_in_hands(S) if(S.run_checks())
src.put_in_hands(S)
else
qdel(S)
/obj/item/weapon/spell/dropped() /obj/item/weapon/spell/dropped()
spawn(1) spawn(1)

View File

@@ -0,0 +1,9 @@
//Returns 1 if the turf is dense, or if there's dense objects on it, unless told to ignore them.
/turf/proc/check_density(var/ignore_objs = 0)
if(density)
return 1
if(!ignore_objs)
for(var/atom/movable/stuff in contents)
if(stuff.density)
return 1
return 0

View File

@@ -11,6 +11,7 @@
icon_state = "apportation" icon_state = "apportation"
desc = "Allows you to reach through Bluespace with your hand, and grab something, bringing it to you instantly." desc = "Allows you to reach through Bluespace with your hand, and grab something, bringing it to you instantly."
cast_methods = CAST_RANGED cast_methods = CAST_RANGED
aspect = ASPECT_TELE
/obj/item/weapon/spell/apportation/on_ranged_cast(atom/hit_atom, mob/user) /obj/item/weapon/spell/apportation/on_ranged_cast(atom/hit_atom, mob/user)
if(istype(hit_atom, /atom/movable)) if(istype(hit_atom, /atom/movable))

View File

@@ -0,0 +1,25 @@
/datum/power/technomancer/aspect_bolt
name = "Aspect Bolt"
desc = "This bolt function takes on the properties of other functions based on which aspect is introduced to it."
verbpath = /mob/living/carbon/human/proc/technomancer_aspect_bolt
/mob/living/carbon/human/proc/technomancer_aspect_bolt()
place_spell_in_hand(/obj/item/weapon/spell/aspect_bolt)
/obj/item/weapon/spell/aspect_bolt
name = "aspect bolt"
desc = "Combine this with another spell to finish the function."
icon_state = "aspect_bolt"
cast_methods = CAST_COMBINE
aspect = ASPECT_CHROMATIC
/obj/item/weapon/spell/aspect_bolt/on_combine_cast(obj/item/W, mob/user)
if(istype(W, /obj/item/weapon/spell))
var/obj/item/weapon/spell/spell = W
if(!spell.aspect || spell.aspect == ASPECT_CHROMATIC)
user << "<span class='warning'>You cannot combine \the [spell] with \the [src], as the aspects are incompatable.</span>"
return
switch(spell.aspect)
if(ASPECT_FIRE)
world << "Ideal."

View File

@@ -12,6 +12,7 @@
desc = "Teleports you or someone else a short distance away." desc = "Teleports you or someone else a short distance away."
icon_state = "blink" icon_state = "blink"
cast_methods = CAST_RANGED | CAST_MELEE | CAST_USE cast_methods = CAST_RANGED | CAST_MELEE | CAST_USE
aspect = ASPECT_TELE
/proc/safe_blink(atom/movable/AM, var/range = 3) /proc/safe_blink(atom/movable/AM, var/range = 3)
if(AM.anchored || !AM.loc) if(AM.anchored || !AM.loc)
@@ -21,7 +22,7 @@
valid_turfs: valid_turfs:
for(var/turf/simulated/T in view(AM, range)) for(var/turf/simulated/T in view(AM, range))
if(T.density || istype(T, /turf/simulated/mineral)) if(T.density || istype(T, /turf/simulated/mineral)) //Don't blink to vacuum or a wall
continue continue
for(var/atom/movable/stuff in T.contents) for(var/atom/movable/stuff in T.contents)
if(stuff.density) if(stuff.density)

View File

@@ -11,6 +11,8 @@
desc = "Not even light can stand in your way now." desc = "Not even light can stand in your way now."
icon_state = "darkness" icon_state = "darkness"
cast_methods = CAST_RANGED cast_methods = CAST_RANGED
aspect = ASPECT_DARK
toggled = 1
/obj/item/weapon/spell/darkness/New() /obj/item/weapon/spell/darkness/New()
..() ..()

View File

@@ -0,0 +1,53 @@
/datum/power/technomancer/discharge
name = "Discharge"
desc = "Attempts to steal energy from your target, electrocuting it and anyone holding it."
verbpath = /mob/living/carbon/human/proc/technomancer_discharge
/mob/living/carbon/human/proc/technomancer_discharge()
place_spell_in_hand(/obj/item/weapon/spell/discharge)
/obj/item/weapon/spell/discharge
name = "discharge"
desc = "The economical solution for when you want to zap someone to death."
icon_state = "generic"
cast_methods = CAST_RANGED
aspect = ASPECT_SHOCK
var/datum/effect/effect/system/spark_spread/sparks
/obj/item/weapon/spell/discharge/New()
..()
sparks = PoolOrNew(/datum/effect/effect/system/spark_spread)
sparks.set_up(5, 0, src)
sparks.attach(loc)
/obj/item/weapon/spell/discharge/on_ranged_cast(atom/hit_atom, mob/user)
var/turf/T = get_turf(hit_atom)
if(T)
var/mob/living/victim = null
for(var/mob/living/L in T.contents)
if(!L.stat)
victim = L
break
if(!victim)
return 0
var/cells = list()
recursive_content_check(victim, cells, recursion_limit = 3, client_check = 0, sight_check = 0, include_mobs = 1, include_objects = 1)
var/drain_factor = isrobot(victim) ? 0.25 : 0.50 //Drain only 25% of the battery if it's a borg.
var/total_charge_drained = 0
for(var/obj/item/weapon/cell/cell in cells)
var/to_drain = cell.charge * drain_factor
// var/to_drain = (cell.maxcharge - cell.charge) * drain_factor
// cell.drain_power(0,0,to_drain)
cell.charge = max(cell.charge - to_drain, 0)
total_charge_drained += to_drain
//Updates icons, so guns look drained when this hits them.
if(istype(loc, /obj))
var/obj/O = loc
O.update_icon()
var/damage_amount = round( min( total_charge_drained / 250, 25) ) //Caps damage at 25.
var/steal_amount = round(total_charge_drained / 50)
victim.adjustFireLoss(damage_amount)
user << "DEBUG: You would have drained [total_charge_drained] kW from [victim], which converts to [steal_amount]. [victim] was hurt for [damage_amount]."

View File

@@ -0,0 +1,63 @@
/datum/power/technomancer/flame_tongue
name = "Flame Tongue"
desc = "Using a miniturized flamethrower in your gloves, you can emit a flame strong enough to melt both your enemies and walls."
verbpath = /mob/living/carbon/human/proc/technomancer_flame_tongue
/mob/living/carbon/human/proc/technomancer_flame_tongue()
place_spell_in_hand(/obj/item/weapon/spell/flame_tongue)
/obj/item/weapon/spell/flame_tongue
name = "flame tongue"
icon_state = "flame_tongue"
desc = "Burn!"
cast_methods = CAST_MELEE
aspect = ASPECT_FIRE
var/obj/item/weapon/weldingtool/spell/welder = null
/obj/item/weapon/spell/flame_tongue/New()
..()
set_light(3, 2, l_color = "#FF6A00")
visible_message("<span class='warning'>\The [loc]'s hand begins to emit a flame.</span>")
welder = new /obj/item/weapon/weldingtool/spell(src)
welder.setWelding(1)
/obj/item/weapon/spell/flame_tongue/Destroy()
qdel(welder)
welder = null
..()
/obj/item/weapon/weldingtool/spell
name = "flame"
/obj/item/weapon/weldingtool/spell/process()
return
//Needed to make the spell welder have infinite fuel. Don't worry, it uses energy instead.
/obj/item/weapon/weldingtool/spell/remove_fuel()
return 1
/obj/item/weapon/weldingtool/spell/eyecheck(mob/user as mob)
return
/obj/item/weapon/spell/flame_tongue/on_melee_cast(atom/hit_atom, mob/living/user, def_zone)
if(isliving(hit_atom))
var/mob/living/L = hit_atom
if(pay_energy(1000))
visible_message("<span class='danger'>\The [user] reaches out towards \the [L] with the flaming hand, and they ignite!</span>")
L << "<span class='danger'>You ignite!</span>"
L.fire_act()
owner.adjust_instability(12)
else
//This is needed in order for the welder to work, and works similarly to grippers.
welder.loc = user
var/resolved = hit_atom.attackby(welder, user)
if(!resolved && welder && hit_atom)
if(pay_energy(500))
welder.attack(hit_atom, user, def_zone)
owner.adjust_instability(4)
if(welder && user && (welder.loc == user))
welder.loc = src
else
welder = null
qdel(src)
return

View File

@@ -0,0 +1,65 @@
/datum/power/technomancer/passwall
name = "Passwall"
desc = "An uncommon function that allows the user to phase through matter (usually walls) in order to enter or exit a room. Be careful you don't pass into \
somewhere dangerous."
verbpath = /mob/living/carbon/human/proc/technomancer_passwall
/mob/living/carbon/human/proc/technomancer_passwall()
place_spell_in_hand(/obj/item/weapon/spell/passwall)
/obj/item/weapon/spell/passwall
name = "passwall"
desc = "No walls can hold you back."
cast_methods = CAST_MELEE
aspect = ASPECT_TELE
var/maximum_distance = 20 //Measured in tiles.
var/busy = 0
/obj/item/weapon/spell/passwall/on_melee_cast(atom/hit_atom, mob/user)
if(busy) //Prevent someone from trying to get two uses of the spell from one instance.
return 0
if(isturf(hit_atom))
var/turf/T = hit_atom //Turf we touched.
var/turf/our_turf = get_turf(user) //Where we are.
if(!T.density)
user << "<span class='warning'>Perhaps you should try using passWALL on a wall.</span>"
return 0
var/direction = get_dir(our_turf, T)
var/total_cost = 0
var/turf/checked_turf = T //Turf we're currently checking for density in the loop below.
var/turf/found_turf = null //Our destination, if one is found.
var/i = maximum_distance
visible_message("<span class='info'>[user] rests a hand on \the [T].</span>")
busy = 1
var/datum/effect/effect/system/spark_spread/spark_system = PoolOrNew(/datum/effect/effect/system/spark_spread)
spark_system.set_up(5, 0, our_turf)
while(i)
checked_turf = get_step(checked_turf, direction) //Advance in the given direction
total_cost += 1000 //Phasing through matter's expensive, you know.
i--
if(!checked_turf.density) //If we found a destination (a non-dense turf), then we can stop.
var/dense_objs_on_turf = 0
for(var/atom/movable/stuff in checked_turf.contents) //Make sure nothing dense is where we want to go, like an airlock or window.
if(stuff.density)
dense_objs_on_turf = 1
if(!dense_objs_on_turf) //If we found a non-dense turf with nothing dense on it, then that's our destination.
found_turf = checked_turf
break
sleep(10)
if(found_turf)
if(user.loc != our_turf)
user << "<span class='warning'>You need to stand still in order to phase through the wall.</span>"
return 0
visible_message("<span class='warning'>[user] appears to phase through \the [T]!</span>")
user << "<span class='info'>You find a destination on the other side of \the [T], and phase through it.</span>"
spark_system.start()
user.forceMove(found_turf)
qdel(src)
return 1
else
user << "<span class='info'>You weren't able to find an open space to go to.</span>"

View File

@@ -0,0 +1,49 @@
/datum/power/technomancer/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."
verbpath = /mob/living/carbon/human/proc/technomancer_phase_shift
/mob/living/carbon/human/proc/technomancer_phase_shift()
place_spell_in_hand(/obj/item/weapon/spell/phase_shift)
/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."
cast_methods = CAST_USE
aspect = ASPECT_TELE
/obj/item/weapon/spell/phase_shift/New()
..()
set_light(3, 2, l_color = "#FA58F4")
/obj/effect/phase_shift
name = "rift"
desc = "There was a maniac here a moment ago..."
icon = 'icons/effects/effects.dmi'
icon_state = "rift"
/obj/effect/phase_shift/ex_act()
return
/obj/effect/phase_shift/New()
..()
set_light(3, 5, l_color = "#FA58F4")
/obj/effect/phase_shift/Destroy()
for(var/atom/movable/AM in contents) //Eject everything out.
AM.forceMove(get_turf(src))
..()
/obj/item/weapon/spell/phase_shift/on_use_cast(mob/user)
if(isturf(user.loc)) //Check if we're not already in a rift.
var/obj/effect/phase_shift/PS = new(get_turf(user))
visible_message("<span class='warning'>[user] vanishes into a pink rift!</span>")
user << "<span class='info'>You create an unstable rift, and go through it. Be sure to not stay too long.</span>"
user.forceMove(PS)
else //We're already in a rift, time to get out.
if(istype(loc, /obj/effect/phase_shift))
var/obj/effect/phase_shift/PS = user.loc
qdel(PS) //Ejecting is handled in Destory()
visible_message("<span class='warning'>[user] reappears from the rift as it collapses.</span>")
qdel(src)

View File

@@ -0,0 +1,49 @@
/datum/power/technomancer/pulsar
name = "Pulsar"
desc = "Emits electronic pulses to destroy, disable, or otherwise harm devices and machines. Be sure to not hit yourself with this."
verbpath = /mob/living/carbon/human/proc/technomancer_pulsar
/mob/living/carbon/human/proc/technomancer_pulsar()
place_spell_in_hand(/obj/item/weapon/spell/pulsar)
/obj/item/weapon/spell/pulsar
name = "pulsar"
desc = "Be sure to not hit yourself!"
icon_state = "radiance"
cast_methods = CAST_RANGED | CAST_THROW
aspect = ASPECT_EMP
/obj/item/weapon/spell/pulsar/New()
..()
set_light(3, 2, l_color = "#2ECCFA")
/obj/effect/pulsar
name = "pulsar"
desc = "Not a real pulsar, but still emits loads of EMP."
icon = 'icons/effects/effects.dmi'
icon_state = "shield2"
var/pulses_remaining = 3
/obj/effect/pulsar/New()
..()
set_light(4, 5, l_color = "#2ECCFA")
spawn(1)
pulse_loop()
/obj/effect/pulsar/proc/pulse_loop()
while(pulses_remaining)
sleep(2 SECONDS)
empulse(src, heavy_range = 1, light_range = 2, log = 1)
pulses_remaining--
qdel(src)
/obj/item/weapon/spell/pulsar/on_ranged_cast(atom/hit_atom, mob/user)
var/turf/T = get_turf(hit_atom)
if(T && pay_energy(4000) )
new /obj/effect/pulsar(T)
user << "<span class='notice'>You create an electromagnetic disturbance on \the [T].</span>"
owner.adjust_instability(8)
qdel(src)
/obj/item/weapon/spell/pulsar/on_throw_cast(atom/hit_atom, mob/user)
empulse(hit_atom, 1, 1, log=1)

View File

@@ -0,0 +1,53 @@
/datum/power/technomancer/purify
name = "Purify"
desc = "Clenses the body of harmful impurities, such as toxins, radiation, viruses, and such."
verbpath = /mob/living/carbon/human/proc/technomancer_purify
/mob/living/carbon/human/proc/technomancer_purify()
place_spell_in_hand(/obj/item/weapon/spell/purify)
/obj/item/weapon/spell/purify
name = "purify"
desc = "Illness and toxins will be no more."
icon_state = "radiance"
cast_methods = CAST_MELEE
toggled = 1
/obj/item/weapon/spell/purify/New()
..()
set_light(3, 2, l_color = "#03A728")
processing_objects |= src
/obj/item/weapon/spell/purify/Destroy()
processing_objects -= src
..()
/obj/item/weapon/spell/purify/process()
owner.adjustToxLoss(-1)
owner.adjustCloneLoss(-1)
owner.radiation = max(owner.radiation - 4, 0)
owner.sdisabilities = 0
owner.disabilities = 0
for(var/datum/disease/D in owner.viruses)
D.cure()
owner.adjust_instability(4)
/obj/item/weapon/spell/purify/on_melee_cast(atom/hit_atom, mob/user)
if(hit_atom == user)
return 0
if(istype(hit_atom, /mob/living))
var/mob/living/L = hit_atom
visible_message("<span class='info'>\The [user] reaches out towards \the [L] with a glowing hand.</span>")
L << "<span class='notice'>Your start to feel a tingling sensation.</span>"
spawn(1)
L.sdisabilities = 0
L.disabilities = 0
for(var/datum/disease/D in L.viruses)
D.cure()
for(var/i = 0, i<25,i++)
if(L)
L.adjustToxLoss(-4)
L.adjustCloneLoss(-4)
L.radiation = max(L.radiation - 8, 0)
sleep(10)
qdel(src)

View File

@@ -0,0 +1,46 @@
/datum/power/technomancer/radiance
name = "Radiance"
desc = "Causes you to be very radiant, glowing brightly in visible light, thermal energy, and deadly ionizing radiation."
verbpath = /mob/living/carbon/human/proc/technomancer_radiance
/mob/living/carbon/human/proc/technomancer_radiance()
place_spell_in_hand(/obj/item/weapon/spell/darkness)
/obj/item/weapon/spell/radiance
name = "radiance"
desc = "You will glow with a radiance similar to that of Supermatter."
icon_state = "radiance"
aspect = ASPECT_LIGHT
var/power = 100
toggled = 1
/obj/item/weapon/spell/radiance/New()
..()
set_light(7, 4, l_color = "#D9D900")
processing_objects |= src
/obj/item/weapon/spell/radiance/Destroy()
processing_objects -= src
..()
/obj/item/weapon/spell/radiance/process()
var/turf/T = get_turf(src)
var/datum/gas_mixture/removed = null
var/datum/gas_mixture/env = null
if(!istype(T, /turf/space))
env = T.return_air()
removed = env.remove(0.25 * env.total_moles) //Remove gas from surrounding area
var/thermal_power = 300 * power
removed.add_thermal_energy(thermal_power)
removed.temperature = between(0, removed.temperature, 10000)
env.merge(removed)
for(var/mob/living/L in range(T, round(sqrt(power / 2))))
var/radius = max(get_dist(L, src), 1)
var/rads = (power / 10) * ( 1 / (radius**2) )
L.apply_effect(rads, IRRADIATE)
owner.adjust_instability(2)

View File

@@ -0,0 +1,46 @@
/datum/power/technomancer/shield
name = "Shield"
desc = "Emits a protective shield fron your hand in front of you, which will protect you from almost anything able to harm you, so long as you can power it."
verbpath = /mob/living/carbon/human/proc/technomancer_shield
/mob/living/carbon/human/proc/technomancer_shield()
place_spell_in_hand(/obj/item/weapon/spell/shield)
/obj/item/weapon/spell/shield
name = "\proper energy shield"
icon_state = "shield"
desc = "A very protective combat shield that'll stop almost anything from hitting you, at least from the front."
aspect = ASPECT_FORCE
toggled = 1
var/damage_to_energy_multiplier = 30.0 //Determines how much energy to charge for blocking, e.g. 20 damage attack = 600 energy cost
var/datum/effect/effect/system/spark_spread/spark_system = null
/obj/item/weapon/spell/shield/New()
..()
set_light(3, 2, l_color = "#006AFF")
spark_system = PoolOrNew(/datum/effect/effect/system/spark_spread)
spark_system.set_up(5, 0, src)
/obj/item/weapon/spell/shield/Destroy()
spark_system = null
..()
/obj/item/weapon/spell/shield/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
if(user.incapacitated())
return 0
var/damage_to_energy_cost = (damage_to_energy_multiplier * damage)
if(!pay_energy(damage_to_energy_cost))
owner << "<span class='danger'>Your shield fades due to lack of energy!</span>"
qdel(src)
return 0
//block as long as they are not directly behind us
var/bad_arc = reverse_direction(user.dir) //arc of directions from which we cannot block
if(check_shield_arc(user, bad_arc, damage_source, attacker))
user.visible_message("<span class='danger'>\The [user]'s [src] blocks [attack_text]!</span>")
spark_system.start()
playsound(user.loc, 'sound/weapons/blade1.ogg', 50, 1)
return 1
return 0

View File

@@ -0,0 +1,81 @@
/datum/power/technomancer/warp_strike
name = "Warp Strike"
desc = "Teleports you next to your target, and attacks them with whatever is in your off-hand, spell or object."
verbpath = /mob/living/carbon/human/proc/technomancer_warp_strike
/mob/living/carbon/human/proc/technomancer_warp_strike()
place_spell_in_hand(/obj/item/weapon/spell/warp_strike)
/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 = "warp_strike"
cast_methods = CAST_RANGED
aspect = ASPECT_TELE
var/datum/effect/effect/system/spark_spread/sparks
/obj/item/weapon/spell/warp_strike/New()
..()
sparks = PoolOrNew(/datum/effect/effect/system/spark_spread)
sparks.set_up(5, 0, src)
sparks.attach(loc)
/obj/item/weapon/spell/warp_strike/on_ranged_cast(atom/hit_atom, mob/user)
var/turf/T = get_turf(hit_atom)
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
if(!chosen_target)
return 0
//Now we handle picking a place for the user to teleport to.
var/list/tele_target_candidates = view(get_turf(chosen_target), 1)
var/list/valid_tele_targets = list()
var/turf/tele_target = null
for(var/turf/checked_turf in tele_target_candidates)
if(!checked_turf.check_density())
valid_tele_targets.Add(checked_turf)
tele_target = pick(valid_tele_targets)
//Pay for our teleport.
if(!pay_energy(2000) || !tele_target)
return 0
//Teleporting time.
user.forceMove(tele_target)
var/new_dir = get_dir(user, chosen_target)
user.dir = new_dir
sparks.start()
owner.adjust_instability(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.
if(I)
if(is_path_in_list(I.type, blacklisted_items))
user << "<span class='danger'>You can't use \the [I] while warping!</span>"
return
if(istype(I, /obj/item/weapon))
var/obj/item/weapon/W = I
W.attack(chosen_target, user)
W.afterattack(chosen_target, user)
else
I.attack(chosen_target, user)
I.afterattack(chosen_target, user)
else
chosen_target.attack_hand(user)

View File

@@ -1,10 +1,11 @@
/datum/game_mode/technomancer /datum/game_mode/technomancer
name = "Technomancer" name = "Technomancer"
round_description = "To be written" round_description = "An entity possessing advanced, unknown technology is onboard, who is capable of accomplishing amazing feats."
extended_round_description = "To be written." extended_round_description = "To be written."
config_tag = "wizard" config_tag = "technomancer"
votable = 1
required_players = 1 required_players = 1
required_players_secret = 8 required_players_secret = 8
required_enemies = 1 required_enemies = 1
end_on_antag_death = 0 end_on_antag_death = 0
antag_tags = list(MODE_WIZARD) antag_tags = list(MODE_TECHNOMANCER)

View File

@@ -0,0 +1,116 @@
/obj/item/weapon/rig/light/technomancer
name = "technomancer control module"
suit_type = "technomancer"
desc = "An advanced powered armour suit with technology that allows the user to manipulate space around them."
icon_state = "hacker_rig"
req_access = list(access_syndicate)
airtight = 0
seal_delay = 5 //not being vaccum-proof has an upside I guess
helm_type = /obj/item/clothing/head/lightrig/technomancer
chest_type = /obj/item/clothing/suit/lightrig/technomancer
glove_type = /obj/item/clothing/gloves/lightrig/technomancer
boot_type = /obj/item/clothing/shoes/lightrig/technomancer
initial_modules = list(
/obj/item/rig_module/ai_container,
/obj/item/rig_module/electrowarfare_suite,
/obj/item/rig_module/technomancer_core,
/obj/item/rig_module/energy_relay,
/obj/item/rig_module/self_destruct
)
//The technomancer suit is not space-proof. It does however, have good siemens_coefficient values
/obj/item/clothing/head/lightrig/technomancer
name = "HUD"
siemens_coefficient = 0.4
flags = 0
/obj/item/clothing/suit/lightrig/technomancer
siemens_coefficient = 0.4
/obj/item/clothing/shoes/lightrig/technomancer
siemens_coefficient = 0.4
flags = NOSLIP //All the other rigs have magboots anyways, hopefully gives the technomancer suit something more going for it.
/obj/item/clothing/gloves/lightrig/technomancer
siemens_coefficient = 0
//This is required for spells (aka Functions) to, well, function.
/obj/item/rig_module/technomancer_core
name = "manipulation core"
desc = "A bewilderingly complex 'black box' that allows the wearer of the RIG to accomplish amazing feats."
icon_state = "enet"
interface_name = "manipulation core"
interface_desc = "A black box device that allows the user to use functions to alter the enviroment significantly."
permanent = 1
//Supplies power to the technomage's rig, similar to the mech relay, just less shitty.
/obj/item/rig_module/energy_relay
name = "hardsuit power relay"
desc = "A very advanced device that allows the user to effortlessly drain power wirelessly."
icon_state = "powersink"
toggleable = 1
disruptive = 0
active = 1
activate_string = "Enable Power Relay"
deactivate_string = "Disable Power Relay"
interface_name = "tesla energy relay"
interface_desc = "This advanced module drains power wirelessly from dedicated power storage units straight into the suit's internal battery."
/obj/item/rig_module/energy_relay/deactivate()
if(holder && holder.wearer)
holder.wearer << "<span class = 'warning'>Your power relay deactivates.</span>"
active = 0
return ..()
/obj/item/rig_module/power_sink/activate()
if(holder && holder.wearer)
holder.wearer << "<span class = 'warning'>Your power relay activates.</span>"
active = 1
return ..()
//This is a lot of copypasta from the powersink, I'm sorry.
/obj/item/rig_module/energy_relay/process()
if(!holder)
return 0
if(!active)
return 0
var/area/my_area = get_area(holder)
var/mob/living/carbon/human/H
if(holder && holder.wearer)
H = holder.wearer
if(!H || !istype(H))
return 0
if(!holder.cell)
H << "<span class = 'danger'>Your power relay flashes an error; there is no cell in your rig.</span>"
deactivate()
return
if(!my_area.apc)
return
if(holder.cell.fully_charged())
return
// Attempts to drain up to 40kW, determines this value from remaining cell capacity to ensure we don't drain too much..
var/to_drain = min(40000, ((holder.cell.maxcharge - holder.cell.charge) / CELLRATE))
var/target_drained = my_area.apc.drain_power(0,0,to_drain)
if(target_drained <= 0)
H << "<span class = 'danger'>Your power relay flashes a red light; there is no power left in \the [my_area.apc].</span>"
return
holder.cell.give(max(target_drained * CELLRATE), 0)
return 1

View File

@@ -100,6 +100,7 @@ PROBABILITY EXTENDED 1
PROBABILITY MALFUNCTION 1 PROBABILITY MALFUNCTION 1
PROBABILITY MERCENARY 1 PROBABILITY MERCENARY 1
PROBABILITY WIZARD 1 PROBABILITY WIZARD 1
PROBABILITY TECHNOMANCER 1
PROBABILITY CHANGELING 1 PROBABILITY CHANGELING 1
PROBABILITY CULT 1 PROBABILITY CULT 1
PROBABILITY EXTEND-A-TRAITORMONGOUS 6 PROBABILITY EXTEND-A-TRAITORMONGOUS 6

Binary file not shown.

Before

Width:  |  Height:  |  Size: 243 KiB

After

Width:  |  Height:  |  Size: 245 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 687 B

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 658 B

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 170 KiB

After

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 373 KiB

After

Width:  |  Height:  |  Size: 378 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

BIN
icons/obj/technomancer.dmi Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 560 B

View File

@@ -373,11 +373,26 @@
#include "code\game\gamemodes\nuclear\nuclear.dm" #include "code\game\gamemodes\nuclear\nuclear.dm"
#include "code\game\gamemodes\nuclear\pinpointer.dm" #include "code\game\gamemodes\nuclear\pinpointer.dm"
#include "code\game\gamemodes\revolution\revolution.dm" #include "code\game\gamemodes\revolution\revolution.dm"
#include "code\game\gamemodes\technomancer\clothing.dm"
#include "code\game\gamemodes\technomancer\core_obj.dm"
#include "code\game\gamemodes\technomancer\instability.dm"
#include "code\game\gamemodes\technomancer\spell_objs.dm" #include "code\game\gamemodes\technomancer\spell_objs.dm"
#include "code\game\gamemodes\technomancer\spell_objs_helpers.dm"
#include "code\game\gamemodes\technomancer\technomancer.dm" #include "code\game\gamemodes\technomancer\technomancer.dm"
#include "code\game\gamemodes\technomancer\technomancer_rig.dm"
#include "code\game\gamemodes\technomancer\spells\apportation.dm" #include "code\game\gamemodes\technomancer\spells\apportation.dm"
#include "code\game\gamemodes\technomancer\spells\aspect_bolt.dm"
#include "code\game\gamemodes\technomancer\spells\blink.dm" #include "code\game\gamemodes\technomancer\spells\blink.dm"
#include "code\game\gamemodes\technomancer\spells\darkness.dm" #include "code\game\gamemodes\technomancer\spells\darkness.dm"
#include "code\game\gamemodes\technomancer\spells\discharge.dm"
#include "code\game\gamemodes\technomancer\spells\flame_tongue.dm"
#include "code\game\gamemodes\technomancer\spells\passwall.dm"
#include "code\game\gamemodes\technomancer\spells\phase_shift.dm"
#include "code\game\gamemodes\technomancer\spells\pulsar.dm"
#include "code\game\gamemodes\technomancer\spells\purify.dm"
#include "code\game\gamemodes\technomancer\spells\radiance.dm"
#include "code\game\gamemodes\technomancer\spells\shield.dm"
#include "code\game\gamemodes\technomancer\spells\warp_strike.dm"
#include "code\game\gamemodes\traitor\traitor.dm" #include "code\game\gamemodes\traitor\traitor.dm"
#include "code\game\gamemodes\wizard\wizard.dm" #include "code\game\gamemodes\wizard\wizard.dm"
#include "code\game\jobs\_access_defs.dm" #include "code\game\jobs\_access_defs.dm"
@@ -1903,6 +1918,18 @@
#include "code\ZAS\Zone.dm" #include "code\ZAS\Zone.dm"
#include "interface\interface.dm" #include "interface\interface.dm"
#include "interface\skin.dmf" #include "interface\skin.dmf"
#include "local\more_ideal_fucking\ass.dm"
#include "local\more_ideal_fucking\breasts.dm"
#include "local\more_ideal_fucking\defines.dm"
#include "local\more_ideal_fucking\dick.dm"
#include "local\more_ideal_fucking\hand.dm"
#include "local\more_ideal_fucking\helpers.dm"
#include "local\more_ideal_fucking\insert.dm"
#include "local\more_ideal_fucking\manipulate.dm"
#include "local\more_ideal_fucking\mouth.dm"
#include "local\more_ideal_fucking\toilet.dm"
#include "local\more_ideal_fucking\urinate.dm"
#include "local\more_ideal_fucking\vagina.dm"
#include "maps\polaris-1.dmm" #include "maps\polaris-1.dmm"
#include "maps\polaris-2.dmm" #include "maps\polaris-2.dmm"
#include "maps\polaris-3.dmm" #include "maps\polaris-3.dmm"