#include "../game/q_shared.h"
#include "l_memory.h"
#include "l_libvar.h"
#include "l_script.h"
#include "l_precomp.h"
#include "l_struct.h"
#include "l_utils.h"
#include "l_log.h"
#include "aasfile.h"
#include "../game/botlib.h"
#include "../game/be_aas.h"
#include "be_aas_funcs.h"
#include "be_interface.h"
#include "../game/be_ea.h"
#include "../game/be_ai_chat.h"
Include dependency graph for be_ai_chat.c:

Go to the source code of this file.
|
|
Definition at line 71 of file be_ai_chat.c. |
|
|
Definition at line 50 of file be_ai_chat.c. Referenced by BotLoadChatMessage(). |
|
|
Definition at line 59 of file be_ai_chat.c. |
|
|
Definition at line 58 of file be_ai_chat.c. |
|
|
Definition at line 61 of file be_ai_chat.c. Referenced by BotCheckValidReplyChatKeySet(). |
|
|
Definition at line 66 of file be_ai_chat.c. |
|
|
Definition at line 67 of file be_ai_chat.c. |
|
|
Definition at line 69 of file be_ai_chat.c. |
|
|
Definition at line 68 of file be_ai_chat.c. |
|
|
Definition at line 63 of file be_ai_chat.c. |
|
|
Definition at line 62 of file be_ai_chat.c. |
|
|
Definition at line 64 of file be_ai_chat.c. |
|
|
Definition at line 65 of file be_ai_chat.c. |
|
|
Referenced by BotCheckInitialChatIntegrety(), BotChooseInitialChatMessage(), BotDumpInitialChat(), and BotLoadInitialChat(). |
|
|
|
|
Referenced by BotCheckInitialChatIntegrety(), BotChooseInitialChatMessage(), BotDumpInitialChat(), BotLoadInitialChat(), and BotNumInitialChats(). |
|
|
Referenced by BotCheckValidReplyChatKeySet(), BotDumpMatchTemplates(), BotDumpReplyChat(), BotFreeMatchPieces(), BotLoadMatchPieces(), BotPrintReplyChatKeys(), and StringsMatch(). |
|
|
Referenced by BotCheckValidReplyChatKeySet(), BotDumpMatchTemplates(), BotFreeMatchPieces(), BotLoadMatchPieces(), and StringsMatch(). |
|
|
Referenced by BotDumpMatchTemplates(), BotFindMatch(), BotFreeMatchTemplates(), and BotLoadMatchTemplates(). |
|
|
Referenced by BotDumpRandomStringList(), BotLoadRandomStrings(), and RandomString(). |
|
|
Referenced by BotDumpRandomStringList(), BotLoadRandomStrings(), and RandomString(). |
|
|
Referenced by BotCheckReplyChatIntegrety(), BotDumpReplyChat(), BotFreeReplyChat(), BotLoadReplyChat(), BotPrintReplyChatKeys(), BotReplyChat(), and BotResetChatAI(). |
|
|
Referenced by BotCheckValidReplyChatKeySet(), BotDumpReplyChat(), BotFreeReplyChat(), BotLoadReplyChat(), BotPrintReplyChatKeys(), and BotReplyChat(). |
|
|
Referenced by BotCheckChatMessageIntegrety(), BotCheckInitialChatIntegrety(), BotCheckReplyChatIntegrety(), and BotFindStringInList(). |
|
|
Referenced by BotDumpSynonymList(), BotLoadSynonyms(), BotReplaceReplySynonyms(), BotReplaceSynonyms(), and BotReplaceWeightedSynonyms(). |
|
|
Referenced by BotDumpSynonymList(), BotLoadSynonyms(), BotReplaceReplySynonyms(), BotReplaceSynonyms(), and BotReplaceWeightedSynonyms(). |
|
|
Definition at line 268 of file be_ai_chat.c. References bot_consolemessage_t, freeconsolemessages, bot_consolemessage_s::next, and bot_consolemessage_s::prev. Referenced by BotQueueConsoleMessage(). 00269 {
00270 bot_consolemessage_t *message;
00271 message = freeconsolemessages;
00272 if (freeconsolemessages) freeconsolemessages = freeconsolemessages->next;
00273 if (freeconsolemessages) freeconsolemessages->prev = NULL;
00274 return message;
00275 } //end of the function AllocConsoleMessage
|
|
|
Definition at line 2895 of file be_ai_chat.c. References bot_chatstate_t, botchatstates, GetClearedMemory(), and i. 02896 {
02897 int i;
02898
02899 for (i = 1; i <= MAX_CLIENTS; i++)
02900 {
02901 if (!botchatstates[i])
02902 {
02903 botchatstates[i] = GetClearedMemory(sizeof(bot_chatstate_t));
02904 return i;
02905 } //end if
02906 } //end for
02907 return 0;
02908 } //end of the function BotAllocChatState
|
Here is the call graph for this function:

|
|
Definition at line 2771 of file be_ai_chat.c. References bot_chatstate_t, BotChatStateFromHandle(), bot_chatstate_s::chatmessage, and strlen(). 02772 {
02773 bot_chatstate_t *cs;
02774
02775 cs = BotChatStateFromHandle(chatstate);
02776 if (!cs) return 0;
02777 return strlen(cs->chatmessage);
02778 } //end of the function BotChatLength
|
Here is the call graph for this function:

|
|
Definition at line 219 of file be_ai_chat.c. References bot_chatstate_t, botchatstates, botimport, and PRT_FATAL. Referenced by BotChatLength(), BotEnterChat(), BotFreeChatFile(), BotGetChatMessage(), BotInitialChat(), BotLoadChatFile(), BotNextConsoleMessage(), BotNumConsoleMessages(), BotNumInitialChats(), BotQueueConsoleMessage(), BotRemoveConsoleMessage(), BotReplyChat(), BotSetChatGender(), and BotSetChatName(). 00220 {
00221 if (handle <= 0 || handle > MAX_CLIENTS)
00222 {
00223 botimport.Print(PRT_FATAL, "chat state handle %d out of range\n", handle);
00224 return NULL;
00225 } //end if
00226 if (!botchatstates[handle])
00227 {
00228 botimport.Print(PRT_FATAL, "invalid chat state %d\n", handle);
00229 return NULL;
00230 } //end if
00231 return botchatstates[handle];
00232 } //end of the function BotChatStateFromHandle
|
|
||||||||||||
|
Definition at line 1513 of file be_ai_chat.c. References bot_stringlist_t, BotFindStringInList(), botimport, GetClearedMemory(), i, Log_Write(), bot_stringlist_s::next, PRT_FATAL, RandomString(), s, strcpy(), bot_stringlist_s::string, and strlen(). Referenced by BotCheckInitialChatIntegrety(), and BotCheckReplyChatIntegrety(). 01514 {
01515 int i;
01516 char *msgptr;
01517 char temp[MAX_MESSAGE_SIZE];
01518 bot_stringlist_t *s;
01519
01520 msgptr = message;
01521 //
01522 while(*msgptr)
01523 {
01524 if (*msgptr == ESCAPE_CHAR)
01525 {
01526 msgptr++;
01527 switch(*msgptr)
01528 {
01529 case 'v': //variable
01530 {
01531 //step over the 'v'
01532 msgptr++;
01533 while(*msgptr && *msgptr != ESCAPE_CHAR) msgptr++;
01534 //step over the trailing escape char
01535 if (*msgptr) msgptr++;
01536 break;
01537 } //end case
01538 case 'r': //random
01539 {
01540 //step over the 'r'
01541 msgptr++;
01542 for (i = 0; (*msgptr && *msgptr != ESCAPE_CHAR); i++)
01543 {
01544 temp[i] = *msgptr++;
01545 } //end while
01546 temp[i] = '\0';
01547 //step over the trailing escape char
01548 if (*msgptr) msgptr++;
01549 //find the random keyword
01550 if (!RandomString(temp))
01551 {
01552 if (!BotFindStringInList(stringlist, temp))
01553 {
01554 Log_Write("%s = {\"%s\"} //MISSING RANDOM\r\n", temp, temp);
01555 s = GetClearedMemory(sizeof(bot_stringlist_t) + strlen(temp) + 1);
01556 s->string = (char *) s + sizeof(bot_stringlist_t);
01557 strcpy(s->string, temp);
01558 s->next = stringlist;
01559 stringlist = s;
01560 } //end if
01561 } //end if
01562 break;
01563 } //end case
01564 default:
01565 {
01566 botimport.Print(PRT_FATAL, "BotCheckChatMessageIntegrety: message \"%s\" invalid escape char\n", message);
01567 break;
01568 } //end default
01569 } //end switch
01570 } //end if
01571 else
01572 {
01573 msgptr++;
01574 } //end else
01575 } //end while
01576 return stringlist;
01577 } //end of the function BotCheckChatMessageIntegrety
|
Here is the call graph for this function:

|
|
Definition at line 1584 of file be_ai_chat.c. References bot_chat_t, bot_chatmessage_t, bot_chattype_t, bot_stringlist_t, BotCheckChatMessageIntegrety(), cm, bot_chattype_s::firstchatmessage, FreeMemory(), bot_stringlist_s::next, bot_chattype_s::next, s, t, and bot_chat_s::types. Referenced by BotLoadInitialChat(). 01585 {
01586 bot_chattype_t *t;
01587 bot_chatmessage_t *cm;
01588 bot_stringlist_t *stringlist, *s, *nexts;
01589
01590 stringlist = NULL;
01591 for (t = chat->types; t; t = t->next)
01592 {
01593 for (cm = t->firstchatmessage; cm; cm = cm->next)
01594 {
01595 stringlist = BotCheckChatMessageIntegrety(cm->chatmessage, stringlist);
01596 } //end for
01597 } //end for
01598 for (s = stringlist; s; s = nexts)
01599 {
01600 nexts = s->next;
01601 FreeMemory(s);
01602 } //end for
01603 } //end of the function BotCheckInitialChatIntegrety
|
Here is the call graph for this function:

|
|
Definition at line 1610 of file be_ai_chat.c. References bot_chatmessage_t, bot_replychat_t, bot_stringlist_t, BotCheckChatMessageIntegrety(), cm, bot_replychat_s::firstchatmessage, FreeMemory(), bot_stringlist_s::next, bot_replychat_s::next, and s. Referenced by BotLoadReplyChat(). 01611 {
01612 bot_replychat_t *rp;
01613 bot_chatmessage_t *cm;
01614 bot_stringlist_t *stringlist, *s, *nexts;
01615
01616 stringlist = NULL;
01617 for (rp = replychat; rp; rp = rp->next)
01618 {
01619 for (cm = rp->firstchatmessage; cm; cm = cm->next)
01620 {
01621 stringlist = BotCheckChatMessageIntegrety(cm->chatmessage, stringlist);
01622 } //end for
01623 } //end for
01624 for (s = stringlist; s; s = nexts)
01625 {
01626 nexts = s->next;
01627 FreeMemory(s);
01628 } //end for
01629 } //end of the function BotCheckReplyChatIntegrety
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 1721 of file be_ai_chat.c. References bot_matchpiece_t, bot_matchstring_t, bot_replychatkey_t, bot_matchpiece_s::firststring, bot_replychatkey_s::flags, m, bot_replychatkey_s::match, bot_matchstring_s::next, bot_matchpiece_s::next, bot_replychatkey_s::next, qfalse, RCKFL_AND, source, source_t, SourceWarning(), bot_replychatkey_s::string, bot_matchstring_s::string, StringContains(), and bot_matchpiece_s::type. Referenced by BotLoadReplyChat(). 01722 {
01723 int allprefixed, hasvariableskey, hasstringkey;
01724 bot_matchpiece_t *m;
01725 bot_matchstring_t *ms;
01726 bot_replychatkey_t *key, *key2;
01727
01728 //
01729 allprefixed = qtrue;
01730 hasvariableskey = hasstringkey = qfalse;
01731 for (key = keys; key; key = key->next)
01732 {
01733 if (!(key->flags & (RCKFL_AND|RCKFL_NOT)))
01734 {
01735 allprefixed = qfalse;
01736 if (key->flags & RCKFL_VARIABLES)
01737 {
01738 for (m = key->match; m; m = m->next)
01739 {
01740 if (m->type == MT_VARIABLE) hasvariableskey = qtrue;
01741 } //end for
01742 } //end if
01743 else if (key->flags & RCKFL_STRING)
01744 {
01745 hasstringkey = qtrue;
01746 } //end else if
01747 } //end if
01748 else if ((key->flags & RCKFL_AND) && (key->flags & RCKFL_STRING))
01749 {
01750 for (key2 = keys; key2; key2 = key2->next)
01751 {
01752 if (key2 == key) continue;
01753 if (key2->flags & RCKFL_NOT) continue;
01754 if (key2->flags & RCKFL_VARIABLES)
01755 {
01756 for (m = key2->match; m; m = m->next)
01757 {
01758 if (m->type == MT_STRING)
01759 {
01760 for (ms = m->firststring; ms; ms = ms->next)
01761 {
01762 if (StringContains(ms->string, key->string, qfalse) != -1)
01763 {
01764 break;
01765 } //end if
01766 } //end for
01767 if (ms) break;
01768 } //end if
01769 else if (m->type == MT_VARIABLE)
01770 {
01771 break;
01772 } //end if
01773 } //end for
01774 if (!m)
01775 {
01776 SourceWarning(source, "one of the match templates does not "
01777 "leave space for the key %s with the & prefix", key->string);
01778 } //end if
01779 } //end if
01780 } //end for
01781 } //end else
01782 if ((key->flags & RCKFL_NOT) && (key->flags & RCKFL_STRING))
01783 {
01784 for (key2 = keys; key2; key2 = key2->next)
01785 {
01786 if (key2 == key) continue;
01787 if (key2->flags & RCKFL_NOT) continue;
01788 if (key2->flags & RCKFL_STRING)
01789 {
01790 if (StringContains(key2->string, key->string, qfalse) != -1)
01791 {
01792 SourceWarning(source, "the key %s with prefix ! is inside the key %s", key->string, key2->string);
01793 } //end if
01794 } //end if
01795 else if (key2->flags & RCKFL_VARIABLES)
01796 {
01797 for (m = key2->match; m; m = m->next)
01798 {
01799 if (m->type == MT_STRING)
01800 {
01801 for (ms = m->firststring; ms; ms = ms->next)
01802 {
01803 if (StringContains(ms->string, key->string, qfalse) != -1)
01804 {
01805 SourceWarning(source, "the key %s with prefix ! is inside "
01806 "the match template string %s", key->string, ms->string);
01807 } //end if
01808 } //end for
01809 } //end if
01810 } //end for
01811 } //end else if
01812 } //end for
01813 } //end if
01814 } //end for
01815 if (allprefixed) SourceWarning(source, "all keys have a & or ! prefix");
01816 if (hasvariableskey && hasstringkey)
01817 {
01818 SourceWarning(source, "variables from the match template(s) could be "
01819 "invalid when outputting one of the chat messages");
01820 } //end if
01821 } //end of the function BotCheckValidReplyChatKeySet
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 2407 of file be_ai_chat.c. References AAS_Time(), bot_chat_t, bot_chatmessage_t, bot_chatstate_t, bot_chattype_t, bot_chatstate_s::chat, bot_chatmessage_s::chatmessage, bot_chattype_s::firstchatmessage, m, n, bot_chattype_s::name, bot_chatmessage_s::next, bot_chattype_s::next, Q_stricmp(), random, t, bot_chatmessage_s::time, type, and bot_chat_s::types. Referenced by BotInitialChat(). 02408 {
02409 int n, numchatmessages;
02410 float besttime;
02411 bot_chattype_t *t;
02412 bot_chatmessage_t *m, *bestchatmessage;
02413 bot_chat_t *chat;
02414
02415 chat = cs->chat;
02416 for (t = chat->types; t; t = t->next)
02417 {
02418 if (!Q_stricmp(t->name, type))
02419 {
02420 numchatmessages = 0;
02421 for (m = t->firstchatmessage; m; m = m->next)
02422 {
02423 if (m->time > AAS_Time()) continue;
02424 numchatmessages++;
02425 } //end if
02426 //if all chat messages have been used recently
02427 if (numchatmessages <= 0)
02428 {
02429 besttime = 0;
02430 bestchatmessage = NULL;
02431 for (m = t->firstchatmessage; m; m = m->next)
02432 {
02433 if (!besttime || m->time < besttime)
02434 {
02435 bestchatmessage = m;
02436 besttime = m->time;
02437 } //end if
02438 } //end for
02439 if (bestchatmessage) return bestchatmessage->chatmessage;
02440 } //end if
02441 else //choose a chat message randomly
02442 {
02443 n = random() * numchatmessages;
02444 for (m = t->firstchatmessage; m; m = m->next)
02445 {
02446 if (m->time > AAS_Time()) continue;
02447 if (--n < 0)
02448 {
02449 m->time = AAS_Time() + CHATMESSAGE_RECENTTIME;
02450 return m->chatmessage;
02451 } //end if
02452 } //end for
02453 } //end else
02454 return NULL;
02455 } //end if
02456 } //end for
02457 return NULL;
02458 } //end of the function BotChooseInitialChatMessage
|
Here is the call graph for this function:

