// find a pointer to a client with the specified name CClient *CServer::FindClientByName(const char *netname) { for (int i = 0; i < GetMaxClients(); i++) { CClient *pClient = m_rgpClients[i]; if (pClient && !strcmp(pClient->GetNetName(), netname)) return pClient; } return NULL; // client with this name is not found }
// 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 }
bool CServer::MessageWrite(void *p) { // return true if message is handled, false if not if (m_pCurrMsgClient) { if (m_pCurrMsgClient->MessageWrite(p)) { m_iCurrMsgState++; return true; } } static int message_WeaponList = -1; static int message_DeathMsg = -1; if (message_WeaponList == -1) { message_WeaponList = g_General.GetUserMsgId("WeaponList"); message_DeathMsg = g_General.GetUserMsgId("DeathMsg"); } if (m_iCurrMsgType == message_WeaponList) { static weaponinfo_t bot_weapon; if (m_iCurrMsgState == 0) strncpy(bot_weapon.szClassname, (char *)p, 64); else if (m_iCurrMsgState == 1) bot_weapon.iAmmo1 = *(int *)p; // ammo index 1 else if (m_iCurrMsgState == 2) bot_weapon.iMaxAmmo1 = *(int *)p; // max ammo1 else if (m_iCurrMsgState == 3) bot_weapon.iAmmo2 = *(int *)p; // ammo index 2 else if (m_iCurrMsgState == 4) bot_weapon.iMaxAmmo2 = *(int *)p; // max ammo2 else if (m_iCurrMsgState == 5) bot_weapon.iSlot = *(int *)p; // slot for this weapon else if (m_iCurrMsgState == 6) bot_weapon.iPosition = *(int *)p; // position in slot else if (m_iCurrMsgState == 7) bot_weapon.iId = *(int *)p; // weapon ID else if (m_iCurrMsgState == 8) { bot_weapon.iFlags = *(int *)p; // flags for weapon // store away this weapon with it's ammo information... g_General.m_rgWeaponDefs[bot_weapon.iId] = bot_weapon; } } else if (m_iCurrMsgType == message_DeathMsg) { static int killer_index; static int victim_index; if (m_iCurrMsgState == 0) { killer_index = *(int *)p - 1; // index of killer } else if (m_iCurrMsgState == 1) { victim_index = *(int *)p - 1; // index of victim if (killer_index >= 0 && victim_index >= 0 && killer_index < MAX_PLAYERS && victim_index < MAX_PLAYERS) { CClient *pKiller = m_rgpClients[killer_index]; CClient *pVictim = m_rgpClients[victim_index]; if (pKiller->IsBot()) { (dynamic_cast<CBaseBot *>(pKiller))->Chat()->m_strLastVictim = pVictim->GetNetName(); } if (pVictim->IsBot()) { (dynamic_cast<CBaseBot *>(pVictim))->Chat()->m_strLastVictim = pKiller->GetNetName(); } } } } else { return false; } m_iCurrMsgState++; return true; }
// 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 }