diff --git a/src/economy.cpp b/src/economy.cpp --- a/src/economy.cpp +++ b/src/economy.cpp @@ -105,15 +105,12 @@ Prices _price; static PriceMultipliers _price_base_multiplier; /** - * Calculate the value of the company. That is the value of all - * assets (vehicles, stations) and money minus the loan, - * except when including_loan is \c false which is useful when - * we want to calculate the value for bankruptcy. - * @param c the company to get the value of. - * @param including_loan include the loan in the company value. - * @return the value of the company. + * Calculate the value of the assets of a company. + * + * @param c The company to calculate the value of. + * @return The value of the assets of the company. */ -Money CalculateCompanyValue(const Company *c, bool including_loan) +static Money CalculateCompanyAssetValue(const Company *c) { Owner owner = c->index; @@ -136,6 +133,22 @@ Money CalculateCompanyValue(const Compan } } + return value; +} + +/** + * Calculate the value of the company. That is the value of all + * assets (vehicles, stations) and money (including loan), + * except when including_loan is \c false which is useful when + * we want to calculate the value for bankruptcy. + * @param c the company to get the value of. + * @param including_loan include the loan in the company value. + * @return the value of the company. + */ +Money CalculateCompanyValue(const Company *c, bool including_loan) +{ + Money value = CalculateCompanyAssetValue(c); + /* Add real money value */ if (including_loan) value -= c->current_loan; value += c->money; @@ -144,6 +157,39 @@ Money CalculateCompanyValue(const Compan } /** + * Calculate what you have to pay to take over a company. + * + * This is different from bankruptcy and company value, and involves a few + * more parameters to make it more realistic. + * + * You have to pay for: + * - The value of all the assets in the company. + * - The loan the company has (the investors really want their money back). + * - The profit for the next two years (if positive) based on the last four quarters. + * + * And on top of that, they walk away with all the money they have in the bank. + * + * @param c the company to get the value of. + * @return The value of the company. + */ +Money CalculateHostileTakeoverValue(const Company *c) +{ + Money value = CalculateCompanyAssetValue(c); + + value += c->current_loan; + /* Negative balance is basically a loan. */ + if (c->money < 0) { + value += -c->money; + } + + for (int quarter = 0; quarter < 4; quarter++) { + value += std::max(c->old_economy[quarter].income - c->old_economy[quarter].expenses, 0) * 2; + } + + return std::max(value, 1); +} + +/** * if update is set to true, the economy is updated with this score * (also the house is updated, should only be true in the on-tick event) * @param update the economy with calculated score @@ -1940,14 +1986,14 @@ static IntervalTimer HandleEconomyFluctuations(); }); -static void DoAcquireCompany(Company *c) +static void DoAcquireCompany(Company *c, bool hostile_takeover) { CompanyID ci = c->index; CompanyNewsInformation *cni = new CompanyNewsInformation(c, Company::Get(_current_company)); SetDParam(0, STR_NEWS_COMPANY_MERGER_TITLE); - SetDParam(1, c->bankrupt_value == 0 ? STR_NEWS_MERGER_TAKEOVER_TITLE : STR_NEWS_COMPANY_MERGER_DESCRIPTION); + SetDParam(1, hostile_takeover ? STR_NEWS_MERGER_TAKEOVER_TITLE : STR_NEWS_COMPANY_MERGER_DESCRIPTION); SetDParamStr(2, cni->company_name); SetDParamStr(3, cni->other_company_name); SetDParam(4, c->bankrupt_value); @@ -1957,14 +2003,6 @@ static void DoAcquireCompany(Company *c) ChangeOwnershipOfCompanyItems(ci, _current_company); - if (c->bankrupt_value == 0) { - Company *owner = Company::Get(_current_company); - - /* Get both the balance and the loan of the company you just bought. */ - SubtractMoneyFromCompany(CommandCost(EXPENSES_OTHER, -c->money)); - owner->current_loan += c->current_loan; - } - if (c->is_ai) AI::Stop(c->index); CloseCompanyWindows(ci); @@ -1983,15 +2021,23 @@ static void DoAcquireCompany(Company *c) * @todo currently this only works for AI companies * @param flags type of operation * @param target_company company to buy up + * @param hostile_takeover whether to buy up the company even if it is not bankrupt * @return the cost of this operation or an error */ -CommandCost CmdBuyCompany(DoCommandFlag flags, CompanyID target_company) +CommandCost CmdBuyCompany(DoCommandFlag flags, CompanyID target_company, bool hostile_takeover) { Company *c = Company::GetIfValid(target_company); if (c == nullptr) return CMD_ERROR; + /* If you do a hostile takeover but the company went bankrupt, buy it via bankruptcy rules. */ + if (hostile_takeover && HasBit(c->bankrupt_asked, _current_company)) hostile_takeover = false; + /* Disable takeovers when not asked */ - if (!HasBit(c->bankrupt_asked, _current_company)) return CMD_ERROR; + if (!hostile_takeover && !HasBit(c->bankrupt_asked, _current_company)) return CMD_ERROR; + + /* Only allow hostile takeover of AI companies and when in single player */ + if (hostile_takeover && !c->is_ai) return CMD_ERROR; + if (hostile_takeover && _networking) return CMD_ERROR; /* Disable taking over the local company in singleplayer mode */ if (!_networking && _local_company == c->index) return CMD_ERROR; @@ -2002,11 +2048,13 @@ CommandCost CmdBuyCompany(DoCommandFlag /* Disable taking over when not allowed. */ if (!MayCompanyTakeOver(_current_company, target_company)) return CMD_ERROR; - /* Get the cost here as the company is deleted in DoAcquireCompany. */ - CommandCost cost(EXPENSES_OTHER, c->bankrupt_value); + /* Get the cost here as the company is deleted in DoAcquireCompany. + * For bankruptcy this amount is calculated when the offer was made; + * for hostile takeover you pay the current price. */ + CommandCost cost(EXPENSES_OTHER, hostile_takeover ? CalculateHostileTakeoverValue(c) : c->bankrupt_value); if (flags & DC_EXEC) { - DoAcquireCompany(c); + DoAcquireCompany(c, hostile_takeover); } return cost; }