|
||||||||||||||||||||||||||||
|
Definition at line 2379 of file be_ai_chat.c. References bot_chatstate_t, bot_match_t, BotExpandChatMessage(), botimport, bot_chatstate_s::chatmessage, i, match(), PRT_WARNING, and strcpy(). Referenced by BotInitialChat(), and BotReplyChat(). 02381 {
02382 int i;
02383 char srcmessage[MAX_MESSAGE_SIZE];
02384
02385 strcpy(srcmessage, message);
02386 for (i = 0; i < 10; i++)
02387 {
02388 if (!BotExpandChatMessage(chatstate->chatmessage, srcmessage, mcontext, match, vcontext, reply))
02389 {
02390 break;
02391 } //end if
02392 strcpy(srcmessage, chatstate->chatmessage);
02393 } //end for
02394 if (i >= 10)
02395 {
02396 botimport.Print(PRT_WARNING, "too many expansions in chat message\n");
02397 botimport.Print(PRT_WARNING, "%s\n", chatstate->chatmessage);
02398 } //end if
02399 } //end of the function BotConstructChatMessage
|
Here is the call graph for this function:

|
|
Definition at line 1988 of file be_ai_chat.c. References bot_chat_t, bot_chatmessage_t, bot_chattype_t, bot_chatmessage_s::chatmessage, bot_chattype_s::firstchatmessage, Log_Write(), m, bot_chattype_s::name, bot_chatmessage_s::next, bot_chattype_s::next, bot_chattype_s::numchatmessages, t, and bot_chat_s::types. 01989 {
01990 bot_chattype_t *t;
01991 bot_chatmessage_t *m;
01992
01993 Log_Write("{");
01994 for (t = chat->types; t; t = t->next)
01995 {
01996 Log_Write(" type \"%s\"", t->name);
01997 Log_Write(" {");
01998 Log_Write(" numchatmessages = %d", t->numchatmessages);
01999 for (m = t->firstchatmessage; m; m = m->next)
02000 {
02001 Log_Write(" \"%s\"", m->chatmessage);
02002 } //end for
02003 Log_Write(" }");
02004 } //end for
02005 Log_Write("}");
02006 } //end of the function BotDumpInitialChat
|
Here is the call graph for this function:

|
|
Definition at line 1077 of file be_ai_chat.c. References bot_matchpiece_t, bot_matchstring_t, bot_matchtemplate_t, bot_matchtemplate_s::first, bot_matchpiece_s::firststring, fp, fprintf(), Log_FilePointer(), bot_matchstring_s::next, bot_matchpiece_s::next, bot_matchtemplate_s::next, bot_matchstring_s::string, bot_matchtemplate_s::subtype, bot_matchtemplate_s::type, bot_matchpiece_s::type, and bot_matchpiece_s::variable. 01078 {
01079 FILE *fp;
01080 bot_matchtemplate_t *mt;
01081 bot_matchpiece_t *mp;
01082 bot_matchstring_t *ms;
01083
01084 fp = Log_FilePointer();
01085 if (!fp) return;
01086 for (mt = matches; mt; mt = mt->next)
01087 {
01088 fprintf(fp, "{ " );
01089 for (mp = mt->first; mp; mp = mp->next)
01090 {
01091 if (mp->type == MT_STRING)
01092 {
01093 for (ms = mp->firststring; ms; ms = ms->next)
01094 {
01095 fprintf(fp, "\"%s\"", ms->string);
01096 if (ms->next) fprintf(fp, "|");
01097 } //end for
01098 } //end if
01099 else if (mp->type == MT_VARIABLE)
01100 {
01101 fprintf(fp, "%d", mp->variable);
01102 } //end else if
01103 if (mp->next) fprintf(fp, ", ");
01104 } //end for
01105 fprintf(fp, " = (%d, %d);}\n", mt->type, mt->subtype);
01106 } //end for
01107 } //end of the function BotDumpMatchTemplates
|
Here is the call graph for this function:

|
|
Definition at line 921 of file be_ai_chat.c. References bot_randomlist_t, bot_randomstring_t, bot_randomlist_s::firstrandomstring, fp, fprintf(), Log_FilePointer(), bot_randomstring_s::next, bot_randomlist_s::next, random, bot_randomstring_s::string, and bot_randomlist_s::string. 00922 {
00923 FILE *fp;
00924 bot_randomlist_t *random;
00925 bot_randomstring_t *rs;
00926
00927 fp = Log_FilePointer();
00928 if (!fp) return;
00929 for (random = randomlist; random; random = random->next)
00930 {
00931 fprintf(fp, "%s = {", random->string);
00932 for (rs = random->firstrandomstring; rs; rs = rs->next)
00933 {
00934 fprintf(fp, "\"%s\"", rs->string);
00935 if (rs->next) fprintf(fp, ", ");
00936 else fprintf(fp, "}\n");
00937 } //end for
00938 } //end for
00939 } //end of the function BotDumpRandomStringList
|
Here is the call graph for this function:

|
|
Definition at line 1636 of file be_ai_chat.c. References bot_chatmessage_t, bot_matchpiece_t, bot_replychat_t, bot_replychatkey_t, cm, bot_replychat_s::firstchatmessage, bot_matchpiece_s::firststring, bot_replychatkey_s::flags, fp, fprintf(), bot_replychat_s::keys, Log_FilePointer(), bot_replychatkey_s::match, bot_matchpiece_s::next, bot_replychatkey_s::next, bot_replychat_s::next, bot_replychat_s::priority, bot_replychatkey_s::string, bot_matchstring_s::string, bot_matchpiece_s::type, and bot_matchpiece_s::variable. 01637 {
01638 FILE *fp;
01639 bot_replychat_t *rp;
01640 bot_replychatkey_t *key;
01641 bot_chatmessage_t *cm;
01642 bot_matchpiece_t *mp;
01643
01644 fp = Log_FilePointer();
01645 if (!fp) return;
01646 fprintf(fp, "BotDumpReplyChat:\n");
01647 for (rp = replychat; rp; rp = rp->next)
01648 {
01649 fprintf(fp, "[");
01650 for (key = rp->keys; key; key = key->next)
01651 {
01652 if (key->flags & RCKFL_AND) fprintf(fp, "&");
01653 else if (key->flags & RCKFL_NOT) fprintf(fp, "!");
01654 //
01655 if (key->flags & RCKFL_NAME) fprintf(fp, "name");
01656 else if (key->flags & RCKFL_GENDERFEMALE) fprintf(fp, "female");
01657 else if (key->flags & RCKFL_GENDERMALE) fprintf(fp, "male");
01658 else if (key->flags & RCKFL_GENDERLESS) fprintf(fp, "it");
01659 else if (key->flags & RCKFL_VARIABLES)
01660 {
01661 fprintf(fp, "(");
01662 for (mp = key->match; mp; mp = mp->next)
01663 {
01664 if (mp->type == MT_STRING) fprintf(fp, "\"%s\"", mp->firststring->string);
01665 else fprintf(fp, "%d", mp->variable);
01666 if (mp->next) fprintf(fp, ", ");
01667 } //end for
01668 fprintf(fp, ")");
01669 } //end if
01670 else if (key->flags & RCKFL_STRING)
01671 {
01672 fprintf(fp, "\"%s\"", key->string);
01673 } //end if
01674 if (key->next) fprintf(fp, ", ");
01675 else fprintf(fp, "] = %1.0f\n", rp->priority);
01676 } //end for
01677 fprintf(fp, "{\n");
01678 for (cm = rp->firstchatmessage; cm; cm = cm->next)
01679 {
01680 fprintf(fp, "\t\"%s\";\n", cm->chatmessage);
01681 } //end for
01682 fprintf(fp, "}\n");
01683 } //end for
01684 } //end of the function BotDumpReplyChat
|
Here is the call graph for this function:

|
|
Definition at line 570 of file be_ai_chat.c. References bot_synonym_t, bot_synonymlist_t, bot_synonymlist_s::context, bot_synonymlist_s::firstsynonym, fp, fprintf(), Log_FilePointer(), bot_synonym_s::next, bot_synonymlist_s::next, bot_synonym_s::string, and bot_synonym_s::weight. 00571 {
00572 FILE *fp;
00573 bot_synonymlist_t *syn;
00574 bot_synonym_t *synonym;
00575
00576 fp = Log_FilePointer();
00577 if (!fp) return;
00578 for (syn = synlist; syn; syn = syn->next)
00579 {
00580 fprintf(fp, "%ld : [", syn->context);
00581 for (synonym = syn->firstsynonym; synonym; synonym = synonym->next)
00582 {
00583 fprintf(fp, "(\"%s\", %1.2f)", synonym->string, synonym->weight);
00584 if (synonym->next) fprintf(fp, ", ");
00585 } //end for
00586 fprintf(fp, "]\n");
00587 } //end for
00588 } //end of the function BotDumpSynonymList
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 2785 of file be_ai_chat.c. References bot_chatstate_t, BotChatStateFromHandle(), botimport, BotRemoveTildes(), CHAT_TEAM, CHAT_TELL, bot_chatstate_s::chatmessage, bot_chatstate_s::client, EA_Command(), LibVarGetValue(), PRT_MESSAGE, strcpy(), strlen(), and va(). 02786 {
02787 bot_chatstate_t *cs;
02788
02789 cs = BotChatStateFromHandle(chatstate);
02790 if (!cs) return;
02791
02792 if (strlen(cs->chatmessage))
02793 {
02794 BotRemoveTildes(cs->chatmessage);
02795 if (LibVarGetValue("bot_testichat")) {
02796 botimport.Print(PRT_MESSAGE, "%s\n", cs->chatmessage);
02797 }
02798 else {
02799 switch(sendto) {
02800 case CHAT_TEAM:
02801 EA_Command(cs->client, va("say_team %s", cs->chatmessage));
02802 break;
02803 case CHAT_TELL:
02804 EA_Command(cs->client, va("tell %d %s", clientto, cs->chatmessage));
02805 break;
02806 default: //CHAT_ALL
02807 EA_Command(cs->client, va("say %s", cs->chatmessage));
02808 break;
02809 }
02810 }
02811 //clear the chat message from the state
02812 strcpy(cs->chatmessage, "");
02813 } //end if
02814 } //end of the function BotEnterChat
|
Here is the call graph for this function:

|
||||||||||||||||||||||||||||
|
Definition at line 2258 of file be_ai_chat.c. References assert, bot_match_t, botimport, BotReplaceReplySynonyms(), BotReplaceSynonyms(), BotReplaceWeightedSynonyms(), i, bot_matchvariable_s::length, match(), bot_matchvariable_s::offset, PRT_ERROR, PRT_FATAL, ptr(), RandomString(), strcpy(), bot_match_s::string, strlen(), and bot_match_s::variables. Referenced by BotConstructChatMessage(). 02260 {
02261 int num, len, i, expansion;
02262 char *outputbuf, *ptr, *msgptr;
02263 char temp[MAX_MESSAGE_SIZE];
02264
02265 expansion = qfalse;
02266 msgptr = message;
02267 outputbuf = outmessage;
02268 len = 0;
02269 //
02270 while(*msgptr)
02271 {
02272 if (*msgptr == ESCAPE_CHAR)
02273 {
02274 msgptr++;
02275 switch(*msgptr)
02276 {
02277 case 'v': //variable
02278 {
02279 msgptr++;
02280 num = 0;
02281 while(*msgptr && *msgptr != ESCAPE_CHAR)
02282 {
02283 num = num * 10 + (*msgptr++) - '0';
02284 } //end while
02285 //step over the trailing escape char
02286 if (*msgptr) msgptr++;
02287 if (num > MAX_MATCHVARIABLES)
02288 {
02289 botimport.Print(PRT_ERROR, "BotConstructChat: message %s variable %d out of range\n", message, num);
02290 return qfalse;
02291 } //end if
02292 if (match->variables[num].offset >= 0)
02293 {
02294 assert( match->variables[num].offset >= 0 ); // bk001204
02295 ptr = &match->string[ (int) match->variables[num].offset];
02296 for (i = 0; i < match->variables[num].length; i++)
02297 {
02298 temp[i] = ptr[i];
02299 } //end for
02300 temp[i] = 0;
02301 //if it's a reply message
02302 if (reply)
02303 {
02304 //replace the reply synonyms in the variables
02305 BotReplaceReplySynonyms(temp, vcontext);
02306 } //end if
02307 else
02308 {
02309 //replace synonyms in the variable context
02310 BotReplaceSynonyms(temp, vcontext);
02311 } //end else
02312 //
02313 if (len + strlen(temp) >= MAX_MESSAGE_SIZE)
02314 {
02315 botimport.Print(PRT_ERROR, "BotConstructChat: message %s too long\n", message);
02316 return qfalse;
02317 } //end if
02318 strcpy(&outputbuf[len], temp);
02319 len += strlen(temp);
02320 } //end if
02321 break;
02322 } //end case
02323 case 'r': //random
02324 {
02325 msgptr++;
02326 for (i = 0; (*msgptr && *msgptr != ESCAPE_CHAR); i++)
02327 {
02328 temp[i] = *msgptr++;
02329 } //end while
02330 temp[i] = '\0';
02331 //step over the trailing escape char
02332 if (*msgptr) msgptr++;
02333 //find the random keyword
02334 ptr = RandomString(temp);
02335 if (!ptr)
02336 {
02337 botimport.Print(PRT_ERROR, "BotConstructChat: unknown random string %s\n", temp);
02338 return qfalse;
02339 } //end if
02340 if (len + strlen(ptr) >= MAX_MESSAGE_SIZE)
02341 {
02342 botimport.Print(PRT_ERROR, "BotConstructChat: message \"%s\" too long\n", message);
02343 return qfalse;
02344 } //end if
02345 strcpy(&outputbuf[len], ptr);
02346 len += strlen(ptr);
02347 expansion = qtrue;
02348 break;
02349 } //end case
02350 default:
02351 {
02352 botimport.Print(PRT_FATAL, "BotConstructChat: message \"%s\" invalid escape char\n", message);
02353 break;
02354 } //end default
02355 } //end switch
02356 } //end if
02357 else
02358 {
02359 outputbuf[len++] = *msgptr++;
02360 if (len >= MAX_MESSAGE_SIZE)
02361 {
02362 botimport.Print(PRT_ERROR, "BotConstructChat: message \"%s\" too long\n", message);
02363 break;
02364 } //end if
02365 } //end else
02366 } //end while
02367 outputbuf[len] = '\0';
02368 //replace synonyms weighted in the message context
02369 BotReplaceWeightedSynonyms(outputbuf, mcontext);
02370 //return true if a random was expanded
02371 return expansion;
02372 } //end of the function BotExpandChatMessage
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 1434 of file be_ai_chat.c. References bot_match_t, bot_matchtemplate_t, bot_matchtemplate_s::context, bot_matchtemplate_s::first, i, match(), MAX_MESSAGE_SIZE, bot_matchtemplate_s::next, bot_matchvariable_s::offset, bot_match_s::string, StringsMatch(), strlen(), strncpy(), bot_match_s::subtype, bot_matchtemplate_s::subtype, bot_match_s::type, bot_matchtemplate_s::type, and bot_match_s::variables. 01435 {
01436 int i;
01437 bot_matchtemplate_t *ms;
01438
01439 strncpy(match->string, str, MAX_MESSAGE_SIZE);
01440 //remove any trailing enters
01441 while(strlen(match->string) &&
01442 match->string[strlen(match->string)-1] == '\n')
01443 {
01444 match->string[strlen(match->string)-1] = '\0';
01445 } //end while
01446 //compare the string with all the match strings
01447 for (ms = matchtemplates; ms; ms = ms->next)
01448 {
01449 if (!(ms->context & context)) continue;
01450 //reset the match variable offsets
01451 for (i = 0; i < MAX_MATCHVARIABLES; i++) match->variables[i].offset = -1;
01452 //
01453 if (StringsMatch(ms->first, match))
01454 {
01455 match->type = ms->type;
01456 match->subtype = ms->subtype;
01457 return qtrue;
01458 } //end if
01459 } //end for
01460 return qfalse;
01461 } //end of the function BotFindMatch
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 1497 of file be_ai_chat.c. References bot_stringlist_t, bot_stringlist_s::next, s, strcmp(), string(), and bot_stringlist_s::string. Referenced by BotCheckChatMessageIntegrety(). 01498 {
01499 bot_stringlist_t *s;
01500
01501 for (s = list; s; s = s->next)
01502 {
01503 if (!strcmp(s->string, string)) return s;
01504 } //end for
01505 return NULL;
01506 } //end of the function BotFindStringInList
|
Here is the call graph for this function:

|
|
Definition at line 2185 of file be_ai_chat.c. References bot_chatstate_t, BotChatStateFromHandle(), bot_chatstate_s::chat, and FreeMemory(). Referenced by BotFreeChatState(), and BotLoadChatFile(). 02186 {
02187 bot_chatstate_t *cs;
02188
02189 cs = BotChatStateFromHandle(chatstate);
02190 if (!cs) return;
02191 if (cs->chat) FreeMemory(cs->chat);
02192 cs->chat = NULL;
02193 } //end of the function BotFreeChatFile
|
Here is the call graph for this function:

|
|
Definition at line 2915 of file be_ai_chat.c. References bot_chatstate_t, bot_consolemessage_t, botchatstates, BotFreeChatFile(), botimport, BotNextConsoleMessage(), BotRemoveConsoleMessage(), FreeMemory(), h(), LibVarGetValue(), m, and PRT_FATAL. Referenced by BotShutdownChatAI(). 02916 {
02917 bot_chatstate_t *cs;
02918 bot_consolemessage_t m;
02919 int h;
02920
02921 if (handle <= 0 || handle > MAX_CLIENTS)
02922 {
02923 botimport.Print(PRT_FATAL, "chat state handle %d out of range\n", handle);
02924 return;
02925 } //end if
02926 if (!botchatstates[handle])
02927 {
02928 botimport.Print(PRT_FATAL, "invalid chat state %d\n", handle);
02929 return;
02930 } //end if
02931 cs = botchatstates[handle];
02932 if (LibVarGetValue("bot_reloadcharacters"))
02933 {
02934 BotFreeChatFile(handle);
02935 } //end if
02936 //free all the console messages left in the chat state
02937 for (h = BotNextConsoleMessage(handle, &m); h; h = BotNextConsoleMessage(handle, &m))
02938 {
02939 //remove the console message
02940 BotRemoveConsoleMessage(handle, h);
02941 } //end for
02942 FreeMemory(botchatstates[handle]);
02943 botchatstates[handle] = NULL;
02944 } //end of the function BotFreeChatState
|
Here is the call graph for this function:

|
|
Definition at line 1114 of file be_ai_chat.c. References bot_matchpiece_t, bot_matchstring_t, bot_matchpiece_s::firststring, FreeMemory(), bot_matchstring_s::next, bot_matchpiece_s::next, and bot_matchpiece_s::type. Referenced by BotFreeMatchTemplates(), BotFreeReplyChat(), and BotLoadMatchPieces(). 01115 {
01116 bot_matchpiece_t *mp, *nextmp;
01117 bot_matchstring_t *ms, *nextms;
01118
01119 for (mp = matchpieces; mp; mp = nextmp)
01120 {
01121 nextmp = mp->next;
01122 if (mp->type == MT_STRING)
01123 {
01124 for (ms = mp->firststring; ms; ms = nextms)
01125 {
01126 nextms = ms->next;
01127 FreeMemory(ms);
01128 } //end for
01129 } //end if
01130 FreeMemory(mp);
01131 } //end for
01132 } //end of the function BotFreeMatchPieces
|
Here is the call graph for this function:

|
|
Definition at line 1241 of file be_ai_chat.c. References bot_matchtemplate_t, BotFreeMatchPieces(), bot_matchtemplate_s::first, FreeMemory(), and bot_matchtemplate_s::next. Referenced by BotLoadMatchTemplates(), and BotShutdownChatAI(). 01242 {
01243 bot_matchtemplate_t *nextmt;
01244
01245 for (; mt; mt = nextmt)
01246 {
01247 nextmt = mt->next;
01248 BotFreeMatchPieces(mt->first);
01249 FreeMemory(mt);
01250 } //end for
01251 } //end of the function BotFreeMatchTemplates
|
Here is the call graph for this function:

|
|
Definition at line 1691 of file be_ai_chat.c. References bot_chatmessage_t, bot_replychat_t, bot_replychatkey_t, BotFreeMatchPieces(), cm, bot_replychat_s::firstchatmessage, FreeMemory(), bot_replychat_s::keys, bot_replychatkey_s::match, bot_replychatkey_s::next, bot_replychat_s::next, and bot_replychatkey_s::string. Referenced by BotLoadReplyChat(), and BotShutdownChatAI(). 01692 {
01693 bot_replychat_t *rp, *nextrp;
01694 bot_replychatkey_t *key, *nextkey;
01695 bot_chatmessage_t *cm, *nextcm;
01696
01697 for (rp = replychat; rp; rp = nextrp)
01698 {
01699 nextrp = rp->next;
01700 for (key = rp->keys; key; key = nextkey)
01701 {
01702 nextkey = key->next;
01703 if (key->match) BotFreeMatchPieces(key->match);
01704 if (key->string) FreeMemory(key->string);
01705 FreeMemory(key);
01706 } //end for
01707 for (cm = rp->firstchatmessage; cm; cm = nextcm)
01708 {
01709 nextcm = cm->next;
01710 FreeMemory(cm);
01711 } //end for
01712 FreeMemory(rp);
01713 } //end for
01714 } //end of the function BotFreeReplyChat
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 2821 of file be_ai_chat.c. References bot_chatstate_t, BotChatStateFromHandle(), BotRemoveTildes(), bot_chatstate_s::chatmessage, strcpy(), and strncpy(). 02822 {
02823 bot_chatstate_t *cs;
02824
02825 cs = BotChatStateFromHandle(chatstate);
02826 if (!cs) return;
02827
02828 BotRemoveTildes(cs->chatmessage);
02829 strncpy(buf, cs->chatmessage, size-1);
02830 buf[size-1] = '\0';
02831 //clear the chat message from the state
02832 strcpy(cs->chatmessage, "");
02833 } //end of the function BotGetChatMessage
|
Here is the call graph for this function:

