diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index cf1836e9b0..17061443d9 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -820,7 +820,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/company_gui.cpp b/src/company_gui.cpp index 4a6a7d1b32..eb99cb9359 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -1768,7 +1768,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); @@ -1785,7 +1786,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/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 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 diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index 8cadcda6be..758c927065 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -1869,7 +1869,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), @@ -1891,7 +1893,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 */ @@ -1907,7 +1909,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; @@ -1915,7 +1918,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() @@ -1931,11 +1934,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; @@ -1949,24 +1954,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; } } @@ -1999,7 +2004,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! */ diff --git a/src/order_gui.cpp b/src/order_gui.cpp index abee5555ab..35eee48048 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -1966,6 +1966,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/pathfinder/follow_track.hpp b/src/pathfinder/follow_track.hpp index 5d3b5b0778..6cdf4c7e43 100644 --- a/src/pathfinder/follow_track.hpp +++ b/src/pathfinder/follow_track.hpp @@ -145,7 +145,12 @@ struct CFollowTrackT * missing road bit, or inability to connect the * different bits due to slopes. */ if (IsRoadTT() && !IsTram() && TryReverse()) return true; + + /* 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()) { 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 d56942aa5a..f6e514d1e8 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -46,6 +46,8 @@ typedef SmallVector TrainList; RailtypeInfo _railtypes[RAILTYPE_END]; +RailType _sorted_railtypes[RAILTYPE_END]; +uint8 _sorted_railtypes_size; assert_compile(sizeof(_original_railtypes) <= sizeof(_railtypes)); @@ -113,6 +115,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 */ @@ -122,6 +135,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 64a985a441..9f337ed276 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -2052,17 +2052,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. @@ -2085,13 +2074,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)); @@ -2099,6 +2087,5 @@ DropDownList *GetRailTypeDropDownList(bool for_replacement) item->SetParam(1, rti->max_speed); *list->Append() = item; } - QSortT(list->Begin(), list->Length(), CompareRailTypes); return list; } 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; - } } diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index 2936e3911e..e5e24a8f86 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -570,7 +570,7 @@ void NORETURN SlError(StringID string, const char *extra_msg, bool already_mallo /** * As SlError, except that it takes a format string and additional parameters */ -void CDECL NORETURN SlErrorFmt(StringID string, const char *msg, ...) +void NORETURN CDECL SlErrorFmt(StringID string, const char *msg, ...) { va_list va; va_start(va, msg); @@ -594,7 +594,7 @@ void NORETURN SlErrorCorrupt(const char *msg, bool already_malloced) /** * As SlErrorCorruptFmt, except that it takes a format string and additional parameters */ -void CDECL NORETURN SlErrorCorruptFmt(const char *msg, ...) +void NORETURN CDECL SlErrorCorruptFmt(const char *msg, ...) { va_list va; va_start(va, msg); diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index 330cdde072..8df011958b 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -631,8 +631,8 @@ void SlObject(void *object, const SaveLoad *sld); bool SlObjectMember(void *object, const SaveLoad *sld); void NORETURN SlError(StringID string, const char *extra_msg = NULL, bool already_malloced = false); void NORETURN SlErrorCorrupt(const char *msg, bool already_malloced = false); -void CDECL NORETURN SlErrorFmt(StringID string, const char *msg, ...) WARN_FORMAT(2, 3); -void CDECL NORETURN SlErrorCorruptFmt(const char *msg, ...) WARN_FORMAT(1, 2); +void NORETURN CDECL SlErrorFmt(StringID string, const char *msg, ...) WARN_FORMAT(2, 3); +void NORETURN CDECL SlErrorCorruptFmt(const char *msg, ...) WARN_FORMAT(1, 2); bool SaveloadCrashWithMissingNewGRFs(); diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 50ccd493fa..b3cb198572 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -1395,8 +1395,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! @@ -1526,13 +1526,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. */ @@ -1567,7 +1566,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; } /** diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 74d05d08ab..2fd0b22f5f 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -1439,13 +1439,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. */ diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 5c9670a19c..e355349b2f 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -1611,6 +1611,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) { @@ -1658,7 +1661,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; + } } /** diff --git a/src/vehicle_cmd.cpp b/src/vehicle_cmd.cpp index 1590647c0c..45f7f3d616 100644 --- a/src/vehicle_cmd.cpp +++ b/src/vehicle_cmd.cpp @@ -386,8 +386,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; @@ -474,8 +476,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 f0dd3cf536..665f79bd7a 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -754,7 +754,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 { @@ -762,7 +765,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 { diff --git a/src/window.cpp b/src/window.cpp index 7999eb0999..dd8da4ad3f 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: 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) {