changeset 18784:c6637e50e2f9 draft

(svn r23632) -Add: GSCompanyMode, to change company in GameScripts
author truebrain <truebrain@openttd.org>
date Mon, 19 Dec 2011 21:05:25 +0000
parents d51770d2b734
children 364318792aae
files projects/openttd_vs100.vcxproj projects/openttd_vs100.vcxproj.filters projects/openttd_vs80.vcproj projects/openttd_vs90.vcproj source.list src/ai/ai_core.cpp src/ai/ai_instance.cpp src/game/game_core.cpp src/game/game_instance.cpp src/script/api/ai/ai_error.hpp.sq src/script/api/game/game_companymode.hpp.sq src/script/api/game/game_error.hpp.sq src/script/api/script_airport.cpp src/script/api/script_basestation.cpp src/script/api/script_bridge.cpp src/script/api/script_company.cpp src/script/api/script_companymode.cpp src/script/api/script_companymode.hpp src/script/api/script_controller.cpp src/script/api/script_controller.hpp src/script/api/script_depotlist.cpp src/script/api/script_engine.cpp src/script/api/script_enginelist.cpp src/script/api/script_error.hpp src/script/api/script_group.cpp src/script/api/script_grouplist.cpp src/script/api/script_log.cpp src/script/api/script_object.cpp src/script/api/script_object.hpp src/script/api/script_rail.cpp src/script/api/script_railtypelist.cpp src/script/api/script_road.cpp src/script/api/script_sign.cpp src/script/api/script_station.cpp src/script/api/script_stationlist.cpp src/script/api/script_tile.cpp src/script/api/script_town.cpp src/script/api/script_tunnel.cpp src/script/api/script_vehicle.cpp src/script/api/script_vehiclelist.cpp src/script/api/script_waypoint.cpp src/script/api/script_waypointlist.cpp src/script/api/template/template_companymode.hpp.sq src/script/script_instance.cpp src/script/script_instance.hpp src/script/script_storage.hpp
diffstat 46 files changed, 273 insertions(+), 59 deletions(-) [+]
line wrap: on
line diff
--- a/projects/openttd_vs100.vcxproj
+++ b/projects/openttd_vs100.vcxproj
@@ -941,6 +941,7 @@
     <ClInclude Include="..\src\script\api\script_cargo.hpp" />
     <ClInclude Include="..\src\script\api\script_cargolist.hpp" />
     <ClInclude Include="..\src\script\api\script_company.hpp" />
+    <ClInclude Include="..\src\script\api\script_companymode.hpp" />
     <ClInclude Include="..\src\script\api\script_controller.hpp" />
     <ClInclude Include="..\src\script\api\script_date.hpp" />
     <ClInclude Include="..\src\script\api\script_depotlist.hpp" />
@@ -1000,6 +1001,7 @@
     <ClCompile Include="..\src\script\api\script_cargo.cpp" />
     <ClCompile Include="..\src\script\api\script_cargolist.cpp" />
     <ClCompile Include="..\src\script\api\script_company.cpp" />
+    <ClCompile Include="..\src\script\api\script_companymode.cpp" />
     <ClCompile Include="..\src\script\api\script_controller.cpp" />
     <ClCompile Include="..\src\script\api\script_date.cpp" />
     <ClCompile Include="..\src\script\api\script_depotlist.cpp" />
--- a/projects/openttd_vs100.vcxproj.filters
+++ b/projects/openttd_vs100.vcxproj.filters
@@ -2052,6 +2052,9 @@
     <ClInclude Include="..\src\script\api\script_company.hpp">
       <Filter>Script API</Filter>
     </ClInclude>
+    <ClInclude Include="..\src\script\api\script_companymode.hpp">
+      <Filter>Script API</Filter>
+    </ClInclude>
     <ClInclude Include="..\src\script\api\script_controller.hpp">
       <Filter>Script API</Filter>
     </ClInclude>
@@ -2229,6 +2232,9 @@
     <ClCompile Include="..\src\script\api\script_company.cpp">
       <Filter>Script API Implementation</Filter>
     </ClCompile>