|
||||||||||||||||||||||||||||||||||||||||||||||||
|
Definition at line 2492 of file be_ai_chat.c. References bot_chatstate_t, bot_match_t, BotChatStateFromHandle(), BotChooseInitialChatMessage(), BotConstructChatMessage(), botimport, bot_chatstate_s::chat, Com_Memset(), match(), PRT_MESSAGE, qfalse, strcat(), strlen(), and type. 02493 {
02494 char *message;
02495 int index;
02496 bot_match_t match;
02497 bot_chatstate_t *cs;
02498
02499 cs = BotChatStateFromHandle(chatstate);
02500 if (!cs) return;
02501 //if no chat file is loaded
02502 if (!cs->chat) return;
02503 //choose a chat message randomly of the given type
02504 message = BotChooseInitialChatMessage(cs, type);
02505 //if there's no message of the given type
02506 if (!message)
02507 {
02508 #ifdef DEBUG
02509 botimport.Print(PRT_MESSAGE, "no chat messages of type %s\n", type);
02510 #endif //DEBUG
02511 return;
02512 } //end if
02513 //
02514 Com_Memset(&match, 0, sizeof(match));
02515 index = 0;
02516 if( var0 ) {
02517 strcat(match.string, var0);
02518 match.variables[0].offset = index;
02519 match.variables[0].length = strlen(var0);
02520 index += strlen(var0);
02521 }
02522 if( var1 ) {
02523 strcat(match.string, var1);
02524 match.variables[1].offset = index;
02525 match.variables[1].length = strlen(var1);
02526 index += strlen(var1);
02527 }
02528 if( var2 ) {
02529 strcat(match.string, var2);
02530 match.variables[2].offset = index;
02531 match.variables[2].length = strlen(var2);
02532 index += strlen(var2);
02533 }
02534 if( var3 ) {
02535 strcat(match.string, var3);
02536 match.variables[3].offset = index;
02537 match.variables[3].length = strlen(var3);
02538 index += strlen(var3);
02539 }
02540 if( var4 ) {
02541 strcat(match.string, var4);
02542 match.variables[4].offset = index;
02543 match.variables[4].length = strlen(var4);
02544 index += strlen(var4);
02545 }
02546 if( var5 ) {
02547 strcat(match.string, var5);
02548 match.variables[5].offset = index;
02549 match.variables[5].length = strlen(var5);
02550 index += strlen(var5);
02551 }
02552 if( var6 ) {
02553 strcat(match.string, var6);
02554 match.variables[6].offset = index;
02555 match.variables[6].length = strlen(var6);
02556 index += strlen(var6);
02557 }
02558 if( var7 ) {
02559 strcat(match.string, var7);
02560 match.variables[7].offset = index;
02561 match.variables[7].length = strlen(var7);
02562 index += strlen(var7);
02563 }
02564 //
02565 BotConstructChatMessage(cs, message, mcontext, &match, 0, qfalse);
02566 } //end of the function BotInitialChat
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 2200 of file be_ai_chat.c. References bot_chatstate_t, BotChatStateFromHandle(), BotFreeChatFile(), botimport, BotLoadInitialChat(), bot_chatstate_s::chat, bot_ichatdata_t::chat, GetClearedMemory(), ichatdata, LibVarGetValue(), n, PRT_FATAL, Q_strncpyz(), and strcmp(). 02201 {
02202 bot_chatstate_t *cs;
02203 int n, avail = 0;
02204
02205 cs = BotChatStateFromHandle(chatstate);
02206 if (!cs) return BLERR_CANNOTLOADICHAT;
02207 BotFreeChatFile(chatstate);
02208
02209 if (!LibVarGetValue("bot_reloadcharacters"))
02210 {
02211 avail = -1;
02212 for( n = 0; n < MAX_CLIENTS; n++ ) {
02213 if( !ichatdata[n] ) {
02214 if( avail == -1 ) {
02215 avail = n;
02216 }
02217 continue;
02218 }
02219 if( strcmp( chatfile, ichatdata[n]->filename ) != 0 ) {
02220 continue;
02221 }
02222 if( strcmp( chatname, ichatdata[n]->chatname ) != 0 ) {
02223 continue;
02224 }
02225 cs->chat = ichatdata[n]->chat;
02226 // botimport.Print( PRT_MESSAGE, "retained %s from %s\n", chatname, chatfile );
02227 return BLERR_NOERROR;
02228 }
02229
02230 if( avail == -1 ) {
02231 botimport.Print(PRT_FATAL, "ichatdata table full; couldn't load chat %s from %s\n", chatname, chatfile);
02232 return BLERR_CANNOTLOADICHAT;
02233 }
02234 }
02235
02236 cs->chat = BotLoadInitialChat(chatfile, chatname);
02237 if (!cs->chat)
02238 {
02239 botimport.Print(PRT_FATAL, "couldn't load chat %s from %s\n", chatname, chatfile);
02240 return BLERR_CANNOTLOADICHAT;
02241 } //end if
02242 if (!LibVarGetValue("bot_reloadcharacters"))
02243 {
02244 ichatdata[avail] = GetClearedMemory( sizeof(bot_ichatdata_t) );
02245 ichatdata[avail]->chat = cs->chat;
02246 Q_strncpyz( ichatdata[avail]->chatname, chatname, sizeof(ichatdata[avail]->chatname) );
02247 Q_strncpyz( ichatdata[avail]->filename, chatfile, sizeof(ichatdata[avail]->filename) );
02248 } //end if
02249
02250 return BLERR_NOERROR;
02251 } //end of the function BotLoadChatFile
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 862 of file be_ai_chat.c. References ESCAPE_CHAR, token_s::intvalue, PC_CheckTokenString(), PC_ExpectAnyToken(), PC_ExpectTokenString(), ptr(), source, source_t, SourceError(), sprintf(), strcat(), token_s::string, StripDoubleQuotes(), strlen(), token_s::subtype, token, token_t, TT_NUMBER, and token_s::type. Referenced by BotLoadInitialChat(), BotLoadRandomStrings(), and BotLoadReplyChat(). 00863 {
00864 char *ptr;
00865 token_t token;
00866
00867 ptr = chatmessagestring;
00868 *ptr = 0;
00869 //
00870 while(1)
00871 {
00872 if (!PC_ExpectAnyToken(source, &token)) return qfalse;
00873 //fixed string
00874 if (token.type == TT_STRING)
00875 {
00876 StripDoubleQuotes(token.string);
00877 if (strlen(ptr) + strlen(token.string) + 1 > MAX_MESSAGE_SIZE)
00878 {
00879 SourceError(source, "chat message too long\n");
00880 return qfalse;
00881 } //end if
00882 strcat(ptr, token.string);
00883 } //end else if
00884 //variable string
00885 else if (token.type == TT_NUMBER && (token.subtype & TT_INTEGER))
00886 {
00887 if (strlen(ptr) + 7 > MAX_MESSAGE_SIZE)
00888 {
00889 SourceError(source, "chat message too long\n");
00890 return qfalse;
00891 } //end if
00892 sprintf(&ptr[strlen(ptr)], "%cv%ld%c", ESCAPE_CHAR, token.intvalue, ESCAPE_CHAR);
00893 } //end if
00894 //random string
00895 else if (token.type == TT_NAME)
00896 {
00897 if (strlen(ptr) + 7 > MAX_MESSAGE_SIZE)
00898 {
00899 SourceError(source, "chat message too long\n");
00900 return qfalse;
00901 } //end if
00902 sprintf(&ptr[strlen(ptr)], "%cr%s%c", ESCAPE_CHAR, token.string, ESCAPE_CHAR);
00903 } //end else if
00904 else
00905 {
00906 SourceError(source, "unknown message component %s\n", token.string);
00907 return qfalse;
00908 } //end else
00909 if (PC_CheckTokenString(source, ";")) break;
00910 if (!PC_ExpectTokenString(source, ",")) return qfalse;
00911 } //end while
00912 //
00913 return qtrue;
00914 } //end of the function BotLoadChatMessage
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 2013 of file be_ai_chat.c. References bot_chat_t, bot_chatmessage_t, bot_chattype_t, BotCheckInitialChatIntegrety(), BOTFILESBASEFOLDER, botimport, BotLoadChatMessage(), bot_chatmessage_s::chatmessage, bot_chattype_s::firstchatmessage, FreeSource(), GetClearedMemory(), LoadSourceFile(), MAX_CHATTYPE_NAME, bot_chattype_s::name, bot_chatmessage_s::next, bot_chattype_s::next, bot_chattype_s::numchatmessages, PC_CheckTokenString(), PC_ExpectAnyToken(), PC_ExpectTokenString(), PC_ExpectTokenType(), PC_ReadToken(), PC_SetBaseFolder(), PRT_ERROR, PRT_MESSAGE, ptr(), Q_stricmp(), source, source_t, SourceError(), strcmp(), strcpy(), token_s::string, StripDoubleQuotes(), strlen(), strncpy(), Sys_MilliSeconds(), bot_chatmessage_s::time, token, token_t, TT_STRING, and bot_chat_s::types. Referenced by BotLoadChatFile(). 02014 {
02015 int pass, foundchat, indent, size;
02016 char *ptr = NULL;
02017 char chatmessagestring[MAX_MESSAGE_SIZE];
02018 source_t *source;
02019 token_t token;
02020 bot_chat_t *chat = NULL;
02021 bot_chattype_t *chattype = NULL;
02022 bot_chatmessage_t *chatmessage = NULL;
02023 #ifdef DEBUG
02024 int starttime;
02025
02026 starttime = Sys_MilliSeconds();
02027 #endif //DEBUG
02028 //
02029 size = 0;
02030 foundchat = qfalse;
02031 //a bot chat is parsed in two phases
02032 for (pass = 0; pass < 2; pass++)
02033 {
02034 //allocate memory
02035 if (pass && size) ptr = (char *) GetClearedMemory(size);
02036 //load the source file
02037 PC_SetBaseFolder(BOTFILESBASEFOLDER);
02038 source = LoadSourceFile(chatfile);
02039 if (!source)
02040 {
02041 botimport.Print(PRT_ERROR, "counldn't load %s\n", chatfile);
02042 return NULL;
02043 } //end if
02044 //chat structure
02045 if (pass)
02046 {
02047 chat = (bot_chat_t *) ptr;
02048 ptr += sizeof(bot_chat_t);
02049 } //end if
02050 size = sizeof(bot_chat_t);
02051 //
02052 while(PC_ReadToken(source, &token))
02053 {
02054 if (!strcmp(token.string, "chat"))
02055 {
02056 if (!PC_ExpectTokenType(source, TT_STRING, 0, &token))
02057 {
02058 FreeSource(source);
02059 return NULL;
02060 } //end if
02061 StripDoubleQuotes(token.string);
02062 //after the chat name we expect a opening brace
02063 if (!PC_ExpectTokenString(source, "{"))
02064 {
02065 FreeSource(source);
02066 return NULL;
02067 } //end if
02068 //if the chat name is found
02069 if (!Q_stricmp(token.string, chatname))
02070 {
02071 foundchat = qtrue;
02072 //read the chat types
02073 while(1)
02074 {
02075 if (!PC_ExpectAnyToken(source, &token))
02076 {
02077 FreeSource(source);
02078 return NULL;
02079 } //end if
02080 if (!strcmp(token.string, "}")) break;
02081 if (strcmp(token.string, "type"))
02082 {
02083 SourceError(source, "expected type found %s\n", token.string);
02084 FreeSource(source);
02085 return NULL;
02086 } //end if
02087 //expect the chat type name
02088 if (!PC_ExpectTokenType(source, TT_STRING, 0, &token) ||
02089 !PC_ExpectTokenString(source, "{"))
02090 {
02091 FreeSource(source);
02092 return NULL;
02093 } //end if
02094 StripDoubleQuotes(token.string);
02095 if (pass)
02096 {
02097 chattype = (bot_chattype_t *) ptr;
02098 strncpy(chattype->name, token.string, MAX_CHATTYPE_NAME);
02099 chattype->firstchatmessage = NULL;
02100 //add the chat type to the chat
02101 chattype->next = chat->types;
02102 chat->types = chattype;
02103 //
02104 ptr += sizeof(bot_chattype_t);
02105 } //end if
02106 size += sizeof(bot_chattype_t);
02107 //read the chat messages
02108 while(!PC_CheckTokenString(source, "}"))
02109 {
02110 if (!BotLoadChatMessage(source, chatmessagestring))
02111 {
02112 FreeSource(source);
02113 return NULL;
02114 } //end if
02115 if (pass)
02116 {
02117 chatmessage = (bot_chatmessage_t *) ptr;
02118 chatmessage->time = -2*CHATMESSAGE_RECENTTIME;
02119 //put the chat message in the list
02120 chatmessage->next = chattype->firstchatmessage;
02121 chattype->firstchatmessage = chatmessage;
02122 //store the chat message
02123 ptr += sizeof(bot_chatmessage_t);
02124 chatmessage->chatmessage = ptr;
02125 strcpy(chatmessage->chatmessage, chatmessagestring);
02126 ptr += strlen(chatmessagestring) + 1;
02127 //the number of chat messages increased
02128 chattype->numchatmessages++;
02129 } //end if
02130 size += sizeof(bot_chatmessage_t) + strlen(chatmessagestring) + 1;
02131 } //end if
02132 } //end while
02133 } //end if
02134 else //skip the bot chat
02135 {
02136 indent = 1;
02137 while(indent)
02138 {
02139 if (!PC_ExpectAnyToken(source, &token))
02140 {
02141 FreeSource(source);
02142 return NULL;
02143 } //end if
02144 if (!strcmp(token.string, "{")) indent++;
02145 else if (!strcmp(token.string, "}")) indent--;
02146 } //end while
02147 } //end else
02148 } //end if
02149 else
02150 {
02151 SourceError(source, "unknown definition %s\n", token.string);
02152 FreeSource(source);
02153 return NULL;
02154 } //end else
02155 } //end while
02156 //free the source
02157 FreeSource(source);
02158 //if the requested character is not found
02159 if (!foundchat)
02160 {
02161 botimport.Print(PRT_ERROR, "couldn't find chat %s in %s\n", chatname, chatfile);
02162 return NULL;
02163 } //end if
02164 } //end for
02165 //
02166 botimport.Print(PRT_MESSAGE, "loaded %s from %s\n", chatname, chatfile);
02167 //
02168 //BotDumpInitialChat(chat);
02169 if (bot_developer)
02170 {
02171 BotCheckInitialChatIntegrety(chat);
02172 } //end if
02173 #ifdef DEBUG
02174 botimport.Print(PRT_MESSAGE, "initial chats loaded in %d msec\n", Sys_MilliSeconds() - starttime);
02175 #endif //DEBUG
02176 //character was read succesfully
02177 return chat;
02178 } //end of the function BotLoadInitialChat
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 1139 of file be_ai_chat.c. References bot_matchpiece_t, bot_matchstring_t, BotFreeMatchPieces(), emptystring, bot_matchpiece_s::firststring, FreeSource(), GetClearedHunkMemory(), token_s::intvalue, MAX_MATCHVARIABLES, bot_matchstring_s::next, bot_matchpiece_s::next, PC_CheckTokenString(), PC_ExpectTokenString(), PC_ExpectTokenType(), PC_ReadToken(), source, source_t, SourceError(), strcpy(), bot_matchstring_s::string, token_s::string, StripDoubleQuotes(), strlen(), token_s::subtype, token, token_t, TT_NUMBER, TT_STRING, bot_matchpiece_s::type, token_s::type, and bot_matchpiece_s::variable. Referenced by BotLoadMatchTemplates(), and BotLoadReplyChat(). 01140 {
01141 int lastwasvariable, emptystring;
01142 token_t token;
01143 bot_matchpiece_t *matchpiece, *firstpiece, *lastpiece;
01144 bot_matchstring_t *matchstring, *lastmatchstring;
01145
01146 firstpiece = NULL;
01147 lastpiece = NULL;
01148 //
01149 lastwasvariable = qfalse;
01150 //
01151 while(PC_ReadToken(source, &token))
01152 {
01153 if (token.type == TT_NUMBER && (token.subtype & TT_INTEGER))
01154 {
01155 if (token.intvalue < 0 || token.intvalue >= MAX_MATCHVARIABLES)
01156 {
01157 SourceError(source, "can't have more than %d match variables\n", MAX_MATCHVARIABLES);
01158 FreeSource(source);
01159 BotFreeMatchPieces(firstpiece);
01160 return NULL;
01161 } //end if
01162 if (lastwasvariable)
01163 {
01164 SourceError(source, "not allowed to have adjacent variables\n");
01165 FreeSource(source);
01166 BotFreeMatchPieces(firstpiece);
01167 return NULL;
01168 } //end if
01169 lastwasvariable = qtrue;
01170 //
01171 matchpiece = (bot_matchpiece_t *) GetClearedHunkMemory(sizeof(bot_matchpiece_t));
01172 matchpiece->type = MT_VARIABLE;
01173 matchpiece->variable = token.intvalue;
01174 matchpiece->next = NULL;
01175 if (lastpiece) lastpiece->next = matchpiece;
01176 else firstpiece = matchpiece;
01177 lastpiece = matchpiece;
01178 } //end if
01179 else if (token.type == TT_STRING)
01180 {
01181 //
01182 matchpiece = (bot_matchpiece_t *) GetClearedHunkMemory(sizeof(bot_matchpiece_t));
01183 matchpiece->firststring = NULL;
01184 matchpiece->type = MT_STRING;
01185 matchpiece->variable = 0;
01186 matchpiece->next = NULL;
01187 if (lastpiece) lastpiece->next = matchpiece;
01188 else firstpiece = matchpiece;
01189 lastpiece = matchpiece;
01190 //
01191 lastmatchstring = NULL;
01192 emptystring = qfalse;
01193 //
01194 do
01195 {
01196 if (matchpiece->firststring)
01197 {
01198 if (!PC_ExpectTokenType(source, TT_STRING, 0, &token))
01199 {
01200 FreeSource(source);
01201 BotFreeMatchPieces(firstpiece);
01202 return NULL;
01203 } //end if
01204 } //end if
01205 StripDoubleQuotes(token.string);
01206 matchstring = (bot_matchstring_t *) GetClearedHunkMemory(sizeof(bot_matchstring_t) + strlen(token.string) + 1);
01207 matchstring->string = (char *) matchstring + sizeof(bot_matchstring_t);
01208 strcpy(matchstring->string, token.string);
01209 if (!strlen(token.string)) emptystring = qtrue;
01210 matchstring->next = NULL;
01211 if (lastmatchstring) lastmatchstring->next = matchstring;
01212 else matchpiece->firststring = matchstring;
01213 lastmatchstring = matchstring;
01214 } while(PC_CheckTokenString(source, "|"));
01215 //if there was no empty string found
01216 if (!emptystring) lastwasvariable = qfalse;
01217 } //end if
01218 else
01219 {
01220 SourceError(source, "invalid token %s\n", token.string);
01221 FreeSource(source);
01222 BotFreeMatchPieces(firstpiece);
01223 return NULL;
01224 } //end else
01225 if (PC_CheckTokenString(source, endtoken)) break;
01226 if (!PC_ExpectTokenString(source, ","))
01227 {
01228 FreeSource(source);
01229 BotFreeMatchPieces(firstpiece);
01230 return NULL;
01231 } //end if
01232 } //end while
01233 return firstpiece;
01234 } //end of the function BotLoadMatchPieces
|
Here is the call graph for this function:

