//---------------------------------------------------------------------------------------------------- // Radio format: assembles the chat line, colouring the sender's tag/name/text through // custom-chatcolors when it is loaded. Colour mapping mirrors custom-chatcolors.sp. //---------------------------------------------------------------------------------------------------- // Same prefix Leader3 puts on its own chat lines (Leader3.sp PREFIX). #define LEADER_PREFIX "\x07FF00E1[Leader] \x01" // ent_idx = author makes \x03 render as the author's team colour; the chat flag must be // true (the client's non-chat path mishandles raw coloured text); BLOCKHOOKS keeps chat // processors (CCC included) from re-processing our synthetic line. void Radio_SendChat(int author, const int[] players, int playersNum, const char[] text) { Handle say = StartMessage("SayText2", players, playersNum, USERMSG_RELIABLE | USERMSG_BLOCKHOOKS); BfWriteByte(say, author); BfWriteByte(say, 1); BfWriteString(say, text); EndMessage(); } static void ColorCode(int color, bool alpha, char[] out, int maxlen) { switch (color) { case COLOR_TEAM: strcopy(out, maxlen, "\x03"); case COLOR_CGREEN: strcopy(out, maxlen, "\x04"); case COLOR_OLIVE: strcopy(out, maxlen, "\x05"); case COLOR_NULL: out[0] = '\0'; case COLOR_NONE: strcopy(out, maxlen, "\x01"); default: { if (alpha) FormatEx(out, maxlen, "\x08%08X", color); else FormatEx(out, maxlen, "\x07%06X", color); } } } void Format_RadioLine(int client, bool leader, const char[] phrase, char[] out, int maxlen) { char sender[MAX_NAME_LENGTH + 96]; bool useCCC = g_bCCC && GetFeatureStatus(FeatureType_Native, "CCC_GetColor") == FeatureStatus_Available; if (useCCC) { // CCC stores tags in 64-byte buffers (custom-chatcolors.sp g_sTag) and a processed // tag can carry an inline \x07RRGGBB code per character, so match CCC's size. char tag[64], tagCode[16], nameCode[16]; bool alpha; CCC_GetTag(client, tag, sizeof(tag)); alpha = false; ColorCode(CCC_GetColor(client, CCC_TagColor, alpha), alpha, tagCode, sizeof(tagCode)); alpha = false; int nameColor = CCC_GetColor(client, CCC_NameColor, alpha); if (nameColor == COLOR_NULL && tag[0]) { // CCC name colour "X" (COLOR_NULL) erases the name so only the tag shows FormatEx(sender, sizeof(sender), "%s%s", tagCode, tag); } else { ColorCode(nameColor, alpha, nameCode, sizeof(nameCode)); if (tag[0]) FormatEx(sender, sizeof(sender), "%s%s%s%N", tagCode, tag, nameCode, client); else FormatEx(sender, sizeof(sender), "%s%N", nameCode, client); } } else { FormatEx(sender, sizeof(sender), "\x03%N", client); } char location[64]; GetEntPropString(client, Prop_Send, "m_szLastPlaceName", location, sizeof(location)); // Leading \x01 guards the CS:S quirk where a colour code as the very first byte may not // render; the \x01 before (RADIO): resets the line to the default orange, so the phrase // renders like a stock radio message regardless of the player's CCC chat colour. if (location[0]) { FormatEx(out, maxlen, "\x01%s%s \x01@ %s (RADIO): %s", leader ? LEADER_PREFIX : "", sender, location, phrase); } else { FormatEx(out, maxlen, "\x01%s%s \x01(RADIO): %s", leader ? LEADER_PREFIX : "", sender, phrase); } }