+    <ClCompile Include="..\src\script\api\script_companymode.cpp">
+      <Filter>Script API Implementation</Filter>
+    </ClCompile>
     <ClCompile Include="..\src\script\api\script_controller.cpp">
       <Filter>Script API Implementation</Filter>
     </ClCompile>
--- a/projects/openttd_vs80.vcproj
+++ b/projects/openttd_vs80.vcproj
@@ -3099,6 +3099,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\script\api\script_companymode.hpp"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\script\api\script_controller.hpp"
 				>
 			</File>
@@ -3339,6 +3343,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\script\api\script_companymode.cpp"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\script\api\script_controller.cpp"
 				>
 			</File>
--- a/projects/openttd_vs90.vcproj
+++ b/projects/openttd_vs90.vcproj
@@ -3096,6 +3096,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\script\api\script_companymode.hpp"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\script\api\script_controller.hpp"
 				>
 			</File>
@@ -3336,6 +3340,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\script\api\script_companymode.cpp"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\script\api\script_controller.cpp"
 				>
 			</File>
--- a/source.list
+++ b/source.list
@@ -719,6 +719,7 @@
 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_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
--- 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;
--- a/src/ai/ai_instance.cpp
+++ b/src/ai/ai_instance.cpp
@@ -94,7 +94,7 @@
 	/* 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()
--- a/src/game/game_core.cpp
+++ b/src/game/game_core.cpp
@@ -87,9 +87,13 @@
 
 /* static */ void Game::Uninitialize(bool keepConfig)
 {
+	Backup<CompanyByte> cur_company(_current_company, FILE_LINE);
+
 	delete Game::instance;
 	Game::instance = NULL;
 
+	cur_company.Restore();
+
 	if (keepConfig) {
 		Rescan();
 	} else {
--- 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 @@
 	/* 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 @@
 	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);
--- a/src/script/api/ai/ai_error.hpp.sq
+++ b/src/script/api/ai/ai_error.hpp.sq
@@ -39,6 +39,7 @@
 	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 @@
 	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");
new file mode 100644
--- /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 <http://www.gnu.org/licenses/>.
+ */
+
+/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
+
+#include "../script_companymode.hpp"
+#include "../template/template_companymode.hpp.sq"
+
+
+template <> const char *GetClassName<ScriptCompanyMode, ST_GS>() { return "GSCompanyMode"; }
+
+void SQGSCompanyMode_Register(Squirrel *engine)
+{
+	DefSQClass<ScriptCompanyMode, ST_GS> SQGSCompanyMode("GSCompanyMode");
+	SQGSCompanyMode.PreRegister(engine);
+	SQGSCompanyMode.AddConstructor<void (ScriptCompanyMode::*)(int company), 2>(engine, "xi");
+
+	SQGSCompanyMode.PostRegister(engine);
+}
--- a/src/script/api/game/game_error.hpp.sq
+++ b/src/script/api/game/game_error.hpp.sq
@@ -39,6 +39,7 @@
 	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 @@
 	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");
--- 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);
--- 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)
--- 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 @@
 	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) {
--- 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()
new file mode 100644
--- /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 <http://www.gnu.org/licenses/>.
+ */
+
+/** @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);
+}
new file mode 100644
--- /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 <http://www.gnu.org/licenses/>.
+ */
+
+/** @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 */
--- 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()
--- 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 <map>
 
@@ -28,8 +29,9 @@
 public:
 	/**
 	 * Initializer of the ScriptController.
+	 * @param company The company this Script is normally serving.
 	 */
-	ScriptController();
+	ScriptController(CompanyID company);
 
 	/**
 	 * Destructor of the ScriptController.
--- a/src/script/api/script_depotlist.cpp
+++ b/src/script/api/script_depotlist.cpp
@@ -11,7 +11,6 @@
 
 #include "../../stdafx.h"
 #include "script_depotlist.hpp"
-#include "../../company_func.h"
 #include "../../depot_base.h"
 #include "../../station_base.h"
 
@@ -29,7 +28,7 @@
 			/* Hangars are not seen as real depots by the depot code. */
 			const Station *st;
 			FOR_ALL_STATIONS(st) {
-				if (st->owner == ::_current_company || ::_current_company == OWNER_DEITY) {
+				if (st->owner == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY) {
 					for (uint i = 0; i < st->airport.GetNumHangars(); i++) {
 						this->AddItem(st->airport.GetHangarTile(i));
 					}
@@ -42,6 +41,6 @@
 	/* Handle 'standard' depots. */
 	const Depot *depot;
 	FOR_ALL_DEPOTS(depot) {
-		if ((::GetTileOwner(depot->xy) == ::_current_company || ::_current_company == OWNER_DEITY) && ::IsTileType(depot->xy, tile_type)) this->AddItem(depot->xy);
+		if ((::GetTileOwner(depot->xy) == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY) && ::IsTileType(depot->xy, tile_type)) this->AddItem(depot->xy);
 	}
 }
--- a/src/script/api/script_engine.cpp
+++ b/src/script/api/script_engine.cpp
@@ -24,13 +24,13 @@
 /* static */ bool ScriptEngine::IsValidEngine(EngineID engine_id)
 {
 	const Engine *e = ::Engine::GetIfValid(engine_id);
-	return e != NULL && (::IsEngineBuildable(engine_id, e->type, _current_company) || (_current_company != OWNER_DEITY && ::Company::Get(_current_company)->group_all[e->type].num_engines[engine_id] > 0));
+	return e != NULL && (::IsEngineBuildable(engine_id, e->type, ScriptObject::GetCompany()) || (ScriptObject::GetCompany() != OWNER_DEITY && ::Company::Get(ScriptObject::GetCompany())->group_all[e->type].num_engines[engine_id] > 0));
 }
 
 /* static */ bool ScriptEngine::IsBuildable(EngineID engine_id)
 {
 	const Engine *e = ::Engine::GetIfValid(engine_id);
-	return e != NULL && ::IsEngineBuildable(engine_id, e->type, _current_company);
+	return e != NULL && ::IsEngineBuildable(engine_id, e->type, ScriptObject::GetCompany());
 }
 
 /* static */ char *ScriptEngine::GetName(EngineID engine_id)
--- a/src/script/api/script_enginelist.cpp
+++ b/src/script/api/script_enginelist.cpp
@@ -11,7 +11,6 @@
 
 #include "../../stdafx.h"
 #include "script_enginelist.hpp"
-#include "../../company_func.h"
 #include "../../engine_base.h"
 #include "../../core/bitmath_func.hpp"
 
@@ -19,6 +18,6 @@
 {
 	Engine *e;
 	FOR_ALL_ENGINES_OF_TYPE(e, (::VehicleType)vehicle_type) {
-		if (_current_company == OWNER_DEITY || HasBit(e->company_avail, _current_company)) this->AddItem(e->index);
+		if (ScriptObject::GetCompany() == OWNER_DEITY || HasBit(e->company_avail, ScriptObject::GetCompany())) this->AddItem(e->index);
 	}
 }
--- a/src/script/api/script_error.hpp
+++ b/src/script/api/script_error.hpp
@@ -81,6 +81,8 @@
 		ERR_PRECONDITION_FAILED,                      // []
 		/** A string supplied was too long */
 		ERR_PRECONDITION_STRING_TOO_LONG,             // []
+		/** The company you use is invalid */
+		ERR_PRECONDITION_INVALID_COMPANY,             // []
 		/** An error returned by a NewGRF. No possibility to get the exact error in an AI readable format */
 		ERR_NEWGRF_SUPPLIED_ERROR,                    // []
 
--- a/src/script/api/script_group.cpp
+++ b/src/script/api/script_group.cpp
@@ -24,7 +24,7 @@
 /* static */ bool ScriptGroup::IsValidGroup(GroupID group_id)
 {
 	const Group *g = ::Group::GetIfValid(group_id);
-	return g != NULL && g->owner == _current_company;
+	return g != NULL && g->owner == ScriptObject::GetCompany();
 }
 
 /* static */ ScriptGroup::GroupID ScriptGroup::CreateGroup(ScriptVehicle::VehicleType vehicle_type)
@@ -88,7 +88,7 @@
 {
 	if (!IsValidGroup(group_id) && group_id != GROUP_DEFAULT && group_id != GROUP_ALL) return -1;
 
-	return GetGroupNumEngines(_current_company, group_id, engine_id);
+	return GetGroupNumEngines(ScriptObject::GetCompany(), group_id, engine_id);
 }
 
 /* static */ bool ScriptGroup::MoveVehicle(GroupID group_id, VehicleID vehicle_id)
@@ -108,7 +108,7 @@
 
 /* static */ bool ScriptGroup::HasWagonRemoval()
 {
-	return ::Company::Get(_current_company)->settings.renew_keep_length;
+	return ::Company::Get(ScriptObject::GetCompany())->settings.renew_keep_length;
 }
 
 /* static */ bool ScriptGroup::SetAutoReplace(GroupID group_id, EngineID engine_id_old, EngineID engine_id_new)
@@ -123,7 +123,7 @@
 {
 	if (!IsValidGroup(group_id) && group_id != GROUP_DEFAULT && group_id != GROUP_ALL) return ::INVALID_ENGINE;
 
-	return ::EngineReplacementForCompany(Company::Get(_current_company), engine_id, group_id);
+	return ::EngineReplacementForCompany(Company::Get(ScriptObject::GetCompany()), engine_id, group_id);
 }
 
 /* static */ bool ScriptGroup::StopAutoReplace(GroupID group_id, EngineID engine_id)
--- a/src/script/api/script_grouplist.cpp
+++ b/src/script/api/script_grouplist.cpp
@@ -18,6 +18,6 @@
 {
 	Group *g;
 	FOR_ALL_GROUPS(g) {
-		if (g->owner == _current_company) this->AddItem(g->index);
+		if (g->owner == ScriptObject::GetCompany()) this->AddItem(g->index);
 	}
 }
--- a/src/script/api/script_log.cpp
+++ b/src/script/api/script_log.cpp
@@ -12,7 +12,6 @@
 #include "../../stdafx.h"
 #include "script_log.hpp"
 #include "../../core/alloc_func.hpp"
-#include "../../company_func.h"
 #include "../../debug.h"
 #include "../../window_func.h"
 
@@ -74,8 +73,8 @@
 	}
 
 	/* Also still print to debug window */
-	DEBUG(script, level, "[%d] [%c] %s", (uint)_current_company, logc, log->lines[log->pos]);
-	InvalidateWindowData(WC_AI_DEBUG, 0, _current_company);
+	DEBUG(script, level, "[%d] [%c] %s", (uint)ScriptObject::GetRootCompany(), logc, log->lines[log->pos]);
+	InvalidateWindowData(WC_AI_DEBUG, 0, ScriptObject::GetRootCompany());
 }
 
 /* static */ void ScriptLog::FreeLogPointer()
--- a/src/script/api/script_object.cpp
+++ b/src/script/api/script_object.cpp
@@ -13,6 +13,7 @@
 #include "../../script/squirrel.hpp"
 #include "../../command_func.h"
 #include "../../company_func.h"
+#include "../../company_base.h"
 #include "../../network/network.h"
 #include "../../tunnelbridge.h"
 #include "../../genworld.h"
@@ -201,6 +202,24 @@
 	return GetStorage()->allow_do_command;
 }
 
