(svn r16113) -Feature [NoAI]: Add UseAsRandomAI as function in info.nut. When an AI returns false, it'll never be chosen as random AI.

replace/41b28d7194a279bdc17475d4fbe2ea6ec885a466
yexo 15 years ago
parent d4d163e127
commit 3949050714

@ -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);

@ -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 {

@ -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;
}

@ -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);

@ -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.

Loading…
Cancel
Save