summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoryexo <yexo@openttd.org>2009-04-21 19:13:32 +0000
committeryexo <yexo@openttd.org>2009-04-21 19:13:32 +0000
commit3949050714463bf13ffb6da231019de6db22a8e5 (patch)
treeb6dc258527d34f2a1db659be97eb7f48e16a7da6
parentd4d163e127a90aecc64ddcfb37c96acbde91d658 (diff)
downloadopenttd-3949050714463bf13ffb6da231019de6db22a8e5.tar.xz
(svn r16113) -Feature [NoAI]: Add UseAsRandomAI as function in info.nut. When an AI returns false, it'll never be chosen as random AI.
-rw-r--r--src/ai/ai_info.cpp6
-rw-r--r--src/ai/ai_info.hpp6
-rw-r--r--src/ai/ai_scanner.cpp21
-rw-r--r--src/script/squirrel.cpp9
-rw-r--r--src/script/squirrel.hpp6
5 files changed, 43 insertions, 5 deletions
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.
@@ -162,6 +163,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.
*/