+/* static */ void ScriptObject::SetCompany(CompanyID company)
+{
+	if (GetStorage()->root_company == INVALID_OWNER) GetStorage()->root_company = company;
+	GetStorage()->company = company;
+
+	_current_company = company;
+}
+
+/* static */ CompanyID ScriptObject::GetCompany()
+{
+	return GetStorage()->company;
+}
+
+/* static */ CompanyID ScriptObject::GetRootCompany()
+{
+	return GetStorage()->root_company;
+}
+
 /* static */ bool ScriptObject::CanSuspend()
 {
 	Squirrel *squirrel = ScriptObject::GetActiveInstance()->engine;
@@ -234,6 +253,11 @@
 		throw Script_FatalError("You are not allowed to execute any DoCommand (even indirect) in your constructor, Save(), Load(), and any valuator.");
 	}
 
+	if (ScriptObject::GetCompany() != OWNER_DEITY && !::Company::IsValidID(ScriptObject::GetCompany())) {
+		ScriptObject::SetLastError(ScriptError::ERR_PRECONDITION_INVALID_COMPANY);
+		return false;
+	}
+
 	/* Set the default callback to return a true/false result of the DoCommand */
 	if (callback == NULL) callback = &ScriptInstance::DoCommandReturn;
 
--- a/src/script/api/script_object.hpp
+++ b/src/script/api/script_object.hpp
@@ -181,6 +181,27 @@
 	static bool GetAllowDoCommand();
 
 	/**
+	 * Set the current company to execute commands for or request
+	 *  information about.
+	 * @param company The new company.
+	 */
+	static void SetCompany(CompanyID company);
+
+	/**
+	 * Get the current company we are executing commands for or
+	 *  requesting information about.
+	 * @return The current company.
+	 */
+	static CompanyID GetCompany();
+
+	/**
+	 * Get the root company, the company that the script really
+	 *  runs under / for.
+	 * @return The root company.
+	 */
+	static CompanyID GetRootCompany();
+
+	/**
 	 * Set the cost of the last command.
 	 */
 	static void SetLastCost(Money last_cost);
--- a/src/script/api/script_rail.cpp
+++ b/src/script/api/script_rail.cpp
@@ -17,7 +17,6 @@
 #include "script_cargo.hpp"
 #include "../../debug.h"
 #include "../../station_base.h"
-#include "../../company_func.h"
 #include "../../newgrf.h"
 #include "../../newgrf_generic.h"
 #include "../../newgrf_station.h"
@@ -74,7 +73,7 @@
 {
 	if ((::RailType)rail_type < RAILTYPE_BEGIN || (::RailType)rail_type >= RAILTYPE_END) return false;
 
-	return _current_company == OWNER_DEITY || ::HasRailtypeAvail(_current_company, (::RailType)rail_type);
+	return ScriptObject::GetCompany() == OWNER_DEITY || ::HasRailtypeAvail(ScriptObject::GetCompany(), (::RailType)rail_type);
 }
 
 /* static */ ScriptRail::RailType ScriptRail::GetCurrentRailType()
--- a/src/script/api/script_railtypelist.cpp
+++ b/src/script/api/script_railtypelist.cpp
@@ -12,11 +12,10 @@
 #include "../../stdafx.h"
 #include "script_railtypelist.hpp"
 #include "../../rail.h"
-#include "../../company_func.h"
 
 ScriptRailTypeList::ScriptRailTypeList()
 {
 	for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) {
-		if (_current_company == OWNER_DEITY || ::HasRailtypeAvail(_current_company, rt)) this->AddItem(rt);
+		if (ScriptObject::GetCompany() == OWNER_DEITY || ::HasRailtypeAvail(ScriptObject::GetCompany(), rt)) this->AddItem(rt);
 	}
 }
