From 3949050714463bf13ffb6da231019de6db22a8e5 Mon Sep 17 00:00:00 2001 From: yexo Date: Tue, 21 Apr 2009 19:13:32 +0000 Subject: (svn r16113) -Feature [NoAI]: Add UseAsRandomAI as function in info.nut. When an AI returns false, it'll never be chosen as random AI. --- src/ai/ai_info.cpp | 6 ++++++ src/ai/ai_info.hpp | 6 ++++++ src/ai/ai_scanner.cpp | 21 ++++++++++++++++----- src/script/squirrel.cpp | 9 +++++++++ src/script/squirrel.hpp | 6 ++++++ 5 files changed, 43 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/ai/ai_info.cpp b/src/ai/ai_info.cpp index aa783c385..da9522d8d 100644 --- a/src/ai/ai_info.cpp +++ b/src/ai/ai_info.cpp @@ -66,6 +66,12 @@ AILibrary::~AILibrary() } else { info->min_loadable_version = info->GetVersion(); } + /* When there is an UseAsRandomAI function, call it. */ + if (info->engine->MethodExists(*info->SQ_instance, "UseAsRandomAI")) { + if (!info->engine->CallBoolMethod(*info->SQ_instance, "UseAsRandomAI", &info->use_as_random)) return SQ_ERROR; + } else { + info->use_as_random = true; + } /* Remove the link to the real instance, else it might get deleted by RegisterAI() */ sq_setinstanceup(vm, 2, NULL); diff --git a/src/ai/ai_info.hpp b/src/ai/ai_info.hpp index 1d86bc9ff..81b1def3e 100644 --- a/src/ai/ai_info.hpp +++ b/src/ai/ai_info.hpp @@ -94,9 +94,15 @@ public: */ int GetSettingDefaultValue(const char *name) const; + /** + * Use this AI as a random AI. + */ + bool UseAsRandomAI() const { return this->use_as_random; } + private: AIConfigItemList config_list; int min_loadable_version; + bool use_as_random; }; class AILibrary : public AIFileInfo { diff --git a/src/ai/ai_scanner.cpp b/src/ai/ai_scanner.cpp index ab9036cf7..a588f5b9b 100644 --- a/src/ai/ai_scanner.cpp +++ b/src/ai/ai_scanner.cpp @@ -243,20 +243,31 @@ void AIScanner::RegisterAI(AIInfo *info) AIInfo *AIScanner::SelectRandomAI() { - if (this->info_single_list.size() == 0) { + uint num_random_ais = 0; + for (AIInfoList::iterator it = this->info_single_list.begin(); it != this->info_single_list.end(); it++) { + if (it->second->UseAsRandomAI()) num_random_ais++; + } + + if (num_random_ais == 0) { DEBUG(ai, 0, "No suitable AI found, loading 'dummy' AI."); return this->info_dummy; } /* Find a random AI */ uint pos; - if (_networking) pos = InteractiveRandomRange((uint16)this->info_single_list.size()); - else pos = RandomRange((uint16)this->info_single_list.size()); + if (_networking) { + pos = InteractiveRandomRange(num_random_ais); + } else { + pos = RandomRange(num_random_ais); + } /* Find the Nth item from the array */ AIInfoList::iterator it = this->info_single_list.begin(); - for (; pos > 0; pos--) it++; - AIInfoList::iterator first_it = it; + while (!it->second->UseAsRandomAI()) it++; + for (; pos > 0; pos--) { + it++; + while (!it->second->UseAsRandomAI()) it++; + } return (*it).second; } diff --git a/src/script/squirrel.cpp b/src/script/squirrel.cpp index a62c83418..f31b813da 100644 --- a/src/script/squirrel.cpp +++ b/src/script/squirrel.cpp @@ -234,6 +234,15 @@ bool Squirrel::CallIntegerMethod(HSQOBJECT instance, const char *method_name, in return true; } +bool Squirrel::CallBoolMethod(HSQOBJECT instance, const char *method_name, bool *res, int suspend) +{ + HSQOBJECT ret; + if (!this->CallMethod(instance, method_name, &ret, suspend)) return false; + if (ret._type != OT_BOOL) return false; + *res = ObjectToBool(&ret); + return true; +} + /* static */ bool Squirrel::CreateClassInstanceVM(HSQUIRRELVM vm, const char *class_name, void *real_instance, HSQOBJECT *instance, SQRELEASEHOOK release_hook) { int oldtop = sq_gettop(vm); diff --git a/src/script/squirrel.hpp b/src/script/squirrel.hpp index 31b36f968..ee597f87a 100644 --- a/src/script/squirrel.hpp +++ b/src/script/squirrel.hpp @@ -116,6 +116,7 @@ public: bool CallMethod(HSQOBJECT instance, const char *method_name, int suspend = -1) { return this->CallMethod(instance, method_name, NULL, suspend); } bool CallStringMethodStrdup(HSQOBJECT instance, const char *method_name, const char **res, int suspend = -1); bool CallIntegerMethod(HSQOBJECT instance, const char *method_name, int *res, int suspend = -1); + bool CallBoolMethod(HSQOBJECT instance, const char *method_name, bool *res, int suspend = -1); /** * Check if a method exists in an instance. @@ -161,6 +162,11 @@ public: */ static int ObjectToInteger(HSQOBJECT *ptr) { return sq_objtointeger(ptr); } + /** + * Convert a Squirrel-object to a bool. + */ + static bool ObjectToBool(HSQOBJECT *ptr) { return sq_objtobool(ptr) == 1; } + /** * Sets a pointer in the VM that is reachable from where ever you are in SQ. * Useful to keep track of the main instance. -- cgit v1.2.3-54-g00ecf