Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #include "../stdafx.h"
00013 #include "../debug.h"
00014 #include "../network/network.h"
00015 #include "../core/random_func.hpp"
00016
00017 #include "../script/squirrel_class.hpp"
00018 #include "ai_info.hpp"
00019 #include "ai_scanner.hpp"
00020
00021
00022 AIScannerInfo::AIScannerInfo() :
00023 ScriptScanner(),
00024 info_dummy(NULL)
00025 {
00026 }
00027
00028 void AIScannerInfo::Initialize()
00029 {
00030 ScriptScanner::Initialize("AIScanner");
00031
00032
00033 free(this->main_script);
00034 this->main_script = strdup("%_dummy");
00035 extern void Script_CreateDummyInfo(HSQUIRRELVM vm, const char *type, const char *dir);
00036 Script_CreateDummyInfo(this->engine->GetVM(), "AI", "ai");
00037 }
00038
00039 void AIScannerInfo::SetDummyAI(class AIInfo *info)
00040 {
00041 this->info_dummy = info;
00042 }
00043
00044 AIScannerInfo::~AIScannerInfo()
00045 {
00046 delete this->info_dummy;
00047 }
00048
00049 void AIScannerInfo::GetScriptName(ScriptInfo *info, char *name, int len)
00050 {
00051 snprintf(name, len, "%s", info->GetName());
00052 }
00053
00054 void AIScannerInfo::RegisterAPI(class Squirrel *engine)
00055 {
00056 AIInfo::RegisterAPI(engine);
00057 }
00058
00059 AIInfo *AIScannerInfo::SelectRandomAI() const
00060 {
00061 uint num_random_ais = 0;
00062 for (ScriptInfoList::const_iterator it = this->info_single_list.begin(); it != this->info_single_list.end(); it++) {
00063 AIInfo *i = static_cast<AIInfo *>((*it).second);
00064 if (i->UseAsRandomAI()) num_random_ais++;
00065 }
00066
00067 if (num_random_ais == 0) {
00068 DEBUG(script, 0, "No suitable AI found, loading 'dummy' AI.");
00069 return this->info_dummy;
00070 }
00071
00072
00073 uint pos;
00074 if (_networking) {
00075 pos = InteractiveRandomRange(num_random_ais);
00076 } else {
00077 pos = RandomRange(num_random_ais);
00078 }
00079
00080
00081 ScriptInfoList::const_iterator it = this->info_single_list.begin();
00082
00083 #define GetAIInfo(it) static_cast<AIInfo *>((*it).second)
00084 while (!GetAIInfo(it)->UseAsRandomAI()) it++;
00085 for (; pos > 0; pos--) {
00086 it++;
00087 while (!GetAIInfo(it)->UseAsRandomAI()) it++;
00088 }
00089 return GetAIInfo(it);
00090 #undef GetAIInfo
00091 }
00092
00093 AIInfo *AIScannerInfo::FindInfo(const char *nameParam, int versionParam, bool force_exact_match)
00094 {
00095 if (this->info_list.size() == 0) return NULL;
00096 if (nameParam == NULL) return NULL;
00097
00098 char ai_name[1024];
00099 ttd_strlcpy(ai_name, nameParam, sizeof(ai_name));
00100 strtolower(ai_name);
00101
00102 AIInfo *info = NULL;
00103 int version = -1;
00104
00105 if (versionParam == -1) {
00106
00107 if (this->info_single_list.find(ai_name) != this->info_single_list.end()) return static_cast<AIInfo *>(this->info_single_list[ai_name]);
00108
00109
00110 char *e = strrchr(ai_name, '.');
00111 if (e == NULL) return NULL;
00112 *e = '\0';
00113 e++;
00114 versionParam = atoi(e);
00115
00116 }
00117
00118 if (force_exact_match) {
00119
00120 char ai_name_tmp[1024];
00121 snprintf(ai_name_tmp, sizeof(ai_name_tmp), "%s.%d", ai_name, versionParam);
00122 strtolower(ai_name_tmp);
00123 if (this->info_list.find(ai_name_tmp) != this->info_list.end()) return static_cast<AIInfo *>(this->info_list[ai_name_tmp]);
00124 }
00125
00126
00127
00128 ScriptInfoList::iterator it = this->info_list.begin();
00129 for (; it != this->info_list.end(); it++) {
00130 AIInfo *i = static_cast<AIInfo *>((*it).second);
00131 if (strcasecmp(ai_name, i->GetName()) == 0 && i->CanLoadFromVersion(versionParam) && (version == -1 || i->GetVersion() > version)) {
00132 version = (*it).second->GetVersion();
00133 info = i;
00134 }
00135 }
00136
00137 return info;
00138 }
00139
00140
00141 void AIScannerLibrary::Initialize()
00142 {
00143 ScriptScanner::Initialize("AIScanner");
00144 }
00145
00146 void AIScannerLibrary::GetScriptName(ScriptInfo *info, char *name, int len)
00147 {
00148 AILibrary *library = static_cast<AILibrary *>(info);
00149 snprintf(name, len, "%s.%s", library->GetCategory(), library->GetInstanceName());
00150 }
00151
00152 void AIScannerLibrary::RegisterAPI(class Squirrel *engine)
00153 {
00154 AILibrary::RegisterAPI(engine);
00155 }
00156
00157 AILibrary *AIScannerLibrary::FindLibrary(const char *library, int version)
00158 {
00159
00160 char library_name[1024];
00161 snprintf(library_name, sizeof(library_name), "%s.%d", library, version);
00162 strtolower(library_name);
00163
00164
00165 ScriptInfoList::iterator iter = this->info_list.find(library_name);
00166 if (iter == this->info_list.end()) return NULL;
00167
00168 return static_cast<AILibrary *>((*iter).second);
00169 }