Changeset - r10713:ba92067a4b49
[Not reviewed]
master
0 13 0
truebrain - 16 years ago 2009-01-13 01:46:46
truebrain@openttd.org
(svn r15045) -Add [NoAI API CHANGE]: in info.nut you can now have (optional) a CanLoadFromVersion(version), which should return true/false, to indicate if you can load a savegame made with your AI of version 'version'
-Add [NoAI API CHANGE]: in main.nut the Load() function now should be Load(version, data), where 'version' is the version of your AI which made the savegame
-Codechange [NoAI]: various of function renames to make things more sane
-Add [NoAI]: push the 'version' of the AI through various of layers
-Codechange [NoAI]: various of code cleanups
-Add [NoAI]: store the version of the AI in the savegame too
13 files changed with 84 insertions and 73 deletions:
0 comments (0 inline, 0 general)
src/ai/ai.hpp
Show inline comments
 
@@ -86,11 +86,11 @@ public:
 
	/**
 
	 * Load data for an AI from a savegame.
 
	 */
 
	static void Load(CompanyID company);
 
	static void Load(CompanyID company, int version);
 

	
 
	static char *GetConsoleList(char *p, const char *last);
 
	static const AIInfoList *GetInfoList();
 
	static AIInfo *GetCompanyInfo(const char *name);
 
	static AIInfo *FindInfo(const char *name, int version);
 
	static bool ImportLibrary(const char *library, const char *class_name, int version, HSQUIRRELVM vm);
 
	static void Rescan();
 

	
src/ai/ai_config.cpp
Show inline comments
 
@@ -9,11 +9,11 @@
 
#include "ai_config.hpp"
 
#include "ai_info.hpp"
 

	
 
void AIConfig::ChangeAI(const char *name)
 
void AIConfig::ChangeAI(const char *name, int version)
 
