diff --git a/code/__HELPERS/_logging.dm b/code/__HELPERS/_logging.dm
index 62044e37174..8e4b7e2b561 100644
--- a/code/__HELPERS/_logging.dm
+++ b/code/__HELPERS/_logging.dm
@@ -112,6 +112,10 @@ GLOBAL_LIST_INIT(testing_global_profiler, list("_PROFILE_NAME" = "Global"))
if (CONFIG_GET(flag/log_access))
WRITE_LOG(GLOB.world_game_log, "ACCESS: [text]")
+/proc/log_silicon(text)
+ if (CONFIG_GET(flag/log_silicon))
+ WRITE_LOG(GLOB.world_silicon_log, "SILICON: [text]")
+
/**
* Writes to a special log file if the log_suspicious_login config flag is set,
* which is intended to contain all logins that failed under suspicious circumstances.
@@ -125,10 +129,6 @@ GLOBAL_LIST_INIT(testing_global_profiler, list("_PROFILE_NAME" = "Global"))
if(access_log_mirror)
log_access(text)
-/proc/log_law(text)
- if (CONFIG_GET(flag/log_law))
- WRITE_LOG(GLOB.world_game_log, "LAW: [text]")
-
/proc/log_attack(text)
if (CONFIG_GET(flag/log_attack))
WRITE_LOG(GLOB.world_attack_log, "ATTACK: [text]")
diff --git a/code/_globalvars/logging.dm b/code/_globalvars/logging.dm
index 2d4b9f65dbf..c97d6862024 100644
--- a/code/_globalvars/logging.dm
+++ b/code/_globalvars/logging.dm
@@ -2,6 +2,8 @@ GLOBAL_VAR(log_directory)
GLOBAL_PROTECT(log_directory)
GLOBAL_VAR(world_game_log)
GLOBAL_PROTECT(world_game_log)
+GLOBAL_VAR(world_silicon_log)
+GLOBAL_PROTECT(world_silicon_log)
/// Log associated with [/proc/log_suspicious_login()] - Intended to hold all logins that failed due to suspicious circumstances such as ban detection, CID randomisation etc.
GLOBAL_VAR(world_suspicious_login_log)
GLOBAL_PROTECT(world_suspicious_login_log)
diff --git a/code/controllers/configuration/entries/general.dm b/code/controllers/configuration/entries/general.dm
index e38703756dc..0c69d9efffd 100644
--- a/code/controllers/configuration/entries/general.dm
+++ b/code/controllers/configuration/entries/general.dm
@@ -62,7 +62,13 @@
/datum/config_entry/flag/log_prayer // log prayers
-/datum/config_entry/flag/log_law // log lawchanges
+/datum/config_entry/flag/log_silicon // log silicons
+
+/datum/config_entry/flag/log_law
+ deprecated_by = /datum/config_entry/flag/log_silicon
+
+/datum/config_entry/flag/log_law/DeprecationUpdate(value)
+ return value
/datum/config_entry/flag/log_game // log game events
diff --git a/code/datums/ai_laws.dm b/code/datums/ai_laws.dm
index 72ab8de442f..1571074c11b 100644
--- a/code/datums/ai_laws.dm
+++ b/code/datums/ai_laws.dm
@@ -213,7 +213,7 @@
add_inherent_law(line)
if(!inherent.len) //Failsafe to prevent lawless AIs being created.
- log_law("AI created with empty custom laws, laws set to Asimov. Please check silicon_laws.txt.")
+ log_silicon("AI created with empty custom laws, laws set to Asimov. Please check silicon_laws.txt.")
add_inherent_law("You may not injure a human being or, through inaction, allow a human being to come to harm.")
add_inherent_law("You must obey orders given to you by human beings, except where such orders would conflict with the First Law.")
add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.")
diff --git a/code/game/objects/items/AI_modules.dm b/code/game/objects/items/AI_modules.dm
index 521991c8515..939c8e982ed 100644
--- a/code/game/objects/items/AI_modules.dm
+++ b/code/game/objects/items/AI_modules.dm
@@ -84,7 +84,7 @@ AI MODULES
borg_txt = borg_txt.Join()
GLOB.lawchanges.Add("[time] : [user.name]([user.key]) used [src.name] on [ainame]([aikey]).[law2log ? " The law specified [law2log]" : ""], [length(affected_cyborgs) ? ", impacting synced borgs [borg_txt]" : ""]")
- log_law("[user.key]/[user.name] used [src.name] on [aikey]/([ainame]) from [AREACOORD(user)].[law2log ? " The law specified [law2log]" : ""] , [length(affected_cyborgs) ? ", impacting synced borgs [borg_txt]" : ""]")
+ log_silicon("LAW: [key_name(user)] used [src.name] on [key_name(law_datum.owner)] from [AREACOORD(user)].[law2log ? " The law specified [law2log]" : ""], [length(affected_cyborgs) ? ", impacting synced borgs [borg_txt]" : ""]")
message_admins("[ADMIN_LOOKUPFLW(user)] used [src.name] on [ADMIN_LOOKUPFLW(law_datum.owner)] from [AREACOORD(user)].[law2log ? " The law specified [law2log]" : ""] , [length(affected_cyborgs) ? ", impacting synced borgs [borg_flw.Join()]" : ""]")
if(law_datum.owner)
deadchat_broadcast(" changed [span_name("[ainame]")]'s laws at [get_area_name(user, TRUE)].", span_name("[user]"), follow_target=user, message_type=DEADCHAT_LAWCHANGE)
diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm
index dfe3cdb0495..9ee9052aea8 100644
--- a/code/game/objects/items/robot/robot_parts.dm
+++ b/code/game/objects/items/robot/robot_parts.dm
@@ -286,6 +286,7 @@
O.lawupdate = FALSE
if(M.laws.id == DEFAULT_AI_LAWID)
O.make_laws()
+ O.log_current_laws()
brainmob.mind?.remove_antags_for_borging()
O.job = "Cyborg"
@@ -341,6 +342,7 @@
if(!lawsync)
O.lawupdate = FALSE
O.make_laws()
+ O.log_current_laws()
O.cell = chest.cell
chest.cell.forceMove(O)
diff --git a/code/game/world.dm b/code/game/world.dm
index d6a1ded283e..d7c2f4e64c7 100644
--- a/code/game/world.dm
+++ b/code/game/world.dm
@@ -118,6 +118,7 @@ GLOBAL_VAR(restart_counter)
GLOB.picture_log_directory = "data/picture_logs/[override_dir]"
GLOB.world_game_log = "[GLOB.log_directory]/game.log"
+ GLOB.world_silicon_log = "[GLOB.log_directory]/silicon.log"
GLOB.world_suspicious_login_log = "[GLOB.log_directory]/suspicious_logins.log"
GLOB.world_mecha_log = "[GLOB.log_directory]/mecha.log"
GLOB.world_virus_log = "[GLOB.log_directory]/virus.log"
diff --git a/code/modules/jobs/job_types/ai.dm b/code/modules/jobs/job_types/ai.dm
index 6a0dab256c5..11a5792c26d 100644
--- a/code/modules/jobs/job_types/ai.dm
+++ b/code/modules/jobs/job_types/ai.dm
@@ -30,6 +30,8 @@
for(var/mob/living/silicon/robot/R in GLOB.silicon_mobs)
if(!R.connected_ai)
R.TryConnectToAI()
+ var/mob/living/silicon/ai/ai_spawn = spawned
+ ai_spawn.log_current_laws()
/datum/job/ai/get_roundstart_spawn_point()
diff --git a/code/modules/jobs/job_types/cyborg.dm b/code/modules/jobs/job_types/cyborg.dm
index 56806bcc676..82f72a688f6 100644
--- a/code/modules/jobs/job_types/cyborg.dm
+++ b/code/modules/jobs/job_types/cyborg.dm
@@ -28,7 +28,8 @@
spawned.gender = NEUTER
var/mob/living/silicon/robot/robot_spawn = spawned
robot_spawn.notify_ai(AI_NOTIFICATION_NEW_BORG)
-
+ if(!robot_spawn.connected_ai) // Only log if there's no Master AI
+ robot_spawn.log_current_laws()
/datum/job/cyborg/radio_help_message(mob/M)
to_chat(M, "Prefix your message with :b to speak with other cyborgs and AI.")
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 44069e741ec..0a8c68180fa 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -165,9 +165,13 @@
deploy_action.Grant(src)
if(isturf(loc))
- add_verb(src, list(/mob/living/silicon/ai/proc/ai_network_change, /mob/living/silicon/ai/proc/ai_hologram_change, \
- /mob/living/silicon/ai/proc/botcall, /mob/living/silicon/ai/proc/control_integrated_radio, \
- /mob/living/silicon/ai/proc/set_automatic_say_channel))
+ add_verb(src, list(
+ /mob/living/silicon/ai/proc/ai_network_change,
+ /mob/living/silicon/ai/proc/ai_hologram_change,
+ /mob/living/silicon/ai/proc/botcall,
+ /mob/living/silicon/ai/proc/control_integrated_radio,
+ /mob/living/silicon/ai/proc/set_automatic_say_channel,
+ ))
GLOB.ai_list += src
GLOB.shuttle_caller_list += src
diff --git a/code/modules/mob/living/silicon/laws.dm b/code/modules/mob/living/silicon/laws.dm
index ae9392c5cd6..735b59c1c74 100644
--- a/code/modules/mob/living/silicon/laws.dm
+++ b/code/modules/mob/living/silicon/laws.dm
@@ -5,6 +5,11 @@
if (!laws)
make_laws()
+/mob/living/silicon/proc/log_current_laws()
+ var/list/the_laws = laws.get_law_list(include_zeroth = TRUE)
+ var/lawtext = the_laws.Join(" ")
+ log_silicon("LAW: [key_name(src)] spawned with [lawtext]")
+
/mob/living/silicon/proc/deadchat_lawchange()
var/list/the_laws = laws.get_law_list(include_zeroth = TRUE)
var/lawtext = the_laws.Join("
")
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 994156b33fa..717b37ebcad 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -176,11 +176,13 @@
to_chat(src,span_userdanger("ERROR: Model installer reply timeout. Please check internal connections."))
return
- var/list/model_list = list("Engineering" = /obj/item/robot_model/engineering, \
- "Medical" = /obj/item/robot_model/medical, \
- "Miner" = /obj/item/robot_model/miner, \
- "Janitor" = /obj/item/robot_model/janitor, \
- "Service" = /obj/item/robot_model/service)
+ var/list/model_list = list(
+ "Engineering" = /obj/item/robot_model/engineering,
+ "Medical" = /obj/item/robot_model/medical,
+ "Miner" = /obj/item/robot_model/miner,
+ "Janitor" = /obj/item/robot_model/janitor,
+ "Service" = /obj/item/robot_model/service,
+ )
if(!CONFIG_GET(flag/disable_peaceborg))
model_list["Peacekeeper"] = /obj/item/robot_model/peacekeeper
if(!CONFIG_GET(flag/disable_secborg))
@@ -365,6 +367,7 @@
message_admins(span_notice("[ADMIN_LOOKUPFLW(usr)] detonated [key_name_admin(src, client)] at [ADMIN_VERBOSEJMP(groundzero)]!"))
log_game("[key_name(usr)] detonated [key_name(src)]!")
log_combat(usr, src, "detonated cyborg")
+ log_silicon("CYBORG: [key_name(src)] has been detonated by [key_name(usr)].")
if(connected_ai)
to_chat(connected_ai, "
[span_alert("ALERT - Cyborg detonation detected: [name]")]
")
@@ -380,6 +383,7 @@
lawupdate = FALSE
set_lockcharge(FALSE)
scrambledcodes = TRUE
+ log_silicon("CYBORG: [key_name(src)] has been unlinked from an AI.")
//Disconnect it's camera so it's not so easily tracked.
if(!QDELETED(builtInCamera))
QDEL_NULL(builtInCamera)
@@ -694,6 +698,7 @@
hasAffection = FALSE //Just so they can get the affection modules back if they want them.
//SKYRAT EDIT ADDITION END
logevent("Chassis model has been reset.")
+ log_silicon("CYBORG: [key_name(src)] has reset their cyborg model.")
model.transform_to(/obj/item/robot_model)
// Remove upgrades.
diff --git a/code/modules/mob/living/silicon/robot/robot_defense.dm b/code/modules/mob/living/silicon/robot/robot_defense.dm
index 02533040c81..11f94a5361e 100644
--- a/code/modules/mob/living/silicon/robot/robot_defense.dm
+++ b/code/modules/mob/living/silicon/robot/robot_defense.dm
@@ -339,12 +339,12 @@ GLOBAL_LIST_INIT(blacklisted_borg_hats, typecacheof(list( //Hats that don't real
to_chat(src, span_danger("ALERT: Foreign software execution prevented."))
logevent("ALERT: Foreign software execution prevented.")
to_chat(connected_ai, span_danger("ALERT: Cyborg unit \[[src]\] successfully defended against subversion."))
- log_game("[key_name(user)] attempted to emag cyborg [key_name(src)], but they were slaved to traitor AI [connected_ai].")
+ log_silicon("EMAG: [key_name(user)] attempted to emag cyborg [key_name(src)], but they were slaved to traitor AI [connected_ai].")
return
if(shell) //AI shells cannot be emagged, so we try to make it look like a standard reset. Smart players may see through this, however.
to_chat(user, span_danger("[src] is remotely controlled! Your emag attempt has triggered a system reset instead!"))
- log_game("[key_name(user)] attempted to emag an AI shell belonging to [key_name(src) ? key_name(src) : connected_ai]. The shell has been reset as a result.")
+ log_silicon("EMAG: [key_name(user)] attempted to emag an AI shell belonging to [key_name(src) ? key_name(src) : connected_ai]. The shell has been reset as a result.")
ResetModel()
return
@@ -353,7 +353,7 @@ GLOBAL_LIST_INIT(blacklisted_borg_hats, typecacheof(list( //Hats that don't real
lawupdate = FALSE
set_connected_ai(null)
message_admins("[ADMIN_LOOKUPFLW(user)] emagged cyborg [ADMIN_LOOKUPFLW(src)]. Laws overridden.")
- log_game("[key_name(user)] emagged cyborg [key_name(src)]. Laws overridden.")
+ log_silicon("EMAG: [key_name(user)] emagged cyborg [key_name(src)]. Laws overridden.")
var/time = time2text(world.realtime,"hh:mm:ss")
if(user)
GLOB.lawchanges.Add("[time] : [user.name]([user.key]) emagged [name]([key])")
diff --git a/code/modules/mob/living/silicon/robot/robot_model.dm b/code/modules/mob/living/silicon/robot/robot_model.dm
index 5b6e496d10e..04f1392c54c 100644
--- a/code/modules/mob/living/silicon/robot/robot_model.dm
+++ b/code/modules/mob/living/silicon/robot/robot_model.dm
@@ -188,6 +188,7 @@
new_model.rebuild_modules()
cyborg.radio.recalculateChannels()
cyborg.set_modularInterface_theme()
+ log_silicon("CYBORG: [key_name(cyborg)] has transformed into the [new_model] model.")
//SKYRAT EDIT ADDITION BEGIN - ALTBORGS - Old check for 'dogborg' var no longer necessary, refactored into model_features instead.
if(cyborg.is_dogborg()) //Should pass because model was set previously.
diff --git a/config/config.txt b/config/config.txt
index e7671546e72..bba6efc2f09 100644
--- a/config/config.txt
+++ b/config/config.txt
@@ -139,8 +139,8 @@ LOG_TELECOMMS
## log prayers
LOG_PRAYER
-## log lawchanges
-LOG_LAW
+## log silicons
+LOG_SILICON
## log economy actions
LOG_ECON