diff --git a/src/company_base.h b/src/company_base.h index affe28ab9a..361279190a 100644 --- a/src/company_base.h +++ b/src/company_base.h @@ -49,6 +49,13 @@ struct CompanyInfrastructure { char *Dump(char *buffer, const char *last) const; }; +enum CompanyBankruptcyFlags : byte { + CBRF_NONE = 0x0, + CBRF_SALE = 0x1, ///< the company has been marked for sale + CBRF_SALE_ONLY = 0x2, ///< the company has been marked for sale without being in a bankruptcy state first +}; +DECLARE_ENUM_AS_BIT_SET(CompanyBankruptcyFlags) + typedef Pool CompanyPool; extern CompanyPool _company_pool; @@ -82,6 +89,7 @@ struct CompanyProperties { byte months_of_bankruptcy; ///< Number of months that the company is unable to pay its debts CompanyID bankrupt_last_asked; ///< Which company was most recently asked about buying it? + CompanyBankruptcyFlags bankrupt_flags; ///< bankruptcy flags CompanyMask bankrupt_asked; ///< which companies were asked about buying it? int16 bankrupt_timeout; ///< If bigger than \c 0, amount of time to wait for an answer on an offer to buy this company. Money bankrupt_value; @@ -113,7 +121,7 @@ struct CompanyProperties { : name_2(0), name_1(0), president_name_1(0), president_name_2(0), face(0), money(0), money_fraction(0), current_loan(0), colour(0), block_preview(0), location_of_HQ(0), last_build_coordinate(0), share_owners(), inaugurated_year(0), - months_of_bankruptcy(0), bankrupt_last_asked(INVALID_COMPANY), bankrupt_asked(0), bankrupt_timeout(0), bankrupt_value(0), + months_of_bankruptcy(0), bankrupt_last_asked(INVALID_COMPANY), bankrupt_flags(CBRF_NONE), bankrupt_asked(0), bankrupt_timeout(0), bankrupt_value(0), terraform_limit(0), clear_limit(0), tree_limit(0), purchase_land_limit(0), build_object_limit(0), is_ai(false), engine_renew_list(nullptr) {} }; diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index 467dbde3ba..c5548805c0 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -681,6 +681,7 @@ static void HandleBankruptcyTakeover(Company *c) assert(c->bankrupt_asked != 0); + /* We're currently asking some company to buy 'us' */ if (c->bankrupt_timeout != 0) { c->bankrupt_timeout -= MAX_COMPANIES; @@ -698,7 +699,7 @@ static void HandleBankruptcyTakeover(Company *c) /* Ask the company with the highest performance history first */ for (Company *c2 : Company::Iterate()) { - if (c2->bankrupt_asked == 0 && // Don't ask companies going bankrupt themselves + if ((c2->bankrupt_asked == 0 || (c2->bankrupt_flags & CBRF_SALE_ONLY)) && // Don't ask companies going bankrupt themselves !HasBit(c->bankrupt_asked, c2->index) && best_performance < c2->old_economy[1].performance_history && MayCompanyTakeOver(c2->index, c->index)) { @@ -709,7 +710,13 @@ static void HandleBankruptcyTakeover(Company *c) /* Asked all companies? */ if (best_performance == -1) { - c->bankrupt_asked = MAX_UVALUE(CompanyMask); + if (c->bankrupt_flags & CBRF_SALE_ONLY) { + c->bankrupt_asked = 0; + DeleteWindowById(WC_BUY_COMPANY, c->index); + } else { + c->bankrupt_asked = MAX_UVALUE(CompanyMask); + } + c->bankrupt_flags = CBRF_NONE; return; } @@ -962,9 +969,12 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 if (!(flags & DC_EXEC)) return CommandCost(); + c->bankrupt_flags |= CBRF_SALE; + if (c->bankrupt_asked == 0) c->bankrupt_flags |= CBRF_SALE_ONLY; c->bankrupt_value = CalculateCompanyValue(c, false); c->bankrupt_asked = 1 << c->index; // Don't ask the owner c->bankrupt_timeout = 0; + DeleteWindowById(WC_BUY_COMPANY, c->index); break; } diff --git a/src/company_gui.cpp b/src/company_gui.cpp index a9114e4160..6245ad2fd3 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -2885,12 +2885,13 @@ struct BuyCompanyWindow : Window { BuyCompanyWindow(WindowDesc *desc, WindowNumber window_number) : Window(desc) { this->InitNested(window_number); + this->owner = _local_company; } ~BuyCompanyWindow() { const Company *c = Company::GetIfValid((CompanyID)this->window_number); - if (c != nullptr && HasBit(c->bankrupt_asked, _current_company)) { + if (c != nullptr && HasBit(c->bankrupt_asked, this->owner)) { DoCommandP(0, this->window_number, 0, CMD_DECLINE_BUY_COMPANY); } } diff --git a/src/economy.cpp b/src/economy.cpp index 2dd9c96cd4..e75b30e41e 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -628,10 +628,12 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) static void CompanyCheckBankrupt(Company *c) { /* If the company has money again, it does not go bankrupt */ + if (c->bankrupt_flags & CBRF_SALE) return; if (c->money - c->current_loan >= -_economy.max_loan) { int previous_months_of_bankruptcy = CeilDiv(c->months_of_bankruptcy, 3); c->months_of_bankruptcy = 0; c->bankrupt_asked = 0; + DeleteWindowById(WC_BUY_COMPANY, c->index); if (previous_months_of_bankruptcy != 0) CompanyAdminUpdate(c); return; } diff --git a/src/saveload/company_sl.cpp b/src/saveload/company_sl.cpp index eae014b581..c9a2da7d7e 100644 --- a/src/saveload/company_sl.cpp +++ b/src/saveload/company_sl.cpp @@ -283,6 +283,7 @@ static const SaveLoad _company_desc[] = { SLE_VAR(CompanyProperties, months_of_bankruptcy, SLE_UINT8), SLE_CONDVAR_X(CompanyProperties, bankrupt_last_asked, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_BANKRUPTCY_EXTRA)), + SLE_CONDVAR_X(CompanyProperties, bankrupt_flags, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_BANKRUPTCY_EXTRA, 2)), SLE_CONDVAR(CompanyProperties, bankrupt_asked, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104), SLE_CONDVAR(CompanyProperties, bankrupt_asked, SLE_UINT16, SLV_104, SL_MAX_VERSION), SLE_VAR(CompanyProperties, bankrupt_timeout, SLE_INT16), diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp index a8dcc3678d..b501e5cb2e 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -161,7 +161,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = { { XSLFI_EXTRA_STATION_NAMES, XSCF_NULL, 1, 1, "extra_station_names", nullptr, nullptr, nullptr }, { XSLFI_DEPOT_ORDER_EXTRA_FLAGS,XSCF_IGNORABLE_UNKNOWN, 1, 1, "depot_order_extra_flags", nullptr, nullptr, nullptr }, { XSLFI_EXTRA_SIGNAL_TYPES, XSCF_NULL, 1, 1, "extra_signal_types", nullptr, nullptr, nullptr }, - { XSLFI_BANKRUPTCY_EXTRA, XSCF_NULL, 1, 1, "bankruptcy_extra", nullptr, nullptr, nullptr }, + { XSLFI_BANKRUPTCY_EXTRA, XSCF_NULL, 2, 2, "bankruptcy_extra", nullptr, nullptr, nullptr }, { XSLFI_OBJECT_GROUND_TYPES, XSCF_NULL, 3, 3, "object_ground_types", nullptr, nullptr, nullptr }, { XSLFI_LINKGRAPH_AIRCRAFT, XSCF_NULL, 1, 1, "linkgraph_aircraft", nullptr, nullptr, nullptr }, { XSLFI_COMPANY_PW, XSCF_IGNORABLE_ALL, 1, 1, "company_password", nullptr, nullptr, "PLYP" },