Merge remote-tracking branch 'upstream/master' into 13.0
This commit is contained in:
+77
-64
@@ -14,7 +14,6 @@
|
||||
#include "core/backup_type.hpp"
|
||||
#include "town.h"
|
||||
#include "news_func.h"
|
||||
#include "cmd_helper.h"
|
||||
#include "command_func.h"
|
||||
#include "network/network.h"
|
||||
#include "network/network_func.h"
|
||||
@@ -36,6 +35,7 @@
|
||||
#include "goal_base.h"
|
||||
#include "story_base.h"
|
||||
#include "widgets/statusbar_widget.h"
|
||||
#include "company_cmd.h"
|
||||
|
||||
#include "table/strings.h"
|
||||
#include "cargo_type.h"
|
||||
@@ -67,11 +67,12 @@ Company::Company(uint16 name_1, bool is_ai)
|
||||
this->name_1 = name_1;
|
||||
this->location_of_HQ = INVALID_TILE;
|
||||
this->is_ai = is_ai;
|
||||
this->terraform_limit = (uint32)_settings_game.construction.terraform_frame_burst << 16;
|
||||
this->clear_limit = (uint32)_settings_game.construction.clear_frame_burst << 16;
|
||||
this->tree_limit = (uint32)_settings_game.construction.tree_frame_burst << 16;
|
||||
this->terraform_limit = (uint32)_settings_game.construction.terraform_frame_burst << 16;
|
||||
this->clear_limit = (uint32)_settings_game.construction.clear_frame_burst << 16;
|
||||
this->tree_limit = (uint32)_settings_game.construction.tree_frame_burst << 16;
|
||||
this->build_object_limit = (uint32)_settings_game.construction.build_object_frame_burst << 16;
|
||||
|
||||
for (uint j = 0; j < 4; j++) this->share_owners[j] = INVALID_OWNER;
|
||||
std::fill(this->share_owners.begin(), this->share_owners.end(), INVALID_OWNER);
|
||||
InvalidateWindowData(WC_PERFORMANCE_DETAIL, 0, INVALID_COMPANY);
|
||||
InvalidateWindowClassesData(WC_WATCH_COMPANY, 0);
|
||||
InvalidateWindowClassesData(WC_WATCH_COMPANYA, 1);
|
||||
@@ -228,17 +229,17 @@ static void SubtractMoneyFromAnyCompany(Company *c, const CommandCost &cost)
|
||||
c->money -= cost.GetCost();
|
||||
c->yearly_expenses[0][cost.GetExpensesType()] += cost.GetCost();
|
||||
|
||||
if (HasBit(1 << EXPENSES_TRAIN_INC |
|
||||
1 << EXPENSES_ROADVEH_INC |
|
||||
1 << EXPENSES_AIRCRAFT_INC |
|
||||
1 << EXPENSES_SHIP_INC, cost.GetExpensesType())) {
|
||||
if (HasBit(1 << EXPENSES_TRAIN_REVENUE |
|
||||
1 << EXPENSES_ROADVEH_REVENUE |
|
||||
1 << EXPENSES_AIRCRAFT_REVENUE |
|
||||
1 << EXPENSES_SHIP_REVENUE, cost.GetExpensesType())) {
|
||||
c->cur_economy.income -= cost.GetCost();
|
||||
} else if (HasBit(1 << EXPENSES_TRAIN_RUN |
|
||||
1 << EXPENSES_ROADVEH_RUN |
|
||||
1 << EXPENSES_AIRCRAFT_RUN |
|
||||
1 << EXPENSES_SHIP_RUN |
|
||||
1 << EXPENSES_PROPERTY |
|
||||
1 << EXPENSES_LOAN_INT, cost.GetExpensesType())) {
|
||||
1 << EXPENSES_LOAN_INTEREST, cost.GetExpensesType())) {
|
||||
c->cur_economy.expenses -= cost.GetCost();
|
||||
}
|
||||
|
||||
@@ -276,9 +277,10 @@ void SubtractMoneyFromCompanyFract(CompanyID company, const CommandCost &cst)
|
||||
void UpdateLandscapingLimits()
|
||||
{
|
||||
for (Company *c : Company::Iterate()) {
|
||||
c->terraform_limit = std::min<uint64>((uint64)c->terraform_limit + _settings_game.construction.terraform_per_64k_frames, (uint64)_settings_game.construction.terraform_frame_burst << 16);
|
||||
c->clear_limit = std::min<uint64>((uint64)c->clear_limit + _settings_game.construction.clear_per_64k_frames, (uint64)_settings_game.construction.clear_frame_burst << 16);
|
||||
c->tree_limit = std::min<uint64>((uint64)c->tree_limit + _settings_game.construction.tree_per_64k_frames, (uint64)_settings_game.construction.tree_frame_burst << 16);
|
||||
c->terraform_limit = std::min<uint64>((uint64)c->terraform_limit + _settings_game.construction.terraform_per_64k_frames, (uint64)_settings_game.construction.terraform_frame_burst << 16);
|
||||
c->clear_limit = std::min<uint64>((uint64)c->clear_limit + _settings_game.construction.clear_per_64k_frames, (uint64)_settings_game.construction.clear_frame_burst << 16);
|
||||
c->tree_limit = std::min<uint64>((uint64)c->tree_limit + _settings_game.construction.tree_per_64k_frames, (uint64)_settings_game.construction.tree_frame_burst << 16);
|
||||
c->build_object_limit = std::min<uint64>((uint64)c->build_object_limit + _settings_game.construction.build_object_per_64k_frames, (uint64)_settings_game.construction.build_object_frame_burst << 16);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -566,12 +568,19 @@ Company *DoStartupNewCompany(bool is_ai, CompanyID company = INVALID_COMPANY)
|
||||
|
||||
c->money = c->current_loan = (std::min<int64>(INITIAL_LOAN, _economy.max_loan) * _economy.inflation_prices >> 16) / 50000 * 50000;
|
||||
|
||||
c->share_owners[0] = c->share_owners[1] = c->share_owners[2] = c->share_owners[3] = INVALID_OWNER;
|
||||
std::fill(c->share_owners.begin(), c->share_owners.end(), INVALID_OWNER);
|
||||
|
||||
c->avail_railtypes = GetCompanyRailtypes(c->index);
|
||||
c->avail_roadtypes = GetCompanyRoadTypes(c->index);
|
||||
c->inaugurated_year = _cur_year;
|
||||
RandomCompanyManagerFaceBits(c->face, (GenderEthnicity)Random(), false, false); // create a random company manager face
|
||||
|
||||
/* If starting a player company in singleplayer and a favorite company manager face is selected, choose it. Otherwise, use a random face.
|
||||
* In a network game, we'll choose the favorite face later in CmdCompanyCtrl to sync it to all clients, but we choose it here for the first (host) company. */
|
||||
if (_company_manager_face != 0 && !is_ai) {
|
||||
c->face = _company_manager_face;
|
||||
} else {
|
||||
RandomCompanyManagerFaceBits(c->face, (GenderEthnicity)Random(), false, false);
|
||||
}
|
||||
|
||||
SetDefaultCompanySettings(c->index);
|
||||
ClearEnginesHiddenFlagOfCompany(c->index);
|
||||
@@ -612,7 +621,7 @@ static bool MaybeStartNewCompany()
|
||||
if (n < (uint)_settings_game.difficulty.max_no_competitors) {
|
||||
/* Send a command to all clients to start up a new AI.
|
||||
* Works fine for Multiplayer and Singleplayer */
|
||||
return DoCommandP(0, CCA_NEW_AI | INVALID_COMPANY << 16, 0, CMD_COMPANY_CTRL);
|
||||
return Command<CMD_COMPANY_CTRL>::Post(CCA_NEW_AI, INVALID_COMPANY, CRR_NONE, INVALID_CLIENT_ID );
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -803,22 +812,17 @@ void CompanyAdminRemove(CompanyID company_id, CompanyRemoveReason reason)
|
||||
|
||||
/**
|
||||
* Control the companies: add, delete, etc.
|
||||
* @param tile unused
|
||||
* @param flags operation to perform
|
||||
* @param p1 various functionality
|
||||
* - bits 0..15: CompanyCtrlAction
|
||||
* - bits 16..23: CompanyID
|
||||
* - bits 24..31: CompanyRemoveReason (with CCA_DELETE)
|
||||
* @param p2 ClientID
|
||||
* @param text unused
|
||||
* @param cca action to perform
|
||||
* @param company_id company to perform the action on
|
||||
* @param client_id ClientID
|
||||
* @return the cost of this operation or an error
|
||||
*/
|
||||
CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text)
|
||||
CommandCost CmdCompanyCtrl(DoCommandFlag flags, CompanyCtrlAction cca, CompanyID company_id, CompanyRemoveReason reason, ClientID client_id)
|
||||
{
|
||||
InvalidateWindowData(WC_COMPANY_LEAGUE, 0, 0);
|
||||
CompanyID company_id = (CompanyID)GB(p1, 16, 8);
|
||||
|
||||
switch ((CompanyCtrlAction)GB(p1, 0, 16)) {
|
||||
switch (cca) {
|
||||
case CCA_NEW: { // Create a new company
|
||||
/* This command is only executed in a multiplayer game */
|
||||
if (!_networking && !citymania::IsReplayingCommands()) return CMD_ERROR;
|
||||
@@ -826,7 +830,6 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
|
||||
/* Has the network client a correct ClientIndex? */
|
||||
if (!(flags & DC_EXEC)) return CommandCost();
|
||||
|
||||
ClientID client_id = (ClientID)p2;
|
||||
NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id);
|
||||
|
||||
/* Delete multiplayer progress bar */
|
||||
@@ -853,6 +856,10 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
|
||||
NetworkChangeCompanyPassword(_local_company, _settings_client.network.default_company_pass);
|
||||
}
|
||||
|
||||
/* In network games, we need to try setting the company manager face here to sync it to all clients.
|
||||
* If a favorite company manager face is selected, choose it. Otherwise, use a random face. */
|
||||
if (_company_manager_face != 0) Command<CMD_SET_COMPANY_MANAGER_FACE>::SendNet(STR_NULL, c->index, _company_manager_face);
|
||||
|
||||
/* Now that we have a new company, broadcast our company settings to
|
||||
* all clients so everything is in sync */
|
||||
SyncCompanySettings();
|
||||
@@ -882,7 +889,6 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
|
||||
}
|
||||
|
||||
case CCA_DELETE: { // Delete a company
|
||||
CompanyRemoveReason reason = (CompanyRemoveReason)GB(p1, 24, 8);
|
||||
if (reason >= CRR_END) return CMD_ERROR;
|
||||
|
||||
/* We can't delete the last existing company in singleplayer mode. */
|
||||
@@ -931,17 +937,12 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
|
||||
|
||||
/**
|
||||
* Change the company manager's face.
|
||||
* @param tile unused
|
||||
* @param flags operation to perform
|
||||
* @param p1 unused
|
||||
* @param p2 face bitmasked
|
||||
* @param text unused
|
||||
* @param cmf face bitmasked
|
||||
* @return the cost of this operation or an error
|
||||
*/
|
||||
CommandCost CmdSetCompanyManagerFace(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text)
|
||||
CommandCost CmdSetCompanyManagerFace(DoCommandFlag flags, CompanyManagerFace cmf)
|
||||
{
|
||||
CompanyManagerFace cmf = (CompanyManagerFace)p2;
|
||||
|
||||
if (!IsValidCompanyManagerFace(cmf)) return CMD_ERROR;
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
@@ -953,21 +954,14 @@ CommandCost CmdSetCompanyManagerFace(TileIndex tile, DoCommandFlag flags, uint32
|
||||
|
||||
/**
|
||||
* Change the company's company-colour
|
||||
* @param tile unused
|
||||
* @param flags operation to perform
|
||||
* @param p1 bitstuffed:
|
||||
* p1 bits 0-7 scheme to set
|
||||
* p1 bit 8 set first/second colour
|
||||
* @param p2 new colour for vehicles, property, etc.
|
||||
* @param text unused
|
||||
* @param scheme scheme to set
|
||||
* @param primary set first/second colour
|
||||
* @param colour new colour for vehicles, property, etc.
|
||||
* @return the cost of this operation or an error
|
||||
*/
|
||||
CommandCost CmdSetCompanyColour(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text)
|
||||
CommandCost CmdSetCompanyColour(DoCommandFlag flags, LiveryScheme scheme, bool primary, Colours colour)
|
||||
{
|
||||
Colours colour = Extract<Colours, 0, 8>(p2);
|
||||
LiveryScheme scheme = Extract<LiveryScheme, 0, 8>(p1);
|
||||
bool second = HasBit(p1, 8);
|
||||
|
||||
if (scheme >= LS_END || (colour >= COLOUR_END && colour != INVALID_COLOUR)) return CMD_ERROR;
|
||||
|
||||
/* Default scheme can't be reset to invalid. */
|
||||
@@ -976,14 +970,14 @@ CommandCost CmdSetCompanyColour(TileIndex tile, DoCommandFlag flags, uint32 p1,
|
||||
Company *c = Company::Get(_current_company);
|
||||
|
||||
/* Ensure no two companies have the same primary colour */
|
||||
if (scheme == LS_DEFAULT && !second) {
|
||||
if (scheme == LS_DEFAULT && primary) {
|
||||
for (const Company *cc : Company::Iterate()) {
|
||||
if (cc != c && cc->colour == colour) return CMD_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
if (!second) {
|
||||
if (primary) {
|
||||
if (scheme != LS_DEFAULT) SB(c->livery[scheme].in_use, 0, 1, colour != INVALID_COLOUR);
|
||||
if (colour == INVALID_COLOUR) colour = (Colours)c->livery[LS_DEFAULT].colour1;
|
||||
c->livery[scheme].colour1 = colour;
|
||||
@@ -1066,14 +1060,11 @@ static bool IsUniqueCompanyName(const std::string &name)
|
||||
|
||||
/**
|
||||
* Change the name of the company.
|
||||
* @param tile unused
|
||||
* @param flags operation to perform
|
||||
* @param p1 unused
|
||||
* @param p2 unused
|
||||
* @param text the new name or an empty string when resetting to the default
|
||||
* @return the cost of this operation or an error
|
||||
*/
|
||||
CommandCost CmdRenameCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text)
|
||||
CommandCost CmdRenameCompany(DoCommandFlag flags, const std::string &text)
|
||||
{
|
||||
bool reset = text.empty();
|
||||
|
||||
@@ -1113,14 +1104,11 @@ static bool IsUniquePresidentName(const std::string &name)
|
||||
|
||||
/**
|
||||
* Change the name of the president.
|
||||
* @param tile unused
|
||||
* @param flags operation to perform
|
||||
* @param p1 unused
|
||||
* @param p2 unused
|
||||
* @param text the new name or an empty string when resetting to the default
|
||||
* @return the cost of this operation or an error
|
||||
*/
|
||||
CommandCost CmdRenamePresident(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text)
|
||||
CommandCost CmdRenamePresident(DoCommandFlag flags, const std::string &text)
|
||||
{
|
||||
bool reset = text.empty();
|
||||
|
||||
@@ -1138,7 +1126,7 @@ CommandCost CmdRenamePresident(TileIndex tile, DoCommandFlag flags, uint32 p1, u
|
||||
c->president_name = text;
|
||||
|
||||
if (c->name_1 == STR_SV_UNNAMED && c->name.empty()) {
|
||||
DoCommand(0, 0, 0, DC_EXEC, CMD_RENAME_COMPANY, text + " Transport");
|
||||
Command<CMD_RENAME_COMPANY>::Do(DC_EXEC, text + " Transport");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1198,20 +1186,17 @@ uint32 CompanyInfrastructure::GetTramTotal() const
|
||||
* To prevent abuse in multiplayer games you can only send money to other
|
||||
* companies if you have paid off your loan (either explicitly, or implicitly
|
||||
* given the fact that you have more money than loan).
|
||||
* @param tile unused
|
||||
* @param flags operation to perform
|
||||
* @param p1 the amount of money to transfer; max 20.000.000
|
||||
* @param p2 the company to transfer the money to
|
||||
* @param text unused
|
||||
* @param money the amount of money to transfer; max 20.000.000
|
||||
* @param dest_company the company to transfer the money to
|
||||
* @return the cost of this operation or an error
|
||||
*/
|
||||
CommandCost CmdGiveMoney(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text)
|
||||
CommandCost CmdGiveMoney(DoCommandFlag flags, uint32 money, CompanyID dest_company)
|
||||
{
|
||||
if (!_settings_game.economy.give_money) return CMD_ERROR;
|
||||
|
||||
const Company *c = Company::Get(_current_company);
|
||||
CommandCost amount(EXPENSES_OTHER, std::min<Money>(p1, 20000000LL));
|
||||
CompanyID dest_company = (CompanyID)p2;
|
||||
CommandCost amount(EXPENSES_OTHER, std::min<Money>(money, 20000000LL));
|
||||
|
||||
/* You can only transfer funds that is in excess of your loan */
|
||||
if (c->money - c->current_loan < amount.GetCost() || amount.GetCost() < 0) return_cmd_error(STR_ERROR_INSUFFICIENT_FUNDS);
|
||||
@@ -1237,3 +1222,31 @@ CommandCost CmdGiveMoney(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
|
||||
/* Subtract money from local-company */
|
||||
return amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the index of the first available company. It attempts,
|
||||
* from first to last, and as soon as the attempt succeeds,
|
||||
* to get the index of the company:
|
||||
* 1st - get the first existing human company.
|
||||
* 2nd - get the first non-existing company.
|
||||
* 3rd - get COMPANY_FIRST.
|
||||
* @return the index of the first available company.
|
||||
*/
|
||||
CompanyID GetFirstPlayableCompanyID()
|
||||
{
|
||||
for (Company *c : Company::Iterate()) {
|
||||
if (Company::IsHumanID(c->index)) {
|
||||
return c->index;
|
||||
}
|
||||
}
|
||||
|
||||
if (Company::CanAllocateItem()) {
|
||||
for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
|
||||
if (!Company::IsValidID(c)) {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return COMPANY_FIRST;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user