diff --git a/projects/openttd_vs100.vcxproj b/projects/openttd_vs100.vcxproj
index 8bd20a2f00..716a1ae30f 100644
--- a/projects/openttd_vs100.vcxproj
+++ b/projects/openttd_vs100.vcxproj
@@ -941,6 +941,7 @@
+
@@ -1000,6 +1001,7 @@
+
diff --git a/projects/openttd_vs100.vcxproj.filters b/projects/openttd_vs100.vcxproj.filters
index e5cd8a177d..10c88fbf46 100644
--- a/projects/openttd_vs100.vcxproj.filters
+++ b/projects/openttd_vs100.vcxproj.filters
@@ -2052,6 +2052,9 @@
Script API
+
+ Script API
+
Script API
@@ -2229,6 +2232,9 @@
Script API Implementation
+
+ Script API Implementation
+
Script API Implementation
diff --git a/projects/openttd_vs80.vcproj b/projects/openttd_vs80.vcproj
index 0a24d1062a..0473d53ffe 100644
--- a/projects/openttd_vs80.vcproj
+++ b/projects/openttd_vs80.vcproj
@@ -3098,6 +3098,10 @@
RelativePath=".\..\src\script\api\script_company.hpp"
>
+
+
@@ -3338,6 +3342,10 @@
RelativePath=".\..\src\script\api\script_company.cpp"
>
+
+
diff --git a/projects/openttd_vs90.vcproj b/projects/openttd_vs90.vcproj
index e819d79449..b8673f3f93 100644
--- a/projects/openttd_vs90.vcproj
+++ b/projects/openttd_vs90.vcproj
@@ -3095,6 +3095,10 @@
RelativePath=".\..\src\script\api\script_company.hpp"
>
+
+
@@ -3335,6 +3339,10 @@
RelativePath=".\..\src\script\api\script_company.cpp"
>
+
+
diff --git a/source.list b/source.list
index bdbffc2071..e78475ac7c 100644
--- a/source.list
+++ b/source.list
@@ -719,6 +719,7 @@ script/api/script_bridgelist.hpp
script/api/script_cargo.hpp
script/api/script_cargolist.hpp
script/api/script_company.hpp
+script/api/script_companymode.hpp
script/api/script_controller.hpp
script/api/script_date.hpp
script/api/script_depotlist.hpp
@@ -780,6 +781,7 @@ script/api/script_bridgelist.cpp
script/api/script_cargo.cpp
script/api/script_cargolist.cpp
script/api/script_company.cpp
+script/api/script_companymode.cpp
script/api/script_controller.cpp
script/api/script_date.cpp
script/api/script_depotlist.cpp
diff --git a/src/ai/ai_core.cpp b/src/ai/ai_core.cpp
index de4034b6b3..3a337ab0b1 100644
--- a/src/ai/ai_core.cpp
+++ b/src/ai/ai_core.cpp
@@ -23,6 +23,7 @@
#include "ai_config.hpp"
#include "ai_info.hpp"
#include "ai.hpp"
+#include "../script/script_storage.hpp"
#include "../script/api/script_error.hpp"
/* static */ uint AI::frame_counter = 0;
diff --git a/src/ai/ai_instance.cpp b/src/ai/ai_instance.cpp
index b6aa20e605..42918b2beb 100644
--- a/src/ai/ai_instance.cpp
+++ b/src/ai/ai_instance.cpp
@@ -94,7 +94,7 @@ void AIInstance::Initialize(AIInfo *info)
/* Register the AIController (including the "import" command) */
SQAIController_Register(this->engine);
- ScriptInstance::Initialize(info->GetMainScript(), info->GetInstanceName());
+ ScriptInstance::Initialize(info->GetMainScript(), info->GetInstanceName(), _current_company);
}
void AIInstance::RegisterAPI()
diff --git a/src/game/game_core.cpp b/src/game/game_core.cpp
index 9fd579599b..ac24853da4 100644
--- a/src/game/game_core.cpp
+++ b/src/game/game_core.cpp
@@ -87,9 +87,13 @@
/* static */ void Game::Uninitialize(bool keepConfig)
{
+ Backup cur_company(_current_company, FILE_LINE);
+
delete Game::instance;
Game::instance = NULL;
+ cur_company.Restore();
+
if (keepConfig) {
Rescan();
} else {
diff --git a/src/game/game_instance.cpp b/src/game/game_instance.cpp
index daa1221585..81870603b0 100644
--- a/src/game/game_instance.cpp
+++ b/src/game/game_instance.cpp
@@ -33,6 +33,7 @@
#include "../script/api/game/game_cargo.hpp.sq"
#include "../script/api/game/game_cargolist.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"
@@ -87,7 +88,7 @@ void GameInstance::Initialize(GameInfo *info)
/* Register the GameController */
SQGSController_Register(this->engine);
- ScriptInstance::Initialize(info->GetMainScript(), info->GetInstanceName());
+ ScriptInstance::Initialize(info->GetMainScript(), info->GetInstanceName(), OWNER_DEITY);
}
void GameInstance::RegisterAPI()
@@ -110,6 +111,7 @@ void GameInstance::RegisterAPI()
SQGSCargoList_IndustryProducing_Register(this->engine);
SQGSCargoList_StationAccepting_Register(this->engine);
SQGSCompany_Register(this->engine);
+ SQGSCompanyMode_Register(this->engine);
SQGSDate_Register(this->engine);
SQGSDepotList_Register(this->engine);
SQGSEngine_Register(this->engine);
diff --git a/src/script/api/ai/ai_error.hpp.sq b/src/script/api/ai/ai_error.hpp.sq
index b0f48033a7..c588f7b403 100644
--- a/src/script/api/ai/ai_error.hpp.sq
+++ b/src/script/api/ai/ai_error.hpp.sq
@@ -39,6 +39,7 @@ void SQAIError_Register(Squirrel *engine)
SQAIError.DefSQConst(engine, ScriptError::ERR_UNKNOWN, "ERR_UNKNOWN");
SQAIError.DefSQConst(engine, ScriptError::ERR_PRECONDITION_FAILED, "ERR_PRECONDITION_FAILED");
SQAIError.DefSQConst(engine, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG, "ERR_PRECONDITION_STRING_TOO_LONG");
+ SQAIError.DefSQConst(engine, ScriptError::ERR_PRECONDITION_INVALID_COMPANY, "ERR_PRECONDITION_INVALID_COMPANY");
SQAIError.DefSQConst(engine, ScriptError::ERR_NEWGRF_SUPPLIED_ERROR, "ERR_NEWGRF_SUPPLIED_ERROR");
SQAIError.DefSQConst(engine, ScriptError::ERR_GENERAL_BASE, "ERR_GENERAL_BASE");
SQAIError.DefSQConst(engine, ScriptError::ERR_NOT_ENOUGH_CASH, "ERR_NOT_ENOUGH_CASH");
@@ -93,6 +94,7 @@ void SQAIError_Register(Squirrel *engine)
ScriptError::RegisterErrorMapString(ScriptError::ERR_UNKNOWN, "ERR_UNKNOWN");
ScriptError::RegisterErrorMapString(ScriptError::ERR_PRECONDITION_FAILED, "ERR_PRECONDITION_FAILED");
ScriptError::RegisterErrorMapString(ScriptError::ERR_PRECONDITION_STRING_TOO_LONG, "ERR_PRECONDITION_STRING_TOO_LONG");
+ ScriptError::RegisterErrorMapString(ScriptError::ERR_PRECONDITION_INVALID_COMPANY, "ERR_PRECONDITION_INVALID_COMPANY");
ScriptError::RegisterErrorMapString(ScriptError::ERR_NEWGRF_SUPPLIED_ERROR, "ERR_NEWGRF_SUPPLIED_ERROR");
ScriptError::RegisterErrorMapString(ScriptError::ERR_NOT_ENOUGH_CASH, "ERR_NOT_ENOUGH_CASH");
ScriptError::RegisterErrorMapString(ScriptError::ERR_LOCAL_AUTHORITY_REFUSES, "ERR_LOCAL_AUTHORITY_REFUSES");
diff --git a/src/script/api/game/game_companymode.hpp.sq b/src/script/api/game/game_companymode.hpp.sq
new file mode 100644
index 0000000000..038e234fa1
--- /dev/null
+++ b/src/script/api/game/game_companymode.hpp.sq
@@ -0,0 +1,25 @@
+/* $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 .
+ */
+
+/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
+
+#include "../script_companymode.hpp"
+#include "../template/template_companymode.hpp.sq"
+
+
+template <> const char *GetClassName() { return "GSCompanyMode"; }
+
+void SQGSCompanyMode_Register(Squirrel *engine)
+{
+ DefSQClass SQGSCompanyMode("GSCompanyMode");
+ SQGSCompanyMode.PreRegister(engine);
+ SQGSCompanyMode.AddConstructor(engine, "xi");
+
+ SQGSCompanyMode.PostRegister(engine);
+}
diff --git a/src/script/api/game/game_error.hpp.sq b/src/script/api/game/game_error.hpp.sq
index ff3f940f35..b47f5d4a93 100644
--- a/src/script/api/game/game_error.hpp.sq
+++ b/src/script/api/game/game_error.hpp.sq
@@ -39,6 +39,7 @@ void SQGSError_Register(Squirrel *engine)
SQGSError.DefSQConst(engine, ScriptError::ERR_UNKNOWN, "ERR_UNKNOWN");
SQGSError.DefSQConst(engine, ScriptError::ERR_PRECONDITION_FAILED, "ERR_PRECONDITION_FAILED");
SQGSError.DefSQConst(engine, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG, "ERR_PRECONDITION_STRING_TOO_LONG");
+ SQGSError.DefSQConst(engine, ScriptError::ERR_PRECONDITION_INVALID_COMPANY, "ERR_PRECONDITION_INVALID_COMPANY");
SQGSError.DefSQConst(engine, ScriptError::ERR_NEWGRF_SUPPLIED_ERROR, "ERR_NEWGRF_SUPPLIED_ERROR");
SQGSError.DefSQConst(engine, ScriptError::ERR_GENERAL_BASE, "ERR_GENERAL_BASE");
SQGSError.DefSQConst(engine, ScriptError::ERR_NOT_ENOUGH_CASH, "ERR_NOT_ENOUGH_CASH");
@@ -93,6 +94,7 @@ void SQGSError_Register(Squirrel *engine)
ScriptError::RegisterErrorMapString(ScriptError::ERR_UNKNOWN, "ERR_UNKNOWN");
ScriptError::RegisterErrorMapString(ScriptError::ERR_PRECONDITION_FAILED, "ERR_PRECONDITION_FAILED");
ScriptError::RegisterErrorMapString(ScriptError::ERR_PRECONDITION_STRING_TOO_LONG, "ERR_PRECONDITION_STRING_TOO_LONG");
+ ScriptError::RegisterErrorMapString(ScriptError::ERR_PRECONDITION_INVALID_COMPANY, "ERR_PRECONDITION_INVALID_COMPANY");
ScriptError::RegisterErrorMapString(ScriptError::ERR_NEWGRF_SUPPLIED_ERROR, "ERR_NEWGRF_SUPPLIED_ERROR");
ScriptError::RegisterErrorMapString(ScriptError::ERR_NOT_ENOUGH_CASH, "ERR_NOT_ENOUGH_CASH");
ScriptError::RegisterErrorMapString(ScriptError::ERR_LOCAL_AUTHORITY_REFUSES, "ERR_LOCAL_AUTHORITY_REFUSES");
diff --git a/src/script/api/script_airport.cpp b/src/script/api/script_airport.cpp
index e08e048035..129ba62ea3 100644
--- a/src/script/api/script_airport.cpp
+++ b/src/script/api/script_airport.cpp
@@ -13,7 +13,6 @@
#include "script_airport.hpp"
#include "script_station.hpp"
#include "../../station_base.h"
-#include "../../company_func.h"
#include "../../town.h"
/* static */ bool ScriptAirport::IsValidAirportType(AirportType type)
@@ -94,7 +93,7 @@
if (!::IsTileType(tile, MP_STATION)) return -1;
const Station *st = ::Station::GetByTile(tile);
- if (st->owner != _current_company && _current_company != OWNER_DEITY) return -1;
+ if (st->owner != ScriptObject::GetCompany() && ScriptObject::GetCompany() != OWNER_DEITY) return -1;
if ((st->facilities & FACIL_AIRPORT) == 0) return -1;
return st->airport.GetNumHangars();
@@ -107,7 +106,7 @@
if (GetNumHangars(tile) < 1) return INVALID_TILE;
const Station *st = ::Station::GetByTile(tile);
- if (st->owner != _current_company && _current_company != OWNER_DEITY) return INVALID_TILE;
+ if (st->owner != ScriptObject::GetCompany() && ScriptObject::GetCompany() != OWNER_DEITY) return INVALID_TILE;
if ((st->facilities & FACIL_AIRPORT) == 0) return INVALID_TILE;
return st->airport.GetHangarTile(0);
diff --git a/src/script/api/script_basestation.cpp b/src/script/api/script_basestation.cpp
index 0ef2862423..5bd87ff78f 100644
--- a/src/script/api/script_basestation.cpp
+++ b/src/script/api/script_basestation.cpp
@@ -14,13 +14,12 @@
#include "../../station_base.h"
#include "../../string_func.h"
#include "../../strings_func.h"
-#include "../../company_func.h"
#include "table/strings.h"
/* static */ bool ScriptBaseStation::IsValidBaseStation(StationID station_id)
{
const BaseStation *st = ::BaseStation::GetIfValid(station_id);
- return st != NULL && (st->owner == _current_company || _current_company == OWNER_DEITY || st->owner == OWNER_NONE);
+ return st != NULL && (st->owner == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY || st->owner == OWNER_NONE);
}
/* static */ char *ScriptBaseStation::GetName(StationID station_id)
diff --git a/src/script/api/script_bridge.cpp b/src/script/api/script_bridge.cpp
index c2cbfcde0a..a268945238 100644
--- a/src/script/api/script_bridge.cpp
+++ b/src/script/api/script_bridge.cpp
@@ -17,7 +17,6 @@
#include "../../strings_func.h"
#include "../../economy_func.h"
#include "../../date_func.h"
-#include "../../company_func.h"
/* static */ bool ScriptBridge::IsValidBridge(BridgeID bridge_id)
{
@@ -75,7 +74,7 @@ static void _DoCommandReturnBuildBridge1(class ScriptInstance *instance)
EnforcePrecondition(false, TileX(start) == TileX(end) || TileY(start) == TileY(end));
EnforcePrecondition(false, vehicle_type == ScriptVehicle::VT_ROAD || vehicle_type == ScriptVehicle::VT_RAIL || vehicle_type == ScriptVehicle::VT_WATER);
EnforcePrecondition(false, vehicle_type != ScriptVehicle::VT_RAIL || ScriptRail::IsRailTypeAvailable(ScriptRail::GetCurrentRailType()));
- EnforcePrecondition(false, _current_company != OWNER_DEITY || vehicle_type == ScriptVehicle::VT_ROAD);
+ EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY || vehicle_type == ScriptVehicle::VT_ROAD);
uint type = 0;
switch (vehicle_type) {
diff --git a/src/script/api/script_company.cpp b/src/script/api/script_company.cpp
index d241d7d306..6d11c17acf 100644
--- a/src/script/api/script_company.cpp
+++ b/src/script/api/script_company.cpp
@@ -26,7 +26,10 @@
/* static */ ScriptCompany::CompanyID ScriptCompany::ResolveCompanyID(ScriptCompany::CompanyID company)
{
- if (company == COMPANY_SELF) return (CompanyID)((byte)_current_company);
+ if (company == COMPANY_SELF) {
+ if (!::Company::IsValidID((::CompanyID)_current_company)) return COMPANY_INVALID;
+ return (CompanyID)((byte)_current_company);
+ }
return ::Company::IsValidID((::CompanyID)company) ? company : COMPANY_INVALID;
}
@@ -170,7 +173,10 @@
/* static */ Money ScriptCompany::GetLoanAmount()
{
- return ::Company::Get(_current_company)->current_loan;
+ ScriptCompany::CompanyID company = ResolveCompanyID(COMPANY_SELF);
+ if (company == COMPANY_INVALID) return -1;
+
+ return ::Company::Get(company)->current_loan;
}
/* static */ Money ScriptCompany::GetMaxLoanAmount()
diff --git a/src/script/api/script_companymode.cpp b/src/script/api/script_companymode.cpp
new file mode 100644
index 0000000000..d260053e1e
--- /dev/null
+++ b/src/script/api/script_companymode.cpp
@@ -0,0 +1,30 @@
+/* $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 .
+ */
+
+/** @file script_companymode.cpp Implementation of ScriptCompanyMode. */
+
+#include "../../stdafx.h"
+#include "script_companymode.hpp"
+#include "../../company_base.h"
+#include "../../company_func.h"
+#include "../script_instance.hpp"
+#include "../script_fatalerror.hpp"
+
+ScriptCompanyMode::ScriptCompanyMode(int company)
+{
+ if (company < OWNER_BEGIN || company >= MAX_COMPANIES) company = INVALID_COMPANY;
+
+ this->last_company = ScriptObject::GetCompany();
+ ScriptObject::SetCompany((CompanyID)company);
+}
+
+ScriptCompanyMode::~ScriptCompanyMode()
+{
+ ScriptObject::SetCompany(this->last_company);
+}
diff --git a/src/script/api/script_companymode.hpp b/src/script/api/script_companymode.hpp
new file mode 100644
index 0000000000..2615494d80
--- /dev/null
+++ b/src/script/api/script_companymode.hpp
@@ -0,0 +1,54 @@
+/* $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 .
+ */
+
+/** @file script_companymode.hpp Switch the company. */
+
+#ifndef SCRIPT_COMPANYMODE_HPP
+#define SCRIPT_COMPANYMODE_HPP
+
+#include "script_object.hpp"
+
+/**
+ * Class to switch the current company.
+ * If you create an instance of this class, the company will be switched.
+ * The original company is stored and recovered from when ever the
+ * instance is destroyed.
+ * All actions performed within the scope of this mode, will be executed
+ * on behalf of the company you switched to. This includes any costs
+ * attached to the action performed. If the company does not have the
+ * funds the action will be aborted. In other words, this is like the
+ * real player is executing the commands.
+ * If the company is not valid during an action, the error
+ * ERR_PRECONDITION_INVALID_COMPANY will be returned. You can switch to
+ * invalid companies, or a company can become invalid (bankrupt) while you
+ * are switched to it.
+ * @api game
+ */
+class ScriptCompanyMode : public ScriptObject {
+private:
+ CompanyID last_company; ///< The previous company we were in.
+
+public:
+ /**
+ * Creating instance of this class switches the company used for queries
+ * and commands.
+ * @param company The new company to switch to.
+ * @note When the instance is destroyed, he restores the company that was
+ * current when the instance was created!
+ */
+ ScriptCompanyMode(int company);
+
+ /**
+ * Destroying this instance reset the company to that what it was
+ * in when the instance was created.
+ */
+ ~ScriptCompanyMode();
+};
+
+#endif /* SCRIPT_COMPANYMODE_HPP */
diff --git a/src/script/api/script_controller.cpp b/src/script/api/script_controller.cpp
index 06b994ad1b..0eabdb7311 100644
--- a/src/script/api/script_controller.cpp
+++ b/src/script/api/script_controller.cpp
@@ -46,10 +46,11 @@
ScriptLog::Log(error_msg ? ScriptLog::LOG_SQ_ERROR : ScriptLog::LOG_SQ_INFO, message);
}
-ScriptController::ScriptController() :
+ScriptController::ScriptController(CompanyID company) :
ticks(0),
loaded_library_count(0)
{
+ ScriptObject::SetCompany(company);
}
ScriptController::~ScriptController()
diff --git a/src/script/api/script_controller.hpp b/src/script/api/script_controller.hpp
index 03d8604ece..9ab73ae0fc 100644
--- a/src/script/api/script_controller.hpp
+++ b/src/script/api/script_controller.hpp
@@ -12,6 +12,7 @@
#ifndef SCRIPT_CONTROLLER_HPP
#define SCRIPT_CONTROLLER_HPP
+#include "../../company_type.h"
#include "../../core/string_compare_type.hpp"
#include