diff --git a/src/command.cpp b/src/command.cpp index b63b416141..2f4cca0b33 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -144,6 +144,7 @@ CommandProc CmdPause; CommandProc CmdBuyShareInCompany; CommandProc CmdSellShareInCompany; CommandProc CmdBuyCompany; +CommandProc CmdDeclineBuyCompany; CommandProc CmdFoundTown; CommandProc CmdRenameTown; @@ -380,7 +381,8 @@ static const Command _command_proc_table[] = { DEF_CMD(CmdBuyShareInCompany, 0, CMDT_MONEY_MANAGEMENT ), // CMD_BUY_SHARE_IN_COMPANY DEF_CMD(CmdSellShareInCompany, 0, CMDT_MONEY_MANAGEMENT ), // CMD_SELL_SHARE_IN_COMPANY - DEF_CMD(CmdBuyCompany, 0, CMDT_MONEY_MANAGEMENT ), // CMD_BUY_COMANY + DEF_CMD(CmdBuyCompany, 0, CMDT_MONEY_MANAGEMENT ), // CMD_BUY_COMPANY + DEF_CMD(CmdDeclineBuyCompany, 0, CMDT_MONEY_MANAGEMENT ), // CMD_DECLINE_BUY_COMPANY DEF_CMD(CmdFoundTown, CMD_DEITY | CMD_NO_TEST, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_FOUND_TOWN; founding random town can fail only in exec run DEF_CMD(CmdRenameTown, CMD_DEITY | CMD_SERVER, CMDT_OTHER_MANAGEMENT ), // CMD_RENAME_TOWN diff --git a/src/command_type.h b/src/command_type.h index b7b29cde0a..073888428b 100644 --- a/src/command_type.h +++ b/src/command_type.h @@ -322,6 +322,7 @@ enum Commands { CMD_BUY_SHARE_IN_COMPANY, ///< buy a share from a company CMD_SELL_SHARE_IN_COMPANY, ///< sell a share from a company CMD_BUY_COMPANY, ///< buy a company which is bankrupt + CMD_DECLINE_BUY_COMPANY, ///< decline to buy a company which is bankrupt CMD_FOUND_TOWN, ///< found a town CMD_RENAME_TOWN, ///< rename a town diff --git a/src/company_base.h b/src/company_base.h index 0d2e0621b8..dc046eb907 100644 --- a/src/company_base.h +++ b/src/company_base.h @@ -81,6 +81,7 @@ struct CompanyProperties { Year inaugurated_year; ///< Year of starting the company. 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? 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; @@ -107,7 +108,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_asked(0), bankrupt_timeout(0), bankrupt_value(0), + months_of_bankruptcy(0), bankrupt_last_asked(INVALID_COMPANY), 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) {} }; diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index 900ccb739b..eba6cfa968 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -707,6 +707,7 @@ static void HandleBankruptcyTakeover(Company *c) } SetBit(c->bankrupt_asked, best->index); + c->bankrupt_last_asked = best->index; c->bankrupt_timeout = TAKE_OVER_TIMEOUT; if (best->is_ai) { diff --git a/src/company_gui.cpp b/src/company_gui.cpp index bac4d59a3d..ad514b06e2 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -2791,6 +2791,14 @@ struct BuyCompanyWindow : Window { this->InitNested(window_number); } + ~BuyCompanyWindow() + { + const Company *c = Company::GetIfValid((CompanyID)this->window_number); + if (c != nullptr && HasBit(c->bankrupt_asked, _current_company)) { + DoCommandP(0, this->window_number, 0, CMD_DECLINE_BUY_COMPANY); + } + } + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { diff --git a/src/economy.cpp b/src/economy.cpp index dcdc7e5932..5d7639649c 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -2285,6 +2285,8 @@ static void DoAcquireCompany(Company *c) if (c->is_ai) AI::Stop(c->index); + c->bankrupt_asked = 0; + DeleteCompanyWindows(ci); InvalidateWindowClassesData(WC_TRAINS_LIST, 0); InvalidateWindowClassesData(WC_TRACE_RESTRICT_SLOTS, 0); @@ -2429,6 +2431,31 @@ CommandCost CmdBuyCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 return cost; } +/** + * Decline to buy up another company. + * When a competing company is gone bankrupt you get the chance to purchase + * that company, actively decline the offer. + * @param tile unused + * @param flags type of operation + * @param p1 company to buy up + * @param p2 unused + * @param text unused + * @return the cost of this operation or an error + */ +CommandCost CmdDeclineBuyCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) +{ + CompanyID target_company = (CompanyID)p1; + Company *c = Company::GetIfValid(target_company); + if (c == nullptr) return CommandCost(); + + if (flags & DC_EXEC) { + if (c->bankrupt_last_asked == _current_company) { + c->bankrupt_timeout = 0; + } + } + return CommandCost(); +} + uint ScaleQuantity(uint amount, int scale_factor) { scale_factor += 200; // ensure factor is positive diff --git a/src/saveload/company_sl.cpp b/src/saveload/company_sl.cpp index 041af087ea..21fbb7894b 100644 --- a/src/saveload/company_sl.cpp +++ b/src/saveload/company_sl.cpp @@ -274,6 +274,7 @@ static const SaveLoad _company_desc[] = { SLE_VAR(CompanyProperties, num_valid_stat_ent, SLE_UINT8), 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(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 863d80c960..edb314f3b2 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -156,6 +156,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_NULL, XSCF_NULL, 0, 0, nullptr, nullptr, nullptr, nullptr },// This is the end marker }; diff --git a/src/saveload/extended_ver_sl.h b/src/saveload/extended_ver_sl.h index d42986dcce..200f668e20 100644 --- a/src/saveload/extended_ver_sl.h +++ b/src/saveload/extended_ver_sl.h @@ -110,6 +110,7 @@ enum SlXvFeatureIndex { XSLFI_EXTRA_STATION_NAMES, ///< Extra station names XSLFI_DEPOT_ORDER_EXTRA_FLAGS, ///< Depot order extra flags XSLFI_EXTRA_SIGNAL_TYPES, ///< Extra signal types + XSLFI_BANKRUPTCY_EXTRA, ///< Extra company bankruptcy fields XSLFI_RIFF_HEADER_60_BIT, ///< Size field in RIFF chunk header is 60 bit XSLFI_HEIGHT_8_BIT, ///< Map tile height is 8 bit instead of 4 bit, but savegame version may be before this became true in trunk