From a1826a043ee583432d687429103f39a038509be8 Mon Sep 17 00:00:00 2001 From: rubidium Date: Sun, 10 Jul 2011 20:23:04 +0000 Subject: [PATCH] (svn r22651) [1.1] -Backport from trunk: - Fix: When closing an AI company the local player cheated to, we need to cheat him to another company [FS#4654] (r22624, r22623) - Fix: When closing down companies their shares in other companies must be sold even if share trading is disabled at that point of time (r22622) - Fix: When asking the user to confirm an unsafe unpausing, there is no need to execute a command if 'no' is choosed. This also prevents crashing when clicking unpause while the confirm window is shown (r22621) - Fix: Enforce refit orders to be 'always go to depot' orders; service-only and stop-in-depot orders make no sense with refitting [FS#4651] (r22620) - Fix: Consider the size of the vehicle sprite for the lineheight in the company GUI. This also makes the widget containing the sprite not skip drawing it, if the bounds of the widget are outside of the drawing area though the sprite actually needs drawing [FS#4662] (r22619) --- src/company_gui.cpp | 17 +++++++++++++++-- src/economy.cpp | 38 +++++++++++++++++++++++--------------- src/gfx.cpp | 8 +++++++- src/gfx_func.h | 2 +- src/misc_cmd.cpp | 4 +++- src/order_cmd.cpp | 8 ++++++++ src/order_gui.cpp | 3 +++ 7 files changed, 60 insertions(+), 20 deletions(-) diff --git a/src/company_gui.cpp b/src/company_gui.cpp index 7c45f3fed3..2c88ea2886 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -1824,6 +1824,15 @@ struct CompanyWindow : Window virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) { switch (widget) { + case CW_WIDGET_DESC_COLOUR_SCHEME_EXAMPLE: { + Point offset; + Dimension d = GetSpriteSize(SPR_VEH_BUS_SW_VIEW, &offset); + d.width -= offset.x; + d.height -= offset.y; + *size = maxdim(*size, d); + break; + } + case CW_WIDGET_DESC_COMPANY_VALUE: SetDParam(0, INT64_MAX); // Arguably the maximum company value size->width = GetStringBoundingBox(STR_COMPANY_VIEW_COMPANY_VALUE).width; @@ -1869,9 +1878,13 @@ struct CompanyWindow : Window DrawStringMultiLine(r.left, r.right, r.top, r.bottom, STR_COMPANY_VIEW_PRESIDENT_MANAGER_TITLE, TC_FROMSTRING, SA_CENTER); break; - case CW_WIDGET_DESC_COLOUR_SCHEME_EXAMPLE: - DrawSprite(SPR_VEH_BUS_SW_VIEW, COMPANY_SPRITE_COLOUR(c->index), (r.left + r.right) / 2, r.top + FONT_HEIGHT_NORMAL / 10); + case CW_WIDGET_DESC_COLOUR_SCHEME_EXAMPLE: { + Point offset; + Dimension d = GetSpriteSize(SPR_VEH_BUS_SW_VIEW, &offset); + d.height -= offset.y; + DrawSprite(SPR_VEH_BUS_SW_VIEW, COMPANY_SPRITE_COLOUR(c->index), r.left - offset.x, (r.top + r.bottom - d.height) / 2 - offset.y); break; + } case CW_WIDGET_DESC_VEHICLE_COUNTS: { uint amounts[4]; diff --git a/src/economy.cpp b/src/economy.cpp index 584eea7c7f..f99c73a7f8 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -292,6 +292,21 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) /* In all cases, make spectators of clients connected to that company */ if (_networking) NetworkClientsToSpectators(old_owner); #endif /* ENABLE_NETWORK */ + if (old_owner == _local_company) { + /* Single player cheated to AI company. + * There are no specatators in single player, so we must pick some other company. */ + assert(!_networking); + Backup cur_company(_current_company, FILE_LINE); + Company *c; + FOR_ALL_COMPANIES(c) { + if (c->index != old_owner) { + SetLocalCompany(c->index); + break; + } + } + cur_company.Restore(); + assert(old_owner != _local_company); + } Town *t; @@ -306,7 +321,7 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) for (i = 0; i < 4; i++) { if (c->share_owners[i] == old_owner) { /* Sell his shares */ - CommandCost res = DoCommand(0, c->index, 0, DC_EXEC, CMD_SELL_SHARE_IN_COMPANY); + CommandCost res = DoCommand(0, c->index, 0, DC_EXEC | DC_BANKRUPT, CMD_SELL_SHARE_IN_COMPANY); /* Because we are in a DoCommand, we can't just execute another one and * expect the money to be removed. We need to do it ourself! */ SubtractMoneyFromCompany(res); @@ -321,7 +336,7 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) cur_company2.Change(c->share_owners[i]); if (_current_company != INVALID_OWNER) { /* Sell the shares */ - CommandCost res = DoCommand(0, old_owner, 0, DC_EXEC, CMD_SELL_SHARE_IN_COMPANY); + CommandCost res = DoCommand(0, old_owner, 0, DC_EXEC | DC_BANKRUPT, CMD_SELL_SHARE_IN_COMPANY); /* Because we are in a DoCommand, we can't just execute another one and * expect the money to be removed. We need to do it ourself! */ SubtractMoneyFromCompany(res); @@ -1500,16 +1515,6 @@ static void DoAcquireCompany(Company *c) owner->current_loan += c->current_loan; } - Money value = CalculateCompanyValue(c) >> 2; - Backup cur_company(_current_company, FILE_LINE); - for (int i = 0; i != 4; i++) { - if (c->share_owners[i] != COMPANY_SPECTATOR) { - cur_company.Change(c->share_owners[i]); - SubtractMoneyFromCompany(CommandCost(EXPENSES_OTHER, -value)); - } - } - cur_company.Restore(); - if (c->is_ai) AI::Stop(c->index); DeleteCompanyWindows(ci); @@ -1589,9 +1594,12 @@ CommandCost CmdSellShareInCompany(TileIndex tile, DoCommandFlag flags, uint32 p1 CompanyID target_company = (CompanyID)p1; Company *c = Company::GetIfValid(target_company); - /* Check if selling shares is allowed (protection against modified clients) - * Cannot sell own shares */ - if (c == NULL || !_settings_game.economy.allow_shares || _current_company == target_company) return CMD_ERROR; + /* Cannot sell own shares */ + if (c == NULL || _current_company == target_company) return CMD_ERROR; + + /* Check if selling shares is allowed (protection against modified clients). + * However, we must sell shares of companies being closed down. */ + if (!_settings_game.economy.allow_shares && !(flags & DC_BANKRUPT)) return CMD_ERROR; /* Those lines are here for network-protection (clients can be slow) */ if (GetAmountOwnedBy(c, _current_company) == 0) return CommandCost(); diff --git a/src/gfx.cpp b/src/gfx.cpp index 7fad4f15b8..259bb3bbe9 100644 --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -1114,13 +1114,19 @@ skip_cont:; /** * Get the size of a sprite. * @param sprid Sprite to examine. + * @param [out] offset Optionally returns the sprite position offset. * @return Sprite size in pixels. * @note The size assumes (0, 0) as top-left coordinate and ignores any part of the sprite drawn at the left or above that position. */ -Dimension GetSpriteSize(SpriteID sprid) +Dimension GetSpriteSize(SpriteID sprid, Point *offset) { const Sprite *sprite = GetSprite(sprid, ST_NORMAL); + if (offset != NULL) { + offset->x = sprite->x_offs; + offset->y = sprite->y_offs; + } + Dimension d; d.width = max(0, sprite->x_offs + sprite->width); d.height = max(0, sprite->y_offs + sprite->height); diff --git a/src/gfx_func.h b/src/gfx_func.h index 9a0c3e63f1..9d20de212a 100644 --- a/src/gfx_func.h +++ b/src/gfx_func.h @@ -88,7 +88,7 @@ static const int DRAW_STRING_BUFFER = 2048; void RedrawScreenRect(int left, int top, int right, int bottom); void GfxScroll(int left, int top, int width, int height, int xo, int yo); -Dimension GetSpriteSize(SpriteID sprid); +Dimension GetSpriteSize(SpriteID sprid, Point *offset = NULL); void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub = NULL); /** How to align the to-be drawn text. */ diff --git a/src/misc_cmd.cpp b/src/misc_cmd.cpp index 1f6ee839a6..ff16c92726 100644 --- a/src/misc_cmd.cpp +++ b/src/misc_cmd.cpp @@ -125,7 +125,9 @@ CommandCost CmdDecreaseLoan(TileIndex tile, DoCommandFlag flags, uint32 p1, uint */ static void AskUnsafeUnpauseCallback(Window *w, bool confirmed) { - DoCommandP(0, PM_PAUSED_ERROR, confirmed ? 0 : 1, CMD_PAUSE); + if (confirmed) { + DoCommandP(0, PM_PAUSED_ERROR, 0, CMD_PAUSE); + } } /** diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index 9737a57cea..88a17d9427 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -1280,11 +1280,13 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 case DA_SERVICE: order->SetDepotOrderType((OrderDepotTypeFlags)(order->GetDepotOrderType() | ODTFB_SERVICE)); order->SetDepotActionType((OrderDepotActionFlags)(order->GetDepotActionType() & ~ODATFB_HALT)); + order->SetRefit(CT_NO_REFIT); break; case DA_STOP: order->SetDepotOrderType((OrderDepotTypeFlags)(order->GetDepotOrderType() & ~ODTFB_SERVICE)); order->SetDepotActionType((OrderDepotActionFlags)(order->GetDepotActionType() | ODATFB_HALT)); + order->SetRefit(CT_NO_REFIT); break; default: @@ -1528,6 +1530,12 @@ CommandCost CmdOrderRefit(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 if (flags & DC_EXEC) { order->SetRefit(cargo, subtype); + /* Make the depot order an 'always go' order. */ + if (cargo != CT_NO_REFIT) { + order->SetDepotOrderType((OrderDepotTypeFlags)(order->GetDepotOrderType() & ~ODTFB_SERVICE)); + order->SetDepotActionType((OrderDepotActionFlags)(order->GetDepotActionType() & ~ODATFB_HALT)); + } + for (Vehicle *u = v->FirstShared(); u != NULL; u = u->NextShared()) { /* Update any possible open window of the vehicle */ InvalidateVehicleOrder(u, -2); diff --git a/src/order_gui.cpp b/src/order_gui.cpp index b278ed6da6..65071d2d93 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -980,6 +980,9 @@ public: this->EnableWidget(ORDER_WIDGET_NON_STOP); this->SetWidgetLoweredState(ORDER_WIDGET_NON_STOP, order->GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS); } + /* Disable refit button if the order is no 'always go' order. + * However, keep the service button enabled for refit-orders to allow clearing refits (without knowing about ctrl). */ + this->SetWidgetDisabledState(ORDER_WIDGET_REFIT, (order->GetDepotOrderType() & ODTFB_SERVICE) || (order->GetDepotActionType() & ODATFB_HALT)); this->SetWidgetLoweredState(ORDER_WIDGET_SERVICE, order->GetDepotOrderType() & ODTFB_SERVICE); break;