Initial support for relative timetabling in wallclock mode

pull/661/head
Jonathan G Rennison 4 months ago
parent 7581ce0010
commit 91b3e9c1ab

@ -75,6 +75,8 @@ inline Ticks TimetableDisplayUnitSize()
{
if (_settings_time.time_in_minutes) {
return _settings_time.ticks_per_minute;
} else if (EconTime::UsingWallclockUnits()) {
return TICKS_PER_SECOND;
} else {
return DAY_TICKS * DayLengthFactor();
}

@ -26,6 +26,9 @@ static const int MONTHS_IN_YEAR = 12; ///< months per year
static const int SECONDS_PER_DAY = 2; ///< approximate seconds per day, not for precise calculations
/** Estimation of how many ticks fit in a single second. */
static const int TICKS_PER_SECOND = 1000 / 27 /*MILLISECONDS_PER_TICK*/;
using Ticks = int32_t; ///< The type to store ticks in
static constexpr Ticks INVALID_TICKS = -1; ///< Representation of an invalid number of ticks

@ -82,6 +82,8 @@ STR_UNIT_NAME_VELOCITY_METRIC :km/h
STR_UNIT_NAME_VELOCITY_SI :m/s
STR_UNIT_NAME_VELOCITY_GAMEUNITS :tiles/day
STR_UNITS_SECONDS_SHORT :{COMMA}{NBSP}s
STR_BUTTON_RENAME :{BLACK}Rename
STR_MEASURE_DIST_HEIGHTDIFF :{BLACK}Manhattan Distance: {NUM}{}Bird Fly Distance: {NUM}{}Distance from the nearest edge: {NUM}{}Height from sea level: {HEIGHT}{}Height difference: {HEIGHT}

@ -1571,7 +1571,14 @@ static void FormatString(StringBuilder builder, const char *str_arg, StringParam
auto tmp_params = MakeParameters(args.GetNextParameter<int64_t>());
FormatString(builder, GetStringPtr(STR_UNITS_TICKS), tmp_params);
} else {
StringID str = _settings_time.time_in_minutes ? STR_TIMETABLE_MINUTES : STR_UNITS_DAYS;
StringID str;
if (_settings_time.time_in_minutes) {
str = STR_TIMETABLE_MINUTES;
} else if (EconTime::UsingWallclockUnits()) {
str = STR_UNITS_SECONDS;
} else {
str = STR_UNITS_DAYS;
}
const int64_t ticks = args.GetNextParameter<int64_t>();
const int64_t ratio = TimetableDisplayUnitSize();
const int64_t units = ticks / ratio;
@ -1598,6 +1605,11 @@ static void FormatString(StringBuilder builder, const char *str_arg, StringParam
case SCC_TT_TIME: { // {TT_TIME}
if (_settings_time.time_in_minutes) {
FormatStateTicksHHMMString(builder, args.GetNextParameter<StateTicks>(), next_substr_case_index);
} else if (EconTime::UsingWallclockUnits()) {
StateTicks tick = args.GetNextParameter<StateTicks>();
StateTicksDelta offset = tick - _state_ticks;
auto tmp_params = MakeParameters(offset / TICKS_PER_SECOND);
FormatString(builder, GetStringPtr(STR_UNITS_SECONDS_SHORT), tmp_params);
} else {
FormatTinyOrISODate(builder, StateTicksToCalendarDate(args.GetNextParameter<StateTicks>()), STR_FORMAT_DATE_TINY);
}

@ -14,9 +14,6 @@
#include <chrono>
/** Estimation of how many ticks fit in a single second. */
static const uint TICKS_PER_SECOND = 1000 / 27 /*MILLISECONDS_PER_TICK*/;
/**
* Timer that represents the game-ticks. It will pause when the game is paused.
*

@ -403,7 +403,13 @@ struct TimetableWindow : GeneralVehicleWindow {
{
switch (widget) {
case WID_VT_ARRIVAL_DEPARTURE_PANEL:
SetDParamMaxValue(0, _settings_time.time_in_minutes ? 0 : EconTime::MAX_YEAR.base() * DAYS_IN_YEAR);
if (_settings_time.time_in_minutes) {
SetDParam(0, 0);
} else if (EconTime::UsingWallclockUnits()) {
SetDParam(0, _state_ticks + (TICKS_PER_SECOND * 9999));
} else {
SetDParam(0, EconTime::MAX_YEAR.base() * DAYS_IN_YEAR);
}
this->deparr_time_width = GetStringBoundingBox(STR_JUST_TT_TIME).width + 4;
this->deparr_abbr_width = std::max(GetStringBoundingBox(STR_TIMETABLE_ARRIVAL_ABBREVIATION).width, GetStringBoundingBox(STR_TIMETABLE_DEPARTURE_ABBREVIATION).width);
size->width = this->deparr_abbr_width + WidgetDimensions::scaled.hsep_wide + this->deparr_time_width + padding.width;
@ -812,9 +818,14 @@ struct TimetableWindow : GeneralVehicleWindow {
if (v->timetable_start != 0) {
/* We are running towards the first station so we can start the
* timetable at the given time. */
SetDParam(0, STR_JUST_TT_TIME);
SetDParam(1, v->timetable_start);
DrawString(tr, STR_TIMETABLE_STATUS_START_AT_DATE);
if (EconTime::UsingWallclockUnits() && !_settings_time.time_in_minutes) {
SetDParam(0, (v->timetable_start - _state_ticks) / TICKS_PER_SECOND);
DrawString(tr, STR_TIMETABLE_STATUS_START_IN_SECONDS);
} else {
SetDParam(0, STR_JUST_TT_TIME);
SetDParam(1, v->timetable_start);
DrawString(tr, STR_TIMETABLE_STATUS_START_AT_DATE);
}
} else if (!HasBit(v->vehicle_flags, VF_TIMETABLE_STARTED)) {
/* We aren't running on a timetable yet, so how can we be "on time"
* when we aren't even "on service"/"on duty"? */
@ -917,17 +928,22 @@ struct TimetableWindow : GeneralVehicleWindow {
break;
}
case WID_VT_START_DATE: // Change the date that the timetable starts.
if (_settings_time.time_in_minutes && _settings_client.gui.timetable_start_text_entry) {
this->set_start_date_all = v->orders->IsCompleteTimetable() && _ctrl_pressed;
case WID_VT_START_DATE: { // Change the date that the timetable starts.
bool set_all = _ctrl_pressed && v->orders->IsCompleteTimetable();
if (EconTime::UsingWallclockUnits() && !_settings_time.time_in_minutes) {
this->set_start_date_all = set_all;
ShowQueryString(STR_EMPTY, STR_TIMETABLE_START_SECONDS_QUERY, 6, this, CS_NUMERAL, QSF_ACCEPT_UNCHANGED);
} else if (_settings_time.time_in_minutes && _settings_client.gui.timetable_start_text_entry) {
this->set_start_date_all = set_all;
StringID str = STR_JUST_INT;
SetDParam(0, _settings_time.NowInTickMinutes().ClockHHMM());
ShowQueryString(str, STR_TIMETABLE_START, 31, this, CS_NUMERAL, QSF_ACCEPT_UNCHANGED);
} else {
ShowSetDateWindow(this, v->index | (_ctrl_pressed ? 1U << 20 : 0),
ShowSetDateWindow(this, v->index | (set_all ? 1U << 20 : 0),
_state_ticks, EconTime::CurYear(), EconTime::CurYear() + 15, ChangeTimetableStartCallback);
}
break;
}
case WID_VT_CHANGE_TIME: { // "Wait For" button.
int selected = this->sel_index;
@ -1131,7 +1147,12 @@ struct TimetableWindow : GeneralVehicleWindow {
if (StrEmpty(str)) break;
char *end;
int32_t val = std::strtol(str, &end, 10);
if (val >= 0 && end && *end == 0) {
if (!(end != nullptr && *end == 0)) break;
if (EconTime::UsingWallclockUnits() && !_settings_time.time_in_minutes) {
ChangeTimetableStartIntl(v->index | (this->set_start_date_all ? 1 << 20 : 0), _state_ticks + (val * TICKS_PER_SECOND));
break;
}
if (val >= 0) {
uint minutes = (val % 100) % 60;
uint hours = (val / 100) % 24;
const TickMinutes now = _settings_time.NowInTickMinutes();

Loading…
Cancel
Save