diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index 039dae59696..415536e45c5 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -1145,6 +1145,7 @@
if(has_antag_datum(/datum/antagonist/traitor))
to_chat(current, "You have been brainwashed! You are no longer a traitor!")
remove_antag_datum(/datum/antagonist/traitor)
+ current.client.chatOutput?.clear_syndicate_codes()
log_admin("[key_name(usr)] has de-traitored [key_name(current)]")
message_admins("[key_name_admin(usr)] has de-traitored [key_name_admin(current)]")
diff --git a/code/defines/procs/announce.dm b/code/defines/procs/announce.dm
index a2b80440ecb..ba5320cfdb3 100644
--- a/code/defines/procs/announce.dm
+++ b/code/defines/procs/announce.dm
@@ -109,7 +109,7 @@ GLOBAL_DATUM_INIT(event_announcement, /datum/announcement/priority/command/event
/datum/announcement/proc/Format_Message(message, message_title, message_announcer, from)
var/formatted_message
formatted_message += "
[message_title]
"
- formatted_message += "
[message]"
+ formatted_message += "
[message]"
if(message_announcer)
formatted_message += "
-[message_announcer]"
@@ -125,7 +125,7 @@ GLOBAL_DATUM_INIT(event_announcement, /datum/announcement/priority/command/event
/datum/announcement/priority/Format_Message(message, message_title, message_announcer, from)
var/formatted_message
formatted_message += "[message_title]
"
- formatted_message += "
[message]"
+ formatted_message += "
[message]"
if(message_announcer)
formatted_message += "
-[message_announcer]"
formatted_message += "
"
@@ -136,7 +136,7 @@ GLOBAL_DATUM_INIT(event_announcement, /datum/announcement/priority/command/event
var/formatted_message
formatted_message += "[from]
"
if(message_title)
- formatted_message += "
[message_title]
"
+ formatted_message += "
[message_title]
"
formatted_message += "
[message]
"
formatted_message += "
"
diff --git a/code/modules/admin/secrets.dm b/code/modules/admin/secrets.dm
index cbda6699694..5cfd50a5ce9 100644
--- a/code/modules/admin/secrets.dm
+++ b/code/modules/admin/secrets.dm
@@ -23,6 +23,7 @@
Show Game Mode
Show Crew Manifest
Show current traitors and objectives
+ Show code phrases and responses
Set Night Shift Mode
Bombs
[check_rights(R_SERVER, 0) ? " Toggle bomb cap
" : "
"]
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index c1b77572a17..d715bbde697 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -3166,6 +3166,9 @@
usr << browse(dat, "window=manifest;size=440x410")
if("check_antagonist")
check_antagonists()
+ if("view_codewords")
+ to_chat(usr, "Code Phrases: [GLOB.syndicate_code_phrase]")
+ to_chat(usr, "Code Responses: [GLOB.syndicate_code_response]")
if("DNA")
var/dat = "Showing DNA from blood.
"
dat += "| Name | DNA | Blood Type |
"
diff --git a/code/modules/antagonists/traitor/datum_traitor.dm b/code/modules/antagonists/traitor/datum_traitor.dm
index 6275c00ba9b..0368957ac11 100644
--- a/code/modules/antagonists/traitor/datum_traitor.dm
+++ b/code/modules/antagonists/traitor/datum_traitor.dm
@@ -288,14 +288,16 @@
var/responses = jointext(GLOB.syndicate_code_response, ", ")
to_chat(traitor_mob, "The Syndicate have provided you with the following codewords to identify fellow agents:")
- to_chat(traitor_mob, "Code Phrase: [phrases]")
- to_chat(traitor_mob, "Code Response: [responses]")
+ to_chat(traitor_mob, "Code Phrase: [phrases]")
+ to_chat(traitor_mob, "Code Response: [responses]")
antag_memory += "Code Phrase: [phrases]
"
antag_memory += "Code Response: [responses]
"
to_chat(traitor_mob, "Use the codewords during regular conversation to identify other agents. Proceed with caution, however, as everyone is a potential foe.")
+ to_chat(traitor_mob, "You memorize the codewords, allowing you to recognize them when heard.")
+ traitor_mob.client.chatOutput?.notify_syndicate_codes()
/datum/antagonist/traitor/proc/add_law_zero()
var/mob/living/silicon/ai/killer = owner.current
diff --git a/goon/browserassets/css/browserOutput-dark.css b/goon/browserassets/css/browserOutput-dark.css
index fe227e96410..89a5a2d2e29 100644
--- a/goon/browserassets/css/browserOutput-dark.css
+++ b/goon/browserassets/css/browserOutput-dark.css
@@ -422,3 +422,7 @@ h1.alert, h2.alert {color: #FFF;}
.adminticket {color: #3daf21; font-weight: bold}
.adminticketalt {color: #ccb847; font-weight: bold}
+
+/* Syndicate codewords */
+span.body > .codephrases {color: #5555FF;}
+span.body > .coderesponses {color: #FF3333;}
diff --git a/goon/browserassets/css/browserOutput.css b/goon/browserassets/css/browserOutput.css
index 8a1ded41e57..abc99d8ce2d 100644
--- a/goon/browserassets/css/browserOutput.css
+++ b/goon/browserassets/css/browserOutput.css
@@ -421,3 +421,7 @@ h1.alert, h2.alert {color: #000000;}
.adminticket {color: #3e7336; font-weight: bold}
.adminticketalt {color: #014c8a; font-weight: bold}
+
+/* Syndicate codewords */
+span.body > .codephrases {color: #0000FF;}
+span.body > .coderesponses {color: #FF0000;}
diff --git a/goon/browserassets/js/browserOutput.js b/goon/browserassets/js/browserOutput.js
index c6abc0ec22f..24b3d6fdc63 100644
--- a/goon/browserassets/js/browserOutput.js
+++ b/goon/browserassets/js/browserOutput.js
@@ -72,7 +72,11 @@ var opts = {
'enableEmoji': true,
// Reboot message stuff
- 'rebootIntervalHandler': null
+ 'rebootIntervalHandler': null,
+
+ // Syndicate codewords
+ 'codePhrases': [],
+ 'codeResponses': []
};
var regexHasError = false; //variable to check if regex has excepted
@@ -186,11 +190,18 @@ function highlightTerms(el) {
if (regexHasError) return; //just stop right there ig the regex is gonna except
- function highlightRecursor(element, term){ //recursor function to do the highlighting proper
+ function highlightRecursor(element, term, className){ //recursor function to do the highlighting proper
var regex = new RegExp(term, "gi");
- function replace(str) {
- return str.replace(regex, '$&');
+ var replace;
+ if (className) {
+ replace = function(str) {
+ return str.replace(regex, '$&');
+ };
+ } else {
+ replace = function(str) {
+ return str.replace(regex, '$&');
+ };
}
var s = '';
@@ -244,6 +255,14 @@ function highlightTerms(el) {
}
}
}
+
+ // Code phrases
+ for (var i = 0; i < opts.codePhrases.length; i++) {
+ highlightRecursor(el, escapeRegexCharacters(opts.codePhrases[i]), "codephrases");
+ }
+ for (var i = 0; i < opts.codeResponses.length; i++) {
+ highlightRecursor(el, escapeRegexCharacters(opts.codeResponses[i]), "coderesponses");
+ }
}
//Send a message to the client
@@ -604,6 +623,22 @@ function rebootFinished() {
$("#reconnectTimer").remove();
}
+function codewords(phrases, responses) {
+ function cleanCodewords(words) {
+ var arr = [];
+ for (var i in words) {
+ var trimmed = words[i].trim();
+ if (trimmed.length > 0) {
+ arr.push(trimmed);
+ }
+ }
+ return arr;
+ }
+
+ opts.codePhrases = cleanCodewords(phrases.split(","));
+ opts.codeResponses = cleanCodewords(responses.split(","));
+}
+
/*****************************************
*
* MAKE MACRO DICTIONARY
diff --git a/goon/code/datums/browserOutput.dm b/goon/code/datums/browserOutput.dm
index d901f351785..11aca69220b 100644
--- a/goon/code/datums/browserOutput.dm
+++ b/goon/code/datums/browserOutput.dm
@@ -112,6 +112,10 @@ var/list/chatResources = list(
owner << output(null, "browseroutput:rebootFinished")
if(owner.holder)
loadAdmin()
+ if(owner.mob?.mind?.has_antag_datum(/datum/antagonist/traitor))
+ notify_syndicate_codes() // Send them the current round's codewords
+ else
+ clear_syndicate_codes() // Flush any codewords they may have in chat
for(var/message in messageQueue)
to_chat(owner, message)
@@ -198,6 +202,24 @@ var/list/chatResources = list(
error = "\[[time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")]\] Client : [owner.key ? owner.key : owner] triggered JS error: [error]"
chatDebug << error
+/**
+ * Sends the lists of code phrases and responses to Goonchat for clientside highlighting
+ *
+ * Arguments:
+ * * phrases - List of code phrases
+ * * responses - List of code responses
+ */
+/datum/chatOutput/proc/notify_syndicate_codes(phrases = GLOB.syndicate_code_phrase, responses = GLOB.syndicate_code_response)
+ var/urlphrases = url_encode(copytext(phrases, 1, length(phrases)))
+ var/urlresponses = url_encode(copytext(responses, 1, length(responses)))
+ owner << output("[urlphrases]&[urlresponses]", "browseroutput:codewords")
+
+/**
+ * Clears any locally stored code phrases to highlight
+ */
+/datum/chatOutput/proc/clear_syndicate_codes()
+ notify_syndicate_codes("", "")
+
/client/verb/debug_chat()
set hidden = 1
chatOutput.ehjax_send(data = list("firebug" = 1))