diff --git a/code/_helpers/roundend.dm b/code/_helpers/roundend.dm
index 1bd34f6ed70..4bbe87059a9 100644
--- a/code/_helpers/roundend.dm
+++ b/code/_helpers/roundend.dm
@@ -91,39 +91,32 @@ GLOBAL_LIST_EMPTY(common_report)
var/list/parts = list()
var/borg_spacer = FALSE //inserts an extra linebreak to seperate AIs from independent borgs, and then multiple independent borgs.
//Silicon laws report
- for (var/mob/living/silicon/ai/aiPlayer in SSmobs.mob_list)
- if (!aiPlayer.is_ooc_dead())
- parts += "[aiPlayer.name] (Played by: [aiPlayer.key])'s laws at the end of the round were:"
- else
- parts += "[aiPlayer.name] (Played by: [aiPlayer.key])'s laws when it was deactivated were:"
-
-
- parts += aiPlayer.laws?.print_laws()
-
- if (aiPlayer.connected_robots.len)
- parts += "The AI's loyal minions were: "
- for(var/mob/living/silicon/robot/robo in aiPlayer.connected_robots)
- parts += "[robo.name][robo.stat?" (Deactivated) (Played by: [robo.key]), ":" (Played by: [robo.key]), "]"
-
- if(!borg_spacer)
- borg_spacer = TRUE
-
var/dronecount = 0
-
- for (var/mob/living/silicon/robot/robo in SSmobs.mob_list)
-
- if(istype(robo,/mob/living/silicon/robot/drone))
+ for(var/datum/mind/M in GLOB.all_synthetic_mind_to_data)
+ var/list/data = GLOB.all_synthetic_mind_to_data[M]
+ var/weakref/silicon_ref = data[3]
+ var/mob/living/silicon/ai/S = silicon_ref?.resolve()
+ if(data[2] in typesof(/mob/living/silicon/ai))
+ if(S && !S?.is_ooc_dead())
+ parts += "[data[1]] (Played by: [M.key])'s laws at the end of the round were:"
+ else
+ parts += "[data[1]] (Played by: [M.key])'s laws when it was deactivated were:"
+ parts += S?.laws?.print_laws() ? S?.laws?.print_laws() : data[4]
+ if(!borg_spacer)
+ borg_spacer = TRUE
+ else if(data[2] in typesof(/mob/living/silicon/robot/drone))
dronecount++
- continue
+ else if(data[2] in typesof(/mob/living/silicon/robot))
+ var/mob/living/silicon/robot/robo = silicon_ref?.resolve()
+ if (!robo.connected_ai)
+ parts += "[borg_spacer?"
":""][data[1]] (Played by: [M.key]) [(!robo || robo?.is_ooc_dead()) ? "was unable to survive the rigors of being a cyborg." : "survived as borg!"]\
+ It was [robo?.connected_ai ? "[robo?.connected_ai.name]'s loyal minion" : "AI-less, independent machine"]. Its laws were:"
- if (!robo.connected_ai)
- parts += "[borg_spacer?"
":""][robo.name] (Played by: [robo.mind.key]) [(!robo.is_ooc_dead())? "survived as an AI-less borg!" : "was unable to survive the rigors of being a cyborg without an AI."] Its laws were:"
+ if(robo) //How the hell do we lose robo between here and the world messages directly above this?
+ parts += robo.laws?.print_laws()
- if(robo) //How the hell do we lose robo between here and the world messages directly above this?
- parts += robo.laws?.print_laws()
-
- if(!borg_spacer)
- borg_spacer = TRUE
+ if(!borg_spacer)
+ borg_spacer = TRUE
if(dronecount)
parts += "[borg_spacer?"
":""]There [dronecount>1 ? "were" : "was"] [dronecount] industrious maintenance [dronecount>1 ? "drones" : "drone"] at the end of this round."
diff --git a/code/game/antagonist/station/traitor.dm b/code/game/antagonist/station/traitor.dm
index f8d2edeea56..07e21b5f566 100644
--- a/code/game/antagonist/station/traitor.dm
+++ b/code/game/antagonist/station/traitor.dm
@@ -26,6 +26,13 @@ GLOBAL_DATUM_INIT(traitors, /datum/antagonist/traitor, new)
return 1
/datum/antagonist/traitor/get_special_objective_text(datum/mind/player)
+ var/detected = FALSE
+ for(var/datum/objective/objective in player.objectives)
+ if(istype(objective, /datum/objective/contracts))
+ detected = TRUE
+ break
+ if(!detected)
+ return
var/contracts_num = player.completed_contracts
if(!contracts_num)
return "
The traitor hasn't completed a single contract. [pick("What a shame", "Loser", "Sorry sight", "Lame duck", "Schlimazel", "Pantywaist", "We will talk about it later")]."
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 9b9806cf450..1fd1909811f 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -182,6 +182,7 @@ var/list/ai_verbs_default = list(
..()
ai_radio = silicon_radio
ai_radio.myAi = src
+ GLOB.all_synthetic_mind_to_data[mind] = list(name, type, weakref(src), laws?.print_laws())
/mob/living/silicon/ai/proc/on_mob_init()
to_chat(src, "You are playing the [station_name()]'s AI. The AI cannot move, but can interact with many objects while viewing them (through cameras).")
@@ -209,6 +210,7 @@ var/list/ai_verbs_default = list(
eyeobj.possess(src)
/mob/living/silicon/ai/Destroy()
+ GLOB.all_synthetic_mind_to_data[mind] = list(name, type, weakref(null), laws?.print_laws())
for(var/robot in connected_robots)
var/mob/living/silicon/robot/S = robot
S.connected_ai = null
diff --git a/code/modules/mob/living/silicon/robot/robot_upgrades.dm b/code/modules/mob/living/silicon/robot/robot_upgrades.dm
index a6dc10cf67a..c2ed95ddd9f 100644
--- a/code/modules/mob/living/silicon/robot/robot_upgrades.dm
+++ b/code/modules/mob/living/silicon/robot/robot_upgrades.dm
@@ -149,8 +149,10 @@
/obj/item/borg/upgrade/rename/action(mob/living/silicon/robot/R)
if(..()) return 0
spawn(1)
- if (held_name == initial(held_name))
+ while(held_name == initial(held_name))
held_name = sanitizeSafe(input(R, "Enter new robot name", "Robot Reclassification", held_name), MAX_NAME_LEN)
+ if(!held_name)
+ held_name = initial(held_name)
R.notify_ai(ROBOT_NOTIFICATION_NEW_NAME, R.name, held_name)
R.SetName(held_name)
R.custom_name = held_name
diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm
index b5b6de3ce9f..72fe61f9f73 100644
--- a/code/modules/mob/living/silicon/silicon.dm
+++ b/code/modules/mob/living/silicon/silicon.dm
@@ -1,4 +1,4 @@
-
+GLOBAL_LIST_EMPTY(all_synthetic_mind_to_data) // data: list of name and type of synthetic
/mob/living/silicon
gender = NEUTER
@@ -63,6 +63,15 @@
AH.unregister_alarm(src)
return ..()
+/mob/living/silicon/mind_initialize()
+ . = ..()
+ GLOB.all_synthetic_mind_to_data[mind] = list(name, type, weakref(src))
+
+/mob/living/silicon/SetName(new_name)
+ . = ..()
+ if(mind)
+ GLOB.all_synthetic_mind_to_data[mind][1] = name
+
/mob/living/silicon/fully_replace_character_name(new_name)
..()
if(istype(idcard))