Planeshift
|
00001 /* 00002 * psnpcdialog.h 00003 * 00004 * Copyright (C) 2001 Atomic Blue ([email protected], http://www.atomicblue.org) 00005 * 00006 * 00007 * This program is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU General Public License 00009 * as published by the Free Software Foundation (version 2 of the License) 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software 00016 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 * 00018 * 00019 */ 00020 #ifndef __PS_IMP_NPC_DIALOG__ 00021 #define __PS_IMP_NPC_DIALOG__ 00022 //============================================================================= 00023 // Crystal Space Includes 00024 //============================================================================= 00025 #include <cstypes.h> 00026 #include <iutil/comp.h> 00027 #include <iutil/eventh.h> 00028 #include <csutil/scf.h> 00029 #include <cstool/collider.h> 00030 #include <ivaria/collider.h> 00031 00032 //============================================================================= 00033 // Project Includes 00034 //============================================================================= 00035 #include "util/psconst.h" 00036 #include "util/psstring.h" 00037 00038 #include <idal.h> 00039 00040 00041 //============================================================================= 00042 // Local Includes 00043 //============================================================================= 00044 #include "dictionary.h" 00045 00046 class gemNPC; 00047 class NPCDialogDict; 00048 class NpcResponse; 00049 class GemActor; 00050 class Client; 00051 00052 struct iObjectRegistry; 00053 00054 struct KnowledgeArea 00055 { 00056 csString area; 00057 int priority; 00058 00059 bool operator==(KnowledgeArea &other) 00060 { 00061 return (priority==other.priority && area == other.area); 00062 }; 00063 bool operator<(KnowledgeArea &other) 00064 { 00065 if(priority<other.priority) 00066 { 00067 return true; 00068 } 00069 else if(priority>other.priority) 00070 { 00071 return false; 00072 } 00073 // Priority is equal so check area. 00074 if(strcmp(area,other.area)<0) 00075 { 00076 return true; 00077 } 00078 else 00079 { 00080 return false; 00081 } 00082 }; 00083 }; 00084 00088 class NpcTriggerSentence 00089 { 00090 protected: 00091 csArray<NpcTerm*> terms; 00092 csString str; 00093 00094 public: 00095 NpcTriggerSentence() {}; 00096 void AddToSentence(NpcTerm* next_word); 00097 size_t TermLength() 00098 { 00099 return terms.GetSize(); 00100 } 00101 const csString &GetString(); 00102 void operator=(NpcTriggerSentence &other) 00103 { 00104 terms = other.terms; 00105 str=other.str; 00106 } 00107 NpcTerm* &Term(size_t i) 00108 { 00109 return terms[i]; 00110 } 00111 }; 00112 00113 00119 class DialogHistory 00120 { 00121 protected: 00122 struct DialogHistoryEntry 00123 { 00124 int playerID; 00125 int responseID; 00126 csTicks when; 00127 }; 00128 csArray<DialogHistoryEntry> history; 00129 int counter; 00130 public: 00131 DialogHistory() 00132 { 00133 counter=0; 00134 } 00135 00136 void AddToHistory(int playerID, int responseID, csTicks when); 00137 bool EverSaid(int playerID, int responseID, csTicks &howLongAgo, int ×); 00138 }; 00139 #define MAX_HISTORY_LEN 100 00140 00146 class psNPCDialog 00147 { 00148 protected: 00149 gemNPC* self; 00150 csArray<KnowledgeArea*> knowareas; 00151 00152 psString antecedent_her, 00153 antecedent_him, 00154 antecedent_it, 00155 antecedent_them; 00156 iDataConnection* db; 00157 csRandomGen* randomgen; 00158 gemActor* currentplayer; 00159 Client* currentClient; 00160 DialogHistory dialogHistory; 00161 00162 NpcResponse* FindResponse(csString &trigger,const char* text, int questID = -1); 00163 NpcResponse* FindResponseWithAllPrior(const char* area,const char* trigger, int questID = -1); 00164 bool CheckPronouns(psString &text); 00165 void UpdateAntecedents(NpcResponse* resp); 00166 void AddBadText(const char* text,const char* trigger); 00167 00168 protected: 00169 void CleanPunctuation(psString &str, bool cleanQMark = true); 00170 00175 void FilterKnownTerms(const psString &text, NpcTriggerSentence &trigger, Client* client); 00176 00181 NpcResponse* FindOrGeneralizeTrigger(Client* client,NpcTriggerSentence &trigger, 00182 csArray<int> &gen_terms, int word); 00183 00184 00185 NpcResponse* ErrorResponse(const psString &text, const char* trigger); 00186 NpcResponse* RepeatedResponse(const psString &text, NpcResponse* resp, csTicks when, int times); 00187 00188 public: 00189 psNPCDialog(gemNPC* npc); 00190 virtual ~psNPCDialog(); 00191 00192 bool Initialize(iDataConnection* db, PID npcID); 00193 bool Initialize(iDataConnection* db); 00194 bool LoadKnowledgeAreas(PID npcID); 00195 00196 NpcResponse* Respond(const char* text,Client* client); 00197 00198 NpcResponse* FindXMLResponse(Client* client, csString trigger, int questID = -1); 00199 00200 bool AddWord(const char* word); 00201 bool AddSynonym(const char* word,const char* synonym); 00202 bool AddKnowledgeArea(const char* ka_name); 00203 bool AddResponse(const char* area,const char* words,const char* response,const char* minfaction); 00204 bool AssignNPCArea(const char* npcname,const char* areaname); 00205 00206 void SubstituteKeywords(Client* player, csString &response) const; 00207 00208 00210 // void AddNewTrigger( int databaseID ); 00211 00213 // void AddNewResponse ( int databaseID ); 00214 00215 void DumpDialog(); 00216 }; 00217 00218 class psDialogManager; 00219 00220 class psTriggerBlock; 00221 class psAttitudeBlock; 00222 class psSpecialResponse; 00223 class psResponse; 00224 00228 class psDialogManager 00229 { 00230 public: 00234 void AddTrigger(psTriggerBlock* trigger); 00235 00239 void AddSpecialResponse(psSpecialResponse* response); 00240 00244 void PrintInfo(); 00245 00252 csArray<psTriggerBlock*> triggers; 00253 00254 00261 csArray<psSpecialResponse*> special; 00262 00271 int GetPriorID(int internalID); 00272 00276 csArray<int> triggerIDs; 00277 00281 csArray<int> responseIDs; 00282 00283 csString area; 00284 00285 bool WriteToDatabase(); 00286 00287 int InsertResponse(csString &response); 00288 int InsertResponseSet(psResponse &response); 00289 int InsertTrigger(const char* trigger, const char* area, int maxAttitude, 00290 int minAttitude, int responseID, int priorID, int questID); 00291 }; 00292 00293 00294 //-------------------------------------------------------------------------- 00295 00306 class psSpecialResponse 00307 { 00308 public: 00312 psSpecialResponse(csRef<iDocumentNode> responseNode, int questID); 00313 00314 csString type; 00315 00316 csString response; 00317 00318 int attMin; 00319 00320 int attMax; 00321 00322 int questID; 00323 }; 00324 00325 00326 //-------------------------------------------------------------------------- 00327 00336 class psTriggerBlock 00337 { 00338 public: 00339 psTriggerBlock(psDialogManager* mgr) 00340 { 00341 manager = mgr; 00342 priorResponseID = 0; 00343 questID = -1; 00344 } 00345 00351 csStringArray phraseList; 00352 00358 csArray<psAttitudeBlock*> attitudes; 00359 00360 psTriggerBlock() 00361 { 00362 priorResponseID = 0; 00363 } 00364 00368 void Create(csRef<iDocumentNode> triggerNode, int questID); 00369 00373 void SetPrior(int id) 00374 { 00375 priorResponseID = id; 00376 } 00377 00378 int priorResponseID; 00379 00380 int databaseID; 00381 00382 csString area; 00383 00384 psDialogManager* manager; 00385 00386 int questID; 00387 }; 00388 00389 00390 //-------------------------------------------------------------------------- 00391 00395 class psResponse 00396 { 00397 public: 00404 csStringArray responses; 00405 00406 csString script; 00407 csString pronoun_him, 00408 pronoun_her, 00409 pronoun_it, 00410 pronoun_them; 00411 00412 int givenID; 00413 00414 int databaseID; 00415 00416 int questID; 00417 00418 }; 00419 00420 00421 //-------------------------------------------------------------------------- 00422 00429 class psAttitudeBlock 00430 { 00431 public: 00432 static int responseID; 00433 00434 psAttitudeBlock(psDialogManager* mgr) 00435 { 00436 manager = mgr; 00437 responseSet.givenID = ++responseID; 00438 } 00439 00440 psResponse responseSet; 00441 00445 void Create(csRef<iDocumentNode> attitudeNode, int questID); 00446 00447 int maxAttitude; 00448 00449 int minAttitude; 00450 00451 psDialogManager* manager; 00452 }; 00453 00454 #endif 00455 00456 00457