--- a/src/script/api/script_road.cpp
+++ b/src/script/api/script_road.cpp
@@ -14,7 +14,6 @@
 #include "script_station.hpp"
 #include "script_cargo.hpp"
 #include "../../station_base.h"
-#include "../../company_func.h"
 #include "../../script/squirrel_helper_type.hpp"
 
 /* static */ ScriptRoad::RoadVehicleType ScriptRoad::GetRoadVehicleTypeForCargo(CargoID cargo_type)
@@ -54,7 +53,7 @@
 
 /* static */ bool ScriptRoad::IsRoadTypeAvailable(RoadType road_type)
 {
-	return ::HasRoadTypesAvail(_current_company, ::RoadTypeToRoadTypes((::RoadType)road_type));
+	return ::HasRoadTypesAvail(ScriptObject::GetCompany(), ::RoadTypeToRoadTypes((::RoadType)road_type));
 }
 
 /* static */ ScriptRoad::RoadType ScriptRoad::GetCurrentRoadType()
--- a/src/script/api/script_sign.cpp
+++ b/src/script/api/script_sign.cpp
@@ -19,12 +19,11 @@
 #include "../../string_func.h"
 #include "../../strings_func.h"
 #include "../../tile_map.h"
-#include "../../company_func.h"
 
 /* static */ bool ScriptSign::IsValidSign(SignID sign_id)
 {
 	const Sign *si = ::Sign::GetIfValid(sign_id);
-	return si != NULL && (si->owner == _current_company || si->owner == OWNER_DEITY);
+	return si != NULL && (si->owner == ScriptObject::GetCompany() || si->owner == OWNER_DEITY);
 }
 
 /* static */ ScriptCompany::CompanyID ScriptSign::GetOwner(SignID sign_id)
