Mercurial > hg > openttd
changeset 18784:c6637e50e2f9 draft
(svn r23632) -Add: GSCompanyMode, to change company in GameScripts
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) */