Baystation Rigsuits

This commit adds baystation's rigsuit system on top of our own hardsuits;
Our own hardsuits still function fine and are around, but these are
available to admins. Next commit will contain balancing and player
implementation stuff.
This commit is contained in:
Tigercat2000
2015-10-05 16:42:00 -07:00
parent 77cb22ef18
commit 4fc91429e5
70 changed files with 5170 additions and 276 deletions
+1 -1
View File
@@ -3,7 +3,7 @@
name = "breath mask"
icon_state = "breath"
item_state = "breath"
flags = MASKCOVERSMOUTH | MASKINTERNALS
flags = MASKCOVERSMOUTH | AIRTIGHT
w_class = 2
gas_transfer_coefficient = 0.10
permeability_coefficient = 0.50
+5 -5
View File
@@ -2,7 +2,7 @@
name = "gas mask"
desc = "A face-covering mask that can be connected to an air supply."
icon_state = "gas_alt"
flags = MASKCOVERSMOUTH | MASKCOVERSEYES | BLOCK_GAS_SMOKE_EFFECT | MASKINTERNALS
flags = MASKCOVERSMOUTH | MASKCOVERSEYES | BLOCK_GAS_SMOKE_EFFECT | AIRTIGHT
flags_inv = HIDEEARS|HIDEEYES|HIDEFACE
w_class = 3.0
item_state = "gas_alt"
@@ -62,7 +62,7 @@
name = "bane mask"
desc = "Only when the station is in flames, do you have my permission to robust."
icon_state = "bane_mask"
flags = MASKCOVERSMOUTH | MASKCOVERSEYES | BLOCK_GAS_SMOKE_EFFECT | MASKINTERNALS
flags = MASKCOVERSMOUTH | MASKCOVERSEYES | BLOCK_GAS_SMOKE_EFFECT | AIRTIGHT
flags_inv = HIDEEARS|HIDEEYES|HIDEFACE
w_class = 3.0
item_state = "bane_mask"
@@ -100,7 +100,7 @@
icon_state = "clown"
item_state = "clown_hat"
species_fit = list("Vox")
flags = MASKCOVERSMOUTH | MASKCOVERSEYES | BLOCK_GAS_SMOKE_EFFECT | MASKINTERNALS | BLOCKHAIR
flags = MASKCOVERSMOUTH | MASKCOVERSEYES | BLOCK_GAS_SMOKE_EFFECT | AIRTIGHT | BLOCKHAIR
/obj/item/clothing/mask/gas/clown_hat/attack_self(mob/user)
@@ -123,7 +123,7 @@
desc = "Some pranksters are truly magical."
icon_state = "wizzclown"
item_state = "wizzclown"
flags = MASKCOVERSMOUTH | MASKCOVERSEYES | BLOCK_GAS_SMOKE_EFFECT | MASKINTERNALS | BLOCKHAIR
flags = MASKCOVERSMOUTH | MASKCOVERSEYES | BLOCK_GAS_SMOKE_EFFECT | AIRTIGHT | BLOCKHAIR
/obj/item/clothing/mask/gas/virusclown_hat
name = "clown wig and mask"
@@ -178,7 +178,7 @@
desc = "Twoooo!"
icon_state = "owl"
species_fit = list("Vox")
flags = MASKCOVERSMOUTH | MASKCOVERSEYES | BLOCK_GAS_SMOKE_EFFECT | MASKINTERNALS | NODROP
flags = MASKCOVERSMOUTH | MASKCOVERSEYES | BLOCK_GAS_SMOKE_EFFECT | AIRTIGHT | NODROP
var/cooldown = 0
action_button_name = "Hoot"
+1 -1
View File
@@ -160,7 +160,7 @@
icon_state = "pennywise_mask"
item_state = "pennywise_mask"
species_fit = list("Vox")
flags = MASKCOVERSMOUTH | MASKCOVERSEYES | BLOCK_GAS_SMOKE_EFFECT | MASKINTERNALS | BLOCKHAIR
flags = MASKCOVERSMOUTH | MASKCOVERSEYES | BLOCK_GAS_SMOKE_EFFECT | AIRTIGHT | BLOCKHAIR
// Bandanas
/obj/item/clothing/mask/bandana
@@ -0,0 +1,248 @@
/*
* Contains
* /obj/item/rig_module/grenade_launcher
* /obj/item/rig_module/mounted
* /obj/item/rig_module/mounted/taser
* /obj/item/rig_module/shield
* /obj/item/rig_module/fabricator
* /obj/item/rig_module/device/flash
*/
/obj/item/rig_module/device/flash
name = "mounted flash"
desc = "You are the law."
icon_state = "flash"
interface_name = "mounted flash"
interface_desc = "Stuns your target by blinding them with a bright light."
device_type = /obj/item/device/flash
/obj/item/rig_module/grenade_launcher
name = "mounted grenade launcher"
desc = "A shoulder-mounted micro-explosive dispenser."
selectable = 1
icon_state = "grenade"
interface_name = "integrated grenade launcher"
interface_desc = "Discharges loaded grenades against the wearer's location."
var/fire_force = 30
var/fire_distance = 10
charges = list(
list("flashbang", "flashbang", /obj/item/weapon/grenade/flashbang, 3),
list("smoke bomb", "smoke bomb", /obj/item/weapon/grenade/smokebomb, 3),
list("EMP grenade", "EMP grenade", /obj/item/weapon/grenade/empgrenade, 3),
)
/obj/item/rig_module/grenade_launcher/accepts_item(var/obj/item/input_device, var/mob/living/user)
if(!istype(input_device) || !istype(user))
return 0
var/datum/rig_charge/accepted_item
for(var/charge in charges)
var/datum/rig_charge/charge_datum = charges[charge]
if(input_device.type == charge_datum.product_type)
accepted_item = charge_datum
break
if(!accepted_item)
return 0
if(accepted_item.charges >= 5)
user << "<span class='danger'>Another grenade of that type will not fit into the module.</span>"
return 0
user << "<font color='blue'><b>You slot \the [input_device] into the suit module.</b></font>"
user.unEquip(input_device)
qdel(input_device)
accepted_item.charges++
return 1
/obj/item/rig_module/grenade_launcher/engage(atom/target)
if(!..())
return 0
if(!target)
return 0
var/mob/living/carbon/human/H = holder.wearer
if(!charge_selected)
H << "<span class='danger'>You have not selected a grenade type.</span>"
return 0
var/datum/rig_charge/charge = charges[charge_selected]
if(!charge)
return 0
if(charge.charges <= 0)
H << "<span class='danger'>Insufficient grenades!</span>"
return 0
charge.charges--
var/obj/item/weapon/grenade/new_grenade = new charge.product_type(get_turf(H))
H.visible_message("<span class='danger'>[H] launches \a [new_grenade]!</span>")
new_grenade.throw_at(target,fire_force,fire_distance)
new_grenade.prime()
/obj/item/rig_module/mounted
name = "mounted laser cannon"
desc = "A shoulder-mounted battery-powered laser cannon mount."
selectable = 1
usable = 1
module_cooldown = 0
icon_state = "lcannon"
engage_string = "Configure"
interface_name = "mounted laser cannon"
interface_desc = "A shoulder-mounted cell-powered laser cannon."
var/gun_type = /obj/item/weapon/gun/energy/lasercannon/mounted
var/obj/item/weapon/gun/gun
/obj/item/rig_module/mounted/New()
..()
gun = new gun_type(src)
/obj/item/rig_module/mounted/engage(atom/target)
if(!..())
return 0
if(!target)
gun.attack_self(holder.wearer)
return 1
gun.Fire(target,holder.wearer)
return 1
/obj/item/rig_module/mounted/egun
name = "mounted energy gun"
desc = "A forearm-mounted energy projector."
icon_state = "egun"
interface_name = "mounted energy gun"
interface_desc = "A forearm-mounted suit-powered energy gun."
gun_type = /obj/item/weapon/gun/energy/gun/mounted
/obj/item/rig_module/mounted/taser
name = "mounted taser"
desc = "A palm-mounted nonlethal energy projector."
icon_state = "taser"
usable = 0
suit_overlay_active = "mounted-taser"
suit_overlay_inactive = "mounted-taser"
interface_name = "mounted energy gun"
interface_desc = "A shoulder-mounted cell-powered energy gun."
gun_type = /obj/item/weapon/gun/energy/taser/mounted
/obj/item/rig_module/mounted/energy_blade
name = "energy blade projector"
desc = "A powerful cutting beam projector."
icon_state = "eblade"
activate_string = "Project Blade"
deactivate_string = "Cancel Blade"
interface_name = "spider fang blade"
interface_desc = "A lethal energy projector that can shape a blade projected from the hand of the wearer or launch radioactive darts."
usable = 0
selectable = 1
toggleable = 1
use_power_cost = 50
active_power_cost = 10
passive_power_cost = 0
gun_type = /obj/item/weapon/gun/energy/crossbow/ninja
/obj/item/rig_module/mounted/energy_blade/process()
if(holder && holder.wearer)
if(!(locate(/obj/item/weapon/melee/energy/blade) in holder.wearer))
deactivate()
return 0
return ..()
/obj/item/rig_module/mounted/energy_blade/activate()
..()
var/mob/living/M = holder.wearer
if(M.l_hand && M.r_hand)
M << "<span class='danger'>Your hands are full.</span>"
deactivate()
return
var/obj/item/weapon/melee/energy/blade/blade = new(M)
M.put_in_hands(blade)
/obj/item/rig_module/mounted/energy_blade/deactivate()
..()
var/mob/living/M = holder.wearer
if(!M)
return
for(var/obj/item/weapon/melee/energy/blade/blade in M.contents)
M.unEquip(blade)
qdel(blade)
/obj/item/rig_module/fabricator
name = "matter fabricator"
desc = "A self-contained microfactory system for hardsuit integration."
selectable = 1
usable = 1
use_power_cost = 15
icon_state = "enet"
engage_string = "Fabricate Star"
interface_name = "death blossom launcher"
interface_desc = "An integrated microfactory that produces floor tiles from thin air and electricity."
var/fabrication_type = /obj/item/stack/tile
var/fire_force = 30
var/fire_distance = 10
/obj/item/rig_module/fabricator/engage(atom/target)
if(!..())
return 0
var/mob/living/H = holder.wearer
if(target)
var/obj/item/firing = new fabrication_type()
firing.forceMove(get_turf(src))
H.visible_message("<span class='danger'>[H] launches \a [firing]!</span>")
firing.throw_at(target,fire_force,fire_distance)
else
if(H.l_hand && H.r_hand)
H << "<span class='danger'>Your hands are full.</span>"
else
var/obj/item/new_weapon = new fabrication_type()
new_weapon.forceMove(H)
H << "<font color='blue'><b>You quickly fabricate \a [new_weapon].</b></font>"
H.put_in_hands(new_weapon)
return 1
@@ -0,0 +1,505 @@
/*
* Contains
* /obj/item/rig_module/ai_container
* /obj/item/rig_module/datajack
* /obj/item/rig_module/power_sink
* /obj/item/rig_module/electrowarfare_suite
*/
/obj/item/ai_verbs
name = "AI verb holder"
/obj/item/ai_verbs/verb/hardsuit_interface()
set category = "Hardsuit"
set name = "Open Hardsuit Interface"
set src in usr
if(!usr.loc || !usr.loc.loc || !istype(usr.loc.loc, /obj/item/rig_module))
usr << "You are not loaded into a hardsuit."
return
var/obj/item/rig_module/module = usr.loc.loc
if(!module.holder)
usr << "Your module is not installed in a hardsuit."
return
module.holder.ui_interact(usr, nano_state = contained_state)
/obj/item/rig_module/ai_container
name = "IIS module"
desc = "An integrated intelligence system module suitable for most hardsuits."
icon_state = "IIS"
toggleable = 1
usable = 1
disruptive = 0
activates_on_touch = 1
engage_string = "Eject AI"
activate_string = "Enable Dataspike"
deactivate_string = "Disable Dataspike"
interface_name = "integrated intelligence system"
interface_desc = "A socket that supports a range of artificial intelligence systems."
var/mob/integrated_ai // Direct reference to the actual mob held in the suit.
var/obj/item/ai_card // Reference to the MMI, posibrain, intellicard or pAI card previously holding the AI.
var/obj/item/ai_verbs/verb_holder
/mob
var/get_rig_stats = 0
/obj/item/rig_module/ai_container/process()
if(integrated_ai)
var/obj/item/weapon/rig/rig = get_rig()
if(rig && rig.ai_override_enabled)
integrated_ai.get_rig_stats = 1
else
integrated_ai.get_rig_stats = 0
/mob/living/Stat()
. = ..()
if(. && get_rig_stats)
var/obj/item/weapon/rig/rig = get_rig()
if(rig)
SetupStat(rig)
/obj/item/rig_module/ai_container/proc/update_verb_holder()
if(!verb_holder)
verb_holder = new(src)
if(integrated_ai)
verb_holder.forceMove(integrated_ai)
else
verb_holder.forceMove(src)
/obj/item/rig_module/ai_container/accepts_item(var/obj/item/input_device, var/mob/living/user)
// Check if there's actually an AI to deal with.
var/mob/living/silicon/ai/target_ai
if(istype(input_device, /mob/living/silicon/ai))
target_ai = input_device
else
target_ai = locate(/mob/living/silicon/ai) in input_device.contents
var/obj/item/device/aicard/card = ai_card
// Downloading from/loading to a terminal.
if(istype(input_device,/obj/machinery/computer/aifixer) || istype(input_device,/mob/living/silicon/ai) || istype(input_device,/obj/structure/AIcore/deactivated))
// If we're stealing an AI, make sure we have a card for it.
if(!card)
card = new /obj/item/device/aicard(src)
// Terminal interaction only works with an intellicarded AI.
if(!istype(card))
return 0
// Since we've explicitly checked for three types, this should be safe.
card.afterattack(input_device, user, 1)
// If the transfer failed we can delete the card.
if(locate(/mob/living/silicon/ai) in card)
ai_card = card
integrated_ai = locate(/mob/living/silicon/ai) in card
else
eject_ai()
update_verb_holder()
return 1
if(istype(input_device,/obj/item/device/aicard))
// We are carding the AI in our suit.
if(integrated_ai)
var/obj/item/device/aicard/ext_card = input_device
ext_card.afterattack(integrated_ai, user, 1)
// If the transfer was successful, we can clear out our vars.
if(integrated_ai.loc != src)
integrated_ai = null
eject_ai()
else
// You're using an empty card on an empty suit, idiot.
if(!target_ai)
return 0
integrate_ai(input_device,user)
return 1
// Okay, it wasn't a terminal being touched, check for all the simple insertions.
if(input_device.type in list(/obj/item/device/paicard, /obj/item/device/mmi, /obj/item/device/mmi/posibrain))
if(integrated_ai)
integrated_ai.attackby(input_device,user)
// If the transfer was successful, we can clear out our vars.
if(integrated_ai.loc != src)
integrated_ai = null
eject_ai()
else
integrate_ai(input_device,user)
return 1
return 0
/obj/item/rig_module/ai_container/engage(atom/target)
if(!..())
return 0
var/mob/living/carbon/human/H = holder.wearer
if(!target)
if(ai_card)
if(istype(ai_card,/obj/item/device/aicard))
ai_card.ui_interact(H, state = deep_inventory_state)
else
eject_ai(H)
update_verb_holder()
return 1
if(accepts_item(target,H))
return 1
return 0
/obj/item/rig_module/ai_container/removed()
eject_ai()
..()
/obj/item/rig_module/ai_container/proc/eject_ai(var/mob/user)
if(ai_card)
if(istype(ai_card, /obj/item/device/aicard))
if(integrated_ai && !integrated_ai.stat)
if(user)
user << "<span class='danger'>You cannot eject your currently stored AI. Purge it manually.</span>"
return 0
user << "<span class='danger'>You purge the remaining scraps of data from your previous AI, freeing it for use.</span>"
if(integrated_ai)
integrated_ai.ghostize()
qdel(integrated_ai)
integrated_ai = null
if(ai_card)
qdel(ai_card)
ai_card = null
else if(user)
user.put_in_hands(ai_card)
else
ai_card.forceMove(get_turf(src))
ai_card = null
integrated_ai = null
update_verb_holder()
/obj/item/rig_module/ai_container/proc/integrate_ai(var/obj/item/ai,var/mob/user)
if(!ai) return
// The ONLY THING all the different AI systems have in common is that they all store the mob inside an item.
var/mob/living/ai_mob = locate(/mob/living) in ai.contents
if(ai_mob)
if(ai_mob.key && ai_mob.client)
if(istype(ai, /obj/item/device/aicard))
if(!ai_card)
ai_card = new /obj/item/device/aicard(src)
var/obj/item/device/aicard/source_card = ai
var/obj/item/device/aicard/target_card = ai_card
if(istype(source_card) && istype(target_card))
if(target_card.grab_ai(ai_mob, user))
source_card.clear()
else
return 0
else
return 0
else
user.unEquip(ai)
ai.forceMove(src)
ai_card = ai
ai_mob << "<font color='blue'>You have been transferred to \the [holder]'s [src].</font>"
user << "<font color='blue'>You load [ai_mob] into \the [holder]'s [src].</font>"
integrated_ai = ai_mob
if(!(locate(integrated_ai) in ai_card))
integrated_ai = null
eject_ai()
else
user << "<span class='warning'>There is no active AI within \the [ai].</span>"
else
user << "<span class='warning'>There is no active AI within \the [ai].</span>"
update_verb_holder()
return
/obj/item/rig_module/datajack
name = "datajack module"
desc = "A simple induction datalink module."
icon_state = "datajack"
toggleable = 1
activates_on_touch = 1
usable = 0
activate_string = "Enable Datajack"
deactivate_string = "Disable Datajack"
interface_name = "contact datajack"
interface_desc = "An induction-powered high-throughput datalink suitable for hacking encrypted networks."
var/list/stored_research
/obj/item/rig_module/datajack/New()
..()
stored_research = list()
/obj/item/rig_module/datajack/engage(atom/target)
if(!..())
return 0
if(target)
var/mob/living/carbon/human/H = holder.wearer
if(!accepts_item(target,H))
return 0
return 1
/obj/item/rig_module/datajack/accepts_item(var/obj/item/input_device, var/mob/living/user)
if(istype(input_device,/obj/item/weapon/disk/tech_disk))
user << "You slot the disk into [src]."
var/obj/item/weapon/disk/tech_disk/disk = input_device
if(disk.stored)
if(load_data(disk.stored))
user << "<font color='blue'>Download successful; disk erased.</font>"
disk.stored = null
else
user << "<span class='warning'>The disk is corrupt. It is useless to you.</span>"
else
user << "<span class='warning'>The disk is blank. It is useless to you.</span>"
return 1
// I fucking hate R&D code. This typecheck spam would be totally unnecessary in a sane setup.
else if(istype(input_device,/obj/machinery))
var/datum/research/incoming_files
if(istype(input_device,/obj/machinery/computer/rdconsole))
var/obj/machinery/computer/rdconsole/input_machine = input_device
incoming_files = input_machine.files
else if(istype(input_device,/obj/machinery/r_n_d/server))
var/obj/machinery/r_n_d/server/input_machine = input_device
incoming_files = input_machine.files
else if(istype(input_device,/obj/machinery/mecha_part_fabricator))
var/obj/machinery/mecha_part_fabricator/input_machine = input_device
incoming_files = input_machine.files
if(!incoming_files || !incoming_files.known_tech || !incoming_files.known_tech.len)
user << "<span class='warning'>Memory failure. There is nothing accessible stored on this terminal.</span>"
else
// Maybe consider a way to drop all your data into a target repo in the future.
if(load_data(incoming_files.known_tech))
user << "<font color='blue'>Download successful; local and remote repositories synchronized.</font>"
else
user << "<span class='warning'>Scan complete. There is nothing useful stored on this terminal.</span>"
return 1
return 0
/obj/item/rig_module/datajack/proc/load_data(var/incoming_data)
if(islist(incoming_data))
for(var/entry in incoming_data)
load_data(entry)
return 1
if(istype(incoming_data, /datum/tech))
var/data_found
var/datum/tech/new_data = incoming_data
for(var/datum/tech/current_data in stored_research)
if(current_data.id == new_data.id)
data_found = 1
if(current_data.level < new_data.level)
current_data.level = new_data.level
break
if(!data_found)
stored_research += incoming_data
return 1
return 0
/obj/item/rig_module/electrowarfare_suite
name = "electrowarfare module"
desc = "A bewilderingly complex bundle of fiber optics and chips."
icon_state = "ewar"
toggleable = 1
usable = 0
activate_string = "Enable Countermeasures"
deactivate_string = "Disable Countermeasures"
interface_name = "electrowarfare system"
interface_desc = "An active counter-electronic warfare suite that disrupts AI tracking."
/obj/item/rig_module/electrowarfare_suite/activate()
if(!..())
return
// This is not the best way to handle this, but I don't want it to mess with ling camo
var/mob/living/M = holder.wearer
M.digitalcamo++
/obj/item/rig_module/electrowarfare_suite/deactivate()
if(!..())
return
var/mob/living/M = holder.wearer
M.digitalcamo = max(0,(M.digitalcamo-1))
/* //Not easily compatible with our current powernet, and is
/obj/item/rig_module/power_sink // quite stupid anyways, iyam
name = "hardsuit power sink"
desc = "An heavy-duty power sink."
icon_state = "powersink"
toggleable = 1
activates_on_touch = 1
disruptive = 0
activate_string = "Enable Power Sink"
deactivate_string = "Disable Power Sink"
interface_name = "niling d-sink"
interface_desc = "Colloquially known as a power siphon, this module drains power through the suit hands into the suit battery."
var/atom/interfaced_with // Currently draining power from this device.
var/total_power_drained = 0
var/drain_loc
/obj/item/rig_module/power_sink/deactivate()
if(interfaced_with)
if(holder && holder.wearer)
holder.wearer << "<span class = 'warning'>Your power sink retracts as the module deactivates.</span>"
drain_complete()
interfaced_with = null
total_power_drained = 0
return ..()
/obj/item/rig_module/power_sink/activate()
interfaced_with = null
total_power_drained = 0
return ..()
/obj/item/rig_module/power_sink/engage(atom/target)
if(!..())
return 0
//Target wasn't supplied or we're already draining.
if(interfaced_with)
return 0
if(!target)
return 1
// Are we close enough?
var/mob/living/carbon/human/H = holder.wearer
if(!target.Adjacent(H))
return 0
// Is it a valid power source?
if(target.drain_power(1) <= 0)
return 0
H << "<span class = 'danger'>You begin draining power from [target]!</span>"
interfaced_with = target
drain_loc = interfaced_with.loc
holder.spark_system.start()
playsound(H.loc, 'sound/effects/sparks2.ogg', 50, 1)
return 1
/obj/item/rig_module/power_sink/accepts_item(var/obj/item/input_device, var/mob/living/user)
var/can_drain = input_device.drain_power(1)
if(can_drain > 0)
engage(input_device)
return 1
return 0
/obj/item/rig_module/power_sink/process()
if(!interfaced_with)
return ..()
var/mob/living/carbon/human/H
if(holder && holder.wearer)
H = holder.wearer
if(!H || !istype(H))
return 0
holder.spark_system.start()
playsound(H.loc, 'sound/effects/sparks2.ogg', 50, 1)
if(!holder.cell)
H << "<span class = 'danger'>Your power sink flashes an error; there is no cell in your rig.</span>"
drain_complete(H)
return
if(!interfaced_with || !interfaced_with.Adjacent(H) || !(interfaced_with.loc == drain_loc))
H << "<span class = 'warning'>Your power sink retracts into its casing.</span>"
drain_complete(H)
return
if(holder.cell.fully_charged())
H << "<span class = 'warning'>Your power sink flashes an amber light; your rig cell is full.</span>"
drain_complete(H)
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 = interfaced_with.drain_power(0,0,to_drain)
if(target_drained <= 0)
H << "<span class = 'danger'>Your power sink flashes a red light; there is no power left in [interfaced_with].</span>"
drain_complete(H)
return
holder.cell.give(target_drained * CELLRATE)
total_power_drained += target_drained
return 1
/obj/item/rig_module/power_sink/proc/drain_complete(var/mob/living/M)
if(!interfaced_with)
if(M) M << "<font color='blue'><b>Total power drained:</b> [round(total_power_drained/1000)]kJ.</font>"
else
if(M) M << "<font color='blue'><b>Total power drained from [interfaced_with]:</b> [round(total_power_drained/1000)]kJ.</font>"
interfaced_with.drain_power(0,1,0) // Damage the victim.
drain_loc = null
interfaced_with = null
total_power_drained = 0*/
/*
//Maybe make this use power when active or something
/obj/item/rig_module/emp_shielding
name = "\improper EMP dissipation module"
desc = "A bewilderingly complex bundle of fiber optics and chips."
toggleable = 1
usable = 0
activate_string = "Enable active EMP shielding"
deactivate_string = "Disable active EMP shielding"
interface_name = "active EMP shielding system"
interface_desc = "A highly experimental system that augments the hardsuit's existing EM shielding."
var/protection_amount = 20
/obj/item/rig_module/emp_shielding/activate()
if(!..())
return
holder.emp_protection += protection_amount
/obj/item/rig_module/emp_shielding/deactivate()
if(!..())
return
holder.emp_protection = max(0,(holder.emp_protection - protection_amount))
*/
@@ -0,0 +1,335 @@
/*
* Rigsuit upgrades/abilities.
*/
/datum/rig_charge
var/short_name = "undef"
var/display_name = "undefined"
var/product_type = "undefined"
var/charges = 0
/obj/item/rig_module
name = "hardsuit upgrade"
desc = "It looks pretty sciency."
icon = 'icons/obj/rig_modules.dmi'
icon_state = "module"
var/damage = 0
var/obj/item/weapon/rig/holder
var/module_cooldown = 10
var/next_use = 0
var/toggleable // Set to 1 for the device to show up as an active effect.
var/usable // Set to 1 for the device to have an on-use effect.
var/selectable // Set to 1 to be able to assign the device as primary system.
var/redundant // Set to 1 to ignore duplicate module checking when installing.
var/permanent // If set, the module can't be removed.
var/disruptive = 1 // Can disrupt by other effects.
var/activates_on_touch // If set, unarmed attacks will call engage() on the target.
var/active // Basic module status
var/disruptable // Will deactivate if some other powers are used.
var/use_power_cost = 0 // Power used when single-use ability called.
var/active_power_cost = 0 // Power used when turned on.
var/passive_power_cost = 0 // Power used when turned off.
var/list/charges // Associative list of charge types and remaining numbers.
var/charge_selected // Currently selected option used for charge dispensing.
// Icons.
var/suit_overlay
var/suit_overlay_active // If set, drawn over icon and mob when effect is active.
var/suit_overlay_inactive // As above, inactive.
var/suit_overlay_used // As above, when engaged.
//Display fluff
var/interface_name = "hardsuit upgrade"
var/interface_desc = "A generic hardsuit upgrade."
var/engage_string = "Engage"
var/activate_string = "Activate"
var/deactivate_string = "Deactivate"
var/list/stat_rig_module/stat_modules = new()
/obj/item/rig_module/examine()
..()
switch(damage)
if(0)
usr << "It is undamaged."
if(1)
usr << "It is badly damaged."
if(2)
usr << "It is almost completely destroyed."
/obj/item/rig_module/attackby(obj/item/W as obj, mob/user as mob)
if(istype(W,/obj/item/stack/nanopaste))
if(damage == 0)
user << "There is no damage to mend."
return
user << "You start mending the damaged portions of \the [src]..."
if(!do_after(user,30, target = src) || !W || !src)
return
var/obj/item/stack/nanopaste/paste = W
damage = 0
user << "You mend the damage to [src] with [W]."
paste.use(1)
return
else if(istype(W,/obj/item/stack/cable_coil))
switch(damage)
if(0)
user << "There is no damage to mend."
return
if(2)
user << "There is no damage that you are capable of mending with such crude tools."
return
var/obj/item/stack/cable_coil/cable = W
if(!cable.amount >= 5)
user << "You need five units of cable to repair \the [src]."
return
user << "You start mending the damaged portions of \the [src]..."
if(!do_after(user, 30, target = src) || !W || !src)
return
damage = 1
user << "You mend some of damage to [src] with [W], but you will need more advanced tools to fix it completely."
cable.use(5)
return
..()
/obj/item/rig_module/New()
..()
if(suit_overlay_inactive)
suit_overlay = suit_overlay_inactive
if(charges && charges.len)
var/list/processed_charges = list()
for(var/list/charge in charges)
var/datum/rig_charge/charge_dat = new
charge_dat.short_name = charge[1]
charge_dat.display_name = charge[2]
charge_dat.product_type = charge[3]
charge_dat.charges = charge[4]
if(!charge_selected) charge_selected = charge_dat.short_name
processed_charges[charge_dat.short_name] = charge_dat
charges = processed_charges
stat_modules += new/stat_rig_module/activate(src)
stat_modules += new/stat_rig_module/deactivate(src)
stat_modules += new/stat_rig_module/engage(src)
stat_modules += new/stat_rig_module/select(src)
stat_modules += new/stat_rig_module/charge(src)
// Called when the module is installed into a suit.
/obj/item/rig_module/proc/installed(var/obj/item/weapon/rig/new_holder)
holder = new_holder
return
//Proc for one-use abilities like teleport.
/obj/item/rig_module/proc/engage()
if(damage >= 2)
usr << "<span class='warning'>The [interface_name] is damaged beyond use!</span>"
return 0
if(world.time < next_use)
usr << "<span class='warning'>You cannot use the [interface_name] again so soon.</span>"
return 0
if(!holder || (!(holder.flags & NODROP)))
usr << "<span class='warning'>The suit is not initialized.</span>"
return 0
if(usr.lying || usr.stat || usr.stunned || usr.paralysis || usr.weakened)
usr << "<span class='warning'>You cannot use the suit in this state.</span>"
return 0
if(holder.wearer && holder.wearer.lying)
usr << "<span class='warning'>The suit cannot function while the wearer is prone.</span>"
return 0
if(holder.security_check_enabled && !holder.check_suit_access(usr))
usr << "<span class='danger'>Access denied.</span>"
return 0
if(!holder.check_power_cost(usr, use_power_cost, 0, src, (istype(usr,/mob/living/silicon ? 1 : 0) ) ) )
return 0
next_use = world.time + module_cooldown
return 1
// Proc for toggling on active abilities.
/obj/item/rig_module/proc/activate()
if(active || !engage())
return 0
active = 1
spawn(1)
if(suit_overlay_active)
suit_overlay = suit_overlay_active
else
suit_overlay = null
holder.update_icon()
return 1
// Proc for toggling off active abilities.
/obj/item/rig_module/proc/deactivate()
if(!active)
return 0
active = 0
spawn(1)
if(suit_overlay_inactive)
suit_overlay = suit_overlay_inactive
else
suit_overlay = null
if(holder)
holder.update_icon()
return 1
// Called when the module is uninstalled from a suit.
/obj/item/rig_module/proc/removed()
deactivate()
holder = null
return
// Called by the hardsuit each rig process tick.
/obj/item/rig_module/process()
if(active)
return active_power_cost
else
return passive_power_cost
// Called by holder rigsuit attackby()
// Checks if an item is usable with this module and handles it if it is
/obj/item/rig_module/proc/accepts_item(var/obj/item/input_device)
return 0
/mob/living/carbon/human/Stat()
. = ..()
if(. && istype(back,/obj/item/weapon/rig))
var/obj/item/weapon/rig/R = back
SetupStat(R)
/mob/proc/SetupStat(var/obj/item/weapon/rig/R)
if(R && (R.flags & NODROP) && R.installed_modules.len && statpanel("Hardsuit Modules"))
var/cell_status = R.cell ? "[R.cell.charge]/[R.cell.maxcharge]" : "ERROR"
stat("Suit charge", cell_status)
for(var/obj/item/rig_module/module in R.installed_modules)
{
for(var/stat_rig_module/SRM in module.stat_modules)
if(SRM.CanUse())
stat(SRM.module.interface_name,SRM)
}
/stat_rig_module
parent_type = /atom/movable
var/module_mode = ""
var/obj/item/rig_module/module
/stat_rig_module/New(var/obj/item/rig_module/module)
..()
src.module = module
/stat_rig_module/proc/AddHref(var/list/href_list)
return
/stat_rig_module/proc/CanUse()
return 0
/stat_rig_module/Click()
if(CanUse())
var/list/href_list = list(
"interact_module" = module.holder.installed_modules.Find(module),
"module_mode" = module_mode
)
AddHref(href_list)
module.holder.Topic(usr, href_list)
/stat_rig_module/DblClick()
return Click()
/stat_rig_module/activate/New(var/obj/item/rig_module/module)
..()
name = module.activate_string
if(module.active_power_cost)
name += " ([module.active_power_cost*10]A)"
module_mode = "activate"
/stat_rig_module/activate/CanUse()
return module.toggleable && !module.active
/stat_rig_module/deactivate/New(var/obj/item/rig_module/module)
..()
name = module.deactivate_string
// Show cost despite being 0, if it means changing from an active cost.
if(module.active_power_cost || module.passive_power_cost)
name += " ([module.passive_power_cost*10]P)"
module_mode = "deactivate"
/stat_rig_module/deactivate/CanUse()
return module.toggleable && module.active
/stat_rig_module/engage/New(var/obj/item/rig_module/module)
..()
name = module.engage_string
if(module.use_power_cost)
name += " ([module.use_power_cost*10]E)"
module_mode = "engage"
/stat_rig_module/engage/CanUse()
return module.usable
/stat_rig_module/select/New()
..()
name = "Select"
module_mode = "select"
/stat_rig_module/select/CanUse()
if(module.selectable)
name = module.holder.selected_module == module ? "Selected" : "Select"
return 1
return 0
/stat_rig_module/charge/New()
..()
name = "Change Charge"
module_mode = "select_charge_type"
/stat_rig_module/charge/AddHref(var/list/href_list)
var/charge_index = module.charges.Find(module.charge_selected)
if(!charge_index)
charge_index = 0
else
charge_index = charge_index == module.charges.len ? 1 : charge_index+1
href_list["charge_type"] = module.charges[charge_index]
/stat_rig_module/charge/CanUse()
if(module.charges && module.charges.len)
var/datum/rig_charge/charge = module.charges[module.charge_selected]
name = "[charge.display_name] ([charge.charges]C) - Change"
return 1
return 0
@@ -0,0 +1,199 @@
/*
* Contains
* /obj/item/rig_module/stealth_field
* /obj/item/rig_module/teleporter
* /obj/item/rig_module/fabricator/energy_net
* /obj/item/rig_module/self_destruct
*/
/obj/item/rig_module/stealth_field
name = "active camouflage module"
desc = "A robust hardsuit-integrated stealth module."
icon_state = "cloak"
toggleable = 1
disruptable = 1
disruptive = 0
use_power_cost = 50
active_power_cost = 10
passive_power_cost = 0
module_cooldown = 30
activate_string = "Enable Cloak"
deactivate_string = "Disable Cloak"
interface_name = "integrated stealth system"
interface_desc = "An integrated active camouflage system."
suit_overlay_active = "stealth_active"
suit_overlay_inactive = "stealth_inactive"
/obj/item/rig_module/stealth_field/activate()
if(!..())
return 0
var/mob/living/carbon/human/H = holder.wearer
H << "<font color='blue'><b>You are now invisible to normal detection.</b></font>"
H.invisibility = INVISIBILITY_LEVEL_TWO
anim(get_turf(H), H, 'icons/effects/effects.dmi', "electricity",null,20,null)
H.visible_message("[H.name] vanishes into thin air!",1)
/obj/item/rig_module/stealth_field/deactivate()
if(!..())
return 0
var/mob/living/carbon/human/H = holder.wearer
H << "<span class='danger'>You are now visible.</span>"
H.invisibility = 0
anim(get_turf(H), H,'icons/mob/mob.dmi',,"uncloak",,H.dir)
anim(get_turf(H), H, 'icons/effects/effects.dmi', "electricity",null,20,null)
for(var/mob/O in oviewers(H))
O.show_message("[H.name] appears from thin air!",1)
playsound(get_turf(H), 'sound/effects/stealthoff.ogg', 75, 1)
/obj/item/rig_module/teleporter
name = "teleportation module"
desc = "A complex, sleek-looking, hardsuit-integrated teleportation module."
icon_state = "teleporter"
use_power_cost = 40
redundant = 1
usable = 1
selectable = 1
engage_string = "Emergency Leap"
interface_name = "VOID-shift phase projector"
interface_desc = "An advanced teleportation system. It is capable of pinpoint precision or random leaps forward."
/obj/item/rig_module/teleporter/proc/phase_in(var/mob/M,var/turf/T)
if(!M || !T)
return
holder.spark_system.start()
playsound(T, 'sound/effects/phasein.ogg', 25, 1)
playsound(T, 'sound/effects/sparks2.ogg', 50, 1)
anim(T,M,'icons/mob/mob.dmi',,"phasein",,M.dir)
/obj/item/rig_module/teleporter/proc/phase_out(var/mob/M,var/turf/T)
if(!M || !T)
return
playsound(T, "sparks", 50, 1)
anim(T,M,'icons/mob/mob.dmi',,"phaseout",,M.dir)
/obj/item/rig_module/teleporter/engage(var/atom/target, var/notify_ai)
if(!..()) return 0
var/mob/living/carbon/human/H = holder.wearer
if(!istype(H.loc, /turf))
H << "<span class='warning'>You cannot teleport out of your current location.</span>"
return 0
var/turf/T
if(target)
T = get_turf(target)
else
T = get_teleport_loc(get_turf(H), H, rand(5, 9))
/*if(!T || T.density)
H << "<span class='warning'>You cannot teleport into solid walls.</span>"
return 0*///Who the fuck cares? Ninjas in walls are cool.
if(T.z in config.admin_levels)
H << "<span class='warning'>You cannot use your teleporter on this Z-level.</span>"
return 0
phase_out(H,get_turf(H))
H.forceMove(T)
phase_in(H,get_turf(H))
for(var/obj/item/weapon/grab/G in H.contents)
if(G.affecting)
phase_out(G.affecting,get_turf(G.affecting))
G.affecting.forceMove(locate(T.x+rand(-1,1),T.y+rand(-1,1),T.z))
phase_in(G.affecting,get_turf(G.affecting))
return 1
/*
/obj/item/rig_module/fabricator/energy_net
name = "net projector"
desc = "Some kind of complex energy projector with a hardsuit mount."
icon_state = "enet"
interface_name = "energy net launcher"
interface_desc = "An advanced energy-patterning projector used to capture targets."
engage_string = "Fabricate Net"
fabrication_type = /obj/item/weapon/energy_net
use_power_cost = 70
/obj/item/rig_module/fabricator/energy_net/engage(atom/target)
if(holder && holder.wearer)
if(..(target) && target)
holder.wearer.Beam(target,"n_beam",,10)
return 1
return 0*/
/obj/item/rig_module/self_destruct
name = "self-destruct module"
desc = "Oh my God, Captain. A bomb."
icon_state = "deadman"
usable = 1
active = 1
permanent = 1
engage_string = "Detonate"
interface_name = "dead man's switch"
interface_desc = "An integrated self-destruct module. When the wearer dies, so does the surrounding area. Do not press this button."
/obj/item/rig_module/self_destruct/activate()
return
/obj/item/rig_module/self_destruct/deactivate()
return
/obj/item/rig_module/self_destruct/process()
// Not being worn, leave it alone.
if(!holder || !holder.wearer || !holder.wearer.wear_suit == holder)
return 0
//OH SHIT.
if(holder.wearer.stat == 2)
engage()
/obj/item/rig_module/self_destruct/engage()
explosion(get_turf(src), 1, 2, 4, 5)
if(holder && holder.wearer)
holder.wearer.unEquip(src)
qdel(holder)
qdel(src)
/obj/item/rig_module/self_destruct/small/engage()
explosion(get_turf(src), 0, 0, 3, 4)
if(holder && holder.wearer)
holder.wearer.unEquip(src)
qdel(holder)
qdel(src)
@@ -0,0 +1,489 @@
/* Contains:
* /obj/item/rig_module/device
* /obj/item/rig_module/device/plasmacutter
* /obj/item/rig_module/device/healthscanner
* /obj/item/rig_module/device/drill
* /obj/item/rig_module/device/orescanner
* /obj/item/rig_module/device/rcd
* /obj/item/rig_module/device/anomaly_scanner
* /obj/item/rig_module/maneuvering_jets
* /obj/item/rig_module/foam_sprayer
* /obj/item/rig_module/device/broadcaster
* /obj/item/rig_module/chem_dispenser
* /obj/item/rig_module/chem_dispenser/injector
* /obj/item/rig_module/voice
* /obj/item/rig_module/device/paperdispenser
* /obj/item/rig_module/device/pen
* /obj/item/rig_module/device/stamp
*/
/obj/item/rig_module/device
name = "mounted device"
desc = "Some kind of hardsuit mount."
usable = 0
selectable = 1
toggleable = 0
disruptive = 0
var/device_type
var/obj/item/device
/obj/item/rig_module/device/plasmacutter
name = "hardsuit plasma cutter"
desc = "A lethal-looking industrial cutter."
icon_state = "plasmacutter"
interface_name = "plasma cutter"
interface_desc = "A self-sustaining plasma arc capable of cutting through walls."
suit_overlay_active = "plasmacutter"
suit_overlay_inactive = "plasmacutter"
device_type = /obj/item/weapon/gun/energy/plasmacutter
/obj/item/rig_module/device/healthscanner
name = "health scanner module"
desc = "A hardsuit-mounted health scanner."
icon_state = "scanner"
interface_name = "health scanner"
interface_desc = "Shows an informative health readout when used on a subject."
device_type = /obj/item/device/healthanalyzer
/obj/item/rig_module/device/drill
name = "hardsuit drill mount"
desc = "A very heavy diamond-tipped drill."
icon_state = "drill"
interface_name = "mounted drill"
interface_desc = "A diamond-tipped industrial drill."
suit_overlay_active = "mounted-drill"
suit_overlay_inactive = "mounted-drill"
device_type = /obj/item/weapon/pickaxe/diamonddrill
/obj/item/rig_module/device/anomaly_scanner
name = "hardsuit anomaly scanner"
desc = "You think it's called an Elder Sarsparilla or something."
icon_state = "eldersasparilla"
interface_name = "Alden-Saraspova counter"
interface_desc = "An exotic particle detector commonly used by xenoarchaeologists."
engage_string = "Begin Scan"
usable = 1
selectable = 0
device_type = /obj/item/device/ano_scanner
/obj/item/rig_module/device/orescanner
name = "ore scanner module"
desc = "A clunky old ore scanner."
icon_state = "scanner"
interface_name = "ore detector"
interface_desc = "A sonar system for detecting large masses of ore."
engage_string = "Begin Scan"
usable = 1
selectable = 0
device_type = /obj/item/device/mining_scanner
/*
/obj/item/rig_module/device/rcd
name = "RCD mount"
desc = "A cell-powered rapid construction device for a hardsuit."
icon_state = "rcd"
interface_name = "mounted RCD"
interface_desc = "A device for building or removing walls. Cell-powered."
usable = 1
engage_string = "Configure RCD"
device_type = /obj/item/weapon/rcd/mounted
*/
/obj/item/rig_module/device/New()
..()
if(device_type) device = new device_type(src)
/obj/item/rig_module/device/engage(atom/target)
if(!..() || !device)
return 0
if(!target)
device.attack_self(holder.wearer)
return 1
var/turf/T = get_turf(target)
if(istype(T) && !T.Adjacent(get_turf(src)))
return 0
var/resolved = target.attackby(device,holder.wearer)
if(!resolved && device && target)
device.afterattack(target,holder.wearer,1)
return 1
/obj/item/rig_module/chem_dispenser
name = "mounted chemical dispenser"
desc = "A complex web of tubing and needles suitable for hardsuit use."
icon_state = "injector"
usable = 1
selectable = 0
toggleable = 0
disruptive = 0
engage_string = "Inject"
interface_name = "integrated chemical dispenser"
interface_desc = "Dispenses loaded chemicals directly into the wearer's bloodstream."
charges = list(
list("tricordrazine", "tricordrazine", 0, 80),
list("tramadol", "tramadol", 0, 80),
list("dexalin plus", "dexalinp", 0, 80),
list("antibiotics", "spaceacillin", 0, 80),
list("antitoxins", "anti_toxin", 0, 80),
list("nutrients", "nutriment", 0, 80),
list("hyronalin", "hyronalin", 0, 80),
list("radium", "radium", 0, 80)
)
var/max_reagent_volume = 80 //Used when refilling.
/obj/item/rig_module/chem_dispenser/ninja
interface_desc = "Dispenses loaded chemicals directly into the wearer's bloodstream. This variant is made to be extremely light and flexible."
//just over a syringe worth of each. Want more? Go refill. Gives the ninja another reason to have to show their face.
charges = list(
list("tricordrazine", "tricordrazine", 0, 20),
list("tramadol", "tramadol", 0, 20),
list("dexalin plus", "dexalinp", 0, 20),
list("antibiotics", "spaceacillin", 0, 20),
list("antitoxins", "anti_toxin", 0, 20),
list("nutrients", "nutriment", 0, 80),
list("hyronalin", "hyronalin", 0, 20),
list("radium", "radium", 0, 20)
)
/obj/item/rig_module/chem_dispenser/accepts_item(var/obj/item/input_item, var/mob/living/user)
if(!input_item.is_open_container())
return 0
if(!input_item.reagents || !input_item.reagents.total_volume)
user << "\The [input_item] is empty."
return 0
// Magical chemical filtration system, do not question it.
var/total_transferred = 0
for(var/datum/reagent/R in input_item.reagents.reagent_list)
for(var/chargetype in charges)
var/datum/rig_charge/charge = charges[chargetype]
if(charge.display_name == R.id)
var/chems_to_transfer = R.volume
if((charge.charges + chems_to_transfer) > max_reagent_volume)
chems_to_transfer = max_reagent_volume - charge.charges
charge.charges += chems_to_transfer
input_item.reagents.remove_reagent(R.id, chems_to_transfer)
total_transferred += chems_to_transfer
break
if(total_transferred)
user << "<font color='blue'>You transfer [total_transferred] units into the suit reservoir.</font>"
else
user << "<span class='danger'>None of the reagents seem suitable.</span>"
return 1
/obj/item/rig_module/chem_dispenser/engage(atom/target)
if(!..())
return 0
var/mob/living/carbon/human/H = holder.wearer
if(!charge_selected)
H << "<span class='danger'>You have not selected a chemical type.</span>"
return 0
var/datum/rig_charge/charge = charges[charge_selected]
if(!charge)
return 0
var/chems_to_use = 10
if(charge.charges <= 0)
H << "<span class='danger'>Insufficient chems!</span>"
return 0
else if(charge.charges < chems_to_use)
chems_to_use = charge.charges
var/mob/living/carbon/target_mob
if(target)
if(istype(target,/mob/living/carbon))
target_mob = target
else
return 0
else
target_mob = H
if(target_mob != H)
H << "<span class='danger'>You inject [target_mob] with [chems_to_use] unit\s of [charge.display_name].</span>"
target_mob << "<span class='danger'>You feel a rushing in your veins as [chems_to_use] unit\s of [charge.display_name] [chems_to_use == 1 ? "is" : "are"] injected.</span>"
target_mob.reagents.add_reagent(charge.display_name, chems_to_use)
charge.charges -= chems_to_use
if(charge.charges < 0) charge.charges = 0
return 1
/obj/item/rig_module/chem_dispenser/combat
name = "combat chemical injector"
desc = "A complex web of tubing and needles suitable for hardsuit use."
charges = list(
list("synaptizine", "synaptizine", 0, 30),
list("hyperzine", "hyperzine", 0, 30),
list("oxycodone", "oxycodone", 0, 30),
list("nutrients", "nutriment", 0, 80),
)
interface_name = "combat chem dispenser"
interface_desc = "Dispenses loaded chemicals directly into the bloodstream."
/obj/item/rig_module/chem_dispenser/injector
name = "mounted chemical injector"
desc = "A complex web of tubing and a large needle suitable for hardsuit use."
usable = 0
selectable = 1
disruptive = 1
interface_name = "mounted chem injector"
interface_desc = "Dispenses loaded chemicals via an arm-mounted injector."
/obj/item/rig_module/voice
name = "hardsuit voice synthesiser"
desc = "A speaker box and sound processor."
icon_state = "megaphone"
usable = 1
selectable = 0
toggleable = 0
disruptive = 0
engage_string = "Configure Synthesiser"
interface_name = "voice synthesiser"
interface_desc = "A flexible and powerful voice modulator system."
var/obj/item/voice_changer/voice_holder
/obj/item/rig_module/voice/New()
..()
voice_holder = new(src)
voice_holder.active = 0
/obj/item/rig_module/voice/installed()
..()
holder.speech = src
/obj/item/rig_module/voice/engage()
if(!..())
return 0
var/choice= input("Would you like to toggle the synthesiser or set the name?") as null|anything in list("Enable","Disable","Set Name")
if(!choice)
return 0
switch(choice)
if("Enable")
active = 1
voice_holder.active = 1
usr << "<font color='blue'>You enable the speech synthesiser.</font>"
if("Disable")
active = 0
voice_holder.active = 0
usr << "<font color='blue'>You disable the speech synthesiser.</font>"
if("Set Name")
var/raw_choice = sanitize(input(usr, "Please enter a new name.") as text|null, MAX_NAME_LEN)
if(!raw_choice)
return 0
voice_holder.voice = raw_choice
usr << "<font color='blue'>You are now mimicking <B>[voice_holder.voice]</B>.</font>"
return 1
/obj/item/rig_module/maneuvering_jets
name = "hardsuit maneuvering jets"
desc = "A compact gas thruster system for a hardsuit."
icon_state = "thrusters"
usable = 1
toggleable = 1
selectable = 0
disruptive = 0
suit_overlay_active = "maneuvering_active"
suit_overlay_inactive = null //"maneuvering_inactive"
engage_string = "Toggle Stabilizers"
activate_string = "Activate Thrusters"
deactivate_string = "Deactivate Thrusters"
interface_name = "maneuvering jets"
interface_desc = "An inbuilt EVA maneuvering system that runs off the rig air supply."
var/obj/item/weapon/tank/jetpack/rig/jets
/obj/item/rig_module/maneuvering_jets/engage()
if(!..())
return 0
jets.toggle_rockets()
return 1
/obj/item/rig_module/maneuvering_jets/activate()
if(active)
return 0
active = 1
spawn(1)
if(suit_overlay_active)
suit_overlay = suit_overlay_active
else
suit_overlay = null
holder.update_icon()
if(!jets.on)
jets.toggle()
return 1
/obj/item/rig_module/maneuvering_jets/deactivate()
if(!..())
return 0
if(jets.on)
jets.toggle()
return 1
/obj/item/rig_module/maneuvering_jets/New()
..()
jets = new(src)
/obj/item/rig_module/maneuvering_jets/installed()
..()
jets.holder = holder
jets.ion_trail.set_up(holder)
/obj/item/rig_module/maneuvering_jets/removed()
..()
jets.holder = null
jets.ion_trail.set_up(jets)
/obj/item/rig_module/foam_sprayer
/obj/item/rig_module/device/paperdispenser
name = "hardsuit paper dispenser"
desc = "Crisp sheets."
icon_state = "paper"
interface_name = "paper dispenser"
interface_desc = "Dispenses warm, clean, and crisp sheets of paper."
engage_string = "Dispense"
usable = 1
selectable = 0
device_type = /obj/item/weapon/paper_bin
/obj/item/rig_module/device/paperdispenser/engage(atom/target)
if(!..() || !device)
return 0
if(!target)
device.attack_hand(holder.wearer)
return 1
/obj/item/rig_module/device/pen
name = "mounted pen"
desc = "For mecha John Hancocks."
icon_state = "pen"
interface_name = "mounted pen"
interface_desc = "Signatures with style(tm)."
engage_string = "Change color"
usable = 1
device_type = /obj/item/weapon/pen/multi
/obj/item/rig_module/device/stamp
name = "mounted internal affairs stamp"
desc = "DENIED."
icon_state = "stamp"
interface_name = "mounted stamp"
interface_desc = "Leave your mark."
engage_string = "Toggle stamp type"
usable = 1
var/iastamp
var/deniedstamp
/obj/item/rig_module/device/stamp/New()
..()
iastamp = new /obj/item/weapon/stamp/law(src)
deniedstamp = new /obj/item/weapon/stamp/denied(src)
device = iastamp
/obj/item/rig_module/device/stamp/engage(atom/target)
if(!..() || !device)
return 0
if(!target)
if(device == iastamp)
device = deniedstamp
holder.wearer << "<span class='notice'>Switched to denied stamp.</span>"
else if(device == deniedstamp)
device = iastamp
holder.wearer << "<span class='notice'>Switched to internal affairs stamp.</span>"
return 1
/obj/item/rig_module/welding_tank
name = "welding fuel tank"
desc = "A bluespace welding fuel storage tank for a rigsuit."
icon_state = "welding_tank"
interface_name = "mounted welding fuel tank"
interface_desc = "A minitaure fuel tank used for storage of welding fuel, built into a hardsuit."
engage_string = "Dispense fuel"
var/max_fuel = 300
/obj/item/rig_module/welding_tank/New()
..()
create_reagents(max_fuel)
reagents.add_reagent("fuel", max_fuel)
/obj/item/rig_module/welding_tank/engage(atom/target)
if(!..() || !reagents)
return 0
if(!target)
if(get_fuel() >= 0)
var/obj/item/weapon/weldingtool/W = holder.wearer.get_active_hand()
if(istype(W))
fill_welder(W)
else
W = holder.wearer.get_inactive_hand()
if(istype(W))
fill_welder(W)
else
holder.wearer << "<span class='danger'>Your welding tank is out of fuel!</span>"
/obj/item/rig_module/welding_tank/proc/fill_welder(var/obj/item/weapon/weldingtool/W)
if(!istype(W))
return 0
if(reagents)
if(get_fuel() >= W.max_fuel)
reagents.trans_to(W, W.max_fuel)
else
reagents.trans_to(W, W.max_fuel)
holder.wearer << "<span class='notice'>You hear a faint dripping as your hardsuit welding tank completely empties.</span>"
W.update_icon()
/obj/item/rig_module/welding_tank/proc/get_fuel()
return reagents.get_reagent_amount("fuel")
@@ -0,0 +1,191 @@
/*
* Contains
* /obj/item/rig_module/vision
* /obj/item/rig_module/vision/multi
* /obj/item/rig_module/vision/meson
* /obj/item/rig_module/vision/thermal
* /obj/item/rig_module/vision/nvg
* /obj/item/rig_module/vision/medhud
* /obj/item/rig_module/vision/sechud
*/
/datum/rig_vision
var/mode
var/obj/item/clothing/glasses/glasses
/datum/rig_vision/nvg
mode = "night vision"
/datum/rig_vision/nvg/New()
glasses = new /obj/item/clothing/glasses/night
/datum/rig_vision/thermal
mode = "thermal scanner"
/datum/rig_vision/thermal/New()
glasses = new /obj/item/clothing/glasses/thermal
/datum/rig_vision/meson
mode = "meson scanner"
/datum/rig_vision/meson/New()
glasses = new /obj/item/clothing/glasses/meson
/datum/rig_vision/sechud
mode = "security HUD"
/datum/rig_vision/sechud/New()
glasses = new /obj/item/clothing/glasses/hud/security
/datum/rig_vision/medhud
mode = "medical HUD"
/datum/rig_vision/medhud/New()
glasses = new /obj/item/clothing/glasses/hud/health
/obj/item/rig_module/vision
name = "hardsuit visor"
desc = "A layered, translucent visor system for a hardsuit."
icon_state = "optics"
interface_name = "optical scanners"
interface_desc = "An integrated multi-mode vision system."
usable = 1
toggleable = 1
disruptive = 0
engage_string = "Cycle Visor Mode"
activate_string = "Enable Visor"
deactivate_string = "Disable Visor"
var/datum/rig_vision/vision
var/list/vision_modes = list(
/datum/rig_vision/nvg,
/datum/rig_vision/thermal,
/datum/rig_vision/meson
)
var/vision_index
/obj/item/rig_module/vision/multi
name = "hardsuit optical package"
desc = "A complete visor system of optical scanners and vision modes."
icon_state = "fulloptics"
interface_name = "multi optical visor"
interface_desc = "An integrated multi-mode vision system."
vision_modes = list(/datum/rig_vision/meson,
/datum/rig_vision/nvg,
/datum/rig_vision/thermal,
/datum/rig_vision/sechud,
/datum/rig_vision/medhud)
/obj/item/rig_module/vision/meson
name = "hardsuit meson scanner"
desc = "A layered, translucent visor system for a hardsuit."
icon_state = "meson"
usable = 0
interface_name = "meson scanner"
interface_desc = "An integrated meson scanner."
vision_modes = list(/datum/rig_vision/meson)
/obj/item/rig_module/vision/thermal
name = "hardsuit thermal scanner"
desc = "A layered, translucent visor system for a hardsuit."
icon_state = "thermal"
usable = 0
interface_name = "thermal scanner"
interface_desc = "An integrated thermal scanner."
vision_modes = list(/datum/rig_vision/thermal)
/obj/item/rig_module/vision/nvg
name = "hardsuit night vision interface"
desc = "A multi input night vision system for a hardsuit."
icon_state = "night"
usable = 0
interface_name = "night vision interface"
interface_desc = "An integrated night vision system."
vision_modes = list(/datum/rig_vision/nvg)
/obj/item/rig_module/vision/sechud
name = "hardsuit security hud"
desc = "A simple tactical information system for a hardsuit."
icon_state = "securityhud"
usable = 0
interface_name = "security HUD"
interface_desc = "An integrated security heads up display."
vision_modes = list(/datum/rig_vision/sechud)
/obj/item/rig_module/vision/medhud
name = "hardsuit medical hud"
desc = "A simple medical status indicator for a hardsuit."
icon_state = "healthhud"
usable = 0
interface_name = "medical HUD"
interface_desc = "An integrated medical heads up display."
vision_modes = list(/datum/rig_vision/medhud)
// There should only ever be one vision module installed in a suit.
/obj/item/rig_module/vision/installed()
..()
holder.visor = src
/obj/item/rig_module/vision/engage()
var/starting_up = !active
if(!..() || !vision_modes)
return 0
// Don't cycle if this engage() is being called by activate().
if(starting_up)
holder.wearer << "<font color='blue'>You activate your visual sensors.</font>"
return 1
if(vision_modes.len > 1)
vision_index++
if(vision_index > vision_modes.len)
vision_index = 1
vision = vision_modes[vision_index]
holder.wearer << "<font color='blue'>You cycle your sensors to <b>[vision.mode]</b> mode.</font>"
else
holder.wearer << "<font color='blue'>Your sensors only have one mode.</font>"
return 1
/obj/item/rig_module/vision/New()
..()
if(!vision_modes)
return
vision_index = 1
var/list/processed_vision = list()
for(var/vision_mode in vision_modes)
var/datum/rig_vision/vision_datum = new vision_mode
if(!vision) vision = vision_datum
processed_vision += vision_datum
vision_modes = processed_vision
+895
View File
@@ -0,0 +1,895 @@
#define ONLY_DEPLOY 1
#define ONLY_RETRACT 2
#define SEAL_DELAY 30
/*
* Defines the behavior of hardsuits/rigs/power armour.
*/
/obj/item/weapon/rig
name = "hardsuit control module"
icon = 'icons/obj/rig_modules.dmi'
desc = "A back-mounted hardsuit deployment and control mechanism."
slot_flags = SLOT_BACK
req_one_access = list()
req_access = list()
w_class = 4
// These values are passed on to all component pieces.
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 20)
min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT
max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT
siemens_coefficient = 0.2
permeability_coefficient = 0.1
unacidable = 1
var/interface_path = "hardsuit.tmpl"
var/ai_interface_path = "hardsuit.tmpl"
var/interface_title = "Hardsuit Controller"
var/wearer_move_delay //Used for AI moving.
var/ai_controlled_move_delay = 10
// Keeps track of what this rig should spawn with.
var/suit_type = "hardsuit"
var/list/initial_modules
var/chest_type = /obj/item/clothing/suit/space/new_rig
var/helm_type = /obj/item/clothing/head/helmet/space/new_rig
var/boot_type = /obj/item/clothing/shoes/magboots/rig
var/glove_type = /obj/item/clothing/gloves/rig
var/cell_type = /obj/item/weapon/stock_parts/cell/high
var/air_type = /obj/item/weapon/tank/oxygen
//Component/device holders.
var/obj/item/weapon/tank/air_supply // Air tank, if any.
var/obj/item/clothing/shoes/boots = null // Deployable boots, if any.
var/obj/item/clothing/suit/space/new_rig/chest // Deployable chestpiece, if any.
var/obj/item/clothing/head/helmet/space/new_rig/helmet = null // Deployable helmet, if any.
var/obj/item/clothing/gloves/rig/gloves = null // Deployable gauntlets, if any.
var/obj/item/weapon/stock_parts/cell/cell // Power supply, if any.
var/obj/item/rig_module/selected_module = null // Primary system (used with middle-click)
var/obj/item/rig_module/vision/visor // Kinda shitty to have a var for a module, but saves time.
var/obj/item/rig_module/voice/speech // As above.
var/mob/living/carbon/human/wearer // The person currently wearing the rig.
var/image/mob_icon // Holder for on-mob icon.
var/list/installed_modules = list() // Power consumption/use bookkeeping.
// Rig status vars.
var/open = 0 // Access panel status.
var/locked = 1 // Lock status.
var/subverted = 0
var/interface_locked = 0
var/control_overridden = 0
var/ai_override_enabled = 0
var/security_check_enabled = 1
var/malfunctioning = 0
var/malfunction_delay = 0
var/electrified = 0
var/locked_down = 0
var/seal_delay = SEAL_DELAY
var/sealing // Keeps track of seal status independantly of NODROP.
var/offline = 1 // Should we be applying suit maluses?
var/offline_slowdown = 3 // If the suit is deployed and unpowered, it sets slowdown to this.
var/vision_restriction
var/offline_vision_restriction = 1 // 0 - none, 1 - welder vision, 2 - blind. Maybe move this to helmets.
var/airtight = 1 //If set, will adjust AIRTIGHT and STOPSPRESSUREDMAGE flags on components. Otherwise it should leave them untouched.
var/emp_protection = 0
// Wiring! How exciting.
var/datum/wires/rig/wires
var/datum/effect/effect/system/spark_spread/spark_system
/obj/item/weapon/rig/examine()
usr << "This is \icon[src][src.name]."
usr << "[src.desc]"
if(wearer)
for(var/obj/item/piece in list(helmet,gloves,chest,boots))
if(!piece || piece.loc != wearer)
continue
usr << "\icon[piece] \The [piece] [piece.gender == PLURAL ? "are" : "is"] deployed."
if(src.loc == usr)
usr << "The maintenance panel is [open ? "open" : "closed"]."
usr << "Hardsuit systems are [offline ? "<font color='red'>offline</font>" : "<font color='green'>online</font>"]."
/obj/item/weapon/rig/New()
..()
item_state = icon_state
wires = new(src)
if((!req_access || !req_access.len) && (!req_one_access || !req_one_access.len))
locked = 0
spark_system = new()
spark_system.set_up(5, 0, src)
spark_system.attach(src)
processing_objects |= src
if(initial_modules && initial_modules.len)
for(var/path in initial_modules)
var/obj/item/rig_module/module = new path(src)
installed_modules += module
module.installed(src)
// Create and initialize our various segments.
if(cell_type)
cell = new cell_type(src)
if(air_type)
air_supply = new air_type(src)
if(glove_type)
gloves = new glove_type(src)
verbs |= /obj/item/weapon/rig/proc/toggle_gauntlets
if(helm_type)
helmet = new helm_type(src)
verbs |= /obj/item/weapon/rig/proc/toggle_helmet
if(boot_type)
boots = new boot_type(src)
verbs |= /obj/item/weapon/rig/proc/toggle_boots
if(chest_type)
chest = new chest_type(src)
if(allowed)
chest.allowed = allowed
chest.slowdown = offline_slowdown
verbs |= /obj/item/weapon/rig/proc/toggle_chest
for(var/obj/item/piece in list(gloves,helmet,boots,chest))
if(!istype(piece))
continue
piece.name = "[suit_type] [initial(piece.name)]"
piece.desc = "It seems to be part of a [src.name]."
piece.icon_state = "[initial(icon_state)]"
piece.min_cold_protection_temperature = min_cold_protection_temperature
piece.max_heat_protection_temperature = max_heat_protection_temperature
if(piece.siemens_coefficient > siemens_coefficient) //So that insulated gloves keep their insulation.
piece.siemens_coefficient = siemens_coefficient
piece.permeability_coefficient = permeability_coefficient
piece.unacidable = unacidable
if(islist(armor))
var/list/L = armor
piece.armor = L.Copy()
update_icon(1)
/obj/item/weapon/rig/Destroy()
for(var/obj/item/piece in list(gloves,boots,helmet,chest))
var/mob/living/M = piece.loc
if(istype(M))
M.unEquip(piece)
qdel(piece)
processing_objects -= src
qdel(wires)
wires = null
qdel(spark_system)
spark_system = null
return ..()
/obj/item/weapon/rig/proc/suit_is_deployed()
if(!istype(wearer) || src.loc != wearer || wearer.back != src)
return 0
if(helm_type && !(helmet && wearer.head == helmet))
return 0
if(glove_type && !(gloves && wearer.gloves == gloves))
return 0
if(boot_type && !(boots && wearer.shoes == boots))
return 0
if(chest_type && !(chest && wearer.wear_suit == chest))
return 0
return 1
/obj/item/weapon/rig/proc/reset()
offline = 2
flags &= ~NODROP
for(var/obj/item/piece in list(helmet,boots,gloves,chest))
if(!piece) continue
piece.icon_state = "[initial(icon_state)]"
if(airtight)
piece.flags &= ~(STOPSPRESSUREDMAGE|AIRTIGHT)
update_icon(1)
/obj/item/weapon/rig/proc/toggle_seals(var/mob/living/carbon/human/M, var/mob/living/user, var/instant)
if(sealing) return
if(!check_power_cost(M, 1)) //costs tiny amount of power to unseal/seal
return 0
deploy(M, instant)
var/seal_target = (flags & NODROP)
var/failed_to_seal
flags |= NODROP // No removing the suit while unsealing.
sealing = 1
if(!seal_target && !suit_is_deployed())
M.visible_message("<span class='danger'>[M]'s suit flashes an error light.</span>","<span class='danger'>Your suit flashes an error light. It can't function properly without being fully deployed.</span>")
failed_to_seal = 1
if(!failed_to_seal)
if(!instant)
M.visible_message("<font color='blue'>[M]'s suit emits a quiet hum as it begins to adjust its seals.</font>","<font color='blue'>With a quiet hum, the suit begins running checks and adjusting components.</font>")
if(seal_delay && !do_after(user, seal_delay, target = M))
if(user) user << "<span class='warning'>You must remain still while the suit is adjusting the components.</span>"
failed_to_seal = 1
if(!M)
failed_to_seal = 1
else
for(var/list/piece_data in list(list(M.shoes,boots,"boots",boot_type),list(M.gloves,gloves,"gloves",glove_type),list(M.head,helmet,"helmet",helm_type),list(M.wear_suit,chest,"chest",chest_type)))
var/obj/item/piece = piece_data[1]
var/obj/item/compare_piece = piece_data[2]
var/msg_type = piece_data[3]
var/piece_type = piece_data[4]
if(!piece || !piece_type)
continue
if(!istype(M) || !istype(piece) || !istype(compare_piece) || !msg_type)
if(M) M << "<span class='warning'>You must remain still while the suit is adjusting the components.</span>"
failed_to_seal = 1
break
if(!failed_to_seal && M.back == src && piece == compare_piece)
if(seal_delay && !instant && !do_after(user, seal_delay, needhand = 0, target = M))
failed_to_seal = 1
piece.icon_state = "[initial(icon_state)][!seal_target ? "_sealed" : ""]"
switch(msg_type)
if("boots")
M << "<font color='blue'>\The [piece] [!seal_target ? "seal around your feet" : "relax their grip on your legs"].</font>"
M.update_inv_shoes()
if("gloves")
M << "<font color='blue'>\The [piece] [!seal_target ? "tighten around your fingers and wrists" : "become loose around your fingers"].</font>"
M.update_inv_gloves()
if("chest")
M << "<font color='blue'>\The [piece] [!seal_target ? "cinches tight again your chest" : "releases your chest"].</font>"
M.update_inv_wear_suit()
if("helmet")
M << "<font color='blue'>\The [piece] hisses [!seal_target ? "closed" : "open"].</font>"
M.update_inv_head()
if(helmet)
helmet.update_light(wearer)
//sealed pieces become airtight, protecting against diseases
if (!seal_target)
piece.armor["bio"] = 100
else
piece.armor["bio"] = src.armor["bio"]
else
failed_to_seal = 1
if((M && !(istype(M) && M.back == src) && !istype(M,/mob/living/silicon)) || (!seal_target && !suit_is_deployed()))
failed_to_seal = 1
sealing = null
if(failed_to_seal)
for(var/obj/item/piece in list(helmet,boots,gloves,chest))
if(!piece) continue
piece.icon_state = "[initial(icon_state)][!seal_target ? "" : "_sealed"]"
if(seal_target)
flags |= NODROP
else
flags &= ~NODROP
if(airtight)
update_component_sealed()
update_icon(1)
return 0
// Success!
if(seal_target)
flags &= ~NODROP
else
flags |= NODROP
M << "<font color='blue'><b>Your entire suit [!(flags & NODROP) ? "loosens as the components relax" : "tightens around you as the components lock into place"].</b></font>"
if(!(flags & NODROP))
for(var/obj/item/rig_module/module in installed_modules)
module.deactivate()
if(airtight)
update_component_sealed()
update_icon(1)
/obj/item/weapon/rig/proc/update_component_sealed()
for(var/obj/item/piece in list(helmet,boots,gloves,chest))
if(!(flags & NODROP))
piece.flags &= ~STOPSPRESSUREDMAGE
piece.flags &= ~AIRTIGHT
else
piece.flags |= STOPSPRESSUREDMAGE
piece.flags |= AIRTIGHT
/obj/item/weapon/rig/process()
// If we've lost any parts, grab them back.
var/mob/living/M
for(var/obj/item/piece in list(gloves,boots,helmet,chest))
if(piece.loc != src && !(wearer && piece.loc == wearer))
if(istype(piece.loc, /mob/living))
M = piece.loc
M.unEquip(piece)
piece.forceMove(src)
if(!istype(wearer) || loc != wearer || wearer.back != src || (!(flags & NODROP)) || !cell || cell.charge <= 0)
if(!cell || cell.charge <= 0)
if(electrified > 0)
electrified = 0
if(!offline)
if(istype(wearer))
if(flags & NODROP)
if (offline_slowdown < 3)
wearer << "<span class='danger'>Your suit beeps stridently, and suddenly goes dead.</span>"
else
wearer << "<span class='danger'>Your suit beeps stridently, and suddenly you're wearing a leaden mass of metal and plastic composites instead of a powered suit.</span>"
if(offline_vision_restriction == 1)
wearer << "<span class='danger'>The suit optics flicker and die, leaving you with restricted vision.</span>"
else if(offline_vision_restriction == 2)
wearer << "<span class='danger'>The suit optics drop out completely, drowning you in darkness.</span>"
if(!offline)
offline = 1
else
if(offline)
offline = 0
if(istype(wearer) && !wearer.wearing_rig)
wearer.wearing_rig = src
chest.slowdown = initial(slowdown)
if(offline)
if(offline == 1)
for(var/obj/item/rig_module/module in installed_modules)
module.deactivate()
offline = 2
chest.slowdown = offline_slowdown
return
if(cell && cell.charge > 0 && electrified > 0)
electrified--
if(malfunction_delay > 0)
malfunction_delay--
else if(malfunctioning)
malfunctioning--
malfunction()
for(var/obj/item/rig_module/module in installed_modules)
cell.use(module.process()*10)
/obj/item/weapon/rig/proc/check_power_cost(var/mob/living/user, var/cost, var/use_unconcious, var/obj/item/rig_module/mod, var/user_is_ai)
if(!istype(user))
return 0
var/fail_msg
if(!user_is_ai)
var/mob/living/carbon/human/H = user
if(istype(H) && H.back != src)
fail_msg = "<span class='warning'>You must be wearing \the [src] to do this.</span>"
else if(user.incorporeal_move)
fail_msg = "<span class='warning'>You must be solid to do this.</span>"
if(sealing)
fail_msg = "<span class='warning'>The hardsuit is in the process of adjusting seals and cannot be activated.</span>"
else if(!fail_msg && ((use_unconcious && user.stat > 1) || (!use_unconcious && user.stat)))
fail_msg = "<span class='warning'>You are in no fit state to do that.</span>"
else if(!cell)
fail_msg = "<span class='warning'>There is no cell installed in the suit.</span>"
else if(cost && cell.charge < cost * 10) //TODO: Cellrate?
fail_msg = "<span class='warning'>Not enough stored power.</span>"
if(fail_msg)
user << "[fail_msg]"
return 0
// This is largely for cancelling stealth and whatever.
if(mod && mod.disruptive)
for(var/obj/item/rig_module/module in (installed_modules - mod))
if(module.active && module.disruptable)
module.deactivate()
cell.use(cost*10)
return 1
/obj/item/weapon/rig/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/nano_state = inventory_state)
if(!user)
return
var/list/data = list()
data["primarysystem"] = null
if(selected_module)
data["primarysystem"] = "[selected_module.interface_name]"
data["ai"] = 0
if(src.loc != user)
data["ai"] = 1
var/is_sealed = (flags & NODROP) //1 if NODROP, 0 if no-nodrop
data["seals"] = "[!is_sealed]" //1 if not NODROP (unsealed), 0 if NODROP (sealed)
data["sealing"] = "[src.sealing]"
data["helmet"] = (helmet ? "[helmet.name]" : "None.")
data["gauntlets"] = (gloves ? "[gloves.name]" : "None.")
data["boots"] = (boots ? "[boots.name]" : "None.")
data["chest"] = (chest ? "[chest.name]" : "None.")
data["charge"] = cell ? round(cell.charge,1) : 0
data["maxcharge"] = cell ? cell.maxcharge : 0
data["chargestatus"] = cell ? Floor((cell.charge/cell.maxcharge)*50) : 0
data["emagged"] = subverted
data["coverlock"] = locked
data["interfacelock"] = interface_locked
data["aicontrol"] = control_overridden
data["aioverride"] = ai_override_enabled
data["securitycheck"] = security_check_enabled
data["malf"] = malfunction_delay
var/list/module_list = list()
var/i = 1
for(var/obj/item/rig_module/module in installed_modules)
var/list/module_data = list(
"index" = i,
"name" = "[module.interface_name]",
"desc" = "[module.interface_desc]",
"can_use" = "[module.usable]",
"can_select" = "[module.selectable]",
"can_toggle" = "[module.toggleable]",
"is_active" = "[module.active]",
"engagecost" = module.use_power_cost*10,
"activecost" = module.active_power_cost*10,
"passivecost" = module.passive_power_cost*10,
"engagestring" = module.engage_string,
"activatestring" = module.activate_string,
"deactivatestring" = module.deactivate_string,
"damage" = module.damage
)
if(module.charges && module.charges.len)
module_data["charges"] = list()
var/datum/rig_charge/selected = module.charges[module.charge_selected]
module_data["chargetype"] = selected ? "[selected.display_name]" : "none"
for(var/chargetype in module.charges)
var/datum/rig_charge/charge = module.charges[chargetype]
module_data["charges"] += list(list("caption" = "[chargetype] ([charge.charges])", "index" = "[chargetype]"))
module_list += list(module_data)
i++
if(module_list.len)
data["modules"] = module_list
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, ((src.loc != user) ? ai_interface_path : interface_path), interface_title, 480, 550, state = nano_state)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
/obj/item/weapon/rig/update_icon(var/update_mob_icon)
//TODO: Maybe consider a cache for this (use mob_icon as blank canvas, use suit icon overlay).
overlays.Cut()
if(!mob_icon || update_mob_icon)
var/species_icon = 'icons/mob/rig_back.dmi'
// Since setting mob_icon will override the species checks in
// update_inv_wear_suit(), handle species checks here.
if(wearer && sprite_sheets && sprite_sheets[wearer.get_species()])
species_icon = sprite_sheets[wearer.get_species()]
mob_icon = image("icon" = species_icon, "icon_state" = "[icon_state]")
if(installed_modules.len)
for(var/obj/item/rig_module/module in installed_modules)
if(module.suit_overlay)
chest.overlays += image("icon" = 'icons/mob/rig_modules.dmi', "icon_state" = "[module.suit_overlay]", "dir" = SOUTH)
if(wearer)
wearer.update_inv_shoes()
wearer.update_inv_gloves()
wearer.update_inv_head()
wearer.update_inv_wear_suit()
wearer.update_inv_back()
return
/obj/item/weapon/rig/proc/check_suit_access(var/mob/living/carbon/human/user)
if(!security_check_enabled)
return 1
if(istype(user))
if(malfunction_check(user))
return 0
if(user.back != src)
return 0
else if(!src.allowed(user))
user << "<span class='danger'>Unauthorized user. Access denied.</span>"
return 0
else if(!ai_override_enabled)
user << "<span class='danger'>Synthetic access disabled. Please consult hardware provider.</span>"
return 0
return 1
//TODO: Fix Topic vulnerabilities for malfunction and AI override.
/obj/item/weapon/rig/Topic(href,href_list)
if(!check_suit_access(usr))
return 0
if(href_list["toggle_piece"])
if(ishuman(usr) && (usr.stat || usr.stunned || usr.lying))
return 0
toggle_piece(href_list["toggle_piece"], wearer, user = usr)
else if(href_list["toggle_seals"])
toggle_seals(wearer, usr)
else if(href_list["interact_module"])
var/module_index = text2num(href_list["interact_module"])
if(module_index > 0 && module_index <= installed_modules.len)
var/obj/item/rig_module/module = installed_modules[module_index]
switch(href_list["module_mode"])
if("activate")
module.activate()
if("deactivate")
module.deactivate()
if("engage")
module.engage()
if("select")
selected_module = module
if("select_charge_type")
module.charge_selected = href_list["charge_type"]
else if(href_list["toggle_ai_control"])
ai_override_enabled = !ai_override_enabled
notify_ai("Synthetic suit control has been [ai_override_enabled ? "enabled" : "disabled"].")
else if(href_list["toggle_suit_lock"])
locked = !locked
usr.set_machine(src)
src.add_fingerprint(usr)
return 0
/obj/item/weapon/rig/proc/notify_ai(var/message)
if(!message || !installed_modules || !installed_modules.len)
return
for(var/obj/item/rig_module/module in installed_modules)
for(var/mob/living/silicon/ai/ai in module.contents)
if(ai && ai.client && !ai.stat)
ai << "[message]"
/obj/item/weapon/rig/equipped(mob/living/carbon/human/M)
..()
if(seal_delay > 0 && istype(M) && M.back == src)
M.visible_message("<font color='blue'>[M] starts putting on \the [src]...</font>", "<font color='blue'>You start putting on \the [src]...</font>")
if(!do_after(M, seal_delay, target = M))
if(M && M.back == src)
M.back = null
M.unEquip(src)
src.forceMove(get_turf(src))
return
if(istype(M) && M.back == src)
M.visible_message("<font color='blue'><b>[M] struggles into \the [src].</b></font>", "<font color='blue'><b>You struggle into \the [src].</b></font>")
wearer = M
wearer.wearing_rig = src
update_icon()
/obj/item/weapon/rig/proc/toggle_piece(var/piece, var/mob/living/carbon/human/H, var/deploy_mode, var/force, var/mob/living/user)
if(!force) //forces the hardsuit to ignore most checks, as the suit being dropped should retract all pieces regardless of power status
if(sealing || !cell || !cell.charge) //or else you have issues with shit getting stuck
return
if(!istype(wearer) || !wearer.back == src)
return
if(usr == wearer && (usr.stat||usr.paralysis||usr.stunned)) // If the usr isn't wearing the suit it's probably an AI.
return
var/obj/item/check_slot
var/equip_to
var/obj/item/use_obj
if(!H)
return
switch(piece)
if("helmet")
equip_to = slot_head
use_obj = helmet
check_slot = H.head
if("gauntlets")
equip_to = slot_gloves
use_obj = gloves
check_slot = H.gloves
if("boots")
equip_to = slot_shoes
use_obj = boots
check_slot = H.shoes
if("chest")
equip_to = slot_wear_suit
use_obj = chest
check_slot = H.wear_suit
if(use_obj)
if(check_slot == use_obj && deploy_mode != ONLY_DEPLOY)
var/mob/living/carbon/human/holder
if(use_obj)
holder = use_obj.loc
if(istype(holder))
if(use_obj && check_slot == use_obj)
H << "<font color='blue'><b>Your [use_obj.name] [use_obj.gender == PLURAL ? "retract" : "retracts"] swiftly.</b></font>"
use_obj.flags &= ~NODROP
holder.unEquip(use_obj, 1)
use_obj.forceMove(src)
else if (deploy_mode != ONLY_RETRACT)
if(check_slot)
if(check_slot != use_obj)
H << "<span class='danger'>You are unable to deploy \the [piece] as \the [check_slot] [check_slot.gender == PLURAL ? "are" : "is"] in the way.</span>"
return
else
use_obj.forceMove(H)
use_obj.flags &= ~NODROP
if(!H.equip_to_slot_if_possible(use_obj, equip_to, 0, 1))
use_obj.forceMove(src)
else
H << "<span class='notice'>Your [use_obj.name] [use_obj.gender == PLURAL ? "deploy" : "deploys"] swiftly.</span>"
use_obj.flags |= NODROP
if(piece == "helmet" && helmet)
helmet.update_light(H)
/obj/item/weapon/rig/proc/deploy(mob/M,var/sealed)
var/mob/living/carbon/human/H = M
if(!H || !istype(H)) return
if(H.back != src)
return
if(sealed)
if(H.head)
var/obj/item/garbage = H.head
H.unEquip(garbage)
H.head = null
qdel(garbage)
if(H.gloves)
var/obj/item/garbage = H.gloves
H.unEquip(garbage)
H.gloves = null
qdel(garbage)
if(H.shoes)
var/obj/item/garbage = H.shoes
H.unEquip(garbage)
H.shoes = null
qdel(garbage)
if(H.wear_suit)
var/obj/item/garbage = H.wear_suit
H.unEquip(garbage)
H.wear_suit = null
qdel(garbage)
for(var/piece in list("helmet","gauntlets","chest","boots"))
toggle_piece(piece, H, ONLY_DEPLOY)
/obj/item/weapon/rig/dropped(var/mob/user)
..()
for(var/piece in list("helmet","gauntlets","chest","boots"))
toggle_piece(piece, user, ONLY_RETRACT, 1)
if(wearer)
wearer.wearing_rig = null
wearer = null
//Todo
/obj/item/weapon/rig/proc/malfunction()
return 0
/obj/item/weapon/rig/emp_act(severity_class)
//set malfunctioning
if(emp_protection < 30) //for ninjas, really.
malfunctioning += 10
if(malfunction_delay <= 0)
malfunction_delay = max(malfunction_delay, round(30/severity_class))
//drain some charge
if(cell) cell.emp_act(severity_class + 15)
//possibly damage some modules
take_hit((100/severity_class), "electrical pulse", 1)
/obj/item/weapon/rig/proc/shock(mob/user)
if (electrocute_mob(user, cell, src)) //electrocute_mob() handles removing charge from the cell, no need to do that here.
spark_system.start()
if(user.stunned)
return 1
return 0
/obj/item/weapon/rig/proc/take_hit(damage, source, is_emp=0)
if(!installed_modules.len)
return
var/chance
if(!is_emp)
chance = 2*max(0, damage - (chest? chest.breach_threshold : 0))
else
//Want this to be roughly independant of the number of modules, meaning that X emp hits will disable Y% of the suit's modules on average.
//that way people designing hardsuits don't have to worry (as much) about how adding that extra module will affect emp resiliance by 'soaking' hits for other modules
chance = 2*max(0, damage - emp_protection)*min(installed_modules.len/15, 1)
if(!prob(chance))
return
//deal addition damage to already damaged module first.
//This way the chances of a module being disabled aren't so remote.
var/list/valid_modules = list()
var/list/damaged_modules = list()
for(var/obj/item/rig_module/module in installed_modules)
if(module.damage < 2)
valid_modules |= module
if(module.damage > 0)
damaged_modules |= module
var/obj/item/rig_module/dam_module = null
if(damaged_modules.len)
dam_module = pick(damaged_modules)
else if(valid_modules.len)
dam_module = pick(valid_modules)
if(!dam_module) return
dam_module.damage++
if(!source)
source = "hit"
if(wearer)
if(dam_module.damage >= 2)
wearer << "<span class='danger'>The [source] has disabled your [dam_module.interface_name]!</span>"
else
wearer << "<span class='warning'>The [source] has damaged your [dam_module.interface_name]!</span>"
dam_module.deactivate()
/obj/item/weapon/rig/proc/malfunction_check(var/mob/living/carbon/human/user)
if(malfunction_delay)
if(offline)
user << "<span class='danger'>The suit is completely unresponsive.</span>"
else
user << "<span class='danger'>ERROR: Hardware fault. Rebooting interface...</span>"
return 1
return 0
/obj/item/weapon/rig/proc/ai_can_move_suit(var/mob/user, var/check_user_module = 0, var/check_for_ai = 0)
if(check_for_ai)
if(!(locate(/obj/item/rig_module/ai_container) in contents))
return 0
var/found_ai
for(var/obj/item/rig_module/ai_container/module in contents)
if(module.damage >= 2)
continue
if(module.integrated_ai && module.integrated_ai.client && !module.integrated_ai.stat)
found_ai = 1
break
if(!found_ai)
return 0
if(check_user_module)
if(!user || !user.loc || !user.loc.loc)
return 0
var/obj/item/rig_module/ai_container/module = user.loc.loc
if(!istype(module) || module.damage >= 2)
user << "<span class='warning'>Your host module is unable to interface with the suit.</span>"
return 0
if(offline || !cell || !cell.charge || locked_down)
if(user) user << "<span class='warning'>Your host rig is unpowered and unresponsive.</span>"
return 0
if(!wearer || wearer.back != src)
if(user) user << "<span class='warning'>Your host rig is not being worn.</span>"
return 0
if(!wearer.stat && !control_overridden && !ai_override_enabled)
if(user) user << "<span class='warning'>You are locked out of the suit servo controller.</span>"
return 0
return 1
/obj/item/weapon/rig/proc/force_rest(var/mob/user)
if(!ai_can_move_suit(user, check_user_module = 1))
return
wearer.lay_down()
user << "<span class='notice'>\The [wearer] is now [wearer.resting ? "resting" : "getting up"].</span>"
/obj/item/weapon/rig/proc/forced_move(var/direction, var/mob/user)
// Why is all this shit in client/Move()? Who knows?
if(world.time < wearer_move_delay)
return
if(!wearer || !wearer.loc || !ai_can_move_suit(user, check_user_module = 1))
return
//This is sota the goto stop mobs from moving var
if(wearer.notransform || !wearer.canmove)
return
if(locate(/obj/effect/stop/, wearer.loc))
for(var/obj/effect/stop/S in wearer.loc)
if(S.victim == wearer)
return
if(!wearer.lastarea)
wearer.lastarea = get_area(wearer.loc)
if((istype(wearer.loc, /turf/space)) || (wearer.lastarea.has_gravity == 0))
if(!wearer.Process_Spacemove(0))
return 0
if(malfunctioning)
direction = pick(cardinal)
// Inside an object, tell it we moved.
if(isobj(wearer.loc) || ismob(wearer.loc))
var/atom/O = wearer.loc
return O.relaymove(wearer, direction)
if(isturf(wearer.loc))
if(wearer.restrained())//Why being pulled while cuffed prevents you from moving
for(var/mob/M in range(wearer, 1))
if(M.pulling == wearer)
if(!M.restrained() && M.stat == 0 && M.canmove && wearer.Adjacent(M))
user << "<span class='notice'>Your host is restrained! They can't move!</span>"
return 0
else
M.stop_pulling()
if(wearer.pinned.len)
src << "<span class='notice'>Your host is pinned to a wall by [wearer.pinned[1]]</span>!"
return 0
// AIs are a bit slower than regular and ignore move intent.
wearer.last_move_intent = world.time + ai_controlled_move_delay
wearer_move_delay = world.time + ai_controlled_move_delay
var/tickcomp = 0
if(config.Tickcomp)
tickcomp = ((1/(world.tick_lag))*1.3) - 1.3
wearer_move_delay += tickcomp
if(wearer.buckled) //if we're buckled to something, tell it we moved.
return wearer.buckled.relaymove(wearer, direction)
if(cell.use(200)) //Arbitrary, TODO
wearer.Move(get_step(get_turf(wearer),direction),direction)
// This returns the rig if you are contained inside one, but not if you are wearing it
/atom/proc/get_rig()
if(loc)
return loc.get_rig()
return null
/obj/item/weapon/rig/get_rig()
return src
/mob/living/carbon/human/get_rig()
return back
#undef ONLY_DEPLOY
#undef ONLY_RETRACT
#undef SEAL_DELAY
@@ -0,0 +1,196 @@
/obj/item/weapon/rig/attackby(obj/item/W as obj, mob/user as mob)
if(!istype(user,/mob/living)) return 0
if(electrified != 0)
if(shock(user)) //Handles removing charge from the cell, as well. No need to do that here.
return
// Pass repair items on to the chestpiece.
if(chest && (istype(W,/obj/item/stack) || istype(W, /obj/item/weapon/weldingtool)))
return chest.attackby(W,user)
// Lock or unlock the access panel.
if(W.GetID())
if(subverted)
locked = 0
user << "<span class='danger'>It looks like the locking system has been shorted out.</span>"
return
if((!req_access || !req_access.len) && (!req_one_access || !req_one_access.len))
locked = 0
user << "<span class='danger'>\The [src] doesn't seem to have a locking mechanism.</span>"
return
if(security_check_enabled && !src.allowed(user))
user << "<span class='danger'>Access denied.</span>"
return
locked = !locked
user << "You [locked ? "lock" : "unlock"] \the [src] access panel."
return
else if(istype(W,/obj/item/weapon/crowbar))
if(!open && locked)
user << "The access panel is locked shut."
return
open = !open
user << "You [open ? "open" : "close"] the access panel."
return
if(open)
// Hacking.
if(istype(W,/obj/item/weapon/wirecutters) || istype(W,/obj/item/device/multitool))
if(open)
wires.Interact(user)
else
user << "You can't reach the wiring."
return
// Air tank.
if(istype(W,/obj/item/weapon/tank)) //Todo, some kind of check for suits without integrated air supplies.
if(air_supply)
user << "\The [src] already has a tank installed."
return
user.unEquip(W)
air_supply = W
W.forceMove(src)
user << "You slot [W] into [src] and tighten the connecting valve."
return
// Check if this is a hardsuit upgrade or a modification.
else if(istype(W,/obj/item/rig_module))
if(istype(src.loc,/mob/living/carbon/human))
var/mob/living/carbon/human/H = src.loc
if(H.back == src)
user << "<span class='danger'>You can't install a hardsuit module while the suit is being worn.</span>"
return 1
if(!installed_modules) installed_modules = list()
if(installed_modules.len)
for(var/obj/item/rig_module/installed_mod in installed_modules)
if(!installed_mod.redundant && istype(installed_mod,W))
user << "The hardsuit already has a module of that class installed."
return 1
var/obj/item/rig_module/mod = W
user << "You begin installing \the [mod] into \the [src]."
if(!do_after(user,40, target = src))
return
if(!user || !W)
return
user << "You install \the [mod] into \the [src]."
user.unEquip(mod)
installed_modules |= mod
mod.forceMove(src)
mod.installed(src)
update_icon()
return 1
else if(!cell && istype(W,/obj/item/weapon/stock_parts/cell))
user << "You jack \the [W] into \the [src]'s battery mount."
user.unEquip(W)
W.forceMove(src)
src.cell = W
return
else if(istype(W,/obj/item/weapon/wrench))
if(!air_supply)
user << "There is not tank to remove."
return
if(user.r_hand && user.l_hand)
air_supply.forceMove(get_turf(user))
else
user.put_in_hands(air_supply)
user << "You detach and remove \the [air_supply]."
air_supply = null
return
else if(istype(W,/obj/item/weapon/screwdriver))
var/list/current_mounts = list()
if(cell) current_mounts += "cell"
if(installed_modules && installed_modules.len) current_mounts += "system module"
var/to_remove = input("Which would you like to modify?") as null|anything in current_mounts
if(!to_remove)
return
if(istype(src.loc,/mob/living/carbon/human) && to_remove != "cell")
var/mob/living/carbon/human/H = src.loc
if(H.back == src)
user << "You can't remove an installed device while the hardsuit is being worn."
return
switch(to_remove)
if("cell")
if(cell)
user << "You detatch \the [cell] from \the [src]'s battery mount."
for(var/obj/item/rig_module/module in installed_modules)
module.deactivate()
if(user.r_hand && user.l_hand)
cell.forceMove(get_turf(user))
else
cell.forceMove(user.put_in_hands(cell))
cell = null
else
user << "There is nothing loaded in that mount."
if("system module")
var/list/possible_removals = list()
for(var/obj/item/rig_module/module in installed_modules)
if(module.permanent)
continue
possible_removals[module.name] = module
if(!possible_removals.len)
user << "There are no installed modules to remove."
return
var/removal_choice = input("Which module would you like to remove?") as null|anything in possible_removals
if(!removal_choice)
return
var/obj/item/rig_module/removed = possible_removals[removal_choice]
user << "You detatch \the [removed] from \the [src]."
removed.forceMove(get_turf(src))
removed.removed()
installed_modules -= removed
update_icon()
return
// If we've gotten this far, all we have left to do before we pass off to root procs
// is check if any of the loaded modules want to use the item we've been given.
for(var/obj/item/rig_module/module in installed_modules)
if(module.accepts_item(W,user)) //Item is handled in this proc
return
..()
/obj/item/weapon/rig/attack_hand(var/mob/user)
if(electrified != 0)
if(shock(user)) //Handles removing charge from the cell, as well. No need to do that here.
return
..()
/obj/item/weapon/rig/emag_act(var/remaining_charges, var/mob/user)
if(!subverted)
req_access.Cut()
req_one_access.Cut()
locked = 0
subverted = 1
user << "<span class='danger'>You short out the access protocol for the suit.</span>"
return 1
@@ -0,0 +1,134 @@
/*
* Defines the helmets, gloves and shoes for rigs.
*/
/obj/item/clothing/head/helmet/space/new_rig
name = "helmet"
flags = HEADCOVERSEYES | BLOCKHAIR | HEADCOVERSMOUTH | THICKMATERIAL
flags_inv = HIDEEARS|HIDEEYES|HIDEFACE|HIDEMASK
body_parts_covered = HEAD
heat_protection = HEAD
cold_protection = HEAD
var/brightness_on = 4
var/on = 0
sprite_sheets = list(
"Tajara" = 'icons/mob/species/tajaran/helmet.dmi',
"Skrell" = 'icons/mob/species/skrell/helmet.dmi',
"Unathi" = 'icons/mob/species/unathi/helmet.dmi'
)
species_restricted = null
flash_protect = 2
/obj/item/clothing/head/helmet/space/new_rig/attack_self(mob/user)
if(!isturf(user.loc))
user << "<span class='warning'>You cannot turn the light on while in this [user.loc].</span>" //To prevent some lighting anomalities.
return
toggle_light(user)
/obj/item/clothing/head/helmet/space/new_rig/proc/toggle_light(mob/user)
on = !on
icon_state = "rig[on]-[_color]"
if(on)
set_light(brightness_on)
else
set_light(0)
if(istype(user,/mob/living/carbon/human))
var/mob/living/carbon/human/H = user
H.update_inv_head()
/obj/item/clothing/gloves/rig
name = "gauntlets"
flags = THICKMATERIAL
body_parts_covered = HANDS
heat_protection = HANDS
cold_protection = HANDS
species_restricted = null
gender = PLURAL
/obj/item/clothing/shoes/magboots/rig
name = "boots"
body_parts_covered = FEET
cold_protection = FEET
heat_protection = FEET
species_restricted = null
gender = PLURAL
/obj/item/clothing/suit/space/new_rig
name = "chestpiece"
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank)
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
cold_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
flags_inv = HIDEJUMPSUIT|HIDETAIL
flags = STOPSPRESSUREDMAGE | THICKMATERIAL | AIRTIGHT
slowdown = 0
//will reach 10 breach damage after 25 laser carbine blasts, 3 revolver hits, or ~1 PTR hit. Completely immune to smg or sts hits.
breach_threshold = 38
resilience = 0.2
can_breach = 1
sprite_sheets = list(
"Tajara" = 'icons/mob/species/tajaran/suit.dmi',
"Unathi" = 'icons/mob/species/unathi/suit.dmi'
)
//TODO: move this to modules
/obj/item/clothing/head/helmet/space/new_rig/proc/prevent_track()
return 0
/obj/item/clothing/gloves/rig/Touch(var/atom/A, var/proximity)
if(!A || !proximity)
return 0
var/mob/living/carbon/human/H = loc
if(!istype(H) || !H.back)
return 0
var/obj/item/weapon/rig/suit = H.back
if(!suit || !istype(suit) || !suit.installed_modules.len)
return 0
for(var/obj/item/rig_module/module in suit.installed_modules)
if(module.active && module.activates_on_touch)
if(module.engage(A))
return 1
return 0
//Rig pieces for non-spacesuit based rigs
/obj/item/clothing/head/lightrig
name = "mask"
body_parts_covered = HEAD
heat_protection = HEAD
cold_protection = HEAD
flags = THICKMATERIAL|AIRTIGHT
/obj/item/clothing/suit/lightrig
name = "suit"
allowed = list(/obj/item/device/flashlight)
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
cold_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
flags_inv = HIDEJUMPSUIT
flags = THICKMATERIAL
/obj/item/clothing/shoes/lightrig
name = "boots"
body_parts_covered = FEET
cold_protection = FEET
heat_protection = FEET
species_restricted = null
gender = PLURAL
/obj/item/clothing/gloves/lightrig
name = "gloves"
flags = THICKMATERIAL
body_parts_covered = HANDS
heat_protection = HANDS
cold_protection = HANDS
species_restricted = null
gender = PLURAL
@@ -0,0 +1,297 @@
// Interface for humans.
/obj/item/weapon/rig/verb/hardsuit_interface()
set name = "Open Hardsuit Interface"
set desc = "Open the hardsuit system interface."
set category = "Hardsuit"
set src = usr.contents
if(wearer && wearer.back == src)
ui_interact(usr)
/obj/item/weapon/rig/verb/toggle_vision()
set name = "Toggle Visor"
set desc = "Turns your rig visor off or on."
set category = "Hardsuit"
set src = usr.contents
if(!istype(wearer) || !wearer.back == src)
usr << "<span class='warning'>The hardsuit is not being worn.</span>"
return
if(!check_power_cost(usr))
return
if(!(flags & NODROP))
usr << "<span class='warning'>The suit is not active.</span>"
return
if(!check_suit_access(usr))
return
if(!visor)
usr << "<span class='warning'>The hardsuit does not have a configurable visor.</span>"
return
if(!visor.active)
visor.activate()
else
visor.deactivate()
/obj/item/weapon/rig/proc/toggle_helmet()
set name = "Toggle Helmet"
set desc = "Deploys or retracts your helmet."
set category = "Hardsuit"
set src = usr.contents
if(!istype(wearer) || !wearer.back == src)
usr << "<span class='warning'>The hardsuit is not being worn.</span>"
return
if(!check_suit_access(usr))
return
toggle_piece("helmet",wearer)
/obj/item/weapon/rig/proc/toggle_chest()
set name = "Toggle Chestpiece"
set desc = "Deploys or retracts your chestpiece."
set category = "Hardsuit"
set src = usr.contents
if(!check_suit_access(usr))
return
toggle_piece("chest",wearer)
/obj/item/weapon/rig/proc/toggle_gauntlets()
set name = "Toggle Gauntlets"
set desc = "Deploys or retracts your gauntlets."
set category = "Hardsuit"
set src = usr.contents
if(!istype(wearer) || !wearer.back == src)
usr << "<span class='warning'>The hardsuit is not being worn.</span>"
return
if(!check_suit_access(usr))
return
toggle_piece("gauntlets",wearer)
/obj/item/weapon/rig/proc/toggle_boots()
set name = "Toggle Boots"
set desc = "Deploys or retracts your boots."
set category = "Hardsuit"
set src = usr.contents
if(!istype(wearer) || !wearer.back == src)
usr << "<span class='warning'>The hardsuit is not being worn.</span>"
return
if(!check_suit_access(usr))
return
toggle_piece("boots",wearer)
/obj/item/weapon/rig/verb/deploy_suit()
set name = "Deploy Hardsuit"
set desc = "Deploys helmet, gloves and boots."
set category = "Hardsuit"
set src = usr.contents
if(!istype(wearer) || !wearer.back == src)
usr << "<span class='warning'>The hardsuit is not being worn.</span>"
return
if(!check_suit_access(usr))
return
if(!check_power_cost(usr))
return
deploy(wearer)
/obj/item/weapon/rig/verb/toggle_seals_verb()
set name = "Toggle Hardsuit"
set desc = "Activates or deactivates your rig."
set category = "Hardsuit"
set src = usr.contents
if(!istype(wearer) || !wearer.back == src)
usr << "<span class='warning'>The hardsuit is not being worn.</span>"
return
if(!check_suit_access(usr))
return
toggle_seals(wearer)
/obj/item/weapon/rig/verb/switch_vision_mode()
set name = "Switch Vision Mode"
set desc = "Switches between available vision modes."
set category = "Hardsuit"
set src = usr.contents
if(malfunction_check(usr))
return
if(!check_power_cost(usr, 0, 0, 0, 0))
return
if(!(flags & NODROP))
usr << "<span class='warning'>The suit is not active.</span>"
return
if(!visor)
usr << "<span class='warning'>The hardsuit does not have a configurable visor.</span>"
return
if(!visor.active)
visor.activate()
if(!visor.active)
usr << "<span class='warning'>The visor is suffering a hardware fault and cannot be configured.</span>"
return
visor.engage()
/obj/item/weapon/rig/verb/alter_voice()
set name = "Configure Voice Synthesiser"
set desc = "Toggles or configures your voice synthesizer."
set category = "Hardsuit"
set src = usr.contents
if(malfunction_check(usr))
return
if(!(flags & NODROP))
usr << "<span class='warning'>The suit is not active.</span>"
return
if(!istype(wearer) || !wearer.back == src)
usr << "<span class='warning'>The hardsuit is not being worn.</span>"
return
if(!speech)
usr << "<span class='warning'>The hardsuit does not have a speech synthesiser.</span>"
return
speech.engage()
/obj/item/weapon/rig/verb/select_module()
set name = "Select Module"
set desc = "Selects a module as your primary system."
set category = "Hardsuit"
set src = usr.contents
if(malfunction_check(usr))
return
if(!check_power_cost(usr, 0, 0, 0, 0))
return
if(!(flags & NODROP))
usr << "<span class='warning'>The suit is not active.</span>"
return
if(!istype(wearer) || !wearer.back == src)
usr << "<span class='warning'>The hardsuit is not being worn.</span>"
return
var/list/selectable = list()
for(var/obj/item/rig_module/module in installed_modules)
if(module.selectable)
selectable |= module
var/obj/item/rig_module/module = input("Which module do you wish to select?") as null|anything in selectable
if(!istype(module))
selected_module = null
usr << "<font color='blue'><b>Primary system is now: deselected.</b></font>"
return
selected_module = module
usr << "<font color='blue'><b>Primary system is now: [selected_module.interface_name].</b></font>"
/obj/item/weapon/rig/verb/toggle_module()
set name = "Toggle Module"
set desc = "Toggle a system module."
set category = "Hardsuit"
set src = usr.contents
if(malfunction_check(usr))
return
if(!check_power_cost(usr, 0, 0, 0, 0))
return
if(!(flags & NODROP))
usr << "<span class='warning'>The suit is not active.</span>"
return
if(!istype(wearer) || !wearer.back == src)
usr << "<span class='warning'>The hardsuit is not being worn.</span>"
return
var/list/selectable = list()
for(var/obj/item/rig_module/module in installed_modules)
if(module.toggleable)
selectable |= module
var/obj/item/rig_module/module = input("Which module do you wish to toggle?") as null|anything in selectable
if(!istype(module))
return
if(module.active)
usr << "<font color='blue'><b>You attempt to deactivate \the [module.interface_name].</b></font>"
module.deactivate()
else
usr << "<font color='blue'><b>You attempt to activate \the [module.interface_name].</b></font>"
module.activate()
/obj/item/weapon/rig/verb/engage_module()
set name = "Engage Module"
set desc = "Engages a system module."
set category = "Hardsuit"
set src = usr.contents
if(malfunction_check(usr))
return
if(!(flags & NODROP))
usr << "<span class='warning'>The suit is not active.</span>"
return
if(!istype(wearer) || !wearer.back == src)
usr << "<span class='warning'>The hardsuit is not being worn.</span>"
return
if(!check_power_cost(usr, 0, 0, 0, 0))
return
var/list/selectable = list()
for(var/obj/item/rig_module/module in installed_modules)
if(module.usable)
selectable |= module
var/obj/item/rig_module/module = input("Which module do you wish to engage?") as null|anything in selectable
if(!istype(module))
return
usr << "<font color='blue'><b>You attempt to engage the [module.interface_name].</b></font>"
module.engage()
@@ -0,0 +1,57 @@
/datum/wires/rig
random = 1
holder_type = /obj/item/weapon/rig
wire_count = 5
#define RIG_SECURITY 1
#define RIG_AI_OVERRIDE 2
#define RIG_SYSTEM_CONTROL 4
#define RIG_INTERFACE_LOCK 8
#define RIG_INTERFACE_SHOCK 16
/*
* Rig security can be snipped to disable ID access checks on rig.
* Rig AI override can be pulsed to toggle whether or not the AI can take control of the suit.
* System control can be pulsed to toggle some malfunctions.
* Interface lock can be pulsed to toggle whether or not the interface can be accessed.
*/
/datum/wires/rig/UpdateCut(var/index, var/mended)
var/obj/item/weapon/rig/rig = holder
switch(index)
if(RIG_SECURITY)
if(mended)
rig.req_access = initial(rig.req_access)
rig.req_one_access = initial(rig.req_one_access)
if(RIG_INTERFACE_SHOCK)
rig.electrified = mended ? 0 : -1
rig.shock(usr,100)
/datum/wires/rig/UpdatePulsed(var/index)
var/obj/item/weapon/rig/rig = holder
switch(index)
if(RIG_SECURITY)
rig.security_check_enabled = !rig.security_check_enabled
rig.visible_message("\The [rig] twitches as several suit locks [rig.security_check_enabled?"close":"open"].")
if(RIG_AI_OVERRIDE)
rig.ai_override_enabled = !rig.ai_override_enabled
rig.visible_message("A small red light on [rig] [rig.ai_override_enabled?"goes dead":"flickers on"].")
if(RIG_SYSTEM_CONTROL)
rig.malfunctioning += 10
if(rig.malfunction_delay <= 0)
rig.malfunction_delay = 20
rig.shock(usr,100)
if(RIG_INTERFACE_LOCK)
rig.interface_locked = !rig.interface_locked
rig.visible_message("\The [rig] clicks audibly as the software interface [rig.interface_locked?"darkens":"brightens"].")
if(RIG_INTERFACE_SHOCK)
if(rig.electrified != -1)
rig.electrified = 30
rig.shock(usr,100)
/datum/wires/rig/CanUse(var/mob/living/L)
var/obj/item/weapon/rig/rig = holder
if(rig.open)
return 1
return 0
@@ -0,0 +1,32 @@
/obj/item/weapon/rig/unathi
name = "NT breacher chassis control module"
desc = "A cheap NT knock-off of an Unathi battle-rig. Looks like a fish, moves like a fish, steers like a cow."
suit_type = "NT breacher"
icon_state = "breacher_rig_cheap"
armor = list(melee = 60, bullet = 60, laser = 60, energy = 60, bomb = 70, bio = 100, rad = 50)
emp_protection = -20
slowdown = 6
offline_slowdown = 10
vision_restriction = 1
offline_vision_restriction = 2
chest_type = /obj/item/clothing/suit/space/new_rig
helm_type = /obj/item/clothing/head/helmet/space/new_rig/unathi
boot_type = /obj/item/clothing/shoes/magboots/rig/unathi
/obj/item/weapon/rig/unathi/fancy
name = "breacher chassis control module"
desc = "An authentic Unathi breacher chassis. Huge, bulky and absurdly heavy. It must be like wearing a tank."
suit_type = "breacher chassis"
icon_state = "breacher_rig"
armor = list(melee = 90, bullet = 90, laser = 90, energy = 90, bomb = 90, bio = 100, rad = 80) //Takes TEN TIMES as much damage to stop someone in a breacher. In exchange, it's slow.
vision_restriction = 0
/obj/item/clothing/head/helmet/space/new_rig/unathi
species_restricted = list("Unathi")
/obj/item/clothing/suit/space/new_rig/unathi
species_restricted = list("Unathi")
/obj/item/clothing/shoes/magboots/rig/unathi
species_restricted = list("Unathi")
@@ -0,0 +1,28 @@
/obj/item/clothing/head/helmet/space/new_rig/combat
/obj/item/weapon/rig/combat
name = "combat hardsuit control module"
desc = "A sleek and dangerous hardsuit for active combat."
icon_state = "security_rig"
suit_type = "combat hardsuit"
armor = list(melee = 80, bullet = 65, laser = 50, energy = 15, bomb = 80, bio = 100, rad = 60)
slowdown = 1
offline_slowdown = 3
offline_vision_restriction = 1
helm_type = /obj/item/clothing/head/helmet/space/new_rig/combat
allowed = list(/obj/item/weapon/gun,/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/melee/baton)
/obj/item/weapon/rig/combat/equipped
initial_modules = list(
/obj/item/rig_module/mounted,
/obj/item/rig_module/vision/thermal,
/obj/item/rig_module/grenade_launcher,
/obj/item/rig_module/ai_container,
// /obj/item/rig_module/power_sink,
/obj/item/rig_module/electrowarfare_suite,
/obj/item/rig_module/chem_dispenser/combat
)
@@ -0,0 +1,83 @@
/obj/item/clothing/head/helmet/space/new_rig/ert
/obj/item/weapon/rig/ert
name = "ERT-C hardsuit control module"
desc = "A suit worn by the commander of an Emergency Response Team. Has blue highlights. Armoured and space ready."
suit_type = "ERT commander"
icon_state = "ert_commander_rig"
helm_type = /obj/item/clothing/head/helmet/space/new_rig/ert
req_access = list(access_cent_specops)
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 100, rad = 100)
allowed = list(/obj/item/device/flashlight, /obj/item/weapon/tank, /obj/item/device/t_scanner, /obj/item/weapon/rcd, /obj/item/weapon/crowbar, \
/obj/item/weapon/screwdriver, /obj/item/weapon/weldingtool, /obj/item/weapon/wirecutters, /obj/item/weapon/wrench, /obj/item/device/multitool, \
/obj/item/device/radio, /obj/item/device/analyzer,/obj/item/weapon/storage/briefcase/inflatable, /obj/item/weapon/melee/baton, /obj/item/weapon/gun, \
/obj/item/weapon/storage/firstaid, /obj/item/weapon/reagent_containers/hypospray, /obj/item/roller)
initial_modules = list(
/obj/item/rig_module/ai_container,
/obj/item/rig_module/maneuvering_jets,
/obj/item/rig_module/datajack,
)
/obj/item/weapon/rig/ert/engineer
name = "ERT-E suit control module"
desc = "A suit worn by the engineering division of an Emergency Response Team. Has orange highlights. Armoured and space ready."
suit_type = "ERT engineer"
icon_state = "ert_engineer_rig"
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 100, rad = 100)
siemens_coefficient = 0
initial_modules = list(
/obj/item/rig_module/ai_container,
/obj/item/rig_module/maneuvering_jets,
/obj/item/rig_module/device/plasmacutter,
// /obj/item/rig_module/device/rcd
)
/obj/item/weapon/rig/ert/medical
name = "ERT-M suit control module"
desc = "A suit worn by the medical division of an Emergency Response Team. Has white highlights. Armoured and space ready."
suit_type = "ERT medic"
icon_state = "ert_medical_rig"
initial_modules = list(
/obj/item/rig_module/ai_container,
/obj/item/rig_module/maneuvering_jets,
/obj/item/rig_module/device/healthscanner,
/obj/item/rig_module/chem_dispenser/injector
)
/obj/item/weapon/rig/ert/security
name = "ERT-S suit control module"
desc = "A suit worn by the security division of an Emergency Response Team. Has red highlights. Armoured and space ready."
suit_type = "ERT security"
icon_state = "ert_security_rig"
initial_modules = list(
/obj/item/rig_module/ai_container,
/obj/item/rig_module/maneuvering_jets,
/obj/item/rig_module/grenade_launcher,
/obj/item/rig_module/mounted/egun,
)
/obj/item/weapon/rig/ert/assetprotection
name = "Heavy Asset Protection suit control module"
desc = "A heavy suit worn by the highest level of Asset Protection, don't mess with the person wearing this. Armoured and space ready."
suit_type = "heavy asset protection"
icon_state = "asset_protection_rig"
armor = list(melee = 60, bullet = 50, laser = 50,energy = 40, bomb = 40, bio = 100, rad = 100)
initial_modules = list(
/obj/item/rig_module/ai_container,
/obj/item/rig_module/maneuvering_jets,
/obj/item/rig_module/grenade_launcher,
/obj/item/rig_module/vision/multi,
/obj/item/rig_module/mounted/egun,
/obj/item/rig_module/chem_dispenser/injector,
/obj/item/rig_module/device/plasmacutter,
// /obj/item/rig_module/device/rcd,
/obj/item/rig_module/datajack
)
@@ -0,0 +1,123 @@
// Light rigs are not space-capable, but don't suffer excessive slowdown or sight issues when depowered.
/obj/item/weapon/rig/light
name = "light suit control module"
desc = "A lighter, less armoured rig suit."
icon_state = "ninja_rig"
suit_type = "light suit"
allowed = list(/obj/item/weapon/gun,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/tank,/obj/item/weapon/stock_parts/cell)
armor = list(melee = 50, bullet = 15, laser = 50, energy = 10, bomb = 25, bio = 0, rad = 0)
emp_protection = 10
slowdown = 0
flags = STOPSPRESSUREDMAGE | THICKMATERIAL
offline_slowdown = 0
offline_vision_restriction = 0
chest_type = /obj/item/clothing/suit/space/new_rig/light
helm_type = /obj/item/clothing/head/helmet/space/new_rig/light
boot_type = /obj/item/clothing/shoes/magboots/rig/light
glove_type = /obj/item/clothing/gloves/rig/light
/obj/item/clothing/suit/space/new_rig/light
name = "suit"
breach_threshold = 18 //comparable to voidsuits
/obj/item/clothing/gloves/rig/light
name = "gloves"
/obj/item/clothing/shoes/magboots/rig/light
name = "shoes"
/obj/item/clothing/head/helmet/space/new_rig/light
name = "hood"
/obj/item/weapon/rig/light/hacker
name = "cybersuit control module"
suit_type = "cyber"
desc = "An advanced powered armour suit with many cyberwarfare enhancements. Comes with built-in insulated gloves for safely tampering with electronics."
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/hacker
chest_type = /obj/item/clothing/suit/lightrig/hacker
glove_type = /obj/item/clothing/gloves/lightrig/hacker
boot_type = /obj/item/clothing/shoes/lightrig/hacker
initial_modules = list(
/obj/item/rig_module/ai_container,
// /obj/item/rig_module/power_sink,
/obj/item/rig_module/datajack,
/obj/item/rig_module/electrowarfare_suite,
/obj/item/rig_module/voice,
/obj/item/rig_module/vision,
)
//The cybersuit is not space-proof. It does however, have good siemens_coefficient values
/obj/item/clothing/head/lightrig/hacker
name = "HUD"
siemens_coefficient = 0.4
flags = 0
/obj/item/clothing/suit/lightrig/hacker
siemens_coefficient = 0.4
/obj/item/clothing/shoes/lightrig/hacker
siemens_coefficient = 0.4
flags = NOSLIP //All the other rigs have magboots anyways, hopefully gives the hacker suit something more going for it.
/obj/item/clothing/gloves/lightrig/hacker
siemens_coefficient = 0
/obj/item/weapon/rig/light/ninja
name = "ominous suit control module"
suit_type = "ominous"
desc = "A unique, vaccum-proof suit of nano-enhanced armor designed specifically for Spider Clan assassins."
icon_state = "ninja_rig"
armor = list(melee = 50, bullet = 15, laser = 30, energy = 10, bomb = 25, bio = 100, rad = 30)
emp_protection = 40 //change this to 30 if too high.
slowdown = 0
chest_type = /obj/item/clothing/suit/space/new_rig/light/ninja
glove_type = /obj/item/clothing/gloves/rig/light/ninja
req_access = list(access_syndicate)
initial_modules = list(
/obj/item/rig_module/teleporter,
/obj/item/rig_module/stealth_field,
/obj/item/rig_module/mounted/energy_blade,
/obj/item/rig_module/vision,
/obj/item/rig_module/voice,
/obj/item/rig_module/chem_dispenser,
/obj/item/rig_module/grenade_launcher,
/obj/item/rig_module/fabricator,
/obj/item/rig_module/ai_container,
// /obj/item/rig_module/power_sink,
/obj/item/rig_module/datajack,
/obj/item/rig_module/self_destruct
)
..()
/obj/item/clothing/gloves/rig/light/ninja
name = "insulated gloves"
siemens_coefficient = 0
/obj/item/clothing/suit/space/new_rig/light/ninja
breach_threshold = 38 //comparable to regular hardsuits
/obj/item/weapon/rig/light/stealth
name = "stealth suit control module"
suit_type = "stealth"
desc = "A highly advanced and expensive suit designed for covert operations."
icon_state = "stealth_rig"
req_access = list(access_syndicate)
initial_modules = list(
/obj/item/rig_module/stealth_field,
/obj/item/rig_module/vision
)
@@ -0,0 +1,32 @@
/obj/item/clothing/head/helmet/space/new_rig/merc
/obj/item/weapon/rig/merc
name = "crimson hardsuit control module"
desc = "A blood-red hardsuit featuring some fairly illegal technology."
icon_state = "merc_rig"
suit_type = "crimson hardsuit"
armor = list(melee = 80, bullet = 65, laser = 50, energy = 15, bomb = 80, bio = 100, rad = 60)
slowdown = 1
offline_slowdown = 3
offline_vision_restriction = 1
helm_type = /obj/item/clothing/head/helmet/space/new_rig/merc
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/gun,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/restraints/handcuffs)
initial_modules = list(
/obj/item/rig_module/mounted,
/obj/item/rig_module/vision/thermal,
/obj/item/rig_module/grenade_launcher,
/obj/item/rig_module/ai_container,
// /obj/item/rig_module/power_sink,
/obj/item/rig_module/electrowarfare_suite,
/obj/item/rig_module/chem_dispenser/combat,
// /obj/item/rig_module/fabricator/energy_net
)
//Has most of the modules removed
/obj/item/weapon/rig/merc/empty
initial_modules = list(
/obj/item/rig_module/ai_container,
/obj/item/rig_module/electrowarfare_suite, //might as well
)
@@ -0,0 +1,227 @@
/obj/item/clothing/head/helmet/space/new_rig/industrial
/obj/item/clothing/head/helmet/space/new_rig/ce
/obj/item/clothing/head/helmet/space/new_rig/eva
/obj/item/clothing/head/helmet/space/new_rig/hazmat
/obj/item/clothing/head/helmet/space/new_rig/medical
/obj/item/clothing/head/helmet/space/new_rig/hazard
/obj/item/weapon/rig/internalaffairs
name = "augmented tie"
suit_type = "augmented suit"
desc = "Prepare for paperwork."
icon_state = "internalaffairs_rig"
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
siemens_coefficient = 0.9
slowdown = 0
offline_slowdown = 0
offline_vision_restriction = 0
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/storage/briefcase,/obj/item/weapon/storage/secure/briefcase)
req_access = list()
req_one_access = list()
glove_type = null
helm_type = null
boot_type = null
/obj/item/weapon/rig/internalaffairs/equipped
req_access = list(access_lawyer)
initial_modules = list(
/obj/item/rig_module/ai_container,
/obj/item/rig_module/device/flash,
/obj/item/rig_module/device/paperdispenser,
/obj/item/rig_module/device/pen,
/obj/item/rig_module/device/stamp
)
glove_type = null
helm_type = null
boot_type = null
/obj/item/weapon/rig/industrial
name = "industrial suit control module"
suit_type = "industrial hardsuit"
desc = "A heavy, powerful rig used by construction crews and mining corporations."
icon_state = "engineering_rig"
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 100, rad = 50)
slowdown = 3
offline_slowdown = 10
offline_vision_restriction = 2
emp_protection = -20
helm_type = /obj/item/clothing/head/helmet/space/new_rig/industrial
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/storage/bag/ore,/obj/item/device/t_scanner,/obj/item/weapon/pickaxe, /obj/item/weapon/rcd)
req_access = list()
req_one_access = list()
/obj/item/weapon/rig/industrial/equipped
initial_modules = list(
/obj/item/rig_module/device/plasmacutter,
/obj/item/rig_module/device/drill,
/obj/item/rig_module/device/orescanner,
// /obj/item/rig_module/device/rcd,
/obj/item/rig_module/vision/meson
)
/obj/item/weapon/rig/eva
name = "EVA suit control module"
suit_type = "EVA hardsuit"
desc = "A light rig for repairs and maintenance to the outside of habitats and vessels."
icon_state = "eva_rig"
armor = list(melee = 30, bullet = 10, laser = 20,energy = 25, bomb = 20, bio = 100, rad = 100)
slowdown = 0
offline_slowdown = 1
offline_vision_restriction = 1
helm_type = /obj/item/clothing/head/helmet/space/new_rig/eva
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/storage/toolbox,/obj/item/weapon/storage/briefcase/inflatable,/obj/item/device/t_scanner,/obj/item/weapon/rcd)
req_access = list()
req_one_access = list()
/obj/item/weapon/rig/eva/equipped
initial_modules = list(
/obj/item/rig_module/device/plasmacutter,
/obj/item/rig_module/maneuvering_jets,
// /obj/item/rig_module/device/rcd,
/obj/item/rig_module/vision/meson
)
//Chief Engineer's rig. This is sort of a halfway point between the old hardsuits (voidsuits) and the rig class.
/obj/item/weapon/rig/ce
name = "advanced voidsuit control module"
suit_type = "advanced voidsuit"
desc = "An advanced voidsuit that protects against hazardous, low pressure environments. Shines with a high polish."
icon_state = "ce_rig"
armor = list(melee = 40, bullet = 10, laser = 30,energy = 25, bomb = 40, bio = 100, rad = 100)
slowdown = 0
offline_slowdown = 0
offline_vision_restriction = 0
helm_type = /obj/item/clothing/head/helmet/space/new_rig/ce
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/storage/bag/ore,/obj/item/device/t_scanner,/obj/item/weapon/pickaxe, /obj/item/weapon/rcd)
req_access = list()
req_one_access = list()
boot_type = null
glove_type = null
/obj/item/weapon/rig/ce/equipped
req_access = list(access_ce)
initial_modules = list(
/obj/item/rig_module/ai_container,
/obj/item/rig_module/maneuvering_jets,
/obj/item/rig_module/device/plasmacutter,
// /obj/item/rig_module/device/rcd,
/obj/item/rig_module/vision/meson
)
chest_type = /obj/item/clothing/suit/space/new_rig/ce
boot_type = null
glove_type = null
/obj/item/clothing/suit/space/new_rig/ce
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
/obj/item/weapon/rig/hazmat
name = "AMI control module"
suit_type = "hazmat hardsuit"
desc = "An Anomalous Material Interaction hardsuit that protects against the strangest energies the universe can throw at it."
icon_state = "science_rig"
armor = list(melee = 45, bullet = 5, laser = 45, energy = 80, bomb = 60, bio = 100, rad = 100)
slowdown = 1
offline_vision_restriction = 1
helm_type = /obj/item/clothing/head/helmet/space/new_rig/hazmat
helm_type = /obj/item/clothing/head/helmet/space/new_rig/ert
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/storage/box/excavation,/obj/item/weapon/pickaxe,/obj/item/device/healthanalyzer,/obj/item/device/measuring_tape,/obj/item/device/ano_scanner,/obj/item/device/depth_scanner,/obj/item/device/core_sampler,/obj/item/device/gps,/obj/item/device/beacon_locator,/obj/item/device/radio/beacon,/obj/item/weapon/pickaxe/hand,/obj/item/weapon/storage/bag/fossils)
req_access = list()
req_one_access = list()
/obj/item/weapon/rig/hazmat/equipped
req_access = list(access_rd)
initial_modules = list(
/obj/item/rig_module/ai_container,
/obj/item/rig_module/maneuvering_jets,
/obj/item/rig_module/device/anomaly_scanner
)
/obj/item/weapon/rig/medical
name = "rescue suit control module"
suit_type = "rescue hardsuit"
desc = "A durable suit designed for medical rescue in high risk areas."
icon_state = "medical_rig"
armor = list(melee = 30, bullet = 15, laser = 20, energy = 60, bomb = 30, bio = 100, rad = 100)
slowdown = 1
offline_vision_restriction = 1
helm_type = /obj/item/clothing/head/helmet/space/new_rig/medical
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/storage/firstaid,/obj/item/device/healthanalyzer,/obj/item/stack/medical,/obj/item/roller )
req_access = list()
req_one_access = list()
/obj/item/weapon/rig/medical/equipped
initial_modules = list(
/obj/item/rig_module/chem_dispenser/injector,
/obj/item/rig_module/maneuvering_jets,
/obj/item/rig_module/device/healthscanner,
/obj/item/rig_module/vision/medhud
)
/obj/item/weapon/rig/hazard
name = "hazard hardsuit control module"
suit_type = "hazard hardsuit"
desc = "A Security hardsuit designed for prolonged EVA in dangerous environments."
icon_state = "hazard_rig"
armor = list(melee = 60, bullet = 40, laser = 30, energy = 15, bomb = 60, bio = 100, rad = 30)
slowdown = 1
offline_slowdown = 3
offline_vision_restriction = 1
helm_type = /obj/item/clothing/head/helmet/space/new_rig/hazard
allowed = list(/obj/item/weapon/gun,/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/melee/baton)
req_access = list()
req_one_access = list()
/obj/item/weapon/rig/hazard/equipped
initial_modules = list(
/obj/item/rig_module/vision/sechud,
/obj/item/rig_module/maneuvering_jets,
/obj/item/rig_module/grenade_launcher,
/obj/item/rig_module/mounted/taser
)
@@ -0,0 +1,21 @@
//Syndicate rig
/obj/item/clothing/head/helmet/space/void/merc
name = "blood-red voidsuit helmet"
desc = "An advanced helmet designed for work in special operations. Property of Gorlex Marauders."
icon_state = "rig0-syndie"
item_state = "syndie_helm"
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 35, bio = 100, rad = 60)
siemens_coefficient = 0.6
species_restricted = list("Human")
/obj/item/clothing/suit/space/void/merc
icon_state = "rig-syndie"
name = "blood-red voidsuit"
desc = "An advanced suit that protects against injuries during special operations. Property of Gorlex Marauders."
item_state = "syndie_voidsuit"
slowdown = 1
w_class = 3
armor = list(melee = 60, bullet = 50, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 60)
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/gun,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/restraints/handcuffs)
siemens_coefficient = 0.6
species_restricted = list("Human", "Skrell")
@@ -0,0 +1,83 @@
// Station voidsuits
//Engineering rig
/obj/item/clothing/head/helmet/space/void/engineering
name = "engineering voidsuit helmet"
desc = "A special helmet designed for work in a hazardous, low-pressure environment. Has radiation shielding."
icon_state = "rig0-engineering"
item_state = "eng_helm"
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 80)
/obj/item/clothing/suit/space/void/engineering
name = "engineering voidsuit"
desc = "A special suit that protects against hazardous, low pressure environments. Has radiation shielding."
icon_state = "rig-engineering"
item_state = "eng_voidsuit"
slowdown = 1
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 80)
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/storage/bag/ore,/obj/item/device/t_scanner,/obj/item/weapon/pickaxe, /obj/item/weapon/rcd)
//Mining rig
/obj/item/clothing/head/helmet/space/void/mining
name = "mining voidsuit helmet"
desc = "A special helmet designed for work in a hazardous, low pressure environment. Has reinforced plating."
icon_state = "rig0-mining"
item_state = "mining_helm"
armor = list(melee = 50, bullet = 5, laser = 20,energy = 5, bomb = 55, bio = 100, rad = 20)
/obj/item/clothing/suit/space/void/mining
icon_state = "rig-mining"
name = "mining voidsuit"
desc = "A special suit that protects against hazardous, low pressure environments. Has reinforced plating."
item_state = "mining_voidsuit"
armor = list(melee = 50, bullet = 5, laser = 20,energy = 5, bomb = 55, bio = 100, rad = 20)
//Medical Rig
/obj/item/clothing/head/helmet/space/void/medical
name = "medical voidsuit helmet"
desc = "A special helmet designed for work in a hazardous, low pressure environment. Has minor radiation shielding."
icon_state = "rig0-medical"
item_state = "medical_helm"
armor = list(melee = 30, bullet = 5, laser = 20,energy = 5, bomb = 25, bio = 100, rad = 50)
/obj/item/clothing/suit/space/void/medical
icon_state = "rig-medical"
name = "medical voidsuit"
desc = "A special suit that protects against hazardous, low pressure environments. Has minor radiation shielding."
item_state = "medical_voidsuit"
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/storage/firstaid,/obj/item/device/healthanalyzer,/obj/item/stack/medical)
armor = list(melee = 30, bullet = 5, laser = 20,energy = 5, bomb = 25, bio = 100, rad = 50)
//Security
/obj/item/clothing/head/helmet/space/void/security
name = "security voidsuit helmet"
desc = "A special helmet designed for work in a hazardous, low pressure environment. Has an additional layer of armor."
icon_state = "rig0-sec"
item_state = "sec_helm"
armor = list(melee = 60, bullet = 10, laser = 30, energy = 5, bomb = 45, bio = 100, rad = 10)
siemens_coefficient = 0.7
/obj/item/clothing/suit/space/void/security
icon_state = "rig-sec"
name = "security voidsuit"
desc = "A special suit that protects against hazardous, low pressure environments. Has an additional layer of armor."
item_state = "sec_voidsuit"
armor = list(melee = 60, bullet = 10, laser = 30, energy = 5, bomb = 45, bio = 100, rad = 10)
allowed = list(/obj/item/weapon/gun,/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/melee/baton)
siemens_coefficient = 0.7
//Atmospherics Rig (BS12)
/obj/item/clothing/head/helmet/space/void/atmos
desc = "A special helmet designed for work in a hazardous, low pressure environments. Has improved thermal protection and minor radiation shielding."
name = "atmospherics voidsuit helmet"
icon_state = "rig0-atmos"
item_state = "atmos_helm"
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 50)
max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT
/obj/item/clothing/suit/space/void/atmos
desc = "A special suit that protects against hazardous, low pressure environments. Has improved thermal protection and minor radiation shielding."
icon_state = "rig-atmos"
name = "atmos voidsuit"
item_state = "atmos_voidsuit"
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 50)
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
@@ -0,0 +1,241 @@
//NASA Voidsuit
/obj/item/clothing/head/helmet/space/void
name = "void helmet"
desc = "A high-tech dark red space suit helmet. Used for AI satellite maintenance."
icon_state = "void"
heat_protection = HEAD
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 20)
max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT
//Species-specific stuff.
species_restricted = list("Human")
sprite_sheets_refit = list(
"Unathi" = 'icons/mob/species/unathi/helmet.dmi',
"Tajara" = 'icons/mob/species/tajaran/helmet.dmi',
"Skrell" = 'icons/mob/species/skrell/helmet.dmi',
)
sprite_sheets_obj = list(
"Unathi" = 'icons/obj/clothing/species/unathi/hats.dmi',
"Tajara" = 'icons/obj/clothing/species/tajaran/hats.dmi',
"Skrell" = 'icons/obj/clothing/species/skrell/hats.dmi',
)
/obj/item/clothing/suit/space/void
name = "voidsuit"
icon_state = "void"
item_state = "void"
desc = "A high-tech dark red space suit. Used for AI satellite maintenance."
slowdown = 1
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 20)
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank)
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT
species_restricted = list("Human", "Skrell")
sprite_sheets_refit = list(
"Unathi" = 'icons/mob/species/unathi/suit.dmi',
"Tajara" = 'icons/mob/species/tajaran/suit.dmi',
"Skrell" = 'icons/mob/species/skrell/suit.dmi',
)
sprite_sheets_obj = list(
"Unathi" = 'icons/obj/clothing/species/unathi/suits.dmi',
"Tajara" = 'icons/obj/clothing/species/tajaran/suits.dmi',
"Skrell" = 'icons/obj/clothing/species/skrell/suits.dmi',
)
//Breach thresholds, should ideally be inherited by most (if not all) voidsuits.
//With 0.2 resiliance, will reach 10 breach damage after 3 laser carbine blasts or 8 smg hits.
breach_threshold = 18
can_breach = 1
//Inbuilt devices.
var/obj/item/clothing/shoes/magboots/boots = null // Deployable boots, if any.
var/obj/item/clothing/head/helmet/helmet = null // Deployable helmet, if any.
var/obj/item/weapon/tank/tank = null // Deployable tank, if any.
/obj/item/clothing/suit/space/void/examine(user)
..(user)
var/list/part_list = new
for(var/obj/item/I in list(helmet,boots,tank))
part_list += "\a [I]"
user << "\The [src] has [english_list(part_list)] installed."
if(tank && in_range(src,user))
user << "<span class='notice'>The wrist-mounted pressure gauge reads [max(round(tank.air_contents.return_pressure()),0)] kPa remaining in \the [tank].</span>"
/obj/item/clothing/suit/space/void/refit_for_species(var/target_species)
..()
if(istype(helmet))
helmet.refit_for_species(target_species)
if(istype(boots))
boots.refit_for_species(target_species)
/obj/item/clothing/suit/space/void/equipped(mob/M)
..()
var/mob/living/carbon/human/H = M
if(!istype(H)) return
if(H.wear_suit != src)
return
if(boots)
if (H.equip_to_slot_if_possible(boots, slot_shoes))
boots.flags |= NODROP
if(helmet)
if(H.head)
M << "You are unable to deploy your suit's helmet as \the [H.head] is in the way."
else if (H.equip_to_slot_if_possible(helmet, slot_head))
M << "Your suit's helmet deploys with a hiss."
helmet.flags |= NODROP
if(tank)
if(H.s_store) //In case someone finds a way.
M << "Alarmingly, the valve on your suit's installed tank fails to engage."
else if (H.equip_to_slot_if_possible(tank, slot_s_store))
M << "The valve on your suit's installed tank safely engages."
tank.flags |= NODROP
/obj/item/clothing/suit/space/void/dropped()
..()
var/mob/living/carbon/human/H
if(helmet)
helmet.flags &= ~NODROP
H = helmet.loc
if(istype(H))
if(helmet && H.head == helmet)
H.unEquip(helmet)
helmet.forceMove(src)
if(boots)
boots.flags &= ~NODROP
H = boots.loc
if(istype(H))
if(boots && H.shoes == boots)
H.unEquip(boots)
boots.forceMove(src)
if(tank)
tank.flags &= ~NODROP
tank.forceMove(src)
/obj/item/clothing/suit/space/void/verb/toggle_helmet()
set name = "Toggle Helmet"
set category = "Object"
set src in usr
if(!istype(src.loc,/mob/living)) return
if(!helmet)
usr << "There is no helmet installed."
return
var/mob/living/carbon/human/H = usr
if(!istype(H)) return
if(H.stat) return
if(H.wear_suit != src) return
if(H.head == helmet)
H << "<span class='notice'>You retract your suit helmet.</span>"
helmet.flags &= ~NODROP
H.unEquip(helmet)
helmet.forceMove(src)
else
if(H.head)
H << "<span class='danger'>You cannot deploy your helmet while wearing \the [H.head].</span>"
return
if(H.equip_to_slot_if_possible(helmet, slot_head))
helmet.pickup(H)
helmet.flags |= NODROP
H << "<span class='info'>You deploy your suit helmet, sealing you off from the world.</span>"
helmet.update_light(H)
/obj/item/clothing/suit/space/void/verb/eject_tank()
set name = "Eject Voidsuit Tank"
set category = "Object"
set src in usr
if(!istype(src.loc,/mob/living)) return
if(!tank)
usr << "There is no tank inserted."
return
var/mob/living/carbon/human/H = usr
if(!istype(H)) return
if(H.stat) return
if(H.wear_suit != src) return
H << "<span class='info'>You press the emergency release, ejecting \the [tank] from your suit.</span>"
tank.flags &= ~NODROP
H.unEquip(tank)
src.tank = null
/obj/item/clothing/suit/space/void/attackby(obj/item/W as obj, mob/user as mob)
if(!istype(user,/mob/living)) return
if(istype(src.loc,/mob/living))
user << "<span class='danger'>How do you propose to modify a voidsuit while it is being worn?</span>"
return
if(istype(W,/obj/item/weapon/screwdriver))
if(helmet || boots || tank)
var/choice = input("What component would you like to remove?") as null|anything in list(helmet,boots,tank)
if(!choice) return
if(choice == tank) //No, a switch doesn't work here. Sorry. ~Techhead
user << "You pop \the [tank] out of \the [src]'s storage compartment."
tank.forceMove(get_turf(src))
src.tank = null
else if(choice == helmet)
user << "You detatch \the [helmet] from \the [src]'s helmet mount."
helmet.forceMove(get_turf(src))
src.helmet = null
else if(choice == boots)
user << "You detatch \the [boots] from \the [src]'s boot mounts."
boots.forceMove(get_turf(src))
src.boots = null
else
user << "\The [src] does not have anything installed."
return
else if(istype(W,/obj/item/clothing/head/helmet/space))
if(helmet)
user << "\The [src] already has a helmet installed."
else
user << "You attach \the [W] to \the [src]'s helmet mount."
user.drop_item()
W.forceMove(src)
src.helmet = W
return
else if(istype(W,/obj/item/clothing/shoes/magboots))
if(boots)
user << "\The [src] already has magboots installed."
else
user << "You attach \the [W] to \the [src]'s boot mounts."
user.drop_item()
W.forceMove(src)
boots = W
return
else if(istype(W,/obj/item/weapon/tank))
if(tank)
user << "\The [src] already has an airtank installed."
else if(istype(W,/obj/item/weapon/tank/plasma))
user << "\The [W] cannot be inserted into \the [src]'s storage compartment."
else
user << "You insert \the [W] into \the [src]'s storage compartment."
user.drop_item()
W.forceMove(src)
tank = W
return
..()
@@ -0,0 +1,24 @@
//Wizard Rig
/obj/item/clothing/head/helmet/space/void/wizard
name = "gem-encrusted voidsuit helmet"
desc = "A bizarre gem-encrusted helmet that radiates magical energies."
icon_state = "rig0-wiz"
item_state = "wiz_helm"
unacidable = 1 //No longer shall our kind be foiled by lone chemists with spray bottles!
armor = list(melee = 40, bullet = 20, laser = 20,energy = 20, bomb = 35, bio = 100, rad = 60)
siemens_coefficient = 0.7
sprite_sheets_refit = null
sprite_sheets_obj = null
/obj/item/clothing/suit/space/void/wizard
icon_state = "rig-wiz"
name = "gem-encrusted voidsuit"
desc = "A bizarre gem-encrusted suit that radiates magical energies."
item_state = "wiz_voidsuit"
slowdown = 1
w_class = 3
unacidable = 1
armor = list(melee = 40, bullet = 20, laser = 20,energy = 20, bomb = 35, bio = 100, rad = 60)
siemens_coefficient = 0.7
sprite_sheets_refit = null
sprite_sheets_obj = null
@@ -15,7 +15,7 @@ var/const/MAX_ACTIVE_TIME = 400
icon_state = "facehugger"
item_state = "facehugger"
w_class = 1 //note: can be picked up by aliens unlike most other items of w_class below 4
flags = MASKCOVERSMOUTH | MASKCOVERSEYES | MASKINTERNALS
flags = MASKCOVERSMOUTH | MASKCOVERSEYES | AIRTIGHT
throw_range = 5
var/stat = CONSCIOUS //UNCONSCIOUS is the idle state in this case
@@ -149,6 +149,13 @@
brainmob.emp_damage += rand(0,10)
..()
/obj/item/device/mmi/relaymove(var/mob/user, var/direction)
if(user.stat || user.stunned)
return
var/obj/item/weapon/rig/rig = src.get_rig()
if(rig)
rig.forced_move(direction, user)
/obj/item/device/mmi/Destroy()
if(isrobot(loc))
var/mob/living/silicon/robot/borg = loc
@@ -54,6 +54,7 @@
if(in_contents_of(/obj/mecha))
canmove = 1
use_me = 1 //If it can move, let it emote
if(istype(loc, /obj/item/device/mmi)) canmove = 1 //mmi won't move anyways so whatever
else canmove = 0
return canmove
@@ -139,6 +139,10 @@
// log_to_dd("k")
sql_report_death(src)
ticker.mode.check_win() //Calls the rounds wincheck, mainly for wizard, malf, and changeling now
if(wearing_rig)
wearing_rig.notify_ai("<span class='danger'>Warning: user death event. Mobility control passed to integrated intelligence system.</span>")
return ..(gibbed)
/mob/living/carbon/human/proc/makeSkeleton()
@@ -739,7 +739,7 @@
// Process toxic farts first.
if(TOXIC_FARTS in mutations)
for(var/mob/M in range(location,aoe_range))
if (M.internal != null && M.wear_mask && (M.wear_mask.flags & MASKINTERNALS))
if (M.internal != null && M.wear_mask && (M.wear_mask.flags & AIRTIGHT))
continue
if(!airborne_can_reach(location,M,aoe_range))
continue
@@ -8,6 +8,7 @@
var/list/hud_list[10]
var/datum/species/species //Contains icon generation and language information, set during New().
var/embedded_flag //To check if we've need to roll for damage on movement while an item is imbedded in us.
var/obj/item/weapon/rig/wearing_rig // This is very not good, but it's much much better than calling get_rig() every update_canmove() call.
/mob/living/carbon/human/New(var/new_loc, var/new_species = null, var/delay_ready_dna=0)
@@ -257,6 +258,14 @@
stat("Internal Atmosphere Info", internal.name)
stat("Tank Pressure", internal.air_contents.return_pressure())
stat("Distribution Pressure", internal.distribute_pressure)
if(back && istype(back, /obj/item/weapon/rig))
var/obj/item/weapon/rig/suit = back
var/cell_status = "ERROR"
if(suit.cell)
cell_status = "[suit.cell.charge]/[suit.cell.maxcharge]"
stat(null, "Suit charge: [cell_status]")
if(mind)
if(mind.changeling)
stat("Chemical Storage", "[mind.changeling.chem_charges]/[mind.changeling.chem_storage]")
@@ -1101,6 +1110,17 @@
if(istype(src.wear_mask, /obj/item/clothing/mask))
var/obj/item/clothing/mask/MT = src.wear_mask
tinted += MT.tint
//god help me
if(istype(back, /obj/item/weapon/rig))
var/obj/item/weapon/rig/O = back
if(O.helmet && O.helmet == head && (O.helmet.body_parts_covered & HEAD))
if((O.offline && O.offline_vision_restriction == 1) || (!O.offline && O.vision_restriction == 1))
tinted = 2
if((O.offline && O.offline_vision_restriction == 2) || (!O.offline && O.vision_restriction == 2))
tinted = 3
//im so sorry
return tinted
@@ -130,6 +130,9 @@
..()
/mob/living/carbon/human/Paralyse(amount)
// Notify our AI if they can now control the suit.
if(wearing_rig && !stat && paralysis < amount) //We are passing out right this second.
wearing_rig.notify_ai("<span class='danger'>Warning: user consciousness failure. Mobility control passed to integrated intelligence system.</span>")
..()
/mob/living/carbon/human/adjustCloneLoss(var/amount)
@@ -58,10 +58,19 @@
if(..())
return 1
//Do we have a working jetpack
if(istype(back, /obj/item/weapon/tank/jetpack) && isturf(loc)) //Second check is so you can't use a jetpack in a mech
var/obj/item/weapon/tank/jetpack/J = back
if((movement_dir || J.stabilization_on) && J.allow_thrust(0.01, src))
//Do we have a working jetpack?
var/obj/item/weapon/tank/jetpack/thrust
if(back)
if(istype(back,/obj/item/weapon/tank/jetpack))
thrust = back
else if(istype(back,/obj/item/weapon/rig))
var/obj/item/weapon/rig/rig = back
for(var/obj/item/rig_module/maneuvering_jets/module in rig.installed_modules)
thrust = module.jets
break
if(thrust)
if((movement_dir || thrust.stabilization_on) && thrust.allow_thrust(0.01, src))
return 1
return 0
+50 -1
View File
@@ -62,6 +62,11 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
//TODO: seperate this out
// update the current life tick, can be used to e.g. only do something every 4 ticks
life_tick++
// This is not an ideal place for this but it will do for now.
if(wearing_rig && wearing_rig.offline)
wearing_rig = null
var/datum/gas_mixture/environment = loc.return_air()
in_stasis = 0
@@ -420,6 +425,24 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
// Health is in deep shit and we're not already dead
return health <= 0 && stat != 2
/mob/living/carbon/human/get_breath_from_internal(volume_needed=BREATH_VOLUME)
if(internal)
var/obj/item/weapon/tank/rig_supply
if(istype(back,/obj/item/weapon/rig))
var/obj/item/weapon/rig/rig = back
if(!rig.offline && (rig.air_supply && internal == rig.air_supply))
rig_supply = rig.air_supply
if (!rig_supply && (!contents.Find(internal) || !((wear_mask && (wear_mask.flags & AIRTIGHT)) || (head && (head.flags & AIRTIGHT)))))
internal = null
if(internal)
return internal.remove_air_volume(volume_needed)
else if(internals)
internals.icon_state = "internal0"
return null
/mob/living/carbon/human/proc/handle_breath(var/datum/gas_mixture/breath)
if(status_flags & GODMODE)
return 0
@@ -1178,7 +1201,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
see_invisible = SEE_INVISIBLE_LIVING
seer = 0
if(glasses || head)
if(glasses || head || back)
if(glasses)
var/obj/item/clothing/glasses/G = glasses
if(istype(G))
@@ -1220,6 +1243,32 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
if(ANTAGHUD)
process_antag_hud(src)
if(back && istype(back, /obj/item/weapon/rig)) ///ahhhg so snowflakey
var/obj/item/weapon/rig/rig = back ///but the way it does it now is incompatible with non-snowflake systems ahhhgg
if(rig.visor)
if(!rig.helmet || (head && rig.helmet == head))
if(rig.visor && rig.visor.vision && rig.visor.active && rig.visor.vision.glasses)
var/obj/item/clothing/glasses/G = rig.visor.vision.glasses
if(istype(G))
see_in_dark = (G.darkness_view ? see_in_dark + G.darkness_view : species.darksight) // Otherwise we keep our darkness view with togglable nightvision.
if(G.vision_flags) // MESONS
sight |= G.vision_flags
if(!druggy)
see_invisible = SEE_INVISIBLE_MINIMUM
if(!G.see_darkness)
see_invisible = SEE_INVISIBLE_MINIMUM
/* HUD shit goes here, as long as it doesn't modify sight flags */
// The purpose of this is to stop xray and w/e from preventing you from using huds -- Love, Doohl
switch(G.HUDType)
if(SECHUD)
process_sec_hud(src,1)
if(MEDHUD)
process_med_hud(src,1)
if(ANTAGHUD)
process_antag_hud(src)
else if(!seer)
see_in_dark = species.darksight
see_invisible = SEE_INVISIBLE_LIVING
@@ -67,6 +67,11 @@
return ..()
/mob/living/carbon/human/proc/HasVoiceChanger()
if(istype(back,/obj/item/weapon/rig))
var/obj/item/weapon/rig/rig = back
if(rig.speech && rig.speech.voice_holder && rig.speech.voice_holder.active && rig.speech.voice_holder.voice)
return rig.speech.voice_holder.voice
for(var/obj/item/gear in list(wear_mask,wear_suit,head))
if(!gear)
continue
@@ -67,7 +67,7 @@
desc = "sturdy adamantine feet"
icon_state = "golem"
item_state = "golem"
flags = NOSLIP | ABSTRACT | MASKINTERNALS | MASKCOVERSMOUTH | NODROP
flags = NOSLIP | ABSTRACT | AIRTIGHT | MASKCOVERSMOUTH | NODROP
slowdown = SHOES_SLOWDOWN+1
@@ -811,14 +811,32 @@ var/global/list/damage_icon_parts = list()
/mob/living/carbon/human/update_inv_back(var/update_icons=1)
if(back)
back.screen_loc = ui_back //TODO
//determine the icon to use
var/icon/overlay_icon
if(back.icon_override)
overlays_standing[BACK_LAYER] = image("icon" = back.icon_override, "icon_state" = "[back.icon_state]")
overlay_icon = back.icon_override
else if(istype(back, /obj/item/weapon/rig))
//If this is a rig and a mob_icon is set, it will take species into account in the rig update_icon() proc.
var/obj/item/weapon/rig/rig = back
overlay_icon = rig.mob_icon
else if(back.sprite_sheets && back.sprite_sheets[species.name])
overlays_standing[BACK_LAYER] = image("icon" = back.sprite_sheets[species.name], "icon_state" = "[back.icon_state]")
overlay_icon = back.sprite_sheets[species.name]
else
overlays_standing[BACK_LAYER] = image("icon" = 'icons/mob/back.dmi', "icon_state" = "[back.icon_state]")
overlay_icon = icon('icons/mob/back.dmi', "[back.icon_state]")
//determine state to use
var/overlay_state
if(back.item_state)
overlay_state = back.item_state
else
overlay_state = back.icon_state
//create the image
overlays_standing[BACK_LAYER] = image(icon = overlay_icon, icon_state = overlay_state)
else
overlays_standing[BACK_LAYER] = null
overlays_standing[BACK_LAYER] = null
if(update_icons) update_icons()
+3 -3
View File
@@ -1,8 +1,8 @@
/mob/living/carbon/proc/get_breath_from_internal(volume_needed)
/mob/living/carbon/proc/get_breath_from_internal(var/volume_needed=BREATH_VOLUME) //hopefully this will allow overrides to specify a different default volume without breaking any cases where volume is passed in.
if(internal)
if (!contents.Find(internal))
internal = null
if (!wear_mask || !(wear_mask.flags & MASKINTERNALS) )
if (!(wear_mask && (wear_mask.flags & AIRTIGHT)))
internal = null
if(internal)
if (internals)
@@ -11,4 +11,4 @@
else
if (internals)
internals.icon_state = "internal0"
return
return null
+16 -6
View File
@@ -101,7 +101,7 @@ var/list/ai_verbs_default = list(
announcement.announcement_type = "A.I. Announcement"
announcement.announcer = name
announcement.newscast = 1
var/list/possibleNames = ai_names
var/pickedName = null
@@ -215,7 +215,7 @@ var/list/ai_verbs_default = list(
/mob/living/silicon/ai/SetName(pickedName as text)
..()
announcement.announcer = name
if(eyeobj)
@@ -332,19 +332,19 @@ var/list/ai_verbs_default = list(
set name = "Show Crew Manifest"
set category = "AI Commands"
show_station_manifest()
/mob/living/silicon/ai/var/message_cooldown = 0
/mob/living/silicon/ai/proc/ai_announcement_text()
set category = "AI Commands"
set name = "Make Station Announcement"
if(check_unable(AI_CHECK_WIRELESS | AI_CHECK_RADIO))
return
if(message_cooldown)
src << "<span class='warning'>Please allow one minute to pass between announcements.</span>"
return
var/input = input(usr, "Please write a message to announce to the station crew.", "A.I. Announcement") as message|null
if(!input)
return
@@ -383,7 +383,7 @@ var/list/ai_verbs_default = list(
/mob/living/silicon/ai/proc/ai_cancel_call()
set name = "Recall Emergency Shuttle"
set category = "AI Commands"
if(check_unable(AI_CHECK_WIRELESS))
return
@@ -999,3 +999,13 @@ var/list/ai_verbs_default = list(
loc = card//Throw AI into the card.
src << "You have been downloaded to a mobile storage device. Remote device connection severed."
user << "<span class='boldnotice'>Transfer successful</span>: [name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory."
// Pass lying down or getting up to our pet human, if we're in a rig.
/mob/living/silicon/ai/lay_down()
set name = "Rest"
set category = "IC"
resting = 0
var/obj/item/weapon/rig/rig = src.get_rig()
if(rig)
rig.force_rest(src)
+1 -2
View File
@@ -25,8 +25,7 @@
else //Not stunned.
src.stat = 0
if(paralysis || stunned || weakened || buckled || resting || src.loc == card) canmove = 0
else canmove = 1
update_canmove()
regular_hud_updates()
if(src.secHUD == 1)
+7 -6
View File
@@ -83,7 +83,6 @@
var/current_pda_messaging = null
/mob/living/silicon/pai/New(var/obj/item/device/paicard)
canmove = 0
src.loc = paicard
card = paicard
sradio = new(src)
@@ -348,8 +347,6 @@
last_special = world.time + 200
canmove = 1
//I'm not sure how much of this is necessary, but I would rather avoid issues.
if(istype(card.loc,/mob))
var/mob/holder = card.loc
@@ -417,16 +414,21 @@
verbs -= /mob/living/silicon/pai/proc/choose_verbs
/mob/living/silicon/pai/lay_down()
set name = "Rest"
set category = "IC"
// Pass lying down or getting up to our pet human, if we're in a rig.
if(istype(src.loc,/obj/item/device/paicard))
resting = 0
var/obj/item/weapon/rig/rig = src.get_rig()
if(istype(rig))
rig.force_rest(src)
else
resting = !resting
icon_state = resting ? "[chassis]_rest" : "[chassis]"
src << "\blue You are now [resting ? "resting" : "getting up"]"
src << "<span class='notice'>You are now [resting ? "resting" : "getting up"]</span>"
canmove = !resting
@@ -445,7 +447,7 @@
"<span class='notice'>You apply some [W] at [src.name]'s damaged areas.</span>")
else
user << "<span class='notice'>All [src.name]'s systems are nominal.</span>"
return
else if(W.force)
visible_message("<span class='danger'>[user.name] attacks [src] with [W]!</span>")
@@ -495,7 +497,6 @@
card.loc = get_turf(card)
src.forceMove(card)
card.forceMove(card.loc)
canmove = 0
icon_state = "[chassis]"
/mob/living/silicon/pai/Bump(atom/movable/AM as mob|obj, yes)
+3
View File
@@ -200,6 +200,9 @@
return mob.remote_control.relaymove(mob, direct)
if(isAI(mob))
if(istype(mob.loc, /obj/item/device/aicard))
var/obj/O = mob.loc
return O.relaymove(mob, direct) //aicards have special relaymove stuff
return AIMove(n,direct,mob)
if(!mob.canmove)
@@ -0,0 +1,10 @@
/*
This state checks if src_object is contained anywhere in the user's inventory, including bags, etc.
*/
/var/global/datum/topic_state/deep_inventory_state/deep_inventory_state = new()
/datum/topic_state/deep_inventory_state/can_use_topic(var/src_object, var/mob/user)
if(!user.contains(src_object))
return STATUS_CLOSE
return user.shared_nano_interaction()
+46 -1
View File
@@ -11,6 +11,12 @@
var/modifystate
var/can_charge = 1
//self-recharging
var/self_recharge = 0 //if set, the weapon will recharge itself
var/use_external_power = 0 //if set, the weapon will look for an external power source to draw from, otherwise it recharges magically
var/recharge_time = 4
var/charge_tick = 0
/obj/item/weapon/gun/energy/emp_act(severity)
if(power_supply)
power_supply.use(round(power_supply.charge / severity))
@@ -23,7 +29,46 @@
else
power_supply = new(src)
power_supply.give(power_supply.maxcharge)
return
if(self_recharge)
processing_objects.Add(src)
update_icon()
/obj/item/weapon/gun/energy/Destroy()
if(self_recharge)
processing_objects.Remove(src)
..()
/obj/item/weapon/gun/energy/process()
if(self_recharge) //Every [recharge_time] ticks, recharge a shot for the cyborg
charge_tick++
if(charge_tick < recharge_time) return 0
charge_tick = 0
if(!power_supply || power_supply.charge >= power_supply.maxcharge)
return 0 // check if we actually need to recharge
if(use_external_power)
var/obj/item/weapon/stock_parts/cell/external = get_external_power_supply()
if(!external || !external.use(charge_cost)) //Take power from the borg...
return 0
power_supply.give(charge_cost) //... to recharge the shot
update_icon()
return 1
/obj/item/weapon/gun/energy/proc/get_external_power_supply()
if(isrobot(src.loc))
var/mob/living/silicon/robot/R = src.loc
return R.cell
if(istype(src.loc, /obj/item/rig_module))
var/obj/item/rig_module/module = src.loc
if(module.holder && module.holder.wearer)
var/mob/living/carbon/human/H = module.holder.wearer
if(istype(H) && H.back)
var/obj/item/weapon/rig/suit = H.back
if(istype(suit))
return suit.cell
return null
/obj/item/weapon/gun/energy/process_chambered()
if(in_chamber) return 1
+22 -72
View File
@@ -29,27 +29,8 @@ obj/item/weapon/gun/energy/laser/retro
desc = "This is an antique laser gun. All craftsmanship is of the highest quality. It is decorated with assistant leather and chrome. The object menaces with spikes of energy. On the item is an image of Space Station 13. The station is exploding."
force = 10
origin_tech = null
var/charge_tick = 0
/obj/item/weapon/gun/energy/laser/captain/New()
..()
processing_objects.Add(src)
/obj/item/weapon/gun/energy/laser/captain/Destroy()
processing_objects.Remove(src)
return ..()
/obj/item/weapon/gun/energy/laser/captain/process()
charge_tick++
if(charge_tick < 4)
return 0
charge_tick = 0
if(!power_supply)
return 0
power_supply.give(1000)
update_icon()
return 1
self_recharge = 1
/obj/item/weapon/gun/energy/laser/cyborg
@@ -89,6 +70,13 @@ obj/item/weapon/gun/energy/laser/retro
isHandgun()
return 0
/obj/item/weapon/gun/energy/lasercannon/mounted
name = "mounted laser cannon"
self_recharge = 1
use_external_power = 1
recharge_time = 10
/obj/item/weapon/gun/energy/lasercannon/cyborg/process_chambered()
if(in_chamber)
return 1
@@ -119,35 +107,15 @@ obj/item/weapon/gun/energy/laser/retro
projectile_type = "/obj/item/projectile/lasertag/blue"
origin_tech = "combat=1;magnets=2"
clumsy_check = 0
var/charge_tick = 0
special_check(var/mob/living/carbon/human/M)
if(ishuman(M))
if(istype(M.wear_suit, /obj/item/clothing/suit/bluetag))
return 1
M << "\red You need to be wearing your laser tag vest!"
return 0
New()
..()
processing_objects.Add(src)
Destroy()
processing_objects.Remove(src)
return ..()
process()
charge_tick++
if(charge_tick < 4) return 0
charge_tick = 0
if(!power_supply) return 0
power_supply.give(1000)
update_icon()
return 1
self_recharge = 1
/obj/item/weapon/gun/energy/laser/bluetag/special_check(var/mob/living/carbon/human/M)
if(ishuman(M))
if(istype(M.wear_suit, /obj/item/clothing/suit/bluetag))
return 1
M << "\red You need to be wearing your laser tag vest!"
return 0
/obj/item/weapon/gun/energy/laser/redtag
name = "laser tag gun"
@@ -156,30 +124,12 @@ obj/item/weapon/gun/energy/laser/retro
projectile_type = "/obj/item/projectile/lasertag/red"
origin_tech = "combat=1;magnets=2"
clumsy_check = 0
var/charge_tick = 0
special_check(var/mob/living/carbon/human/M)
if(ishuman(M))
if(istype(M.wear_suit, /obj/item/clothing/suit/redtag))
return 1
M << "\red You need to be wearing your laser tag vest!"
return 0
self_recharge = 1
New()
..()
processing_objects.Add(src)
Destroy()
processing_objects.Remove(src)
return ..()
process()
charge_tick++
if(charge_tick < 4) return 0
charge_tick = 0
if(!power_supply) return 0
power_supply.give(1000)
update_icon()
return 1
/obj/item/weapon/gun/energy/laser/redtag/special_check(var/mob/living/carbon/human/M)
if(ishuman(M))
if(istype(M.wear_suit, /obj/item/clothing/suit/redtag))
return 1
M << "\red You need to be wearing your laser tag vest!"
return 0
@@ -35,8 +35,10 @@
else
user.update_inv_r_hand()
/obj/item/weapon/gun/energy/gun/mounted
name = "mounted energy gun"
self_recharge = 1
use_external_power = 1
/obj/item/weapon/gun/energy/gun/nuclear
name = "Advanced Energy Gun"
@@ -44,7 +46,6 @@
icon_state = "nucgun"
origin_tech = "combat=3;materials=5;powerstorage=3"
var/lightfail = 0
var/charge_tick = 0
can_flashlight = 0
can_charge = 0
@@ -40,25 +40,9 @@
projectile_type = "/obj/item/projectile/energy/floramut"
origin_tech = "materials=2;biotech=3;powerstorage=3"
modifystate = "floramut"
var/charge_tick = 0
var/mode = 0 //0 = mutate, 1 = yield boost
/obj/item/weapon/gun/energy/floragun/New()
..()
processing_objects.Add(src)
/obj/item/weapon/gun/energy/floragun/Destroy()
processing_objects.Remove(src)
return ..()
/obj/item/weapon/gun/energy/floragun/process()
charge_tick++
if(charge_tick < 4) return 0
charge_tick = 0
if(!power_supply) return 0
power_supply.give(1000)
update_icon()
return 1
self_recharge = 1
/obj/item/weapon/gun/energy/floragun/attack_self(mob/living/user as mob)
switch(mode)
@@ -98,27 +82,9 @@
projectile_type = "/obj/item/projectile/meteor"
cell_type = "/obj/item/weapon/stock_parts/cell/potato"
clumsy_check = 0 //Admin spawn only, might as well let clowns use it.
var/charge_tick = 0
var/recharge_time = 5 //Time it takes for shots to recharge (in ticks)
New()
..()
processing_objects.Add(src)
Destroy()
processing_objects.Remove(src)
return ..()
process()
charge_tick++
if(charge_tick < recharge_time) return 0
charge_tick = 0
if(!power_supply) return 0
power_supply.give(1000)
update_icon()
return
self_recharge = 1
recharge_time = 5 //Time it takes for shots to recharge (in ticks)
/obj/item/weapon/gun/energy/meteorgun/pen
@@ -351,36 +317,12 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out.
/obj/item/weapon/gun/energy/disabler/cyborg
name = "cyborg disabler"
desc = "An integrated disabler that draws from a cyborg's power cell. This weapon contains a limiter to prevent the cyborg's power cell from overheating."
var/charge_tick = 0
var/recharge_time = 2.5
/obj/item/weapon/gun/energy/disabler/cyborg/New()
..()
processing_objects.Add(src)
self_recharge = 1
use_external_power = 1
recharge_time = 2.5
/obj/item/weapon/gun/energy/disabler/cyborg/Destroy()
processing_objects.Remove(src)
return ..()
/obj/item/weapon/gun/energy/disabler/cyborg/process() //Every [recharge_time] ticks, recharge a shot for the cyborg
if(power_supply.charge == power_supply.maxcharge)
return 0
charge_tick++
if(charge_tick < recharge_time)
return 0
charge_tick = 0
if(!power_supply) return 0 //sanity
if(isrobot(src.loc))
var/mob/living/silicon/robot/R = src.loc
if(R && R.cell)
if(R.cell.use(charge_cost/10)) //Take power from the borg...
power_supply.give(charge_cost) //... to recharge the shot
update_icon()
return 1
/* 3d printer 'pseudo guns' for borgs */
/obj/item/weapon/gun/energy/printer
@@ -392,32 +334,7 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out.
cell_type = "/obj/item/weapon/stock_parts/cell/secborg"
projectile_type = "/obj/item/projectile/bullet/midbullet3"
charge_cost = 200 //Yeah, let's NOT give them a 300 round clip that recharges, 20 is more reasonable and will actually hurt the borg's battery for overuse.
var/charge_tick = 0
var/recharge_time = 5
/obj/item/weapon/gun/energy/printer/update_icon()
return
/obj/item/weapon/gun/energy/printer/New()
..()
processing_objects.Add(src)
/obj/item/weapon/gun/energy/printer/Destroy()
processing_objects.Remove(src)
return ..()
/obj/item/weapon/gun/energy/printer/process()
if(power_supply.charge == power_supply.maxcharge)
return 0
charge_tick++
if(charge_tick < recharge_time)
return 0
charge_tick = 0
if(!power_supply) return 0 //sanity
if(isrobot(src.loc))
var/mob/living/silicon/robot/R = src.loc
if(R && R.cell)
if(R.cell.use(charge_cost/10)) //Take power from the borg...
power_supply.give(charge_cost) //...to recharge the shot
return 1
self_recharge = 1
use_external_power = 1
recharge_time = 5
+11 -45
View File
@@ -9,6 +9,11 @@
cell_type = "/obj/item/weapon/stock_parts/cell/crap"
fire_delay = 15
/obj/item/weapon/gun/energy/taser/mounted
name = "mounted taser gun"
self_recharge = 1
use_external_power = 1
/obj/item/weapon/gun/energy/taser/cyborg
name = "taser gun"
desc = "A small, low capacity gun used for non-lethal takedowns."
@@ -16,35 +21,9 @@
fire_sound = 'sound/weapons/Taser.ogg'
projectile_type = "/obj/item/projectile/energy/electrode"
cell_type = "/obj/item/weapon/stock_parts/cell/secborg"
var/charge_tick = 0
var/recharge_time = 10 //Time it takes for shots to recharge (in ticks)
/obj/item/weapon/gun/energy/taser/cyborg/New()
..()
processing_objects.Add(src)
/obj/item/weapon/gun/energy/taser/cyborg/Destroy()
processing_objects.Remove(src)
return ..()
/obj/item/weapon/gun/energy/taser/cyborg/process() //Every [recharge_time] ticks, recharge a shot for the cyborg
if(power_supply.charge == power_supply.maxcharge)
return 0
charge_tick++
if(charge_tick < recharge_time)
return 0
charge_tick = 0
if(!power_supply) return 0 //sanity
if(isrobot(src.loc))
var/mob/living/silicon/robot/R = src.loc
if(R && R.cell)
if(R.cell.use(charge_cost)) //Take power from the borg...
power_supply.give(charge_cost) //... to recharge the shot
update_icon()
return 1
self_recharge = 1
recharge_time = 10 //Time it takes for shots to recharge (in ticks)
/obj/item/weapon/gun/energy/stunrevolver
name = "stun revolver"
@@ -69,25 +48,12 @@
fire_sound = 'sound/weapons/Genhit.ogg'
projectile_type = "/obj/item/projectile/energy/bolt"
cell_type = "/obj/item/weapon/stock_parts/cell/crap"
var/charge_tick = 0
/obj/item/weapon/gun/energy/crossbow/New()
..()
processing_objects.Add(src)
self_recharge = 1
/obj/item/weapon/gun/energy/crossbow/Destroy()
processing_objects.Remove(src)
return ..()
/obj/item/weapon/gun/energy/crossbow/process()
charge_tick++
if(charge_tick < 4)
return 0
charge_tick = 0
if(!power_supply)
return 0
power_supply.give(1000)
return 1
/obj/item/weapon/gun/energy/crossbow/ninja
name = "energy dart thrower"
projectile_type = /obj/item/projectile/energy/dart
/obj/item/weapon/gun/energy/crossbow/update_icon()
return