diff --git a/src/lang/english.txt b/src/lang/english.txt index 9beedeb86e..84cbfea325 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -295,6 +295,7 @@ STR_SORT_BY_VALUE :Value STR_SORT_BY_LENGTH :Length STR_SORT_BY_LIFE_TIME :Remaining lifetime STR_SORT_BY_TIMETABLE_DELAY :Timetable delay +STR_SORT_BY_AVG_ORDER_OCCUPANCY :Average order occupancy STR_SORT_BY_FACILITY :Station type STR_SORT_BY_WAITING_TOTAL :Total waiting cargo STR_SORT_BY_WAITING_AVAILABLE :Available waiting cargo @@ -3822,9 +3823,9 @@ STR_ORDERS_GO_TO_TOOLTIP :{BLACK}Insert a STR_ORDERS_VEH_WITH_SHARED_ORDERS_LIST_TOOLTIP :{BLACK}Show all vehicles that share this schedule -STR_ORDERS_OCCUPANCY_BUTTON :{BLACK}% -STR_ORDERS_OCCUPANCY_BUTTON_TOOLTIP :{BLACK}Show occupancy running averages -STR_ORDERS_OCCUPANCY_LIST_TOOLTIP :{BLACK}Order occupancy - this shows runnings averages of recent occupancy levels when leaving a station, for all vehicles sharing these orders +STR_ORDERS_OCCUPANCY_BUTTON :{BLACK}{STRING2}% +STR_ORDERS_OCCUPANCY_BUTTON_TOOLTIP :{BLACK}Show occupancy running averages{}The percentage shown is the overall average of the order occupancies +STR_ORDERS_OCCUPANCY_LIST_TOOLTIP :{BLACK}Order occupancy - this shows running averages of recent occupancy levels when leaving a station, for all vehicles sharing these orders STR_ORDERS_OCCUPANCY_PERCENT :{NUM}% # String parts to build the order string diff --git a/src/order_gui.cpp b/src/order_gui.cpp index 44a7a5116a..c09291442d 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -833,6 +833,11 @@ public: *size = maxdim(*size, d); break; } + + case WID_O_OCCUPANCY_TOGGLE: + SetDParamMaxValue(0, 100); + size->width = WD_FRAMERECT_LEFT + GetStringBoundingBox(STR_ORDERS_OCCUPANCY_PERCENT).width + 10 + WD_FRAMERECT_RIGHT; + break; } } @@ -1199,6 +1204,17 @@ public: case WID_O_CAPTION: SetDParam(0, this->vehicle->index); break; + + case WID_O_OCCUPANCY_TOGGLE: + const_cast(this->vehicle)->RecalculateOrderOccupancyAverage(); + if (this->vehicle->order_occupancy_average >= 16) { + SetDParam(0, STR_JUST_INT); + SetDParam(1, this->vehicle->order_occupancy_average - 16); + } else { + SetDParam(0, STR_EMPTY); + SetDParam(1, 0); + } + break; } } @@ -1634,7 +1650,7 @@ static const NWidgetPart _nested_orders_train_widgets[] = { SetDataTip(STR_BLACK_COMMA, STR_ORDER_CONDITIONAL_VALUE_TOOLTIP), SetResize(1, 0), EndContainer(), EndContainer(), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_O_OCCUPANCY_TOGGLE), SetMinimalSize(12, 12), SetDataTip(STR_ORDERS_OCCUPANCY_BUTTON, STR_ORDERS_OCCUPANCY_BUTTON_TOOLTIP), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_O_OCCUPANCY_TOGGLE), SetMinimalSize(36, 12), SetDataTip(STR_ORDERS_OCCUPANCY_BUTTON, STR_ORDERS_OCCUPANCY_BUTTON_TOOLTIP), NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_O_SHARED_ORDER_LIST), SetMinimalSize(12, 12), SetDataTip(SPR_SHARED_ORDERS_ICON, STR_ORDERS_VEH_WITH_SHARED_ORDERS_LIST_TOOLTIP), EndContainer(), @@ -1714,7 +1730,7 @@ static const NWidgetPart _nested_orders_widgets[] = { EndContainer(), EndContainer(), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_O_OCCUPANCY_TOGGLE), SetMinimalSize(12, 12), SetDataTip(STR_ORDERS_OCCUPANCY_BUTTON, STR_ORDERS_OCCUPANCY_BUTTON_TOOLTIP), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_O_OCCUPANCY_TOGGLE), SetMinimalSize(36, 12), SetDataTip(STR_ORDERS_OCCUPANCY_BUTTON, STR_ORDERS_OCCUPANCY_BUTTON_TOOLTIP), NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_O_SHARED_ORDER_LIST), SetMinimalSize(12, 12), SetDataTip(SPR_SHARED_ORDERS_ICON, STR_ORDERS_VEH_WITH_SHARED_ORDERS_LIST_TOOLTIP), EndContainer(), diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 7400ec8089..51a5b4cc4b 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -2132,6 +2132,7 @@ void Vehicle::LeaveStation() new_occupancy /= 100; } if (new_occupancy + 1 != old_occupancy) { + this->order_occupancy_average = 0; real_current_order->SetOccupancy(static_cast(new_occupancy + 1)); for (const Vehicle *v = this->FirstShared(); v != NULL; v = v->NextShared()) { SetWindowDirty(WC_VEHICLE_ORDERS, v->index); @@ -2142,6 +2143,25 @@ void Vehicle::LeaveStation() this->MarkDirty(); } +void Vehicle::RecalculateOrderOccupancyAverage() +{ + uint num_valid = 0; + uint total = 0; + uint order_count = this->GetNumOrders(); + for (uint i = 0; i < order_count; i++) { + uint occupancy = this->GetOrder(i)->GetOccupancy(); + if (occupancy > 0) { + num_valid++; + total += (occupancy - 1); + } + } + if (num_valid > 0) { + this->order_occupancy_average = 16 + ((total + (num_valid / 2)) / num_valid); + } else { + this->order_occupancy_average = 1; + } +} + /** * Reset all refit_cap in the consist to cargo_cap. */ diff --git a/src/vehicle_base.h b/src/vehicle_base.h index 59584da788..2170886341 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -256,6 +256,8 @@ public: byte running_ticks; ///< Number of ticks this vehicle was not stopped this day byte vehstatus; ///< Status + + uint8 order_occupancy_average; ///< NOSAVE: order occupancy average. 0 = invalid, 1 = n/a, 16-116 = 0-100% Order current_order; ///< The current order (+ status, like: loading) union { @@ -643,6 +645,14 @@ public: return (this->orders.list == NULL) ? INVALID_STATION : this->orders.list->GetNextStoppingStation(this); } + void RecalculateOrderOccupancyAverage(); + + inline uint8 GetOrderOccupancyAverage() const + { + if (order_occupancy_average == 0) const_cast(this)->RecalculateOrderOccupancyAverage(); + return this->order_occupancy_average; + } + void ResetRefitCaps(); /** diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index 4ace090dda..864210a558 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -57,6 +57,7 @@ static GUIVehicleList::SortFunction VehicleValueSorter; static GUIVehicleList::SortFunction VehicleLengthSorter; static GUIVehicleList::SortFunction VehicleTimeToLiveSorter; static GUIVehicleList::SortFunction VehicleTimetableDelaySorter; +static GUIVehicleList::SortFunction VehicleAverageOrderOccupancySorter; GUIVehicleList::SortFunction * const BaseVehicleListWindow::vehicle_sorter_funcs[] = { &VehicleNumberSorter, @@ -72,6 +73,7 @@ GUIVehicleList::SortFunction * const BaseVehicleListWindow::vehicle_sorter_funcs &VehicleLengthSorter, &VehicleTimeToLiveSorter, &VehicleTimetableDelaySorter, + &VehicleAverageOrderOccupancySorter, }; const StringID BaseVehicleListWindow::vehicle_sorter_names[] = { @@ -88,6 +90,7 @@ const StringID BaseVehicleListWindow::vehicle_sorter_names[] = { STR_SORT_BY_LENGTH, STR_SORT_BY_LIFE_TIME, STR_SORT_BY_TIMETABLE_DELAY, + STR_SORT_BY_AVG_ORDER_OCCUPANCY, INVALID_STRING_ID }; @@ -1199,6 +1202,13 @@ static int CDECL VehicleTimetableDelaySorter(const Vehicle * const *a, const Veh return (r != 0) ? r : VehicleNumberSorter(a, b); } +/** Sort vehicles by the average order occupancy */ +static int CDECL VehicleAverageOrderOccupancySorter(const Vehicle * const *a, const Vehicle * const *b) +{ + int r = (*a)->GetOrderOccupancyAverage() - (*b)->GetOrderOccupancyAverage(); + return (r != 0) ? r : VehicleNumberSorter(a, b); +} + void InitializeGUI() { MemSetT(&_sorting, 0);