Merge remote-tracking branch 'upstream/master'

This commit is contained in:
dP
2025-05-14 18:41:13 +05:00
994 changed files with 38759 additions and 34518 deletions

View File

@@ -88,20 +88,20 @@ static inline TimerGameTick::Ticks TicksPerTimetableUnit()
}
/**
* Determine if a vehicle should be shown as late, depending on the timetable display setting.
* @param v The vehicle in question.
* Determine if a vehicle should be shown as late or early, using a threshold depending on the timetable display setting.
* @param ticks The number of ticks that the vehicle is late or early.
* @param round_to_day When using ticks, if we should round up to the nearest day.
* @return True if the vehicle is later than the threshold.
* @return True if the vehicle is outside the "on time" threshold, either early or late.
*/
bool VehicleIsAboveLatenessThreshold(const Vehicle *v, bool round_to_day)
bool VehicleIsAboveLatenessThreshold(TimerGameTick::Ticks ticks, bool round_to_day)
{
switch (_settings_client.gui.timetable_mode) {
case TimetableMode::Days:
return v->lateness_counter > Ticks::DAY_TICKS;
return ticks > Ticks::DAY_TICKS;
case TimetableMode::Seconds:
return v->lateness_counter > Ticks::TICKS_PER_SECOND;
return ticks > Ticks::TICKS_PER_SECOND;
case TimetableMode::Ticks:
return v->lateness_counter > (round_to_day ? Ticks::DAY_TICKS : 0);
return ticks > (round_to_day ? Ticks::DAY_TICKS : 0);
default:
NOT_REACHED();
}
@@ -209,7 +209,7 @@ struct TimetableWindow : Window {
bool set_start_date_all; ///< Set start date using minutes text entry for all timetable entries (ctrl-click) action.
bool change_timetable_all; ///< Set wait time or speed for all timetable entries (ctrl-click) action.
TimetableWindow(WindowDesc *desc, WindowNumber window_number) :
TimetableWindow(WindowDesc &desc, WindowNumber window_number) :
Window(desc),
sel_index(-1),
vehicle(Vehicle::Get(window_number)),
@@ -250,7 +250,7 @@ struct TimetableWindow : Window {
return (travelling && v->lateness_counter < 0);
}
void UpdateWidgetSize(WidgetID widget, Dimension *size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension *fill, [[maybe_unused]] Dimension *resize) override
void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
{
switch (widget) {
case WID_VT_ARRIVAL_DEPARTURE_PANEL:
@@ -258,29 +258,29 @@ struct TimetableWindow : Window {
if (_settings_client.gui.timetable_mode == TimetableMode::Seconds) {
/* A five-digit number would fit a timetable lasting 2.7 real-world hours, which should be plenty. */
SetDParamMaxDigits(1, 4, FS_SMALL);
size->width = std::max(GetStringBoundingBox(STR_TIMETABLE_ARRIVAL_SECONDS_IN_FUTURE).width, GetStringBoundingBox(STR_TIMETABLE_DEPARTURE_SECONDS_IN_FUTURE).width) + WidgetDimensions::scaled.hsep_wide + padding.width;
size.width = std::max(GetStringBoundingBox(STR_TIMETABLE_ARRIVAL_SECONDS_IN_FUTURE).width, GetStringBoundingBox(STR_TIMETABLE_DEPARTURE_SECONDS_IN_FUTURE).width) + WidgetDimensions::scaled.hsep_wide + padding.width;
} else {
SetDParamMaxValue(1, TimerGameEconomy::DateAtStartOfYear(EconomyTime::MAX_YEAR), 0, FS_SMALL);
size->width = std::max(GetStringBoundingBox(STR_TIMETABLE_ARRIVAL_DATE).width, GetStringBoundingBox(STR_TIMETABLE_DEPARTURE_DATE).width) + WidgetDimensions::scaled.hsep_wide + padding.width;
size.width = std::max(GetStringBoundingBox(STR_TIMETABLE_ARRIVAL_DATE).width, GetStringBoundingBox(STR_TIMETABLE_DEPARTURE_DATE).width) + WidgetDimensions::scaled.hsep_wide + padding.width;
}
[[fallthrough]];
case WID_VT_ARRIVAL_DEPARTURE_SELECTION:
case WID_VT_TIMETABLE_PANEL:
resize->height = GetCharacterHeight(FS_NORMAL);
size->height = 8 * resize->height + padding.height;
resize.height = GetCharacterHeight(FS_NORMAL);
size.height = 8 * resize.height + padding.height;
break;
case WID_VT_SUMMARY_PANEL:
size->height = 2 * GetCharacterHeight(FS_NORMAL) + padding.height;
size.height = 2 * GetCharacterHeight(FS_NORMAL) + padding.height;
break;
}
}
int GetOrderFromTimetableWndPt(int y, [[maybe_unused]] const Vehicle *v)
{
int sel = this->vscroll->GetScrolledRowFromWidget(y, this, WID_VT_TIMETABLE_PANEL, WidgetDimensions::scaled.framerect.top);
if (sel == INT_MAX) return INVALID_ORDER;
int32_t sel = this->vscroll->GetScrolledRowFromWidget(y, this, WID_VT_TIMETABLE_PANEL, WidgetDimensions::scaled.framerect.top);
if (sel == INT32_MAX) return INVALID_ORDER;
assert(IsInsideBS(sel, 0, v->GetNumOrders() * 2));
return sel;
}
@@ -503,7 +503,7 @@ struct TimetableWindow : Window {
int selected = this->sel_index;
Rect tr = r.Shrink(WidgetDimensions::scaled.framerect);
bool show_late = this->show_expected && VehicleIsAboveLatenessThreshold(v, true);
bool show_late = this->show_expected && VehicleIsAboveLatenessThreshold(v->lateness_counter, true);
TimerGameTick::Ticks offset = show_late ? 0 : -v->lateness_counter;
for (int i = this->vscroll->GetPosition(); i / 2 < v->GetNumOrders(); ++i) { // note: i is also incremented in the loop
@@ -567,7 +567,13 @@ struct TimetableWindow : Window {
TimerGameTick::Ticks total_time = v->orders != nullptr ? v->orders->GetTimetableDurationIncomplete() : 0;
if (total_time != 0) {
SetTimetableParams(0, 1, total_time);
DrawString(tr, v->orders->IsCompleteTimetable() ? STR_TIMETABLE_TOTAL_TIME : STR_TIMETABLE_TOTAL_TIME_INCOMPLETE);
if (!v->orders->IsCompleteTimetable()) {
DrawString(tr, STR_TIMETABLE_TOTAL_TIME_INCOMPLETE);
} else if (total_time % TicksPerTimetableUnit() == 0) {
DrawString(tr, STR_TIMETABLE_TOTAL_TIME);
} else {
DrawString(tr, STR_TIMETABLE_APPROX_TIME);
}
}
tr.top += GetCharacterHeight(FS_NORMAL);
@@ -588,7 +594,7 @@ struct TimetableWindow : Window {
} else if (!HasBit(v->vehicle_flags, VF_TIMETABLE_STARTED)) {
/* We aren't running on a timetable yet. */
DrawString(tr, STR_TIMETABLE_STATUS_NOT_STARTED);
} else if (!VehicleIsAboveLatenessThreshold(v, false)) {
} else if (!VehicleIsAboveLatenessThreshold(abs(v->lateness_counter), false)) {
/* We are on time. */
DrawString(tr, STR_TIMETABLE_STATUS_ON_TIME);
} else {
@@ -742,12 +748,12 @@ struct TimetableWindow : Window {
this->SetDirty();
}
void OnQueryTextFinished(char *str) override
void OnQueryTextFinished(std::optional<std::string> str) override
{
if (str == nullptr) return;
if (!str.has_value()) return;
const Vehicle *v = this->vehicle;
uint64_t val = StrEmpty(str) ? 0 : std::strtoul(str, nullptr, 10);
uint64_t val = str->empty() ? 0 : std::strtoul(str->c_str(), nullptr, 10);
auto [order_id, mtf] = PackTimetableArgs(v, this->sel_index, query_widget == WID_VT_CHANGE_SPEED);
switch (query_widget) {
@@ -854,11 +860,11 @@ static constexpr NWidgetPart _nested_timetable_widgets[] = {
EndContainer(),
};
static WindowDesc _timetable_desc(__FILE__, __LINE__,
static WindowDesc _timetable_desc(
WDP_AUTO, "view_vehicle_timetable", 400, 130,
WC_VEHICLE_TIMETABLE, WC_VEHICLE_VIEW,
WDF_CONSTRUCTION,
std::begin(_nested_timetable_widgets), std::end(_nested_timetable_widgets)
_nested_timetable_widgets
);
/**
@@ -869,5 +875,5 @@ void ShowTimetableWindow(const Vehicle *v)
{
CloseWindowById(WC_VEHICLE_DETAILS, v->index, false);
CloseWindowById(WC_VEHICLE_ORDERS, v->index, false);
AllocateWindowDescFront<TimetableWindow>(&_timetable_desc, v->index);
AllocateWindowDescFront<TimetableWindow>(_timetable_desc, v->index);
}