You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
520 lines
11 KiB
520 lines
11 KiB
// |
|
// HPB bot - botman's High Ping Bastard bot |
|
// |
|
// (http://planethalflife.com/botman/) |
|
// |
|
// bot_combat.cpp |
|
// |
|
|
|
#include "extdll.h" |
|
#include "util.h" |
|
#include "cbase.h" |
|
|
|
#include "bot.h" |
|
|
|
|
|
#define NUM_TAGS 22 |
|
|
|
char *tag1[NUM_TAGS]={ |
|
"-=","-[","-]","-}","-{","<[","<]","[-","]-","{-","}-","[[","[","{","]","}","<",">","-","|","=","+"}; |
|
char *tag2[NUM_TAGS]={ |
|
"=-","]-","[-","{-","}-","]>","[>","-]","-[","-}","-{","]]","]","}","[","{",">","<","-","|","=","+"}; |
|
|
|
int bot_chat_count; |
|
int bot_taunt_count; |
|
int bot_whine_count; |
|
|
|
bot_chat_t bot_chat[MAX_BOT_CHAT]; |
|
bot_chat_t bot_taunt[MAX_BOT_CHAT]; |
|
bot_chat_t bot_whine[MAX_BOT_CHAT]; |
|
|
|
int recent_bot_chat[5]; |
|
int recent_bot_taunt[5]; |
|
int recent_bot_whine[5]; |
|
|
|
int player_count; |
|
char player_names[32][33]; // 32 players max, 32 chars + null |
|
|
|
extern int bot_chat_tag_percent; |
|
extern int bot_chat_drop_percent; |
|
extern int bot_chat_swap_percent; |
|
extern int bot_chat_lower_percent; |
|
|
|
|
|
void LoadBotChat(void) |
|
{ |
|
FILE *bfp; |
|
char filename[256]; |
|
char buffer[256]; |
|
char *stat; |
|
int section = -1; |
|
int i, length; |
|
|
|
bot_chat_count = 0; |
|
bot_taunt_count = 0; |
|
bot_whine_count = 0; |
|
|
|
for (i=0; i < 5; i++) |
|
{ |
|
recent_bot_chat[i] = -1; |
|
recent_bot_taunt[i] = -1; |
|
recent_bot_whine[i] = -1; |
|
} |
|
|
|
UTIL_BuildFileName(filename, "HPB_bot_chat.txt", NULL); |
|
|
|
bfp = fopen(filename, "r"); |
|
|
|
while (bfp != NULL) |
|
{ |
|
stat = fgets(buffer, 80, bfp); |
|
|
|
if (stat == NULL) |
|
{ |
|
fclose(bfp); |
|
bfp = NULL; |
|
continue; |
|
} |
|
|
|
buffer[80] = 0; // truncate lines longer than 80 characters |
|
|
|
length = strlen(buffer); |
|
|
|
if (buffer[length-1] == '\n') |
|
{ |
|
buffer[length-1] = 0; // remove '\n' |
|
length--; |
|
} |
|
|
|
if (strcmp(buffer, "[bot_chat]") == 0) |
|
{ |
|
section = 0; |
|
continue; |
|
} |
|
|
|
if (strcmp(buffer, "[bot_taunt]") == 0) |
|
{ |
|
section = 1; |
|
continue; |
|
} |
|
|
|
if (strcmp(buffer, "[bot_whine]") == 0) |
|
{ |
|
section = 2; |
|
continue; |
|
} |
|
|
|
if ((length > 0) && (section == 0) && // bot chat |
|
(bot_chat_count < MAX_BOT_CHAT)) |
|
{ |
|
if (buffer[0] == '!') |
|
{ |
|
strcpy(bot_chat[bot_chat_count].text, &buffer[1]); |
|
bot_chat[bot_chat_count].can_modify = FALSE; |
|
} |
|
else |
|
{ |
|
strcpy(bot_chat[bot_chat_count].text, buffer); |
|
bot_chat[bot_chat_count].can_modify = TRUE; |
|
} |
|
|
|
bot_chat_count++; |
|
} |
|
|
|
if ((length > 0) && (section == 1) && // bot taunt |
|
(bot_taunt_count < MAX_BOT_CHAT)) |
|
{ |
|
if (buffer[0] == '!') |
|
{ |
|
strcpy(bot_taunt[bot_taunt_count].text, &buffer[1]); |
|
bot_taunt[bot_taunt_count].can_modify = FALSE; |
|
} |
|
else |
|
{ |
|
strcpy(bot_taunt[bot_taunt_count].text, buffer); |
|
bot_taunt[bot_taunt_count].can_modify = TRUE; |
|
} |
|
|
|
bot_taunt_count++; |
|
} |
|
|
|
if ((length > 0) && (section == 2) && // bot whine |
|
(bot_whine_count < MAX_BOT_CHAT)) |
|
{ |
|
if (buffer[0] == '!') |
|
{ |
|
strcpy(bot_whine[bot_whine_count].text, &buffer[1]); |
|
bot_whine[bot_whine_count].can_modify = FALSE; |
|
} |
|
else |
|
{ |
|
strcpy(bot_whine[bot_whine_count].text, buffer); |
|
bot_whine[bot_whine_count].can_modify = TRUE; |
|
} |
|
|
|
bot_whine_count++; |
|
} |
|
} |
|
} |
|
|
|
|
|
void BotTrimBlanks(char *in_string, char *out_string) |
|
{ |
|
int i, pos; |
|
char *dest; |
|
|
|
pos=0; |
|
while ((pos < 80) && (in_string[pos] == ' ')) // skip leading blanks |
|
pos++; |
|
|
|
dest=&out_string[0]; |
|
|
|
while ((pos < 80) && (in_string[pos])) |
|
{ |
|
*dest++ = in_string[pos]; |
|
pos++; |
|
} |
|
*dest = 0; // store the null |
|
|
|
i = strlen(out_string) - 1; |
|
while ((i > 0) && (out_string[i] == ' ')) // remove trailing blanks |
|
{ |
|
out_string[i] = 0; |
|
i--; |
|
} |
|
} |
|
|
|
|
|
int BotChatTrimTag(char *original_name, char *out_name) |
|
{ |
|
int i; |
|
char *pos1, *pos2, *src, *dest; |
|
char in_name[80]; |
|
int result = 0; |
|
|
|
strncpy(in_name, original_name, 31); |
|
in_name[32] = 0; |
|
|
|
for (i=0; i < NUM_TAGS; i++) |
|
{ |
|
pos1=strstr(in_name, tag1[i]); |
|
if (pos1) |
|
pos2=strstr(pos1+strlen(tag1[i]), tag2[i]); |
|
else |
|
pos2 = NULL; |
|
|
|
if (pos1 && pos2 && pos1 < pos2) |
|
{ |
|
src = pos2+strlen(tag2[i]); |
|
dest = pos1; |
|
while (*src) |
|
*dest++ = *src++; |
|
*dest = *src; // copy the null; |
|
|
|
result = 1; |
|
} |
|
} |
|
|
|
strcpy(out_name, in_name); |
|
|
|
BotTrimBlanks(out_name, in_name); |
|
|
|
if (strlen(in_name) == 0) // is name just a tag? |
|
{ |
|
strncpy(in_name, original_name, 31); |
|
in_name[32] = 0; |
|
|
|
// strip just the tag part... |
|
for (i=0; i < NUM_TAGS; i++) |
|
{ |
|
pos1=strstr(in_name, tag1[i]); |
|
if (pos1) |
|
pos2=strstr(pos1+strlen(tag1[i]), tag2[i]); |
|
else |
|
pos2 = NULL; |
|
|
|
if (pos1 && pos2 && pos1 < pos2) |
|
{ |
|
src = pos1 + strlen(tag1[i]); |
|
dest = pos1; |
|
while (*src) |
|
*dest++ = *src++; |
|
*dest = *src; // copy the null; |
|
|
|
src = pos2 - strlen(tag2[i]); |
|
*src = 0; // null out the rest of the string |
|
} |
|
} |
|
} |
|
|
|
BotTrimBlanks(in_name, out_name); |
|
|
|
out_name[31] = 0; |
|
|
|
return (result); |
|
} |
|
|
|
|
|
void BotDropCharacter(char *in_string, char *out_string) |
|
{ |
|
int len, pos; |
|
int count = 0; |
|
char *src, *dest; |
|
bool is_bad; |
|
|
|
strcpy(out_string, in_string); |
|
|
|
len = strlen(out_string); |
|
pos = RANDOM_LONG(1, len-1); // don't drop position zero |
|
|
|
is_bad = !isalpha(out_string[pos]) || (out_string[pos-1] == '%'); |
|
|
|
while ((is_bad) && (count < 20)) |
|
{ |
|
pos = RANDOM_LONG(1, len-1); |
|
is_bad = !isalpha(out_string[pos]) || (out_string[pos-1] == '%'); |
|
count++; |
|
} |
|
|
|
if (count < 20) |
|
{ |
|
src = &out_string[pos+1]; |
|
dest = &out_string[pos]; |
|
while (*src) |
|
*dest++ = *src++; |
|
*dest = *src; // copy the null; |
|
} |
|
} |
|
|
|
|
|
void BotSwapCharacter(char *in_string, char *out_string) |
|
{ |
|
int len, pos; |
|
int count = 0; |
|
char temp; |
|
bool is_bad; |
|
|
|
strcpy(out_string, in_string); |
|
|
|
len = strlen(out_string); |
|
pos = RANDOM_LONG(1, len-2); // don't swap position zero |
|
|
|
is_bad = !isalpha(out_string[pos]) || !isalpha(out_string[pos+1]) || |
|
(out_string[pos-1] == '%'); |
|
|
|
while ((is_bad) && (count < 20)) |
|
{ |
|
pos = RANDOM_LONG(1, len-2); |
|
is_bad = !isalpha(out_string[pos]) || !isalpha(out_string[pos+1]) || |
|
(out_string[pos-1] == '%'); |
|
count++; |
|
} |
|
|
|
if (count < 20) |
|
{ |
|
temp = out_string[pos]; |
|
out_string[pos] = out_string[pos+1]; |
|
out_string[pos+1] = temp; |
|
} |
|
} |
|
|
|
|
|
void BotChatName(char *original_name, char *out_name) |
|
{ |
|
int pos; |
|
|
|
if (RANDOM_LONG(1, 100) <= bot_chat_tag_percent) |
|
{ |
|
char temp_name[80]; |
|
|
|
strncpy(temp_name, original_name, 31); |
|
temp_name[31] = 0; |
|
|
|
while (BotChatTrimTag(temp_name, out_name)) |
|
{ |
|
strcpy(temp_name, out_name); |
|
} |
|
} |
|
else |
|
{ |
|
strncpy(out_name, original_name, 31); |
|
out_name[31] = 0; |
|
} |
|
|
|
if (RANDOM_LONG(1, 100) <= bot_chat_lower_percent) |
|
{ |
|
pos=0; |
|
while ((pos < 80) && (out_name[pos])) |
|
{ |
|
out_name[pos] = tolower(out_name[pos]); |
|
pos++; |
|
} |
|
} |
|
} |
|
|
|
|
|
void BotChatText(char *in_text, char *out_text) |
|
{ |
|
int pos; |
|
char temp_text[81]; |
|
int count; |
|
|
|
strncpy(temp_text, in_text, 79); |
|
temp_text[80] = 0; |
|
|
|
if (RANDOM_LONG(1, 100) <= bot_chat_drop_percent) |
|
{ |
|
count = RANDOM_LONG(1, 3); |
|
|
|
while (count) |
|
{ |
|
BotDropCharacter(temp_text, out_text); |
|
strcpy(temp_text, out_text); |
|
count--; |
|
} |
|
} |
|
|
|
if (RANDOM_LONG(1, 100) <= bot_chat_swap_percent) |
|
{ |
|
count = RANDOM_LONG(1, 2); |
|
|
|
while (count) |
|
{ |
|
BotSwapCharacter(temp_text, out_text); |
|
strcpy(temp_text, out_text); |
|
count--; |
|
} |
|
} |
|
|
|
if (RANDOM_LONG(1, 100) <= bot_chat_lower_percent) |
|
{ |
|
pos=0; |
|
while (temp_text[pos]) |
|
{ |
|
temp_text[pos] = tolower(temp_text[pos]); |
|
pos++; |
|
} |
|
} |
|
|
|
strcpy(out_text, temp_text); |
|
} |
|
|
|
|
|
void BotChatGetPlayers(void) |
|
{ |
|
int index; |
|
const char *pName; |
|
|
|
player_count = 0; |
|
|
|
for (index = 1; index <= gpGlobals->maxClients; index++) |
|
{ |
|
edict_t *pPlayer = INDEXENT(index); |
|
|
|
// skip invalid players |
|
if ((pPlayer) && (!pPlayer->free)) |
|
{ |
|
if (pPlayer->v.netname) |
|
{ |
|
pName = STRING(pPlayer->v.netname); |
|
|
|
if (*pName != 0) |
|
{ |
|
strncpy(player_names[player_count], pName, 32); |
|
|
|
player_count++; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
|
|
void BotChatFillInName(char *bot_say_msg, char *chat_text, |
|
char *chat_name, const char *bot_name) |
|
{ |
|
int chat_index, say_index; |
|
char *name_pos, *rand_pos; |
|
char random_name[64]; |
|
int index, name_offset, rand_offset; |
|
bool is_bad; |
|
|
|
chat_index = 0; |
|
say_index = 0; |
|
bot_say_msg[0] = 0; |
|
|
|
name_pos = strstr(&chat_text[chat_index], "%n"); |
|
rand_pos = strstr(&chat_text[chat_index], "%r"); |
|
|
|
while ((name_pos != NULL) || (rand_pos != NULL)) |
|
{ |
|
if (name_pos != NULL) |
|
name_offset = name_pos - chat_text; |
|
if (rand_pos != NULL) |
|
rand_offset = rand_pos - chat_text; |
|
|
|
if ((rand_pos == NULL) || |
|
((name_offset < rand_offset) && (name_pos != NULL))) |
|
{ |
|
while (&chat_text[chat_index] < name_pos) |
|
bot_say_msg[say_index++] = chat_text[chat_index++]; |
|
|
|
bot_say_msg[say_index] = 0; // add null terminator |
|
|
|
chat_index += 2; // skip the "%n" |
|
|
|
strcat(bot_say_msg, chat_name); |
|
say_index += strlen(chat_name); |
|
|
|
bot_say_msg[say_index] = 0; |
|
} |
|
else // use random player name... |
|
{ |
|
int count = 0; |
|
|
|
BotChatGetPlayers(); |
|
|
|
// pick a name at random from the list of players... |
|
|
|
index = RANDOM_LONG(0, player_count-1); |
|
|
|
is_bad = (strcmp(player_names[index], chat_name) == 0) || |
|
(strcmp(player_names[index], bot_name) == 0); |
|
|
|
while ((is_bad) && (count < 20)) |
|
{ |
|
index = RANDOM_LONG(0, player_count-1); |
|
|
|
is_bad = (strcmp(player_names[index], chat_name) == 0) || |
|
(strcmp(player_names[index], bot_name) == 0); |
|
|
|
count++; |
|
} |
|
|
|
BotChatName(player_names[index], random_name); |
|
|
|
while (&chat_text[chat_index] < rand_pos) |
|
bot_say_msg[say_index++] = chat_text[chat_index++]; |
|
|
|
bot_say_msg[say_index] = 0; // add null terminator |
|
|
|
chat_index += 2; // skip the "%r" |
|
|
|
strcat(bot_say_msg, random_name); |
|
say_index += strlen(random_name); |
|
|
|
bot_say_msg[say_index] = 0; |
|
} |
|
|
|
name_pos = strstr(&chat_text[chat_index], "%n"); |
|
rand_pos = strstr(&chat_text[chat_index], "%r"); |
|
} |
|
|
|
// copy the rest of the chat_text into the bot_say_msg... |
|
|
|
while (chat_text[chat_index]) |
|
bot_say_msg[say_index++] = chat_text[chat_index++]; |
|
|
|
bot_say_msg[say_index] = 0; // add null terminator |
|
} |
|
|
|
|