// Generate a reply message from the input message, and return the // pointer of the reply message char *CChatManager::GenerateReply(CBaseBot *pClient, CClient *pFrom, const char *msg) { static char message[256]; // for the reply message message[0] = '\0'; // initialize the string char *p; int i; // find a reply block with the correct keyword for (i = 0; i < m_ChatReply.size(); i++) { if (m_ChatReply[i].IsValidReply(msg)) break; } if (i >= m_ChatReply.size()) { // no replies for this sentence are found if (RandomLong(1, 100) > 50) { // about half the time use a general reply if ((p = GenerateChat(pClient, "GENERAL_REPLIES")) != NULL) { strncpy(message, p, 256); } else { return NULL; // No general replies } } else { return NULL; // don't reply to this message } } else { // we have replies for this sentence, generate the message now p = (char *)m_ChatReply[i].PickMessage(); if (!p) { return NULL; // no message is available, don't proceed } while (p && *p) { if (*p == '%') { char type = *(++p); // skip to next character to get the type int hiscore = -9999, j, count; CClient *pPickedClient = NULL; char buffer[32]; switch (type) { case '%': strncat(message, "%", 256); break; case 'n': // bot name strncpy(buffer, pClient->GetNetName(), 32); HumanizeName(buffer); strncat(message, buffer, 256); // append it to the message break; case 'r': // random opponent j = RandomLong(0, g_pServer->GetMaxClients()); for (count = 0; count < g_pServer->GetMaxClients(); count++, j++) { CClient *p = g_pServer->m_rgpClients[j]; if (p != pClient && p->IsValid()) { strncpy(buffer, p->GetNetName(), 32); HumanizeName(buffer); strncat(message, buffer, 256); // append it to the message break; } } if (count >= g_pServer->GetMaxClients()) return NULL; // can't find any player, don't say anything break; case 'f': // opponent in first place for (j = 0; j < g_pServer->GetMaxClients(); j++) { CClient *p = g_pServer->m_rgpClients[j]; if (p == pClient || !p->IsValid()) continue; if (p->GetFrags() >= hiscore) { hiscore = p->GetFrags(); pPickedClient = p; } } if (pPickedClient) { strncpy(buffer, pPickedClient->GetNetName(), 32); HumanizeName(buffer); // humanize the name strncat(message, buffer, 256); // append it to the message } else { return NULL; // can't find such a player, don't say anything } break; case 'l': // opponent in last place hiscore = 9999; for (j = 0; j < g_pServer->GetMaxClients(); j++) { CClient *p = g_pServer->m_rgpClients[j]; if (p == pClient || !p->IsValid()) continue; if (p->GetFrags() <= hiscore) { hiscore = p->GetFrags(); pPickedClient = p; } } if (pPickedClient) { strncpy(buffer, pPickedClient->GetNetName(), 32); HumanizeName(buffer); // humanize the name strncat(message, buffer, 256); // append it to the message } else { return NULL; // can't find such a player, don't say anything } break; case 'v': // last victim of this bot if (pClient->Chat()->m_strLastVictim.length() <= 0) return NULL; // we don't have a victim yet strncat(message, pClient->Chat()->m_strLastVictim.c_str(), 256); break; case 'k': // last player killed this bot if (pClient->Chat()->m_strLastKiller.length() <= 0) return NULL; // this bot hasn't been killed yet strncat(message, pClient->Chat()->m_strLastKiller.c_str(), 256); break; case 'm': // map title strncat(message, g_pServer->GetMapName(), 256); // get the map name break; // reply specific items case 's': // player to reply strncat(message, pFrom->GetNetName(), 256); break; } p++; // skip to the next character continue; } char *prev = p; p = strchr(p, '%'); // search for the next "%" sign if (p) { *p = '\0'; // if found, terminate the string } strncat(message, prev, 256); // append the remaining text if (p) { *p = '%'; // restore the '%' } } HumanizeChat(message); // 'humanize' the chat message } return message; // return the message }
// Generate a chat message from a specified message type, and return // the pointer of the generated message char *CChatManager::GenerateChat(CBaseBot *pClient, const char *type) { static char msg[256]; // for the chat message msg[0] = '\0'; // initialize the string unsigned short usCrc = CRC_Block((unsigned char *)type, strlen(type)); // find if we already have this section int found; for (found = 0; found < m_ChatItem.size(); found++) { if (m_ChatItem[found].type == usCrc) break; } if (found < m_ChatItem.size()) { char sz[256]; strncpy(sz, m_ChatItem[found].PickMessage(), 256); int length = strlen(sz); char *p = sz; while (p != NULL && *p) { if (*p == '%') { char type = *(++p); // skip to next character to get the type int hiscore = -9999, j, count; CClient *pPickedClient = NULL; char buffer[32]; switch (type) { case '%': strncat(msg, "%", 256); break; case 'n': // bot name strncpy(buffer, pClient->GetNetName(), 32); HumanizeName(buffer); strncat(msg, buffer, 256); // append it to the message break; case 'r': // random opponent j = RandomLong(0, g_pServer->GetMaxClients()); for (count = 0; count < g_pServer->GetMaxClients(); count++, j++) { CClient *p = g_pServer->m_rgpClients[j]; if (p != pClient && p->IsValid()) { strncpy(buffer, p->GetNetName(), 32); HumanizeName(buffer); strncat(msg, buffer, 256); // append it to the message break; } } if (count >= g_pServer->GetMaxClients()) return NULL; // can't find any player, don't say anything break; case 'f': // opponent in first place for (j = 0; j < g_pServer->GetMaxClients(); j++) { CClient *p = g_pServer->m_rgpClients[j]; if (p == pClient || !p->IsValid()) continue; if (p->GetFrags() >= hiscore) { hiscore = p->GetFrags(); pPickedClient = p; } } if (pPickedClient) { strncpy(buffer, pPickedClient->GetNetName(), 32); HumanizeName(buffer); // humanize the name strncat(msg, buffer, 256); // append it to the message } else { return NULL; // can't find such a player, don't say anything } break; case 'l': // opponent in last place hiscore = 9999; for (j = 0; j < g_pServer->GetMaxClients(); j++) { CClient *p = g_pServer->m_rgpClients[j]; if (p == pClient || !p->IsValid()) continue; if (p->GetFrags() <= hiscore) { hiscore = p->GetFrags(); pPickedClient = p; } } if (pPickedClient) { strncpy(buffer, pPickedClient->GetNetName(), 32); HumanizeName(buffer); // humanize the name strncat(msg, buffer, 256); // append it to the message } else { return NULL; // can't find such a player, don't say anything } break; case 'm': // map title strncat(msg, g_pServer->GetMapName(), 256); // get the map name break; case 'v': // last victim of this bot if (pClient->Chat()->m_strLastVictim.length() <= 0) return NULL; // we don't have a victim yet, don't say anything strncat(msg, pClient->Chat()->m_strLastVictim.c_str(), 256); break; case 'k': // last player killed this bot if (pClient->Chat()->m_strLastKiller.length() <= 0) return NULL; // this bot hasn't been killed yet, don't say anything strncat(msg, pClient->Chat()->m_strLastKiller.c_str(), 256); break; } p++; // skip to the next character continue; } char *prev = p; p = strchr(p, '%'); // search for the next "%" sign if (p) { *p = '\0'; // if found, terminate the string } strncat(msg, prev, 256); // append the remaining text if (p) { *p = '%'; // restore the '%' } } HumanizeChat(msg); // 'Humanize' the chat message return msg; } return NULL; // not found }