diff --git a/aurorastation.dme b/aurorastation.dme
index e264c1c9b45..39d019a09fb 100644
--- a/aurorastation.dme
+++ b/aurorastation.dme
@@ -817,6 +817,7 @@
#include "code\game\objects\items\toys.dm"
#include "code\game\objects\items\trash.dm"
#include "code\game\objects\items\devices\aicard.dm"
+#include "code\game\objects\items\devices\augment_implanter.dm"
#include "code\game\objects\items\devices\binoculars.dm"
#include "code\game\objects\items\devices\chameleonproj.dm"
#include "code\game\objects\items\devices\debugger.dm"
@@ -1336,6 +1337,7 @@
#include "code\modules\client\preference_setup\loadout\gear_tweaks.dm"
#include "code\modules\client\preference_setup\loadout\loadout.dm"
#include "code\modules\client\preference_setup\loadout\loadout_accessories.dm"
+#include "code\modules\client\preference_setup\loadout\loadout_augments.dm"
#include "code\modules\client\preference_setup\loadout\loadout_computer.dm"
#include "code\modules\client\preference_setup\loadout\loadout_cosmetics.dm"
#include "code\modules\client\preference_setup\loadout\loadout_ears.dm"
@@ -2177,6 +2179,7 @@
#include "code\modules\organs\internal\lungs.dm"
#include "code\modules\organs\internal\stomach.dm"
#include "code\modules\organs\internal\species\diona.dm"
+#include "code\modules\organs\subtypes\augment.dm"
#include "code\modules\organs\subtypes\autakh.dm"
#include "code\modules\organs\subtypes\diona.dm"
#include "code\modules\organs\subtypes\industrial.dm"
diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm
index 96e6457edb3..0f10a926b85 100644
--- a/code/__defines/mobs.dm
+++ b/code/__defines/mobs.dm
@@ -111,6 +111,22 @@
#define BP_OPTICS "optics"
#define BP_IPCTAG "ipc tag"
+//Augment organs
+#define BP_AUG_TIMEPIECE "integrated timepiece"
+#define BP_AUG_PDA "integrated pda"
+#define BP_AUG_TOOL "retractable combitool"
+#define BP_AUG_PEN "retractable combipen"
+#define BP_AUG_LIGHTER "retractable lighter"
+#define BP_AUG_HEALTHSCAN "integrated health scanner"
+#define BP_AUG_TESLA "tesla spine"
+#define BP_AUG_EYE_SENSORS "integrated eyes sensors"
+#define BP_AUG_HAIR "synthetic hair extensions"
+#define BP_AUG_SUSPENSION "calf suspension"
+#define BP_AUG_TASTE_BOOSTER "taste booster"
+#define BP_AUG_RADIO "integrated radio"
+#define BP_AUG_FUEL_CELL "integrated fuel cell"
+#define BP_AUG_AIR_ANALYZER "integrated air analyzer"
+
//Organ defines
#define PROCESS_ACCURACY 10
#define DEFAULT_BLOOD_AMOUNT 560 //Default blood amount in units
@@ -304,6 +320,7 @@
#define PROSTHETIC_XMG "Xion Manufacturing Group"
#define PROSTHETIC_DIONA "Unknown Model"
#define PROSTHETIC_AUTAKH "Aut'akh Manufactured"
+#define PROSTHETIC_TESLA "Tesla Powered Prosthetics"
//Brain Damage defines
#define BRAIN_DAMAGE_MILD 10
diff --git a/code/controllers/subsystems/garbage-debug.dm b/code/controllers/subsystems/garbage-debug.dm
index e31fa720ed2..e0031ccb557 100644
--- a/code/controllers/subsystems/garbage-debug.dm
+++ b/code/controllers/subsystems/garbage-debug.dm
@@ -790,6 +790,7 @@
SearchVar(ntnrc_uid)
SearchVar(all_robolimbs)
SearchVar(chargen_robolimbs)
+ SearchVar(fabricator_robolimbs)
SearchVar(basic_robolimb)
SearchVar(moving_levels)
SearchVar(cached_space)
diff --git a/code/controllers/subsystems/icon_cache.dm b/code/controllers/subsystems/icon_cache.dm
index dbb2108c6e0..98fa0225a25 100644
--- a/code/controllers/subsystems/icon_cache.dm
+++ b/code/controllers/subsystems/icon_cache.dm
@@ -44,6 +44,7 @@
var/list/markings_cache = list() // [icon]-[icon_state]-[limb_name]-[color]
var/list/human_eye_cache = list()
var/list/human_lip_cache = list()
+ var/list/internal_organ_cache = list()
// Cached composited human hair (beard & hair).
// Key:
// hair+beard: [beard_style][r_facial][g_facial][b_facial]_[hair_style][r_hair][g_hair][b_hair]
diff --git a/code/controllers/subsystems/job.dm b/code/controllers/subsystems/job.dm
index 8ccb00d09a9..98f261dfef1 100644
--- a/code/controllers/subsystems/job.dm
+++ b/code/controllers/subsystems/job.dm
@@ -727,6 +727,10 @@
for(var/thing in prefs.gear)
var/datum/gear/G = gear_datums[thing]
if(G)
+
+ if(G.augment) //augments are handled somewhere else
+ continue
+
var/permitted
if(G.allowed_roles)
for(var/job_name in G.allowed_roles)
@@ -860,4 +864,51 @@
deferred_preference_sanitizations.Cut()
+
+/datum/controller/subsystem/jobs/proc/EquipAugments(mob/living/carbon/human/H, datum/preferences/prefs)
+ Debug("EA/([H]): Entry.")
+ if(!istype(H))
+ Debug("EA/([H]): Abort: invalid arguments.")
+ return FALSE
+
+ var/datum/job/rank = GetJob(H.mind.assigned_role)
+
+ switch (rank.title)
+ if ("AI", "Cyborg")
+ Debug("EA/([H]): Abort: synthetic.")
+ return FALSE
+
+ for(var/thing in prefs.gear)
+ var/datum/gear/G = gear_datums[thing]
+ if(G)
+ if(!G.augment)
+ continue
+
+ var/permitted = FALSE
+ if(G.allowed_roles)
+ for(var/job_name in G.allowed_roles)
+ if(rank.title == job_name)
+ permitted = TRUE
+ break
+ else
+ permitted = TRUE
+
+ if(G.whitelisted && (!(H.species.name in G.whitelisted)))
+ permitted = FALSE
+
+ if(G.faction && G.faction != H.employer_faction)
+ permitted = FALSE
+
+ if(!permitted)
+ to_chat(H, SPAN_WARNING("Your current job or whitelist status does not permit you to spawn with [thing]!"))
+ continue
+
+ var/obj/item/organ/A = new G.path(H)
+ var/obj/item/organ/external/affected = H.get_organ(A.parent_organ)
+ A.replaced(H, affected)
+ H.update_body()
+
+ Debug("EA/([H]): Complete.")
+ return TRUE
+
#undef Debug
diff --git a/code/controllers/subsystems/ticker.dm b/code/controllers/subsystems/ticker.dm
index 1d7438017ce..d07cc90122a 100644
--- a/code/controllers/subsystems/ticker.dm
+++ b/code/controllers/subsystems/ticker.dm
@@ -619,6 +619,7 @@ var/datum/controller/subsystem/ticker/SSticker
if(player.mind.assigned_role == "Captain")
captainless = FALSE
if(!player_is_antag(player.mind, only_offstation_roles = 1))
+ SSjobs.EquipAugments(player, player.client.prefs)
SSjobs.EquipRank(player, player.mind.assigned_role, 0)
equip_custom_items(player)
diff --git a/code/game/machinery/mecha_fabricator.dm b/code/game/machinery/mecha_fabricator.dm
index a6d6b83143d..a94354d0563 100644
--- a/code/game/machinery/mecha_fabricator.dm
+++ b/code/game/machinery/mecha_fabricator.dm
@@ -99,10 +99,10 @@
data["buildable"] = get_build_options()
data["category"] = category
data["categories"] = categories
- if(chargen_robolimbs )
+ if(fabricator_robolimbs )
var/list/T = list()
- for(var/A in chargen_robolimbs )
- var/datum/robolimb/R = chargen_robolimbs [A]
+ for(var/A in fabricator_robolimbs )
+ var/datum/robolimb/R = fabricator_robolimbs [A]
T += list(list("id" = A, "company" = R.company))
data["manufacturers"] = T
data["manufacturer"] = manufacturer
@@ -134,7 +134,7 @@
category = href_list["category"]
if(href_list["manufacturer"])
- if(href_list["manufacturer"] in chargen_robolimbs )
+ if(href_list["manufacturer"] in fabricator_robolimbs )
manufacturer = href_list["manufacturer"]
if(href_list["eject"])
diff --git a/code/game/objects/items/devices/augment_implanter.dm b/code/game/objects/items/devices/augment_implanter.dm
new file mode 100644
index 00000000000..274fdc3687a
--- /dev/null
+++ b/code/game/objects/items/devices/augment_implanter.dm
@@ -0,0 +1,59 @@
+/obj/item/device/augment_implanter
+ name = "augment implanter"
+ desc = "A complex single use injector that is used to implant augments without the need for surgery."
+ w_class = ITEMSIZE_NORMAL
+ origin_tech = list(TECH_BIO = 5, TECH_MATERIAL = 2)
+ icon = 'icons/obj/guns/decloner.dmi'
+ icon_state = "decloner"
+ item_state = "decloner"
+ contained_sprite = TRUE
+ var/obj/item/organ/augment_type
+
+/obj/item/device/augment_implanter/Initialize()
+ . = ..()
+ if(!augment_type)
+ augment_type = new augment_type(src)
+
+/obj/item/device/augment_implanter/examine(mob/user)
+ ..(user)
+ if(augment_type)
+ to_chat(user, FONT_SMALL(SPAN_NOTICE("\The [augment_type] can be seen floating inside \the [src]'s biogel.")))
+
+/obj/item/device/augment_implanter/afterattack(mob/living/L, mob/user, proximity)
+ if(!proximity)
+ return
+
+ if(!augment_type)
+ to_chat(user, SPAN_WARNING("\The [src] is empty!"))
+ return
+
+ if(!ishuman(L))
+ to_chat(user, SPAN_WARNING("\The [src] has no effect on \the [L]."))
+ return
+
+ var/mob/living/carbon/human/H = L
+
+ if(!(H.species.name in augment_type.species_restricted))
+ to_chat(user, SPAN_WARNING("\The [augment_type] is not compatible with \the [H]'s body."))
+ return
+
+ if(H.internal_organs_by_name[augment_type.organ_tag])
+ to_chat(user, SPAN_WARNING("\The [H] already has a [augment_type]."))
+ return
+
+ if(!do_mob(user, H, 4 SECONDS))
+ return
+
+ augment_type.replaced(H, augment_type.parent_organ)
+ H.update_body()
+ H.updatehealth()
+ H.UpdateDamageIcon()
+ augment_type = null
+
+ user.visible_message(SPAN_WARNING("\The [user] thrusts \the [src] deep into \the [H], injecting something!"))
+
+/obj/item/device/augment_implanter/advanced_tesla
+ augment_type = /obj/item/organ/internal/augment/tesla/advanced
+
+/obj/item/device/augment_implanter/advanced_suspension
+ augment_type = /obj/item/organ/internal/augment/suspension/advanced
diff --git a/code/modules/cargo/random_stock/t2_uncommon.dm b/code/modules/cargo/random_stock/t2_uncommon.dm
index e0dda968b4e..3c54cb5666a 100644
--- a/code/modules/cargo/random_stock/t2_uncommon.dm
+++ b/code/modules/cargo/random_stock/t2_uncommon.dm
@@ -91,7 +91,7 @@ STOCK_ITEM_UNCOMMON(chempack, 5)
STOCK_ITEM_UNCOMMON(robolimbs, 3)
for (var/i in 1 to rand(2, 5))
- var/manuf = pick(chargen_robolimbs)
+ var/manuf = pick(fabricator_robolimbs)
var/type = pick( \
/obj/item/robot_parts/l_arm, \
/obj/item/robot_parts/r_arm, \
diff --git a/code/modules/client/preference_setup/loadout/loadout.dm b/code/modules/client/preference_setup/loadout/loadout.dm
index 42771c8c054..b0158157132 100644
--- a/code/modules/client/preference_setup/loadout/loadout.dm
+++ b/code/modules/client/preference_setup/loadout/loadout.dm
@@ -237,6 +237,7 @@ var/list/gear_datums = list()
var/sort_category = "General"
var/list/gear_tweaks = list() //List of datums which will alter the item after it has been spawned.
var/flags = GEAR_HAS_NAME_SELECTION | GEAR_HAS_DESC_SELECTION
+ var/augment = FALSE
/datum/gear/New()
..()
diff --git a/code/modules/client/preference_setup/loadout/loadout_augments.dm b/code/modules/client/preference_setup/loadout/loadout_augments.dm
new file mode 100644
index 00000000000..d26aa052700
--- /dev/null
+++ b/code/modules/client/preference_setup/loadout/loadout_augments.dm
@@ -0,0 +1,67 @@
+/datum/gear/augment
+ display_name = "integrated timepiece"
+ description = "An augment that allows the user to consult the time anywhere."
+ path = /obj/item/organ/internal/augment/timepiece
+ cost = 1
+ augment = TRUE
+ sort_category = "Augments"
+ whitelisted = list("Human", "Off-Worlder Human", "Tajara", "Zhan-Khazan Tajara", "M'sai Tajara", "Aut'akh Unathi", "Skrell", "Baseline Frame", "Hephaestus G1 Industrial Frame", "Hephaestus G2 Industrial Frame", "Xion Industrial Frame", "Zeng-Hu Mobility Frame", "Bishop Accessory Frame")
+ flags = GEAR_NO_SELECTION
+
+/datum/gear/augment/eye_sensors
+ display_name = "integrated eye sensors"
+ description = "An eye augment that allows the user to deploy medical or security sensors."
+ path = /obj/item/organ/internal/augment/eye_sensors
+ cost = 4
+ whitelisted = list("Human", "Off-Worlder Human", "Tajara", "Zhan-Khazan Tajara", "M'sai Tajara", "Aut'akh Unathi", "Skrell", "Baseline Frame", "Hephaestus G1 Industrial Frame", "Hephaestus G2 Industrial Frame", "Xion Industrial Frame", "Zeng-Hu Mobility Frame", "Bishop Accessory Frame", "Vaurca Worker", "Vaurca Warrior")
+
+
+/datum/gear/augment/cyber_hair
+ display_name = "synthetic hair extensions"
+ description = "A hair augment that allows the user to change the shape and color of their hair."
+ path = /obj/item/organ/internal/augment/cyber_hair
+ cost = 2
+
+/datum/gear/augment/combitool
+ display_name = "retractable combitool"
+ description = "An augment that allows the user to deploy a robotic combitool."
+ path = /obj/item/organ/internal/augment/tool/combitool
+ cost = 5
+
+/datum/gear/augment/combitool/New()
+ ..()
+ var/augs = list()
+ augs["retractable combitool, right hand"] = /obj/item/organ/internal/augment/tool/combitool
+ augs["retractable combitool, left hand"] = /obj/item/organ/internal/augment/tool/combitool/left
+ gear_tweaks += new /datum/gear_tweak/path(augs)
+
+/datum/gear/augment/health_scanner
+ display_name = "integrated health scanner"
+ description = "An augment that allows the user scan their own health condition."
+ path = /obj/item/organ/internal/augment/health_scanner
+ cost = 3
+
+/datum/gear/augment/suspension
+ display_name = "calf suspension"
+ description = "An augment that reduces the damage from falling from heights."
+ path = /obj/item/organ/internal/augment/suspension
+ cost = 4
+
+/datum/gear/augment/taste_boosters
+ display_name = "taste booster selection"
+ description = "A selection of augments that modify the user's taste sensitivity."
+ path = /obj/item/organ/internal/augment/taste_booster
+ cost = 3
+
+/datum/gear/augment/taste_boosters/New()
+ ..()
+ var/augs = list()
+ augs["taste booster"] = /obj/item/organ/internal/augment/taste_booster
+ augs["taste duller"] = /obj/item/organ/internal/augment/taste_booster/dull
+ gear_tweaks += new /datum/gear_tweak/path(augs)
+
+/datum/gear/augment/fuel_cell
+ display_name = "integrated fuel cell"
+ description = "An augment that allows the user to synthetize welding fuel into nutrients."
+ path = /obj/item/organ/internal/augment/fuel_cell
+ cost = 3
diff --git a/code/modules/client/preference_setup/loadout/loadout_xeno/tajara.dm b/code/modules/client/preference_setup/loadout/loadout_xeno/tajara.dm
index 50719cf3997..f9cff3581bd 100644
--- a/code/modules/client/preference_setup/loadout/loadout_xeno/tajara.dm
+++ b/code/modules/client/preference_setup/loadout/loadout_xeno/tajara.dm
@@ -185,4 +185,12 @@
path = /obj/item/storage/belt/shumaila_buckle
whitelisted = list("Tajara", "Zhan-Khazan Tajara", "M'sai Tajara")
sort_category = "Xenowear - Tajara"
- flags = GEAR_HAS_DESC_SELECTION
\ No newline at end of file
+ flags = GEAR_HAS_DESC_SELECTION
+
+/datum/gear/augment/tesla_spine
+ display_name = "tesla spine"
+ description = "A People's Republic of Adhomai made tesla spine issued to disabled veterans and civilians."
+ path = /obj/item/organ/internal/augment/tesla
+ cost = 4
+ whitelisted = list("Tajara", "Zhan-Khazan Tajara", "M'sai Tajara")
+ sort_category = "Xenowear - Tajara"
diff --git a/code/modules/client/preference_setup/loadout/loadout_xeno/unathi.dm b/code/modules/client/preference_setup/loadout/loadout_xeno/unathi.dm
index d8346addb06..f9f67fda06e 100644
--- a/code/modules/client/preference_setup/loadout/loadout_xeno/unathi.dm
+++ b/code/modules/client/preference_setup/loadout/loadout_xeno/unathi.dm
@@ -46,41 +46,41 @@
sort_category = "Xenowear - Unathi"
flags = GEAR_HAS_NAME_SELECTION | GEAR_HAS_DESC_SELECTION | GEAR_HAS_COLOR_SELECTION
-/datum/gear/autakh_engineering
+/datum/gear/augment/autakh_engineering
display_name = "engineering grasper"
description = "An Aut'akh augment limb, this one is outfitted with a limited toolkit."
path = /obj/item/organ/external/hand/right/autakh/tool
- whitelisted = list("Aut'akh Unathi")
+ whitelisted = list("Unathi", "Aut'akh Unathi")
sort_category = "Xenowear - Unathi"
cost = 3
allowed_roles = list("Station Engineer", "Chief Engineer", "Atmospheric Technician", "Engineering Apprentice", "Roboticist")
flags = GEAR_NO_SELECTION
-/datum/gear/autakh_mining
+/datum/gear/augment/autakh_mining
display_name = "mining grasper"
description = "An Aut'akh augment limb, this one is outfitted with a mining drill."
path = /obj/item/organ/external/hand/right/autakh/tool/mining
- whitelisted = list("Aut'akh Unathi")
+ whitelisted = list("Unathi", "Aut'akh Unathi")
sort_category = "Xenowear - Unathi"
cost = 3
allowed_roles = list("Shaft Miner")
flags = GEAR_NO_SELECTION
-/datum/gear/autakh_medical
+/datum/gear/augment/autakh_medical
display_name = "medical grasper"
description = "An Aut'akh augment limb, this one is outfitted with a health scanner."
path = /obj/item/organ/external/hand/right/autakh/medical
- whitelisted = list("Aut'akh Unathi")
+ whitelisted = list("Unathi", "Aut'akh Unathi")
sort_category = "Xenowear - Unathi"
cost = 3
allowed_roles = list("Chief Medical Officer", "Physician", "Surgeon", "Paramedic", "Medical Resident", "Psychiatrist", "Chemist")
flags = GEAR_NO_SELECTION
-/datum/gear/autakh_security
+/datum/gear/augment/autakh_security
display_name = "security grasper"
description = "An Aut'akh augment limb, this one is outfitted with an electroshock weapon."
path = /obj/item/organ/external/hand/right/autakh/security
- whitelisted = list("Aut'akh Unathi")
+ whitelisted = list("Unathi", "Aut'akh Unathi")
sort_category = "Xenowear - Unathi"
cost = 3
allowed_roles = list("Security Officer", "Head of Security", "Warden")
@@ -138,4 +138,12 @@
cost = 1
whitelisted = list("Unathi")
sort_category = "Xenowear - Unathi"
- flags = GEAR_HAS_DESC_SELECTION
\ No newline at end of file
+ flags = GEAR_HAS_DESC_SELECTION
+
+/datum/gear/augment/anchor
+ display_name = "soul anchor"
+ description = "An implant that connects the Aut'akh to the Mesh."
+ path = /obj/item/organ/internal/anchor
+ cost = 1
+ whitelisted = list("Unathi")
+ sort_category = "Xenowear - Unathi"
\ No newline at end of file
diff --git a/code/modules/clothing/spacesuits/rig/suits/alien.dm b/code/modules/clothing/spacesuits/rig/suits/alien.dm
index 14e5c53bf6e..b65ae6a1d52 100644
--- a/code/modules/clothing/spacesuits/rig/suits/alien.dm
+++ b/code/modules/clothing/spacesuits/rig/suits/alien.dm
@@ -96,3 +96,11 @@
/obj/item/rig_module/mounted/tesla)
allowed_module_types = MODULE_GENERAL | MODULE_LIGHT_COMBAT | MODULE_HEAVY_COMBAT | MODULE_UTILITY
+
+/obj/item/rig/tesla/process()
+ ..()
+ if(wearer)
+ var/obj/item/organ/internal/augment/tesla/T = wearer.internal_organs_by_name[BP_AUG_TESLA]
+ if(T && !T.is_broken())
+ if(cell)
+ cell.give(T.max_charges)
diff --git a/code/modules/mob/abstract/new_player/new_player.dm b/code/modules/mob/abstract/new_player/new_player.dm
index 520843cf979..a7ca37f4825 100644
--- a/code/modules/mob/abstract/new_player/new_player.dm
+++ b/code/modules/mob/abstract/new_player/new_player.dm
@@ -333,6 +333,7 @@ INITIALIZE_IMMEDIATE(/mob/abstract/new_player)
var/mob/living/character = create_character() //creates the human and transfers vars and mind
+ SSjobs.EquipAugments(character, character.client.prefs)
character = SSjobs.EquipPersonal(character, rank, 1,spawning_at) //equips the human
// AIs don't need a spawnpoint, they must spawn at an empty core
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 41da71d9f0b..4a71a702119 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -509,6 +509,11 @@
if (shock_damage<1)
return 0
+ var/obj/item/organ/internal/augment/tesla/tesla = internal_organs_by_name[BP_AUG_TESLA]
+ if(tesla?.check_shock())
+ tesla.actual_charges = min(tesla.actual_charges+1, tesla.max_charges)
+ return FALSE
+
if(!def_zone)
//The way this works is by damaging multiple areas in an "Arc" if no def_zone is provided. should be pretty easy to add more arcs if it's needed. though I can't imangine a situation that can apply.
switch ((h_style == "Floorlength Braid" || h_style == "Very Long Hair") ? rand(1, 7) : rand(1, 6))
@@ -1278,6 +1283,8 @@
//Fix husks
mutations.Remove(HUSK)
status_flags &= ~DISFIGURED //Fixes the unknown status
+ if(src.client)
+ SSjobs.EquipAugments(src, src.client.prefs)
update_body(1)
update_eyes()
diff --git a/code/modules/mob/living/carbon/taste.dm b/code/modules/mob/living/carbon/taste.dm
index e2337ac94e0..072d4a1144f 100644
--- a/code/modules/mob/living/carbon/taste.dm
+++ b/code/modules/mob/living/carbon/taste.dm
@@ -18,7 +18,15 @@ calculate text size per text.
var/minimum_percent = 15
if(ishuman(taster))
var/mob/living/carbon/human/H = taster
- minimum_percent = round(15/ (H.isSynthetic() ? TASTE_DULL : H.species.taste_sensitivity))
+ var/total_taste_sensitivity
+
+ var/obj/item/organ/internal/augment/taste_booster/booster = H.internal_organs_by_name[BP_AUG_TASTE_BOOSTER]
+ if(booster && !booster.is_broken())
+ total_taste_sensitivity = booster.new_taste
+ else
+ total_taste_sensitivity = H.species.taste_sensitivity
+
+ minimum_percent = round(15 / (H.isSynthetic() ? TASTE_DULL : total_taste_sensitivity))
var/list/out = list()
var/list/tastes = list() //descriptor = strength
@@ -91,4 +99,4 @@ calculate text size per text.
return "[temp_text][temp_text ? " " : ""][english_list(out, "something indescribable")]."
/mob/living/carbon/proc/get_fullness()
- return nutrition + (reagents.get_reagent_amount("nutriment") * 25)
\ No newline at end of file
+ return nutrition + (reagents.get_reagent_amount("nutriment") * 25)
diff --git a/code/modules/multiz/movement.dm b/code/modules/multiz/movement.dm
index 80f9297da02..b19d0bc21dc 100644
--- a/code/modules/multiz/movement.dm
+++ b/code/modules/multiz/movement.dm
@@ -496,8 +496,14 @@
visible_message(span("notice", "\The [src] tucks into a roll as they hit \the [loc]!"),
span("notice", "You tuck into a roll as you hit \the [loc], minimizing damage!"))
+ var/aug_mod = 1
+ var/obj/item/organ/internal/augment/suspension/suspension = internal_organs_by_name[BP_AUG_SUSPENSION]
+ if(suspension && !suspension.is_broken())
+ aug_mod = suspension.suspension_mod
+ suspension.take_damage(10)
+
var/z_velocity = 5*(levels_fallen**2)
- var/damage = (((40 * species.fall_mod) + z_velocity) + rand(-20,20)) * combat_roll * damage_mod
+ var/damage = (((40 * species.fall_mod) + z_velocity) + rand(-20,20)) * combat_roll * damage_mod * aug_mod
var/limb_damage = rand(0,damage/2)
diff --git a/code/modules/organs/internal/_internal.dm b/code/modules/organs/internal/_internal.dm
index 0cc122960ac..1f7a1b8edd7 100644
--- a/code/modules/organs/internal/_internal.dm
+++ b/code/modules/organs/internal/_internal.dm
@@ -6,6 +6,7 @@
var/damage_reduction = 0.5 //modifier for internal organ injury
var/toxin_type = "undefined"
var/relative_size = 25 //Used for size calcs
+ var/on_mob_icon
min_broken_damage = 10 //Internal organs are frail, man.
diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm
index f1d62d6e7da..13e59b3b9ae 100644
--- a/code/modules/organs/organ.dm
+++ b/code/modules/organs/organ.dm
@@ -11,6 +11,7 @@
var/status = 0
var/vital //Lose a vital limb, die immediately.
var/rejecting // Is this organ already being rejected?
+ var/is_augment = FALSE
//Organ damage stats.
var/damage = 0 // amount of damage to the organ
@@ -28,18 +29,19 @@
var/robotic_name
var/robotic_sprite
var/emp_coeff = 1 //coefficient for damages taken by EMP, if the organ is robotic.
-
+
//Lists.
var/list/transplant_data
var/list/datum/autopsy_data/autopsy_data = list()
var/list/organ_verbs //verb that are added when you gain the organ
var/list/trace_chemicals = list() // traces of chemicals in the organ,
// links chemical IDs to number of ticks for which they'll stay in the blood
-
+
//DNA stuff.
var/datum/dna/dna
var/datum/species/species
var/force_skintone = FALSE // If true, icon generation will skip is-robotic checks. Used for synthskin limbs.
+ var/list/species_restricted //used by augments and biomods to see what species can have this augment
/obj/item/organ/New(loc, ...)
..()
diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm
index 523c6ffb6b1..418aa4b43a8 100644
--- a/code/modules/organs/organ_external.dm
+++ b/code/modules/organs/organ_external.dm
@@ -85,6 +85,8 @@
var/image/hud_damage_image
+ var/augment_limit //how many augments you can fit inside this limb
+
/obj/item/organ/external/proc/invalidate_marking_cache()
cached_markings = null
@@ -1042,6 +1044,8 @@ Note that amputating the affected organ does in fact remove the infection from t
brute_mod = R.brute_mod
burn_mod = R.burn_mod
+ robotize_type = company
+ augment_limit += 1 //robotic limbs get one extra augment capacity
dislocated = -1 //TODO, make robotic limbs a separate type, remove snowflake
limb_flags &= ~ORGAN_CAN_BREAK
@@ -1085,7 +1089,14 @@ Note that amputating the affected organ does in fact remove the infection from t
return ..() && !is_dislocated() && !(status & ORGAN_TENDON_CUT) && (!can_feel_pain() || get_pain() < pain_disability_threshold) && brute_ratio < 1 && burn_ratio < 1
/obj/item/organ/external/proc/is_malfunctioning()
- return (BP_IS_ROBOTIC(src) && (brute_ratio + burn_ratio) >= 0.3 && prob(brute_dam + burn_dam))
+ if(BP_IS_ROBOTIC(src) && (brute_ratio + burn_ratio) >= 0.3 && prob(brute_dam + burn_dam))
+ return TRUE
+ if(robotize_type)
+ var/datum/robolimb/R = all_robolimbs[robotize_type]
+ if(R.malfunctioning_check(owner))
+ return TRUE
+ else
+ return FALSE
/obj/item/organ/external/proc/embed(var/obj/item/W, var/silent = 0, var/supplied_message)
if(!owner || loc != owner)
diff --git a/code/modules/organs/organ_icon.dm b/code/modules/organs/organ_icon.dm
index de5238e2c08..f130299ffdc 100644
--- a/code/modules/organs/organ_icon.dm
+++ b/code/modules/organs/organ_icon.dm
@@ -85,6 +85,8 @@
apply_markings()
+ get_internal_organs_overlay()
+
add_overlay(owner.generate_hair_icon())
compile_overlays()
@@ -113,6 +115,19 @@
add_overlay(finished_icon) //So when it's not on your body, it has icons
mob_icon.Blend(finished_icon, ICON_OVERLAY) //So when it's on your body, it has icons
+/obj/item/organ/external/proc/get_internal_organs_overlay()
+ for(var/obj/item/organ/internal/O in internal_organs)
+ if(O.on_mob_icon)
+ var/cache_key = "[O.on_mob_icon]-[O.icon_state]"
+
+ var/icon/organ_icon = SSicon_cache.internal_organ_cache[cache_key]
+ if (!organ_icon)
+ organ_icon = new /icon(O.on_mob_icon, O.icon_state)
+ SSicon_cache.internal_organ_cache[cache_key] = organ_icon
+
+ add_overlay(organ_icon)
+ mob_icon.Blend(organ_icon, ICON_OVERLAY)
+
/obj/item/organ/external/var/icon_cache_key
/obj/item/organ/external/proc/get_icon(var/skeletal)
@@ -125,6 +140,7 @@
if(painted && skin_color)
mob_icon.Blend(skin_color, ICON_ADD)
apply_markings(restrict_to_robotic = TRUE)
+ get_internal_organs_overlay()
else
if(!dna)
mob_icon = new /icon('icons/mob/human_races/human/r_human.dmi', "[icon_name][gendered_icon ? "_[gender]" : ""]")
@@ -162,6 +178,7 @@
apply_markings()
+ get_internal_organs_overlay()
if(body_hair)
var/list/limb_icon_cache = SSicon_cache.limb_icons_cache
@@ -212,6 +229,10 @@
for (var/marking in cached_markings)
keyparts += "[marking][cached_markings[marking]["color"]]"
+ for(var/obj/item/organ/internal/O in internal_organs)
+ if(O.on_mob_icon)
+ keyparts += "[O.on_mob_icon]-[O.icon_state]"
+
. = keyparts.Join("_")
/obj/item/organ/external/proc/update_marking_cache()
@@ -252,4 +273,4 @@ var/list/robot_hud_colours = list("#ffffff","#cccccc","#aaaaaa","#888888","#6666
// Apply colour and return product.
var/list/hud_colours = !BP_IS_ROBOTIC(src) ? flesh_hud_colours : robot_hud_colours
hud_damage_image.color = hud_colours[max(1,min(Ceiling(dam_state*hud_colours.len),hud_colours.len))]
- return hud_damage_image
\ No newline at end of file
+ return hud_damage_image
diff --git a/code/modules/organs/robolimbs.dm b/code/modules/organs/robolimbs.dm
index 0777a72bec4..88135356dc3 100644
--- a/code/modules/organs/robolimbs.dm
+++ b/code/modules/organs/robolimbs.dm
@@ -1,5 +1,6 @@
var/global/list/all_robolimbs = list()
var/global/list/chargen_robolimbs = list()
+var/global/list/fabricator_robolimbs = list()
var/global/datum/robolimb/basic_robolimb
/proc/populate_robolimb_list()
@@ -9,6 +10,8 @@ var/global/datum/robolimb/basic_robolimb
all_robolimbs[R.company] = R
if(!R.unavailable_at_chargen)
chargen_robolimbs[R.company] = R
+ if(R.fabricator_available)
+ fabricator_robolimbs[R.company] = R
/datum/robolimb
var/company = "Unbranded" // Shown when selecting the limb.
@@ -31,30 +34,38 @@ var/global/datum/robolimb/basic_robolimb
var/linked_frame = "Unbranded Frame" //which machine species this limb will create
var/brute_mod = 0.9 //how resistant is this mode to brute damage
var/burn_mod = 1.1 //how resistant is this mode to burn damage
+ var/fabricator_available = FALSE //if you can print this limb in the robotics fabricator
+
+/datum/robolimb/proc/malfunctioning_check()
+ return FALSE
/datum/robolimb/bishop
company = PROSTHETIC_BC
desc = "This limb is coated in a brilliant silver illuminated from the inside with blue status lights."
icon = 'icons/mob/human_races/ipc/r_ind_bishop.dmi'
linked_frame = "Bishop Accessory Frame"
+ fabricator_available = TRUE
/datum/robolimb/hesphaistos
company = PROSTHETIC_HI
desc = "This limb is covered in thick plating coated with a militaristic olive drab."
icon = 'icons/mob/human_races/ipc/r_ind_hephaestus.dmi'
linked_frame = "Hephaestus G2 Industrial Frame"
+ fabricator_available = TRUE
/datum/robolimb/zenghu
company = PROSTHETIC_ZH
desc = "This limb has sleek white plating over a graphene-based nanofiber weave."
icon = 'icons/mob/human_races/ipc/r_ind_zenghu.dmi'
linked_frame = "Zeng-Hu Mobility Frame"
+ fabricator_available = TRUE
/datum/robolimb/xion
company = PROSTHETIC_XMG
desc = "This limb has a minimalist black and grey casing with exposed orange wiring channels."
icon = 'icons/mob/human_races/ipc/r_ind_xion.dmi'
linked_frame = "Xion Industrial Frame"
+ fabricator_available = TRUE
/datum/robolimb/ipc
company = PROSTHETIC_IPC
@@ -63,6 +74,7 @@ var/global/datum/robolimb/basic_robolimb
unavailable_at_chargen = 1
paintable = 1
linked_frame = "Baseline Frame"
+ fabricator_available = TRUE
/datum/robolimb/industrial
company = PROSTHETIC_IND
@@ -70,6 +82,7 @@ var/global/datum/robolimb/basic_robolimb
icon = 'icons/mob/human_races/ipc/r_industrial.dmi'
unavailable_at_chargen = 1
linked_frame = "Hephaestus G1 Industrial Frame"
+ fabricator_available = TRUE
/datum/robolimb/terminator
company = PROSTHETIC_HK
@@ -83,6 +96,7 @@ var/global/datum/robolimb/basic_robolimb
icon = 'icons/mob/human_races/human/r_human.dmi'
species_can_use = list("Human")
linked_frame = "Shell Frame"
+ fabricator_available = TRUE
/datum/robolimb/autakh
company = PROSTHETIC_AUTAKH
@@ -93,4 +107,17 @@ var/global/datum/robolimb/basic_robolimb
unavailable_at_chargen = 1
paintable = 1
brute_mod = 1
- burn_mod = 1
\ No newline at end of file
+ burn_mod = 1
+
+/datum/robolimb/tesla
+ company = PROSTHETIC_TESLA
+ desc = "A limb designed to be used by the People's Republic of Adhomai Tesla Brigade. This civilian version is issued to disabled veterans and civilians."
+ icon = 'icons/mob/human_races/tajara/tesla_limbs.dmi'
+ species_can_use = list("Tajara", "Zhan-Khazan Tajara", "M'sai Tajara")
+
+/datum/robolimb/tesla/malfunctioning_check(var/mob/living/carbon/human/H)
+ var/obj/item/organ/internal/augment/tesla/T = H.internal_organs_by_name[BP_AUG_TESLA]
+ if(T && !T.is_broken())
+ return FALSE
+ else
+ return TRUE
diff --git a/code/modules/organs/subtypes/augment.dm b/code/modules/organs/subtypes/augment.dm
new file mode 100644
index 00000000000..ff985ead8d8
--- /dev/null
+++ b/code/modules/organs/subtypes/augment.dm
@@ -0,0 +1,294 @@
+/obj/item/organ/internal/augment
+ name = "augment"
+ icon_state = "augment"
+ parent_organ = BP_CHEST
+ organ_tag = "augment"
+ robotic = 2
+ emp_coeff = 2
+ is_augment = TRUE
+ species_restricted = list("Human","Off-Worlder Human",
+ "Tajara", "Zhan-Khazan Tajara", "M'sai Tajara",
+ "Unathi", "Aut'akh Unathi", "Skrell",
+ "Baseline Frame", "Hephaestus G1 Industrial Frame",
+ "Hephaestus G2 Industrial Frame", "Xion Industrial Frame",
+ "Zeng-Hu Mobility Frame", "Bishop Accessory Frame")
+ var/cooldown = 150
+ var/action_button_icon = "augment"
+ var/activable = FALSE
+
+/obj/item/organ/internal/augment/Initialize()
+ robotize()
+ . = ..()
+
+/obj/item/organ/internal/augment/refresh_action_button()
+ . = ..()
+ if(.)
+ if(activable)
+ action.button_icon_state = action_button_icon
+ if(action.button)
+ action.button.UpdateIcon()
+
+/obj/item/organ/internal/augment/attack_self(var/mob/user)
+ . = ..()
+
+ if(.)
+
+ if(owner.last_special > world.time)
+ to_chat(owner, SPAN_WARNING("\The [src] is still recharging!"))
+ return FALSE
+
+ if(use_check_and_message(owner))
+ return FALSE
+
+ if(is_bruised())
+ if(do_bruised_act())
+ return FALSE
+
+ if(is_broken())
+ if(do_broken_act())
+ return FALSE
+
+ owner.last_special = world.time + cooldown
+ return TRUE
+
+
+/obj/item/organ/internal/augment/proc/do_broken_act()
+ spark(get_turf(owner), 3)
+ return TRUE
+
+/obj/item/organ/internal/augment/proc/do_bruised_act()
+ spark(get_turf(owner), 3)
+ return FALSE
+
+/obj/item/organ/internal/augment/timepiece
+ name = "integrated timepiece"
+ icon_state = "augment-clock"
+ parent_organ = BP_HEAD
+ action_button_name = "Activate Integrated Timepiece"
+ activable = TRUE
+ organ_tag = BP_AUG_TIMEPIECE
+ action_button_icon = "augment-clock"
+ cooldown = 10
+
+/obj/item/organ/internal/augment/timepiece/attack_self(var/mob/user)
+ . = ..()
+
+ if(!.)
+ return FALSE
+
+ to_chat(owner, SPAN_NOTICE("Hello [user], it is currently: '[worldtime2text()]'. Today's date is '[time2text(world.time, "Month DD")]. [game_year]'. Have a lovely day."))
+ if (emergency_shuttle.get_status_panel_eta())
+ to_chat(owner, SPAN_WARNING("Notice: You have one (1) scheduled flight, ETA: [emergency_shuttle.get_status_panel_eta()]."))
+
+/obj/item/organ/internal/augment/tool
+ name = "retractable widget"
+ action_button_name = "Deploy Widget"
+ cooldown = 10
+ activable = TRUE
+ var/obj/item/augment_type
+
+
+/obj/item/organ/internal/augment/tool/attack_self(var/mob/user)
+ . = ..()
+
+ if(!.)
+ return FALSE
+
+
+ if(!augment_type)
+ return FALSE
+
+ if (locate(augment_type) in owner)
+ to_chat(owner, SPAN_WARNING("\The [src] is already enabled!"))
+ return
+
+ if(owner.get_active_hand())
+ to_chat(owner, SPAN_WARNING("You must empty your active hand before enabling your [src]!"))
+ return
+
+ var/obj/item/M = new augment_type(owner)
+ owner.put_in_active_hand(M)
+ owner.visible_message(SPAN_NOTICE("\The [M] slides out of \the [owner]'s [src.loc]."), SPAN_NOTICE("You deploy \the [M]!"))
+
+/obj/item/organ/internal/augment/tool/combitool
+ name = "retractable combitool"
+ icon_state = "augment-tool"
+ action_button_name = "Deploy Combitool"
+ action_button_icon = "augment-tool"
+ parent_organ = BP_R_HAND
+ organ_tag = BP_AUG_TOOL
+ augment_type = /obj/item/combitool/robotic
+
+/obj/item/organ/internal/augment/tool/combitool/left
+ parent_organ = BP_L_HAND
+
+/obj/item/organ/internal/augment/health_scanner
+ name = "integrated health scanner"
+ action_button_name = "Activate Health Scanner"
+ action_button_icon = "health"
+ organ_tag = BP_AUG_HEALTHSCAN
+ activable = TRUE
+ cooldown = 8
+
+/obj/item/organ/internal/augment/health_scanner/attack_self(var/mob/user)
+ . = ..()
+ if(!.)
+ return FALSE
+
+ health_scan_mob(owner, owner)
+
+/obj/item/organ/internal/augment/tesla
+ name = "tesla spine"
+ icon_state = "tesla_spine"
+ organ_tag = BP_AUG_TESLA
+ on_mob_icon = 'icons/mob/human_races/augments_external.dmi'
+ species_restricted = list("Tajara", "Zhan-Khazan Tajara", "M'sai Tajara")
+ var/max_charges = 1
+ var/actual_charges = 0
+ var/recharge_time = 5 //this is in minutes
+
+/obj/item/organ/internal/augment/tesla/proc/check_shock()
+ if(is_broken())
+ return FALSE
+ if(is_bruised())
+ if(prob(50))
+ return FALSE
+ if(actual_charges >= max_charges)
+ return FALSE
+ else
+ do_tesla_act()
+ return TRUE
+
+/obj/item/organ/internal/augment/tesla/proc/do_tesla_act()
+ if(owner)
+ to_chat(owner, FONT_LARGE(SPAN_DANGER("You feel your [src.name] surge with energy!")))
+ spark(get_turf(owner), 3)
+ addtimer(CALLBACK(src, .proc/disarm), recharge_time MINUTES)
+ if(is_bruised() && prob(50))
+ owner.electrocute_act(40, owner)
+
+/obj/item/organ/internal/augment/tesla/proc/disarm()
+ if(actual_charges <= 0)
+ return
+ actual_charges = min(actual_charges - 1, max_charges)
+ if(actual_charges > 0)
+ addtimer(CALLBACK(src, .proc/disarm), recharge_time MINUTES)
+ if(is_broken())
+ visible_message(SPAN_DANGER("\The [owner] crackles with energy!"))
+ playsound(owner, 'sound/magic/LightningShock.ogg', 75, 1)
+ tesla_zap(owner, 7, 1500)
+
+/obj/item/organ/internal/augment/tesla/advanced
+ name = "advanced tesla spine"
+ max_charges = 15
+ cooldown = 50
+ emp_coeff = 1
+ action_button_icon = "tesla_spine"
+ action_button_name = "Activate Tesla Coil"
+ activable = TRUE
+
+/obj/item/organ/internal/augment/tesla/advanced/attack_self(var/mob/user)
+ . = ..()
+
+ if(!.)
+ return FALSE
+
+ visible_message(SPAN_DANGER("\The [owner] crackles with energy!"))
+ playsound(owner, 'sound/magic/LightningShock.ogg', 75, 1)
+ tesla_zap(owner, 7, 1500)
+
+/obj/item/organ/internal/augment/eye_sensors
+ name = "integrated eye sensors"
+ icon_state = "augment_eyes"
+ cooldown = 25
+ activable = TRUE
+ organ_tag = BP_AUG_EYE_SENSORS
+ action_button_name = "Toggle Eye Sensors"
+
+ var/static/list/hud_types = list(
+ "Disabled",
+ "Security",
+ "Medical")
+
+ var/selected_hud = "Disabled"
+
+/obj/item/organ/internal/augment/eye_sensors/attack_self(var/mob/user)
+ . = ..()
+
+ if(!.)
+ return FALSE
+
+ var/choice = input("Select the Sensor Type.", "Bionic Eyes Sensors") as null|anything in hud_types
+
+ selected_hud = choice
+
+/obj/item/organ/internal/augment/eye_sensors/process()
+ ..()
+
+ if(!owner)
+ return
+
+ switch(selected_hud)
+
+ if("Security")
+ req_access = list(access_security)
+ if(allowed(owner))
+ process_sec_hud(owner, 1)
+
+ if("Medical")
+ req_access = list(access_medical)
+ if(allowed(owner))
+ process_med_hud(owner, 1)
+
+/obj/item/organ/internal/augment/eye_sensors/emp_act(severity)
+ ..()
+ var/obj/item/organ/internal/eyes/E = owner.get_eyes()
+ if(!E)
+ return
+ E.take_damage(5)
+
+/obj/item/organ/internal/augment/cyber_hair
+ name = "synthetic hair extensions"
+ cooldown = 20
+ action_button_icon = "cyber_hair"
+ organ_tag = BP_AUG_HAIR
+ activable = TRUE
+ action_button_name = "Activate Synthetic Hair Extensions"
+
+/obj/item/organ/internal/augment/cyber_hair/attack_self(var/mob/user)
+ . = ..()
+
+ if(!.)
+ return FALSE
+
+ owner.visible_message(SPAN_NOTICE("\The [owner]'s hair begins to rapidly shift in shape and length."))
+ owner.change_appearance(APPEARANCE_ALL_HAIR, owner.loc, owner, check_species_whitelist = 1)
+
+/obj/item/organ/internal/augment/suspension
+ name = "calf suspension"
+ icon_state = "suspension"
+ organ_tag = BP_AUG_SUSPENSION
+ parent_organ = BP_GROIN
+ min_broken_damage = 20
+ max_damage = 20
+ var/suspension_mod = 0.8
+
+/obj/item/organ/internal/augment/suspension/advanced
+ name = "advanced calf suspension"
+ min_broken_damage = 50
+ max_damage = 50
+ suspension_mod = 0
+
+/obj/item/organ/internal/augment/taste_booster
+ name = "taste booster"
+ organ_tag = BP_AUG_TASTE_BOOSTER
+ parent_organ = BP_HEAD
+ var/new_taste = TASTE_SENSITIVE //this will replace the species' taste var
+
+/obj/item/organ/internal/augment/taste_booster/dull
+ name = "taste duller"
+ new_taste = TASTE_DULL
+
+/obj/item/organ/internal/augment/fuel_cell
+ name = "integrated fuel cell"
+ organ_tag = BP_AUG_FUEL_CELL
\ No newline at end of file
diff --git a/code/modules/organs/subtypes/autakh.dm b/code/modules/organs/subtypes/autakh.dm
index 771893df7d1..8dd7789c329 100644
--- a/code/modules/organs/subtypes/autakh.dm
+++ b/code/modules/organs/subtypes/autakh.dm
@@ -334,7 +334,8 @@
desc = "An integrated combitool module."
icon_state = "digitool"
item_state = "digitool"
-
+ w_class = ITEMSIZE_LARGE
+
/obj/item/combitool/robotic/throw_at()
usr.drop_from_inventory(src)
diff --git a/code/modules/organs/subtypes/standard.dm b/code/modules/organs/subtypes/standard.dm
index 77e2f7a8e90..e8dc90b0758 100644
--- a/code/modules/organs/subtypes/standard.dm
+++ b/code/modules/organs/subtypes/standard.dm
@@ -19,6 +19,7 @@
limb_flags = ORGAN_CAN_BREAK
parent_organ = null
encased = "ribcage"
+ augment_limit = 3
/obj/item/organ/external/groin
name = "lower body"
@@ -35,6 +36,7 @@
artery_name = "iliac artery"
dislocated = -1
gendered_icon = 1
+ augment_limit = 3
/obj/item/organ/external/arm
limb_name = "l_arm"
@@ -50,6 +52,7 @@
tendon_name = "palmaris longus tendon"
artery_name = "basilic vein"
amputation_point = "left shoulder"
+ augment_limit = 2
/obj/item/organ/external/arm/right
limb_name = "r_arm"
@@ -76,6 +79,7 @@
artery_name = "femoral artery"
amputation_point = "left hip"
limb_flags = ORGAN_CAN_AMPUTATE | ORGAN_CAN_BREAK | ORGAN_CAN_MAIM | ORGAN_HAS_TENDON
+ augment_limit = 2
/obj/item/organ/external/leg/right
limb_name = "r_leg"
@@ -100,6 +104,7 @@
amputation_point = "left ankle"
limb_flags = ORGAN_CAN_AMPUTATE | ORGAN_CAN_BREAK | ORGAN_CAN_MAIM | ORGAN_CAN_STAND
maim_bonus = 1
+ augment_limit = 1
/obj/item/organ/external/foot/removed()
if(owner)
@@ -130,6 +135,7 @@
amputation_point = "left wrist"
limb_flags = ORGAN_CAN_AMPUTATE | ORGAN_CAN_BREAK | ORGAN_CAN_MAIM | ORGAN_CAN_GRASP | ORGAN_HAS_TENDON
maim_bonus = 1
+ augment_limit = 1
/obj/item/organ/external/hand/removed()
owner.drop_from_inventory(owner.gloves)
@@ -163,6 +169,7 @@
amputation_point = "neck"
gendered_icon = 1
encased = "skull"
+ augment_limit = 3
var/can_intake_reagents = 1
/obj/item/organ/external/head/removed()
diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm
index 8db132568ca..5bccb29c9e1 100644
--- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm
+++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm
@@ -275,7 +275,11 @@
return
/datum/reagent/fuel/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
- M.adjustToxLoss(2 * removed)
+ var/obj/item/organ/internal/augment/fuel_cell/aug = M.internal_organs_by_name[BP_AUG_FUEL_CELL]
+ if(aug && !aug.is_broken())
+ M.adjustNutritionLoss(-8 * removed)
+ else
+ M.adjustToxLoss(2 * removed)
/datum/reagent/fuel/touch_mob(var/mob/living/L, var/amount)
. = ..()
diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm
index 8f04afa73d4..0e9e6850139 100644
--- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm
+++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm
@@ -160,7 +160,7 @@
if (halluci)
M.hallucination = max(M.hallucination, halluci)
-
+
if(caffeine)
M.add_chemical_effect(CE_PULSE, caffeine*2)
if(!caffeine_mod)
@@ -269,7 +269,11 @@
fallback_specific_heat = 0.549 //Unknown
/datum/reagent/hydrazine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
- M.adjustToxLoss(4 * removed)
+ var/obj/item/organ/internal/augment/fuel_cell/aug = M.internal_organs_by_name[BP_AUG_FUEL_CELL]
+ if(aug && !aug.is_broken())
+ M.adjustNutritionLoss(-12 * removed)
+ else
+ M.adjustToxLoss(4 * removed)
/datum/reagent/hydrazine/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) // Hydrazine is both toxic and flammable.
M.adjust_fire_stacks(removed / 12)
diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm
index bb3adc07e77..d31453bb85b 100644
--- a/code/modules/surgery/organs_internal.dm
+++ b/code/modules/surgery/organs_internal.dm
@@ -9,7 +9,12 @@
return 0
var/obj/item/organ/external/affected = target.get_organ(target_zone)
- return affected && affected.open == (affected.encased ? 3 : 2)
+ if(affected.encased)
+ return affected && affected.open == (affected.encased ? 3 : 2)
+ if(BP_IS_ROBOTIC(affected))
+ return affected.augment_limit && affected.open == 3
+ else
+ return affected.augment_limit && affected.open == 2
//////////////////////////////////////////////////////////////////
// CHEST INTERNAL ORGAN SURGERY //
@@ -148,6 +153,10 @@
if(I && istype(I))
I.status |= ORGAN_CUT_AWAY
+ target.update_body()
+ target.updatehealth()
+ target.UpdateDamageIcon()
+
/datum/surgery_step/internal/detach_organ/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("[user]'s hand slips, slicing an artery inside [target]'s [affected.name] with \the [tool]!", \
@@ -205,6 +214,10 @@
else
playsound(target.loc, 'sound/items/Ratchet.ogg', 50, 1)
+ target.update_body()
+ target.updatehealth()
+ target.UpdateDamageIcon()
+
/datum/surgery_step/internal/remove_organ/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("[user]'s hand slips, damaging [target]'s [affected.name] with \the [tool]!", \
@@ -246,12 +259,30 @@
if(O.organ_tag == "limb")
return 0
- else if(target.species.has_organ[O.organ_tag])
+ else if(target.species.has_organ[O.organ_tag] || O.is_augment)
if(O.damage > (O.max_damage * 0.75))
to_chat(user, "\The [O.organ_tag] [o_is] in no state to be transplanted.")
return SURGERY_FAILURE
+ if(O.species_restricted)
+ if(!target.species.name in O.species_restricted)
+ to_chat(user, SPAN_WARNING("\The [O] is not compatible with \the [target]'s biology."))
+ return SURGERY_FAILURE
+
+ if(O.is_augment)
+ if(affected.augment_limit)
+ var/total_augments
+ for(var/obj/item/organ/internal/I in affected.internal_organs)
+ if(I.is_augment)
+ total_augments += 1
+ if(total_augments >= affected.augment_limit)
+ to_chat(user, SPAN_WARNING("There is no space left in \the [affected] to implant \the [O]."))
+ return SURGERY_FAILURE
+ else
+ to_chat(user, SPAN_WARNING("There is no space in \the [affected] to implant \the [O]."))
+ return SURGERY_FAILURE
+
if(!target.internal_organs_by_name[O.organ_tag])
organ_missing = 1
else
@@ -285,6 +316,10 @@
O.replaced(target,affected)
playsound(target.loc, 'sound/effects/squelch1.ogg', 50, 1)
+ target.update_body()
+ target.updatehealth()
+ target.UpdateDamageIcon()
+
/datum/surgery_step/internal/replace_organ/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
user.visible_message("[user]'s hand slips, damaging \the [tool]!", \
"Your hand slips, damaging \the [tool]!")
@@ -334,6 +369,10 @@
if(I && istype(I))
I.status &= ~ORGAN_CUT_AWAY
+ target.update_body()
+ target.updatehealth()
+ target.UpdateDamageIcon()
+
/datum/surgery_step/internal/attach_organ/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("[user]'s hand slips, damaging the flesh in [target]'s [affected.name] with \the [tool]!", \
diff --git a/html/changelogs/alberyk-augs.yml b/html/changelogs/alberyk-augs.yml
new file mode 100644
index 00000000000..f97286de98d
--- /dev/null
+++ b/html/changelogs/alberyk-augs.yml
@@ -0,0 +1,7 @@
+author: Alberyk, Kyres1
+
+delete-after: True
+
+changes:
+ - rscadd: "Added a couple of augments to the custom loadout."
+ - rscadd: "Added tesla limbs for the Tajara species."
diff --git a/icons/mob/human_races/augments_external.dmi b/icons/mob/human_races/augments_external.dmi
new file mode 100644
index 00000000000..74c345f5a7b
Binary files /dev/null and b/icons/mob/human_races/augments_external.dmi differ
diff --git a/icons/mob/human_races/tajara/tesla_limbs.dmi b/icons/mob/human_races/tajara/tesla_limbs.dmi
new file mode 100644
index 00000000000..cb74cd7e705
Binary files /dev/null and b/icons/mob/human_races/tajara/tesla_limbs.dmi differ
diff --git a/icons/obj/action_buttons/organs.dmi b/icons/obj/action_buttons/organs.dmi
index 90dfa669594..0db0a83f09d 100644
Binary files a/icons/obj/action_buttons/organs.dmi and b/icons/obj/action_buttons/organs.dmi differ
diff --git a/icons/obj/surgery.dmi b/icons/obj/surgery.dmi
index 6bb60a28888..bcafd8ae745 100644
Binary files a/icons/obj/surgery.dmi and b/icons/obj/surgery.dmi differ