--- a/src/script/api/script_station.cpp
+++ b/src/script/api/script_station.cpp
@@ -17,13 +17,12 @@
 #include "../../debug.h"
 #include "../../station_base.h"
 #include "../../roadstop_base.h"
-#include "../../company_func.h"
 #include "../../town.h"
 
 /* static */ bool ScriptStation::IsValidStation(StationID station_id)
 {
 	const Station *st = ::Station::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 */ ScriptCompany::CompanyID ScriptStation::GetOwner(StationID station_id)
--- a/src/script/api/script_stationlist.cpp
+++ b/src/script/api/script_stationlist.cpp
@@ -12,7 +12,6 @@
 #include "../../stdafx.h"
 #include "script_stationlist.hpp"
 #include "script_vehicle.hpp"
-#include "../../company_func.h"
 #include "../../station_base.h"
 #include "../../vehicle_base.h"
 
@@ -20,7 +19,7 @@
 {
 	Station *st;
 	FOR_ALL_STATIONS(st) {
-		if ((st->owner == _current_company || _current_company == OWNER_DEITY) && (st->facilities & station_type) != 0) this->AddItem(st->index);
+		if ((st->owner == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY) && (st->facilities & station_type) != 0) this->AddItem(st->index);
 	}
 }
 
--- a/src/script/api/script_tile.cpp
+++ b/src/script/api/script_tile.cpp
@@ -39,7 +39,7 @@
 			if (::GetRoadTileType(tile) != ROAD_TILE_NORMAL) return false;
 			if (!HasExactlyOneBit(::GetRoadBits(tile, ROADTYPE_ROAD))) return false;
 			if (::IsRoadOwner(tile, ROADTYPE_ROAD, OWNER_TOWN)) return true;
-			if (::IsRoadOwner(tile, ROADTYPE_ROAD, _current_company)) return true;
+			if (::IsRoadOwner(tile, ROADTYPE_ROAD, ScriptObject::GetCompany())) return true;
 			return false;
 	}
 }
--- a/src/script/api/script_town.cpp
+++ b/src/script/api/script_town.cpp
@@ -178,7 +178,7 @@
 {
 	if (!IsValidTown(town_id)) return false;
 
-	return ::HasBit(::Town::Get(town_id)->statues, _current_company);
+	return ::HasBit(::Town::Get(town_id)->statues, ScriptObject::GetCompany());
 }
 
 /* static */ bool ScriptTown::IsCity(TownID town_id)
@@ -213,7 +213,7 @@
 {
 	if (!IsValidTown(town_id)) return false;
 
-	return HasBit(::GetMaskOfTownActions(NULL, _current_company, ::Town::Get(town_id)), town_action);
+	return HasBit(::GetMaskOfTownActions(NULL, ScriptObject::GetCompany(), ::Town::Get(town_id)), town_action);
 }
 
 /* static */ bool ScriptTown::PerformTownAction(TownID town_id, TownAction town_action)
