From 0ac197a0c5616afbca86c26acd160393db147fee Mon Sep 17 00:00:00 2001 From: rubidium Date: Mon, 9 Aug 2010 21:53:44 +0000 Subject: [PATCH] (svn r20431) [1.0] -Backport from trunk: - Fix: PBS reservations were always displayed on halftile foundations if the railtype uses overlays [FS#4013] (r20408) - Fix: Make the default minimum width for editboxes 10 pixels to prevent crashes [FS#4010] (r20394) - Fix: Prevent buying more vehicles than allowed or buying companies when you'd get too many vehicles [FS#3993] (r20393, r20392, r20391, r20390) --- src/company_cmd.cpp | 22 +++++++++++++++++++++- src/company_func.h | 1 + src/company_gui.cpp | 17 ++++------------- src/economy.cpp | 11 +++++++++-- src/rail_cmd.cpp | 2 +- src/vehicle.cpp | 35 +++++++++++++++++++++++++++++++++++ src/vehicle_func.h | 1 + src/widget.cpp | 12 +++++------- 8 files changed, 77 insertions(+), 24 deletions(-) diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index c59a64ca11..dcd77c8492 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -539,6 +539,25 @@ void InitializeCompanies() _cur_company_tick_index = 0; } +/** + * May company \a cbig buy company \a csmall? + * @param cbig Company buying \a csmall. + * @param csmall Company getting bought. + * @return Return \c true if it is allowed. + */ +bool MayCompanyTakeOver(CompanyID cbig, CompanyID csmall) +{ + uint big_counts[4], small_counts[4]; + CountCompanyVehicles(cbig, big_counts); + CountCompanyVehicles(csmall, small_counts); + + /* Do the combined vehicle counts stay within the limits? */ + return big_counts[VEH_TRAIN] + small_counts[VEH_TRAIN] <= _settings_game.vehicle.max_trains && + big_counts[VEH_ROAD] + small_counts[VEH_ROAD] <= _settings_game.vehicle.max_roadveh && + big_counts[VEH_SHIP] + small_counts[VEH_SHIP] <= _settings_game.vehicle.max_ships && + big_counts[VEH_AIRCRAFT] + small_counts[VEH_AIRCRAFT] <= _settings_game.vehicle.max_aircraft; +} + /** * Handle the bankruptcy take over of a company. * Companies going bankrupt will ask the other companies in order of their @@ -578,7 +597,8 @@ static void HandleBankruptcyTakeover(Company *c) FOR_ALL_COMPANIES(c2) { if (c2->bankrupt_asked == 0 && // Don't ask companies going bankrupt themselves !HasBit(c->bankrupt_asked, c2->index) && - best_performance < c2->old_economy[1].performance_history) { + best_performance < c2->old_economy[1].performance_history && + MayCompanyTakeOver(c2->index, c->index)) { best_performance = c2->old_economy[1].performance_history; best = c2; } diff --git a/src/company_func.h b/src/company_func.h index 4b520ce7bb..e01c91da95 100644 --- a/src/company_func.h +++ b/src/company_func.h @@ -16,6 +16,7 @@ #include "tile_type.h" #include "gfx_type.h" +bool MayCompanyTakeOver(CompanyID cbig, CompanyID small); void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner); void GetNameOfOwner(Owner owner, TileIndex tile); void SetLocalCompany(CompanyID new_company); diff --git a/src/company_gui.cpp b/src/company_gui.cpp index d97ed0612e..8e65f55520 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -20,7 +20,7 @@ #include "network/network_gui.h" #include "network/network_func.h" #include "economy_func.h" -#include "vehicle_base.h" +#include "vehicle_func.h" #include "newgrf.h" #include "company_manager_face.h" #include "strings_func.h" @@ -1844,19 +1844,10 @@ struct CompanyWindow : Window break; case CW_WIDGET_DESC_VEHICLE_COUNTS: { - uint amounts[] = { 0, 0, 0, 0 }; + uint amounts[4]; + CountCompanyVehicles((CompanyID)this->window_number, amounts); + int y = r.top; - - const Vehicle *v; - FOR_ALL_VEHICLES(v) { - if (v->owner == c->index) { - if (v->IsPrimaryVehicle()) { - assert((size_t)v->type < lengthof(amounts)); - amounts[v->type]++; - } - } - } - if (amounts[0] + amounts[1] + amounts[2] + amounts[3] == 0) { DrawString(r.left, r.right, y, STR_COMPANY_VIEW_VEHICLES_NONE); } else { diff --git a/src/economy.cpp b/src/economy.cpp index 6042e9816f..b1551dfc24 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -1501,8 +1501,12 @@ CommandCost CmdBuyShareInCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, /* Those lines are here for network-protection (clients can be slow) */ if (GetAmountOwnedBy(c, COMPANY_SPECTATOR) == 0) return cost; - /* We can not buy out a real company (temporarily). TODO: well, enable it obviously */ - if (GetAmountOwnedBy(c, COMPANY_SPECTATOR) == 1 && !c->is_ai) return cost; + if (GetAmountOwnedBy(c, COMPANY_SPECTATOR) == 1) { + if (!c->is_ai) return cost; // We can not buy out a real company (temporarily). TODO: well, enable it obviously. + + if (GetAmountOwnedBy(c, _current_company) == 3 && !MayCompanyTakeOver(_current_company, target_company)) return_cmd_error(STR_ERROR_TOO_MANY_VEHICLES_IN_GAME); + } + cost.AddCost(CalculateCompanyValue(c) >> 2); if (flags & DC_EXEC) { @@ -1583,6 +1587,9 @@ CommandCost CmdBuyCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 /* Do not allow companies to take over themselves */ if (target_company == _current_company) return CMD_ERROR; + /* Disable taking over when not allowed. */ + if (!MayCompanyTakeOver(_current_company, target_company)) return CMD_ERROR; + /* Get the cost here as the company is deleted in DoAcquireCompany. */ CommandCost cost(EXPENSES_OTHER, c->bankrupt_value); diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 5a64edd4a0..4a8fda85a9 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -1945,7 +1945,7 @@ static void DrawTrackBitsOverlay(TileInfo *ti, TrackBits track, const RailtypeIn } DrawTrackSprite(ground + offset, PAL_NONE, ti, fake_slope); - if (HasReservedTracks(ti->tile, track)) { + if (_settings_client.gui.show_track_reservation && HasReservedTracks(ti->tile, track)) { DrawTrackSprite(overlay + offset, PALETTE_CRASH, ti, fake_slope); } } diff --git a/src/vehicle.cpp b/src/vehicle.cpp index f027a5fa26..81a5fe22ed 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -531,6 +531,21 @@ uint CountVehiclesInChain(const Vehicle *v) return count; } +/** + * Count the number of vehicles of a company. + * @param c Company owning the vehicles. + * @param [out] counts Array of counts. Contains the vehicle count ordered by type afterwards. + */ +void CountCompanyVehicles(CompanyID cid, uint counts[4]) +{ + for (uint i = 0; i < 4; i++) counts[i] = 0; + + const Vehicle *v; + FOR_ALL_VEHICLES(v) { + if (v->owner == cid && v->IsPrimaryVehicle()) counts[v->type]++; + } +} + /** Check if a vehicle is counted in num_engines in each company struct * @return true if the vehicle is counted in num_engines */ @@ -1239,8 +1254,28 @@ UnitID FreeUnitIDGenerator::NextID() return this->curid; } +/** + * Get an unused unit number for a vehicle (if allowed). + * @param type Type of vehicle + * @return A unused unit number for the given type of vehicle if it is allowed to build one, else \c UINT16_MAX. + */ UnitID GetFreeUnitNumber(VehicleType type) { + /* Check whether it is allowed to build another vehicle. */ + uint max_veh; + switch (type) { + case VEH_TRAIN: max_veh = _settings_game.vehicle.max_trains; break; + case VEH_ROAD: max_veh = _settings_game.vehicle.max_roadveh; break; + case VEH_SHIP: max_veh = _settings_game.vehicle.max_ships; break; + case VEH_AIRCRAFT: max_veh = _settings_game.vehicle.max_aircraft; break; + default: NOT_REACHED(); + } + + uint amounts[4]; + CountCompanyVehicles(_current_company, amounts); + assert((uint)type < lengthof(amounts)); + if (amounts[type] >= max_veh) return UINT16_MAX; // Currently already at the limit, no room to make a new one. + FreeUnitIDGenerator gen(type, _current_company); return gen.NextID(); diff --git a/src/vehicle_func.h b/src/vehicle_func.h index 7aa48bb3e7..efb217b993 100644 --- a/src/vehicle_func.h +++ b/src/vehicle_func.h @@ -29,6 +29,7 @@ typedef Vehicle *VehicleFromPosProc(Vehicle *v, void *data); void VehicleServiceInDepot(Vehicle *v); uint CountVehiclesInChain(const Vehicle *v); +void CountCompanyVehicles(CompanyID cid, uint counts[4]); void FindVehicleOnPos(TileIndex tile, void *data, VehicleFromPosProc *proc); void FindVehicleOnPosXY(int x, int y, void *data, VehicleFromPosProc *proc); bool HasVehicleOnPos(TileIndex tile, void *data, VehicleFromPosProc *proc); diff --git a/src/widget.cpp b/src/widget.cpp index 33977b20b6..0aa988d622 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -1720,27 +1720,25 @@ NWidgetLeaf::NWidgetLeaf(WidgetType tp, Colours colour, int index, uint16 data, break; case WWT_PUSHBTN: - this->SetFill(0, 0); - break; - case WWT_IMGBTN: case WWT_PUSHIMGBTN: case WWT_IMGBTN_2: - this->SetFill(0, 0); - break; - case WWT_TEXTBTN: case WWT_PUSHTXTBTN: case WWT_TEXTBTN_2: case WWT_LABEL: case WWT_TEXT: case WWT_MATRIX: - case WWT_EDITBOX: case NWID_BUTTON_DROPDOWN: case NWID_BUTTON_ARROW: this->SetFill(0, 0); break; + case WWT_EDITBOX: + this->SetMinimalSize(10, 0); + this->SetFill(0, 0); + break; + case WWT_SCROLLBAR: case WWT_SCROLL2BAR: this->SetFill(0, 1);