diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm
index a7297bc60d..40ea2035df 100644
--- a/code/__defines/misc.dm
+++ b/code/__defines/misc.dm
@@ -177,6 +177,7 @@
#define MAT_SUPERMATTER "supermatter"
#define MAT_METALHYDROGEN "mhydrogen"
#define MAT_OSMIUM "osmium"
+#define MAT_GRAPHITE "graphite"
#define SHARD_SHARD "shard"
#define SHARD_SHRAPNEL "shrapnel"
diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm
index 71a7610547..f2a2867220 100644
--- a/code/game/mecha/mech_fabricator.dm
+++ b/code/game/mecha/mech_fabricator.dm
@@ -13,8 +13,8 @@
var/speed = 1
var/mat_efficiency = 1
- var/list/materials = list(DEFAULT_WALL_MATERIAL = 0, "glass" = 0, "plastic" = 0, MAT_PLASTEEL = 0, "gold" = 0, "silver" = 0, MAT_LEAD = 0, "osmium" = 0, "diamond" = 0, MAT_DURASTEEL = 0, "phoron" = 0, "uranium" = 0, MAT_VERDANTIUM = 0, MAT_MORPHIUM = 0, MAT_METALHYDROGEN = 0, MAT_SUPERMATTER = 0)
- var/list/hidden_materials = list(MAT_PLASTEEL, MAT_DURASTEEL, MAT_VERDANTIUM, MAT_MORPHIUM, MAT_METALHYDROGEN, MAT_SUPERMATTER)
+ var/list/materials = list(DEFAULT_WALL_MATERIAL = 0, "glass" = 0, "plastic" = 0, MAT_GRAPHITE = 0, MAT_PLASTEEL = 0, "gold" = 0, "silver" = 0, MAT_LEAD = 0, "osmium" = 0, "diamond" = 0, MAT_DURASTEEL = 0, "phoron" = 0, "uranium" = 0, MAT_VERDANTIUM = 0, MAT_MORPHIUM = 0, MAT_METALHYDROGEN = 0, MAT_SUPERMATTER = 0)
+ var/list/hidden_materials = list(MAT_PLASTEEL, MAT_DURASTEEL, MAT_GRAPHITE, MAT_VERDANTIUM, MAT_MORPHIUM, MAT_METALHYDROGEN, MAT_SUPERMATTER)
var/res_max_amount = 200000
var/datum/research/files
diff --git a/code/game/mecha/mech_prosthetics.dm b/code/game/mecha/mech_prosthetics.dm
index 39b4cf1623..2f59728128 100644
--- a/code/game/mecha/mech_prosthetics.dm
+++ b/code/game/mecha/mech_prosthetics.dm
@@ -13,8 +13,8 @@
var/speed = 1
var/mat_efficiency = 1
- var/list/materials = list(DEFAULT_WALL_MATERIAL = 0, "glass" = 0, "plastic" = 0, MAT_PLASTEEL = 0, "gold" = 0, "silver" = 0, MAT_LEAD = 0, "osmium" = 0, "diamond" = 0, MAT_DURASTEEL = 0, "phoron" = 0, "uranium" = 0, MAT_VERDANTIUM = 0, MAT_MORPHIUM = 0)
- var/list/hidden_materials = list(MAT_DURASTEEL, MAT_VERDANTIUM, MAT_MORPHIUM)
+ var/list/materials = list(DEFAULT_WALL_MATERIAL = 0, "glass" = 0, "plastic" = 0, MAT_GRAPHITE = 0, MAT_PLASTEEL = 0, "gold" = 0, "silver" = 0, MAT_LEAD = 0, "osmium" = 0, "diamond" = 0, MAT_DURASTEEL = 0, "phoron" = 0, "uranium" = 0, MAT_VERDANTIUM = 0, MAT_MORPHIUM = 0)
+ var/list/hidden_materials = list(MAT_DURASTEEL, MAT_GRAPHITE, MAT_VERDANTIUM, MAT_MORPHIUM)
var/res_max_amount = 200000
var/datum/research/files
diff --git a/code/modules/clothing/spacesuits/rig/modules/specific/ai_container.dm b/code/modules/clothing/spacesuits/rig/modules/specific/ai_container.dm
new file mode 100644
index 0000000000..6dc5fc4f01
--- /dev/null
+++ b/code/modules/clothing/spacesuits/rig/modules/specific/ai_container.dm
@@ -0,0 +1,216 @@
+/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))
+ to_chat(usr, "You are not loaded into a hardsuit.")
+ return
+
+ var/obj/item/rig_module/module = usr.loc.loc
+ if(!module.holder)
+ to_chat(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 Core Transfer"
+ deactivate_string = "Disable Core Transfer"
+
+ 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
+
+/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.
+ input_device.attackby(card,user)
+
+ // 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)
+ 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
+ // 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/digital/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)
+ to_chat(user, "You cannot eject your currently stored AI. Purge it manually.")
+ return 0
+ to_chat(user, "You purge the previous AI from your Integrated Intelligence System, freeing it for use.")
+ 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.drop_from_inventory(ai)
+ ai.forceMove(src)
+ ai_card = ai
+ to_chat(ai_mob, "You have been transferred to \the [holder]'s [src].")
+ to_chat(user, "You load [ai_mob] into \the [holder]'s [src].")
+
+ integrated_ai = ai_mob
+
+ if(!(locate(integrated_ai) in ai_card))
+ integrated_ai = null
+ eject_ai()
+ else
+ to_chat(user, "There is no active AI within \the [ai].")
+ else
+ to_chat(user, "There is no active AI within \the [ai].")
+ update_verb_holder()
+ return
diff --git a/code/modules/clothing/spacesuits/rig/modules/specific/chem_dispenser.dm b/code/modules/clothing/spacesuits/rig/modules/specific/chem_dispenser.dm
new file mode 100644
index 0000000000..e8d6416e9a
--- /dev/null
+++ b/code/modules/clothing/spacesuits/rig/modules/specific/chem_dispenser.dm
@@ -0,0 +1,174 @@
+/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", "glucose", 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."
+
+ //Want more? Go refill. Gives the ninja another reason to have to show their face.
+ charges = list(
+ list("tricordrazine", "tricordrazine", 0, 30),
+ list("tramadol", "tramadol", 0, 30),
+ list("dexalin plus", "dexalinp", 0, 30),
+ list("antibiotics", "spaceacillin", 0, 30),
+ list("antitoxins", "anti_toxin", 0, 60),
+ list("nutrients", "glucose", 0, 80),
+ list("bicaridine", "bicaridine", 0, 30),
+ list("clotting agent", "myelamine", 0, 30),
+ list("peridaxon", "peridaxon", 0, 30),
+ list("hyronalin", "hyronalin", 0, 30),
+ list("radium", "radium", 0, 30)
+ )
+
+/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)
+ to_chat(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)
+ to_chat(user, "You transfer [total_transferred] units into the suit reservoir.")
+ else
+ to_chat(user, "None of the reagents seem suitable.")
+ 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)
+ to_chat(H, "You have not selected a chemical type.")
+ return 0
+
+ var/datum/rig_charge/charge = charges[charge_selected]
+
+ if(!charge)
+ return 0
+
+ var/chems_to_use = 10
+ if(charge.charges <= 0)
+ to_chat(H, "Insufficient chems!")
+ 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)
+ to_chat(H, "You inject [target_mob] with [chems_to_use] unit\s of [charge.display_name].")
+ to_chat(target_mob, "You feel a rushing in your veins as [chems_to_use] unit\s of [charge.display_name] [chems_to_use == 1 ? "is" : "are"] injected.")
+ 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", "glucose", 0, 80),
+ list("clotting agent", "myelamine", 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/chem_dispenser/injector/advanced
+
+ 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", "glucose", 0, 80),
+ list("hyronalin", "hyronalin", 0, 80),
+ list("radium", "radium", 0, 80),
+ list("clotting agent", "myelamine", 0, 80)
+ )
+
+/obj/item/rig_module/chem_dispenser/injector/advanced/empty
+ charges = list(
+ list("tricordrazine", "tricordrazine", 0, 0),
+ list("tramadol", "tramadol", 0, 0),
+ list("dexalin plus", "dexalinp", 0, 0),
+ list("antibiotics", "spaceacillin", 0, 0),
+ list("antitoxins", "anti_toxin", 0, 0),
+ list("nutrients", "glucose", 0, 0),
+ list("hyronalin", "hyronalin", 0, 0),
+ list("radium", "radium", 0, 0),
+ list("clotting agent", "myelamine", 0, 0)
+ )
diff --git a/code/modules/clothing/spacesuits/rig/modules/specific/cleaner_launcher.dm b/code/modules/clothing/spacesuits/rig/modules/specific/cleaner_launcher.dm
new file mode 100644
index 0000000000..998fc3d46a
--- /dev/null
+++ b/code/modules/clothing/spacesuits/rig/modules/specific/cleaner_launcher.dm
@@ -0,0 +1,70 @@
+/obj/item/rig_module/cleaner_launcher
+
+ name = "mounted space cleaner launcher"
+ desc = "A shoulder-mounted micro-cleaner dispenser."
+ selectable = 1
+ icon_state = "grenade_launcher"
+
+ interface_name = "integrated cleaner launcher"
+ interface_desc = "Discharges loaded cleaner grenades against the wearer's location."
+
+ var/fire_force = 30
+ var/fire_distance = 10
+
+ charges = list(
+ list("cleaner grenade", "cleaner grenade", /obj/item/weapon/grenade/chem_grenade/cleaner, 9),
+ )
+
+/obj/item/rig_module/cleaner_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)
+ to_chat(user, "Another grenade of that type will not fit into the module.")
+ return 0
+
+ to_chat(user, "You slot \the [input_device] into the suit module.")
+ user.drop_from_inventory(input_device)
+ qdel(input_device)
+ accepted_item.charges++
+ return 1
+
+/obj/item/rig_module/cleaner_launcher/engage(atom/target)
+
+ if(!..())
+ return 0
+
+ if(!target)
+ return 0
+
+ var/mob/living/carbon/human/H = holder.wearer
+
+ if(!charge_selected)
+ to_chat(H, "You have not selected a grenade type.")
+ return 0
+
+ var/datum/rig_charge/charge = charges[charge_selected]
+
+ if(!charge)
+ return 0
+
+ if(charge.charges <= 0)
+ to_chat(H, "Insufficient grenades!")
+ return 0
+
+ charge.charges--
+ var/obj/item/weapon/grenade/new_grenade = new charge.product_type(get_turf(H))
+ H.visible_message("[H] launches \a [new_grenade]!")
+ new_grenade.activate(H)
+ new_grenade.throw_at(target,fire_force,fire_distance)
diff --git a/code/modules/clothing/spacesuits/rig/modules/specific/cloak.dm b/code/modules/clothing/spacesuits/rig/modules/specific/cloak.dm
new file mode 100644
index 0000000000..a1dfb05812
--- /dev/null
+++ b/code/modules/clothing/spacesuits/rig/modules/specific/cloak.dm
@@ -0,0 +1,53 @@
+/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
+
+ to_chat(H, "You are now nearly invisible to normal detection.")
+ H.alpha = 5
+
+ anim(get_turf(H), H, 'icons/effects/effects.dmi', "electricity",null,20,null)
+
+ H.visible_message("[H.name] vanishes into thin air!")
+
+/obj/item/rig_module/stealth_field/deactivate()
+
+ if(!..())
+ return 0
+
+ var/mob/living/carbon/human/H = holder.wearer
+
+ to_chat(H, "You are now visible.")
+
+ 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)
+ H.alpha = initial(H.alpha)
+
+ H.visible_message("[H.name] appears from thin air!")
+ playsound(get_turf(H), 'sound/effects/stealthoff.ogg', 75, 1)
\ No newline at end of file
diff --git a/code/modules/clothing/spacesuits/rig/modules/specific/datajack.dm b/code/modules/clothing/spacesuits/rig/modules/specific/datajack.dm
new file mode 100644
index 0000000000..be34426447
--- /dev/null
+++ b/code/modules/clothing/spacesuits/rig/modules/specific/datajack.dm
@@ -0,0 +1,86 @@
+/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))
+ to_chat(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))
+ to_chat(user, "Download successful; disk erased.")
+ disk.stored = null
+ else
+ to_chat(user, "The disk is corrupt. It is useless to you.")
+ else
+ to_chat(user, "The disk is blank. It is useless to you.")
+ return 1
+
+ // I fucking hate R&D code. This typecheck spam would be totally unnecessary in a sane setup. Sanity? This is BYOND.
+ else if(istype(input_device,/obj/machinery))
+ var/datum/research/incoming_files
+ if(istype(input_device,/obj/machinery/computer/rdconsole) ||\
+ istype(input_device,/obj/machinery/r_n_d/server) ||\
+ istype(input_device,/obj/machinery/mecha_part_fabricator))
+
+ incoming_files = input_device:files
+
+ if(!incoming_files || !incoming_files.known_tech || !incoming_files.known_tech.len)
+ to_chat(user, "Memory failure. There is nothing accessible stored on this terminal.")
+ else
+ // Maybe consider a way to drop all your data into a target repo in the future.
+ if(load_data(incoming_files.known_tech))
+ to_chat(user, "Download successful; local and remote repositories synchronized.")
+ else
+ to_chat(user, "Scan complete. There is nothing useful stored on this terminal.")
+ 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
\ No newline at end of file
diff --git a/code/modules/clothing/spacesuits/rig/modules/specific/device.dm b/code/modules/clothing/spacesuits/rig/modules/specific/device.dm
new file mode 100644
index 0000000000..5771857a27
--- /dev/null
+++ b/code/modules/clothing/spacesuits/rig/modules/specific/device.dm
@@ -0,0 +1,176 @@
+/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/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/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/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"
+ use_power_cost = 0.5
+
+ device_type = /obj/item/weapon/pickaxe/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"
+ use_power_cost = 0.1
+
+ 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/weapon/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/electric/mounted/rig
+
+/obj/item/rig_module/device/arch_drill
+ name = "archaeology drill mount"
+ desc = "A cell-powered fine-excavation device for a hardsuit."
+ icon_state = "exdrill"
+ interface_name = "mounted excavation tool"
+ interface_desc = "A device for excavating ancient relics."
+ usable = 1
+ engage_string = "Configure Drill Depth"
+
+ device_type = /obj/item/weapon/pickaxe/excavationdrill
+
+/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/internalaffairs(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
+ to_chat(holder.wearer, "Switched to denied stamp.")
+ else if(device == deniedstamp)
+ device = iastamp
+ to_chat(holder.wearer, "Switched to internal affairs stamp.")
+ return 1
diff --git a/code/modules/clothing/spacesuits/rig/modules/specific/electrowarfare.dm b/code/modules/clothing/spacesuits/rig/modules/specific/electrowarfare.dm
new file mode 100644
index 0000000000..f30be0b54a
--- /dev/null
+++ b/code/modules/clothing/spacesuits/rig/modules/specific/electrowarfare.dm
@@ -0,0 +1,30 @@
+/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))
\ No newline at end of file
diff --git a/code/modules/clothing/spacesuits/rig/modules/specific/grenade_launcher.dm b/code/modules/clothing/spacesuits/rig/modules/specific/grenade_launcher.dm
new file mode 100644
index 0000000000..9252b062bd
--- /dev/null
+++ b/code/modules/clothing/spacesuits/rig/modules/specific/grenade_launcher.dm
@@ -0,0 +1,98 @@
+/obj/item/rig_module/grenade_launcher
+
+ name = "mounted grenade launcher"
+ desc = "A shoulder-mounted micro-explosive dispenser."
+ selectable = 1
+ icon_state = "grenadelauncher"
+
+ 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)
+ to_chat(user, "Another grenade of that type will not fit into the module.")
+ return 0
+
+ to_chat(user, "You slot \the [input_device] into the suit module.")
+ user.drop_from_inventory(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)
+ to_chat(H, "You have not selected a grenade type.")
+ return 0
+
+ var/datum/rig_charge/charge = charges[charge_selected]
+
+ if(!charge)
+ return 0
+
+ if(charge.charges <= 0)
+ to_chat(H, "Insufficient grenades!")
+ return 0
+
+ charge.charges--
+ var/obj/item/weapon/grenade/new_grenade = new charge.product_type(get_turf(H))
+ H.visible_message("[H] launches \a [new_grenade]!")
+ new_grenade.activate(H)
+ new_grenade.throw_at(target,fire_force,fire_distance)
+
+/obj/item/rig_module/grenade_launcher/smoke
+ name = "mounted smoke-bomb launcher"
+ desc = "A shoulder-mounted smoke-bomb dispenser."
+
+ interface_name = "integrated smoke-bomb launcher"
+ interface_desc = "Discharges loaded smoke-bombs against the wearer's location."
+
+ fire_force = 15
+
+ charges = list(
+ list("smoke bomb", "smoke bomb", /obj/item/weapon/grenade/smokebomb, 6)
+ )
+
+/obj/item/rig_module/grenade_launcher/flash
+ name = "mounted flashbang launcher"
+ desc = "A shoulder-mounted flashbang dispenser."
+ selectable = 1
+ icon_state = "grenadelauncher"
+
+ interface_name = "integrated flashbang launcher"
+ interface_desc = "Discharges loaded grenades against the wearer's location."
+
+ charges = list(
+ list("flashbang", "flashbang", /obj/item/weapon/grenade/flashbang, 3)
+ )
diff --git a/code/modules/clothing/spacesuits/rig/modules/specific/inhand_fabricator.dm b/code/modules/clothing/spacesuits/rig/modules/specific/inhand_fabricator.dm
new file mode 100644
index 0000000000..8e71cf2745
--- /dev/null
+++ b/code/modules/clothing/spacesuits/rig/modules/specific/inhand_fabricator.dm
@@ -0,0 +1,63 @@
+/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 poisoned throwing stars from thin air and electricity."
+
+ var/fabrication_type = /obj/item/weapon/material/star/ninja
+ 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("[H] launches \a [firing]!")
+ firing.throw_at(target,fire_force,fire_distance)
+ else
+ if(H.l_hand && H.r_hand)
+ to_chat(H, "Your hands are full.")
+ else
+ var/obj/item/new_weapon = new fabrication_type()
+ new_weapon.forceMove(H)
+ to_chat(H, "You quickly fabricate \a [new_weapon].")
+ H.put_in_hands(new_weapon)
+
+ 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)
+ set_dir(get_dir(src,target)) // Face the target
+ holder.wearer.Beam(target,"n_beam",,10)
+ return 1
+ return 0
diff --git a/code/modules/clothing/spacesuits/rig/modules/specific/jetpack.dm b/code/modules/clothing/spacesuits/rig/modules/specific/jetpack.dm
new file mode 100644
index 0000000000..6f9f7e3804
--- /dev/null
+++ b/code/modules/clothing/spacesuits/rig/modules/specific/jetpack.dm
@@ -0,0 +1,66 @@
+/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)
\ No newline at end of file
diff --git a/code/modules/clothing/spacesuits/rig/modules/specific/metalfoam_launcher.dm b/code/modules/clothing/spacesuits/rig/modules/specific/metalfoam_launcher.dm
new file mode 100644
index 0000000000..0843b9f779
--- /dev/null
+++ b/code/modules/clothing/spacesuits/rig/modules/specific/metalfoam_launcher.dm
@@ -0,0 +1,15 @@
+
+/obj/item/rig_module/grenade_launcher/metalfoam
+ name = "mounted metalfoam grenade launcher"
+ desc = "A shoulder-mounted foam-bomb dispenser."
+ selectable = 1
+ icon_state = "grenadelauncher"
+
+ interface_name = "integrated metalfoam grenade launcher"
+ interface_desc = "Discharges loaded grenades against the wearer's location."
+
+ fire_force = 15
+
+ charges = list(
+ list("metalfoam", "metalfoam", /obj/item/weapon/grenade/chem_grenade/metalfoam, 5)
+ )
diff --git a/code/modules/clothing/spacesuits/rig/modules/specific/mounted_gun.dm b/code/modules/clothing/spacesuits/rig/modules/specific/mounted_gun.dm
new file mode 100644
index 0000000000..97db6b3281
--- /dev/null
+++ b/code/modules/clothing/spacesuits/rig/modules/specific/mounted_gun.dm
@@ -0,0 +1,175 @@
+/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
+
+ 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 taser"
+ interface_desc = "A shoulder-mounted cell-powered taser."
+
+ 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)
+ to_chat(M, "Your hands are full.")
+ deactivate()
+ return
+
+ var/obj/item/weapon/melee/energy/blade/blade = new(M)
+ blade.creator = 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.drop_from_inventory(blade)
+ qdel(blade)
+
+/obj/item/rig_module/mounted/mop
+
+ name = "mop projector"
+ desc = "A powerful mop projector."
+ icon_state = "mop"
+
+ activate_string = "Project Mop"
+ deactivate_string = "Cancel Mop"
+
+ interface_name = "mop projector"
+ interface_desc = "A mop that can be deployed from the hand of the wearer."
+
+ usable = 1
+ selectable = 1
+ toggleable = 1
+ use_power_cost = 5
+ active_power_cost = 0
+ passive_power_cost = 0
+
+ gun_type = /obj/item/weapon/gun/energy/temperature/mounted
+
+/obj/item/rig_module/mounted/mop/process()
+
+ if(holder && holder.wearer)
+ if(!(locate(/obj/item/weapon/mop_deploy) in holder.wearer))
+ deactivate()
+ return 0
+
+ return ..()
+
+/obj/item/rig_module/mounted/mop/activate()
+
+ ..()
+
+ var/mob/living/M = holder.wearer
+
+ if(M.l_hand && M.r_hand)
+ to_chat(M, "Your hands are full.")
+ deactivate()
+ return
+
+ var/obj/item/weapon/mop_deploy/blade = new(M)
+ blade.creator = M
+ M.put_in_hands(blade)
+
+/obj/item/rig_module/mounted/mop/deactivate()
+
+ ..()
+
+ var/mob/living/M = holder.wearer
+
+ if(!M)
+ return
+
+ for(var/obj/item/weapon/mop_deploy/blade in M.contents)
+ M.drop_from_inventory(blade)
+ qdel(blade)
diff --git a/code/modules/clothing/spacesuits/rig/modules/specific/powersink.dm b/code/modules/clothing/spacesuits/rig/modules/specific/powersink.dm
new file mode 100644
index 0000000000..ec8fba92d6
--- /dev/null
+++ b/code/modules/clothing/spacesuits/rig/modules/specific/powersink.dm
@@ -0,0 +1,129 @@
+/obj/item/rig_module/power_sink
+ 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)
+ to_chat(holder.wearer, "Your power sink retracts as the module deactivates.")
+ 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
+
+ to_chat(H, "You begin draining power from [target]!")
+ 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)
+
+ H.break_cloak()
+
+ if(!holder.cell)
+ to_chat(H, "Your power sink flashes an error; there is no cell in your rig.")
+ drain_complete(H)
+ return
+
+ if(!interfaced_with || !interfaced_with.Adjacent(H) || !(interfaced_with.loc == drain_loc))
+ to_chat(H, "Your power sink retracts into its casing.")
+ drain_complete(H)
+ return
+
+ if(holder.cell.fully_charged())
+ to_chat(H, "Your power sink flashes an amber light; your rig cell is full.")
+ drain_complete(H)
+ return
+
+ // Attempts to drain up to 12.5*cell-capacity kW, determines this value from remaining cell capacity to ensure we don't drain too much.
+ // 1Ws/(12.5*CELLRATE) = 40s to charge
+ var/to_drain = min(12.5*holder.cell.maxcharge, ((holder.cell.maxcharge - holder.cell.charge) / CELLRATE))
+ var/target_drained = interfaced_with.drain_power(0,0,to_drain)
+ if(target_drained <= 0)
+ to_chat(H, "Your power sink flashes a red light; there is no power left in [interfaced_with].")
+ drain_complete(H)
+ return
+
+ holder.cell.give(target_drained * CELLRATE)
+ total_power_drained += target_drained
+
+ return
+
+/obj/item/rig_module/power_sink/proc/drain_complete(var/mob/living/M)
+
+ if(!interfaced_with)
+ if(M)
+ to_chat(M, "Total power drained: [round(total_power_drained*CELLRATE)] cell units.")
+ else
+ if(M)
+ to_chat(M, "Total power drained from [interfaced_with]: [round(total_power_drained*CELLRATE)] cell units.")
+ interfaced_with.drain_power(0,1,0) // Damage the victim.
+
+ drain_loc = null
+ interfaced_with = null
+ total_power_drained = 0
diff --git a/code/modules/clothing/spacesuits/rig/modules/specific/self_destruct.dm b/code/modules/clothing/spacesuits/rig/modules/specific/self_destruct.dm
new file mode 100644
index 0000000000..391bdf8f6c
--- /dev/null
+++ b/code/modules/clothing/spacesuits/rig/modules/specific/self_destruct.dm
@@ -0,0 +1,50 @@
+/obj/item/rig_module/self_destruct
+
+ name = "self-destruct module"
+ desc = "Oh my God, a bomb!"
+ icon_state = "deadman"
+ usable = 1
+ active = 1
+ permanent = 1
+ var/datum/effect/effect/system/smoke_spread/bad/smoke
+ var/smoke_strength = 8
+
+ engage_string = "Detonate"
+
+ interface_name = "dead man's switch"
+ interface_desc = "An integrated self-destruct module. When the wearer dies, they vanish in smoke. Do not press this button."
+
+/obj/item/rig_module/self_destruct/New()
+ ..()
+ src.smoke = new /datum/effect/effect/system/smoke_spread/bad()
+ src.smoke.attach(src)
+
+/obj/item/rig_module/self_destruct/Destroy()
+ qdel(smoke)
+ smoke = null
+ return ..()
+
+/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(1)
+
+/obj/item/rig_module/self_destruct/engage(var/skip_check)
+ if(!skip_check && usr && alert(usr, "Are you sure you want to push that button?", "Self-destruct", "No", "Yes") == "No")
+ return
+ if(holder && holder.wearer)
+ smoke.set_up(10, 0, holder.loc)
+ for(var/i = 1 to smoke_strength)
+ smoke.start(272727)
+ holder.wearer.ash()
diff --git a/code/modules/clothing/spacesuits/rig/modules/specific/sprinter.dm b/code/modules/clothing/spacesuits/rig/modules/specific/sprinter.dm
new file mode 100644
index 0000000000..f69f053260
--- /dev/null
+++ b/code/modules/clothing/spacesuits/rig/modules/specific/sprinter.dm
@@ -0,0 +1,43 @@
+/obj/item/rig_module/sprinter
+ name = "sprint module"
+ desc = "A robust hardsuit-integrated sprint module."
+ icon_state = "sprinter"
+
+ var/sprint_speed = 1
+
+ toggleable = 1
+ disruptable = 1
+ disruptive = 0
+
+ use_power_cost = 50
+ active_power_cost = 5
+ passive_power_cost = 0
+ module_cooldown = 30
+
+ activate_string = "Enable Sprint"
+ deactivate_string = "Disable Sprint"
+
+ interface_name = "sprint system"
+ interface_desc = "Increases power to the suit's actuators, allowing faster movement."
+
+/obj/item/rig_module/sprinter/activate()
+
+ if(!..())
+ return 0
+
+ var/mob/living/carbon/human/H = holder.wearer
+
+ to_chat(H, "You activate the suit's sprint mode.")
+
+ holder.slowdown = initial(holder.slowdown) - sprint_speed
+
+/obj/item/rig_module/sprinter/deactivate()
+
+ if(!..())
+ return 0
+
+ var/mob/living/carbon/human/H = holder.wearer
+
+ to_chat(H, "Your hardsuit returns to normal speed.")
+
+ holder.slowdown = initial(holder.slowdown)
diff --git a/code/modules/clothing/spacesuits/rig/modules/specific/teleporter.dm b/code/modules/clothing/spacesuits/rig/modules/specific/teleporter.dm
new file mode 100644
index 0000000000..1f533f98fe
--- /dev/null
+++ b/code/modules/clothing/spacesuits/rig/modules/specific/teleporter.dm
@@ -0,0 +1,80 @@
+/obj/item/rig_module/teleporter
+
+ name = "teleportation module"
+ desc = "A complex, sleek-looking, hardsuit-integrated teleportation module."
+ icon_state = "teleporter"
+ use_power_cost = 200
+ 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)
+
+ var/mob/living/carbon/human/H = holder.wearer
+
+ if(!istype(H.loc, /turf))
+ to_chat(H, "You cannot teleport out of your current location.")
+ return 0
+
+ var/turf/T
+ if(target)
+ T = get_turf(target)
+ else
+ T = get_teleport_loc(get_turf(H), H, 6, 1, 1, 1)
+
+ if(!T)
+ to_chat(H, "No valid teleport target found.")
+ return 0
+
+ if(T.density)
+ to_chat(H, "You cannot teleport into solid walls.")
+ return 0
+
+ if(T.z in using_map.admin_levels)
+ to_chat(H, "You cannot use your teleporter on this Z-level.")
+ return 0
+
+ if(T.contains_dense_objects())
+ to_chat(H, "You cannot teleport to a location with solid objects.")
+ return 0
+
+ if(T.z != H.z || get_dist(T, get_turf(H)) > world.view)
+ to_chat(H, "You cannot teleport to such a distant object.")
+ return 0
+
+ if(!..()) 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
\ No newline at end of file
diff --git a/code/modules/clothing/spacesuits/rig/modules/specific/vision.dm b/code/modules/clothing/spacesuits/rig/modules/specific/vision.dm
new file mode 100644
index 0000000000..7e73f08880
--- /dev/null
+++ b/code/modules/clothing/spacesuits/rig/modules/specific/vision.dm
@@ -0,0 +1,237 @@
+/*
+ * 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
+
+/datum/rig_vision/material
+ mode = "material scanner"
+
+/datum/rig_vision/material/New()
+ glasses = new /obj/item/clothing/glasses/material
+
+/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
+ module_cooldown = 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/material,
+ /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/material
+
+ name = "hardsuit material scanner"
+ desc = "A layered, translucent visor system for a hardsuit."
+ icon_state = "meson"
+
+ usable = 0
+
+ interface_name = "material scanner"
+ interface_desc = "An integrated material scanner."
+
+ vision_modes = list(/datum/rig_vision/material)
+
+/obj/item/rig_module/vision/mining
+
+ name = "hardsuit mining scanners"
+ desc = "A layered, translucent visor system for a hardsuit."
+ icon_state = "optics"
+
+ usable = 0
+
+ interface_name = "mining scanners"
+ interface_desc = "An integrated mining scanner array."
+
+ vision_modes = list(/datum/rig_vision/material,
+ /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()
+
+ if(!..() || !vision_modes)
+ return 0
+
+ // Don't cycle if this engage() is being called by activate().
+ if(!active)
+ to_chat(holder.wearer, "You activate your visual sensors.")
+ return 1
+
+ if(vision_modes.len > 1)
+ vision_index++
+ if(vision_index > vision_modes.len)
+ vision_index = 1
+ vision = vision_modes[vision_index]
+
+ to_chat(holder.wearer, "You cycle your sensors to [vision.mode] mode.")
+ else
+ to_chat(holder.wearer, "Your sensors only have one mode.")
+ return 1
+
+/obj/item/rig_module/vision/activate()
+ if((. = ..()) && holder.wearer)
+ holder.wearer.recalculate_vis()
+
+/obj/item/rig_module/vision/deactivate()
+ if((. = ..()) && holder.wearer)
+ holder.wearer.recalculate_vis()
+
+/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
\ No newline at end of file
diff --git a/code/modules/clothing/spacesuits/rig/modules/specific/voice.dm b/code/modules/clothing/spacesuits/rig/modules/specific/voice.dm
new file mode 100644
index 0000000000..0df94d756b
--- /dev/null
+++ b/code/modules/clothing/spacesuits/rig/modules/specific/voice.dm
@@ -0,0 +1,52 @@
+/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
+ to_chat(usr, "You enable the speech synthesiser.")
+ if("Disable")
+ active = 0
+ voice_holder.active = 0
+ to_chat(usr, "You disable the speech synthesiser.")
+ 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
+ to_chat(usr, "You are now mimicking [voice_holder.voice].")
+ return 1
\ No newline at end of file
diff --git a/code/modules/clothing/spacesuits/rig/modules/utility.dm b/code/modules/clothing/spacesuits/rig/modules/utility.dm
index c0b2065b86..2362cb7990 100644
--- a/code/modules/clothing/spacesuits/rig/modules/utility.dm
+++ b/code/modules/clothing/spacesuits/rig/modules/utility.dm
@@ -5,6 +5,7 @@
* /obj/item/rig_module/device/drill
* /obj/item/rig_module/device/orescanner
* /obj/item/rig_module/device/rcd
+ * /obj/item/rig_module/device/arch_drill
* /obj/item/rig_module/device/anomaly_scanner
* /obj/item/rig_module/maneuvering_jets
* /obj/item/rig_module/foam_sprayer
@@ -96,6 +97,17 @@
device_type = /obj/item/weapon/rcd/electric/mounted/rig
+/obj/item/rig_module/device/arch_drill
+ name = "archaeology drill mount"
+ desc = "A cell-powered fine-excavation device for a hardsuit."
+ icon_state = "exdrill"
+ interface_name = "mounted excavation tool"
+ interface_desc = "A device for excavating ancient relics."
+ usable = 1
+ engage_string = "Configure Drill Depth"
+
+ device_type = /obj/item/weapon/pickaxe/excavationdrill
+
/obj/item/rig_module/device/New()
..()
if(device_type) device = new device_type(src)
@@ -117,8 +129,6 @@
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."
@@ -418,29 +428,14 @@
interface_name = "mop projector"
interface_desc = "A mop that can be deployed from the hand of the wearer."
- usable = 0
+ usable = 1
selectable = 1
toggleable = 1
- use_power_cost = 0
+ use_power_cost = 5
active_power_cost = 0
passive_power_cost = 0
- gun = /obj/item/weapon/reagent_containers/spray/cleaner
-
-//obj/item/weapon/reagent_containers/spray/cleaner
-// spary =
-
-/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
+ gun_type = /obj/item/weapon/gun/energy/temperature/mounted
/obj/item/rig_module/mounted/mop/process()
@@ -655,4 +650,4 @@
to_chat(H, "Your hardsuit returns to normal speed.")
- holder.slowdown = initial(holder.slowdown)
\ No newline at end of file
+ holder.slowdown = initial(holder.slowdown)
diff --git a/code/modules/clothing/spacesuits/rig/suits/robotics.dm b/code/modules/clothing/spacesuits/rig/suits/robotics.dm
new file mode 100644
index 0000000000..4fb43d355d
--- /dev/null
+++ b/code/modules/clothing/spacesuits/rig/suits/robotics.dm
@@ -0,0 +1,29 @@
+//Mining suit
+/obj/item/weapon/rig/robotics
+ name = "advanced suit control belt"
+ suit_type = "advanced suit"
+ desc = "A lightweight suit combining the utility of a RIG with the wearability of a voidsuit."
+ icon_state = "void_explorer2"
+ slot_flags = SLOT_BELT
+ armor = list(melee = 40, bullet = 30, laser = 20, energy = 15, bomb = 30, bio = 100, rad = 50)
+ slowdown = 1
+ offline_slowdown = 2
+ offline_vision_restriction = 0
+ emp_protection = -20
+ siemens_coefficient= 0.75
+ rigsuit_max_pressure = 8 * ONE_ATMOSPHERE
+ rigsuit_min_pressure = 0
+
+ chest_type = /obj/item/clothing/suit/space/rig
+ helm_type = /obj/item/clothing/head/helmet/space/rig
+ boot_type = null
+ glove_type = null
+ cell_type = null
+
+ allowed = list(
+ /obj/item/device/flashlight,
+ /obj/item/weapon/storage/box
+ )
+
+ req_access = list()
+ req_one_access = list()
diff --git a/code/modules/materials/fifty_spawner_mats.dm b/code/modules/materials/fifty_spawner_mats.dm
index 1b39b38d93..50d4184ebf 100644
--- a/code/modules/materials/fifty_spawner_mats.dm
+++ b/code/modules/materials/fifty_spawner_mats.dm
@@ -28,6 +28,10 @@
name = "stack of plastic"
type_to_spawn = /obj/item/stack/material/plastic
+/obj/fiftyspawner/graphite
+ name = "stack of graphite"
+ type_to_spawn = /obj/item/stack/material/graphite
+
/obj/fiftyspawner/gold
name = "stack of gold"
type_to_spawn = /obj/item/stack/material/gold
diff --git a/code/modules/materials/material_sheets.dm b/code/modules/materials/material_sheets.dm
index 287e35be27..aaf312e229 100644
--- a/code/modules/materials/material_sheets.dm
+++ b/code/modules/materials/material_sheets.dm
@@ -136,6 +136,13 @@
default_type = "plastic"
no_variants = FALSE
+/obj/item/stack/material/graphite
+ name = "graphite"
+ icon_state = "sheet-silver"
+ default_type = MAT_GRAPHITE
+ apply_colour = 1
+ no_variants = FALSE
+
/obj/item/stack/material/gold
name = "gold"
icon_state = "sheet-gold"
diff --git a/code/modules/materials/materials.dm b/code/modules/materials/materials.dm
index 621017bdb4..2da552c5b1 100644
--- a/code/modules/materials/materials.dm
+++ b/code/modules/materials/materials.dm
@@ -652,6 +652,22 @@ var/list/name_to_material
stack_type = null
shard_type = SHARD_NONE
+/material/graphite
+ name = MAT_GRAPHITE
+ stack_type = /obj/item/stack/material/graphite
+ flags = MATERIAL_BRITTLE
+ icon_base = "solid"
+ icon_reinf = "reinf_mesh"
+ icon_colour = "#333333"
+ hardness = 75
+ weight = 15
+ integrity = 175
+ protectiveness = 15
+ conductivity = 18
+ melting_point = T0C+3600
+ radiation_resistance = 15
+ stack_origin_tech = list(TECH_MATERIAL = 2, TECH_MAGNET = 2)
+
/material/osmium
name = "osmium"
stack_type = /obj/item/stack/material/osmium
diff --git a/code/modules/mining/ore_datum.dm b/code/modules/mining/ore_datum.dm
index e578902104..f888ae3bb6 100644
--- a/code/modules/mining/ore_datum.dm
+++ b/code/modules/mining/ore_datum.dm
@@ -51,6 +51,7 @@ var/global/list/ore_data = list()
name = "carbon"
display_name = "raw carbon"
smelts_to = "plastic"
+ compresses_to = "graphite"
alloy = 1
result_amount = 5
spread_chance = 25
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index 3a44c18bd3..017bfd39d7 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -363,6 +363,11 @@
if(!rig.offline && (rig.air_supply && internal == rig.air_supply))
rig_supply = rig.air_supply
+ else if(istype(belt,/obj/item/weapon/rig))
+ var/obj/item/weapon/rig/rig = belt
+ 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.item_flags & AIRTIGHT)) || (head && (head.item_flags & AIRTIGHT))))
internal = null
diff --git a/code/modules/projectiles/guns/energy/temperature.dm b/code/modules/projectiles/guns/energy/temperature.dm
index cf9706effd..9343f9116c 100644
--- a/code/modules/projectiles/guns/energy/temperature.dm
+++ b/code/modules/projectiles/guns/energy/temperature.dm
@@ -12,3 +12,7 @@
list(mode_name="endothermic beam", projectile_type = /obj/item/projectile/temp, charge_cost = 240),
list(mode_name="exothermic beam", projectile_type = /obj/item/projectile/temp/hot, charge_cost = 240),
)
+
+/obj/item/weapon/gun/energy/temperature/mounted
+ self_recharge = 1
+ use_external_power = 1
diff --git a/code/modules/research/circuitprinter.dm b/code/modules/research/circuitprinter.dm
index 7f9fcb565f..75d45652d9 100644
--- a/code/modules/research/circuitprinter.dm
+++ b/code/modules/research/circuitprinter.dm
@@ -16,9 +16,9 @@ using metal and glass, it uses glass and reagents (usually sulphuric acid).
var/mat_efficiency = 1
var/speed = 1
- materials = list(DEFAULT_WALL_MATERIAL = 0, "glass" = 0, MAT_PLASTEEL = 0, "plastic" = 0, "gold" = 0, "silver" = 0, "osmium" = 0, MAT_LEAD = 0, "phoron" = 0, "uranium" = 0, "diamond" = 0, MAT_DURASTEEL = 0, MAT_VERDANTIUM = 0, MAT_MORPHIUM = 0, MAT_METALHYDROGEN = 0, MAT_SUPERMATTER = 0)
+ materials = list(DEFAULT_WALL_MATERIAL = 0, "glass" = 0, MAT_PLASTEEL = 0, "plastic" = 0, MAT_GRAPHITE, "gold" = 0, "silver" = 0, "osmium" = 0, MAT_LEAD = 0, "phoron" = 0, "uranium" = 0, "diamond" = 0, MAT_DURASTEEL = 0, MAT_VERDANTIUM = 0, MAT_MORPHIUM = 0, MAT_METALHYDROGEN = 0, MAT_SUPERMATTER = 0)
- hidden_materials = list(MAT_PLASTEEL, MAT_DURASTEEL, MAT_VERDANTIUM, MAT_MORPHIUM, MAT_METALHYDROGEN, MAT_SUPERMATTER)
+ hidden_materials = list(MAT_PLASTEEL, MAT_DURASTEEL, MAT_GRAPHITE, MAT_VERDANTIUM, MAT_MORPHIUM, MAT_METALHYDROGEN, MAT_SUPERMATTER)
use_power = 1
idle_power_usage = 30
diff --git a/code/modules/research/mechfab_designs.dm b/code/modules/research/mechfab_designs.dm
index 480f085c90..af8afc44fb 100644
--- a/code/modules/research/mechfab_designs.dm
+++ b/code/modules/research/mechfab_designs.dm
@@ -769,3 +769,249 @@
req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 6, TECH_MAGNET = 3, TECH_POWER = 2)
materials = list(DEFAULT_WALL_MATERIAL = 15000, "silver" = 3000, "plastic" = 3000, "osmium" = 1000)
build_path = /obj/item/weapon/vehicle_assembly/quadbike
+
+/*
+ * Rigsuits
+ */
+
+/datum/design/item/mechfab/rigsuit
+ category = "Rigsuit"
+ req_tech = list(TECH_MATERIAL = 6, TECH_ENGINEERING = 5, TECH_PHORON = 3, TECH_MAGNET = 4, TECH_POWER = 6)
+
+/datum/design/item/mechfab/rigsuit/basic_belt
+ name = "Advanced Suit Control Belt"
+ desc = "A belt holding a compressed space-suit."
+ id = "rigmodule_belt_basic"
+ materials = list(MAT_PLASTEEL = 12000, MAT_GOLD = 3000, MAT_GRAPHITE = 3000, MAT_OSMIUM = 1000, MAT_PLASTIC = 5000)
+ build_path = /obj/item/weapon/rig/robotics
+
+/datum/design/item/mechfab/rigsuit/jetpack
+ name = "hardsuit maneuvering jets"
+ desc = "A compact gas thruster system for a hardsuit."
+ id = "rig_thrusters"
+ materials = list(MAT_PLASTEEL = 1000, MAT_GOLD = 1000, MAT_GRAPHITE = 1000, MAT_PLASTIC = 500)
+ build_path = /obj/item/rig_module/maneuvering_jets
+
+/datum/design/item/mechfab/rigsuit/powersink
+ name = "hardsuit power siphon"
+ desc = "A complex device used to pull power from machines."
+ id = "rig_siphon"
+ req_tech = list(TECH_MATERIAL = 7, TECH_ENGINEERING = 5, TECH_PHORON = 4, TECH_MAGNET = 5, TECH_POWER = 6, TECH_ILLEGAL = 3)
+ materials = list(MAT_PLASTEEL = 3000, MAT_METALHYDROGEN = 1000, MAT_GRAPHITE = 1000, MAT_PLASTIC = 5000, MAT_PHORON = 2000, MAT_VERDANTIUM = 1500)
+ build_path = /obj/item/rig_module/power_sink
+
+/datum/design/item/mechfab/rigsuit/flash
+ name = "hardsuit mounted flash"
+ desc = "A suit-mounted flash."
+ id = "rig_device_flash"
+ req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 3, TECH_MAGNET = 4, TECH_POWER = 4)
+ materials = list(MAT_PLASTEEL = 2000, MAT_PLASTIC = 3000, MAT_METALHYDROGEN = 200, MAT_GRAPHITE = 500)
+ build_path = /obj/item/rig_module/device/flash
+
+/datum/design/item/mechfab/rigsuit/plasmacutter
+ name = "hardsuit mounted plasmacutter"
+ desc = "A suit-mounted plasmacutter."
+ id = "rig_device_plasmacutter"
+ req_tech = list(TECH_MATERIAL = 6, TECH_ENGINEERING = 3, TECH_MAGNET = 4, TECH_PHORON = 3, TECH_POWER = 4)
+ materials = list(MAT_PLASTEEL = 3000, MAT_PLASTIC = 3000, MAT_PHORON = 2500, MAT_GRAPHITE = 500)
+ build_path = /obj/item/rig_module/device/plasmacutter
+
+/datum/design/item/mechfab/rigsuit/healthanalyzer
+ name = "hardsuit health analyzer"
+ desc = "A hardsuit mounted health analyzer."
+ id = "rig_device_healthanalyzer"
+ req_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 3, TECH_BIO = 4, TECH_POWER = 4)
+ materials = list(MAT_PLASTEEL = 1000, MAT_SILVER = 1000, MAT_GRAPHITE = 1000, MAT_PLASTIC = 500)
+ build_path = /obj/item/rig_module/device/healthscanner
+
+/datum/design/item/mechfab/rigsuit/drill
+ name = "hardsuit mounted drill"
+ desc = "A hardsuit mounted drill."
+ id = "rig_device_drill"
+ req_tech = list(TECH_MATERIAL = 7, TECH_ENGINEERING = 5, TECH_MAGNET = 5, TECH_POWER = 4)
+ materials = list(MAT_PLASTEEL = 1500, MAT_DIAMOND = 2500, MAT_GRAPHITE = 1000, MAT_PLASTIC = 500)
+ build_path = /obj/item/rig_module/device/drill
+
+/datum/design/item/mechfab/rigsuit/excdrill
+ name = "hardsuit mounted excavation drill"
+ desc = "A hardsuit mounted excavation drill."
+ id = "rig_device_excdrill"
+ req_tech = list(TECH_MATERIAL = 7, TECH_ENGINEERING = 6, TECH_MAGNET = 5, TECH_POWER = 5, TECH_ARCANE = 1)
+ materials = list(MAT_PLASTEEL = 1500, MAT_DIAMOND = 2000, MAT_GRAPHITE = 1500, MAT_PLASTIC = 1000)
+ build_path = /obj/item/rig_module/device/arch_drill
+
+/datum/design/item/mechfab/rigsuit/anomscanner
+ name = "hardsuit mounted anomaly scanner"
+ desc = "A suit-mounted anomaly scanner."
+ id = "rig_device_anomscanner"
+ req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 3, TECH_MAGNET = 4, TECH_POWER = 4)
+ materials = list(MAT_PLASTEEL = 2000, MAT_PLASTIC = 3000, MAT_METALHYDROGEN = 200, MAT_GRAPHITE = 500)
+ build_path = /obj/item/rig_module/device/anomaly_scanner
+
+/datum/design/item/mechfab/rigsuit/orescanner
+ name = "hardsuit mounted ore scanner"
+ desc = "A suit-mounted ore scanner."
+ id = "rig_device_orescanner"
+ req_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 3, TECH_MAGNET = 3, TECH_POWER = 3)
+ materials = list(MAT_PLASTEEL = 2000, MAT_PLASTIC = 2000, MAT_GRAPHITE = 500)
+ build_path = /obj/item/rig_module/device/orescanner
+
+/datum/design/item/mechfab/rigsuit/rcd
+ name = "hardsuit mounted rcd"
+ desc = "A suit-mounted rcd."
+ id = "rig_device_rcd"
+ req_tech = list(TECH_MATERIAL = 7, TECH_ENGINEERING = 3, TECH_MAGNET = 4, TECH_PHORON = 3, TECH_POWER = 4)
+ materials = list(MAT_PLASTEEL = 5000, MAT_URANIUM = 3000, MAT_PHORON = 2000, MAT_GRAPHITE = 1500)
+ build_path = /obj/item/rig_module/device/rcd
+
+/datum/design/item/mechfab/rigsuit/paperdispenser
+ name = "hardsuit mounted paper dispenser"
+ desc = "A suit-mounted paper dispenser."
+ id = "rig_device_paperdispenser"
+ req_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 2, TECH_MAGNET = 2, TECH_BIO = 2, TECH_POWER = 2)
+ materials = list(MAT_PLASTEEL = 1000, MAT_PLASTIC = 500, MAT_PHORON = 500, MAT_GRAPHITE = 100)
+ build_path = /obj/item/rig_module/device/paperdispenser
+
+/datum/design/item/mechfab/rigsuit/pen
+ name = "hardsuit mounted pen"
+ desc = "A suit-mounted pen."
+ id = "rig_device_pen"
+ req_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 2, TECH_MAGNET = 2, TECH_BIO = 2, TECH_POWER = 2)
+ materials = list(MAT_PLASTEEL = 1000, MAT_PLASTIC = 500, MAT_PHORON = 500, MAT_GRAPHITE = 100)
+ build_path = /obj/item/rig_module/device/pen
+
+/datum/design/item/mechfab/rigsuit/grenade_metalfoam
+ name = "hardsuit metalfoam-bomb launcher"
+ desc = "A compact metalfoam grenade system for a hardsuit."
+ id = "rig_grenade_metalfoam"
+ req_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 3, TECH_MAGNET = 2, TECH_POWER = 3)
+ materials = list(MAT_PLASTEEL = 2000, MAT_OSMIUM = 1000, MAT_GRAPHITE = 1500, MAT_PLASTIC = 500)
+ build_path = /obj/item/rig_module/grenade_launcher/metalfoam
+
+/datum/design/item/mechfab/rigsuit/grenade_flash
+ name = "hardsuit flashbang launcher"
+ desc = "A compact flashbang grenade system for a hardsuit."
+ id = "rig_grenade_flashbang"
+ req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 5, TECH_PHORON = 3, TECH_MAGNET = 4, TECH_POWER = 5, TECH_COMBAT = 4)
+ materials = list(MAT_PLASTEEL = 2000, MAT_OSMIUM = 1500, MAT_GRAPHITE = 1000, MAT_PLASTIC = 1000)
+ build_path = /obj/item/rig_module/grenade_launcher/flash
+
+/datum/design/item/mechfab/rigsuit/grenade_cleanfoam
+ name = "hardsuit cleaning-foam-bomb launcher"
+ desc = "A compact cleaning-foam grenade system for a hardsuit."
+ id = "rig_grenade_cleanfoam"
+ req_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 3, TECH_BIO = 2, TECH_POWER = 2)
+ materials = list(MAT_PLASTEEL = 2000, MAT_GLASS = 1000, MAT_GRAPHITE = 1500, MAT_PLASTIC = 750)
+ build_path = /obj/item/rig_module/cleaner_launcher
+
+/datum/design/item/mechfab/rigsuit/taser
+ name = "hardsuit taser"
+ desc = "A compact taser system for a hardsuit."
+ id = "rig_gun_taser"
+ req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 3, TECH_MAGNET = 2, TECH_POWER = 3, TECH_COMBAT = 2)
+ materials = list(MAT_PLASTEEL = 2000, MAT_GRAPHITE = 1500, MAT_PLASTIC = 500)
+ build_path = /obj/item/rig_module/mounted/taser
+
+/datum/design/item/mechfab/rigsuit/egun
+ name = "hardsuit egun"
+ desc = "A compact egun system for a hardsuit."
+ id = "rig_gun_egun"
+ req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 4, TECH_MAGNET = 3, TECH_POWER = 4, TECH_COMBAT = 4)
+ materials = list(MAT_PLASTEEL = 2000, MAT_GOLD = 1250, MAT_GRAPHITE = 1500, MAT_PLASTIC = 500)
+ build_path = /obj/item/rig_module/mounted/egun
+
+/datum/design/item/mechfab/rigsuit/mop
+ name = "hardsuit intense cleaning device"
+ desc = "An advanced cleaning device."
+ id = "rig_gun_tempgun"
+ req_tech = list(TECH_MATERIAL = 6, TECH_ENGINEERING = 4, TECH_MAGNET = 5, TECH_POWER = 4, TECH_COMBAT = 6)
+ materials = list(MAT_PLASTEEL = 2000, MAT_GOLD = 1750, MAT_URANIUM = 1500, MAT_GRAPHITE = 1500, MAT_PLASTIC = 1000)
+ build_path = /obj/item/rig_module/mounted/mop
+
+/datum/design/item/mechfab/rigsuit/sprinter
+ name = "hardsuit overclocker"
+ desc = "A compact overclocking system for a hardsuit."
+ id = "rig_component_sprinter"
+ req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 5, TECH_BIO = 4, TECH_POWER = 4)
+ materials = list(MAT_PLASTEEL = 2000, MAT_GRAPHITE = 1500, MAT_PLASTIC = 500, MAT_VERDANTIUM = 1000)
+ build_path = /obj/item/rig_module/sprinter
+
+/datum/design/item/mechfab/rigsuit/meson
+ name = "hardsuit meson visor"
+ desc = "A compact meson visor for a hardsuit."
+ id = "rig_component_meson"
+ req_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 5, TECH_MAGNET = 3, TECH_POWER = 4)
+ materials = list(MAT_PLASTEEL = 2000, MAT_GRAPHITE = 1500, MAT_OSMIUM = 500)
+ build_path = /obj/item/rig_module/vision/meson
+
+/datum/design/item/mechfab/rigsuit/material
+ name = "hardsuit material visor"
+ desc = "A compact material visor for a hardsuit."
+ id = "rig_component_material"
+ req_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 5, TECH_MAGNET = 3, TECH_POWER = 4)
+ materials = list(MAT_PLASTEEL = 2000, MAT_GRAPHITE = 1500, MAT_OSMIUM = 500)
+ build_path = /obj/item/rig_module/vision/material
+
+/datum/design/item/mechfab/rigsuit/nvg
+ name = "hardsuit night-vision visor"
+ desc = "A compact night-vision visor for a hardsuit."
+ id = "rig_component_nvg"
+ req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 6, TECH_MAGNET = 4, TECH_POWER = 5)
+ materials = list(MAT_PLASTEEL = 2000, MAT_GRAPHITE = 1500, MAT_OSMIUM = 500, MAT_URANIUM = 1000)
+ build_path = /obj/item/rig_module/vision/nvg
+
+/datum/design/item/mechfab/rigsuit/sechud
+ name = "hardsuit security visor"
+ desc = "A compact security visor for a hardsuit."
+ id = "rig_component_sechud"
+ req_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 3, TECH_MAGNET = 3, TECH_POWER = 2)
+ materials = list(MAT_PLASTEEL = 2000, MAT_GRAPHITE = 1500, MAT_PLASTIC = 500, MAT_SILVER = 500)
+ build_path = /obj/item/rig_module/vision/sechud
+
+/datum/design/item/mechfab/rigsuit/medhud
+ name = "hardsuit medical visor"
+ desc = "A compact medical visor for a hardsuit."
+ id = "rig_component_medhud"
+ req_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 3, TECH_MAGNET = 3, TECH_BIO = 2)
+ materials = list(MAT_PLASTEEL = 2000, MAT_GRAPHITE = 1500, MAT_PLASTIC = 500, MAT_SILVER = 500)
+ build_path = /obj/item/rig_module/vision/medhud
+
+/datum/design/item/mechfab/rigsuit/voice
+ name = "hardsuit voice-changer"
+ desc = "A compact voice-changer for a hardsuit."
+ id = "rig_component_voice"
+ req_tech = list(TECH_MATERIAL = 6, TECH_ENGINEERING = 4, TECH_MAGNET = 4, TECH_BIO = 4, TECH_ILLEGAL = 3)
+ materials = list(MAT_PLASTEEL = 2000, MAT_GRAPHITE = 1500, MAT_PLASTIC = 1000, MAT_SILVER = 500, MAT_PHORON = 1000)
+ build_path = /obj/item/rig_module/voice
+
+/datum/design/item/mechfab/rigsuit/aicontainer
+ name = "hardsuit intelligence storage system"
+ desc = "A compact AI network system for a hardsuit."
+ id = "rig_component_aicontainer"
+ req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 5, TECH_BIO = 4, TECH_POWER = 4)
+ materials = list(MAT_PLASTEEL = 2000, MAT_GRAPHITE = 1500, MAT_DIAMOND = 1000, MAT_GOLD = 500, MAT_SILVER = 750, MAT_VERDANTIUM = 1000)
+ build_path = /obj/item/rig_module/ai_container
+
+/datum/design/item/mechfab/rigsuit/datajack
+ name = "hardsuit datajack"
+ desc = "A compact datajack for a hardsuit."
+ id = "rig_component_datajack"
+ req_tech = list(TECH_MATERIAL = 7, TECH_ENGINEERING = 5, TECH_MAGNET = 5, TECH_POWER = 5)
+ materials = list(MAT_PLASTEEL = 2000, MAT_GRAPHITE = 1500, MAT_METALHYDROGEN = 1000, MAT_GOLD = 500, MAT_SILVER = 750, MAT_VERDANTIUM = 1000)
+ build_path = /obj/item/rig_module/datajack
+
+/datum/design/item/mechfab/rigsuit/cheminjector
+ name = "hardsuit chemical injector"
+ desc = "A compact chemical injector network for a hardsuit."
+ id = "rig_component_chemicals"
+ req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 5, TECH_MAGNET = 5, TECH_BIO = 4)
+ materials = list(MAT_PLASTEEL = 3000, MAT_GRAPHITE = 2000, MAT_PLASTIC = 3500, MAT_SILVER = 1750, MAT_GOLD = 1250)
+ build_path = /obj/item/rig_module/chem_dispenser/injector/advanced/empty
+
+/datum/design/item/mechfab/rigsuit/teleporter
+ name = "hardsuit teleporter system"
+ desc = "An enigmatic teleporter system for a hardsuit."
+ id = "rig_component_teleport"
+ req_tech = list(TECH_MATERIAL = 7, TECH_ENGINEERING = 5, TECH_MAGNET = 5, TECH_POWER = 6, TECH_ILLEGAL = 3, TECH_BLUESPACE = 4, TECH_ARCANE = 2, TECH_PRECURSOR = 3)
+ materials = list(MAT_DURASTEEL = 5000, MAT_GRAPHITE = 3000, MAT_MORPHIUM = 1500, MAT_OSMIUM = 1500, MAT_PHORON = 1750, MAT_VERDANTIUM = 3000, MAT_SUPERMATTER = 2000)
+ build_path = /obj/item/rig_module/teleporter
diff --git a/code/modules/research/protolathe.dm b/code/modules/research/protolathe.dm
index dc3a0cf437..3d65e35d63 100644
--- a/code/modules/research/protolathe.dm
+++ b/code/modules/research/protolathe.dm
@@ -15,9 +15,9 @@
var/mat_efficiency = 1
var/speed = 1
- materials = list(DEFAULT_WALL_MATERIAL = 0, "glass" = 0, MAT_PLASTEEL = 0, "plastic" = 0, "gold" = 0, "silver" = 0, "osmium" = 0, MAT_LEAD = 0, "phoron" = 0, "uranium" = 0, "diamond" = 0, MAT_DURASTEEL = 0, MAT_VERDANTIUM = 0, MAT_MORPHIUM = 0, MAT_METALHYDROGEN = 0, MAT_SUPERMATTER = 0)
+ materials = list(DEFAULT_WALL_MATERIAL = 0, "glass" = 0, MAT_PLASTEEL = 0, "plastic" = 0, MAT_GRAPHITE = 0, "gold" = 0, "silver" = 0, "osmium" = 0, MAT_LEAD = 0, "phoron" = 0, "uranium" = 0, "diamond" = 0, MAT_DURASTEEL = 0, MAT_VERDANTIUM = 0, MAT_MORPHIUM = 0, MAT_METALHYDROGEN = 0, MAT_SUPERMATTER = 0)
- hidden_materials = list(MAT_PLASTEEL, MAT_DURASTEEL, MAT_VERDANTIUM, MAT_MORPHIUM, MAT_METALHYDROGEN, MAT_SUPERMATTER)
+ hidden_materials = list(MAT_PLASTEEL, MAT_DURASTEEL, MAT_GRAPHITE, MAT_VERDANTIUM, MAT_MORPHIUM, MAT_METALHYDROGEN, MAT_SUPERMATTER)
/obj/machinery/r_n_d/protolathe/Initialize()
. = ..()
diff --git a/html/changelogs/mechoid - RoboticsRigs.yml b/html/changelogs/mechoid - RoboticsRigs.yml
new file mode 100644
index 0000000000..f7023732ea
--- /dev/null
+++ b/html/changelogs/mechoid - RoboticsRigs.yml
@@ -0,0 +1,38 @@
+################################
+# Example Changelog File
+#
+# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
+#
+# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
+# When it is, any changes listed below will disappear.
+#
+# Valid Prefixes:
+# bugfix
+# wip (For works in progress)
+# tweak
+# soundadd
+# sounddel
+# rscadd (general adding of nice things)
+# rscdel (general deleting of nice things)
+# imageadd
+# imagedel
+# maptweak
+# spellcheck (typo fixes)
+# experiment
+#################################
+
+# Your name.
+author: Mechoid
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
+# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - tweak: "Move Rig modules to more granular files"
+ - rscadd: "Add RIG components to robotics mechfab, plus incredibly basic belt-voidsuit RIG."
+ - rscadd: "Add Graphite, made by compressing coal, presently only used heavily in RIG components."
diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi
index 3dd2c190b7..d7760bcfd9 100644
Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ
diff --git a/icons/mob/rig_back.dmi b/icons/mob/rig_back.dmi
index 74cb306a6c..d3402980d7 100644
Binary files a/icons/mob/rig_back.dmi and b/icons/mob/rig_back.dmi differ
diff --git a/icons/mob/spacesuit.dmi b/icons/mob/spacesuit.dmi
index 504a947b22..62a2dd1906 100644
Binary files a/icons/mob/spacesuit.dmi and b/icons/mob/spacesuit.dmi differ
diff --git a/icons/mob/species/seromi/back.dmi b/icons/mob/species/seromi/back.dmi
index 0dcbeae289..b330228a40 100644
Binary files a/icons/mob/species/seromi/back.dmi and b/icons/mob/species/seromi/back.dmi differ
diff --git a/icons/mob/species/seromi/head.dmi b/icons/mob/species/seromi/head.dmi
index f1904c1e8e..4081403589 100644
Binary files a/icons/mob/species/seromi/head.dmi and b/icons/mob/species/seromi/head.dmi differ
diff --git a/icons/mob/species/seromi/suit.dmi b/icons/mob/species/seromi/suit.dmi
index eefd49d94c..332f4ba2f4 100644
Binary files a/icons/mob/species/seromi/suit.dmi and b/icons/mob/species/seromi/suit.dmi differ
diff --git a/icons/mob/species/skrell/helmet.dmi b/icons/mob/species/skrell/helmet.dmi
index e095112b9d..99ad73f964 100644
Binary files a/icons/mob/species/skrell/helmet.dmi and b/icons/mob/species/skrell/helmet.dmi differ
diff --git a/icons/mob/species/skrell/suit.dmi b/icons/mob/species/skrell/suit.dmi
index 87fd12b212..a4ffe9d1b9 100644
Binary files a/icons/mob/species/skrell/suit.dmi and b/icons/mob/species/skrell/suit.dmi differ
diff --git a/icons/mob/species/tajaran/helmet.dmi b/icons/mob/species/tajaran/helmet.dmi
index 5cb060dbe4..9c03c0e36d 100644
Binary files a/icons/mob/species/tajaran/helmet.dmi and b/icons/mob/species/tajaran/helmet.dmi differ
diff --git a/icons/mob/species/tajaran/suit.dmi b/icons/mob/species/tajaran/suit.dmi
index 9e211d4290..4f699202b4 100644
Binary files a/icons/mob/species/tajaran/suit.dmi and b/icons/mob/species/tajaran/suit.dmi differ
diff --git a/icons/mob/species/unathi/helmet.dmi b/icons/mob/species/unathi/helmet.dmi
index 00dfec5a86..7e5e03f7d2 100644
Binary files a/icons/mob/species/unathi/helmet.dmi and b/icons/mob/species/unathi/helmet.dmi differ
diff --git a/icons/mob/species/unathi/suit.dmi b/icons/mob/species/unathi/suit.dmi
index 430f5b9c35..f201822bfa 100644
Binary files a/icons/mob/species/unathi/suit.dmi and b/icons/mob/species/unathi/suit.dmi differ
diff --git a/icons/obj/rig_modules.dmi b/icons/obj/rig_modules.dmi
index 833baa61ca..1b6b12e465 100644
Binary files a/icons/obj/rig_modules.dmi and b/icons/obj/rig_modules.dmi differ
diff --git a/vorestation.dme b/vorestation.dme
index 1673969857..80d17397d8 100644
--- a/vorestation.dme
+++ b/vorestation.dme
@@ -1769,6 +1769,7 @@
#include "code\modules\clothing\spacesuits\rig\rig_pieces_vr.dm"
#include "code\modules\clothing\spacesuits\rig\rig_verbs.dm"
#include "code\modules\clothing\spacesuits\rig\rig_wiring.dm"
+<<<<<<< HEAD:vorestation.dme
#include "code\modules\clothing\spacesuits\rig\modules\combat.dm"
#include "code\modules\clothing\spacesuits\rig\modules\combat_vr.dm"
#include "code\modules\clothing\spacesuits\rig\modules\computer.dm"
@@ -1777,6 +1778,27 @@
#include "code\modules\clothing\spacesuits\rig\modules\utility.dm"
#include "code\modules\clothing\spacesuits\rig\modules\utility_vr.dm"
#include "code\modules\clothing\spacesuits\rig\modules\vision.dm"
+=======
+#include "code\modules\clothing\spacesuits\rig\modules\modules.dm"
+#include "code\modules\clothing\spacesuits\rig\modules\specific\ai_container.dm"
+#include "code\modules\clothing\spacesuits\rig\modules\specific\chem_dispenser.dm"
+#include "code\modules\clothing\spacesuits\rig\modules\specific\cleaner_launcher.dm"
+#include "code\modules\clothing\spacesuits\rig\modules\specific\cloak.dm"
+#include "code\modules\clothing\spacesuits\rig\modules\specific\datajack.dm"
+#include "code\modules\clothing\spacesuits\rig\modules\specific\device.dm"
+#include "code\modules\clothing\spacesuits\rig\modules\specific\electrowarfare.dm"
+#include "code\modules\clothing\spacesuits\rig\modules\specific\grenade_launcher.dm"
+#include "code\modules\clothing\spacesuits\rig\modules\specific\inhand_fabricator.dm"
+#include "code\modules\clothing\spacesuits\rig\modules\specific\jetpack.dm"
+#include "code\modules\clothing\spacesuits\rig\modules\specific\metalfoam_launcher.dm"
+#include "code\modules\clothing\spacesuits\rig\modules\specific\mounted_gun.dm"
+#include "code\modules\clothing\spacesuits\rig\modules\specific\powersink.dm"
+#include "code\modules\clothing\spacesuits\rig\modules\specific\self_destruct.dm"
+#include "code\modules\clothing\spacesuits\rig\modules\specific\sprinter.dm"
+#include "code\modules\clothing\spacesuits\rig\modules\specific\teleporter.dm"
+#include "code\modules\clothing\spacesuits\rig\modules\specific\vision.dm"
+#include "code\modules\clothing\spacesuits\rig\modules\specific\voice.dm"
+>>>>>>> 4d4a426... Merge pull request #6775 from Mechoid/Robotics_Expansion_RIG-ged_and_Ready:polaris.dme
#include "code\modules\clothing\spacesuits\rig\suits\alien.dm"
#include "code\modules\clothing\spacesuits\rig\suits\combat.dm"
#include "code\modules\clothing\spacesuits\rig\suits\ert.dm"
@@ -1784,6 +1806,7 @@
#include "code\modules\clothing\spacesuits\rig\suits\light.dm"
#include "code\modules\clothing\spacesuits\rig\suits\merc.dm"
#include "code\modules\clothing\spacesuits\rig\suits\pmc.dm"
+#include "code\modules\clothing\spacesuits\rig\suits\robotics.dm"
#include "code\modules\clothing\spacesuits\rig\suits\station.dm"
#include "code\modules\clothing\spacesuits\rig\suits\station_vr.dm"
#include "code\modules\clothing\spacesuits\void\merc.dm"