Improve handling of company sales
Avoid conflicts between bankruptcy and manual company sale paths
This commit is contained in:
@@ -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<Company, CompanyID, 1, MAX_COMPANIES> 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) {}
|
||||
};
|
||||
|
||||
|
@@ -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) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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),
|
||||
|
@@ -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" },
|
||||
|
Reference in New Issue
Block a user