|
|
Definition at line 1258 of file be_ai_chat.c. References bot_matchtemplate_t, BOTFILESBASEFOLDER, BotFreeMatchTemplates(), botimport, BotLoadMatchPieces(), bot_matchtemplate_s::context, bot_matchtemplate_s::first, FreeSource(), GetClearedHunkMemory(), token_s::intvalue, LoadSourceFile(), bot_matchtemplate_s::next, PC_ExpectTokenString(), PC_ExpectTokenType(), PC_ReadToken(), PC_SetBaseFolder(), PC_UnreadLastToken(), PRT_ERROR, PRT_MESSAGE, source, source_t, SourceError(), strcmp(), token_s::string, bot_matchtemplate_s::subtype, token_s::subtype, token, token_t, TT_INTEGER, TT_NUMBER, bot_matchtemplate_s::type, and token_s::type. Referenced by BotSetupChatAI(). 01259 {
01260 source_t *source;
01261 token_t token;
01262 bot_matchtemplate_t *matchtemplate, *matches, *lastmatch;
01263 unsigned long int context;
01264
01265 PC_SetBaseFolder(BOTFILESBASEFOLDER);
01266 source = LoadSourceFile(matchfile);
01267 if (!source)
01268 {
01269 botimport.Print(PRT_ERROR, "counldn't load %s\n", matchfile);
01270 return NULL;
01271 } //end if
01272 //
01273 matches = NULL; //list with matches
01274 lastmatch = NULL; //last match in the list
01275
01276 while(PC_ReadToken(source, &token))
01277 {
01278 if (token.type != TT_NUMBER || !(token.subtype & TT_INTEGER))
01279 {
01280 SourceError(source, "expected integer, found %s\n", token.string);
01281 BotFreeMatchTemplates(matches);
01282 FreeSource(source);
01283 return NULL;
01284 } //end if
01285 //the context
01286 context = token.intvalue;
01287 //
01288 if (!PC_ExpectTokenString(source, "{"))
01289 {
01290 BotFreeMatchTemplates(matches);
01291 FreeSource(source);
01292 return NULL;
01293 } //end if
01294 //
01295 while(PC_ReadToken(source, &token))
01296 {
01297 if (!strcmp(token.string, "}")) break;
01298 //
01299 PC_UnreadLastToken(source);
01300 //
01301 matchtemplate = (bot_matchtemplate_t *) GetClearedHunkMemory(sizeof(bot_matchtemplate_t));
01302 matchtemplate->context = context;
01303 matchtemplate->next = NULL;
01304 //add the match template to the list
01305 if (lastmatch) lastmatch->next = matchtemplate;
01306 else matches = matchtemplate;
01307 lastmatch = matchtemplate;
01308 //load the match template
01309 matchtemplate->first = BotLoadMatchPieces(source, "=");
01310 if (!matchtemplate->first)
01311 {
01312 BotFreeMatchTemplates(matches);
01313 return NULL;
01314 } //end if
01315 //read the match type
01316 if (!PC_ExpectTokenString(source, "(") ||
01317 !PC_ExpectTokenType(source, TT_NUMBER, TT_INTEGER, &token))
01318 {
01319 BotFreeMatchTemplates(matches);
01320 FreeSource(source);
01321 return NULL;
01322 } //end if
01323 matchtemplate->type = token.intvalue;
01324 //read the match subtype
01325 if (!PC_ExpectTokenString(source, ",") ||
01326 !PC_ExpectTokenType(source, TT_NUMBER, TT_INTEGER, &token))
01327 {
01328 BotFreeMatchTemplates(matches);
01329 FreeSource(source);
01330 return NULL;
01331 } //end if
01332 matchtemplate->subtype = token.intvalue;
01333 //read trailing punctuations
01334 if (!PC_ExpectTokenString(source, ")") ||
01335 !PC_ExpectTokenString(source, ";"))
01336 {
01337 BotFreeMatchTemplates(matches);
01338 FreeSource(source);
01339 return NULL;
01340 } //end if
01341 } //end while
01342 } //end while
01343 //free the source
01344 FreeSource(source);
01345 botimport.Print(PRT_MESSAGE, "loaded %s\n", matchfile);
01346 //
01347 //BotDumpMatchTemplates(matches);
01348 //
01349 return matches;
01350 } //end of the function BotLoadMatchTemplates
|
Here is the call graph for this function:

|
|
Definition at line 946 of file be_ai_chat.c. References bot_randomlist_t, bot_randomstring_t, BOTFILESBASEFOLDER, botimport, BotLoadChatMessage(), bot_randomlist_s::firstrandomstring, FreeSource(), GetClearedHunkMemory(), LoadSourceFile(), bot_randomstring_s::next, bot_randomlist_s::next, bot_randomlist_s::numstrings, PC_CheckTokenString(), PC_ExpectTokenString(), PC_ReadToken(), PC_SetBaseFolder(), PRT_ERROR, PRT_MESSAGE, ptr(), random, source, source_t, SourceError(), strcpy(), bot_randomstring_s::string, bot_randomlist_s::string, token_s::string, strlen(), Sys_MilliSeconds(), token, token_t, and token_s::type. Referenced by BotSetupChatAI(). 00947 {
00948 int pass, size;
00949 char *ptr = NULL, chatmessagestring[MAX_MESSAGE_SIZE];
00950 source_t *source;
00951 token_t token;
00952 bot_randomlist_t *randomlist, *lastrandom, *random;
00953 bot_randomstring_t *randomstring;
00954
00955 #ifdef DEBUG
00956 int starttime = Sys_MilliSeconds();
00957 #endif //DEBUG
00958
00959 size = 0;
00960 randomlist = NULL;
00961 random = NULL;
00962 //the synonyms are parsed in two phases
00963 for (pass = 0; pass < 2; pass++)
00964 {
00965 //
00966 if (pass && size) ptr = (char *) GetClearedHunkMemory(size);
00967 //
00968 PC_SetBaseFolder(BOTFILESBASEFOLDER);
00969 source = LoadSourceFile(filename);
00970 if (!source)
00971 {
00972 botimport.Print(PRT_ERROR, "counldn't load %s\n", filename);
00973 return NULL;
00974 } //end if
00975 //
00976 randomlist = NULL; //list
00977 lastrandom = NULL; //last
00978 //
00979 while(PC_ReadToken(source, &token))
00980 {
00981 if (token.type != TT_NAME)
00982 {
00983 SourceError(source, "unknown random %s", token.string);
00984 FreeSource(source);
00985 return NULL;
00986 } //end if
00987 size += sizeof(bot_randomlist_t) + strlen(token.string) + 1;
00988 if (pass)
00989 {
00990 random = (bot_randomlist_t *) ptr;
00991 ptr += sizeof(bot_randomlist_t);
00992 random->string = ptr;
00993 ptr += strlen(token.string) + 1;
00994 strcpy(random->string, token.string);
00995 random->firstrandomstring = NULL;
00996 random->numstrings = 0;
00997 //
00998 if (lastrandom) lastrandom->next = random;
00999 else randomlist = random;
01000 lastrandom = random;
01001 } //end if
01002 if (!PC_ExpectTokenString(source, "=") ||
01003 !PC_ExpectTokenString(source, "{"))
01004 {
01005 FreeSource(source);
01006 return NULL;
01007 } //end if
01008 while(!PC_CheckTokenString(source, "}"))
01009 {
01010 if (!BotLoadChatMessage(source, chatmessagestring))
01011 {
01012 FreeSource(source);
01013 return NULL;
01014 } //end if
01015 size += sizeof(bot_randomstring_t) + strlen(chatmessagestring) + 1;
01016 if (pass)
01017 {
01018 randomstring = (bot_randomstring_t *) ptr;
01019 ptr += sizeof(bot_randomstring_t);
01020 randomstring->string = ptr;
01021 ptr += strlen(chatmessagestring) + 1;
01022 strcpy(randomstring->string, chatmessagestring);
01023 //
01024 random->numstrings++;
01025 randomstring->next = random->firstrandomstring;
01026 random->firstrandomstring = randomstring;
01027 } //end if
01028 } //end while
01029 } //end while
01030 //free the source after one pass
01031 FreeSource(source);
01032 } //end for
01033 botimport.Print(PRT_MESSAGE, "loaded %s\n", filename);
01034 //
01035 #ifdef DEBUG
01036 botimport.Print(PRT_MESSAGE, "random strings %d msec\n", Sys_MilliSeconds() - starttime);
01037 //BotDumpRandomStringList(randomlist);
01038 #endif //DEBUG
01039 //
01040 return randomlist;
01041 } //end of the function BotLoadRandomStrings
|
Here is the call graph for this function:

|
|
Definition at line 1828 of file be_ai_chat.c. References bot_chatmessage_t, bot_replychat_t, bot_replychatkey_t, BotCheckReplyChatIntegrety(), BotCheckValidReplyChatKeySet(), BOTFILESBASEFOLDER, BotFreeReplyChat(), botimport, BotLoadChatMessage(), BotLoadMatchPieces(), bot_chatmessage_s::chatmessage, bot_replychat_s::firstchatmessage, bot_replychatkey_s::flags, token_s::floatvalue, FreeSource(), GetClearedHunkMemory(), bot_replychat_s::keys, LoadSourceFile(), bot_replychatkey_s::match, bot_chatmessage_s::next, bot_replychatkey_s::next, bot_replychat_s::next, bot_replychat_s::numchatmessages, PC_CheckTokenString(), PC_ExpectTokenString(), PC_ExpectTokenType(), PC_ReadToken(), PC_SetBaseFolder(), bot_replychat_s::priority, PRT_ERROR, PRT_MESSAGE, source, source_t, SourceError(), strcat(), strcmp(), strcpy(), bot_replychatkey_s::string, token_s::string, StripDoubleQuotes(), strlen(), bot_chatmessage_s::time, token, token_t, TT_NUMBER, and TT_STRING. Referenced by BotSetupChatAI(). 01829 {
01830 char chatmessagestring[MAX_MESSAGE_SIZE];
01831 char namebuffer[MAX_MESSAGE_SIZE];
01832 source_t *source;
01833 token_t token;
01834 bot_chatmessage_t *chatmessage = NULL;
01835 bot_replychat_t *replychat, *replychatlist;
01836 bot_replychatkey_t *key;
01837
01838 PC_SetBaseFolder(BOTFILESBASEFOLDER);
01839 source = LoadSourceFile(filename);
01840 if (!source)
01841 {
01842 botimport.Print(PRT_ERROR, "counldn't load %s\n", filename);
01843 return NULL;
01844 } //end if
01845 //
01846 replychatlist = NULL;
01847 //
01848 while(PC_ReadToken(source, &token))
01849 {
01850 if (strcmp(token.string, "["))
01851 {
01852 SourceError(source, "expected [, found %s", token.string);
01853 BotFreeReplyChat(replychatlist);
01854 FreeSource(source);
01855 return NULL;
01856 } //end if
01857 //
01858 replychat = GetClearedHunkMemory(sizeof(bot_replychat_t));
01859 replychat->keys = NULL;
01860 replychat->next = replychatlist;
01861 replychatlist = replychat;
01862 //read the keys, there must be at least one key
01863 do
01864 {
01865 //allocate a key
01866 key = (bot_replychatkey_t *) GetClearedHunkMemory(sizeof(bot_replychatkey_t));
01867 key->flags = 0;
01868 key->string = NULL;
01869 key->match = NULL;
01870 key->next = replychat->keys;
01871 replychat->keys = key;
01872 //check for MUST BE PRESENT and MUST BE ABSENT keys
01873 if (PC_CheckTokenString(source, "&")) key->flags |= RCKFL_AND;
01874 else if (PC_CheckTokenString(source, "!")) key->flags |= RCKFL_NOT;
01875 //special keys
01876 if (PC_CheckTokenString(source, "name")) key->flags |= RCKFL_NAME;
01877 else if (PC_CheckTokenString(source, "female")) key->flags |= RCKFL_GENDERFEMALE;
01878 else if (PC_CheckTokenString(source, "male")) key->flags |= RCKFL_GENDERMALE;
01879 else if (PC_CheckTokenString(source, "it")) key->flags |= RCKFL_GENDERLESS;
01880 else if (PC_CheckTokenString(source, "(")) //match key
01881 {
01882 key->flags |= RCKFL_VARIABLES;
01883 key->match = BotLoadMatchPieces(source, ")");
01884 if (!key->match)
01885 {
01886 BotFreeReplyChat(replychatlist);
01887 return NULL;
01888 } //end if
01889 } //end else if
01890 else if (PC_CheckTokenString(source, "<")) //bot names
01891 {
01892 key->flags |= RCKFL_BOTNAMES;
01893 strcpy(namebuffer, "");
01894 do
01895 {
01896 if (!PC_ExpectTokenType(source, TT_STRING, 0, &token))
01897 {
01898 BotFreeReplyChat(replychatlist);
01899 FreeSource(source);
01900 return NULL;
01901 } //end if
01902 StripDoubleQuotes(token.string);
01903 if (strlen(namebuffer)) strcat(namebuffer, "\\");
01904 strcat(namebuffer, token.string);
01905 } while(PC_CheckTokenString(source, ","));
01906 if (!PC_ExpectTokenString(source, ">"))
01907 {
01908 BotFreeReplyChat(replychatlist);
01909 FreeSource(source);
01910 return NULL;
01911 } //end if
01912 key->string = (char *) GetClearedHunkMemory(strlen(namebuffer) + 1);
01913 strcpy(key->string, namebuffer);
01914 } //end else if
01915 else //normal string key
01916 {
01917 key->flags |= RCKFL_STRING;
01918 if (!PC_ExpectTokenType(source, TT_STRING, 0, &token))
01919 {
01920 BotFreeReplyChat(replychatlist);
01921 FreeSource(source);
01922 return NULL;
01923 } //end if
01924 StripDoubleQuotes(token.string);
01925 key->string = (char *) GetClearedHunkMemory(strlen(token.string) + 1);
01926 strcpy(key->string, token.string);
01927 } //end else
01928 //
01929 PC_CheckTokenString(source, ",");
01930 } while(!PC_CheckTokenString(source, "]"));
01931 //
01932 BotCheckValidReplyChatKeySet(source, replychat->keys);
01933 //read the = sign and the priority
01934 if (!PC_ExpectTokenString(source, "=") ||
01935 !PC_ExpectTokenType(source, TT_NUMBER, 0, &token))
01936 {
01937 BotFreeReplyChat(replychatlist);
01938 FreeSource(source);
01939 return NULL;
01940 } //end if
01941 replychat->priority = token.floatvalue;
01942 //read the leading {
01943 if (!PC_ExpectTokenString(source, "{"))
01944 {
01945 BotFreeReplyChat(replychatlist);
01946 FreeSource(source);
01947 return NULL;
01948 } //end if
01949 replychat->numchatmessages = 0;
01950 //while the trailing } is not found
01951 while(!PC_CheckTokenString(source, "}"))
01952 {
01953 if (!BotLoadChatMessage(source, chatmessagestring))
01954 {
01955 BotFreeReplyChat(replychatlist);
01956 FreeSource(source);
01957 return NULL;
01958 } //end if
01959 chatmessage = (bot_chatmessage_t *) GetClearedHunkMemory(sizeof(bot_chatmessage_t) + strlen(chatmessagestring) + 1);
01960 chatmessage->chatmessage = (char *) chatmessage + sizeof(bot_chatmessage_t);
01961 strcpy(chatmessage->chatmessage, chatmessagestring);
01962 chatmessage->time = -2*CHATMESSAGE_RECENTTIME;
01963 chatmessage->next = replychat->firstchatmessage;
01964 //add the chat message to the reply chat
01965 replychat->firstchatmessage = chatmessage;
01966 replychat->numchatmessages++;
01967 } //end while
01968 } //end while
01969 FreeSource(source);
01970 botimport.Print(PRT_MESSAGE, "loaded %s\n", filename);
01971 //
01972 //BotDumpReplyChat(replychatlist);
01973 if (bot_developer)
01974 {
01975 BotCheckReplyChatIntegrety(replychatlist);
01976 } //end if
01977 //
01978 if (!replychatlist) botimport.Print(PRT_MESSAGE, "no rchats\n");
01979 //
01980 return replychatlist;
01981 } //end of the function BotLoadReplyChat
|
Here is the call graph for this function:

