📄 be_ai_chat.c
字号:
"leave space for the key %s with the & prefix", key->string);
} //end if
} //end if
} //end for
} //end else
if ((key->flags & RCKFL_NOT) && (key->flags & RCKFL_STRING))
{
for (key2 = keys; key2; key2 = key2->next)
{
if (key2 == key) continue;
if (key2->flags & RCKFL_NOT) continue;
if (key2->flags & RCKFL_STRING)
{
if (StringContains(key2->string, key->string, qfalse) != -1)
{
SourceWarning(source, "the key %s with prefix ! is inside the key %s", key->string, key2->string);
} //end if
} //end if
else if (key2->flags & RCKFL_VARIABLES)
{
for (m = key2->match; m; m = m->next)
{
if (m->type == MT_STRING)
{
for (ms = m->firststring; ms; ms = ms->next)
{
if (StringContains(ms->string, key->string, qfalse) != -1)
{
SourceWarning(source, "the key %s with prefix ! is inside "
"the match template string %s", key->string, ms->string);
} //end if
} //end for
} //end if
} //end for
} //end else if
} //end for
} //end if
} //end for
if (allprefixed) SourceWarning(source, "all keys have a & or ! prefix");
if (hasvariableskey && hasstringkey)
{
SourceWarning(source, "variables from the match template(s) could be "
"invalid when outputting one of the chat messages");
} //end if
} //end of the function BotCheckValidReplyChatKeySet
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
bot_replychat_t *BotLoadReplyChat(char *filename)
{
char chatmessagestring[MAX_MESSAGE_SIZE];
char namebuffer[MAX_MESSAGE_SIZE];
source_t *source;
token_t token;
bot_chatmessage_t *chatmessage = NULL;
bot_replychat_t *replychat, *replychatlist;
bot_replychatkey_t *key;
PC_SetBaseFolder(BOTFILESBASEFOLDER);
source = LoadSourceFile(filename);
if (!source)
{
botimport.Print(PRT_ERROR, "counldn't load %s\n", filename);
return NULL;
} //end if
//
replychatlist = NULL;
//
while(PC_ReadToken(source, &token))
{
if (strcmp(token.string, "["))
{
SourceError(source, "expected [, found %s", token.string);
BotFreeReplyChat(replychatlist);
FreeSource(source);
return NULL;
} //end if
//
replychat = GetClearedHunkMemory(sizeof(bot_replychat_t));
replychat->keys = NULL;
replychat->next = replychatlist;
replychatlist = replychat;
//read the keys, there must be at least one key
do
{
//allocate a key
key = (bot_replychatkey_t *) GetClearedHunkMemory(sizeof(bot_replychatkey_t));
key->flags = 0;
key->string = NULL;
key->match = NULL;
key->next = replychat->keys;
replychat->keys = key;
//check for MUST BE PRESENT and MUST BE ABSENT keys
if (PC_CheckTokenString(source, "&")) key->flags |= RCKFL_AND;
else if (PC_CheckTokenString(source, "!")) key->flags |= RCKFL_NOT;
//special keys
if (PC_CheckTokenString(source, "name")) key->flags |= RCKFL_NAME;
else if (PC_CheckTokenString(source, "female")) key->flags |= RCKFL_GENDERFEMALE;
else if (PC_CheckTokenString(source, "male")) key->flags |= RCKFL_GENDERMALE;
else if (PC_CheckTokenString(source, "it")) key->flags |= RCKFL_GENDERLESS;
else if (PC_CheckTokenString(source, "(")) //match key
{
key->flags |= RCKFL_VARIABLES;
key->match = BotLoadMatchPieces(source, ")");
if (!key->match)
{
BotFreeReplyChat(replychatlist);
return NULL;
} //end if
} //end else if
else if (PC_CheckTokenString(source, "<")) //bot names
{
key->flags |= RCKFL_BOTNAMES;
strcpy(namebuffer, "");
do
{
if (!PC_ExpectTokenType(source, TT_STRING, 0, &token))
{
BotFreeReplyChat(replychatlist);
FreeSource(source);
return NULL;
} //end if
StripDoubleQuotes(token.string);
if (strlen(namebuffer)) strcat(namebuffer, "\\");
strcat(namebuffer, token.string);
} while(PC_CheckTokenString(source, ","));
if (!PC_ExpectTokenString(source, ">"))
{
BotFreeReplyChat(replychatlist);
FreeSource(source);
return NULL;
} //end if
key->string = (char *) GetClearedHunkMemory(strlen(namebuffer) + 1);
strcpy(key->string, namebuffer);
} //end else if
else //normal string key
{
key->flags |= RCKFL_STRING;
if (!PC_ExpectTokenType(source, TT_STRING, 0, &token))
{
BotFreeReplyChat(replychatlist);
FreeSource(source);
return NULL;
} //end if
StripDoubleQuotes(token.string);
key->string = (char *) GetClearedHunkMemory(strlen(token.string) + 1);
strcpy(key->string, token.string);
} //end else
//
PC_CheckTokenString(source, ",");
} while(!PC_CheckTokenString(source, "]"));
//
BotCheckValidReplyChatKeySet(source, replychat->keys);
//read the = sign and the priority
if (!PC_ExpectTokenString(source, "=") ||
!PC_ExpectTokenType(source, TT_NUMBER, 0, &token))
{
BotFreeReplyChat(replychatlist);
FreeSource(source);
return NULL;
} //end if
replychat->priority = token.floatvalue;
//read the leading {
if (!PC_ExpectTokenString(source, "{"))
{
BotFreeReplyChat(replychatlist);
FreeSource(source);
return NULL;
} //end if
replychat->numchatmessages = 0;
//while the trailing } is not found
while(!PC_CheckTokenString(source, "}"))
{
if (!BotLoadChatMessage(source, chatmessagestring))
{
BotFreeReplyChat(replychatlist);
FreeSource(source);
return NULL;
} //end if
chatmessage = (bot_chatmessage_t *) GetClearedHunkMemory(sizeof(bot_chatmessage_t) + strlen(chatmessagestring) + 1);
chatmessage->chatmessage = (char *) chatmessage + sizeof(bot_chatmessage_t);
strcpy(chatmessage->chatmessage, chatmessagestring);
chatmessage->time = -2*CHATMESSAGE_RECENTTIME;
chatmessage->next = replychat->firstchatmessage;
//add the chat message to the reply chat
replychat->firstchatmessage = chatmessage;
replychat->numchatmessages++;
} //end while
} //end while
FreeSource(source);
botimport.Print(PRT_MESSAGE, "loaded %s\n", filename);
//
//BotDumpReplyChat(replychatlist);
if (bot_developer)
{
BotCheckReplyChatIntegrety(replychatlist);
} //end if
//
if (!replychatlist) botimport.Print(PRT_MESSAGE, "no rchats\n");
//
return replychatlist;
} //end of the function BotLoadReplyChat
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void BotDumpInitialChat(bot_chat_t *chat)
{
bot_chattype_t *t;
bot_chatmessage_t *m;
Log_Write("{");
for (t = chat->types; t; t = t->next)
{
Log_Write(" type \"%s\"", t->name);
Log_Write(" {");
Log_Write(" numchatmessages = %d", t->numchatmessages);
for (m = t->firstchatmessage; m; m = m->next)
{
Log_Write(" \"%s\"", m->chatmessage);
} //end for
Log_Write(" }");
} //end for
Log_Write("}");
} //end of the function BotDumpInitialChat
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
bot_chat_t *BotLoadInitialChat(char *chatfile, char *chatname)
{
int pass, foundchat, indent, size;
char *ptr = NULL;
char chatmessagestring[MAX_MESSAGE_SIZE];
source_t *source;
token_t token;
bot_chat_t *chat = NULL;
bot_chattype_t *chattype = NULL;
bot_chatmessage_t *chatmessage = NULL;
#ifdef DEBUG
int starttime;
starttime = Sys_MilliSeconds();
#endif //DEBUG
//
size = 0;
foundchat = qfalse;
//a bot chat is parsed in two phases
for (pass = 0; pass < 2; pass++)
{
//allocate memory
if (pass && size) ptr = (char *) GetClearedMemory(size);
//load the source file
PC_SetBaseFolder(BOTFILESBASEFOLDER);
source = LoadSourceFile(chatfile);
if (!source)
{
botimport.Print(PRT_ERROR, "counldn't load %s\n", chatfile);
return NULL;
} //end if
//chat structure
if (pass)
{
chat = (bot_chat_t *) ptr;
ptr += sizeof(bot_chat_t);
} //end if
size = sizeof(bot_chat_t);
//
while(PC_ReadToken(source, &token))
{
if (!strcmp(token.string, "chat"))
{
if (!PC_ExpectTokenType(source, TT_STRING, 0, &token))
{
FreeSource(source);
return NULL;
} //end if
StripDoubleQuotes(token.string);
//after the chat name we expect a opening brace
if (!PC_ExpectTokenString(source, "{"))
{
FreeSource(source);
return NULL;
} //end if
//if the chat name is found
if (!Q_stricmp(token.string, chatname))
{
foundchat = qtrue;
//read the chat types
while(1)
{
if (!PC_ExpectAnyToken(source, &token))
{
FreeSource(source);
return NULL;
} //end if
if (!strcmp(token.string, "}")) break;
if (strcmp(token.string, "type"))
{
SourceError(source, "expected type found %s\n", token.string);
FreeSource(source);
return NULL;
} //end if
//expect the chat type name
if (!PC_ExpectTokenType(source, TT_STRING, 0, &token) ||
!PC_ExpectTokenString(source, "{"))
{
FreeSource(source);
return NULL;
} //end if
StripDoubleQuotes(token.string);
if (pass)
{
chattype = (bot_chattype_t *) ptr;
strncpy(chattype->name, token.string, MAX_CHATTYPE_NAME);
chattype->firstchatmessage = NULL;
//add the chat type to the chat
chattype->next = chat->types;
chat->types = chattype;
//
ptr += sizeof(bot_chattype_t);
} //end if
size += sizeof(bot_chattype_t);
//read the chat messages
while(!PC_CheckTokenString(source, "}"))
{
if (!BotLoadChatMessage(source, chatmessagestring))
{
FreeSource(source);
return NULL;
} //end if
if (pass)
{
chatmessage = (bot_chatmessage_t *) ptr;
chatmessage->time = -2*CHATMESSAGE_RECENTTIME;
//put the chat message in the list
chatmessage->next = chattype->firstchatmessage;
chattype->firstchatmessage = chatmessage;
//store the chat message
ptr += sizeof(bot_chatmessage_t);
chatmessage->chatmessage = ptr;
strcpy(chatmessage->chatmessage, chatmessagestring);
ptr += strlen(chatmessagestring) + 1;
//the number of chat messages increased
chattype->numchatmessages++;
} //end if
size += sizeof(bot_chatmessage_t) + strlen(chatmessagestring) + 1;
} //end if
} //end while
} //end if
else //skip the bot chat
{
indent = 1;
while(indent)
{
if (!PC_ExpectAnyToken(source, &token))
{
FreeSource(source);
return NULL;
} //end if
if (!strcmp(token.string, "{")) indent++;
else if (!strcmp(token.string, "}")) indent--;
} //end while
} //end else
} //end if
else
{
SourceError(source, "unknown definition %s\n", token.string);
FreeSource(source);
return NULL;
} //end else
} //end while
//free the source
FreeSource(source);
//if the requested character is not found
if (!foundchat)
{
botimport.Print(PRT_ERROR, "couldn't find chat %s in %s\n", chatname, chatfile);
return NULL;
} //end if
} //end for
//
botimport.Print(PRT_MESSAGE, "loaded %s from %s\n", chatname, chatfile);
//
//BotDumpInitialChat(chat);
if (bot_developer)
{
BotCheckInitialChatIntegrety(chat);
} //end if
#ifdef DEBUG
botimport.Print(PRT_MESSAGE, "initial chats loaded in %d msec\n", Sys_MilliSeconds() - starttime);
#endif //DEBUG
//character was read succesfully
return chat;
} //end of the function BotLoadInitialChat
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void BotFreeChatFile(int chatstate)
{
bot_chatstate_t *cs;
cs = BotChatStateFromHandle(chatstate);
if (!cs) return;
if (cs->chat) FreeMemory(cs->chat);
cs->chat = NULL;
} //end of the function BotFreeChatFile
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int BotLoadChatFile(int chatstate, char *chatfile, char *chatname)
{
bot_chatstate_t *cs;
int n, avail = 0;
cs = BotChatStateFromHandle(chatstate);
if (!cs) return BLERR_CANNOTLOADICHAT;
BotFreeChatFile(chatstate);
if (!LibVarGetValue("bot_reloadcharacters"))
{
avail = -1;
for( n = 0; n < MAX_CLIENTS; n++ ) {
if( !ichatdata[n] ) {
if( avail == -1 ) {
avail = n;
}
continue;
}
if( strcmp( chatfile
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -