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