primeiro commit
This commit is contained in:
133
src/game/game.hpp
Normal file
133
src/game/game.hpp
Normal file
@@ -0,0 +1,133 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* This file is part of OpenTTD.
|
||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @file game.hpp Base functions for all Games. */
|
||||
|
||||
#ifndef GAME_HPP
|
||||
#define GAME_HPP
|
||||
|
||||
#include "../core/string_compare_type.hpp"
|
||||
#include "game_scanner.hpp"
|
||||
#include <map>
|
||||
|
||||
/** A list that maps AI names to their AIInfo object. */
|
||||
typedef std::map<const char *, class ScriptInfo *, StringCompare> ScriptInfoList;
|
||||
|
||||
#include "../script/api/script_event_types.hpp"
|
||||
|
||||
/**
|
||||
* Main Game class. Contains all functions needed to start, stop, save and load Game Scripts.
|
||||
*/
|
||||
class Game {
|
||||
public:
|
||||
/**
|
||||
* Called every game-tick to let Game do something.
|
||||
*/
|
||||
static void GameLoop();
|
||||
|
||||
/**
|
||||
* Initialize the Game system.
|
||||
*/
|
||||
static void Initialize();
|
||||
|
||||
/**
|
||||
* Start up a new GameScript.
|
||||
*/
|
||||
static void StartNew();
|
||||
|
||||
/**
|
||||
* Uninitialize the Game system.
|
||||
*/
|
||||
static void Uninitialize(bool keepConfig);
|
||||
|
||||
/**
|
||||
* Suspends the Game Script and then pause the execution of the script. The
|
||||
* script will not be resumed from its suspended state until the script
|
||||
* has been unpaused.
|
||||
*/
|
||||
static void Pause();
|
||||
|
||||
/**
|
||||
* Resume execution of the Game Script. This function will not actually execute
|
||||
* the script, but set a flag so that the script is executed my the usual
|
||||
* mechanism that executes the script.
|
||||
*/
|
||||
static void Unpause();
|
||||
|
||||
/**
|
||||
* Checks if the Game Script is paused.
|
||||
* @return true if the Game Script is paused, otherwise false.
|
||||
*/
|
||||
static bool IsPaused();
|
||||
|
||||
/**
|
||||
* Queue a new event for a Game Script.
|
||||
*/
|
||||
static void NewEvent(class ScriptEvent *event);
|
||||
|
||||
/**
|
||||
* Get the current GameScript instance.
|
||||
*/
|
||||
static class GameInstance *GetGameInstance() { return Game::instance; }
|
||||
|
||||
/**
|
||||
* Get the current GameInfo.
|
||||
*/
|
||||
static class GameInfo *GetInfo() { return Game::info; }
|
||||
|
||||
static void Rescan();
|
||||
static void ResetConfig();
|
||||
|
||||
/**
|
||||
* Save data from a GameScript to a savegame.
|
||||
*/
|
||||
static void Save();
|
||||
|
||||
/**
|
||||
* Load data for a GameScript from a savegame.
|
||||
*/
|
||||
static void Load(int version);
|
||||
|
||||
/** 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
|
||||
/** Gets the ScriptScanner instance that is used to find Game scripts */
|
||||
static GameScannerInfo *GetScannerInfo();
|
||||
/** Gets the ScriptScanner instance that is used to find Game Libraries */
|
||||
static GameScannerLibrary *GetScannerLibrary();
|
||||
|
||||
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_info; ///< Scanner for Game scripts.
|
||||
static class GameScannerLibrary *scanner_library; ///< Scanner for GS Libraries.
|
||||
static class GameInfo *info; ///< Current selected GameInfo.
|
||||
};
|
||||
|
||||
#endif /* GAME_HPP */
|
||||
46
src/game/game_config.cpp
Normal file
46
src/game/game_config.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* This file is part of OpenTTD.
|
||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @file game_config.cpp Implementation of GameConfig. */
|
||||
|
||||
#include "../stdafx.h"
|
||||
#include "../settings_type.h"
|
||||
#include "game.hpp"
|
||||
#include "game_config.hpp"
|
||||
#include "game_info.hpp"
|
||||
|
||||
#include "../safeguards.h"
|
||||
|
||||
/* static */ GameConfig *GameConfig::GetConfig(ScriptSettingSource source)
|
||||
{
|
||||
GameConfig **config;
|
||||
if (source == SSS_FORCE_NEWGAME || (source == SSS_DEFAULT && _game_mode == GM_MENU)) {
|
||||
config = &_settings_newgame.game_config;
|
||||
} else {
|
||||
config = &_settings_game.game_config;
|
||||
}
|
||||
if (*config == NULL) *config = new GameConfig();
|
||||
return *config;
|
||||
}
|
||||
|
||||
class GameInfo *GameConfig::GetInfo() const
|
||||
{
|
||||
return static_cast<class GameInfo *>(ScriptConfig::GetInfo());
|
||||
}
|
||||
|
||||
ScriptInfo *GameConfig::FindInfo(const char *name, int version, bool force_exact_match)
|
||||
{
|
||||
return static_cast<ScriptInfo *>(Game::FindInfo(name, version, force_exact_match));
|
||||
}
|
||||
|
||||
bool GameConfig::ResetInfo(bool force_exact_match)
|
||||
{
|
||||
this->info = (ScriptInfo *)Game::FindInfo(this->name, force_exact_match ? this->version : -1, force_exact_match);
|
||||
return this->info != NULL;
|
||||
}
|
||||
48
src/game/game_config.hpp
Normal file
48
src/game/game_config.hpp
Normal file
@@ -0,0 +1,48 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* This file is part of OpenTTD.
|
||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @file game_config.hpp GameConfig stores the configuration settings of every Game. */
|
||||
|
||||
#ifndef GAME_CONFIG_HPP
|
||||
#define GAME_CONFIG_HPP
|
||||
|
||||
#include "../script/script_config.hpp"
|
||||
|
||||
class GameConfig : public ScriptConfig {
|
||||
public:
|
||||
/**
|
||||
* Get the config of a company.
|
||||
*/
|
||||
static GameConfig *GetConfig(ScriptSettingSource source = SSS_DEFAULT);
|
||||
|
||||
GameConfig() :
|
||||
ScriptConfig()
|
||||
{}
|
||||
|
||||
GameConfig(const GameConfig *config) :
|
||||
ScriptConfig(config)
|
||||
{}
|
||||
|
||||
class GameInfo *GetInfo() const;
|
||||
|
||||
/**
|
||||
* When ever the Game Scanner is reloaded, all infos become invalid. This
|
||||
* function tells GameConfig about this.
|
||||
* @param force_exact_match If true try to find the exact same version
|
||||
* as specified. If false any version is ok.
|
||||
* @return \c true if the reset was successful, \c false if the Game was no longer
|
||||
* found.
|
||||
*/
|
||||
bool ResetInfo(bool force_exact_match);
|
||||
|
||||
protected:
|
||||
/* virtual */ ScriptInfo *FindInfo(const char *name, int version, bool force_exact_match);
|
||||
};
|
||||
|
||||
#endif /* GAME_CONFIG_HPP */
|
||||
278
src/game/game_core.cpp
Normal file
278
src/game/game_core.cpp
Normal file
@@ -0,0 +1,278 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* This file is part of OpenTTD.
|
||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @file game_core.cpp Implementation of Game. */
|
||||
|
||||
#include "../stdafx.h"
|
||||
#include "../core/backup_type.hpp"
|
||||
#include "../company_base.h"
|
||||
#include "../company_func.h"
|
||||
#include "../network/network.h"
|
||||
#include "../window_func.h"
|
||||
#include "game.hpp"
|
||||
#include "game_scanner.hpp"
|
||||
#include "game_config.hpp"
|
||||
#include "game_instance.hpp"
|
||||
#include "game_info.hpp"
|
||||
|
||||
#include "../safeguards.h"
|
||||
|
||||
/* static */ uint Game::frame_counter = 0;
|
||||
/* static */ GameInfo *Game::info = NULL;
|
||||
/* static */ GameInstance *Game::instance = NULL;
|
||||
/* static */ GameScannerInfo *Game::scanner_info = NULL;
|
||||
/* static */ GameScannerLibrary *Game::scanner_library = NULL;
|
||||
|
||||
/* static */ void Game::GameLoop()
|
||||
{
|
||||
if (_networking && !_network_server) return;
|
||||
if (Game::instance == NULL) return;
|
||||
|
||||
Game::frame_counter++;
|
||||
|
||||
Backup<CompanyByte> cur_company(_current_company, FILE_LINE);
|
||||
cur_company.Change(OWNER_DEITY);
|
||||
Game::instance->GameLoop();
|
||||
cur_company.Restore();
|
||||
|
||||
/* Occasionally collect garbage */
|
||||
if ((Game::frame_counter & 255) == 0) {
|
||||
Game::instance->CollectGarbage();
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ void Game::Initialize()
|
||||
{
|
||||
if (Game::instance != NULL) Game::Uninitialize(true);
|
||||
|
||||
Game::frame_counter = 0;
|
||||
|
||||
if (Game::scanner_info == NULL) {
|
||||
TarScanner::DoScan(TarScanner::GAME);
|
||||
Game::scanner_info = new GameScannerInfo();
|
||||
Game::scanner_info->Initialize();
|
||||
Game::scanner_library = new GameScannerLibrary();
|
||||
Game::scanner_library->Initialize();
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ void Game::StartNew()
|
||||
{
|
||||
if (Game::instance != NULL) return;
|
||||
|
||||
/* Clients shouldn't start GameScripts */
|
||||
if (_networking && !_network_server) return;
|
||||
|
||||
GameConfig *config = GameConfig::GetConfig(GameConfig::SSS_FORCE_GAME);
|
||||
GameInfo *info = config->GetInfo();
|
||||
if (info == NULL) return;
|
||||
|
||||
config->AnchorUnchangeableSettings();
|
||||
|
||||
Backup<CompanyByte> cur_company(_current_company, FILE_LINE);
|
||||
cur_company.Change(OWNER_DEITY);
|
||||
|
||||
Game::info = info;
|
||||
Game::instance = new GameInstance();
|
||||
Game::instance->Initialize(info);
|
||||
|
||||
cur_company.Restore();
|
||||
|
||||
InvalidateWindowData(WC_AI_DEBUG, 0, -1);
|
||||
}
|
||||
|
||||
/* static */ void Game::Uninitialize(bool keepConfig)
|
||||
{
|
||||
Backup<CompanyByte> cur_company(_current_company, FILE_LINE);
|
||||
|
||||
delete Game::instance;
|
||||
Game::instance = NULL;
|
||||
Game::info = NULL;
|
||||
|
||||
cur_company.Restore();
|
||||
|
||||
if (keepConfig) {
|
||||
Rescan();
|
||||
} else {
|
||||
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;
|
||||
_settings_game.game_config = NULL;
|
||||
}
|
||||
if (_settings_newgame.game_config != NULL) {
|
||||
delete _settings_newgame.game_config;
|
||||
_settings_newgame.game_config = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ void Game::Pause()
|
||||
{
|
||||
if (Game::instance != NULL) Game::instance->Pause();
|
||||
}
|
||||
|
||||
/* static */ void Game::Unpause()
|
||||
{
|
||||
if (Game::instance != NULL) Game::instance->Unpause();
|
||||
}
|
||||
|
||||
/* static */ bool Game::IsPaused()
|
||||
{
|
||||
return Game::instance != NULL? Game::instance->IsPaused() : false;
|
||||
}
|
||||
|
||||
/* static */ void Game::NewEvent(ScriptEvent *event)
|
||||
{
|
||||
/* AddRef() and Release() need to be called at least once, so do it here */
|
||||
event->AddRef();
|
||||
|
||||
/* Clients should ignore events */
|
||||
if (_networking && !_network_server) {
|
||||
event->Release();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check if Game instance is alive */
|
||||
if (Game::instance == NULL) {
|
||||
event->Release();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Queue the event */
|
||||
Backup<CompanyByte> cur_company(_current_company, OWNER_DEITY, FILE_LINE);
|
||||
Game::instance->InsertEvent(event);
|
||||
cur_company.Restore();
|
||||
|
||||
event->Release();
|
||||
}
|
||||
|
||||
/* static */ void Game::ResetConfig()
|
||||
{
|
||||
/* Check for both newgame as current game if we can reload the GameInfo inside
|
||||
* the GameConfig. If not, remove the Game from the list. */
|
||||
if (_settings_game.game_config != NULL && _settings_game.game_config->HasScript()) {
|
||||
if (!_settings_game.game_config->ResetInfo(true)) {
|
||||
DEBUG(script, 0, "After a reload, the GameScript by the name '%s' was no longer found, and removed from the list.", _settings_game.game_config->GetName());
|
||||
_settings_game.game_config->Change(NULL);
|
||||
if (Game::instance != NULL) {
|
||||
delete Game::instance;
|
||||
Game::instance = NULL;
|
||||
Game::info = NULL;
|
||||
}
|
||||
} else if (Game::instance != NULL) {
|
||||
Game::info = _settings_game.game_config->GetInfo();
|
||||
}
|
||||
}
|
||||
if (_settings_newgame.game_config != NULL && _settings_newgame.game_config->HasScript()) {
|
||||
if (!_settings_newgame.game_config->ResetInfo(false)) {
|
||||
DEBUG(script, 0, "After a reload, the GameScript by the name '%s' was no longer found, and removed from the list.", _settings_newgame.game_config->GetName());
|
||||
_settings_newgame.game_config->Change(NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ void Game::Rescan()
|
||||
{
|
||||
TarScanner::DoScan(TarScanner::GAME);
|
||||
|
||||
Game::scanner_info->RescanDir();
|
||||
Game::scanner_library->RescanDir();
|
||||
ResetConfig();
|
||||
|
||||
InvalidateWindowData(WC_AI_LIST, 0, 1);
|
||||
SetWindowClassesDirty(WC_AI_DEBUG);
|
||||
InvalidateWindowClassesData(WC_AI_SETTINGS);
|
||||
}
|
||||
|
||||
|
||||
/* static */ void Game::Save()
|
||||
{
|
||||
if (Game::instance != NULL && (!_networking || _network_server)) {
|
||||
Backup<CompanyByte> cur_company(_current_company, OWNER_DEITY, FILE_LINE);
|
||||
Game::instance->Save();
|
||||
cur_company.Restore();
|
||||
} else {
|
||||
GameInstance::SaveEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ void Game::Load(int version)
|
||||
{
|
||||
if (Game::instance != NULL && (!_networking || _network_server)) {
|
||||
Backup<CompanyByte> cur_company(_current_company, OWNER_DEITY, FILE_LINE);
|
||||
Game::instance->Load(version);
|
||||
cur_company.Restore();
|
||||
} else {
|
||||
/* Read, but ignore, the load data */
|
||||
GameInstance::LoadEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ char *Game::GetConsoleList(char *p, const char *last, bool 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_info->GetInfoList();
|
||||
}
|
||||
|
||||
/* static */ const ScriptInfoList *Game::GetUniqueInfoList()
|
||||
{
|
||||
return Game::scanner_info->GetUniqueInfoList();
|
||||
}
|
||||
|
||||
/* static */ GameInfo *Game::FindInfo(const char *name, int version, bool 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) */
|
||||
|
||||
/* static */ GameScannerInfo *Game::GetScannerInfo()
|
||||
{
|
||||
return Game::scanner_info;
|
||||
}
|
||||
/* static */ GameScannerLibrary *Game::GetScannerLibrary()
|
||||
{
|
||||
return Game::scanner_library;
|
||||
}
|
||||
143
src/game/game_info.cpp
Normal file
143
src/game/game_info.cpp
Normal file
@@ -0,0 +1,143 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* This file is part of OpenTTD.
|
||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @file game_info.cpp Implementation of GameInfo */
|
||||
|
||||
#include "../stdafx.h"
|
||||
|
||||
#include "../script/squirrel_class.hpp"
|
||||
#include "game_info.hpp"
|
||||
#include "game_scanner.hpp"
|
||||
#include "../debug.h"
|
||||
|
||||
#include "../safeguards.h"
|
||||
|
||||
/**
|
||||
* Check if the API version provided by the Game is supported.
|
||||
* @param api_version The API version as provided by the Game.
|
||||
*/
|
||||
static bool CheckAPIVersion(const char *api_version)
|
||||
{
|
||||
return strcmp(api_version, "1.2") == 0 || strcmp(api_version, "1.3") == 0 || strcmp(api_version, "1.4") == 0 ||
|
||||
strcmp(api_version, "1.5") == 0;
|
||||
}
|
||||
|
||||
#if defined(WIN32)
|
||||
#undef GetClassName
|
||||
#endif /* WIN32 */
|
||||
template <> const char *GetClassName<GameInfo, ST_GS>() { return "GSInfo"; }
|
||||
|
||||
/* static */ void GameInfo::RegisterAPI(Squirrel *engine)
|
||||
{
|
||||
/* Create the GSInfo class, and add the RegisterGS function */
|
||||
DefSQClass<GameInfo, ST_GS> SQGSInfo("GSInfo");
|
||||
SQGSInfo.PreRegister(engine);
|
||||
SQGSInfo.AddConstructor<void (GameInfo::*)(), 1>(engine, "x");
|
||||
SQGSInfo.DefSQAdvancedMethod(engine, &GameInfo::AddSetting, "AddSetting");
|
||||
SQGSInfo.DefSQAdvancedMethod(engine, &GameInfo::AddLabels, "AddLabels");
|
||||
SQGSInfo.DefSQConst(engine, SCRIPTCONFIG_NONE, "CONFIG_NONE");
|
||||
SQGSInfo.DefSQConst(engine, SCRIPTCONFIG_RANDOM, "CONFIG_RANDOM");
|
||||
SQGSInfo.DefSQConst(engine, SCRIPTCONFIG_BOOLEAN, "CONFIG_BOOLEAN");
|
||||
SQGSInfo.DefSQConst(engine, SCRIPTCONFIG_INGAME, "CONFIG_INGAME");
|
||||
SQGSInfo.DefSQConst(engine, SCRIPTCONFIG_DEVELOPER, "CONFIG_DEVELOPER");
|
||||
|
||||
SQGSInfo.PostRegister(engine);
|
||||
engine->AddMethod("RegisterGS", &GameInfo::Constructor, 2, "tx");
|
||||
}
|
||||
|
||||
/* static */ SQInteger GameInfo::Constructor(HSQUIRRELVM vm)
|
||||
{
|
||||
/* Get the GameInfo */
|
||||
SQUserPointer instance = NULL;
|
||||
if (SQ_FAILED(sq_getinstanceup(vm, 2, &instance, 0)) || instance == NULL) return sq_throwerror(vm, "Pass an instance of a child class of GameInfo to RegisterGame");
|
||||
GameInfo *info = (GameInfo *)instance;
|
||||
|
||||
SQInteger res = ScriptInfo::Constructor(vm, info);
|
||||
if (res != 0) return res;
|
||||
|
||||
if (info->engine->MethodExists(*info->SQ_instance, "MinVersionToLoad")) {
|
||||
if (!info->engine->CallIntegerMethod(*info->SQ_instance, "MinVersionToLoad", &info->min_loadable_version, MAX_GET_OPS)) return SQ_ERROR;
|
||||
} else {
|
||||
info->min_loadable_version = info->GetVersion();
|
||||
}
|
||||
/* When there is an IsSelectable function, call it. */
|
||||
if (info->engine->MethodExists(*info->SQ_instance, "IsDeveloperOnly")) {
|
||||
if (!info->engine->CallBoolMethod(*info->SQ_instance, "IsDeveloperOnly", &info->is_developer_only, MAX_GET_OPS)) return SQ_ERROR;
|
||||
} else {
|
||||
info->is_developer_only = false;
|
||||
}
|
||||
/* Try to get the API version the AI is written for. */
|
||||
if (!info->CheckMethod("GetAPIVersion")) return SQ_ERROR;
|
||||
if (!info->engine->CallStringMethodStrdup(*info->SQ_instance, "GetAPIVersion", &info->api_version, MAX_GET_OPS)) return SQ_ERROR;
|
||||
if (!CheckAPIVersion(info->api_version)) {
|
||||
DEBUG(script, 1, "Loading info.nut from (%s.%d): GetAPIVersion returned invalid version", info->GetName(), info->GetVersion());
|
||||
return SQ_ERROR;
|
||||
}
|
||||
|
||||
/* Remove the link to the real instance, else it might get deleted by RegisterGame() */
|
||||
sq_setinstanceup(vm, 2, NULL);
|
||||
/* Register the Game to the base system */
|
||||
info->GetScanner()->RegisterScript(info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
GameInfo::GameInfo() :
|
||||
min_loadable_version(0),
|
||||
is_developer_only(false),
|
||||
api_version(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
GameInfo::~GameInfo()
|
||||
{
|
||||
free(this->api_version);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
76
src/game/game_info.hpp
Normal file
76
src/game/game_info.hpp
Normal file
@@ -0,0 +1,76 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* This file is part of OpenTTD.
|
||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @file game_info.hpp GameInfo keeps track of all information of an Game, like Author, Description, ... */
|
||||
|
||||
#ifndef GAME_INFO_HPP
|
||||
#define GAME_INFO_HPP
|
||||
|
||||
#include "../script/script_info.hpp"
|
||||
|
||||
/** All static information from an Game like name, version, etc. */
|
||||
class GameInfo : public ScriptInfo {
|
||||
public:
|
||||
GameInfo();
|
||||
~GameInfo();
|
||||
|
||||
/**
|
||||
* Register the functions of this class.
|
||||
*/
|
||||
static void RegisterAPI(Squirrel *engine);
|
||||
|
||||
/**
|
||||
* Create an Game, using this GameInfo as start-template.
|
||||
*/
|
||||
static SQInteger Constructor(HSQUIRRELVM vm);
|
||||
|
||||
/**
|
||||
* Check if we can start this Game.
|
||||
*/
|
||||
bool CanLoadFromVersion(int version) const;
|
||||
|
||||
/**
|
||||
* Get the API version this Game is written for.
|
||||
*/
|
||||
const char *GetAPIVersion() const { return this->api_version; }
|
||||
|
||||
/* virtual */ bool IsDeveloperOnly() const { return this->is_developer_only; }
|
||||
|
||||
private:
|
||||
int min_loadable_version; ///< The Game can load savegame data if the version is equal or greater than this.
|
||||
bool is_developer_only; ///< Is the script selectable by non-developers?
|
||||
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 */
|
||||
263
src/game/game_instance.cpp
Normal file
263
src/game/game_instance.cpp
Normal file
@@ -0,0 +1,263 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* This file is part of OpenTTD.
|
||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @file game_instance.cpp Implementation of GameInstance. */
|
||||
|
||||
#include "../stdafx.h"
|
||||
#include "../error.h"
|
||||
|
||||
#include "../script/squirrel_class.hpp"
|
||||
|
||||
#include "../script/script_storage.hpp"
|
||||
#include "../ai/ai_gui.hpp"
|
||||
#include "game_config.hpp"
|
||||
#include "game_info.hpp"
|
||||
#include "game_instance.hpp"
|
||||
#include "game_text.hpp"
|
||||
#include "game.hpp"
|
||||
|
||||
/* Convert all Game related classes to Squirrel data.
|
||||
* Note: this line is a marker in squirrel_export.sh. Do not change! */
|
||||
#include "../script/api/game/game_accounting.hpp.sq"
|
||||
#include "../script/api/game/game_admin.hpp.sq"
|
||||
#include "../script/api/game/game_airport.hpp.sq"
|
||||
#include "../script/api/game/game_base.hpp.sq"
|
||||
#include "../script/api/game/game_basestation.hpp.sq"
|
||||
#include "../script/api/game/game_bridge.hpp.sq"
|
||||
#include "../script/api/game/game_bridgelist.hpp.sq"
|
||||
#include "../script/api/game/game_cargo.hpp.sq"
|
||||
#include "../script/api/game/game_cargolist.hpp.sq"
|
||||
#include "../script/api/game/game_cargomonitor.hpp.sq"
|
||||
#include "../script/api/game/game_company.hpp.sq"
|
||||
#include "../script/api/game/game_companymode.hpp.sq"
|
||||
#include "../script/api/game/game_controller.hpp.sq"
|
||||
#include "../script/api/game/game_date.hpp.sq"
|
||||
#include "../script/api/game/game_depotlist.hpp.sq"
|
||||
#include "../script/api/game/game_engine.hpp.sq"
|
||||
#include "../script/api/game/game_enginelist.hpp.sq"
|
||||
#include "../script/api/game/game_error.hpp.sq"
|
||||
#include "../script/api/game/game_event.hpp.sq"
|
||||
#include "../script/api/game/game_event_types.hpp.sq"
|
||||
#include "../script/api/game/game_execmode.hpp.sq"
|
||||
#include "../script/api/game/game_game.hpp.sq"
|
||||
#include "../script/api/game/game_gamesettings.hpp.sq"
|
||||
#include "../script/api/game/game_goal.hpp.sq"
|
||||
#include "../script/api/game/game_industry.hpp.sq"
|
||||
#include "../script/api/game/game_industrylist.hpp.sq"
|
||||
#include "../script/api/game/game_industrytype.hpp.sq"
|
||||
#include "../script/api/game/game_industrytypelist.hpp.sq"
|
||||
#include "../script/api/game/game_infrastructure.hpp.sq"
|
||||
#include "../script/api/game/game_list.hpp.sq"
|
||||
#include "../script/api/game/game_log.hpp.sq"
|
||||
#include "../script/api/game/game_map.hpp.sq"
|
||||
#include "../script/api/game/game_marine.hpp.sq"
|
||||
#include "../script/api/game/game_news.hpp.sq"
|
||||
#include "../script/api/game/game_order.hpp.sq"
|
||||
#include "../script/api/game/game_rail.hpp.sq"
|
||||
#include "../script/api/game/game_railtypelist.hpp.sq"
|
||||
#include "../script/api/game/game_road.hpp.sq"
|
||||
#include "../script/api/game/game_sign.hpp.sq"
|
||||
#include "../script/api/game/game_signlist.hpp.sq"
|
||||
#include "../script/api/game/game_station.hpp.sq"
|
||||
#include "../script/api/game/game_stationlist.hpp.sq"
|
||||
#include "../script/api/game/game_story_page.hpp.sq"
|
||||
#include "../script/api/game/game_storypageelementlist.hpp.sq"
|
||||
#include "../script/api/game/game_storypagelist.hpp.sq"
|
||||
#include "../script/api/game/game_subsidy.hpp.sq"
|
||||
#include "../script/api/game/game_subsidylist.hpp.sq"
|
||||
#include "../script/api/game/game_testmode.hpp.sq"
|
||||
#include "../script/api/game/game_text.hpp.sq"
|
||||
#include "../script/api/game/game_tile.hpp.sq"
|
||||
#include "../script/api/game/game_tilelist.hpp.sq"
|
||||
#include "../script/api/game/game_town.hpp.sq"
|
||||
#include "../script/api/game/game_townlist.hpp.sq"
|
||||
#include "../script/api/game/game_tunnel.hpp.sq"
|
||||
#include "../script/api/game/game_vehicle.hpp.sq"
|
||||
#include "../script/api/game/game_vehiclelist.hpp.sq"
|
||||
#include "../script/api/game/game_viewport.hpp.sq"
|
||||
#include "../script/api/game/game_waypoint.hpp.sq"
|
||||
#include "../script/api/game/game_waypointlist.hpp.sq"
|
||||
#include "../script/api/game/game_window.hpp.sq"
|
||||
|
||||
#include "../safeguards.h"
|
||||
|
||||
|
||||
GameInstance::GameInstance() :
|
||||
ScriptInstance("GS")
|
||||
{}
|
||||
|
||||
void GameInstance::Initialize(GameInfo *info)
|
||||
{
|
||||
this->versionAPI = info->GetAPIVersion();
|
||||
|
||||
/* Register the GameController */
|
||||
SQGSController_Register(this->engine);
|
||||
|
||||
ScriptInstance::Initialize(info->GetMainScript(), info->GetInstanceName(), OWNER_DEITY);
|
||||
}
|
||||
|
||||
void GameInstance::RegisterAPI()
|
||||
{
|
||||
ScriptInstance::RegisterAPI();
|
||||
|
||||
/* Register all classes */
|
||||
SQGSList_Register(this->engine);
|
||||
SQGSAccounting_Register(this->engine);
|
||||
SQGSAdmin_Register(this->engine);
|
||||
SQGSAirport_Register(this->engine);
|
||||
SQGSBase_Register(this->engine);
|
||||
SQGSBaseStation_Register(this->engine);
|
||||
SQGSBridge_Register(this->engine);
|
||||
SQGSBridgeList_Register(this->engine);
|
||||
SQGSBridgeList_Length_Register(this->engine);
|
||||
SQGSCargo_Register(this->engine);
|
||||
SQGSCargoList_Register(this->engine);
|
||||
SQGSCargoList_IndustryAccepting_Register(this->engine);
|
||||
SQGSCargoList_IndustryProducing_Register(this->engine);
|
||||
SQGSCargoList_StationAccepting_Register(this->engine);
|
||||
SQGSCargoMonitor_Register(this->engine);
|
||||
SQGSCompany_Register(this->engine);
|
||||
SQGSCompanyMode_Register(this->engine);
|
||||
SQGSDate_Register(this->engine);
|
||||
SQGSDepotList_Register(this->engine);
|
||||
SQGSEngine_Register(this->engine);
|
||||
SQGSEngineList_Register(this->engine);
|
||||
SQGSError_Register(this->engine);
|
||||
SQGSEvent_Register(this->engine);
|
||||
SQGSEventAdminPort_Register(this->engine);
|
||||
SQGSEventCompanyBankrupt_Register(this->engine);
|
||||
SQGSEventCompanyInTrouble_Register(this->engine);
|
||||
SQGSEventCompanyMerger_Register(this->engine);
|
||||
SQGSEventCompanyNew_Register(this->engine);
|
||||
SQGSEventCompanyTown_Register(this->engine);
|
||||
SQGSEventController_Register(this->engine);
|
||||
SQGSEventExclusiveTransportRights_Register(this->engine);
|
||||
SQGSEventGoalQuestionAnswer_Register(this->engine);
|
||||
SQGSEventIndustryClose_Register(this->engine);
|
||||
SQGSEventIndustryOpen_Register(this->engine);
|
||||
SQGSEventRoadReconstruction_Register(this->engine);
|
||||
SQGSEventStationFirstVehicle_Register(this->engine);
|
||||
SQGSEventSubsidyAwarded_Register(this->engine);
|
||||
SQGSEventSubsidyExpired_Register(this->engine);
|
||||
SQGSEventSubsidyOffer_Register(this->engine);
|
||||
SQGSEventSubsidyOfferExpired_Register(this->engine);
|
||||
SQGSEventTownFounded_Register(this->engine);
|
||||
SQGSEventVehicleCrashed_Register(this->engine);
|
||||
SQGSEventWindowWidgetClick_Register(this->engine);
|
||||
SQGSExecMode_Register(this->engine);
|
||||
SQGSGame_Register(this->engine);
|
||||
SQGSGameSettings_Register(this->engine);
|
||||
SQGSGoal_Register(this->engine);
|
||||
SQGSIndustry_Register(this->engine);
|
||||
SQGSIndustryList_Register(this->engine);
|
||||
SQGSIndustryList_CargoAccepting_Register(this->engine);
|
||||
SQGSIndustryList_CargoProducing_Register(this->engine);
|
||||
SQGSIndustryType_Register(this->engine);
|
||||
SQGSIndustryTypeList_Register(this->engine);
|
||||
SQGSInfrastructure_Register(this->engine);
|
||||
SQGSLog_Register(this->engine);
|
||||
SQGSMap_Register(this->engine);
|
||||
SQGSMarine_Register(this->engine);
|
||||
SQGSNews_Register(this->engine);
|
||||
SQGSOrder_Register(this->engine);
|
||||
SQGSRail_Register(this->engine);
|
||||
SQGSRailTypeList_Register(this->engine);
|
||||
SQGSRoad_Register(this->engine);
|
||||
SQGSSign_Register(this->engine);
|
||||
SQGSSignList_Register(this->engine);
|
||||
SQGSStation_Register(this->engine);
|
||||
SQGSStationList_Register(this->engine);
|
||||
SQGSStationList_Cargo_Register(this->engine);
|
||||
SQGSStationList_CargoPlanned_Register(this->engine);
|
||||
SQGSStationList_CargoPlannedByFrom_Register(this->engine);
|
||||
SQGSStationList_CargoPlannedByVia_Register(this->engine);
|
||||
SQGSStationList_CargoPlannedFromByVia_Register(this->engine);
|
||||
SQGSStationList_CargoPlannedViaByFrom_Register(this->engine);
|
||||
SQGSStationList_CargoWaiting_Register(this->engine);
|
||||
SQGSStationList_CargoWaitingByFrom_Register(this->engine);
|
||||
SQGSStationList_CargoWaitingByVia_Register(this->engine);
|
||||
SQGSStationList_CargoWaitingFromByVia_Register(this->engine);
|
||||
SQGSStationList_CargoWaitingViaByFrom_Register(this->engine);
|
||||
SQGSStationList_Vehicle_Register(this->engine);
|
||||
SQGSStoryPage_Register(this->engine);
|
||||
SQGSStoryPageElementList_Register(this->engine);
|
||||
SQGSStoryPageList_Register(this->engine);
|
||||
SQGSSubsidy_Register(this->engine);
|
||||
SQGSSubsidyList_Register(this->engine);
|
||||
SQGSTestMode_Register(this->engine);
|
||||
SQGSText_Register(this->engine);
|
||||
SQGSTile_Register(this->engine);
|
||||
SQGSTileList_Register(this->engine);
|
||||
SQGSTileList_IndustryAccepting_Register(this->engine);
|
||||
SQGSTileList_IndustryProducing_Register(this->engine);
|
||||
SQGSTileList_StationType_Register(this->engine);
|
||||
SQGSTown_Register(this->engine);
|
||||
SQGSTownEffectList_Register(this->engine);
|
||||
SQGSTownList_Register(this->engine);
|
||||
SQGSTunnel_Register(this->engine);
|
||||
SQGSVehicle_Register(this->engine);
|
||||
SQGSVehicleList_Register(this->engine);
|
||||
SQGSVehicleList_Depot_Register(this->engine);
|
||||
SQGSVehicleList_SharedOrders_Register(this->engine);
|
||||
SQGSVehicleList_Station_Register(this->engine);
|
||||
SQGSViewport_Register(this->engine);
|
||||
SQGSWaypoint_Register(this->engine);
|
||||
SQGSWaypointList_Register(this->engine);
|
||||
SQGSWaypointList_Vehicle_Register(this->engine);
|
||||
SQGSWindow_Register(this->engine);
|
||||
|
||||
RegisterGameTranslation(this->engine);
|
||||
|
||||
if (!this->LoadCompatibilityScripts(this->versionAPI, GAME_DIR)) this->Died();
|
||||
}
|
||||
|
||||
int GameInstance::GetSetting(const char *name)
|
||||
{
|
||||
return GameConfig::GetConfig()->GetSetting(name);
|
||||
}
|
||||
|
||||
ScriptInfo *GameInstance::FindLibrary(const char *library, int version)
|
||||
{
|
||||
return (ScriptInfo *)Game::FindLibrary(library, version);
|
||||
}
|
||||
|
||||
void GameInstance::Died()
|
||||
{
|
||||
ScriptInstance::Died();
|
||||
|
||||
ShowAIDebugWindow(OWNER_DEITY);
|
||||
|
||||
const GameInfo *info = Game::GetInfo();
|
||||
if (info != NULL) {
|
||||
ShowErrorMessage(STR_ERROR_AI_PLEASE_REPORT_CRASH, INVALID_STRING_ID, WL_WARNING);
|
||||
|
||||
if (info->GetURL() != NULL) {
|
||||
ScriptLog::Info("Please report the error to the following URL:");
|
||||
ScriptLog::Info(info->GetURL());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DoCommand callback function for all commands executed by Game Scripts.
|
||||
* @param result The result of the command.
|
||||
* @param tile The tile on which the command was executed.
|
||||
* @param p1 p1 as given to DoCommandPInternal.
|
||||
* @param p2 p2 as given to DoCommandPInternal.
|
||||
*/
|
||||
void CcGame(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2)
|
||||
{
|
||||
Game::GetGameInstance()->DoCommandCallback(result, tile, p1, p2);
|
||||
Game::GetGameInstance()->Continue();
|
||||
}
|
||||
|
||||
CommandCallback *GameInstance::GetDoCommandCallback()
|
||||
{
|
||||
return &CcGame;
|
||||
}
|
||||
38
src/game/game_instance.hpp
Normal file
38
src/game/game_instance.hpp
Normal file
@@ -0,0 +1,38 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* This file is part of OpenTTD.
|
||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @file game_instance.hpp The GameInstance tracks games. */
|
||||
|
||||
#ifndef GAME_INSTANCE_HPP
|
||||
#define GAME_INSTANCE_HPP
|
||||
|
||||
#include "../script/script_instance.hpp"
|
||||
|
||||
/** Runtime information about a game script like a pointer to the squirrel vm and the current state. */
|
||||
class GameInstance : public ScriptInstance {
|
||||
public:
|
||||
GameInstance();
|
||||
|
||||
/**
|
||||
* Initialize the script and prepare it for its first run.
|
||||
* @param info The GameInfo to start.
|
||||
*/
|
||||
void Initialize(class GameInfo *info);
|
||||
|
||||
/* virtual */ int GetSetting(const char *name);
|
||||
/* virtual */ ScriptInfo *FindLibrary(const char *library, int version);
|
||||
|
||||
private:
|
||||
/* virtual */ void RegisterAPI();
|
||||
/* virtual */ void Died();
|
||||
/* virtual */ CommandCallback *GetDoCommandCallback();
|
||||
/* virtual */ void LoadDummyScript() {}
|
||||
};
|
||||
|
||||
#endif /* GAME_INSTANCE_HPP */
|
||||
112
src/game/game_scanner.cpp
Normal file
112
src/game/game_scanner.cpp
Normal file
@@ -0,0 +1,112 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* This file is part of OpenTTD.
|
||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @file game_scanner.cpp allows scanning Game scripts */
|
||||
|
||||
#include "../stdafx.h"
|
||||
|
||||
#include "../script/squirrel_class.hpp"
|
||||
#include "game_info.hpp"
|
||||
#include "game_scanner.hpp"
|
||||
|
||||
#include "../safeguards.h"
|
||||
|
||||
|
||||
void GameScannerInfo::Initialize()
|
||||
{
|
||||
ScriptScanner::Initialize("GSScanner");
|
||||
}
|
||||
|
||||
void GameScannerInfo::GetScriptName(ScriptInfo *info, char *name, const char *last)
|
||||
{
|
||||
seprintf(name, last, "%s", info->GetName());
|
||||
}
|
||||
|
||||
void GameScannerInfo::RegisterAPI(class Squirrel *engine)
|
||||
{
|
||||
GameInfo::RegisterAPI(engine);
|
||||
}
|
||||
|
||||
GameInfo *GameScannerInfo::FindInfo(const char *nameParam, int versionParam, bool force_exact_match)
|
||||
{
|
||||
if (this->info_list.size() == 0) return NULL;
|
||||
if (nameParam == NULL) return NULL;
|
||||
|
||||
char game_name[1024];
|
||||
strecpy(game_name, nameParam, lastof(game_name));
|
||||
strtolower(game_name);
|
||||
|
||||
GameInfo *info = NULL;
|
||||
int version = -1;
|
||||
|
||||
if (versionParam == -1) {
|
||||
/* We want to load the latest version of this Game script; so find it */
|
||||
if (this->info_single_list.find(game_name) != this->info_single_list.end()) return static_cast<GameInfo *>(this->info_single_list[game_name]);
|
||||
|
||||
/* If we didn't find a match Game script, maybe the user included a version */
|
||||
char *e = strrchr(game_name, '.');
|
||||
if (e == NULL) return NULL;
|
||||
*e = '\0';
|
||||
e++;
|
||||
versionParam = atoi(e);
|
||||
/* FALL THROUGH, like we were calling this function with a version. */
|
||||
}
|
||||
|
||||
if (force_exact_match) {
|
||||
/* Try to find a direct 'name.version' match */
|
||||
char game_name_tmp[1024];
|
||||
seprintf(game_name_tmp, lastof(game_name_tmp), "%s.%d", game_name, versionParam);
|
||||
strtolower(game_name_tmp);
|
||||
if (this->info_list.find(game_name_tmp) != this->info_list.end()) return static_cast<GameInfo *>(this->info_list[game_name_tmp]);
|
||||
}
|
||||
|
||||
/* See if there is a compatible Game script which goes by that name, with the highest
|
||||
* version which allows loading the requested version */
|
||||
ScriptInfoList::iterator it = this->info_list.begin();
|
||||
for (; it != this->info_list.end(); it++) {
|
||||
GameInfo *i = static_cast<GameInfo *>((*it).second);
|
||||
if (strcasecmp(game_name, i->GetName()) == 0 && i->CanLoadFromVersion(versionParam) && (version == -1 || i->GetVersion() > version)) {
|
||||
version = (*it).second->GetVersion();
|
||||
info = i;
|
||||
}
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
|
||||
void GameScannerLibrary::Initialize()
|
||||
{
|
||||
ScriptScanner::Initialize("GSScanner");
|
||||
}
|
||||
|
||||
void GameScannerLibrary::GetScriptName(ScriptInfo *info, char *name, const char *last)
|
||||
{
|
||||
GameLibrary *library = static_cast<GameLibrary *>(info);
|
||||
seprintf(name, last, "%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];
|
||||
seprintf(library_name, lastof(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);
|
||||
}
|
||||
59
src/game/game_scanner.hpp
Normal file
59
src/game/game_scanner.hpp
Normal file
@@ -0,0 +1,59 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* This file is part of OpenTTD.
|
||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @file game_scanner.hpp declarations of the class for Game scanner */
|
||||
|
||||
#ifndef GAME_SCANNER_HPP
|
||||
#define GAME_SCANNER_HPP
|
||||
|
||||
#include "../script/script_scanner.hpp"
|
||||
|
||||
class GameScannerInfo : public ScriptScanner {
|
||||
public:
|
||||
/* virtual */ void Initialize();
|
||||
|
||||
/**
|
||||
* Check if we have a game by name and version available in our list.
|
||||
* @param nameParam The name of the game script.
|
||||
* @param versionParam The version of the game script, or -1 if you want the latest.
|
||||
* @param force_exact_match Only match name+version, never latest.
|
||||
* @return NULL if no match found, otherwise the game script that matched.
|
||||
*/
|
||||
class GameInfo *FindInfo(const char *nameParam, int versionParam, bool force_exact_match);
|
||||
|
||||
protected:
|
||||
/* virtual */ void GetScriptName(ScriptInfo *info, char *name, const char *last);
|
||||
/* virtual */ const char *GetFileName() const { return PATHSEP "info.nut"; }
|
||||
/* virtual */ Subdirectory GetDirectory() const { return GAME_DIR; }
|
||||
/* virtual */ const char *GetScannerName() const { return "Game Scripts"; }
|
||||
/* 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, const char *last);
|
||||
/* 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 */
|
||||
402
src/game/game_text.cpp
Normal file
402
src/game/game_text.cpp
Normal file
@@ -0,0 +1,402 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* This file is part of OpenTTD.
|
||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @file game_text.cpp Implementation of handling translated strings. */
|
||||
|
||||
#include "../stdafx.h"
|
||||
#include "../strgen/strgen.h"
|
||||
#include "../debug.h"
|
||||
#include "../fileio_func.h"
|
||||
#include "../tar_type.h"
|
||||
#include "../script/squirrel_class.hpp"
|
||||
#include "../strings_func.h"
|
||||
#include "game_text.hpp"
|
||||
#include "game.hpp"
|
||||
#include "game_info.hpp"
|
||||
|
||||
#include "table/strings.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "../safeguards.h"
|
||||
|
||||
void CDECL strgen_warning(const char *s, ...)
|
||||
{
|
||||
char buf[1024];
|
||||
va_list va;
|
||||
va_start(va, s);
|
||||
vseprintf(buf, lastof(buf), s, va);
|
||||
va_end(va);
|
||||
DEBUG(script, 0, "%s:%d: warning: %s", _file, _cur_line, buf);
|
||||
_warnings++;
|
||||
}
|
||||
|
||||
void CDECL strgen_error(const char *s, ...)
|
||||
{
|
||||
char buf[1024];
|
||||
va_list va;
|
||||
va_start(va, s);
|
||||
vseprintf(buf, lastof(buf), s, va);
|
||||
va_end(va);
|
||||
DEBUG(script, 0, "%s:%d: error: %s", _file, _cur_line, buf);
|
||||
_errors++;
|
||||
}
|
||||
|
||||
void NORETURN CDECL strgen_fatal(const char *s, ...)
|
||||
{
|
||||
char buf[1024];
|
||||
va_list va;
|
||||
va_start(va, s);
|
||||
vseprintf(buf, lastof(buf), s, va);
|
||||
va_end(va);
|
||||
DEBUG(script, 0, "%s:%d: FATAL: %s", _file, _cur_line, buf);
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new container for language strings.
|
||||
* @param language The language name.
|
||||
* @param end If not NULL, terminate \a language at this position.
|
||||
*/
|
||||
LanguageStrings::LanguageStrings(const char *language, const char *end)
|
||||
{
|
||||
this->language = stredup(language, end != NULL ? end - 1 : NULL);
|
||||
}
|
||||
|
||||
/** Free everything. */
|
||||
LanguageStrings::~LanguageStrings()
|
||||
{
|
||||
free(this->language);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read all the raw language strings from the given file.
|
||||
* @param file The file to read from.
|
||||
* @return The raw strings, or NULL upon error.
|
||||
*/
|
||||
LanguageStrings *ReadRawLanguageStrings(const char *file)
|
||||
{
|
||||
LanguageStrings *ret = NULL;
|
||||
FILE *fh = NULL;
|
||||
try {
|
||||
size_t to_read;
|
||||
fh = FioFOpenFile(file, "rb", GAME_DIR, &to_read);
|
||||
if (fh == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *langname = strrchr(file, PATHSEPCHAR);
|
||||
if (langname == NULL) {
|
||||
langname = file;
|
||||
} else {
|
||||
langname++;
|
||||
}
|
||||
|
||||
/* Check for invalid empty filename */
|
||||
if (*langname == '.' || *langname == 0) {
|
||||
fclose(fh);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = new LanguageStrings(langname, strchr(langname, '.'));
|
||||
|
||||
char buffer[2048];
|
||||
while (to_read != 0 && fgets(buffer, sizeof(buffer), fh) != NULL) {
|
||||
size_t len = strlen(buffer);
|
||||
|
||||
/* Remove trailing spaces/newlines from the string. */
|
||||
size_t i = len;
|
||||
while (i > 0 && (buffer[i - 1] == '\r' || buffer[i - 1] == '\n' || buffer[i - 1] == ' ')) i--;
|
||||
buffer[i] = '\0';
|
||||
|
||||
*ret->lines.Append() = stredup(buffer, buffer + to_read - 1);
|
||||
|
||||
if (len > to_read) {
|
||||
to_read = 0;
|
||||
} else {
|
||||
to_read -= len;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fh);
|
||||
return ret;
|
||||
} catch (...) {
|
||||
if (fh != NULL) fclose(fh);
|
||||
delete ret;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** A reader that simply reads using fopen. */
|
||||
struct StringListReader : StringReader {
|
||||
const char * const *p; ///< The current location of the iteration.
|
||||
const char * const *end; ///< The end of the iteration.
|
||||
|
||||
/**
|
||||
* Create the reader.
|
||||
* @param data The data to fill during reading.
|
||||
* @param file The file we are reading.
|
||||
* @param master Are we reading the master file?
|
||||
* @param translation Are we reading a translation?
|
||||
*/
|
||||
StringListReader(StringData &data, const LanguageStrings *strings, bool master, bool translation) :
|
||||
StringReader(data, strings->language, master, translation), p(strings->lines.Begin()), end(strings->lines.End())
|
||||
{
|
||||
}
|
||||
|
||||
/* virtual */ char *ReadLine(char *buffer, const char *last)
|
||||
{
|
||||
if (this->p == this->end) return NULL;
|
||||
|
||||
strecpy(buffer, *this->p, last);
|
||||
this->p++;
|
||||
|
||||
return buffer;
|
||||
}
|
||||
};
|
||||
|
||||
/** Class for writing an encoded language. */
|
||||
struct TranslationWriter : LanguageWriter {
|
||||
StringList *strings; ///< The encoded strings.
|
||||
|
||||
/**
|
||||
* Writer for the encoded data.
|
||||
* @param strings The string table to add the strings to.
|
||||
*/
|
||||
TranslationWriter(StringList *strings) : strings(strings)
|
||||
{
|
||||
}
|
||||
|
||||
void WriteHeader(const LanguagePackHeader *header)
|
||||
{
|
||||
/* We don't use the header. */
|
||||
}
|
||||
|
||||
void Finalise()
|
||||
{
|
||||
/* Nothing to do. */
|
||||
}
|
||||
|
||||
void WriteLength(uint length)
|
||||
{
|
||||
/* We don't write the length. */
|
||||
}
|
||||
|
||||
void Write(const byte *buffer, size_t length)
|
||||
{
|
||||
char *dest = MallocT<char>(length + 1);
|
||||
memcpy(dest, buffer, length);
|
||||
dest[length] = '\0';
|
||||
*this->strings->Append() = dest;
|
||||
}
|
||||
};
|
||||
|
||||
/** Class for writing the string IDs. */
|
||||
struct StringNameWriter : HeaderWriter {
|
||||
StringList *strings; ///< The string names.
|
||||
|
||||
/**
|
||||
* Writer for the string names.
|
||||
* @param strings The string table to add the strings to.
|
||||
*/
|
||||
StringNameWriter(StringList *strings) : strings(strings)
|
||||
{
|
||||
}
|
||||
|
||||
void WriteStringID(const char *name, int stringid)
|
||||
{
|
||||
if (stringid == (int)this->strings->Length()) *this->strings->Append() = stredup(name);
|
||||
}
|
||||
|
||||
void Finalise(const StringData &data)
|
||||
{
|
||||
/* Nothing to do. */
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Scanner to find language files in a GameScript directory.
|
||||
*/
|
||||
class LanguageScanner : protected FileScanner {
|
||||
private:
|
||||
GameStrings *gs;
|
||||
char *exclude;
|
||||
|
||||
public:
|
||||
/** Initialise */
|
||||
LanguageScanner(GameStrings *gs, const char *exclude) : gs(gs), exclude(stredup(exclude)) {}
|
||||
~LanguageScanner() { free(exclude); }
|
||||
|
||||
/**
|
||||
* Scan.
|
||||
*/
|
||||
void Scan(const char *directory)
|
||||
{
|
||||
this->FileScanner::Scan(".txt", directory, false);
|
||||
}
|
||||
|
||||
/* virtual */ bool AddFile(const char *filename, size_t basepath_length, const char *tar_filename)
|
||||
{
|
||||
if (strcmp(filename, exclude) == 0) return true;
|
||||
|
||||
*gs->raw_strings.Append() = ReadRawLanguageStrings(filename);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Load all translations that we know of.
|
||||
* @return Container with all (compiled) translations.
|
||||
*/
|
||||
GameStrings *LoadTranslations()
|
||||
{
|
||||
const GameInfo *info = Game::GetInfo();
|
||||
char filename[512];
|
||||
strecpy(filename, info->GetMainScript(), lastof(filename));
|
||||
char *e = strrchr(filename, PATHSEPCHAR);
|
||||
if (e == NULL) return NULL;
|
||||
e++; // Make 'e' point after the PATHSEPCHAR
|
||||
|
||||
strecpy(e, "lang" PATHSEP "english.txt", lastof(filename));
|
||||
if (!FioCheckFileExists(filename, GAME_DIR)) return NULL;
|
||||
|
||||
GameStrings *gs = new GameStrings();
|
||||
try {
|
||||
*gs->raw_strings.Append() = ReadRawLanguageStrings(filename);
|
||||
|
||||
/* Scan for other language files */
|
||||
LanguageScanner scanner(gs, filename);
|
||||
strecpy(e, "lang" PATHSEP, lastof(filename));
|
||||
size_t len = strlen(filename);
|
||||
|
||||
const char *tar_filename = info->GetTarFile();
|
||||
TarList::iterator iter;
|
||||
if (tar_filename != NULL && (iter = _tar_list[GAME_DIR].find(tar_filename)) != _tar_list[GAME_DIR].end()) {
|
||||
/* The main script is in a tar file, so find all files that
|
||||
* are in the same tar and add them to the langfile scanner. */
|
||||
TarFileList::iterator tar;
|
||||
FOR_ALL_TARS(tar, GAME_DIR) {
|
||||
/* Not in the same tar. */
|
||||
if (tar->second.tar_filename != iter->first) continue;
|
||||
|
||||
/* Check the path and extension. */
|
||||
if (tar->first.size() <= len || tar->first.compare(0, len, filename) != 0) continue;
|
||||
if (tar->first.compare(tar->first.size() - 4, 4, ".txt") != 0) continue;
|
||||
|
||||
scanner.AddFile(tar->first.c_str(), 0, tar_filename);
|
||||
}
|
||||
} else {
|
||||
/* Scan filesystem */
|
||||
scanner.Scan(filename);
|
||||
}
|
||||
|
||||
gs->Compile();
|
||||
return gs;
|
||||
} catch (...) {
|
||||
delete gs;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/** Compile the language. */
|
||||
void GameStrings::Compile()
|
||||
{
|
||||
StringData data(1);
|
||||
StringListReader master_reader(data, this->raw_strings[0], true, false);
|
||||
master_reader.ParseFile();
|
||||
if (_errors != 0) throw std::exception();
|
||||
|
||||
this->version = data.Version();
|
||||
|
||||
StringNameWriter id_writer(&this->string_names);
|
||||
id_writer.WriteHeader(data);
|
||||
|
||||
for (LanguageStrings **p = this->raw_strings.Begin(); p != this->raw_strings.End(); p++) {
|
||||
data.FreeTranslation();
|
||||
StringListReader translation_reader(data, *p, false, strcmp((*p)->language, "english") != 0);
|
||||
translation_reader.ParseFile();
|
||||
if (_errors != 0) throw std::exception();
|
||||
|
||||
LanguageStrings *compiled = *this->compiled_strings.Append() = new LanguageStrings((*p)->language);
|
||||
TranslationWriter writer(&compiled->lines);
|
||||
writer.WriteLang(data);
|
||||
}
|
||||
}
|
||||
|
||||
/** The currently loaded game strings. */
|
||||
GameStrings *_current_data = NULL;
|
||||
|
||||
/**
|
||||
* Get the string pointer of a particular game string.
|
||||
* @param id The ID of the game string.
|
||||
* @return The encoded string.
|
||||
*/
|
||||
const char *GetGameStringPtr(uint id)
|
||||
{
|
||||
if (id >= _current_data->cur_language->lines.Length()) return GetStringPtr(STR_UNDEFINED);
|
||||
return _current_data->cur_language->lines[id];
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the current translation to the Squirrel engine.
|
||||
* @param engine The engine to update/
|
||||
*/
|
||||
void RegisterGameTranslation(Squirrel *engine)
|
||||
{
|
||||
delete _current_data;
|
||||
_current_data = LoadTranslations();
|
||||
if (_current_data == NULL) return;
|
||||
|
||||
HSQUIRRELVM vm = engine->GetVM();
|
||||
sq_pushroottable(vm);
|
||||
sq_pushstring(vm, "GSText", -1);
|
||||
if (SQ_FAILED(sq_get(vm, -2))) return;
|
||||
|
||||
int idx = 0;
|
||||
for (const char * const *p = _current_data->string_names.Begin(); p != _current_data->string_names.End(); p++, idx++) {
|
||||
sq_pushstring(vm, *p, -1);
|
||||
sq_pushinteger(vm, idx);
|
||||
sq_rawset(vm, -3);
|
||||
}
|
||||
|
||||
sq_pop(vm, 2);
|
||||
|
||||
ReconsiderGameScriptLanguage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reconsider the game script language, so we use the right one.
|
||||
*/
|
||||
void ReconsiderGameScriptLanguage()
|
||||
{
|
||||
if (_current_data == NULL) return;
|
||||
|
||||
char temp[MAX_PATH];
|
||||
strecpy(temp, _current_language->file, lastof(temp));
|
||||
|
||||
/* Remove the extension */
|
||||
char *l = strrchr(temp, '.');
|
||||
assert(l != NULL);
|
||||
*l = '\0';
|
||||
|
||||
/* Skip the path */
|
||||
char *language = strrchr(temp, PATHSEPCHAR);
|
||||
assert(language != NULL);
|
||||
language++;
|
||||
|
||||
for (LanguageStrings **p = _current_data->compiled_strings.Begin(); p != _current_data->compiled_strings.End(); p++) {
|
||||
if (strcmp((*p)->language, language) == 0) {
|
||||
_current_data->cur_language = *p;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_current_data->cur_language = _current_data->compiled_strings[0];
|
||||
}
|
||||
45
src/game/game_text.hpp
Normal file
45
src/game/game_text.hpp
Normal file
@@ -0,0 +1,45 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* This file is part of OpenTTD.
|
||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @file game_text.hpp Base functions regarding game texts. */
|
||||
|
||||
#ifndef GAME_TEXT_HPP
|
||||
#define GAME_TEXT_HPP
|
||||
|
||||
#include "../core/smallvec_type.hpp"
|
||||
|
||||
/** The tab we place our strings in. */
|
||||
static const uint GAME_TEXT_TAB = 18;
|
||||
|
||||
const char *GetGameStringPtr(uint id);
|
||||
void RegisterGameTranslation(class Squirrel *engine);
|
||||
void ReconsiderGameScriptLanguage();
|
||||
|
||||
/** Container for the raw (unencoded) language strings of a language. */
|
||||
struct LanguageStrings {
|
||||
const char *language; ///< Name of the language (base filename).
|
||||
StringList lines; ///< The lines of the file to pass into the parser/encoder.
|
||||
|
||||
LanguageStrings(const char *language, const char *end = NULL);
|
||||
~LanguageStrings();
|
||||
};
|
||||
|
||||
/** Container for all the game strings. */
|
||||
struct GameStrings {
|
||||
uint version; ///< The version of the language strings.
|
||||
LanguageStrings *cur_language; ///< The current (compiled) language.
|
||||
|
||||
AutoDeleteSmallVector<LanguageStrings *, 4> raw_strings; ///< The raw strings per language, first must be English/the master language!.
|
||||
AutoDeleteSmallVector<LanguageStrings *, 4> compiled_strings; ///< The compiled strings per language, first must be English/the master language!.
|
||||
StringList string_names; ///< The names of the compiled strings.
|
||||
|
||||
void Compile();
|
||||
};
|
||||
|
||||
#endif /* GAME_TEXT_HPP */
|
||||
Reference in New Issue
Block a user