From 85b19944f437302e994820fde5e2387aa3bacb8c Mon Sep 17 00:00:00 2001 From: translators Date: Thu, 29 Oct 2015 17:45:08 +0000 Subject: [PATCH 01/13] (svn r27416) -Update from WebTranslator v3.0: welsh - 2 changes by kazzie --- src/lang/welsh.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lang/welsh.txt b/src/lang/welsh.txt index bc4c18db46..d25dfff6c7 100644 --- a/src/lang/welsh.txt +++ b/src/lang/welsh.txt @@ -284,8 +284,8 @@ STR_SORT_BY_PRODUCTION :Cynyrch STR_SORT_BY_TYPE :Math STR_SORT_BY_TRANSPORTED :Wedi'i gludo STR_SORT_BY_NUMBER :Rhif -STR_SORT_BY_PROFIT_LAST_YEAR :Elw eleni -STR_SORT_BY_PROFIT_THIS_YEAR :Elw llynedd +STR_SORT_BY_PROFIT_LAST_YEAR :Elw llynedd +STR_SORT_BY_PROFIT_THIS_YEAR :Elw eleni STR_SORT_BY_AGE :Oed STR_SORT_BY_RELIABILITY :Dibynadwyedd STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :Cyfanswm Gallu Cludo fesul y math o lwyth From d20a116dfdf8a43bc0f5182456863dcaa8b28c63 Mon Sep 17 00:00:00 2001 From: frosch Date: Thu, 29 Oct 2015 19:23:21 +0000 Subject: [PATCH 02/13] (svn r27417) -Doc: ScaleGUITrad (adf88) --- src/zoom_func.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/zoom_func.h b/src/zoom_func.h index 1cb3d0c486..da266e35c6 100644 --- a/src/zoom_func.h +++ b/src/zoom_func.h @@ -67,7 +67,7 @@ static inline int UnScaleByZoomLower(int value, ZoomLevel zoom) /** * Short-hand to apply GUI zoom level. * @param value Pixel amount at #ZOOM_LVL_BEGIN (full zoom in). - * @return value Pixel amount at #ZOOM_LVL_GUI. + * @return Pixel amount at #ZOOM_LVL_GUI (current interface size). */ static inline int UnScaleGUI(int value) { @@ -76,8 +76,8 @@ static inline int UnScaleGUI(int value) /** * Scale traditional pixel dimensions to GUI zoom level. - * @param value Pixel amount at 1x zoom level. - * @return value Pixel amount at #ZOOM_LVL_GUI. + * @param value Pixel amount at #ZOOM_LVL_BASE (traditional "normal" interface size). + * @return Pixel amount at #ZOOM_LVL_GUI (current interface size). */ static inline int ScaleGUITrad(int value) { From 147b53fbff263b707423080b5f09731d06b2a194 Mon Sep 17 00:00:00 2001 From: frosch Date: Fri, 30 Oct 2015 16:18:03 +0000 Subject: [PATCH 03/13] (svn r27418) -Fix [FS#6329] [FS#6379]: Desync due to incorrect storage of segments with different railtype in the YAPF cache. (JGR) --- src/pathfinder/follow_track.hpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/pathfinder/follow_track.hpp b/src/pathfinder/follow_track.hpp index a16512bc06..9f19b029c0 100644 --- a/src/pathfinder/follow_track.hpp +++ b/src/pathfinder/follow_track.hpp @@ -144,7 +144,12 @@ struct CFollowTrackT * missing road bit, or inability to connect the * different bits due to slopes. */ if (IsRoadTT() && !IsTram() && TryReverse()) return true; - m_err = EC_NO_WAY; + + /* CanEnterNewTile already set a reason. + * Do NOT overwrite it (important for example for EC_RAIL_TYPE). + * Only set a reason if CanEnterNewTile was not called */ + if (m_new_td_bits == TRACKDIR_BIT_NONE) m_err = EC_NO_WAY; + return false; } if (!Allow90degTurns()) { From 51787a34655d182e9abb24057ff6add76fd1c9d9 Mon Sep 17 00:00:00 2001 From: frosch Date: Fri, 30 Oct 2015 16:18:39 +0000 Subject: [PATCH 04/13] (svn r27419) -Fix [FS#6369]: CmdSellRailWagon did not revert all actions properly when no orderlist could be allocated. (Juanjo) --- src/train_cmd.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 8f20973b35..6f2feeaab7 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -1386,13 +1386,15 @@ CommandCost CmdSellRailWagon(DoCommandFlag flags, Vehicle *t, uint16 data, uint3 return ret; } - CommandCost cost(EXPENSES_NEW_VEHICLES); - for (Train *t = sell_head; t != NULL; t = t->Next()) cost.AddCost(-t->value); - if (first->orders.list == NULL && !OrderList::CanAllocateItem()) { + /* Restore the train we had. */ + RestoreTrainBackup(original); return_cmd_error(STR_ERROR_NO_MORE_SPACE_FOR_ORDERS); } + CommandCost cost(EXPENSES_NEW_VEHICLES); + for (Train *t = sell_head; t != NULL; t = t->Next()) cost.AddCost(-t->value); + /* do it? */ if (flags & DC_EXEC) { /* First normalise the sub types of the chain. */ From 49a18025f8936fdc6c2df6f6c3ada6a151bed6d4 Mon Sep 17 00:00:00 2001 From: frosch Date: Fri, 30 Oct 2015 16:19:09 +0000 Subject: [PATCH 05/13] (svn r27420) -Fix [FS#6362]: GrowTownAtRoad sometimes returned false, even when a house was built. (_dp_) --- src/town_cmd.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index ea44603b0c..ee2828ad7a 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -1378,13 +1378,12 @@ static bool GrowTownAtRoad(Town *t, TileIndex tile) /* Try to grow the town from this point */ GrowTownInTile(&tile, cur_rb, target_dir, t); + if (_grow_town_result == GROWTH_SUCCEED) return true; /* Exclude the source position from the bitmask * and return if no more road blocks available */ if (IsValidDiagDirection(target_dir)) cur_rb &= ~DiagDirToRoadBits(ReverseDiagDir(target_dir)); - if (cur_rb == ROAD_NONE) { - return _grow_town_result == GROWTH_SUCCEED; - } + if (cur_rb == ROAD_NONE) return false; if (IsTileType(tile, MP_TUNNELBRIDGE)) { /* Only build in the direction away from the tunnel or bridge. */ @@ -1419,7 +1418,7 @@ static bool GrowTownAtRoad(Town *t, TileIndex tile) /* Max number of times is checked. */ } while (--_grow_town_result >= 0); - return _grow_town_result == GROWTH_SUCCEED - 1; + return false; } /** From 7be7851b947675dba3a6891139d207bbc16089ab Mon Sep 17 00:00:00 2001 From: frosch Date: Fri, 30 Oct 2015 16:19:33 +0000 Subject: [PATCH 06/13] (svn r27421) -Fix [FS#6265]: Consider text and icon sizes when drawing the client list. (_dp_) --- src/network/network_gui.cpp | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index 013b375bda..795d28e139 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -1863,7 +1863,9 @@ struct NetworkClientListWindow : Window { int selected_item; uint server_client_width; - uint company_icon_width; + uint line_height; + + Dimension icon_size; NetworkClientListWindow(WindowDesc *desc, WindowNumber window_number) : Window(desc), @@ -1885,7 +1887,7 @@ struct NetworkClientListWindow : Window { if (ci->client_playas != COMPANY_INACTIVE_CLIENT) num++; } - num *= FONT_HEIGHT_NORMAL; + num *= this->line_height; int diff = (num + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM) - (this->GetWidget(WID_CL_PANEL)->current_y); /* If height is changed */ @@ -1901,7 +1903,8 @@ struct NetworkClientListWindow : Window { if (widget != WID_CL_PANEL) return; this->server_client_width = max(GetStringBoundingBox(STR_NETWORK_SERVER).width, GetStringBoundingBox(STR_NETWORK_CLIENT).width) + WD_FRAMERECT_RIGHT; - this->company_icon_width = GetSpriteSize(SPR_COMPANY_ICON).width + WD_FRAMERECT_LEFT; + this->icon_size = GetSpriteSize(SPR_COMPANY_ICON); + this->line_height = max(this->icon_size.height + 2U, (uint)FONT_HEIGHT_NORMAL); uint width = 100; // Default width const NetworkClientInfo *ci; @@ -1909,7 +1912,7 @@ struct NetworkClientListWindow : Window { width = max(width, GetStringBoundingBox(ci->client_name).width); } - size->width = WD_FRAMERECT_LEFT + this->server_client_width + this->company_icon_width + width + WD_FRAMERECT_RIGHT; + size->width = WD_FRAMERECT_LEFT + this->server_client_width + this->icon_size.width + WD_FRAMERECT_LEFT + width + WD_FRAMERECT_RIGHT; } virtual void OnPaint() @@ -1925,11 +1928,13 @@ struct NetworkClientListWindow : Window { if (widget != WID_CL_PANEL) return; bool rtl = _current_text_dir == TD_RTL; - int icon_y_offset = 1 + (FONT_HEIGHT_NORMAL - 10) / 2; + int icon_offset = (this->line_height - icon_size.height) / 2; + int text_offset = (this->line_height - FONT_HEIGHT_NORMAL) / 2; + uint y = r.top + WD_FRAMERECT_TOP; uint left = r.left + WD_FRAMERECT_LEFT; uint right = r.right - WD_FRAMERECT_RIGHT; - uint type_icon_width = this->server_client_width + this->company_icon_width; + uint type_icon_width = this->server_client_width + this->icon_size.width + WD_FRAMERECT_LEFT; uint type_left = rtl ? right - this->server_client_width : left; @@ -1943,24 +1948,24 @@ struct NetworkClientListWindow : Window { FOR_ALL_CLIENT_INFOS(ci) { TextColour colour; if (this->selected_item == i++) { // Selected item, highlight it - GfxFillRect(r.left + 1, y, r.right - 1, y + FONT_HEIGHT_NORMAL - 1, PC_BLACK); + GfxFillRect(r.left + 1, y, r.right - 1, y + this->line_height - 1, PC_BLACK); colour = TC_WHITE; } else { colour = TC_BLACK; } if (ci->client_id == CLIENT_ID_SERVER) { - DrawString(type_left, type_right, y, STR_NETWORK_SERVER, colour); + DrawString(type_left, type_right, y + text_offset, STR_NETWORK_SERVER, colour); } else { - DrawString(type_left, type_right, y, STR_NETWORK_CLIENT, colour); + DrawString(type_left, type_right, y + text_offset, STR_NETWORK_CLIENT, colour); } /* Filter out spectators */ - if (Company::IsValidID(ci->client_playas)) DrawCompanyIcon(ci->client_playas, icon_left, y + icon_y_offset); + if (Company::IsValidID(ci->client_playas)) DrawCompanyIcon(ci->client_playas, icon_left, y + icon_offset); - DrawString(name_left, name_right, y, ci->client_name, colour); + DrawString(name_left, name_right, y + text_offset, ci->client_name, colour); - y += FONT_HEIGHT_NORMAL; + y += line_height; } } @@ -1993,7 +1998,7 @@ struct NetworkClientListWindow : Window { pt.y -= this->GetWidget(WID_CL_PANEL)->pos_y; int item = -1; if (IsInsideMM(pt.y, WD_FRAMERECT_TOP, this->GetWidget(WID_CL_PANEL)->current_y - WD_FRAMERECT_BOTTOM)) { - item = (pt.y - WD_FRAMERECT_TOP) / FONT_HEIGHT_NORMAL; + item = (pt.y - WD_FRAMERECT_TOP) / this->line_height; } /* It did not change.. no update! */ From 1e897531cbc9b227a86e1f156d17bcea1cf47a2f Mon Sep 17 00:00:00 2001 From: frosch Date: Fri, 30 Oct 2015 16:20:00 +0000 Subject: [PATCH 07/13] (svn r27422) -Fix [FS#6341]: Aircraft picked the wrong airport entry point, if airports were rotated by 180 degree. (marcole) --- src/aircraft_cmd.cpp | 2 +- src/direction_func.h | 20 +++++++++++++++++--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index 18dcbea27b..edb10af327 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -809,7 +809,7 @@ static byte AircraftGetEntryPoint(const Aircraft *v, const AirportFTAClass *apc, /* We are northwest or southeast of the airport */ dir = delta_y < 0 ? DIAGDIR_NW : DIAGDIR_SE; } - dir = ChangeDiagDir(dir, (DiagDirDiff)ReverseDiagDir(DirToDiagDir(rotation))); + dir = ChangeDiagDir(dir, DiagDirDifference(DIAGDIR_NE, DirToDiagDir(rotation))); return apc->entry_points[dir]; } diff --git a/src/direction_func.h b/src/direction_func.h index 8889485842..12aee58639 100644 --- a/src/direction_func.h +++ b/src/direction_func.h @@ -61,11 +61,11 @@ static inline Direction ReverseDir(Direction d) /** - * Calculate the difference between to directions + * Calculate the difference between two directions * * @param d0 The first direction as the base * @param d1 The second direction as the offset from the base - * @return The difference how the second directions drifts of the first one. + * @return The difference how the second direction drifts of the first one. */ static inline DirDiff DirDifference(Direction d0, Direction d1) { @@ -79,7 +79,7 @@ static inline DirDiff DirDifference(Direction d0, Direction d1) /** * Applies two differences together * - * This function adds two differences together and return the resulting + * This function adds two differences together and returns the resulting * difference. So adding two DIRDIFF_REVERSE together results in the * DIRDIFF_SAME difference. * @@ -123,6 +123,20 @@ static inline DiagDirection ReverseDiagDir(DiagDirection d) return (DiagDirection)(2 ^ d); } +/** + * Calculate the difference between two DiagDirection values + * + * @param d0 The first direction as the base + * @param d1 The second direction as the offset from the base + * @return The difference how the second direction drifts of the first one. + */ +static inline DiagDirDiff DiagDirDifference(DiagDirection d0, DiagDirection d1) +{ + assert(IsValidDiagDirection(d0)); + assert(IsValidDiagDirection(d1)); + /* Cast to uint so compiler can use bitmask. Result can never be negative. */ + return (DiagDirDiff)((uint)(d0 - d1) % 4); +} /** * Applies a difference on a DiagDirection From 34627862c65c0e245964a957894f53b087105d2d Mon Sep 17 00:00:00 2001 From: frosch Date: Fri, 30 Oct 2015 17:17:54 +0000 Subject: [PATCH 08/13] (svn r27423) -Fix: When towns expanded single-bit roadtiles using a grid-layout, they used the layout position of the neighbouring tile. --- src/town_cmd.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index ee2828ad7a..7479892c23 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -1247,8 +1247,8 @@ static void GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection t /* FALL THROUGH */ case TL_2X2_GRID: - rcmd = GetTownRoadGridElement(t1, house_tile, target_dir); - allow_house = (rcmd == ROAD_NONE); + rcmd = GetTownRoadGridElement(t1, tile, target_dir); + allow_house = (rcmd & DiagDirToRoadBits(target_dir)) == ROAD_NONE; break; case TL_BETTER_ROADS: // Use original afterwards! From e51abf17966bdcfc278bc0802380ad0231e5ddb1 Mon Sep 17 00:00:00 2001 From: frosch Date: Fri, 30 Oct 2015 17:19:01 +0000 Subject: [PATCH 09/13] (svn r27424) -Fix [FS#6374]: Towns did not connect roads to existing roads, unless they had only a single roadbit. Otoh, towns also tried to connect to single roadbit tiles such as tunnels and depots, even though they were not connectable in the direction of interest. --- src/road.cpp | 57 +++++++++++++++++++++++++++------------------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/src/road.cpp b/src/road.cpp index 57c5da5d41..f51597538d 100644 --- a/src/road.cpp +++ b/src/road.cpp @@ -57,41 +57,44 @@ RoadBits CleanUpRoadBits(const TileIndex tile, RoadBits org_rb) bool connective = false; const RoadBits mirrored_rb = MirrorRoadBits(target_rb); - switch (GetTileType(neighbor_tile)) { - /* Always connective ones */ - case MP_CLEAR: case MP_TREES: - connective = true; - break; + if (IsValidTile(neighbor_tile)) { + switch (GetTileType(neighbor_tile)) { + /* Always connective ones */ + case MP_CLEAR: case MP_TREES: + connective = true; + break; - /* The conditionally connective ones */ - case MP_TUNNELBRIDGE: - case MP_STATION: - case MP_ROAD: { - const RoadBits neighbor_rb = GetAnyRoadBits(neighbor_tile, ROADTYPE_ROAD) | GetAnyRoadBits(neighbor_tile, ROADTYPE_TRAM); + /* The conditionally connective ones */ + case MP_TUNNELBRIDGE: + case MP_STATION: + case MP_ROAD: + if (IsNormalRoadTile(neighbor_tile)) { + /* Always connective */ + connective = true; + } else { + const RoadBits neighbor_rb = GetAnyRoadBits(neighbor_tile, ROADTYPE_ROAD) | GetAnyRoadBits(neighbor_tile, ROADTYPE_TRAM); - /* Accept only connective tiles */ - connective = (neighbor_rb & mirrored_rb) || // Neighbor has got the fitting RoadBit - HasExactlyOneBit(neighbor_rb); // Neighbor has got only one Roadbit + /* Accept only connective tiles */ + connective = (neighbor_rb & mirrored_rb) != ROAD_NONE; + } + break; - break; + case MP_RAILWAY: + connective = IsPossibleCrossing(neighbor_tile, DiagDirToAxis(dir)); + break; + + case MP_WATER: + /* Check for real water tile */ + connective = !IsWater(neighbor_tile); + break; + + /* The definitely not connective ones */ + default: break; } - - case MP_RAILWAY: - connective = IsPossibleCrossing(neighbor_tile, DiagDirToAxis(dir)); - break; - - case MP_WATER: - /* Check for real water tile */ - connective = !IsWater(neighbor_tile); - break; - - /* The definitely not connective ones */ - default: break; } /* If the neighbor tile is inconnective, remove the planed road connection to it */ if (!connective) org_rb ^= target_rb; - } } From c74ffeecd19bbdb1e79ea02ecd592fc4b085211b Mon Sep 17 00:00:00 2001 From: frosch Date: Fri, 30 Oct 2015 17:23:16 +0000 Subject: [PATCH 10/13] (svn r27425) -Fix [FS#5842]: Crash when switching to or taking over companies, when an order window of a vehicle of the new company was opened. Now close those windows. --- src/order_gui.cpp | 6 ++++++ src/window.cpp | 1 + 2 files changed, 7 insertions(+) diff --git a/src/order_gui.cpp b/src/order_gui.cpp index d4feae35ca..3ca29e087a 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -1713,6 +1713,12 @@ void ShowOrdersWindow(const Vehicle *v) DeleteWindowById(WC_VEHICLE_TIMETABLE, v->index, false); if (BringWindowToFrontById(WC_VEHICLE_ORDERS, v->index) != NULL) return; + /* Using a different WindowDescs for _local_company causes problems. + * Due to this we have to close order windows in ChangeWindowOwner/DeleteCompanyWindows, + * because we cannot change switch the WindowDescs and keeping the old WindowDesc results + * in crashed due to missing widges. + * TODO Rewrite the order GUI to not use different WindowDescs. + */ if (v->owner != _local_company) { new OrdersWindow(&_other_orders_desc, v); } else { diff --git a/src/window.cpp b/src/window.cpp index 18e8f35881..1fce1f3a8d 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -1207,6 +1207,7 @@ void ChangeWindowOwner(Owner old_owner, Owner new_owner) case WC_BUY_COMPANY: case WC_COMPANY: case WC_COMPANY_INFRASTRUCTURE: + case WC_VEHICLE_ORDERS: // Changing owner would also require changing WindowDesc, which is not possible; however keeping the old one crashes because of missing widgets etc.. See ShowOrdersWindow(). continue; default: From 0f8f73894218d44ec1edaab1302b4b754b36262c Mon Sep 17 00:00:00 2001 From: frosch Date: Fri, 30 Oct 2015 17:24:05 +0000 Subject: [PATCH 11/13] (svn r27426) -Change: Round loading percentage in loading indicators and conditional orders towards 50%, so that 0% and 100% mean completely empty or full. --- src/vehicle.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 46f98fe63b..a482520f25 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -1290,6 +1290,9 @@ void AgeVehicle(Vehicle *v) * @param front The front vehicle of the consist to check. * @param colour The string to show depending on if we are unloading or loading * @return A percentage of how full the Vehicle is. + * Percentages are rounded towards 50%, so that 0% and 100% are only returned + * if the vehicle is completely empty or full. + * This is useful for both display and conditional orders. */ uint8 CalcPercentVehicleFilled(const Vehicle *front, StringID *colour) { @@ -1337,7 +1340,13 @@ uint8 CalcPercentVehicleFilled(const Vehicle *front, StringID *colour) if (max == 0) return 100; /* Return the percentage */ - return (count * 100) / max; + if (count * 2 < max) { + /* Less than 50%; round up, so that 0% means really empty. */ + return CeilDiv(count * 100, max); + } else { + /* More than 50%; round down, so that 100% means really full. */ + return (count * 100) / max; + } } /** From ade25fff71f7cfb3448b2cb8480c772091f36691 Mon Sep 17 00:00:00 2001 From: frosch Date: Fri, 30 Oct 2015 17:24:30 +0000 Subject: [PATCH 12/13] (svn r27427) -Fix: Use the NewGRF railtype sorting order in the infrastructure window. --- src/company_gui.cpp | 6 ++++-- src/rail.h | 9 +++++++++ src/rail_cmd.cpp | 21 +++++++++++++++++++++ src/rail_gui.cpp | 17 ++--------------- 4 files changed, 36 insertions(+), 17 deletions(-) diff --git a/src/company_gui.cpp b/src/company_gui.cpp index 1343acb91b..0be6679583 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -1764,7 +1764,8 @@ struct CompanyInfrastructureWindow : Window if (this->railtypes != RAILTYPES_NONE) { /* Draw name of each valid railtype. */ - for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) { + RailType rt; + FOR_ALL_SORTED_RAILTYPES(rt) { if (HasBit(this->railtypes, rt)) { SetDParam(0, GetRailTypeInfo(rt)->strings.name); DrawString(r.left + offs_left, r.right - offs_right, y += FONT_HEIGHT_NORMAL, STR_WHITE_STRING); @@ -1781,7 +1782,8 @@ struct CompanyInfrastructureWindow : Window case WID_CI_RAIL_COUNT: { /* Draw infrastructure count for each valid railtype. */ uint32 rail_total = c->infrastructure.GetRailTotal(); - for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) { + RailType rt; + FOR_ALL_SORTED_RAILTYPES(rt) { if (HasBit(this->railtypes, rt)) { this->DrawCountLine(r, y, c->infrastructure.rail[rt], RailMaintenanceCost(rt, c->infrastructure.rail[rt], rail_total)); } diff --git a/src/rail.h b/src/rail.h index 539a162b8e..320d24a9a0 100644 --- a/src/rail.h +++ b/src/rail.h @@ -431,4 +431,13 @@ void ResetRailTypes(); void InitRailTypes(); RailType AllocateRailType(RailTypeLabel label); +extern RailType _sorted_railtypes[RAILTYPE_END]; +extern uint8 _sorted_railtypes_size; + +/** + * Loop header for iterating over railtypes, sorted by sortorder. + * @param var Railtype. + */ +#define FOR_ALL_SORTED_RAILTYPES(var) for (uint8 index = 0; index < _sorted_railtypes_size && (var = _sorted_railtypes[index], true) ; index++) + #endif /* RAIL_H */ diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 743e6e193c..2010f9b305 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -44,6 +44,8 @@ typedef SmallVector TrainList; RailtypeInfo _railtypes[RAILTYPE_END]; +RailType _sorted_railtypes[RAILTYPE_END]; +uint8 _sorted_railtypes_size; assert_compile(sizeof(_original_railtypes) <= sizeof(_railtypes)); @@ -109,6 +111,17 @@ void ResolveRailTypeGUISprites(RailtypeInfo *rti) } } +/** + * Compare railtypes based on their sorting order. + * @param first The railtype to compare to. + * @param second The railtype to compare. + * @return True iff the first should be sorted before the second. + */ +static int CDECL CompareRailTypes(const RailType *first, const RailType *second) +{ + return GetRailTypeInfo(*first)->sorting_order - GetRailTypeInfo(*second)->sorting_order; +} + /** * Resolve sprites of custom rail types */ @@ -118,6 +131,14 @@ void InitRailTypes() RailtypeInfo *rti = &_railtypes[rt]; ResolveRailTypeGUISprites(rti); } + + _sorted_railtypes_size = 0; + for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) { + if (_railtypes[rt].label != 0) { + _sorted_railtypes[_sorted_railtypes_size++] = rt; + } + } + QSortT(_sorted_railtypes, _sorted_railtypes_size, CompareRailTypes); } /** diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index a8c2fc6b33..a48abd29cc 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -1978,17 +1978,6 @@ void InitializeRailGUI() ResetSignalVariant(); } -/** - * Compare railtypes based on their sorting order. - * @param first The railtype to compare to. - * @param second The railtype to compare. - * @return True iff the first should be sorted before the second. - */ -static int CDECL CompareRailTypes(const DropDownListItem * const *first, const DropDownListItem * const *second) -{ - return GetRailTypeInfo((RailType)(*first)->result)->sorting_order - GetRailTypeInfo((RailType)(*second)->result)->sorting_order; -} - /** * Create a drop down list for all the rail types of the local company. * @param for_replacement Whether this list is for the replacement window. @@ -2011,13 +2000,12 @@ DropDownList *GetRailTypeDropDownList(bool for_replacement) const Company *c = Company::Get(_local_company); DropDownList *list = new DropDownList(); - for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) { + RailType rt; + FOR_ALL_SORTED_RAILTYPES(rt) { /* If it's not used ever, don't show it to the user. */ if (!HasBit(used_railtypes, rt)) continue; const RailtypeInfo *rti = GetRailTypeInfo(rt); - /* Skip rail type if it has no label */ - if (rti->label == 0) continue; StringID str = for_replacement ? rti->strings.replace_text : (rti->max_speed > 0 ? STR_TOOLBAR_RAILTYPE_VELOCITY : STR_JUST_STRING); DropDownListParamStringItem *item = new DropDownListParamStringItem(str, rt, !HasBit(c->avail_railtypes, rt)); @@ -2025,6 +2013,5 @@ DropDownList *GetRailTypeDropDownList(bool for_replacement) item->SetParam(1, rti->max_speed); *list->Append() = item; } - QSortT(list->Begin(), list->Length(), CompareRailTypes); return list; } From ba955956cbceede0edcbb1a91cd6b06292dffb35 Mon Sep 17 00:00:00 2001 From: frosch Date: Fri, 30 Oct 2015 17:27:21 +0000 Subject: [PATCH 13/13] (svn r27428) -Fix: When selecting a refit cargo for orders, do not check whether the vehicle is in a depot or station, and do not ask whether the vehicle currently allows station-refitting. Also hide the refit cost for orders, it is not predictable. --- src/vehicle_cmd.cpp | 15 ++++++++++++--- src/vehicle_gui.cpp | 11 +++++++++-- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/vehicle_cmd.cpp b/src/vehicle_cmd.cpp index 72cff271a4..3b664defb6 100644 --- a/src/vehicle_cmd.cpp +++ b/src/vehicle_cmd.cpp @@ -358,8 +358,10 @@ static CommandCost RefitVehicle(Vehicle *v, bool only_this, uint8 num_vehicles, bool auto_refit_allowed; CommandCost refit_cost = GetRefitCost(v, v->engine_type, new_cid, actual_subtype, &auto_refit_allowed); - if (auto_refit && !auto_refit_allowed) { - /* Sorry, auto-refitting not allowed, subtract the cargo amount again from the total. */ + if (auto_refit && (flags & DC_QUERY_COST) == 0 && !auto_refit_allowed) { + /* Sorry, auto-refitting not allowed, subtract the cargo amount again from the total. + * When querrying cost/capacity (for example in order refit GUI), we always assume 'allowed'. + * It is not predictable. */ total_capacity -= amount; total_mail_capacity -= mail_capacity; @@ -446,8 +448,15 @@ CommandCost CmdRefitVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint /* Don't allow shadows and such to be refitted. */ if (v != front && (v->type == VEH_SHIP || v->type == VEH_AIRCRAFT)) return CMD_ERROR; + /* Allow auto-refitting only during loading and normal refitting only in a depot. */ - if (!free_wagon && (!auto_refit || !front->current_order.IsType(OT_LOADING)) && !front->IsStoppedInDepot()) return_cmd_error(STR_ERROR_TRAIN_MUST_BE_STOPPED_INSIDE_DEPOT + front->type); + if ((flags & DC_QUERY_COST) == 0 && // used by the refit GUI, including the order refit GUI. + !free_wagon && // used by autoreplace/renew + (!auto_refit || !front->current_order.IsType(OT_LOADING)) && // refit inside stations + !front->IsStoppedInDepot()) { // refit inside depots + return_cmd_error(STR_ERROR_TRAIN_MUST_BE_STOPPED_INSIDE_DEPOT + front->type); + } + if (front->vehstatus & VS_CRASHED) return_cmd_error(STR_ERROR_VEHICLE_IS_DESTROYED); /* Check cargo */ diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index 4ace090dda..10f1d952da 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -701,7 +701,10 @@ struct RefitWindow : public Window { if (_returned_mail_refit_capacity > 0) { SetDParam(2, CT_MAIL); SetDParam(3, _returned_mail_refit_capacity); - if (money <= 0) { + if (this->order != INVALID_VEH_ORDER_ID) { + /* No predictable cost */ + return STR_PURCHASE_INFO_AIRCRAFT_CAPACITY; + } else if (money <= 0) { SetDParam(4, -money); return STR_REFIT_NEW_CAPACITY_INCOME_FROM_AIRCRAFT_REFIT; } else { @@ -709,7 +712,11 @@ struct RefitWindow : public Window { return STR_REFIT_NEW_CAPACITY_COST_OF_AIRCRAFT_REFIT; } } else { - if (money <= 0) { + if (this->order != INVALID_VEH_ORDER_ID) { + /* No predictable cost */ + SetDParam(2, STR_EMPTY); + return STR_PURCHASE_INFO_CAPACITY; + } else if (money <= 0) { SetDParam(2, -money); return STR_REFIT_NEW_CAPACITY_INCOME_FROM_REFIT; } else {