|
|
Definition at line 595 of file be_ai_chat.c. References bot_synonym_t, bot_synonymlist_t, BOTFILESBASEFOLDER, botimport, bot_synonymlist_s::context, bot_synonymlist_s::firstsynonym, token_s::floatvalue, FreeSource(), GetClearedHunkMemory(), token_s::intvalue, LoadSourceFile(), bot_synonym_s::next, bot_synonymlist_s::next, PC_CheckTokenString(), PC_ExpectTokenString(), PC_ExpectTokenType(), PC_ReadToken(), PC_SetBaseFolder(), PRT_ERROR, PRT_MESSAGE, ptr(), source, source_t, SourceError(), strcmp(), strcpy(), bot_synonym_s::string, token_s::string, StripDoubleQuotes(), strlen(), token, token_t, bot_synonymlist_s::totalweight, TT_NUMBER, TT_STRING, token_s::type, and bot_synonym_s::weight. Referenced by BotSetupChatAI(). 00596 {
00597 int pass, size, contextlevel, numsynonyms;
00598 unsigned long int context, contextstack[32];
00599 char *ptr = NULL;
00600 source_t *source;
00601 token_t token;
00602 bot_synonymlist_t *synlist, *lastsyn, *syn;
00603 bot_synonym_t *synonym, *lastsynonym;
00604
00605 size = 0;
00606 synlist = NULL; //make compiler happy
00607 syn = NULL; //make compiler happy
00608 synonym = NULL; //make compiler happy
00609 //the synonyms are parsed in two phases
00610 for (pass = 0; pass < 2; pass++)
00611 {
00612 //
00613 if (pass && size) ptr = (char *) GetClearedHunkMemory(size);
00614 //
00615 PC_SetBaseFolder(BOTFILESBASEFOLDER);
00616 source = LoadSourceFile(filename);
00617 if (!source)
00618 {
00619 botimport.Print(PRT_ERROR, "counldn't load %s\n", filename);
00620 return NULL;
00621 } //end if
00622 //
00623 context = 0;
00624 contextlevel = 0;
00625 synlist = NULL; //list synonyms
00626 lastsyn = NULL; //last synonym in the list
00627 //
00628 while(PC_ReadToken(source, &token))
00629 {
00630 if (token.type == TT_NUMBER)
00631 {
00632 context |= token.intvalue;
00633 contextstack[contextlevel] = token.intvalue;
00634 contextlevel++;
00635 if (contextlevel >= 32)
00636 {
00637 SourceError(source, "more than 32 context levels");
00638 FreeSource(source);
00639 return NULL;
00640 } //end if
00641 if (!PC_ExpectTokenString(source, "{"))
00642 {
00643 FreeSource(source);
00644 return NULL;
00645 } //end if
00646 } //end if
00647 else if (token.type == TT_PUNCTUATION)
00648 {
00649 if (!strcmp(token.string, "}"))
00650 {
00651 contextlevel--;
00652 if (contextlevel < 0)
00653 {
00654 SourceError(source, "too many }");
00655 FreeSource(source);
00656 return NULL;
00657 } //end if
00658 context &= ~contextstack[contextlevel];
00659 } //end if
00660 else if (!strcmp(token.string, "["))
00661 {
00662 size += sizeof(bot_synonymlist_t);
00663 if (pass)
00664 {
00665 syn = (bot_synonymlist_t *) ptr;
00666 ptr += sizeof(bot_synonymlist_t);
00667 syn->context = context;
00668 syn->firstsynonym = NULL;
00669 syn->next = NULL;
00670 if (lastsyn) lastsyn->next = syn;
00671 else synlist = syn;
00672 lastsyn = syn;
00673 } //end if
00674 numsynonyms = 0;
00675 lastsynonym = NULL;
00676 while(1)
00677 {
00678 if (!PC_ExpectTokenString(source, "(") ||
00679 !PC_ExpectTokenType(source, TT_STRING, 0, &token))
00680 {
00681 FreeSource(source);
00682 return NULL;
00683 } //end if
00684 StripDoubleQuotes(token.string);
00685 if (strlen(token.string) <= 0)
00686 {
00687 SourceError(source, "empty string", token.string);
00688 FreeSource(source);
00689 return NULL;
00690 } //end if
00691 size += sizeof(bot_synonym_t) + strlen(token.string) + 1;
00692 if (pass)
00693 {
00694 synonym = (bot_synonym_t *) ptr;
00695 ptr += sizeof(bot_synonym_t);
00696 synonym->string = ptr;
00697 ptr += strlen(token.string) + 1;
00698 strcpy(synonym->string, token.string);
00699 //
00700 if (lastsynonym) lastsynonym->next = synonym;
00701 else syn->firstsynonym = synonym;
00702 lastsynonym = synonym;
00703 } //end if
00704 numsynonyms++;
00705 if (!PC_ExpectTokenString(source, ",") ||
00706 !PC_ExpectTokenType(source, TT_NUMBER, 0, &token) ||
00707 !PC_ExpectTokenString(source, ")"))
00708 {
00709 FreeSource(source);
00710 return NULL;
00711 } //end if
00712 if (pass)
00713 {
00714 synonym->weight = token.floatvalue;
00715 syn->totalweight += synonym->weight;
00716 } //end if
00717 if (PC_CheckTokenString(source, "]")) break;
00718 if (!PC_ExpectTokenString(source, ","))
00719 {
00720 FreeSource(source);
00721 return NULL;
00722 } //end if
00723 } //end while
00724 if (numsynonyms < 2)
00725 {
00726 SourceError(source, "synonym must have at least two entries\n");
00727 FreeSource(source);
00728 return NULL;
00729 } //end if
00730 } //end else
00731 else
00732 {
00733 SourceError(source, "unexpected %s", token.string);
00734 FreeSource(source);
00735 return NULL;
00736 } //end if
00737 } //end else if
00738 } //end while
00739 //
00740 FreeSource(source);
00741 //
00742 if (contextlevel > 0)
00743 {
00744 SourceError(source, "missing }");
00745 return NULL;
00746 } //end if
00747 } //end for
00748 botimport.Print(PRT_MESSAGE, "loaded %s\n", filename);
00749 //
00750 //BotDumpSynonymList(synlist);
00751 //
00752 return synlist;
00753 } //end of the function BotLoadSynonyms
|
Here is the call graph for this function:

|
||||||||||||||||||||
|
Definition at line 1468 of file be_ai_chat.c. References assert, bot_match_t, botimport, bot_matchvariable_s::length, match(), bot_matchvariable_s::offset, PRT_FATAL, strcpy(), bot_match_s::string, strncpy(), and bot_match_s::variables. 01469 {
01470 if (variable < 0 || variable >= MAX_MATCHVARIABLES)
01471 {
01472 botimport.Print(PRT_FATAL, "BotMatchVariable: variable out of range\n");
01473 strcpy(buf, "");
01474 return;
01475 } //end if
01476
01477 if (match->variables[variable].offset >= 0)
01478 {
01479 if (match->variables[variable].length < size)
01480 size = match->variables[variable].length+1;
01481 assert( match->variables[variable].offset >= 0 ); // bk001204
01482 strncpy(buf, &match->string[ (int) match->variables[variable].offset], size-1);
01483 buf[size-1] = '\0';
01484 } //end if
01485 else
01486 {
01487 strcpy(buf, "");
01488 } //end else
01489 return;
01490 } //end of the function BotMatchVariable
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 367 of file be_ai_chat.c. References bot_chatstate_t, bot_consolemessage_t, BotChatStateFromHandle(), cm, Com_Memcpy(), and bot_chatstate_s::firstmessage. Referenced by BotFreeChatState(). 00368 {
00369 bot_chatstate_t *cs;
00370
00371 cs = BotChatStateFromHandle(chatstate);
00372 if (!cs) return 0;
00373 if (cs->firstmessage)
00374 {
00375 Com_Memcpy(cm, cs->firstmessage, sizeof(bot_consolemessage_t));
00376 cm->next = cm->prev = NULL;
00377 return cm->handle;
00378 } //end if
00379 return 0;
00380 } //end of the function BotConsoleMessage
|
Here is the call graph for this function:

|
|
Definition at line 387 of file be_ai_chat.c. References bot_chatstate_t, BotChatStateFromHandle(), and bot_chatstate_s::numconsolemessages. 00388 {
00389 bot_chatstate_t *cs;
00390
00391 cs = BotChatStateFromHandle(chatstate);
00392 if (!cs) return 0;
00393 return cs->numconsolemessages;
00394 } //end of the function BotNumConsoleMessages
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 2465 of file be_ai_chat.c. References bot_chatstate_t, bot_chattype_t, BotChatStateFromHandle(), botimport, bot_chatstate_s::chat, LibVarGetValue(), bot_chattype_s::name, bot_chattype_s::next, bot_chattype_s::numchatmessages, PRT_MESSAGE, Q_stricmp(), t, type, and bot_chat_s::types. 02466 {
02467 bot_chatstate_t *cs;
02468 bot_chattype_t *t;
02469
02470 cs = BotChatStateFromHandle(chatstate);
02471 if (!cs) return 0;
02472
02473 for (t = cs->chat->types; t; t = t->next)
02474 {
02475 if (!Q_stricmp(t->name, type))
02476 {
02477 if (LibVarGetValue("bot_testichat")) {
02478 botimport.Print(PRT_MESSAGE, "%s has %d chat lines\n", type, t->numchatmessages);
02479 botimport.Print(PRT_MESSAGE, "-------------------\n");
02480 }
02481 return t->numchatmessages;
02482 } //end if
02483 } //end for
02484 return 0;
02485 } //end of the function BotNumInitialChats
|
Here is the call graph for this function:

|
|
Definition at line 2573 of file be_ai_chat.c. References bot_matchpiece_t, bot_replychat_t, bot_replychatkey_t, botimport, bot_matchpiece_s::firststring, bot_replychatkey_s::flags, bot_replychat_s::keys, bot_replychatkey_s::match, bot_matchpiece_s::next, bot_replychatkey_s::next, bot_replychat_s::priority, PRT_MESSAGE, bot_replychatkey_s::string, bot_matchstring_s::string, bot_matchpiece_s::type, and bot_matchpiece_s::variable. 02574 {
02575 bot_replychatkey_t *key;
02576 bot_matchpiece_t *mp;
02577
02578 botimport.Print(PRT_MESSAGE, "[");
02579 for (key = replychat->keys; key; key = key->next)
02580 {
02581 if (key->flags & RCKFL_AND) botimport.Print(PRT_MESSAGE, "&");
02582 else if (key->flags & RCKFL_NOT) botimport.Print(PRT_MESSAGE, "!");
02583 //
02584 if (key->flags & RCKFL_NAME) botimport.Print(PRT_MESSAGE, "name");
02585 else if (key->flags & RCKFL_GENDERFEMALE) botimport.Print(PRT_MESSAGE, "female");
02586 else if (key->flags & RCKFL_GENDERMALE) botimport.Print(PRT_MESSAGE, "male");
02587 else if (key->flags & RCKFL_GENDERLESS) botimport.Print(PRT_MESSAGE, "it");
02588 else if (key->flags & RCKFL_VARIABLES)
02589 {
02590 botimport.Print(PRT_MESSAGE, "(");
02591 for (mp = key->match; mp; mp = mp->next)
02592 {
02593 if (mp->type == MT_STRING) botimport.Print(PRT_MESSAGE, "\"%s\"", mp->firststring->string);
02594 else botimport.Print(PRT_MESSAGE, "%d", mp->variable);
02595 if (mp->next) botimport.Print(PRT_MESSAGE, ", ");
02596 } //end for
02597 botimport.Print(PRT_MESSAGE, ")");
02598 } //end if
02599 else if (key->flags & RCKFL_STRING)
02600 {
02601 botimport.Print(PRT_MESSAGE, "\"%s\"", key->string);
02602 } //end if
02603 if (key->next) botimport.Print(PRT_MESSAGE, ", ");
02604 else botimport.Print(PRT_MESSAGE, "] = %1.0f\n", replychat->priority);
02605 } //end for
02606 botimport.Print(PRT_MESSAGE, "{\n");
02607 } //end of the function BotPrintReplyChatKeys
|
|
||||||||||||||||
|
Definition at line 326 of file be_ai_chat.c. References AAS_Time(), AllocConsoleMessage(), bot_chatstate_t, bot_consolemessage_t, BotChatStateFromHandle(), botimport, bot_chatstate_s::firstmessage, bot_chatstate_s::handle, bot_consolemessage_s::handle, bot_chatstate_s::lastmessage, m, MAX_MESSAGE_SIZE, bot_consolemessage_s::message, bot_consolemessage_s::next, bot_chatstate_s::numconsolemessages, bot_consolemessage_s::prev, PRT_ERROR, strncpy(), bot_consolemessage_s::time, and bot_consolemessage_s::type. 00327 {
00328 bot_consolemessage_t *m;
00329 bot_chatstate_t *cs;
00330
00331 cs = BotChatStateFromHandle(chatstate);
00332 if (!cs) return;
00333
00334 m = AllocConsoleMessage();
00335 if (!m)
00336 {
00337 botimport.Print(PRT_ERROR, "empty console message heap\n");
00338 return;
00339 } //end if
00340 cs->handle++;
00341 if (cs->handle <= 0 || cs->handle > 8192) cs->handle = 1;
00342 m->handle = cs->handle;
00343 m->time = AAS_Time();
00344 m->type = type;
00345 strncpy(m->message, message, MAX_MESSAGE_SIZE);
00346 m->next = NULL;
00347 if (cs->lastmessage)
00348 {
00349 cs->lastmessage->next = m;
00350 m->prev = cs->lastmessage;
00351 cs->lastmessage = m;
00352 } //end if
00353 else
00354 {
00355 cs->lastmessage = m;
00356 cs->firstmessage = m;
00357 m->prev = NULL;
00358 } //end if
00359 cs->numconsolemessages++;
00360 } //end of the function BotQueueConsoleMessage
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 296 of file be_ai_chat.c. References bot_chatstate_t, bot_consolemessage_t, BotChatStateFromHandle(), bot_chatstate_s::firstmessage, FreeConsoleMessage(), bot_consolemessage_s::handle, bot_chatstate_s::lastmessage, m, bot_consolemessage_s::next, bot_chatstate_s::numconsolemessages, and bot_consolemessage_s::prev. Referenced by BotFreeChatState(). 00297 {
00298 bot_consolemessage_t *m, *nextm;
00299 bot_chatstate_t *cs;
00300
00301 cs = BotChatStateFromHandle(chatstate);
00302 if (!cs) return;
00303
00304 for (m = cs->firstmessage; m; m = nextm)
00305 {
00306 nextm = m->next;
00307 if (m->handle == handle)
00308 {
00309 if (m->next) m->next->prev = m->prev;
00310 else cs->lastmessage = m->prev;
00311 if (m->prev) m->prev->next = m->next;
00312 else cs->firstmessage = m->next;
00313
00314 FreeConsoleMessage(m);
00315 cs->numconsolemessages--;
00316 break;
00317 } //end if
00318 } //end for
00319 } //end of the function BotRemoveConsoleMessage
|
Here is the call graph for this function:

