AIInfo *AIScannerInfo::SelectRandomAI() const { uint num_random_ais = 0; for (ScriptInfoList::const_iterator it = this->info_single_list.begin(); it != this->info_single_list.end(); it++) { AIInfo *i = static_cast<AIInfo *>((*it).second); if (i->UseAsRandomAI()) num_random_ais++; } if (num_random_ais == 0) { DEBUG(script, 0, "No suitable AI found, loading 'dummy' AI."); return this->info_dummy; } /* Find a random AI */ uint pos; if (_networking) { pos = InteractiveRandomRange(num_random_ais); } else { pos = RandomRange(num_random_ais); } /* Find the Nth item from the array */ ScriptInfoList::const_iterator it = this->info_single_list.begin(); #define GetAIInfo(it) static_cast<AIInfo *>((*it).second) while (!GetAIInfo(it)->UseAsRandomAI()) it++; for (; pos > 0; pos--) { it++; while (!GetAIInfo(it)->UseAsRandomAI()) it++; } return GetAIInfo(it); #undef GetAIInfo }
void ScriptConfig::AddRandomDeviation() { for (ScriptConfigItemList::const_iterator it = this->GetConfigList()->begin(); it != this->GetConfigList()->end(); it++) { if ((*it).random_deviation != 0) { this->SetSetting((*it).name, InteractiveRandomRange((*it).random_deviation * 2) - (*it).random_deviation + this->GetSetting((*it).name)); } } }
void ScriptConfig::Change(const char *name, int version, bool force_exact_match, bool is_random) { free(this->name); this->name = (name == NULL) ? NULL : strdup(name); this->info = (name == NULL) ? NULL : this->FindInfo(this->name, version, force_exact_match); this->version = (info == NULL) ? -1 : info->GetVersion(); this->is_random = is_random; if (this->config_list != NULL) delete this->config_list; this->config_list = (info == NULL) ? NULL : new ScriptConfigItemList(); if (this->config_list != NULL) this->PushExtraConfigList(); this->ClearConfigList(); if (_game_mode == GM_NORMAL && this->info != NULL) { /* If we're in an existing game and the Script is changed, set all settings * for the Script that have the random flag to a random value. */ for (ScriptConfigItemList::const_iterator it = this->info->GetConfigList()->begin(); it != this->info->GetConfigList()->end(); it++) { if ((*it).flags & SCRIPTCONFIG_RANDOM) { this->SetSetting((*it).name, InteractiveRandomRange((*it).max_value - (*it).min_value) + (*it).min_value); } } this->AddRandomDeviation(); } }
void AIScanner::RegisterLibrary(AILibrary *library) { char library_name[1024]; snprintf(library_name, sizeof(library_name), "%s.%s.%d", library->GetCategory(), library->GetInstanceName(), library->GetVersion()); strtolower(library_name); if (this->library_list.find(library_name) != this->library_list.end()) { /* This AI was already registered */ #ifdef WIN32 /* Windows doesn't care about the case */ if (strcasecmp(this->library_list[library_name]->GetMainScript(), library->GetMainScript()) == 0) { #else if (strcmp(this->library_list[library_name]->GetMainScript(), library->GetMainScript()) == 0) { #endif delete library; return; } DEBUG(ai, 1, "Registering two libraries with the same name and version"); DEBUG(ai, 1, " 1: %s", this->library_list[library_name]->GetMainScript()); DEBUG(ai, 1, " 2: %s", library->GetMainScript()); DEBUG(ai, 1, "The first is taking precedence."); delete library; return; } this->library_list[strdup(library_name)] = library; } void AIScanner::RegisterAI(AIInfo *info) { char ai_name[1024]; snprintf(ai_name, sizeof(ai_name), "%s.%d", info->GetName(), info->GetVersion()); strtolower(ai_name); /* Check if GetShortName follows the rules */ if (strlen(info->GetShortName()) != 4) { DEBUG(ai, 0, "The AI '%s' returned a string from GetShortName() which is not four characaters. Unable to load the AI.", info->GetName()); delete info; return; } if (this->info_list.find(ai_name) != this->info_list.end()) { /* This AI was already registered */ #ifdef WIN32 /* Windows doesn't care about the case */ if (strcasecmp(this->info_list[ai_name]->GetMainScript(), info->GetMainScript()) == 0) { #else if (strcmp(this->info_list[ai_name]->GetMainScript(), info->GetMainScript()) == 0) { #endif delete info; return; } DEBUG(ai, 1, "Registering two AIs with the same name and version"); DEBUG(ai, 1, " 1: %s", this->info_list[ai_name]->GetMainScript()); DEBUG(ai, 1, " 2: %s", info->GetMainScript()); DEBUG(ai, 1, "The first is taking precedence."); delete info; return; } this->info_list[strdup(ai_name)] = info; /* Add the AI to the 'unique' AI list, where only the highest version of the * AI is registered. */ snprintf(ai_name, sizeof(ai_name), "%s", info->GetName()); strtolower(ai_name); if (this->info_single_list.find(ai_name) == this->info_single_list.end()) { this->info_single_list[strdup(ai_name)] = info; } else if (this->info_single_list[ai_name]->GetVersion() < info->GetVersion()) { this->info_single_list[ai_name] = info; } } AIInfo *AIScanner::SelectRandomAI() const { uint num_random_ais = 0; for (AIInfoList::const_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(num_random_ais); } else { pos = RandomRange(num_random_ais); } /* Find the Nth item from the array */ AIInfoList::const_iterator it = this->info_single_list.begin(); while (!it->second->UseAsRandomAI()) it++; for (; pos > 0; pos--) { it++; while (!it->second->UseAsRandomAI()) it++; } return (*it).second; }