--- a/src/script/api/script_tunnel.cpp
+++ b/src/script/api/script_tunnel.cpp
@@ -84,7 +84,7 @@
 	EnforcePrecondition(false, ::IsValidTile(start));
 	EnforcePrecondition(false, vehicle_type == ScriptVehicle::VT_RAIL || vehicle_type == ScriptVehicle::VT_ROAD);
 	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;
 	if (vehicle_type == ScriptVehicle::VT_ROAD) {
--- a/src/script/api/script_vehicle.cpp
+++ b/src/script/api/script_vehicle.cpp
@@ -15,7 +15,6 @@
 #include "script_gamesettings.hpp"
 #include "script_group.hpp"
 #include "../script_instance.hpp"
-#include "../../company_func.h"
 #include "../../string_func.h"
 #include "../../strings_func.h"
 #include "../../command_func.h"
@@ -28,7 +27,7 @@
 /* static */ bool ScriptVehicle::IsValidVehicle(VehicleID vehicle_id)
 {
 	const Vehicle *v = ::Vehicle::GetIfValid(vehicle_id);
-	return v != NULL && (v->owner == _current_company || _current_company == OWNER_DEITY) && (v->IsPrimaryVehicle() || (v->type == VEH_TRAIN && ::Train::From(v)->IsFreeWagon()));
+	return v != NULL && (v->owner == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY) && (v->IsPrimaryVehicle() || (v->type == VEH_TRAIN && ::Train::From(v)->IsFreeWagon()));
 }
 
 /* static */ ScriptCompany::CompanyID ScriptVehicle::GetOwner(VehicleID vehicle_id)
--- a/src/script/api/script_vehiclelist.cpp
+++ b/src/script/api/script_vehiclelist.cpp
@@ -14,7 +14,6 @@
 #include "script_group.hpp"
 #include "script_map.hpp"
 #include "script_station.hpp"
-#include "../../company_func.h"
 #include "../../depot_map.h"
 #include "../../vehicle_base.h"
 
@@ -22,7 +21,7 @@
 {
 	const Vehicle *v;
 	FOR_ALL_VEHICLES(v) {
-		if ((v->owner == _current_company || _current_company == OWNER_DEITY) && v->IsPrimaryVehicle()) this->AddItem(v->index);
+		if ((v->owner == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY) && v->IsPrimaryVehicle()) this->AddItem(v->index);
 	}
 }
 
@@ -32,7 +31,7 @@
 
 	const Vehicle *v;
 	FOR_ALL_VEHICLES(v) {
-		if ((v->owner == _current_company || _current_company == OWNER_DEITY) && v->IsPrimaryVehicle()) {
+		if ((v->owner == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY) && v->IsPrimaryVehicle()) {
 			const Order *order;
 
 			FOR_VEHICLE_ORDERS(v, order) {
@@ -83,7 +82,7 @@
 
 	const Vehicle *v;
 	FOR_ALL_VEHICLES(v) {
-		if ((v->owner == _current_company || _current_company == OWNER_DEITY) && v->IsPrimaryVehicle() && v->type == type) {
+		if ((v->owner == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY) && v->IsPrimaryVehicle() && v->type == type) {
 			const Order *order;
 
 			FOR_VEHICLE_ORDERS(v, order) {
@@ -111,7 +110,7 @@
 
 	const Vehicle *v;
 	FOR_ALL_VEHICLES(v) {
-		if (v->owner == _current_company && v->IsPrimaryVehicle()) {
+		if (v->owner == ScriptObject::GetCompany() && v->IsPrimaryVehicle()) {
 			if (v->group_id == group_id) this->AddItem(v->index);
 		}
 	}
@@ -123,7 +122,7 @@
 
 	const Vehicle *v;
 	FOR_ALL_VEHICLES(v) {
-		if (v->owner == _current_company && v->IsPrimaryVehicle()) {
+		if (v->owner == ScriptObject::GetCompany() && v->IsPrimaryVehicle()) {
 			if (v->type == vehicle_type && v->group_id == ScriptGroup::GROUP_DEFAULT) this->AddItem(v->index);
 		}
 	}
--- a/src/script/api/script_waypoint.cpp
+++ b/src/script/api/script_waypoint.cpp
@@ -13,13 +13,12 @@
 #include "script_waypoint.hpp"
 #include "script_rail.hpp"
 #include "script_marine.hpp"
-#include "../../company_func.h"
 #include "../../waypoint_base.h"
 
 /* static */ bool ScriptWaypoint::IsValidWaypoint(StationID waypoint_id)
 {
 	const Waypoint *wp = ::Waypoint::GetIfValid(waypoint_id);
-	return wp != NULL && (wp->owner == _current_company || _current_company == OWNER_DEITY || wp->owner == OWNER_NONE);
+	return wp != NULL && (wp->owner == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY || wp->owner == OWNER_NONE);
 }
 
 /* static */ StationID ScriptWaypoint::GetWaypointID(TileIndex tile)
--- a/src/script/api/script_waypointlist.cpp
+++ b/src/script/api/script_waypointlist.cpp
@@ -12,7 +12,6 @@
 #include "../../stdafx.h"
 #include "script_waypointlist.hpp"
 #include "script_vehicle.hpp"
-#include "../../company_func.h"
 #include "../../vehicle_base.h"
 #include "../../waypoint_base.h"
 
@@ -21,7 +20,7 @@
 	const Waypoint *wp;
 	FOR_ALL_WAYPOINTS(wp) {
 		if ((wp->facilities & waypoint_type) &&
-				(wp->owner == _current_company || _current_company == OWNER_DEITY || wp->owner == OWNER_NONE)) this->AddItem(wp->index);
+				(wp->owner == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY || wp->owner == OWNER_NONE)) this->AddItem(wp->index);
 	}
 }
 
new file mode 100644
--- /dev/null
+++ b/src/script/api/template/template_companymode.hpp.sq
@@ -0,0 +1,21 @@
+/* $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/>.
+ */
+
+/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
+
+#include "../script_companymode.hpp"
+
+namespace SQConvert {
+	/* Allow ScriptCompanyMode to be used as Squirrel parameter */
+	template <> inline ScriptCompanyMode *GetParam(ForceType<ScriptCompanyMode *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (ScriptCompanyMode *)instance; }
+	template <> inline ScriptCompanyMode &GetParam(ForceType<ScriptCompanyMode &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptCompanyMode *)instance; }
+	template <> inline const ScriptCompanyMode *GetParam(ForceType<const ScriptCompanyMode *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (ScriptCompanyMode *)instance; }
+	template <> inline const ScriptCompanyMode &GetParam(ForceType<const ScriptCompanyMode &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptCompanyMode *)instance; }
+	template <> inline int Return<ScriptCompanyMode *>(HSQUIRRELVM vm, ScriptCompanyMode *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "CompanyMode", res, NULL, DefSQDestructorCallback<ScriptCompanyMode>, true); return 1; }
+} // namespace SQConvert
--- a/src/script/script_instance.cpp
+++ b/src/script/script_instance.cpp
@@ -64,11 +64,11 @@
 	this->engine->SetPrintFunction(&PrintFunc);
 }
 
-void ScriptInstance::Initialize(const char *main_script, const char *instance_name)
+void ScriptInstance::Initialize(const char *main_script, const char *instance_name, CompanyID company)
 {
 	ScriptObject::ActiveInstance active(this);
 
-	this->controller = new ScriptController();
+	this->controller = new ScriptController(company);
 
 	/* Register the API functions and classes */
 	this->engine->SetGlobalPointer(this->engine);
@@ -150,6 +150,8 @@
 	if (this->suspend   < 0)  return;          // Multiplayer suspend, wait for Continue().
 	if (--this->suspend > 0)  return;          // Singleplayer suspend, decrease to 0.
 
+	_current_company = ScriptObject::GetCompany();
+
 	/* If there is a callback to call, call that first */
 	if (this->callback != NULL) {
 		if (this->is_save_data_on_stack) {
--- a/src/script/script_instance.hpp
+++ b/src/script/script_instance.hpp
@@ -35,8 +35,9 @@
 	 * Initialize the script and prepare it for its first run.
 	 * @param main_script The full path of the script to load.
 	 * @param instance_name The name of the instance out of the script to load.
+	 * @param company Which company this script is serving.
 	 */
-	void Initialize(const char *main_script, const char *instance_name);
+	void Initialize(const char *main_script, const char *instance_name, CompanyID company);
 
 	/**
 	 * Get the value of a setting of the current instance.
--- a/src/script/script_storage.hpp
+++ b/src/script/script_storage.hpp
@@ -34,6 +34,8 @@
 private:
 	ScriptModeProc *mode;             ///< The current build mode we are int.
 	class ScriptObject *mode_instance; ///< The instance belonging to the current build mode.
+	CompanyID root_company;          ///< The root company, the company that the script really belongs to.
+	CompanyID company;               ///< The current company.
 
 	uint delay;                      ///< The ticks of delay each DoCommand has.
 	bool allow_do_command;           ///< Is the usage of DoCommands restricted?
@@ -60,6 +62,8 @@
 	ScriptStorage() :
 		mode              (NULL),
 		mode_instance     (NULL),
+		root_company      (INVALID_OWNER),
+		company           (INVALID_OWNER),
 		delay             (1),
 		allow_do_command  (true),
 		/* costs (can't be set) */