1
0
Fork 0

(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)
release/1.0
rubidium 2010-08-09 21:53:44 +00:00
parent 2da34ec3d6
commit 0ac197a0c5
8 changed files with 77 additions and 24 deletions

View File

@ -539,6 +539,25 @@ void InitializeCompanies()
_cur_company_tick_index = 0; _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. * Handle the bankruptcy take over of a company.
* Companies going bankrupt will ask the other companies in order of their * 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) { FOR_ALL_COMPANIES(c2) {
if (c2->bankrupt_asked == 0 && // Don't ask companies going bankrupt themselves if (c2->bankrupt_asked == 0 && // Don't ask companies going bankrupt themselves
!HasBit(c->bankrupt_asked, c2->index) && !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_performance = c2->old_economy[1].performance_history;
best = c2; best = c2;
} }

View File

@ -16,6 +16,7 @@
#include "tile_type.h" #include "tile_type.h"
#include "gfx_type.h" #include "gfx_type.h"
bool MayCompanyTakeOver(CompanyID cbig, CompanyID small);
void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner); void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner);
void GetNameOfOwner(Owner owner, TileIndex tile); void GetNameOfOwner(Owner owner, TileIndex tile);
void SetLocalCompany(CompanyID new_company); void SetLocalCompany(CompanyID new_company);

View File

@ -20,7 +20,7 @@
#include "network/network_gui.h" #include "network/network_gui.h"
#include "network/network_func.h" #include "network/network_func.h"
#include "economy_func.h" #include "economy_func.h"
#include "vehicle_base.h" #include "vehicle_func.h"
#include "newgrf.h" #include "newgrf.h"
#include "company_manager_face.h" #include "company_manager_face.h"
#include "strings_func.h" #include "strings_func.h"
@ -1844,19 +1844,10 @@ struct CompanyWindow : Window
break; break;
case CW_WIDGET_DESC_VEHICLE_COUNTS: { 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; 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) { if (amounts[0] + amounts[1] + amounts[2] + amounts[3] == 0) {
DrawString(r.left, r.right, y, STR_COMPANY_VIEW_VEHICLES_NONE); DrawString(r.left, r.right, y, STR_COMPANY_VIEW_VEHICLES_NONE);
} else { } else {

View File

@ -1501,8 +1501,12 @@ CommandCost CmdBuyShareInCompany(TileIndex tile, DoCommandFlag flags, uint32 p1,
/* Those lines are here for network-protection (clients can be slow) */ /* Those lines are here for network-protection (clients can be slow) */
if (GetAmountOwnedBy(c, COMPANY_SPECTATOR) == 0) return cost; 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) {
if (GetAmountOwnedBy(c, COMPANY_SPECTATOR) == 1 && !c->is_ai) return cost; 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); cost.AddCost(CalculateCompanyValue(c) >> 2);
if (flags & DC_EXEC) { 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 */ /* Do not allow companies to take over themselves */
if (target_company == _current_company) return CMD_ERROR; 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. */ /* Get the cost here as the company is deleted in DoAcquireCompany. */
CommandCost cost(EXPENSES_OTHER, c->bankrupt_value); CommandCost cost(EXPENSES_OTHER, c->bankrupt_value);

View File

@ -1945,7 +1945,7 @@ static void DrawTrackBitsOverlay(TileInfo *ti, TrackBits track, const RailtypeIn
} }
DrawTrackSprite(ground + offset, PAL_NONE, ti, fake_slope); 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); DrawTrackSprite(overlay + offset, PALETTE_CRASH, ti, fake_slope);
} }
} }

View File

@ -531,6 +531,21 @@ uint CountVehiclesInChain(const Vehicle *v)
return count; 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 /** Check if a vehicle is counted in num_engines in each company struct
* @return true if the vehicle is counted in num_engines * @return true if the vehicle is counted in num_engines
*/ */
@ -1239,8 +1254,28 @@ UnitID FreeUnitIDGenerator::NextID()
return this->curid; 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) 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); FreeUnitIDGenerator gen(type, _current_company);
return gen.NextID(); return gen.NextID();

View File

@ -29,6 +29,7 @@ typedef Vehicle *VehicleFromPosProc(Vehicle *v, void *data);
void VehicleServiceInDepot(Vehicle *v); void VehicleServiceInDepot(Vehicle *v);
uint CountVehiclesInChain(const Vehicle *v); uint CountVehiclesInChain(const Vehicle *v);
void CountCompanyVehicles(CompanyID cid, uint counts[4]);
void FindVehicleOnPos(TileIndex tile, void *data, VehicleFromPosProc *proc); void FindVehicleOnPos(TileIndex tile, void *data, VehicleFromPosProc *proc);
void FindVehicleOnPosXY(int x, int y, void *data, VehicleFromPosProc *proc); void FindVehicleOnPosXY(int x, int y, void *data, VehicleFromPosProc *proc);
bool HasVehicleOnPos(TileIndex tile, void *data, VehicleFromPosProc *proc); bool HasVehicleOnPos(TileIndex tile, void *data, VehicleFromPosProc *proc);

View File

@ -1720,27 +1720,25 @@ NWidgetLeaf::NWidgetLeaf(WidgetType tp, Colours colour, int index, uint16 data,
break; break;
case WWT_PUSHBTN: case WWT_PUSHBTN:
this->SetFill(0, 0);
break;
case WWT_IMGBTN: case WWT_IMGBTN:
case WWT_PUSHIMGBTN: case WWT_PUSHIMGBTN:
case WWT_IMGBTN_2: case WWT_IMGBTN_2:
this->SetFill(0, 0);
break;
case WWT_TEXTBTN: case WWT_TEXTBTN:
case WWT_PUSHTXTBTN: case WWT_PUSHTXTBTN:
case WWT_TEXTBTN_2: case WWT_TEXTBTN_2:
case WWT_LABEL: case WWT_LABEL:
case WWT_TEXT: case WWT_TEXT:
case WWT_MATRIX: case WWT_MATRIX:
case WWT_EDITBOX:
case NWID_BUTTON_DROPDOWN: case NWID_BUTTON_DROPDOWN:
case NWID_BUTTON_ARROW: case NWID_BUTTON_ARROW:
this->SetFill(0, 0); this->SetFill(0, 0);
break; break;
case WWT_EDITBOX:
this->SetMinimalSize(10, 0);
this->SetFill(0, 0);
break;
case WWT_SCROLLBAR: case WWT_SCROLLBAR:
case WWT_SCROLL2BAR: case WWT_SCROLL2BAR:
this->SetFill(0, 1); this->SetFill(0, 1);