Merge branch 'order_occupancy-sx' into jgrpp
Conflicts: src/lang/english.txt src/saveload/extended_ver_sl.cpp src/saveload/extended_ver_sl.h src/settings_gui.cpp
This commit is contained in:
@@ -1789,6 +1789,9 @@ STR_CONFIG_SETTING_PAY_FOR_REPAIR_VEHICLE_HELPTEXT :Pay for repairi
|
||||
STR_CONFIG_SETTING_REPAIR_COST :Cost of repairing vehicle: 1/{STRING2} of total cost
|
||||
STR_CONFIG_SETTING_REPAIR_COST_HELPTEXT :Cost of repairing vehicle
|
||||
|
||||
STR_CONFIG_OCCUPANCY_SMOOTHNESS :Smoothness of order occupancy measurement: {STRING2}
|
||||
STR_CONFIG_OCCUPANCY_SMOOTHNESS_HELPTEXT :0% sets the measurement to the most recent value, 100% leaves it unchanged
|
||||
|
||||
# Config errors
|
||||
STR_CONFIG_ERROR :{WHITE}Error with the configuration file...
|
||||
STR_CONFIG_ERROR_ARRAY :{WHITE}... error in array '{RAW_STRING}'
|
||||
@@ -4236,6 +4239,11 @@ 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_PERCENT :{NUM}%
|
||||
|
||||
# String parts to build the order string
|
||||
STR_ORDER_GO_TO_WAYPOINT :Go via {WAYPOINT}
|
||||
STR_ORDER_GO_NON_STOP_TO_WAYPOINT :Go non-stop via {WAYPOINT}
|
||||
|
@@ -43,6 +43,8 @@ private:
|
||||
|
||||
CargoID refit_cargo; ///< Refit CargoID
|
||||
|
||||
uint8 occupancy; ///< Estimate of vehicle occupancy on departure, for the current order, 0 indicates invalid, 1 - 101 indicate 0 - 100%
|
||||
|
||||
uint16 wait_time; ///< How long in ticks to wait at the destination.
|
||||
uint16 travel_time; ///< How long in ticks the journey to this destination should take.
|
||||
uint16 max_speed; ///< How fast the vehicle may go on the way to the destination.
|
||||
@@ -218,6 +220,18 @@ public:
|
||||
*/
|
||||
inline void SetMaxSpeed(uint16 speed) { this->max_speed = speed; }
|
||||
|
||||
/**
|
||||
* Get the occupancy value
|
||||
* @return occupancy
|
||||
*/
|
||||
inline uint8 GetOccupancy() const { return this->occupancy; }
|
||||
|
||||
/**
|
||||
* Set the occupancy value
|
||||
* @param occupancy The occupancy to set
|
||||
*/
|
||||
inline void SetOccupancy(uint8 occupancy) { this->occupancy = occupancy; }
|
||||
|
||||
bool ShouldStopAtStation(const Vehicle *v, StationID station) const;
|
||||
bool CanLoadOrUnload() const;
|
||||
bool CanLeaveWithCargo(bool has_cargo) const;
|
||||
|
@@ -245,6 +245,7 @@ Order::Order(uint32 packed)
|
||||
this->dest = GB(packed, 16, 16);
|
||||
this->next = NULL;
|
||||
this->refit_cargo = CT_NO_REFIT;
|
||||
this->occupancy = 0;
|
||||
this->wait_time = 0;
|
||||
this->travel_time = 0;
|
||||
this->max_speed = UINT16_MAX;
|
||||
|
@@ -782,6 +782,7 @@ public:
|
||||
|
||||
this->CreateNestedTree();
|
||||
this->vscroll = this->GetScrollbar(WID_O_SCROLLBAR);
|
||||
this->GetWidget<NWidgetStacked>(WID_O_SEL_OCCUPANCY)->SetDisplayedPlane(SZSP_NONE);
|
||||
this->FinishInitNested(v->index);
|
||||
if (v->owner == _local_company) {
|
||||
this->DisableWidget(WID_O_EMPTY);
|
||||
@@ -817,6 +818,12 @@ public:
|
||||
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_O_OCCUPANCY_LIST:
|
||||
SetDParamMaxValue(0, 100);
|
||||
size->width = WD_FRAMERECT_LEFT + GetStringBoundingBox(STR_ORDERS_OCCUPANCY_PERCENT).width + 10 + WD_FRAMERECT_RIGHT;
|
||||
/* FALL THROUGH */
|
||||
|
||||
case WID_O_SEL_OCCUPANCY:
|
||||
case WID_O_ORDER_LIST:
|
||||
resize->height = FONT_HEIGHT_NORMAL;
|
||||
size->height = 6 * resize->height + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
|
||||
@@ -1083,6 +1090,8 @@ public:
|
||||
/* Disable list of vehicles with the same shared orders if there is no list */
|
||||
this->SetWidgetDisabledState(WID_O_SHARED_ORDER_LIST, !shared_orders);
|
||||
|
||||
this->GetWidget<NWidgetStacked>(WID_O_SEL_OCCUPANCY)->SetDisplayedPlane(IsWidgetLowered(WID_O_OCCUPANCY_TOGGLE) ? 0 : SZSP_NONE);
|
||||
|
||||
this->SetDirty();
|
||||
}
|
||||
|
||||
@@ -1098,8 +1107,19 @@ public:
|
||||
|
||||
virtual void DrawWidget(const Rect &r, int widget) const
|
||||
{
|
||||
if (widget != WID_O_ORDER_LIST) return;
|
||||
switch (widget) {
|
||||
case WID_O_ORDER_LIST:
|
||||
DrawOrderListWidget(r);
|
||||
break;
|
||||
|
||||
case WID_O_OCCUPANCY_LIST:
|
||||
DrawOccupancyListWidget(r);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DrawOrderListWidget(const Rect &r) const
|
||||
{
|
||||
bool rtl = _current_text_dir == TD_RTL;
|
||||
SetDParamMaxValue(0, this->vehicle->GetNumOrders(), 2);
|
||||
int index_column_width = GetStringBoundingBox(STR_ORDER_INDEX).width + 2 * GetSpriteSize(rtl ? SPR_ARROW_RIGHT : SPR_ARROW_LEFT).width + 3;
|
||||
@@ -1154,6 +1174,30 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void DrawOccupancyListWidget(const Rect &r) const
|
||||
{
|
||||
int y = r.top + WD_FRAMERECT_TOP;
|
||||
int line_height = this->GetWidget<NWidgetBase>(WID_O_ORDER_LIST)->resize_y;
|
||||
|
||||
int i = this->vscroll->GetPosition();
|
||||
const Order *order = this->vehicle->GetOrder(i);
|
||||
/* Draw the orders. */
|
||||
while (order != NULL) {
|
||||
/* Don't draw anything if it extends past the end of the window. */
|
||||
if (!this->vscroll->IsVisible(i)) break;
|
||||
|
||||
uint8 occupancy = order->GetOccupancy();
|
||||
if (occupancy > 0) {
|
||||
SetDParam(0, occupancy - 1);
|
||||
DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, y, STR_ORDERS_OCCUPANCY_PERCENT, (i == this->selected_order) ? TC_WHITE : TC_BLACK);
|
||||
}
|
||||
y += line_height;
|
||||
|
||||
i++;
|
||||
order = order->next;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void SetStringParameters(int widget) const
|
||||
{
|
||||
switch (widget) {
|
||||
@@ -1339,6 +1383,12 @@ public:
|
||||
case WID_O_SHARED_ORDER_LIST:
|
||||
ShowVehicleListWindow(this->vehicle);
|
||||
break;
|
||||
|
||||
case WID_O_OCCUPANCY_TOGGLE:
|
||||
ToggleWidgetLoweredState(WID_O_OCCUPANCY_TOGGLE);
|
||||
this->UpdateButtonState();
|
||||
this->ReInit();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1585,6 +1635,10 @@ static const NWidgetPart _nested_orders_train_widgets[] = {
|
||||
EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
NWidget(WWT_PANEL, COLOUR_GREY, WID_O_ORDER_LIST), SetMinimalSize(372, 62), SetDataTip(0x0, STR_ORDERS_LIST_TOOLTIP), SetResize(1, 1), SetScrollbar(WID_O_SCROLLBAR), EndContainer(),
|
||||
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_O_SEL_OCCUPANCY),
|
||||
NWidget(WWT_PANEL, COLOUR_GREY, WID_O_OCCUPANCY_LIST), SetMinimalSize(50, 0), SetFill(0, 1), SetDataTip(STR_NULL, STR_ORDERS_OCCUPANCY_LIST_TOOLTIP),
|
||||
SetScrollbar(WID_O_SCROLLBAR), EndContainer(),
|
||||
EndContainer(),
|
||||
NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_O_SCROLLBAR),
|
||||
EndContainer(),
|
||||
|
||||
@@ -1622,6 +1676,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_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(),
|
||||
|
||||
@@ -1663,6 +1718,10 @@ static const NWidgetPart _nested_orders_widgets[] = {
|
||||
EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
NWidget(WWT_PANEL, COLOUR_GREY, WID_O_ORDER_LIST), SetMinimalSize(372, 62), SetDataTip(0x0, STR_ORDERS_LIST_TOOLTIP), SetResize(1, 1), SetScrollbar(WID_O_SCROLLBAR), EndContainer(),
|
||||
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_O_SEL_OCCUPANCY),
|
||||
NWidget(WWT_PANEL, COLOUR_GREY, WID_O_OCCUPANCY_LIST), SetMinimalSize(50, 0), SetFill(0, 1), SetDataTip(STR_NULL, STR_ORDERS_OCCUPANCY_LIST_TOOLTIP),
|
||||
SetScrollbar(WID_O_SCROLLBAR), EndContainer(),
|
||||
EndContainer(),
|
||||
NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_O_SCROLLBAR),
|
||||
EndContainer(),
|
||||
|
||||
@@ -1697,6 +1756,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_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(),
|
||||
|
||||
|
@@ -60,6 +60,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
|
||||
{ XSLFI_ENH_VIEWPORT_PLANS, XSCF_IGNORABLE_ALL, 1, 1, "enh_viewport_plans", NULL, NULL, "PLAN,PLLN" },
|
||||
{ XSLFI_INFRA_SHARING, XSCF_NULL, 1, 1, "infra_sharing", NULL, NULL, NULL },
|
||||
{ XSLFI_VARIABLE_DAY_LENGTH, XSCF_NULL, 1, 1, "variable_day_length", NULL, NULL, NULL },
|
||||
{ XSLFI_ORDER_OCCUPANCY, XSCF_NULL, 1, 1, "order_occupancy", NULL, NULL, NULL },
|
||||
{ XSLFI_NULL, XSCF_NULL, 0, 0, NULL, NULL, NULL, NULL },// This is the end marker
|
||||
};
|
||||
|
||||
|
@@ -35,6 +35,7 @@ enum SlXvFeatureIndex {
|
||||
XSLFI_ENH_VIEWPORT_PLANS, ///< Enhanced viewport patch: plans
|
||||
XSLFI_INFRA_SHARING, ///< Infrastructure sharing patch
|
||||
XSLFI_VARIABLE_DAY_LENGTH, ///< Variable day length patch
|
||||
XSLFI_ORDER_OCCUPANCY, ///< Running average of order occupancy
|
||||
|
||||
XSLFI_SIZE, ///< Total count of features, including null feature
|
||||
};
|
||||
|
@@ -110,6 +110,7 @@ const SaveLoad *GetOrderDescription()
|
||||
SLE_REF(Order, next, REF_ORDER),
|
||||
SLE_CONDVAR(Order, refit_cargo, SLE_UINT8, 36, SL_MAX_VERSION),
|
||||
SLE_CONDNULL(1, 36, 181), // refit_subtype
|
||||
SLE_CONDVAR_X(Order, occupancy, SLE_UINT8, 0, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ORDER_OCCUPANCY)),
|
||||
SLE_CONDVAR(Order, wait_time, SLE_UINT16, 67, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Order, travel_time, SLE_UINT16, 67, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Order, max_speed, SLE_UINT16, 172, SL_MAX_VERSION),
|
||||
|
@@ -1676,6 +1676,7 @@ static SettingsContainer &GetSettingsTree()
|
||||
vehicles->Add(new SettingEntry("order.timetable_automated"));
|
||||
vehicles->Add(new SettingEntry("order.timetable_separation"));
|
||||
vehicles->Add(new SettingEntry("vehicle.adjacent_crossings"));
|
||||
vehicles->Add(new SettingEntry("order.occupancy_smoothness"));
|
||||
}
|
||||
|
||||
SettingsPage *limitations = main->Add(new SettingsPage(STR_CONFIG_SETTING_LIMITATIONS));
|
||||
|
@@ -475,6 +475,7 @@ struct OrderSettings {
|
||||
bool timetable_automated; ///< whether to automatically manage timetables
|
||||
bool timetable_separation; ///< whether to perform automatic separation based on timetable
|
||||
bool serviceathelipad; ///< service helicopters at helipads automatically (no need to send to depot)
|
||||
uint8 occupancy_smoothness; ///< percentage smoothness of occupancy measurement changes
|
||||
};
|
||||
|
||||
/** Settings related to vehicles. */
|
||||
|
@@ -2336,6 +2336,21 @@ min = 0
|
||||
max = 1000000
|
||||
cat = SC_EXPERT
|
||||
|
||||
[SDT_VAR]
|
||||
base = GameSettings
|
||||
var = order.occupancy_smoothness
|
||||
type = SLE_UINT8
|
||||
def = 75
|
||||
min = 0
|
||||
max = 100
|
||||
interval = 10
|
||||
str = STR_CONFIG_OCCUPANCY_SMOOTHNESS
|
||||
strhelp = STR_CONFIG_OCCUPANCY_SMOOTHNESS_HELPTEXT
|
||||
strval = STR_CONFIG_SETTING_PERCENTAGE
|
||||
cat = SC_EXPERT
|
||||
extver = SlXvFeatureTest(XSLFTO_AND, XSLFI_ORDER_OCCUPANCY)
|
||||
patxname = ""order_occupancy.order.occupancy_smoothness""
|
||||
|
||||
##
|
||||
[SDT_VAR]
|
||||
base = GameSettings
|
||||
|
@@ -2450,6 +2450,28 @@ void Vehicle::LeaveStation()
|
||||
SetBit(Train::From(this)->flags, VRF_LEAVING_STATION);
|
||||
}
|
||||
|
||||
if (this->cur_real_order_index < this->GetNumOrders()) {
|
||||
Order *real_current_order = this->GetOrder(this->cur_real_order_index);
|
||||
uint current_occupancy = CalcPercentVehicleFilled(this, NULL);
|
||||
uint old_occupancy = real_current_order->GetOccupancy();
|
||||
uint new_occupancy;
|
||||
if (old_occupancy == 0) {
|
||||
new_occupancy = current_occupancy;
|
||||
} else {
|
||||
// Exponential weighted moving average using occupancy_smoothness
|
||||
new_occupancy = (old_occupancy - 1) * _settings_game.order.occupancy_smoothness;
|
||||
new_occupancy += current_occupancy * (100 - _settings_game.order.occupancy_smoothness);
|
||||
new_occupancy += 50; // round to nearest integer percent, rather than just floor
|
||||
new_occupancy /= 100;
|
||||
}
|
||||
if (new_occupancy + 1 != old_occupancy) {
|
||||
real_current_order->SetOccupancy(static_cast<uint8>(new_occupancy + 1));
|
||||
for (const Vehicle *v = this->FirstShared(); v != NULL; v = v->NextShared()) {
|
||||
SetWindowDirty(WC_VEHICLE_ORDERS, v->index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this->MarkDirty();
|
||||
}
|
||||
|
||||
|
@@ -39,6 +39,9 @@ enum OrderWidgets {
|
||||
WID_O_SEL_TOP_ROW, ///< #NWID_SELECTION widget for the top row of the 'your non-trains' order window.
|
||||
WID_O_SEL_BOTTOM_MIDDLE, ///< #NWID_SELECTION widget for the middle part of the bottom row of the 'your train' order window.
|
||||
WID_O_SHARED_ORDER_LIST, ///< Open list of shared vehicles.
|
||||
WID_O_SEL_OCCUPANCY, ///< #NWID_SELECTION widget for the occupancy list panel.
|
||||
WID_O_OCCUPANCY_LIST, ///< Occupancy list panel.
|
||||
WID_O_OCCUPANCY_TOGGLE, ///< Toggle display of occupancy measures.
|
||||
};
|
||||
|
||||
#endif /* WIDGETS_ORDER_WIDGET_H */
|
||||
|
Reference in New Issue
Block a user