|
|
Definition at line 421 of file be_ai_chat.c. References i, memmove(), and strlen(). Referenced by BotEnterChat(), BotGetChatMessage(), and BotReplyChat(). 00422 {
00423 int i;
00424
00425 //remove all tildes from the chat message
00426 for (i = 0; message[i]; i++)
00427 {
00428 if (message[i] == '~')
00429 {
00430 memmove(&message[i], &message[i+1], strlen(&message[i+1])+1);
00431 } //end if
00432 } //end for
00433 } //end of the function BotRemoveTildes
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 814 of file be_ai_chat.c. References bot_synonym_t, bot_synonymlist_t, Com_Memcpy(), bot_synonymlist_s::context, bot_synonymlist_s::firstsynonym, memmove(), bot_synonym_s::next, bot_synonymlist_s::next, qfalse, bot_synonym_s::string, StringContainsWord(), and strlen(). Referenced by BotExpandChatMessage(). 00815 {
00816 char *str1, *str2, *replacement;
00817 bot_synonymlist_t *syn;
00818 bot_synonym_t *synonym;
00819
00820 for (str1 = string; *str1; )
00821 {
00822 //go to the start of the next word
00823 while(*str1 && *str1 <= ' ') str1++;
00824 if (!*str1) break;
00825 //
00826 for (syn = synonyms; syn; syn = syn->next)
00827 {
00828 if (!(syn->context & context)) continue;
00829 for (synonym = syn->firstsynonym->next; synonym; synonym = synonym->next)
00830 {
00831 str2 = synonym->string;
00832 //if the synonym is not at the front of the string continue
00833 str2 = StringContainsWord(str1, synonym->string, qfalse);
00834 if (!str2 || str2 != str1) continue;
00835 //
00836 replacement = syn->firstsynonym->string;
00837 //if the replacement IS in front of the string continue
00838 str2 = StringContainsWord(str1, replacement, qfalse);
00839 if (str2 && str2 == str1) continue;
00840 //
00841 memmove(str1 + strlen(replacement), str1+strlen(synonym->string),
00842 strlen(str1+strlen(synonym->string)) + 1);
00843 //append the synonum replacement
00844 Com_Memcpy(str1, replacement, strlen(replacement));
00845 //
00846 break;
00847 } //end for
00848 //if a synonym has been replaced
00849 if (synonym) break;
00850 } //end for
00851 //skip over this word
00852 while(*str1 && *str1 > ' ') str1++;
00853 if (!*str1) break;
00854 } //end while
00855 } //end of the function BotReplaceReplySynonyms
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 761 of file be_ai_chat.c. References bot_synonym_t, bot_synonymlist_t, bot_synonymlist_s::context, bot_synonymlist_s::firstsynonym, bot_synonymlist_s::next, bot_synonym_s::next, string(), bot_synonym_s::string, and StringReplaceWords(). Referenced by BotExpandChatMessage(). 00762 {
00763 bot_synonymlist_t *syn;
00764 bot_synonym_t *synonym;
00765
00766 for (syn = synonyms; syn; syn = syn->next)
00767 {
00768 if (!(syn->context & context)) continue;
00769 for (synonym = syn->firstsynonym->next; synonym; synonym = synonym->next)
00770 {
00771 StringReplaceWords(string, synonym->string, syn->firstsynonym->string);
00772 } //end for
00773 } //end for
00774 } //end of the function BotReplaceSynonyms
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 781 of file be_ai_chat.c. References bot_synonym_t, bot_synonymlist_t, bot_synonymlist_s::context, bot_synonymlist_s::firstsynonym, bot_synonym_s::next, bot_synonymlist_s::next, random, bot_synonym_s::string, string(), StringReplaceWords(), bot_synonymlist_s::totalweight, and bot_synonym_s::weight. Referenced by BotExpandChatMessage(). 00782 {
00783 bot_synonymlist_t *syn;
00784 bot_synonym_t *synonym, *replacement;
00785 float weight, curweight;
00786
00787 for (syn = synonyms; syn; syn = syn->next)
00788 {
00789 if (!(syn->context & context)) continue;
00790 //choose a weighted random replacement synonym
00791 weight = random() * syn->totalweight;
00792 if (!weight) continue;
00793 curweight = 0;
00794 for (replacement = syn->firstsynonym; replacement; replacement = replacement->next)
00795 {
00796 curweight += replacement->weight;
00797 if (weight < curweight) break;
00798 } //end for
00799 if (!replacement) continue;
00800 //replace all synonyms with the replacement
00801 for (synonym = syn->firstsynonym; synonym; synonym = synonym->next)
00802 {
00803 if (synonym == replacement) continue;
00804 StringReplaceWords(string, synonym->string, replacement->string);
00805 } //end for
00806 } //end for
00807 } //end of the function BotReplaceWeightedSynonyms
|
Here is the call graph for this function:

|
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Definition at line 2614 of file be_ai_chat.c. References AAS_Time(), bot_chatmessage_t, bot_chatstate_t, bot_match_t, bot_replychat_t, bot_replychatkey_t, BotChatStateFromHandle(), BotConstructChatMessage(), botimport, BotRemoveTildes(), bot_chatmessage_s::chatmessage, bot_chatstate_s::chatmessage, Com_Memcpy(), Com_Memset(), bot_replychat_s::firstchatmessage, bot_replychatkey_s::flags, bot_chatstate_s::gender, bot_replychat_s::keys, bot_matchvariable_s::length, LibVarGetValue(), m, match(), bot_replychatkey_s::match, bot_chatstate_s::name, bot_replychat_s::next, bot_replychatkey_s::next, bot_chatmessage_s::next, bot_matchvariable_s::offset, bot_replychat_s::priority, PRT_MESSAGE, qfalse, qtrue, random, strcat(), strcpy(), bot_match_s::string, bot_replychatkey_s::string, StringContains(), StringContainsWord(), StringsMatch(), strlen(), bot_chatmessage_s::time, and bot_match_s::variables. 02615 {
02616 bot_replychat_t *rchat, *bestrchat;
02617 bot_replychatkey_t *key;
02618 bot_chatmessage_t *m, *bestchatmessage;
02619 bot_match_t match, bestmatch;
02620 int bestpriority, num, found, res, numchatmessages, index;
02621 bot_chatstate_t *cs;
02622
02623 cs = BotChatStateFromHandle(chatstate);
02624 if (!cs) return qfalse;
02625 Com_Memset(&match, 0, sizeof(bot_match_t));
02626 strcpy(match.string, message);
02627 bestpriority = -1;
02628 bestchatmessage = NULL;
02629 bestrchat = NULL;
02630 //go through all the reply chats
02631 for (rchat = replychats; rchat; rchat = rchat->next)
02632 {
02633 found = qfalse;
02634 for (key = rchat->keys; key; key = key->next)
02635 {
02636 res = qfalse;
02637 //get the match result
02638 if (key->flags & RCKFL_NAME) res = (StringContains(message, cs->name, qfalse) != -1);
02639 else if (key->flags & RCKFL_BOTNAMES) res = (StringContains(key->string, cs->name, qfalse) != -1);
02640 else if (key->flags & RCKFL_GENDERFEMALE) res = (cs->gender == CHAT_GENDERFEMALE);
02641 else if (key->flags & RCKFL_GENDERMALE) res = (cs->gender == CHAT_GENDERMALE);
02642 else if (key->flags & RCKFL_GENDERLESS) res = (cs->gender == CHAT_GENDERLESS);
02643 else if (key->flags & RCKFL_VARIABLES) res = StringsMatch(key->match, &match);
02644 else if (key->flags & RCKFL_STRING) res = (StringContainsWord(message, key->string, qfalse) != NULL);
02645 //if the key must be present
02646 if (key->flags & RCKFL_AND)
02647 {
02648 if (!res)
02649 {
02650 found = qfalse;
02651 break;
02652 } //end if
02653 } //end else if
02654 //if the key must be absent
02655 else if (key->flags & RCKFL_NOT)
02656 {
02657 if (res)
02658 {
02659 found = qfalse;
02660 break;
02661 } //end if
02662 } //end if
02663 else if (res)
02664 {
02665 found = qtrue;
02666 } //end else
02667 } //end for
02668 //
02669 if (found)
02670 {
02671 if (rchat->priority > bestpriority)
02672 {
02673 numchatmessages = 0;
02674 for (m = rchat->firstchatmessage; m; m = m->next)
02675 {
02676 if (m->time > AAS_Time()) continue;
02677 numchatmessages++;
02678 } //end if
02679 num = random() * numchatmessages;
02680 for (m = rchat->firstchatmessage; m; m = m->next)
02681 {
02682 if (--num < 0) break;
02683 if (m->time > AAS_Time()) continue;
02684 } //end for
02685 //if the reply chat has a message
02686 if (m)
02687 {
02688 Com_Memcpy(&bestmatch, &match, sizeof(bot_match_t));
02689 bestchatmessage = m;
02690 bestrchat = rchat;
02691 bestpriority = rchat->priority;
02692 } //end if
02693 } //end if
02694 } //end if
02695 } //end for
02696 if (bestchatmessage)
02697 {
02698 index = strlen(bestmatch.string);
02699 if( var0 ) {
02700 strcat(bestmatch.string, var0);
02701 bestmatch.variables[0].offset = index;
02702 bestmatch.variables[0].length = strlen(var0);
02703 index += strlen(var0);
02704 }
02705 if( var1 ) {
02706 strcat(bestmatch.string, var1);
02707 bestmatch.variables[1].offset = index;
02708 bestmatch.variables[1].length = strlen(var1);
02709 index += strlen(var1);
02710 }
02711 if( var2 ) {
02712 strcat(bestmatch.string, var2);
02713 bestmatch.variables[2].offset = index;
02714 bestmatch.variables[2].length = strlen(var2);
02715 index += strlen(var2);
02716 }
02717 if( var3 ) {
02718 strcat(bestmatch.string, var3);
02719 bestmatch.variables[3].offset = index;
02720 bestmatch.variables[3].length = strlen(var3);
02721 index += strlen(var3);
02722 }
02723 if( var4 ) {
02724 strcat(bestmatch.string, var4);
02725 bestmatch.variables[4].offset = index;
02726 bestmatch.variables[4].length = strlen(var4);
02727 index += strlen(var4);
02728 }
02729 if( var5 ) {
02730 strcat(bestmatch.string, var5);
02731 bestmatch.variables[5].offset = index;
02732 bestmatch.variables[5].length = strlen(var5);
02733 index += strlen(var5);
02734 }
02735 if( var6 ) {
02736 strcat(bestmatch.string, var6);
02737 bestmatch.variables[6].offset = index;
02738 bestmatch.variables[6].length = strlen(var6);
02739 index += strlen(var6);
02740 }
02741 if( var7 ) {
02742 strcat(bestmatch.string, var7);
02743 bestmatch.variables[7].offset = index;
02744 bestmatch.variables[7].length = strlen(var7);
02745 index += strlen(var7);
02746 }
02747 if (LibVarGetValue("bot_testrchat"))
02748 {
02749 for (m = bestrchat->firstchatmessage; m; m = m->next)
02750 {
02751 BotConstructChatMessage(cs, m->chatmessage, mcontext, &bestmatch, vcontext, qtrue);
02752 BotRemoveTildes(cs->chatmessage);
02753 botimport.Print(PRT_MESSAGE, "%s\n", cs->chatmessage);
02754 } //end if
02755 } //end if
02756 else
02757 {
02758 bestchatmessage->time = AAS_Time() + CHATMESSAGE_RECENTTIME;
02759 BotConstructChatMessage(cs, bestchatmessage->chatmessage, mcontext, &bestmatch, vcontext, qtrue);
02760 } //end else
02761 return qtrue;
02762 } //end if
02763 return qfalse;
02764 } //end of the function BotReplyChat
|
Here is the call graph for this function:

|
|
Definition at line 2876 of file be_ai_chat.c. References bot_chatmessage_t, bot_replychat_t, bot_replychat_s::firstchatmessage, m, bot_chatmessage_s::next, bot_replychat_s::next, and bot_chatmessage_s::time. 02877 {
02878 bot_replychat_t *rchat;
02879 bot_chatmessage_t *m;
02880
02881 for (rchat = replychats; rchat; rchat = rchat->next)
02882 {
02883 for (m = rchat->firstchatmessage; m; m = m->next)
02884 {
02885 m->time = 0;
02886 } //end for
02887 } //end for
02888 } //end of the function BotResetChatAI
|
|
||||||||||||
|
Definition at line 2840 of file be_ai_chat.c. References bot_chatstate_t, BotChatStateFromHandle(), CHAT_GENDERFEMALE, CHAT_GENDERMALE, and bot_chatstate_s::gender. 02841 {
02842 bot_chatstate_t *cs;
02843
02844 cs = BotChatStateFromHandle(chatstate);
02845 if (!cs) return;
02846 switch(gender)
02847 {
02848 case CHAT_GENDERFEMALE: cs->gender = CHAT_GENDERFEMALE; break;
02849 case CHAT_GENDERMALE: cs->gender = CHAT_GENDERMALE; break;
02850 default: cs->gender = CHAT_GENDERLESS; break;
02851 } //end switch
02852 } //end of the function BotSetChatGender
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 2859 of file be_ai_chat.c. References bot_chatstate_t, BotChatStateFromHandle(), bot_chatstate_s::client, Com_Memset(), bot_chatstate_s::name, name, and strncpy(). 02860 {
02861 bot_chatstate_t *cs;
02862
02863 cs = BotChatStateFromHandle(chatstate);
02864 if (!cs) return;
02865 cs->client = client;
02866 Com_Memset(cs->name, 0, sizeof(cs->name));
02867 strncpy(cs->name, name, sizeof(cs->name));
02868 cs->name[sizeof(cs->name)-1] = '\0';
02869 } //end of the function BotSetChatName
|
Here is the call graph for this function:

|
|
Definition at line 2951 of file be_ai_chat.c. References botimport, BotLoadMatchTemplates(), BotLoadRandomStrings(), BotLoadReplyChat(), BotLoadSynonyms(), file, InitConsoleMessageHeap(), LibVarString(), LibVarValue(), matchtemplates, PRT_MESSAGE, randomstrings, replychats, synonyms, and Sys_MilliSeconds(). Referenced by Export_BotLibSetup(). 02952 {
02953 char *file;
02954
02955 #ifdef DEBUG
02956 int starttime = Sys_MilliSeconds();
02957 #endif //DEBUG
02958
02959 file = LibVarString("synfile", "syn.c");
02960 synonyms = BotLoadSynonyms(file);
02961 file = LibVarString("rndfile", "rnd.c");
02962 randomstrings = BotLoadRandomStrings(file);
02963 file = LibVarString("matchfile", "match.c");
02964 matchtemplates = BotLoadMatchTemplates(file);
02965 //
02966 if (!LibVarValue("nochat", "0"))
02967 {
02968 file = LibVarString("rchatfile", "rchat.c");
02969 replychats = BotLoadReplyChat(file);
02970 } //end if
02971
02972 InitConsoleMessageHeap();
02973
02974 #ifdef DEBUG
02975 botimport.Print(PRT_MESSAGE, "setup chat AI %d msec\n", Sys_MilliSeconds() - starttime);
02976 #endif //DEBUG
02977 return BLERR_NOERROR;
02978 } //end of the function BotSetupChatAI
|
Here is the call graph for this function:

|
|
Definition at line 2985 of file be_ai_chat.c. References botchatstates, BotFreeChatState(), BotFreeMatchTemplates(), BotFreeReplyChat(), consolemessageheap, FreeMemory(), i, ichatdata, matchtemplates, randomstrings, replychats, and synonyms. Referenced by Export_BotLibShutdown(). 02986 {
02987 int i;
02988
02989 //free all remaining chat states
02990 for(i = 0; i < MAX_CLIENTS; i++)
02991 {
02992 if (botchatstates[i])
02993 {
02994 BotFreeChatState(i);
02995 } //end if
02996 } //end for
02997 //free all cached chats
02998 for(i = 0; i < MAX_CLIENTS; i++)
02999 {
03000 if (ichatdata[i])
03001 {
03002 FreeMemory(ichatdata[i]->chat);
03003 FreeMemory(ichatdata[i]);
03004 ichatdata[i] = NULL;
03005 } //end if
03006 } //end for
03007 if (consolemessageheap) FreeMemory(consolemessageheap);
03008 consolemessageheap = NULL;
03009 if (matchtemplates) BotFreeMatchTemplates(matchtemplates);
03010 matchtemplates = NULL;
03011 if (randomstrings) FreeMemory(randomstrings);
03012 randomstrings = NULL;
03013 if (synonyms) FreeMemory(synonyms);
03014 synonyms = NULL;
03015 if (replychats) BotFreeReplyChat(replychats);
03016 replychats = NULL;
03017 } //end of the function BotShutdownChatAI
|
Here is the call graph for this function:

|
|
Definition at line 283 of file be_ai_chat.c. References bot_consolemessage_t, freeconsolemessages, bot_consolemessage_s::next, and bot_consolemessage_s::prev. Referenced by BotRemoveConsoleMessage(). 00284 {
00285 if (freeconsolemessages) freeconsolemessages->prev = message;
00286 message->prev = NULL;
00287 message->next = freeconsolemessages;
00288 freeconsolemessages = message;
00289 } //end of the function FreeConsoleMessage
|
|
|
Definition at line 240 of file be_ai_chat.c. References bot_consolemessage_t, consolemessageheap, freeconsolemessages, FreeMemory(), GetClearedHunkMemory(), i, LibVarValue(), bot_consolemessage_s::next, and bot_consolemessage_s::prev. Referenced by BotSetupChatAI(). 00241 {
00242 int i, max_messages;
00243
00244 if (consolemessageheap) FreeMemory(consolemessageheap);
00245 //
00246 max_messages = (int) LibVarValue("max_messages", "1024");
00247 consolemessageheap = (bot_consolemessage_t *) GetClearedHunkMemory(max_messages *
00248 sizeof(bot_consolemessage_t));
00249 consolemessageheap[0].prev = NULL;
00250 consolemessageheap[0].next = &consolemessageheap[1];
00251 for (i = 1; i < max_messages-1; i++)
00252 {
00253 consolemessageheap[i].prev = &consolemessageheap[i - 1];
00254 consolemessageheap[i].next = &consolemessageheap[i + 1];
00255 } //end for
00256 consolemessageheap[max_messages-1].prev = &consolemessageheap[max_messages-2];
00257 consolemessageheap[max_messages-1].next = NULL;
00258 //pointer to the free console messages
00259 freeconsolemessages = consolemessageheap;
00260 } //end of the function InitConsoleMessageHeap
|
Here is the call graph for this function:

|
|
Definition at line 401 of file be_ai_chat.c. References c. Referenced by UnifyWhiteSpaces(). 00402 {
00403 if ((c >= 'a' && c <= 'z')
00404 || (c >= 'A' && c <= 'Z')
00405 || (c >= '0' && c <= '9')
00406 || c == '(' || c == ')'
00407 || c == '?' || c == ':'
00408 || c == '\''|| c == '/'
00409 || c == ',' || c == '.'
00410 || c == '[' || c == ']'
00411 || c == '-' || c == '_'
00412 || c == '+' || c == '=') return qfalse;
00413 return qtrue;
00414 } //end of the function IsWhiteSpace
|
|
|
Definition at line 1048 of file be_ai_chat.c. References bot_randomlist_t, bot_randomstring_t, bot_randomlist_s::firstrandomstring, i, name, bot_randomstring_s::next, bot_randomlist_s::next, bot_randomlist_s::numstrings, random, strcmp(), bot_randomstring_s::string, and bot_randomlist_s::string. Referenced by BotCheckChatMessageIntegrety(), and BotExpandChatMessage(). 01049 {
01050 bot_randomlist_t *random;
01051 bot_randomstring_t *rs;
01052 int i;
01053
01054 for (random = randomstrings; random; random = random->next)
01055 {
01056 if (!strcmp(random->string, name))
01057 {
01058 i = random() * random->numstrings;
01059 for (rs = random->firstrandomstring; rs; rs = rs->next)
01060 {
01061 if (--i < 0) break;
01062 } //end for
01063 if (rs)
01064 {
01065 return rs->string;
01066 } //end if
01067 } //end for
01068 } //end for
01069 return NULL;
01070 } //end of the function RandomString
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 464 of file be_ai_chat.c. 00465 {
00466 int len, i, j, index;
00467
00468 if (str1 == NULL || str2 == NULL) return -1;
00469
00470 len = strlen(str1) - strlen(str2);
00471 index = 0;
00472 for (i = 0; i <= len; i++, str1++, index++)
00473 {
00474 for (j = 0; str2[j]; j++)
00475 {
00476 if (casesensitive)
00477 {
00478 if (str1[j] != str2[j]) break;
00479 } //end if
00480 else
00481 {
00482 if (toupper(str1[j]) != toupper(str2[j])) break;
00483 } //end else
00484 } //end for
00485 if (!str2[j]) return index;
00486 } //end for
00487 return -1;
00488 } //end of the function StringContains
|
|
||||||||||||||||
|
Definition at line 495 of file be_ai_chat.c. References i, j, strlen(), and toupper(). Referenced by BotReplaceReplySynonyms(), BotReplyChat(), and StringReplaceWords(). 00496 {
00497 int len, i, j;
00498
00499 len = strlen(str1) - strlen(str2);
00500 for (i = 0; i <= len; i++, str1++)
00501 {
00502 //if not at the start of the string
00503 if (i)
00504 {
00505 //skip to the start of the next word
00506 while(*str1 && *str1 != ' ' && *str1 != '.' && *str1 != ',' && *str1 != '!') str1++;
00507 if (!*str1) break;
00508 str1++;
00509 } //end for
00510 //compare the word
00511 for (j = 0; str2[j]; j++)
00512 {
00513 if (casesensitive)
00514 {
00515 if (str1[j] != str2[j]) break;
00516 } //end if
00517 else
00518 {
00519 if (toupper(str1[j]) != toupper(str2[j])) break;
00520 } //end else
00521 } //end for
00522 //if there was a word match
00523 if (!str2[j])
00524 {
00525 //if the first string has an end of word
00526 if (!str1[j] || str1[j] == ' ' || str1[j] == '.' || str1[j] == ',' || str1[j] == '!') return str1;
00527 } //end if
00528 } //end for
00529 return NULL;
00530 } //end of the function StringContainsWord
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 537 of file be_ai_chat.c. References Com_Memcpy(), memmove(), qfalse, string(), StringContainsWord(), and strlen(). Referenced by BotReplaceSynonyms(), and BotReplaceWeightedSynonyms(). 00538 {
00539 char *str, *str2;
00540
00541 //find the synonym in the string
00542 str = StringContainsWord(string, synonym, qfalse);
00543 //if the synonym occured in the string
00544 while(str)
00545 {
00546 //if the synonym isn't part of the replacement which is already in the string
00547 //usefull for abreviations
00548 str2 = StringContainsWord(string, replacement, qfalse);
00549 while(str2)
00550 {
00551 if (str2 <= str && str < str2 + strlen(replacement)) break;
00552 str2 = StringContainsWord(str2+1, replacement, qfalse);
00553 } //end while
00554 if (!str2)
00555 {
00556 memmove(str + strlen(replacement), str+strlen(synonym), strlen(str+strlen(synonym))+1);
00557 //append the synonum replacement
00558 Com_Memcpy(str, replacement, strlen(replacement));
00559 } //end if
00560 //find the next synonym in the string
00561 str = StringContainsWord(str+strlen(replacement), synonym, qfalse);
00562 } //end if
00563 } //end of the function StringReplaceWords
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 1357 of file be_ai_chat.c. References assert, bot_match_t, bot_matchpiece_t, bot_matchstring_t, bot_matchpiece_s::firststring, bot_matchvariable_s::length, match(), bot_matchstring_s::next, bot_matchpiece_s::next, bot_matchvariable_s::offset, qfalse, bot_matchstring_s::string, bot_match_s::string, StringContains(), strlen(), bot_matchpiece_s::type, bot_matchpiece_s::variable, and bot_match_s::variables. Referenced by BotFindMatch(), and BotReplyChat(). 01358 {
01359 int lastvariable, index;
01360 char *strptr, *newstrptr;
01361 bot_matchpiece_t *mp;
01362 bot_matchstring_t *ms;
01363
01364 //no last variable
01365 lastvariable = -1;
01366 //pointer to the string to compare the match string with
01367 strptr = match->string;
01368 //Log_Write("match: %s", strptr);
01369 //compare the string with the current match string
01370 for (mp = pieces; mp; mp = mp->next)
01371 {
01372 //if it is a piece of string
01373 if (mp->type == MT_STRING)
01374 {
01375 newstrptr = NULL;
01376 for (ms = mp->firststring; ms; ms = ms->next)
01377 {
01378 if (!strlen(ms->string))
01379 {
01380 newstrptr = strptr;
01381 break;
01382 } //end if
01383 //Log_Write("MT_STRING: %s", mp->string);
01384 index = StringContains(strptr, ms->string, qfalse);
01385 if (index >= 0)
01386 {
01387 newstrptr = strptr + index;
01388 if (lastvariable >= 0)
01389 {
01390 match->variables[lastvariable].length =
01391 (newstrptr - match->string) - match->variables[lastvariable].offset;
01392 //newstrptr - match->variables[lastvariable].ptr;
01393 lastvariable = -1;
01394 break;
01395 } //end if
01396 else if (index == 0)
01397 {
01398 break;
01399 } //end else
01400 newstrptr = NULL;
01401 } //end if
01402 } //end for
01403 if (!newstrptr) return qfalse;
01404 strptr = newstrptr + strlen(ms->string);
01405 } //end if
01406 //if it is a variable piece of string
01407 else if (mp->type == MT_VARIABLE)
01408 {
01409 //Log_Write("MT_VARIABLE");
01410 match->variables[mp->variable].offset = strptr - match->string;
01411 lastvariable = mp->variable;
01412 } //end else if
01413 } //end for
01414 //if a match was found
01415 if (!mp && (lastvariable >= 0 || !strlen(strptr)))
01416 {
01417 //if the last piece was a variable string
01418 if (lastvariable >= 0)
01419 {
01420 assert( match->variables[lastvariable].offset >= 0 ); // bk001204
01421 match->variables[lastvariable].length =
01422 strlen(&match->string[ (int) match->variables[lastvariable].offset]);
01423 } //end if
01424 return qtrue;
01425 } //end if
01426 return qfalse;
01427 } //end of the function StringsMatch
|
Here is the call graph for this function:

|
|
Definition at line 440 of file be_ai_chat.c. References IsWhiteSpace(), memmove(), ptr(), string(), and strlen(). 00441 {
00442 char *ptr, *oldptr;
00443
00444 for (ptr = oldptr = string; *ptr; oldptr = ptr)
00445 {
00446 while(*ptr && IsWhiteSpace(*ptr)) ptr++;
00447 if (ptr > oldptr)
00448 {
00449 //if not at the start and not at the end of the string
00450 //write only one space
00451 if (oldptr > string && *ptr) *oldptr++ = ' ';
00452 //remove all other white spaces
00453 if (ptr > oldptr) memmove(oldptr, ptr, strlen(ptr)+1);
00454 } //end if
00455 while(*ptr && !IsWhiteSpace(*ptr)) ptr++;
00456 } //end while
00457 } //end of the function UnifyWhiteSpaces
|
Here is the call graph for this function:

|
|
Definition at line 200 of file be_ai_chat.c. Referenced by BotAllocChatState(), BotChatStateFromHandle(), BotFreeChatState(), and BotShutdownChatAI(). |
|
|
Definition at line 202 of file be_ai_chat.c. Referenced by BotShutdownChatAI(), and InitConsoleMessageHeap(). |
|
|
Definition at line 203 of file be_ai_chat.c. Referenced by AllocConsoleMessage(), FreeConsoleMessage(), and InitConsoleMessageHeap(). |
|
|
Definition at line 198 of file be_ai_chat.c. Referenced by BotLoadChatFile(), and BotShutdownChatAI(). |
|
|
Definition at line 205 of file be_ai_chat.c. Referenced by BotSetupChatAI(), and BotShutdownChatAI(). |
|
|
Definition at line 209 of file be_ai_chat.c. Referenced by BotSetupChatAI(), and BotShutdownChatAI(). |
|
|
Definition at line 211 of file be_ai_chat.c. Referenced by BotSetupChatAI(), and BotShutdownChatAI(). |
|
|
Definition at line 207 of file be_ai_chat.c. Referenced by BotSetupChatAI(), and BotShutdownChatAI(). |
1.3.9.1