(svn r23612) -Add: allow importing libraries in the same way as AI does, only with GS prefix (and in game/library)

replace/41b28d7194a279bdc17475d4fbe2ea6ec885a466
truebrain 13 years ago
parent 83f2785f54
commit 963802e9a7

@ -1106,6 +1106,16 @@ DEF_CONSOLE_CMD(ConListAI)
return true;
}
DEF_CONSOLE_CMD(ConListGameLibs)
{
char buf[4096];
Game::GetConsoleLibraryList(buf, lastof(buf));
PrintLineByLine(buf);
return true;
}
DEF_CONSOLE_CMD(ConListGame)
{
char buf[4096];
@ -1743,7 +1753,7 @@ DEF_CONSOLE_CMD(ConContent)
if (strcasecmp(argv[1], "state") == 0) {
IConsolePrintF(CC_WHITE, "id, type, state, name");
for (ConstContentIterator iter = _network_content_client.Begin(); iter != _network_content_client.End(); iter++) {
static const char * const types[] = { "Base graphics", "NewGRF", "AI", "AI library", "Scenario", "Heightmap", "Base sound", "Base music", "Game script" };
static const char * const types[] = { "Base graphics", "NewGRF", "AI", "AI library", "Scenario", "Heightmap", "Base sound", "Base music", "Game script", "GS library" };
assert_compile(lengthof(types) == CONTENT_TYPE_END - CONTENT_TYPE_BEGIN);
static const char * const states[] = { "Not selected", "Selected", "Dep Selected", "Installed", "Unknown" };
static const TextColour state_to_colour[] = { CC_COMMAND, CC_INFO, CC_INFO, CC_WHITE, CC_ERROR };
@ -1907,6 +1917,7 @@ void IConsoleStdLibRegister()
IConsoleCmdRegister("stop_ai", ConStopAI);
IConsoleCmdRegister("list_game", ConListGame);
IConsoleCmdRegister("list_game_libs", ConListGameLibs);
/* networking functions */
#ifdef ENABLE_NETWORK

@ -282,6 +282,7 @@ static const char * const _subdirs[] = {
"ai" PATHSEP,
"ai" PATHSEP "library" PATHSEP,
"game" PATHSEP,
"game" PATHSEP "library" PATHSEP,
};
assert_compile(lengthof(_subdirs) == NUM_SUBDIRS);
@ -678,6 +679,7 @@ uint TarScanner::DoScan(Subdirectory sd)
}
if (mode & TarScanner::GAME) {
num += fs.DoScan(GAME_DIR);
num += fs.DoScan(GAME_LIBRARY_DIR);
}
if (mode & TarScanner::SCENARIO) {
num += fs.DoScan(SCENARIO_DIR);
@ -1199,7 +1201,7 @@ void DeterminePaths(const char *exe)
#endif
static const Subdirectory default_subdirs[] = {
SAVE_DIR, AUTOSAVE_DIR, SCENARIO_DIR, HEIGHTMAP_DIR, BASESET_DIR, NEWGRF_DIR, AI_DIR, AI_LIBRARY_DIR, GAME_DIR
SAVE_DIR, AUTOSAVE_DIR, SCENARIO_DIR, HEIGHTMAP_DIR, BASESET_DIR, NEWGRF_DIR, AI_DIR, AI_LIBRARY_DIR, GAME_DIR, GAME_LIBRARY_DIR
};
for (uint i = 0; i < lengthof(default_subdirs); i++) {
@ -1214,7 +1216,7 @@ void DeterminePaths(const char *exe)
FioCreateDirectory(_searchpaths[SP_AUTODOWNLOAD_DIR]);
/* Create the directory for each of the types of content */
const Subdirectory dirs[] = { SCENARIO_DIR, HEIGHTMAP_DIR, BASESET_DIR, NEWGRF_DIR, AI_DIR, AI_LIBRARY_DIR, GAME_DIR };
const Subdirectory dirs[] = { SCENARIO_DIR, HEIGHTMAP_DIR, BASESET_DIR, NEWGRF_DIR, AI_DIR, AI_LIBRARY_DIR, GAME_DIR, GAME_LIBRARY_DIR };
for (uint i = 0; i < lengthof(dirs); i++) {
char *tmp = str_fmt("%s%s", _searchpaths[SP_AUTODOWNLOAD_DIR], _subdirs[dirs[i]]);
FioCreateDirectory(tmp);

@ -31,6 +31,7 @@ enum Subdirectory {
AI_DIR, ///< Subdirectory for all AI files
AI_LIBRARY_DIR,///< Subdirectory for all AI libraries
GAME_DIR, ///< Subdirectory for all game scripts
GAME_LIBRARY_DIR, ///< Subdirectory for all GS libraries
NUM_SUBDIRS, ///< Number of subdirectories
NO_DIRECTORY, ///< A path without any base directory
};

@ -68,23 +68,34 @@ public:
/** Wrapper function for GameScanner::GetConsoleList */
static char *GetConsoleList(char *p, const char *last, bool newest_only = false);
/** Wrapper function for GameScanner::GetConsoleLibraryList */
static char *GetConsoleLibraryList(char *p, const char *last);
/** Wrapper function for GameScanner::GetInfoList */
static const ScriptInfoList *GetInfoList();
/** Wrapper function for GameScanner::GetUniqueInfoList */
static const ScriptInfoList *GetUniqueInfoList();
/** Wrapper function for GameScannerInfo::FindInfo */
static class GameInfo *FindInfo(const char *name, int version, bool force_exact_match);
/** Wrapper function for GameScanner::FindLibrary */
static class GameLibrary *FindLibrary(const char *library, int version);
/**
* Get the current active instance.
*/
static class GameInstance *GetInstance() { return Game::instance; }
#if defined(ENABLE_NETWORK)
/** Wrapper function for GameScanner::HasGame */
static bool HasGame(const struct ContentInfo *ci, bool md5sum);
static bool HasGameLibrary(const ContentInfo *ci, bool md5sum);
#endif
private:
static uint frame_counter; ///< Tick counter for the Game code.
static class GameInstance *instance; ///< Instance to the current active Game.
static class GameScannerInfo *scanner; ///< Scanner for Game scripts.
static class GameInfo *info; ///< Current selected GameInfo.
static uint frame_counter; ///< Tick counter for the Game code.
static class GameInstance *instance; ///< Instance to the current active Game.
static class GameScannerInfo *scanner_info; ///< Scanner for Game scripts.
static class GameScannerLibrary *scanner_library; ///< Scanner for GS Libraries.
static class GameInfo *info; ///< Current selected GameInfo.
};
#endif /* GAME_HPP */

@ -26,7 +26,8 @@
/* static */ uint Game::frame_counter = 0;
/* static */ GameInfo *Game::info = NULL;
/* static */ GameInstance *Game::instance = NULL;
/* static */ GameScannerInfo *Game::scanner = NULL;
/* static */ GameScannerInfo *Game::scanner_info = NULL;
/* static */ GameScannerLibrary *Game::scanner_library = NULL;
/* static */ void Game::GameLoop()
{
@ -52,10 +53,12 @@
Game::frame_counter = 0;
if (Game::scanner == NULL) {
if (Game::scanner_info == NULL) {
TarScanner::DoScan(TarScanner::GAME);
Game::scanner = new GameScannerInfo();
Game::scanner->Initialize();
Game::scanner_info = new GameScannerInfo();
Game::scanner_info->Initialize();
Game::scanner_library = new GameScannerLibrary();
Game::scanner_library->Initialize();
}
}
@ -90,8 +93,10 @@
if (keepConfig) {
Rescan();
} else {
delete Game::scanner;
Game::scanner = NULL;
delete Game::scanner_info;
delete Game::scanner_library;
Game::scanner_info = NULL;
Game::scanner_library = NULL;
if (_settings_game.game_config != NULL) {
delete _settings_game.game_config;
@ -132,7 +137,8 @@
{
TarScanner::DoScan(TarScanner::GAME);
Game::scanner->RescanDir();
Game::scanner_info->RescanDir();
Game::scanner_library->RescanDir();
ResetConfig();
InvalidateWindowData(WC_AI_LIST, 0, 1);
@ -166,20 +172,50 @@
/* static */ char *Game::GetConsoleList(char *p, const char *last, bool newest_only)
{
return Game::scanner->GetConsoleList(p, last, newest_only);
return Game::scanner_info->GetConsoleList(p, last, newest_only);
}
/* static */ char *Game::GetConsoleLibraryList(char *p, const char *last)
{
return Game::scanner_library->GetConsoleList(p, last, true);
}
/* static */ const ScriptInfoList *Game::GetInfoList()
{
return Game::scanner->GetInfoList();
return Game::scanner_info->GetInfoList();
}
/* static */ const ScriptInfoList *Game::GetUniqueInfoList()
{
return Game::scanner->GetUniqueInfoList();
return Game::scanner_info->GetUniqueInfoList();
}
/* static */ GameInfo *Game::FindInfo(const char *name, int version, bool force_exact_match)
{
return Game::scanner->FindInfo(name, version, force_exact_match);
return Game::scanner_info->FindInfo(name, version, force_exact_match);
}
/* static */ GameLibrary *Game::FindLibrary(const char *library, int version)
{
return Game::scanner_library->FindLibrary(library, version);
}
#if defined(ENABLE_NETWORK)
/**
* Check whether we have an Game (library) with the exact characteristics as ci.
* @param ci the characteristics to search on (shortname and md5sum)
* @param md5sum whether to check the MD5 checksum
* @return true iff we have an Game (library) matching.
*/
/* static */ bool Game::HasGame(const ContentInfo *ci, bool md5sum)
{
return Game::scanner_info->HasScript(ci, md5sum);
}
/* static */ bool Game::HasGameLibrary(const ContentInfo *ci, bool md5sum)
{
return Game::scanner_library->HasScript(ci, md5sum);
}
#endif /* defined(ENABLE_NETWORK) */

@ -99,3 +99,40 @@ bool GameInfo::CanLoadFromVersion(int version) const
if (version == -1) return true;
return version >= this->min_loadable_version && version <= this->GetVersion();
}
GameLibrary::~GameLibrary()
{
free(this->category);
}
/* static */ void GameLibrary::RegisterAPI(Squirrel *engine)
{
/* Create the GameLibrary class, and add the RegisterLibrary function */
engine->AddClassBegin("GSLibrary");
engine->AddClassEnd();
engine->AddMethod("RegisterLibrary", &GameLibrary::Constructor, 2, "tx");
}
/* static */ SQInteger GameLibrary::Constructor(HSQUIRRELVM vm)
{
/* Create a new library */
GameLibrary *library = new GameLibrary();
SQInteger res = ScriptInfo::Constructor(vm, library);
if (res != 0) {
delete library;
return res;
}
/* Cache the category */
if (!library->CheckMethod("GetCategory") || !library->engine->CallStringMethodStrdup(*library->SQ_instance, "GetCategory", &library->category, MAX_GET_OPS)) {
delete library;
return SQ_ERROR;
}
/* Register the Library to the base system */
library->GetScanner()->RegisterScript(library);
return 0;
}

@ -46,4 +46,29 @@ private:
const char *api_version; ///< API version used by this Game.
};
/** All static information from an Game library like name, version, etc. */
class GameLibrary : public ScriptInfo {
public:
GameLibrary() : ScriptInfo(), category(NULL) {};
~GameLibrary();
/**
* Register the functions of this class.
*/
static void RegisterAPI(Squirrel *engine);
/**
* Create an GSLibrary, using this GSInfo as start-template.
*/
static SQInteger Constructor(HSQUIRRELVM vm);
/**
* Get the category this library is in.
*/
const char *GetCategory() const { return this->category; }
private:
const char *category; ///< The category this library is in.
};
#endif /* GAME_INFO_HPP */

@ -68,8 +68,7 @@ int GameInstance::GetSetting(const char *name)
ScriptInfo *GameInstance::FindLibrary(const char *library, int version)
{
/* 'import' is not supported with GameScripts */
return NULL;
return (ScriptInfo *)Game::FindLibrary(library, version);
}
/**

@ -21,11 +21,6 @@
#include "../script/api/script_controller.hpp"
GameScannerInfo::GameScannerInfo() :
ScriptScanner()
{
}
void GameScannerInfo::Initialize()
{
ScriptScanner::Initialize("GSScanner");
@ -87,3 +82,34 @@ GameInfo *GameScannerInfo::FindInfo(const char *nameParam, int versionParam, boo
return info;
}
void GameScannerLibrary::Initialize()
{
ScriptScanner::Initialize("GSScanner");
}
void GameScannerLibrary::GetScriptName(ScriptInfo *info, char *name, int len)
{
GameLibrary *library = static_cast<GameLibrary *>(info);
snprintf(name, len, "%s.%s", library->GetCategory(), library->GetInstanceName());
}
void GameScannerLibrary::RegisterAPI(class Squirrel *engine)
{
GameLibrary::RegisterAPI(engine);
}
GameLibrary *GameScannerLibrary::FindLibrary(const char *library, int version)
{
/* Internally we store libraries as 'library.version' */
char library_name[1024];
snprintf(library_name, sizeof(library_name), "%s.%d", library, version);
strtolower(library_name);
/* Check if the library + version exists */
ScriptInfoList::iterator iter = this->info_list.find(library_name);
if (iter == this->info_list.end()) return NULL;
return static_cast<GameLibrary *>((*iter).second);
}

@ -16,8 +16,6 @@
class GameScannerInfo : public ScriptScanner {
public:
GameScannerInfo();
/* virtual */ void Initialize();
/**
@ -37,4 +35,25 @@ protected:
/* virtual */ void RegisterAPI(class Squirrel *engine);
};
class GameScannerLibrary : public ScriptScanner {
public:
/* virtual */ void Initialize();
/**
* Find a library in the pool.
* @param library The library name to find.
* @param version The version the library should have.
* @return The library if found, NULL otherwise.
*/
class GameLibrary *FindLibrary(const char *library, int version);
protected:
/* virtual */ void GetScriptName(ScriptInfo *info, char *name, int len);
/* virtual */ const char *GetFileName() const { return PATHSEP "library.nut"; }
/* virtual */ Subdirectory GetDirectory() const { return GAME_LIBRARY_DIR; }
/* virtual */ const char *GetScannerName() const { return "GS Libraries"; }
/* virtual */ void RegisterAPI(class Squirrel *engine);
};
#endif /* GAME_SCANNER_HPP */

@ -33,6 +33,7 @@ enum ContentType {
CONTENT_TYPE_BASE_SOUNDS = 7, ///< The content consists of base sounds
CONTENT_TYPE_BASE_MUSIC = 8, ///< The content consists of base music
CONTENT_TYPE_GAME = 9, ///< The content consists of a game script
CONTENT_TYPE_GAME_LIBRARY = 10, ///< The content consists of a GS library
CONTENT_TYPE_END, ///< Helper to mark the end of the types
};

@ -14,6 +14,7 @@
#include "../stdafx.h"
#include "../rev.h"
#include "../ai/ai.hpp"
#include "../game/game.hpp"
#include "../window_func.h"
#include "../error.h"
#include "../base_media_base.h"
@ -104,6 +105,14 @@ bool ClientNetworkContentSocketHandler::Receive_SERVER_INFO(Packet *p)
proc = AI::HasAILibrary; break;
break;
case CONTENT_TYPE_GAME:
proc = Game::HasGame; break;
break;
case CONTENT_TYPE_GAME_LIBRARY:
proc = Game::HasGameLibrary; break;
break;
case CONTENT_TYPE_SCENARIO:
case CONTENT_TYPE_HEIGHTMAP:
proc = HasScenario;
@ -183,6 +192,7 @@ void ClientNetworkContentSocketHandler::RequestContentList(ContentType type)
this->RequestContentList(CONTENT_TYPE_AI);
this->RequestContentList(CONTENT_TYPE_AI_LIBRARY);
this->RequestContentList(CONTENT_TYPE_GAME);
this->RequestContentList(CONTENT_TYPE_GAME_LIBRARY);
this->RequestContentList(CONTENT_TYPE_NEWGRF);
return;
}
@ -386,6 +396,7 @@ static char *GetFullFilename(const ContentInfo *ci, bool compressed)
case CONTENT_TYPE_SCENARIO: dir = SCENARIO_DIR; break;
case CONTENT_TYPE_HEIGHTMAP: dir = HEIGHTMAP_DIR; break;
case CONTENT_TYPE_GAME: dir = GAME_DIR; break;
case CONTENT_TYPE_GAME_LIBRARY: dir = GAME_LIBRARY_DIR; break;
}
static char buf[MAX_PATH];
@ -552,6 +563,10 @@ void ClientNetworkContentSocketHandler::AfterDownload()
sd = GAME_DIR;
break;
case CONTENT_TYPE_GAME_LIBRARY:
sd = GAME_LIBRARY_DIR;
break;
case CONTENT_TYPE_BASE_GRAPHICS:
case CONTENT_TYPE_BASE_SOUNDS:
case CONTENT_TYPE_BASE_MUSIC:

@ -25,4 +25,7 @@ void SQGSController_Register(Squirrel *engine)
SQGSController.DefSQStaticMethod(engine, &ScriptController::Print, "Print", 3, ".bs");
SQGSController.PostRegister(engine);
/* Register the import statement to the global scope */
SQGSController.DefSQStaticMethod(engine, &ScriptController::Import, "import", 4, ".ssi");
}

@ -451,6 +451,7 @@ SQRESULT Squirrel::LoadFile(HSQUIRRELVM vm, const char *filename, SQBool printer
if (file == NULL) file = FioFOpenFile(filename, "rb", AI_LIBRARY_DIR, &size);
} else if (strncmp(this->GetAPIName(), "GS", 2) == 0) {
file = FioFOpenFile(filename, "rb", GAME_DIR, &size);
if (file == NULL) file = FioFOpenFile(filename, "rb", GAME_LIBRARY_DIR, &size);
} else {
NOT_REACHED();
}

Loading…
Cancel
Save