Feature: allow to do a hostile takeover of an AI company (in singleplayer) (#10914)

With the removal of the share-system, you could no longer make an
AI disappear in a single player game. At least, not without going
into the console.
This commit is contained in:
Patric Stout
2023-06-05 19:32:22 +02:00
committed by GitHub
parent f814c86389
commit 3b1407d240
9 changed files with 136 additions and 36 deletions

View File

@@ -2228,6 +2228,12 @@ static const NWidgetPart _nested_company_widgets[] = {
/* Multi player buttons. */
NWidget(NWID_VERTICAL), SetPIP(4, 2, 4),
NWidget(NWID_SPACER), SetFill(0, 1),
NWidget(NWID_HORIZONTAL), SetPIP(0, 4, 0),
NWidget(NWID_SPACER), SetFill(1, 0),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_C_SELECT_HOSTILE_TAKEOVER),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_C_HOSTILE_TAKEOVER), SetDataTip(STR_COMPANY_VIEW_HOSTILE_TAKEOVER_BUTTON, STR_COMPANY_VIEW_HOSTILE_TAKEOVER_TOOLTIP),
EndContainer(),
EndContainer(),
NWidget(NWID_HORIZONTAL), SetPIP(0, 4, 0),
NWidget(NWID_SPACER), SetFill(1, 0),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_C_SELECT_GIVE_MONEY),
@@ -2332,6 +2338,13 @@ struct CompanyWindow : Window
wi->SetDisplayedPlane(plane);
reinit = true;
}
/* Enable/disable 'Hostile Takeover' button. */
plane = ((local || _local_company == COMPANY_SPECTATOR || !c->is_ai || _networking) ? SZSP_NONE : 0);
wi = this->GetWidget<NWidgetStacked>(WID_C_SELECT_HOSTILE_TAKEOVER);
if (plane != wi->shown_plane) {
wi->SetDisplayedPlane(plane);
reinit = true;
}
/* Multiplayer buttons. */
plane = ((!_networking) ? (int)SZSP_NONE : (int)(local ? CWP_MP_C_PWD : CWP_MP_C_JOIN));
@@ -2398,6 +2411,7 @@ struct CompanyWindow : Window
case WID_C_RELOCATE_HQ:
case WID_C_VIEW_INFRASTRUCTURE:
case WID_C_GIVE_MONEY:
case WID_C_HOSTILE_TAKEOVER:
case WID_C_COMPANY_PASSWORD:
case WID_C_COMPANY_JOIN:
size->width = GetStringBoundingBox(STR_COMPANY_VIEW_VIEW_HQ_BUTTON).width;
@@ -2405,6 +2419,7 @@ struct CompanyWindow : Window
size->width = std::max(size->width, GetStringBoundingBox(STR_COMPANY_VIEW_RELOCATE_HQ).width);
size->width = std::max(size->width, GetStringBoundingBox(STR_COMPANY_VIEW_INFRASTRUCTURE_BUTTON).width);
size->width = std::max(size->width, GetStringBoundingBox(STR_COMPANY_VIEW_GIVE_MONEY_BUTTON).width);
size->width = std::max(size->width, GetStringBoundingBox(STR_COMPANY_VIEW_HOSTILE_TAKEOVER_BUTTON).width);
size->width = std::max(size->width, GetStringBoundingBox(STR_COMPANY_VIEW_PASSWORD).width);
size->width = std::max(size->width, GetStringBoundingBox(STR_COMPANY_VIEW_JOIN).width);
size->width += padding.width;
@@ -2600,6 +2615,10 @@ struct CompanyWindow : Window
ShowQueryString(STR_EMPTY, STR_COMPANY_VIEW_GIVE_MONEY_QUERY_CAPTION, 30, this, CS_NUMERAL, QSF_NONE);
break;
case WID_C_HOSTILE_TAKEOVER:
ShowBuyCompanyDialog((CompanyID)this->window_number, true);
break;
case WID_C_COMPANY_PASSWORD:
if (this->window_number == _local_company) ShowNetworkCompanyPasswordWindow(this);
break;
@@ -2697,9 +2716,12 @@ void DirtyCompanyInfrastructureWindows(CompanyID company)
}
struct BuyCompanyWindow : Window {
BuyCompanyWindow(WindowDesc *desc, WindowNumber window_number) : Window(desc)
BuyCompanyWindow(WindowDesc *desc, WindowNumber window_number, bool hostile_takeover) : Window(desc), hostile_takeover(hostile_takeover)
{
this->InitNested(window_number);
const Company *c = Company::Get((CompanyID)this->window_number);
this->company_value = hostile_takeover ? CalculateHostileTakeoverValue(c) : c->bankrupt_value;
}
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
@@ -2712,8 +2734,8 @@ struct BuyCompanyWindow : Window {
case WID_BC_QUESTION:
const Company *c = Company::Get((CompanyID)this->window_number);
SetDParam(0, c->index);
SetDParam(1, c->bankrupt_value);
size->height = GetStringHeight(STR_BUY_COMPANY_MESSAGE, size->width);
SetDParam(1, this->company_value);
size->height = GetStringHeight(this->hostile_takeover ? STR_BUY_COMPANY_HOSTILE_TAKEOVER : STR_BUY_COMPANY_MESSAGE, size->width);
break;
}
}
@@ -2740,8 +2762,8 @@ struct BuyCompanyWindow : Window {
case WID_BC_QUESTION: {
const Company *c = Company::Get((CompanyID)this->window_number);
SetDParam(0, c->index);
SetDParam(1, c->bankrupt_value);
DrawStringMultiLine(r.left, r.right, r.top, r.bottom, STR_BUY_COMPANY_MESSAGE, TC_FROMSTRING, SA_CENTER);
SetDParam(1, this->company_value);
DrawStringMultiLine(r.left, r.right, r.top, r.bottom, this->hostile_takeover ? STR_BUY_COMPANY_HOSTILE_TAKEOVER : STR_BUY_COMPANY_MESSAGE, TC_FROMSTRING, SA_CENTER);
break;
}
}
@@ -2755,10 +2777,29 @@ struct BuyCompanyWindow : Window {
break;
case WID_BC_YES:
Command<CMD_BUY_COMPANY>::Post(STR_ERROR_CAN_T_BUY_COMPANY, (CompanyID)this->window_number);
Command<CMD_BUY_COMPANY>::Post(STR_ERROR_CAN_T_BUY_COMPANY, (CompanyID)this->window_number, this->hostile_takeover);
break;
}
}
/**
* Check on a regular interval if the company value has changed.
*/
IntervalTimer<TimerWindow> rescale_interval = {std::chrono::seconds(3), [this](auto) {
/* Value can't change when in bankruptcy. */
if (!this->hostile_takeover) return;
const Company *c = Company::Get((CompanyID)this->window_number);
auto new_value = CalculateHostileTakeoverValue(c);
if (new_value != this->company_value) {
this->company_value = new_value;
this->ReInit();
}
}};
private:
bool hostile_takeover; ///< Whether the window is showing a hostile takeover.
Money company_value; ///< The value of the company for which the user can buy it.
};
static const NWidgetPart _nested_buy_company_widgets[] = {
@@ -2790,8 +2831,12 @@ static WindowDesc _buy_company_desc(
/**
* Show the query to buy another company.
* @param company The company to buy.
* @param hostile_takeover Whether this is a hostile takeover.
*/
void ShowBuyCompanyDialog(CompanyID company)
void ShowBuyCompanyDialog(CompanyID company, bool hostile_takeover)
{
AllocateWindowDescFront<BuyCompanyWindow>(&_buy_company_desc, company);
auto window = BringWindowToFrontById(WC_BUY_COMPANY, company);
if (window == nullptr) {
new BuyCompanyWindow(&_buy_company_desc, company, hostile_takeover);
}
}