From 001430f6fc7297866c78752711b9c8f2d4190b8d Mon Sep 17 00:00:00 2001
From: PollardTheDragon <144391971+PollardTheDragon@users.noreply.github.com>
Date: Thu, 7 Aug 2025 12:54:49 -0400
Subject: [PATCH] Adds new AI upgrade disks as space and trader loot (#29837)
* Adds new AI upgrade disks, makes them space loot and trader loot
* Fixed oversight
---
.../spawners/random/pool/space_loot.dm | 4 ++
.../traders/trader_department_spawners.dm | 4 ++
code/game/objects/items/robot/ai_upgrades.dm | 54 +++++++++++++++++++
code/modules/mob/living/silicon/ai/ai_mob.dm | 6 ++-
4 files changed, 66 insertions(+), 2 deletions(-)
diff --git a/code/game/objects/effects/spawners/random/pool/space_loot.dm b/code/game/objects/effects/spawners/random/pool/space_loot.dm
index e60150bab53..06fd29d8883 100644
--- a/code/game/objects/effects/spawners/random/pool/space_loot.dm
+++ b/code/game/objects/effects/spawners/random/pool/space_loot.dm
@@ -55,6 +55,10 @@
/obj/item/storage/toolbox/syndicate,
/obj/item/suppressor,
/obj/item/toy/syndicateballoon,
+ /obj/item/ai_upgrade/expanded_storage,
+ /obj/item/ai_upgrade/expanded_network,
+ /obj/item/ai_upgrade/expanded_tank,
+ /obj/item/ai_upgrade/expanded_fabricator,
)
/obj/effect/spawner/random/pool/spaceloot/syndicate/common/depot
diff --git a/code/game/objects/effects/spawners/random/traders/trader_department_spawners.dm b/code/game/objects/effects/spawners/random/traders/trader_department_spawners.dm
index 8f164aedca1..ed8351471eb 100644
--- a/code/game/objects/effects/spawners/random/traders/trader_department_spawners.dm
+++ b/code/game/objects/effects/spawners/random/traders/trader_department_spawners.dm
@@ -98,6 +98,10 @@
// Might as well let AI be interested
/obj/item/ai_upgrade/surveillance_upgrade = 25,
+ /obj/item/ai_upgrade/expanded_storage = 10,
+ /obj/item/ai_upgrade/expanded_network = 10,
+ /obj/item/ai_upgrade/expanded_tank = 10,
+ /obj/item/ai_upgrade/expanded_fabricator = 10,
)
/obj/effect/spawner/random/traders/medical
diff --git a/code/game/objects/items/robot/ai_upgrades.dm b/code/game/objects/items/robot/ai_upgrades.dm
index dcedf09e0f6..6bb05201d42 100644
--- a/code/game/objects/items/robot/ai_upgrades.dm
+++ b/code/game/objects/items/robot/ai_upgrades.dm
@@ -59,3 +59,57 @@
return
to_chat(user, "You reset [AI]'s program storage to factory settings.")
AI.reset_programs()
+
+// Expanded Storage
+/obj/item/ai_upgrade/expanded_storage
+ name = "expanded storage upgrade"
+ desc = "An experimental upgrade labelled EX.ST. Within is an algorithm to compress an AI's processes, granting them spare memory."
+
+/obj/item/ai_upgrade/expanded_storage/ai_upgrade_action(mob/living/silicon/ai/AI, mob/user)
+ if(!istype(AI))
+ return
+ to_chat(AI, "[user] has upgraded you an expanded storage module. Extra memory granted!")
+ AI.program_picker.total_memory += 2
+ AI.program_picker.memory += 2
+ to_chat(user, "You upgrade [AI]. [src] is consumed in the process.")
+ qdel(src)
+
+// Expanded Network Array
+/obj/item/ai_upgrade/expanded_network
+ name = "expanded network array upgrade"
+ desc = "An experimental upgrade labelled EX.AR. Within is an algorithm to optimize an AI's network, granting them spare bandwidth."
+
+/obj/item/ai_upgrade/expanded_network/ai_upgrade_action(mob/living/silicon/ai/AI, mob/user)
+ if(!istype(AI))
+ return
+ to_chat(AI, "[user] has upgraded you an expanded network array module. Extra bandwidth granted!")
+ AI.program_picker.total_bandwidth += 1
+ AI.program_picker.bandwidth += 1
+ to_chat(user, "You upgrade [AI]. [src] is consumed in the process.")
+ qdel(src)
+
+// Expanded Nanite Tank
+/obj/item/ai_upgrade/expanded_tank
+ name = "expanded nanite tank upgrade"
+ desc = "An experimental upgrade labelled NA.TA. Within is a bluespace compacting program to make an AI's nanite reserves just a bit bigger."
+
+/obj/item/ai_upgrade/expanded_tank/ai_upgrade_action(mob/living/silicon/ai/AI, mob/user)
+ if(!istype(AI))
+ return
+ to_chat(AI, "[user] has upgraded you an expanded nanite tank module. Extra nanite storage capacity granted!")
+ AI.program_picker.max_nanites += 10
+ to_chat(user, "You upgrade [AI]. [src] is consumed in the process.")
+ qdel(src)
+
+// Expanded Nanite Fabricator
+/obj/item/ai_upgrade/expanded_fabricator
+ name = "expanded nanite fabricator upgrade"
+ desc = "An experimental upgrade labelled NA.FA. Within is a program to compress the fabricators of an AI's nanites, allowing them to construct them quicker."
+
+/obj/item/ai_upgrade/expanded_fabricator/ai_upgrade_action(mob/living/silicon/ai/AI, mob/user)
+ if(!istype(AI))
+ return
+ to_chat(AI, "[user] has upgraded you an expanded nanite fabricator module. Extra nanite regeneration granted!")
+ AI.nanite_regen += 0.5
+ to_chat(user, "You upgrade [AI]. [src] is consumed in the process.")
+ qdel(src)
diff --git a/code/modules/mob/living/silicon/ai/ai_mob.dm b/code/modules/mob/living/silicon/ai/ai_mob.dm
index 9b1feaf64b1..e89e588c5b1 100644
--- a/code/modules/mob/living/silicon/ai/ai_mob.dm
+++ b/code/modules/mob/living/silicon/ai/ai_mob.dm
@@ -70,6 +70,8 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
// AI Powers
var/datum/program_picker/program_picker
var/datum/spell/ai_spell/choose_program/program_action
+ /// Base rate of nanite regen
+ var/nanite_regen = 1
/// Whether or not the AI has unlocked universal adapter
var/universal_adapter = FALSE
/// How effective is the adapter?
@@ -331,7 +333,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
var/list/status_tab_data = ..()
. = status_tab_data
status_tab_data[++status_tab_data.len] = list("Nanites:", "[program_picker.nanites] / [program_picker.max_nanites]")
- status_tab_data[++status_tab_data.len] = list("Nanite Manufacture Rate:", "[(1 + 0.5 * program_picker.bandwidth)]")
+ status_tab_data[++status_tab_data.len] = list("Nanite Manufacture Rate:", "[(nanite_regen + 0.5 * program_picker.bandwidth)]")
if(stat)
status_tab_data[++status_tab_data.len] = list("System status:", "Nonfunctional")
return
@@ -438,7 +440,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
qdel(src)
return
// Regenerate nanites for abilities only when powered.
- powered_ai.program_picker.nanites = min(100, powered_ai.program_picker.nanites + (1 + 0.5 * powered_ai.program_picker.bandwidth))
+ powered_ai.program_picker.nanites = min(powered_ai.program_picker.max_nanites, powered_ai.program_picker.nanites + (powered_ai.nanite_regen + 0.5 * powered_ai.program_picker.bandwidth))
if(!powered_ai.anchored)
loc = powered_ai.loc
change_power_mode(NO_POWER_USE)