{
 
	free((void *)this->name);
 
	this->name = (name == NULL) ? NULL : strdup(name);
 
	this->info = (name == NULL) ? NULL : AI::GetCompanyInfo(this->name);
 
	this->info = (name == NULL) ? NULL : AI::FindInfo(this->name, version);
 
	this->version = (info == NULL) ? -1 : info->GetVersion();
 

	
 
	for (SettingValueList::iterator it = this->settings.begin(); it != this->settings.end(); it++) {
 
@@ -45,7 +45,7 @@ AIInfo *AIConfig::GetInfo()
 

	
 
bool AIConfig::ResetInfo()
 
{
 
	 this->info = AI::GetCompanyInfo(this->name);
 
	 this->info = AI::FindInfo(this->name, this->version);
 
	 return this->info != NULL;
 
}
 

	
src/ai/ai_config.hpp
Show inline comments
 
@@ -26,8 +26,10 @@ public:
 

	
 
	/**
 
	 * Set another AI to be loaded in this slot.
 
	 * @param name The name of the AI.
 
	 * @param version The version of the AI to load, or -1 of latest.
 
	 */
 
	void ChangeAI(const char *name);
 
	void ChangeAI(const char *name, int version = -1);
 

	
 
	/**
 
	 * When ever the AI Scanner is reloaded, all infos become invalid. This
src/ai/ai_core.cpp
Show inline comments
 
@@ -211,7 +211,7 @@ void CcAI(bool success, TileIndex tile, 
 
	}
 
}
 

	
 
/* static */ void AI::Load(CompanyID company)
 
/* static */ void AI::Load(CompanyID company, int version)
 
{
 
	if (!_networking || _network_server) {
 
		assert(IsValidCompanyID(company));
 
@@ -219,7 +219,7 @@ void CcAI(bool success, TileIndex tile, 
 

	
 
		CompanyID old_company = _current_company;
 
		_current_company = company;
 
		GetCompany(company)->ai_instance->Load();
 
		GetCompany(company)->ai_instance->Load(version);
 
		_current_company = old_company;
 
	} else {
 
		/* Read, but ignore, the load data */
 
@@ -237,9 +237,9 @@ void CcAI(bool success, TileIndex tile, 
 
	return AI::ai_scanner->GetAIInfoList();
 
}
 

	
 
/* static */ AIInfo *AI::GetCompanyInfo(const char *name)
 
/* static */ AIInfo *AI::FindInfo(const char *name, int version)
 
{
 
	return AI::ai_scanner->FindAI(name);
 
	return AI::ai_scanner->FindInfo(name, version);
 
}
 

	
 
/* static */ bool AI::ImportLibrary(const char *library, const char *class_name, int version, HSQUIRRELVM vm)
src/ai/ai_info.cpp
Show inline comments
 
@@ -70,9 +70,26 @@ const char *AIFileInfo::GetInstanceName(
 
	return this->instance_name;
 
}
 

	
 
bool AIFileInfo::AllowStartup()
 
bool AIFileInfo::CanLoadFromVersion(int version)
 
{
 
	return true;
 
	if (version == -1) return true;
 
	if (!this->engine->MethodExists(*this->SQ_instance, "CanLoadFromVersion")) return true;
 

	
 
	HSQUIRRELVM vm = this->engine->GetVM();
 
	int top = sq_gettop(vm);
 

	
 
	sq_pushobject(vm, *this->SQ_instance);
 
	sq_pushstring(vm, OTTD2FS("CanLoadFromVersion"), -1);
 
	sq_get(vm, -2);
 
	sq_pushobject(vm, *this->SQ_instance);
 
	sq_pushinteger(vm, version);
 
	sq_call(vm, 2, SQTrue, SQFalse);
 

	
 
	HSQOBJECT ret;
 
	sq_getstackobj(vm, -1, &ret);
 

	
 
	sq_settop(vm, top);
 
	return sq_objtobool(&ret);
 
}
 

	
 
const char *AIFileInfo::GetDirName()
src/ai/ai_info.hpp
Show inline comments
 
@@ -74,7 +74,7 @@ public:
 
	/**
 
	 * Check if we can start this AI.
 
	 */
 
	bool AllowStartup();
 
	bool CanLoadFromVersion(int version);
 

	
 
	/**
 
	 * Get the name of the dir this AI is in.
src/ai/ai_instance.cpp
Show inline comments
 
@@ -592,37 +592,38 @@ void AIInstance::Save()
 
	LoadObjects(NULL);
 
}
 

	
 
bool AIInstance::Load()
 
void AIInstance::Load(int version)
 
{
 
	HSQUIRRELVM vm = (this->engine == NULL) ? NULL : this->engine->GetVM();
 
	if (this->engine == NULL || version == -1) {
 
		LoadEmpty();
 
		return;
 
	}
 
	HSQUIRRELVM vm = this->engine->GetVM();
 

	
 
	SlObject(NULL, _ai_byte);
 
	/* Check if there was anything saved at all. */
 
	if (_ai_sl_byte == 0) return true;
 
	if (_ai_sl_byte == 0) return;
 
	AIObject::SetAllowDoCommand(false);
 

	
 
	if (vm != NULL) {
 
		/* Go to the instance-root */
 
		sq_pushobject(vm, *this->instance);
 
		/* Find the function-name inside the script */
 
		sq_pushstring(vm, OTTD2FS("Load"), -1);
 
		if (SQ_FAILED(sq_get(vm, -2))) sq_pushnull(vm);
 
		sq_pushobject(vm, *this->instance);
 
	}
 
	/* Go to the instance-root */
 
	sq_pushobject(vm, *this->instance);
 
	/* Find the function-name inside the script */
 
	sq_pushstring(vm, OTTD2FS("Load"), -1);
 
	if (SQ_FAILED(sq_get(vm, -2))) sq_pushnull(vm);
 
	sq_pushobject(vm, *this->instance);
 
	sq_pushinteger(vm, version);
 

	
 
	LoadObjects(vm);
 

	
 
	if (this->engine != NULL) {
 
		if (this->engine->MethodExists(*this->instance, "Load")) {
 
			sq_call(vm, 2, SQFalse, SQFalse);
 
		} else {
 
			AILog::Warning("Loading failed: there was data for the AI to load, but the AI does not have a Load() function.");
 
		}
 
	if (this->engine->MethodExists(*this->instance, "Load")) {
 
		sq_call(vm, 3, SQFalse, SQFalse);
 
	} else {
 
		AILog::Warning("Loading failed: there was data for the AI to load, but the AI does not have a Load() function.");
 
	}
 

	
 
	/* Pop 1) the object instance, 2) the function name, 3) the instance again, 4) the table. */
 
	if (vm != NULL) sq_pop(vm, 4);
 
	/* Pop 1) the object instance, 2) the function name, 3) the instance again, 4) the (null) result. */
 
	sq_pop(vm, 4);
 

	
 
	AIObject::SetAllowDoCommand(true);
 
	return true;
 
	return;
 
}
src/ai/ai_instance.hpp
Show inline comments
 
@@ -87,9 +87,10 @@ public:
 
	/**
 
	 * Load data from a savegame and call the AI Load function if it
 
	 *   exists.
 
	 * @return True if the loading was successfull.
 
	 * @param version The version of the AI when saving, or -1 if this was
 
	 *  not the original AI saving the game.
 
	 */
 
	bool Load();
 
	void Load(int version);
 

	
 
	/**
 
	 * Load and discard data from a savegame.
src/ai/ai_scanner.cpp
Show inline comments
 
@@ -344,26 +344,10 @@ AIInfo *AIScanner::SelectRandomAI()
 
	AIInfoList::iterator it = this->info_list.begin();
 
	for (; pos > 0; pos--) it++;
 
	AIInfoList::iterator first_it = it;
 
	AIInfo *i = (*it).second;
 

	
 
	if (!i->AllowStartup()) {
 
		/* We can't start this AI, try to find the next best */
 
		do {
 
			it++;
 
			if (it == this->info_list.end()) it = this->info_list.begin();
 
			/* Back at the beginning? We can't start an AI. */
 
			if (first_it == it) {
 
				DEBUG(ai, 0, "No suitable AI found, loading 'dummy' AI.");
 
				return this->info_dummy;
 
			}
 

	
 
			i = (*it).second;
 
		} while (!i->AllowStartup());
 
	}
 
	return i;
 
	return (*it).second;
 
}
 

	
 
AIInfo *AIScanner::FindAI(const char *name)
 
AIInfo *AIScanner::FindInfo(const char *name, int version)
 
{
 
	if (this->info_list.size() == 0) return NULL;
 
	if (name == NULL) return NULL;
 
@@ -372,7 +356,7 @@ AIInfo *AIScanner::FindAI(const char *na
 
	for (; it != this->info_list.end(); it++) {
 
		AIInfo *i = (*it).second;
 

	
 
		if (strcasecmp(name, (*it).first) == 0 && i->AllowStartup()) {
 
		if (strcasecmp(name, (*it).first) == 0 && i->CanLoadFromVersion(version)) {
 
			return i;
 
		}
 
	}
 
@@ -386,8 +370,7 @@ char *AIScanner::GetAIConsoleList(char *
 
	AIInfoList::iterator it = this->info_list.begin();
 
	for (; it != this->info_list.end(); it++) {
 
		AIInfo *i = (*it).second;
 
		if (!i->AllowStartup()) continue;
 
		p += seprintf(p, last, "%10s: %s\n", (*it).first, i->GetDescription());
 
		p += seprintf(p, last, "%10s (v%d): %s\n", (*it).first, i->GetVersion(), i->GetDescription());
 
	}
 
	p += seprintf(p, last, "\n");
 

	
src/ai/ai_scanner.hpp
Show inline comments
 
@@ -42,7 +42,7 @@ public:
 
	/**
 
	 * Find an AI by name.
 
	 */
 
	class AIInfo *FindAI(const char *name);
 
	class AIInfo *FindInfo(const char *name, int version);
 

	
 
	/**
 
	 * Get the list of available AIs for the console.
src/saveload/ai_sl.cpp
Show inline comments
 
@@ -13,12 +13,14 @@
 
#include "../ai/ai.hpp"
 
#include "../ai/ai_config.hpp"
 

	
 
static char _ai_saveload_ainame[64];
 
static char _ai_company_convert_array[1024];
 
static char _ai_saveload_name[64];
 
static int  _ai_saveload_version;
 
static char _ai_saveload_settings[1024];
 

	
 
static const SaveLoad _ai_company[] = {
 
	SLEG_STR(_ai_saveload_ainame,       SLE_STRB),
 
	SLEG_STR(_ai_company_convert_array, SLE_STRB),
 
	SLEG_STR(_ai_saveload_name,        SLE_STRB),
 
	SLEG_STR(_ai_saveload_settings,    SLE_STRB),
 
	SLEG_CONDVAR(_ai_saveload_version, SLE_UINT32, 108, SL_MAX_VERSION),
 
	SLE_END()
 
};
 

	
 
@@ -27,10 +29,11 @@ static void SaveReal_AIPL(int *index_ptr
 
	CompanyID index = (CompanyID)*index_ptr;
 
	AIConfig *config = AIConfig::GetConfig(index);
 

	
 
	ttd_strlcpy(_ai_saveload_ainame, config->GetName(), lengthof(_ai_saveload_ainame));
 
	ttd_strlcpy(_ai_saveload_name, config->GetName(), lengthof(_ai_saveload_name));
 
	_ai_saveload_version = config->GetVersion();
 

	
 
	_ai_company_convert_array[0] = '\0';
 
	config->SettingsToString(_ai_company_convert_array, lengthof(_ai_company_convert_array));
 
	_ai_saveload_settings[0] = '\0';
 
	config->SettingsToString(_ai_saveload_settings, lengthof(_ai_saveload_settings));
 

	
 
	SlObject(NULL, _ai_company);
 
	/* If the AI was active, store his data too */
 
@@ -47,27 +50,30 @@ static void Load_AIPL()
 
	CompanyID index;
 
	while ((index = (CompanyID)SlIterateArray()) != (CompanyID)-1) {
 
		AIConfig *config = AIConfig::GetConfig(index);
 

	
 
		_ai_saveload_version = -1;
 
		SlObject(NULL, _ai_company);
 

	
 
		if (_ai_saveload_ainame[0] == '\0' || AI::GetCompanyInfo(_ai_saveload_ainame) == NULL) {
 
			if (strcmp(_ai_saveload_ainame, "%_dummy") != 0) {
 
				DEBUG(ai, 0, "The savegame has an AI by the name '%s' which is no longer available.", _ai_saveload_ainame);
 
		config->ChangeAI(_ai_saveload_name, _ai_saveload_version);
 
		if (!config->HasAI()) {
 
			if (strcmp(_ai_saveload_name, "%_dummy") != 0) {
 
				DEBUG(ai, 0, "The savegame has an AI by the name '%s', version %d which is no longer available.", _ai_saveload_name, _ai_saveload_version);
 
				DEBUG(ai, 0, "A random other AI will be loaded in its place.");
 
			} else {
 
				DEBUG(ai, 0, "The savegame had no AIs available at the time of saving.");
 
				DEBUG(ai, 0, "A random available AI will be loaded now.");
 
			}
 
			config->ChangeAI(NULL);
 
		} else {
 
			config->ChangeAI(_ai_saveload_ainame);
 
			/* Make sure the AI doesn't get the saveload data, as he was not the
 
			 *  writer of the saveload data in the first place */
 
			_ai_saveload_version = -1;
 
		}
 

	
 
		config->StringToSettings(_ai_company_convert_array);
 
		config->StringToSettings(_ai_saveload_settings);
 

	
 
		/* Start the AI directly if it was active in the savegame */
 
		if (IsValidCompanyID(index) && !IsHumanCompany(index)) {
 
			AI::StartNew(index);
 
			AI::Load(index);
 
			AI::Load(index, _ai_saveload_version);
 
		}
 
	}
 
}
src/saveload/saveload.cpp
Show inline comments
 
@@ -42,7 +42,7 @@
 

	
 
#include <list>
 

	
 
extern const uint16 SAVEGAME_VERSION = 107;
 
extern const uint16 SAVEGAME_VERSION = 108;
 

	
 
SavegameType _savegame_type; ///< type of savegame we are loading
 

	
src/script/squirrel.hpp
Show inline comments
 
@@ -48,6 +48,7 @@ public:
 
	friend class AIController;
 
	friend class AIScanner;
 
	friend class AIInstance;
 
	friend class AIFileInfo;
 

	
 
	Squirrel();
 
	~Squirrel();
0 comments (0 inline, 0 general)