Changeset - r28559:3924f7d56927
src/cheat_gui.cpp
Show inline comments
 
@@ -113,13 +113,15 @@ static int32_t ClickChangeDateCheat(int3
 
	/* Shift cached dates before we change the date. */
 
	for (auto v : Vehicle::Iterate()) v->ShiftDates(new_economy_date - TimerGameEconomy::date);
 
	LinkGraphSchedule::instance.ShiftDates(new_economy_date - TimerGameEconomy::date);
 

	
 
	/* Now it's safe to actually change the date. */
 
	TimerGameCalendar::SetDate(new_calendar_date, TimerGameCalendar::date_fract);
 
	TimerGameEconomy::SetDate(new_economy_date, TimerGameEconomy::date_fract);
 

	
 
	/* If not using wallclock units, we keep economy date in sync with calendar date and must change it also. */
 
	if (!TimerGameEconomy::UsingWallclockUnits()) TimerGameEconomy::SetDate(new_economy_date, TimerGameEconomy::date_fract);
 

	
 
	CalendarEnginesMonthlyLoop();
 
	SetWindowDirty(WC_STATUS_BAR, 0);
 
	InvalidateWindowClassesData(WC_BUILD_STATION, 0);
 
	InvalidateWindowClassesData(WC_BUS_STATION, 0);
 
	InvalidateWindowClassesData(WC_TRUCK_STATION, 0);
src/company_gui.cpp
Show inline comments
 
@@ -135,13 +135,13 @@ static uint GetTotalCategoriesHeight()
 
/**
 
 * Get the required width of the "categories" column, equal to the widest element.
 
 * @return The required width in pixels.
 
 */
 
static uint GetMaxCategoriesWidth()
 
{
 
	uint max_width = 0;
 
	uint max_width = GetStringBoundingBox(STR_FINANCES_YEAR_CAPTION).width;
 

	
 
	/* Loop through categories to check max widths. */
 
	for (const ExpensesList &list : _expenses_list_types) {
 
		/* Title of category */
 
		max_width = std::max(max_width, GetStringBoundingBox(list.title).width);
 
		/* Entries in category */
 
@@ -170,14 +170,16 @@ static void DrawCategory(const Rect &r, 
 
 * Draw the expenses categories.
 
 * @param r Available space for drawing.
 
 * @note The environment must provide padding at the left and right of \a r.
 
 */
 
static void DrawCategories(const Rect &r)
 
{
 
	/* Start with an empty space in the year row, plus the blockspace under the year. */
 
	int y = r.top + GetCharacterHeight(FS_NORMAL) + WidgetDimensions::scaled.vsep_wide;
 
	int y = r.top;
 
	/* Draw description of 12-minute economic period. */
 
	DrawString(r.left, r.right, y, (STR_FINANCES_YEAR_CAPTION), TC_FROMSTRING, SA_LEFT, true);
 
	y += GetCharacterHeight(FS_NORMAL) + WidgetDimensions::scaled.vsep_wide;
 

	
 
	for (const ExpensesList &list : _expenses_list_types) {
 
		/* Draw category title and advance y */
 
		DrawString(r.left, r.right, y, list.title, TC_FROMSTRING, SA_LEFT);
 
		y += GetCharacterHeight(FS_NORMAL);
 

	
src/graph_gui.cpp
Show inline comments
 
@@ -167,12 +167,15 @@ protected:
 
	static const int GRAPH_BASE_COLOUR      =  GREY_SCALE(2);
 
	static const int GRAPH_GRID_COLOUR      =  GREY_SCALE(3);
 
	static const int GRAPH_AXIS_LINE_COLOUR =  GREY_SCALE(1);
 
	static const int GRAPH_ZERO_LINE_COLOUR =  GREY_SCALE(8);
 
	static const int GRAPH_YEAR_LINE_COLOUR =  GREY_SCALE(5);
 
	static const int GRAPH_NUM_MONTHS       =  24; ///< Number of months displayed in the graph.
 
	static const int PAYMENT_GRAPH_X_STEP_DAYS    = 20; ///< X-axis step label for cargo payment rates "Days in transit".
 
	static const int PAYMENT_GRAPH_X_STEP_SECONDS = 10; ///< X-axis step label for cargo payment rates "Seconds in transit".
 
	static const int ECONOMY_QUARTER_MINUTES = 3;  ///< Minutes per economic quarter.
 

	
 
	static const TextColour GRAPH_AXIS_LABEL_COLOUR = TC_BLACK; ///< colour of the graph axis label.
 

	
 
	static const int MIN_GRAPH_NUM_LINES_Y  =   9; ///< Minimal number of horizontal lines to draw.
 
	static const int MIN_GRID_PIXEL_SIZE    =  20; ///< Minimum distance between graph lines.
 

	
 
@@ -333,14 +336,19 @@ protected:
 

	
 
		/* Draw the vertical grid lines. */
 

	
 
		/* Don't draw the first line, as that's where the axis will be. */
 
		x = r.left + x_sep;
 

	
 
		for (int i = 0; i < this->num_vert_lines; i++) {
 
			GfxFillRect(x, r.top, x, r.bottom, GRAPH_GRID_COLOUR);
 
		int grid_colour = GRAPH_GRID_COLOUR;
 
		for (int i = 1; i < this->num_vert_lines + 1; i++) {
 
			/* If using wallclock units, we separate periods with a lighter line. */
 
			if (TimerGameEconomy::UsingWallclockUnits()) {
 
				grid_colour = (i % 4 == 0) ? GRAPH_YEAR_LINE_COLOUR : GRAPH_GRID_COLOUR;
 
			}
 
			GfxFillRect(x, r.top, x, r.bottom, grid_colour);
 
			x += x_sep;
 
		}
 

	
 
		/* Draw the horizontal grid lines. */
 
		y = r.bottom;
 

	
 
@@ -396,13 +404,13 @@ protected:
 
					/* Draw a lighter grid line between years. Top and bottom adjustments ensure we don't draw over top and bottom horizontal grid lines. */
 
					GfxFillRect(x + x_sep, r.top + 1, x + x_sep, r.bottom - 1, GRAPH_YEAR_LINE_COLOUR);
 
				}
 
				x += x_sep;
 
			}
 
		} else {
 
			/* Draw x-axis labels for graphs not based on quarterly performance (cargo payment rates). */
 
			/* Draw x-axis labels for graphs not based on quarterly performance (cargo payment rates, and all graphs when using wallclock units). */
 
			x = r.left;
 
			y = r.bottom + ScaleGUITrad(2);
 
			uint16_t label = this->x_values_start;
 

	
 
			for (int i = 0; i < this->num_on_x_axis; i++) {
 
				SetDParam(0, label);
 
@@ -619,12 +627,18 @@ public:
 
/********************/
 

	
 
struct OperatingProfitGraphWindow : BaseGraphWindow {
 
	OperatingProfitGraphWindow(WindowDesc *desc, WindowNumber window_number) :
 
			BaseGraphWindow(desc, WID_CV_GRAPH, STR_JUST_CURRENCY_SHORT)
 
	{
 
		this->num_on_x_axis = GRAPH_NUM_MONTHS;
 
		this->num_vert_lines = GRAPH_NUM_MONTHS;
 
		this->x_values_start = ECONOMY_QUARTER_MINUTES;
 
		this->x_values_increment = ECONOMY_QUARTER_MINUTES;
 
		this->draw_dates = !TimerGameEconomy::UsingWallclockUnits();
 

	
 
		this->InitializeWindow(window_number);
 
	}
 

	
 
	OverflowSafeInt64 GetGraphData(const Company *c, int j) override
 
	{
 
		return c->old_economy[j].income + c->old_economy[j].expenses;
 
@@ -638,16 +652,18 @@ static constexpr NWidgetPart _nested_ope
 
		NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CV_KEY_BUTTON), SetMinimalSize(50, 0), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP),
 
		NWidget(WWT_SHADEBOX, COLOUR_BROWN),
 
		NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
 
		NWidget(WWT_STICKYBOX, COLOUR_BROWN),
 
	EndContainer(),
 
	NWidget(WWT_PANEL, COLOUR_BROWN, WID_CV_BACKGROUND),
 
		NWidget(NWID_HORIZONTAL),
 
		NWidget(NWID_VERTICAL),
 
			NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CV_GRAPH), SetMinimalSize(576, 160), SetFill(1, 1), SetResize(1, 1),
 
			NWidget(NWID_VERTICAL),
 
				NWidget(NWID_SPACER), SetFill(0, 1), SetResize(0, 1),
 
			NWidget(NWID_HORIZONTAL),
 
				NWidget(NWID_SPACER), SetMinimalSize(12, 0), SetFill(1, 0), SetResize(1, 0),
 
				NWidget(WWT_TEXT, COLOUR_BROWN, WID_CV_FOOTER), SetMinimalSize(0, 6), SetPadding(2, 0, 2, 0), SetDataTip(STR_GRAPH_LAST_72_MINUTES_TIME_LABEL, STR_NULL),
 
				NWidget(NWID_SPACER), SetFill(1, 0), SetResize(1, 0),
 
				NWidget(WWT_RESIZEBOX, COLOUR_BROWN, WID_CV_RESIZE), SetDataTip(RWV_HIDE_BEVEL, STR_TOOLTIP_RESIZE),
 
			EndContainer(),
 
		EndContainer(),
 
	EndContainer(),
 
};
 

	
 
@@ -670,12 +686,18 @@ void ShowOperatingProfitGraph()
 
/****************/
 

	
 
struct IncomeGraphWindow : BaseGraphWindow {
 
	IncomeGraphWindow(WindowDesc *desc, WindowNumber window_number) :
 
			BaseGraphWindow(desc, WID_CV_GRAPH, STR_JUST_CURRENCY_SHORT)
 
	{
 
		this->num_on_x_axis = GRAPH_NUM_MONTHS;
 
		this->num_vert_lines = GRAPH_NUM_MONTHS;
 
		this->x_values_start = ECONOMY_QUARTER_MINUTES;
 
		this->x_values_increment = ECONOMY_QUARTER_MINUTES;
 
		this->draw_dates = !TimerGameEconomy::UsingWallclockUnits();
 

	
 
		this->InitializeWindow(window_number);
 
	}
 

	
 
	OverflowSafeInt64 GetGraphData(const Company *c, int j) override
 
	{
 
		return c->old_economy[j].income;
 
@@ -689,16 +711,18 @@ static constexpr NWidgetPart _nested_inc
 
		NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CV_KEY_BUTTON), SetMinimalSize(50, 0), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP),
 
		NWidget(WWT_SHADEBOX, COLOUR_BROWN),
 
		NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
 
		NWidget(WWT_STICKYBOX, COLOUR_BROWN),
 
	EndContainer(),
 
	NWidget(WWT_PANEL, COLOUR_BROWN, WID_CV_BACKGROUND),
 
		NWidget(NWID_HORIZONTAL),
 
		NWidget(NWID_VERTICAL),
 
			NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CV_GRAPH), SetMinimalSize(576, 128), SetFill(1, 1), SetResize(1, 1),
 
			NWidget(NWID_VERTICAL),
 
				NWidget(NWID_SPACER), SetFill(0, 1), SetResize(0, 1),
 
			NWidget(NWID_HORIZONTAL),
 
				NWidget(NWID_SPACER), SetMinimalSize(12, 0), SetFill(1, 0), SetResize(1, 0),
 
				NWidget(WWT_TEXT, COLOUR_BROWN, WID_CV_FOOTER), SetMinimalSize(0, 6), SetPadding(2, 0, 2, 0), SetDataTip(STR_GRAPH_LAST_72_MINUTES_TIME_LABEL, STR_NULL),
 
				NWidget(NWID_SPACER), SetFill(1, 0), SetResize(1, 0),
 
				NWidget(WWT_RESIZEBOX, COLOUR_BROWN, WID_CV_RESIZE), SetDataTip(RWV_HIDE_BEVEL, STR_TOOLTIP_RESIZE),
 
			EndContainer(),
 
		EndContainer(),
 
	EndContainer(),
 
};
 

	
 
@@ -719,12 +743,18 @@ void ShowIncomeGraph()
 
/*******************/
 

	
 
struct DeliveredCargoGraphWindow : BaseGraphWindow {
 
	DeliveredCargoGraphWindow(WindowDesc *desc, WindowNumber window_number) :
 
			BaseGraphWindow(desc, WID_CV_GRAPH, STR_JUST_COMMA)
 
	{
 
		this->num_on_x_axis = GRAPH_NUM_MONTHS;
 
		this->num_vert_lines = GRAPH_NUM_MONTHS;
 
		this->x_values_start = ECONOMY_QUARTER_MINUTES;
 
		this->x_values_increment = ECONOMY_QUARTER_MINUTES;
 
		this->draw_dates = !TimerGameEconomy::UsingWallclockUnits();
 

	
 
		this->InitializeWindow(window_number);
 
	}
 

	
 
	OverflowSafeInt64 GetGraphData(const Company *c, int j) override
 
	{
 
		return c->old_economy[j].delivered_cargo.GetSum<OverflowSafeInt64>();
 
@@ -738,16 +768,18 @@ static constexpr NWidgetPart _nested_del
 
		NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CV_KEY_BUTTON), SetMinimalSize(50, 0), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP),
 
		NWidget(WWT_SHADEBOX, COLOUR_BROWN),
 
		NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
 
		NWidget(WWT_STICKYBOX, COLOUR_BROWN),
 
	EndContainer(),
 
	NWidget(WWT_PANEL, COLOUR_BROWN, WID_CV_BACKGROUND),
 
		NWidget(NWID_HORIZONTAL),
 
		NWidget(NWID_VERTICAL),
 
			NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CV_GRAPH), SetMinimalSize(576, 128), SetFill(1, 1), SetResize(1, 1),
 
			NWidget(NWID_VERTICAL),
 
				NWidget(NWID_SPACER), SetFill(0, 1), SetResize(0, 1),
 
			NWidget(NWID_HORIZONTAL),
 
				NWidget(NWID_SPACER), SetMinimalSize(12, 0), SetFill(1, 0), SetResize(1, 0),
 
				NWidget(WWT_TEXT, COLOUR_BROWN, WID_CV_FOOTER), SetMinimalSize(0, 6), SetPadding(2, 0, 2, 0), SetDataTip(STR_GRAPH_LAST_72_MINUTES_TIME_LABEL, STR_NULL),
 
				NWidget(NWID_SPACER), SetFill(1, 0), SetResize(1, 0),
 
				NWidget(WWT_RESIZEBOX, COLOUR_BROWN, WID_CV_RESIZE), SetDataTip(RWV_HIDE_BEVEL, STR_TOOLTIP_RESIZE),
 
			EndContainer(),
 
		EndContainer(),
 
	EndContainer(),
 
};
 

	
 
@@ -768,12 +800,18 @@ void ShowDeliveredCargoGraph()
 
/***********************/
 

	
 
struct PerformanceHistoryGraphWindow : BaseGraphWindow {
 
	PerformanceHistoryGraphWindow(WindowDesc *desc, WindowNumber window_number) :
 
			BaseGraphWindow(desc, WID_PHG_GRAPH, STR_JUST_COMMA)
 
	{
 
		this->num_on_x_axis = GRAPH_NUM_MONTHS;
 
		this->num_vert_lines = GRAPH_NUM_MONTHS;
 
		this->x_values_start = ECONOMY_QUARTER_MINUTES;
 
		this->x_values_increment = ECONOMY_QUARTER_MINUTES;
 
		this->draw_dates = !TimerGameEconomy::UsingWallclockUnits();
 

	
 
		this->InitializeWindow(window_number);
 
	}
 

	
 
	OverflowSafeInt64 GetGraphData(const Company *c, int j) override
 
	{
 
		return c->old_economy[j].performance_history;
 
@@ -794,16 +832,18 @@ static constexpr NWidgetPart _nested_per
 
		NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_PHG_KEY), SetMinimalSize(50, 0), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP),
 
		NWidget(WWT_SHADEBOX, COLOUR_BROWN),
 
		NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
 
		NWidget(WWT_STICKYBOX, COLOUR_BROWN),
 
	EndContainer(),
 
	NWidget(WWT_PANEL, COLOUR_BROWN, WID_PHG_BACKGROUND),
 
		NWidget(NWID_HORIZONTAL),
 
		NWidget(NWID_VERTICAL),
 
			NWidget(WWT_EMPTY, COLOUR_BROWN, WID_PHG_GRAPH), SetMinimalSize(576, 224), SetFill(1, 1), SetResize(1, 1),
 
			NWidget(NWID_VERTICAL),
 
				NWidget(NWID_SPACER), SetFill(0, 1), SetResize(0, 1),
 
			NWidget(NWID_HORIZONTAL),
 
				NWidget(NWID_SPACER), SetMinimalSize(12, 0), SetFill(1, 0), SetResize(1, 0),
 
				NWidget(WWT_TEXT, COLOUR_BROWN, WID_PHG_FOOTER), SetMinimalSize(0, 6), SetPadding(2, 0, 2, 0), SetDataTip(STR_GRAPH_LAST_72_MINUTES_TIME_LABEL, STR_NULL),
 
				NWidget(NWID_SPACER), SetFill(1, 0), SetResize(1, 0),
 
				NWidget(WWT_RESIZEBOX, COLOUR_BROWN, WID_PHG_RESIZE), SetDataTip(RWV_HIDE_BEVEL, STR_TOOLTIP_RESIZE),
 
			EndContainer(),
 
		EndContainer(),
 
	EndContainer(),
 
};
 

	
 
@@ -824,12 +864,18 @@ void ShowPerformanceHistoryGraph()
 
/*****************/
 

	
 
struct CompanyValueGraphWindow : BaseGraphWindow {
 
	CompanyValueGraphWindow(WindowDesc *desc, WindowNumber window_number) :
 
			BaseGraphWindow(desc, WID_CV_GRAPH, STR_JUST_CURRENCY_SHORT)
 
	{
 
		this->num_on_x_axis = GRAPH_NUM_MONTHS;
 
		this->num_vert_lines = GRAPH_NUM_MONTHS;
 
		this->x_values_start = ECONOMY_QUARTER_MINUTES;
 
		this->x_values_increment = ECONOMY_QUARTER_MINUTES;
 
		this->draw_dates = !TimerGameEconomy::UsingWallclockUnits();
 

	
 
		this->InitializeWindow(window_number);
 
	}
 

	
 
	OverflowSafeInt64 GetGraphData(const Company *c, int j) override
 
	{
 
		return c->old_economy[j].company_value;
 
@@ -843,16 +889,18 @@ static constexpr NWidgetPart _nested_com
 
		NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CV_KEY_BUTTON), SetMinimalSize(50, 0), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP),
 
		NWidget(WWT_SHADEBOX, COLOUR_BROWN),
 
		NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
 
		NWidget(WWT_STICKYBOX, COLOUR_BROWN),
 
	EndContainer(),
 
	NWidget(WWT_PANEL, COLOUR_BROWN, WID_CV_BACKGROUND),
 
		NWidget(NWID_HORIZONTAL),
 
		NWidget(NWID_VERTICAL),
 
			NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CV_GRAPH), SetMinimalSize(576, 224), SetFill(1, 1), SetResize(1, 1),
 
			NWidget(NWID_VERTICAL),
 
				NWidget(NWID_SPACER), SetFill(0, 1), SetResize(0, 1),
 
			NWidget(NWID_HORIZONTAL),
 
				NWidget(NWID_SPACER), SetMinimalSize(12, 0), SetFill(1, 0), SetResize(1, 0),
 
				NWidget(WWT_TEXT, COLOUR_BROWN, WID_CV_FOOTER), SetMinimalSize(0, 6), SetPadding(2, 0, 2, 0), SetDataTip(STR_GRAPH_LAST_72_MINUTES_TIME_LABEL, STR_NULL),
 
				NWidget(NWID_SPACER), SetFill(1, 0), SetResize(1, 0),
 
				NWidget(WWT_RESIZEBOX, COLOUR_BROWN, WID_CV_RESIZE), SetDataTip(RWV_HIDE_BEVEL, STR_TOOLTIP_RESIZE),
 
			EndContainer(),
 
		EndContainer(),
 
	EndContainer(),
 
};
 

	
 
@@ -880,14 +928,15 @@ struct PaymentRatesGraphWindow : BaseGra
 
	PaymentRatesGraphWindow(WindowDesc *desc, WindowNumber window_number) :
 
			BaseGraphWindow(desc, WID_CPR_GRAPH, STR_JUST_CURRENCY_SHORT)
 
	{
 
		this->num_on_x_axis = 20;
 
		this->num_vert_lines = 20;
 
		this->draw_dates = false;
 
		this->x_values_start     = 10;
 
		this->x_values_increment = 10;
 
		/* The x-axis is labeled in either seconds or days. A day is two seconds, so we adjust the label if needed. */
 
		this->x_values_start     = (TimerGameEconomy::UsingWallclockUnits() ? PAYMENT_GRAPH_X_STEP_SECONDS : PAYMENT_GRAPH_X_STEP_DAYS);
 
		this->x_values_increment = (TimerGameEconomy::UsingWallclockUnits() ? PAYMENT_GRAPH_X_STEP_SECONDS : PAYMENT_GRAPH_X_STEP_DAYS);
 

	
 
		this->CreateNestedTree();
 
		this->vscroll = this->GetScrollbar(WID_CPR_MATRIX_SCROLLBAR);
 
		this->vscroll->SetCount(_sorted_standard_cargo_specs.size());
 

	
 
		/* Initialise the dataset */
 
@@ -1082,13 +1131,13 @@ static constexpr NWidgetPart _nested_car
 
				NWidget(NWID_SPACER), SetMinimalSize(0, 24), SetFill(0, 1),
 
			EndContainer(),
 
			NWidget(NWID_SPACER), SetMinimalSize(5, 0), SetFill(0, 1), SetResize(0, 1),
 
		EndContainer(),
 
		NWidget(NWID_HORIZONTAL),
 
			NWidget(NWID_SPACER), SetMinimalSize(12, 0), SetFill(1, 0), SetResize(1, 0),
 
			NWidget(WWT_TEXT, COLOUR_BROWN, WID_CPR_FOOTER), SetMinimalSize(0, 6), SetPadding(2, 0, 2, 0), SetDataTip(STR_GRAPH_CARGO_PAYMENT_RATES_X_LABEL, STR_NULL),
 
			NWidget(WWT_TEXT, COLOUR_BROWN, WID_CPR_FOOTER), SetMinimalSize(0, 6), SetPadding(2, 0, 2, 0), SetDataTip(STR_GRAPH_CARGO_PAYMENT_RATES_TIME_LABEL, STR_NULL),
 
			NWidget(NWID_SPACER), SetFill(1, 0), SetResize(1, 0),
 
			NWidget(WWT_RESIZEBOX, COLOUR_BROWN, WID_CPR_RESIZE), SetDataTip(RWV_HIDE_BEVEL, STR_TOOLTIP_RESIZE),
 
		EndContainer(),
 
	EndContainer(),
 
};
 

	
src/lang/english.txt
Show inline comments
 
@@ -211,13 +211,14 @@ STR_COLOUR_SECONDARY_SAME_AS_PRIMARY    
 

	
 

	
 
# Units used in OpenTTD
 
STR_UNITS_VELOCITY_IMPERIAL                                     :{DECIMAL}{NBSP}mph
 
STR_UNITS_VELOCITY_METRIC                                       :{DECIMAL}{NBSP}km/h
 
STR_UNITS_VELOCITY_SI                                           :{DECIMAL}{NBSP}m/s
 
STR_UNITS_VELOCITY_GAMEUNITS                                    :{DECIMAL}{NBSP}tiles/day
 
STR_UNITS_VELOCITY_GAMEUNITS_DAY                                :{DECIMAL}{NBSP}tiles/day
 
STR_UNITS_VELOCITY_GAMEUNITS_SEC                                :{DECIMAL}{NBSP}tiles/sec
 
STR_UNITS_VELOCITY_KNOTS                                        :{DECIMAL}{NBSP}knots
 

	
 
STR_UNITS_POWER_IMPERIAL                                        :{DECIMAL}{NBSP}hp
 
STR_UNITS_POWER_METRIC                                          :{DECIMAL}{NBSP}hp
 
STR_UNITS_POWER_SI                                              :{DECIMAL}{NBSP}kW
 

	
 
@@ -252,16 +253,23 @@ STR_UNITS_FORCE_METRIC                  
 
STR_UNITS_FORCE_SI                                              :{DECIMAL}{NBSP}kN
 

	
 
STR_UNITS_HEIGHT_IMPERIAL                                       :{DECIMAL}{NBSP}ft
 
STR_UNITS_HEIGHT_METRIC                                         :{DECIMAL}{NBSP}m
 
STR_UNITS_HEIGHT_SI                                             :{DECIMAL}{NBSP}m
 

	
 
# Time units used in string control characters
 
STR_UNITS_DAYS                                                  :{COMMA}{NBSP}day{P "" s}
 
STR_UNITS_SECONDS                                               :{COMMA}{NBSP}second{P "" s}
 
STR_UNITS_TICKS                                                 :{COMMA}{NBSP}tick{P "" s}
 

	
 
STR_UNITS_MONTHS                                                :{NUM}{NBSP}month{P "" s}
 
STR_UNITS_MINUTES                                               :{NUM}{NBSP}minute{P "" s}
 

	
 
STR_UNITS_YEARS                                                 :{NUM}{NBSP}year{P "" s}
 
STR_UNITS_PERIODS                                               :{NUM}{NBSP}period{P "" s}
 

	
 
# Common window strings
 
STR_LIST_FILTER_TITLE                                           :{BLACK}Filter:
 
STR_LIST_FILTER_OSKTITLE                                        :{BLACK}Enter one or more keywords to filter the list for
 
STR_LIST_FILTER_TOOLTIP                                         :{BLACK}Enter one or more keywords to filter the list for
 

	
 
STR_TOOLTIP_GROUP_ORDER                                         :{BLACK}Select grouping order
 
@@ -320,14 +328,14 @@ STR_SORT_BY_CAPTION_DATE                
 
# These are used in dropdowns
 
STR_SORT_BY_NAME                                                :Name
 
STR_SORT_BY_PRODUCTION                                          :Production
 
STR_SORT_BY_TYPE                                                :Type
 
STR_SORT_BY_TRANSPORTED                                         :Transported
 
STR_SORT_BY_NUMBER                                              :Number
 
STR_SORT_BY_PROFIT_LAST_YEAR                                    :Profit last year
 
STR_SORT_BY_PROFIT_THIS_YEAR                                    :Profit this year
 
STR_SORT_BY_PROFIT_LAST_YEAR                                    :Profit last {TKM year period}
 
STR_SORT_BY_PROFIT_THIS_YEAR                                    :Profit this {TKM year period}
 
STR_SORT_BY_AGE                                                 :Age
 
STR_SORT_BY_RELIABILITY                                         :Reliability
 
STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE                        :Total capacity per cargo type
 
STR_SORT_BY_MAX_SPEED                                           :Maximum speed
 
STR_SORT_BY_MODEL                                               :Model
 
STR_SORT_BY_VALUE                                               :Value
 
@@ -348,16 +356,16 @@ STR_SORT_BY_RUNNING_COST                
 
STR_SORT_BY_POWER_VS_RUNNING_COST                               :Power/Running cost
 
STR_SORT_BY_CARGO_CAPACITY                                      :Cargo capacity
 
STR_SORT_BY_RANGE                                               :Range
 
STR_SORT_BY_POPULATION                                          :Population
 
STR_SORT_BY_RATING                                              :Rating
 
STR_SORT_BY_NUM_VEHICLES                                        :Number of vehicles
 
STR_SORT_BY_TOTAL_PROFIT_LAST_YEAR                              :Total profit last year
 
STR_SORT_BY_TOTAL_PROFIT_THIS_YEAR                              :Total profit this year
 
STR_SORT_BY_AVERAGE_PROFIT_LAST_YEAR                            :Average profit last year
 
STR_SORT_BY_AVERAGE_PROFIT_THIS_YEAR                            :Average profit this year
 
STR_SORT_BY_TOTAL_PROFIT_LAST_YEAR                              :Total profit last {TKM year period}
 
STR_SORT_BY_TOTAL_PROFIT_THIS_YEAR                              :Total profit this {TKM year period}
 
STR_SORT_BY_AVERAGE_PROFIT_LAST_YEAR                            :Average profit last {TKM year period}
 
STR_SORT_BY_AVERAGE_PROFIT_THIS_YEAR                            :Average profit this {TKM year period}
 

	
 
# Group by options for vehicle list
 
STR_GROUP_BY_NONE                                               :None
 
STR_GROUP_BY_SHARED_ORDERS                                      :Shared orders
 

	
 
# Order button in shared orders vehicle list
 
@@ -612,14 +620,16 @@ STR_GRAPH_Y_LABEL_NUMBER                
 
STR_GRAPH_OPERATING_PROFIT_CAPTION                              :{WHITE}Operating Profit Graph
 
STR_GRAPH_INCOME_CAPTION                                        :{WHITE}Income Graph
 
STR_GRAPH_CARGO_DELIVERED_CAPTION                               :{WHITE}Units of cargo delivered
 
STR_GRAPH_COMPANY_PERFORMANCE_RATINGS_CAPTION                   :{WHITE}Company performance ratings (maximum rating=1000)
 
STR_GRAPH_COMPANY_VALUES_CAPTION                                :{WHITE}Company Value Graph
 

	
 
STR_GRAPH_LAST_72_MINUTES_TIME_LABEL                            :{TINY_FONT}{BLACK}{TKM "" "Last 72 minutes"}
 

	
 
STR_GRAPH_CARGO_PAYMENT_RATES_CAPTION                           :{WHITE}Cargo Payment Rates
 
STR_GRAPH_CARGO_PAYMENT_RATES_X_LABEL                           :{TINY_FONT}{BLACK}Days in transit
 
STR_GRAPH_CARGO_PAYMENT_RATES_TIME_LABEL                        :{TINY_FONT}{BLACK}{TKM Days Seconds} in transit
 
STR_GRAPH_CARGO_PAYMENT_RATES_TITLE                             :{TINY_FONT}{BLACK}Payment for delivering 10 units (or 10,000 litres) of cargo a distance of 20 squares
 
STR_GRAPH_CARGO_ENABLE_ALL                                      :{TINY_FONT}{BLACK}Enable all
 
STR_GRAPH_CARGO_DISABLE_ALL                                     :{TINY_FONT}{BLACK}Disable all
 
STR_GRAPH_CARGO_TOOLTIP_ENABLE_ALL                              :{BLACK}Display all cargoes on the cargo payment rates graph
 
STR_GRAPH_CARGO_TOOLTIP_DISABLE_ALL                             :{BLACK}Display no cargoes on the cargo payment rates graph
 
STR_GRAPH_CARGO_PAYMENT_TOGGLE_CARGO                            :{BLACK}Toggle graph for cargo type on/off
 
@@ -662,15 +672,15 @@ STR_PERFORMANCE_DETAIL_DELIVERED        
 
STR_PERFORMANCE_DETAIL_CARGO                                    :{BLACK}Cargo:
 
STR_PERFORMANCE_DETAIL_MONEY                                    :{BLACK}Money:
 
STR_PERFORMANCE_DETAIL_LOAN                                     :{BLACK}Loan:
 
STR_PERFORMANCE_DETAIL_TOTAL                                    :{BLACK}Total:
 

	
 
###length 10
 
STR_PERFORMANCE_DETAIL_VEHICLES_TOOLTIP                         :{BLACK}Number of vehicles that turned a profit last year. This includes road vehicles, trains, ships and aircraft
 
STR_PERFORMANCE_DETAIL_VEHICLES_TOOLTIP                         :{BLACK}Number of vehicles that turned a profit last {TKM year period}. This includes road vehicles, trains, ships and aircraft
 
STR_PERFORMANCE_DETAIL_STATIONS_TOOLTIP                         :{BLACK}Number of recently-serviced stations. Train stations, bus stops, airports and so on are counted separately even if they belong to the same station
 
STR_PERFORMANCE_DETAIL_MIN_PROFIT_TOOLTIP                       :{BLACK}The profit of the vehicle with the lowest income (only vehicles older than two years are considered)
 
STR_PERFORMANCE_DETAIL_MIN_PROFIT_TOOLTIP                       :{BLACK}The profit of the vehicle with the lowest income (only vehicles older than two {TKM years periods} are considered)
 
STR_PERFORMANCE_DETAIL_MIN_INCOME_TOOLTIP                       :{BLACK}Amount of cash made in the quarter with the lowest profit of the last 12 quarters
 
STR_PERFORMANCE_DETAIL_MAX_INCOME_TOOLTIP                       :{BLACK}Amount of cash made in the quarter with the highest profit of the last 12 quarters
 
STR_PERFORMANCE_DETAIL_DELIVERED_TOOLTIP                        :{BLACK}Units of cargo delivered in the last four quarters
 
STR_PERFORMANCE_DETAIL_CARGO_TOOLTIP                            :{BLACK}Number of types of cargo delivered in the last quarter
 
STR_PERFORMANCE_DETAIL_MONEY_TOOLTIP                            :{BLACK}Amount of money this company has in the bank
 
STR_PERFORMANCE_DETAIL_LOAN_TOOLTIP                             :{BLACK}The amount of money this company has taken on loan
 
@@ -896,13 +906,13 @@ STR_NEWS_PLANE_USES_TOO_SHORT_RUNWAY    
 

	
 
STR_NEWS_VEHICLE_IS_GETTING_OLD                                 :{WHITE}{VEHICLE} is getting old
 
STR_NEWS_VEHICLE_IS_GETTING_VERY_OLD                            :{WHITE}{VEHICLE} is getting very old
 
STR_NEWS_VEHICLE_IS_GETTING_VERY_OLD_AND                        :{WHITE}{VEHICLE} is getting very old and urgently needs replacing
 
STR_NEWS_TRAIN_IS_STUCK                                         :{WHITE}{VEHICLE} can't find a path to continue
 
STR_NEWS_VEHICLE_IS_LOST                                        :{WHITE}{VEHICLE} is lost
 
STR_NEWS_VEHICLE_IS_UNPROFITABLE                                :{WHITE}{VEHICLE}'s profit last year was {CURRENCY_LONG}
 
STR_NEWS_VEHICLE_IS_UNPROFITABLE                                :{WHITE}{VEHICLE}'s profit last {TKM year period} was {CURRENCY_LONG}
 
STR_NEWS_AIRCRAFT_DEST_TOO_FAR                                  :{WHITE}{VEHICLE} can't get to the next destination because it is out of range
 

	
 
STR_NEWS_ORDER_REFIT_FAILED                                     :{WHITE}{VEHICLE} stopped because an ordered refit failed
 
STR_NEWS_VEHICLE_AUTORENEW_FAILED                               :{WHITE}Autorenew failed on {VEHICLE}{}{STRING2}
 

	
 
STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE                              :{BIG_FONT}{BLACK}New {STRING} now available!
 
@@ -913,22 +923,22 @@ STR_NEWS_SHOW_VEHICLE_GROUP_TOOLTIP     
 

	
 
STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_LIST                   :{WHITE}{STATION} no longer accepts: {CARGO_LIST}
 
STR_NEWS_STATION_NOW_ACCEPTS_CARGO_LIST                         :{WHITE}{STATION} now accepts: {CARGO_LIST}
 

	
 
STR_NEWS_OFFER_OF_SUBSIDY_EXPIRED                               :{BIG_FONT}{BLACK}Offer of subsidy expired:{}{}{STRING} from {STRING2} to {STRING2} will now not attract a subsidy
 
STR_NEWS_SUBSIDY_WITHDRAWN_SERVICE                              :{BIG_FONT}{BLACK}Subsidy withdrawn:{}{}{STRING} service from {STRING2} to {STRING2} is no longer subsidised
 
STR_NEWS_SERVICE_SUBSIDY_OFFERED                                :{BIG_FONT}{BLACK}Service subsidy offered:{}{}First {STRING} from {STRING2} to {STRING2} will attract a {NUM} year subsidy from the local authority!
 
STR_NEWS_SERVICE_SUBSIDY_OFFERED                                :{BIG_FONT}{BLACK}Service subsidy offered:{}{}First {STRING} from {STRING2} to {STRING2} will attract a {UNITS_YEARS_OR_MINUTES} subsidy from the local authority!
 
###length 4
 
STR_NEWS_SERVICE_SUBSIDY_AWARDED_HALF                           :{BIG_FONT}{BLACK}Service subsidy awarded to {RAW_STRING}!{}{}{STRING} from {STRING2} to {STRING2} will pay 50% extra for the next {NUM} year{P "" s}!
 
STR_NEWS_SERVICE_SUBSIDY_AWARDED_DOUBLE                         :{BIG_FONT}{BLACK}Service subsidy awarded to {RAW_STRING}!{}{}{STRING} from {STRING2} to {STRING2} will pay double rates for the next {NUM} year{P "" s}!
 
STR_NEWS_SERVICE_SUBSIDY_AWARDED_TRIPLE                         :{BIG_FONT}{BLACK}Service subsidy awarded to {RAW_STRING}!{}{}{STRING} from {STRING2} to {STRING2} will pay triple rates for the next {NUM} year{P "" s}!
 
STR_NEWS_SERVICE_SUBSIDY_AWARDED_QUADRUPLE                      :{BIG_FONT}{BLACK}Service subsidy awarded to {RAW_STRING}!{}{}{STRING} from {STRING2} to {STRING2} will pay quadruple rates for the next {NUM} year{P "" s}!
 

	
 
STR_NEWS_ROAD_REBUILDING                                        :{BIG_FONT}{BLACK}Traffic chaos in {TOWN}!{}{}Road rebuilding programme funded by {RAW_STRING} brings 6 months of misery to motorists!
 
STR_NEWS_SERVICE_SUBSIDY_AWARDED_HALF                           :{BIG_FONT}{BLACK}Service subsidy awarded to {RAW_STRING}!{}{}{STRING} from {STRING2} to {STRING2} will pay 50% extra for the next {UNITS_YEARS_OR_MINUTES}!
 
STR_NEWS_SERVICE_SUBSIDY_AWARDED_DOUBLE                         :{BIG_FONT}{BLACK}Service subsidy awarded to {RAW_STRING}!{}{}{STRING} from {STRING2} to {STRING2} will pay double rates for the next {UNITS_YEARS_OR_MINUTES}!
 
STR_NEWS_SERVICE_SUBSIDY_AWARDED_TRIPLE                         :{BIG_FONT}{BLACK}Service subsidy awarded to {RAW_STRING}!{}{}{STRING} from {STRING2} to {STRING2} will pay triple rates for the next {UNITS_YEARS_OR_MINUTES}!
 
STR_NEWS_SERVICE_SUBSIDY_AWARDED_QUADRUPLE                      :{BIG_FONT}{BLACK}Service subsidy awarded to {RAW_STRING}!{}{}{STRING} from {STRING2} to {STRING2} will pay quadruple rates for the next {UNITS_YEARS_OR_MINUTES}!
 

	
 
STR_NEWS_ROAD_REBUILDING                                        :{BIG_FONT}{BLACK}Traffic chaos in {TOWN}!{}{}Road rebuilding programme funded by {RAW_STRING} brings 6 {TKM months minutes} of misery to motorists!
 
STR_NEWS_EXCLUSIVE_RIGHTS_TITLE                                 :{BIG_FONT}{BLACK}Transport monopoly!
 
STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION                           :{BIG_FONT}{BLACK}Local authority of {TOWN} signs contract with {RAW_STRING} for one year of exclusive transport rights!
 
STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION                           :{BIG_FONT}{BLACK}Local authority of {TOWN} signs contract with {RAW_STRING} for 12 {TKM months minutes} of exclusive transport rights!
 

	
 
# Extra view window
 
STR_EXTRA_VIEWPORT_TITLE                                        :{WHITE}Viewport {COMMA}
 
STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN                                :{BLACK}Change viewport
 
STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT                             :{BLACK}Copy the location of the main view to this viewport
 
STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW                                :{BLACK}Change main view
 
@@ -1283,23 +1293,23 @@ STR_CONFIG_SETTING_VEHICLE_BREAKDOWNS   
 
STR_CONFIG_SETTING_VEHICLE_BREAKDOWNS_HELPTEXT                  :Control how often inadequately serviced vehicles may break down
 

	
 
STR_CONFIG_SETTING_SUBSIDY_MULTIPLIER                           :Subsidy multiplier: {STRING2}
 
STR_CONFIG_SETTING_SUBSIDY_MULTIPLIER_HELPTEXT                  :Set how much is paid for subsidised connections
 

	
 
STR_CONFIG_SETTING_SUBSIDY_DURATION                             :Subsidy duration: {STRING2}
 
STR_CONFIG_SETTING_SUBSIDY_DURATION_HELPTEXT                    :Set the number of years for which a subsidy is awarded
 

	
 
STR_CONFIG_SETTING_SUBSIDY_DURATION_VALUE                       :{NUM} year{P "" s}
 
STR_CONFIG_SETTING_SUBSIDY_DURATION_HELPTEXT                    :Set the number of {TKM years periods} for which a subsidy is awarded
 

	
 
STR_CONFIG_SETTING_SUBSIDY_DURATION_VALUE                       :{UNITS_YEARS_OR_PERIODS}
 
###setting-zero-is-special
 
STR_CONFIG_SETTING_SUBSIDY_DURATION_DISABLED                    :No subsidies
 

	
 
STR_CONFIG_SETTING_CONSTRUCTION_COSTS                           :Construction costs: {STRING2}
 
STR_CONFIG_SETTING_CONSTRUCTION_COSTS_HELPTEXT                  :Set level of construction and purchase costs
 

	
 
STR_CONFIG_SETTING_RECESSIONS                                   :Recessions: {STRING2}
 
STR_CONFIG_SETTING_RECESSIONS_HELPTEXT                          :If enabled, recessions may occur every few years. During a recession all production is significantly lower (it returns to previous level when the recession is over)
 
STR_CONFIG_SETTING_RECESSIONS_HELPTEXT                          :If enabled, recessions may occur periodically. During a recession all production is significantly lower (it returns to previous level when the recession is over)
 

	
 
STR_CONFIG_SETTING_TRAIN_REVERSING                              :Disallow train reversing in stations: {STRING2}
 
STR_CONFIG_SETTING_TRAIN_REVERSING_HELPTEXT                     :If enabled, trains will not reverse in non-terminus stations, even if there is a shorter path to their next destination when reversing
 

	
 
STR_CONFIG_SETTING_DISASTERS                                    :Disasters: {STRING2}
 
STR_CONFIG_SETTING_DISASTERS_HELPTEXT                           :Toggle disasters which may occasionally block or destroy vehicles or infrastructure
 
@@ -1381,14 +1391,14 @@ STR_CONFIG_SETTING_SIGNALSIDE           
 
STR_CONFIG_SETTING_SIGNALSIDE_HELPTEXT                          :Select on which side of the track to place signals
 
###length 3
 
STR_CONFIG_SETTING_SIGNALSIDE_LEFT                              :On the left
 
STR_CONFIG_SETTING_SIGNALSIDE_DRIVING_SIDE                      :On the driving side
 
STR_CONFIG_SETTING_SIGNALSIDE_RIGHT                             :On the right
 

	
 
STR_CONFIG_SETTING_SHOWFINANCES                                 :Show finances window at the end of the year: {STRING2}
 
STR_CONFIG_SETTING_SHOWFINANCES_HELPTEXT                        :If enabled, the finances window pops up at the end of each year to allow easy inspection of the financial status of the company
 
STR_CONFIG_SETTING_SHOWFINANCES                                 :Show finances window at the end of the {TKM year period}: {STRING2}
 
STR_CONFIG_SETTING_SHOWFINANCES_HELPTEXT                        :If enabled, the finances window pops up at the end of each {TKM year period} to allow easy inspection of the financial status of the company
 

	
 
STR_CONFIG_SETTING_NONSTOP_BY_DEFAULT                           :New orders are 'non-stop' by default: {STRING2}
 
STR_CONFIG_SETTING_NONSTOP_BY_DEFAULT_HELPTEXT                  :Normally, a vehicle will stop at every station it passes. By enabling this setting, it will drive through all station on the way to its final destination without stopping. Note, that this setting only defines a default value for new orders. Individual orders can be set explicitly to either behaviour nevertheless
 

	
 
STR_CONFIG_SETTING_STOP_LOCATION                                :New train orders stop by default at the {STRING2} of the platform
 
STR_CONFIG_SETTING_STOP_LOCATION_HELPTEXT                       :Place where a train will stop at the platform by default. The 'near end' means close to the entry point, 'middle' means in the middle of the platform, and 'far end' means far away from the entry point. Note, that this setting only defines a default value for new orders. Individual orders can have their stop location set by clicking on the order text
 
@@ -1403,16 +1413,16 @@ STR_CONFIG_SETTING_AUTOSCROLL_HELPTEXT  
 
STR_CONFIG_SETTING_AUTOSCROLL_DISABLED                          :Disabled
 
STR_CONFIG_SETTING_AUTOSCROLL_MAIN_VIEWPORT_FULLSCREEN          :Main viewport, full-screen only
 
STR_CONFIG_SETTING_AUTOSCROLL_MAIN_VIEWPORT                     :Main viewport
 
STR_CONFIG_SETTING_AUTOSCROLL_EVERY_VIEWPORT                    :Every viewport
 

	
 
STR_CONFIG_SETTING_BRIBE                                        :Allow bribing of the local authority: {STRING2}
 
STR_CONFIG_SETTING_BRIBE_HELPTEXT                               :Allow companies to try bribing the local town authority. If the bribe is noticed by an inspector, the company will not be able to act in the town for six months
 
STR_CONFIG_SETTING_BRIBE_HELPTEXT                               :Allow companies to try bribing the local town authority. If the bribe is noticed by an inspector, the company will not be able to act in the town for six {TKM months minutes}
 

	
 
STR_CONFIG_SETTING_ALLOW_EXCLUSIVE                              :Allow buying exclusive transport rights: {STRING2}
 
STR_CONFIG_SETTING_ALLOW_EXCLUSIVE_HELPTEXT                     :If a company buys exclusive transport rights for a town, opponents' stations (passenger and cargo) won't receive any cargo for a whole year
 
STR_CONFIG_SETTING_ALLOW_EXCLUSIVE_HELPTEXT                     :If a company buys exclusive transport rights for a town, opponents' stations (passenger and cargo) won't receive any cargo for twelve {TKM months minutes}
 

	
 
STR_CONFIG_SETTING_ALLOW_FUND_BUILDINGS                         :Allow funding buildings: {STRING2}
 
STR_CONFIG_SETTING_ALLOW_FUND_BUILDINGS_HELPTEXT                :Allow companies to give money to towns for funding new houses
 

	
 
STR_CONFIG_SETTING_ALLOW_FUND_ROAD                              :Allow funding local road reconstruction: {STRING2}
 
STR_CONFIG_SETTING_ALLOW_FUND_ROAD_HELPTEXT                     :Allow companies to give money to towns for road re-construction to sabotage road-based services in the town
 
@@ -1463,17 +1473,23 @@ STR_CONFIG_SETTING_ORDER_REVIEW_HELPTEXT
 
###length 3
 
STR_CONFIG_SETTING_ORDER_REVIEW_OFF                             :No
 
STR_CONFIG_SETTING_ORDER_REVIEW_EXDEPOT                         :Yes, but exclude stopped vehicles
 
STR_CONFIG_SETTING_ORDER_REVIEW_ON                              :Of all vehicles
 

	
 
STR_CONFIG_SETTING_WARN_INCOME_LESS                             :Warn if a vehicle's income is negative: {STRING2}
 
STR_CONFIG_SETTING_WARN_INCOME_LESS_HELPTEXT                    :When enabled, a news message gets sent when a vehicle has not made any profit within a calendar year
 
STR_CONFIG_SETTING_WARN_INCOME_LESS_HELPTEXT                    :When enabled, a news message gets sent when a vehicle has not made any profit within a {TKM year period}
 

	
 
STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES                        :Vehicles never expire: {STRING2}
 
STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES_HELPTEXT               :When enabled, all vehicle models remain available forever after their introduction
 

	
 
STR_CONFIG_SETTING_TIMEKEEPING_UNITS                            :Timekeeping: {STRING2}
 
STR_CONFIG_SETTING_TIMEKEEPING_UNITS_HELPTEXT                   :Select the timekeeping units of the game. This cannot be changed later.{}{}Calendar-based is the classic OpenTTD experience, with a year consisting of 12 months, and each month having 28-31 days.{}{}In Wallclock-based time, vehicle movement, cargo production, and financials are instead based on one-minute increments, which is about as long as a 30 day month takes in Calendar-based mode. These are grouped into 12-minute periods, equivalent to a year in Calendar-based mode.{}{}In either mode there is always a classic calendar, which is used for introduction dates of vehicles, houses, and other infrastructure.
 
###length 2
 
STR_CONFIG_SETTING_TIMEKEEPING_UNITS_CALENDAR                   :Calendar
 
STR_CONFIG_SETTING_TIMEKEEPING_UNITS_WALLCLOCK                  :Wallclock
 

	
 
STR_CONFIG_SETTING_AUTORENEW_VEHICLE                            :Autorenew vehicle when it gets old: {STRING2}
 
STR_CONFIG_SETTING_AUTORENEW_VEHICLE_HELPTEXT                   :When enabled, a vehicle nearing its end of life gets automatically replaced when the renew conditions are fulfilled
 

	
 
STR_CONFIG_SETTING_AUTORENEW_MONTHS                             :Autorenew when vehicle is {STRING2} maximum age
 
STR_CONFIG_SETTING_AUTORENEW_MONTHS_HELPTEXT                    :Relative age when a vehicle should be considered for auto-renewing
 
###length 2
 
@@ -1720,14 +1736,14 @@ STR_CONFIG_SETTING_FAST_FORWARD_SPEED_LI
 
STR_CONFIG_SETTING_SOUND_TICKER                                 :News ticker: {STRING2}
 
STR_CONFIG_SETTING_SOUND_TICKER_HELPTEXT                        :Play sound for summarised news messages
 

	
 
STR_CONFIG_SETTING_SOUND_NEWS                                   :Newspaper: {STRING2}
 
STR_CONFIG_SETTING_SOUND_NEWS_HELPTEXT                          :Play sound upon display of newspapers
 

	
 
STR_CONFIG_SETTING_SOUND_NEW_YEAR                               :End of year: {STRING2}
 
STR_CONFIG_SETTING_SOUND_NEW_YEAR_HELPTEXT                      :Play sound at the end of a year summarising the company's performance during the year compared to the previous year
 
STR_CONFIG_SETTING_SOUND_NEW_YEAR                               :End of {TKM year period}: {STRING2}
 
STR_CONFIG_SETTING_SOUND_NEW_YEAR_HELPTEXT                      :Play sound at the end of a {TKM year period} summarising the company's performance during the {TKM year period} compared to the previous {TKM year period}
 

	
 
STR_CONFIG_SETTING_SOUND_CONFIRM                                :Construction: {STRING2}
 
STR_CONFIG_SETTING_SOUND_CONFIRM_HELPTEXT                       :Play sound on successful constructions or other actions
 

	
 
STR_CONFIG_SETTING_SOUND_CLICK                                  :Button clicks: {STRING2}
 
STR_CONFIG_SETTING_SOUND_CLICK_HELPTEXT                         :Beep when clicking buttons
 
@@ -1789,13 +1805,13 @@ STR_CONFIG_SETTING_SERVINT_TRAINS_HELPTE
 
STR_CONFIG_SETTING_SERVINT_ROAD_VEHICLES                        :Default service interval for road vehicles: {STRING2}
 
STR_CONFIG_SETTING_SERVINT_ROAD_VEHICLES_HELPTEXT               :Set the default service interval for new road vehicles, if no explicit service interval is set for the vehicle
 
STR_CONFIG_SETTING_SERVINT_AIRCRAFT                             :Default service interval for aircraft: {STRING2}
 
STR_CONFIG_SETTING_SERVINT_AIRCRAFT_HELPTEXT                    :Set the default service interval for new aircraft, if no explicit service interval is set for the vehicle
 
STR_CONFIG_SETTING_SERVINT_SHIPS                                :Default service interval for ships: {STRING2}
 
STR_CONFIG_SETTING_SERVINT_SHIPS_HELPTEXT                       :Set the default service interval for new ships, if no explicit service interval is set for the vehicle
 
STR_CONFIG_SETTING_SERVINT_VALUE                                :{COMMA}{NBSP}day{P 0 "" s}/%
 
STR_CONFIG_SETTING_SERVINT_VALUE                                :{COMMA}{NBSP}Day{P 0 "" s}/Minute{P 0 "" s}/%
 
###setting-zero-is-special
 
STR_CONFIG_SETTING_SERVINT_DISABLED                             :Disabled
 

	
 
STR_CONFIG_SETTING_NOSERVICE                                    :Disable servicing when breakdowns set to none: {STRING2}
 
STR_CONFIG_SETTING_NOSERVICE_HELPTEXT                           :When enabled, vehicles do not get serviced if they cannot break down
 

	
 
@@ -2023,13 +2039,13 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_VE
 
STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_NAUTICAL         :Speed units (nautical): {STRING2}
 
STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_HELPTEXT         :Whenever a speed is shown in the user interface, show it in the selected units
 
###length 5
 
STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_IMPERIAL         :Imperial (mph)
 
STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_METRIC           :Metric (km/h)
 
STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_SI               :SI (m/s)
 
STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_GAMEUNITS        :Game units (tiles/day)
 
STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_GAMEUNITS        :Game units ({TKM "tiles/day" "tiles/sec"})
 
STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_KNOTS            :Knots
 

	
 
STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER                     :Vehicle power units: {STRING2}
 
STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER_HELPTEXT            :Whenever a vehicle's power is shown in the user interface, show it in the selected units
 
###length 3
 
STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER_IMPERIAL            :Imperial (hp)
 
@@ -2709,25 +2725,25 @@ STR_LINKGRAPH_LEGEND_COMPANY_TOOLTIP    
 
# Linkgraph legend window and linkgraph legend in smallmap
 
STR_LINKGRAPH_LEGEND_UNUSED                                     :{TINY_FONT}{BLACK}unused
 
STR_LINKGRAPH_LEGEND_SATURATED                                  :{TINY_FONT}{BLACK}saturated
 
STR_LINKGRAPH_LEGEND_OVERLOADED                                 :{TINY_FONT}{BLACK}overloaded
 

	
 
# Linkgraph tooltip
 
STR_LINKGRAPH_STATS_TOOLTIP                                     :{BLACK}{CARGO_LONG} to be transported per month from {STATION} to {STATION} ({COMMA}% of capacity){RAW_STRING}
 
STR_LINKGRAPH_STATS_TOOLTIP                                     :{BLACK}{CARGO_LONG} to be transported per {TKM month minute} from {STATION} to {STATION} ({COMMA}% of capacity){RAW_STRING}
 
STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION                    :{}{CARGO_LONG} to be transported back ({COMMA}% of capacity)
 
STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION                      :{}Average travel time: {NUM}{NBSP}day{P "" s}
 
STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION                      :{}Average travel time: {UNITS_DAYS_OR_SECONDS}
 

	
 
# Base for station construction window(s)
 
STR_STATION_BUILD_COVERAGE_AREA_TITLE                           :{BLACK}Coverage area highlight
 
STR_STATION_BUILD_COVERAGE_OFF                                  :{BLACK}Off
 
STR_STATION_BUILD_COVERAGE_ON                                   :{BLACK}On
 
STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP                     :{BLACK}Don't highlight coverage area of proposed site
 
STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP                      :{BLACK}Highlight coverage area of proposed site
 
STR_STATION_BUILD_ACCEPTS_CARGO                                 :{BLACK}Accepts: {GOLD}{CARGO_LIST}
 
STR_STATION_BUILD_SUPPLIES_CARGO                                :{BLACK}Supplies: {GOLD}{CARGO_LIST}
 
STR_STATION_BUILD_INFRASTRUCTURE_COST                           :{BLACK}Maintenance cost: {GOLD}{CURRENCY_SHORT}/yr
 
STR_STATION_BUILD_INFRASTRUCTURE_COST                           :{BLACK}Maintenance cost: {GOLD}{CURRENCY_SHORT}/{TKM year period}
 

	
 
# Join station window
 
STR_JOIN_STATION_CAPTION                                        :{WHITE}Join station
 
STR_JOIN_STATION_CREATE_SPLITTED_STATION                        :{YELLOW}Build a separate station
 

	
 
STR_JOIN_WAYPOINT_CAPTION                                       :{WHITE}Join waypoint
 
@@ -3568,21 +3584,21 @@ STR_TOWN_DIRECTORY_LIST_TOOLTIP         
 
STR_TOWN_POPULATION                                             :{BLACK}World population: {COMMA}
 

	
 
# Town view window
 
STR_TOWN_VIEW_TOWN_CAPTION                                      :{WHITE}{TOWN}
 
STR_TOWN_VIEW_CITY_CAPTION                                      :{WHITE}{TOWN} (City)
 
STR_TOWN_VIEW_POPULATION_HOUSES                                 :{BLACK}Population: {ORANGE}{COMMA}{BLACK}  Houses: {ORANGE}{COMMA}
 
STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX                              :{BLACK}{CARGO_LIST} last month: {ORANGE}{COMMA}{BLACK}  max: {ORANGE}{COMMA}
 
STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX                              :{BLACK}{CARGO_LIST} last {TKM month minute}: {ORANGE}{COMMA}{BLACK}  max: {ORANGE}{COMMA}
 
STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH                              :{BLACK}Cargo needed for town growth:
 
STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL             :{ORANGE}{STRING}{RED} required
 
STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER              :{ORANGE}{STRING}{BLACK} required in winter
 
STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_DELIVERED_GENERAL            :{ORANGE}{STRING}{GREEN} delivered
 
STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED                     :{ORANGE}{CARGO_TINY} / {CARGO_LONG}{RED} (still required)
 
STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_DELIVERED                    :{ORANGE}{CARGO_TINY} / {CARGO_LONG}{GREEN} (delivered)
 
STR_TOWN_VIEW_TOWN_GROWS_EVERY                                  :{BLACK}Town grows every {ORANGE}{COMMA}{BLACK}{NBSP}day{P "" s}
 
STR_TOWN_VIEW_TOWN_GROWS_EVERY_FUNDED                           :{BLACK}Town grows every {ORANGE}{COMMA}{BLACK}{NBSP}day{P "" s} (funded)
 
STR_TOWN_VIEW_TOWN_GROWS_EVERY                                  :{BLACK}Town grows every {ORANGE}{UNITS_DAYS_OR_SECONDS}
 
STR_TOWN_VIEW_TOWN_GROWS_EVERY_FUNDED                           :{BLACK}Town grows every {ORANGE}{UNITS_DAYS_OR_SECONDS} (funded)
 
STR_TOWN_VIEW_TOWN_GROW_STOPPED                                 :{BLACK}Town is {RED}not{BLACK} growing
 
STR_TOWN_VIEW_NOISE_IN_TOWN                                     :{BLACK}Noise limit in town: {ORANGE}{COMMA}{BLACK}  max: {ORANGE}{COMMA}
 
STR_TOWN_VIEW_CENTER_TOOLTIP                                    :{BLACK}Centre the main view on town location. Ctrl+Click to open a new viewport on town location
 
STR_TOWN_VIEW_LOCAL_AUTHORITY_BUTTON                            :{BLACK}Local Authority
 
STR_TOWN_VIEW_LOCAL_AUTHORITY_TOOLTIP                           :{BLACK}Show information on local authority
 
STR_TOWN_VIEW_RENAME_TOOLTIP                                    :{BLACK}Change town name
 
@@ -3616,16 +3632,16 @@ STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRA
 
STR_LOCAL_AUTHORITY_ACTION_BRIBE                                :Bribe the local authority
 

	
 
###length 8
 
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING            :{PUSH_COLOUR}{YELLOW}Initiate a small local advertising campaign, to attract more passengers and cargo to your transport services.{}Provides a temporary boost to station rating in a small radius around the town centre.{}{POP_COLOUR}Cost: {CURRENCY_LONG}
 
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING           :{PUSH_COLOUR}{YELLOW}Initiate a medium local advertising campaign, to attract more passengers and cargo to your transport services.{}Provides a temporary boost to station rating in a medium radius around the town centre.{}{POP_COLOUR}Cost: {CURRENCY_LONG}
 
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING            :{PUSH_COLOUR}{YELLOW}Initiate a large local advertising campaign, to attract more passengers and cargo to your transport services.{}Provides a temporary boost to station rating in a large radius around the town centre.{}{POP_COLOUR}Cost: {CURRENCY_LONG}
 
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION          :{PUSH_COLOUR}{YELLOW}Fund the reconstruction of the urban road network.{}Causes considerable disruption to road traffic for up to 6 months.{}{POP_COLOUR}Cost: {CURRENCY_LONG}
 
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION          :{PUSH_COLOUR}{YELLOW}Fund the reconstruction of the urban road network.{}Causes considerable disruption to road traffic for up to 6 {TKM months minutes}.{}{POP_COLOUR}Cost: {CURRENCY_LONG}
 
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY            :{PUSH_COLOUR}{YELLOW}Build a statue in honour of your company.{}Provides a permanent boost to station rating in this town.{}{POP_COLOUR}Cost: {CURRENCY_LONG}
 
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS                :{PUSH_COLOUR}{YELLOW}Fund the construction of new buildings in the town.{}Provides a temporary boost to town growth in this town.{}{POP_COLOUR}Cost: {CURRENCY_LONG}
 
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT          :{PUSH_COLOUR}{YELLOW}Buy 1 year's exclusive transport rights in town.{}Town authority will not allow passengers and cargo to use your competitors' stations. A successful bribe from a competitor will cancel this contract.{}{POP_COLOUR}Cost: {CURRENCY_LONG}
 
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT          :{PUSH_COLOUR}{YELLOW}Buy exclusive transport rights in town for 12 {TKM months minutes}.{}Town authority will not allow passengers and cargo to use your competitors' stations. A successful bribe from a competitor will cancel this contract.{}{POP_COLOUR}Cost: {CURRENCY_LONG}
 
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE                        :{PUSH_COLOUR}{YELLOW}Bribe the local authority to increase your rating and abort a competitor's exclusive transport rights, at the risk of a severe penalty if caught.{}{POP_COLOUR}Cost: {CURRENCY_LONG}
 

	
 
# Goal window
 
STR_GOALS_CAPTION                                               :{WHITE}{COMPANY} Goals
 
STR_GOALS_SPECTATOR_CAPTION                                     :{WHITE}Global Goals
 
STR_GOALS_SPECTATOR                                             :Global Goals
 
@@ -3666,17 +3682,21 @@ STR_GOAL_QUESTION_BUTTON_POSTPONE       
 
STR_GOAL_QUESTION_BUTTON_SURRENDER                              :Surrender
 
STR_GOAL_QUESTION_BUTTON_CLOSE                                  :Close
 

	
 
# Subsidies window
 
STR_SUBSIDIES_CAPTION                                           :{WHITE}Subsidies
 
STR_SUBSIDIES_OFFERED_TITLE                                     :{BLACK}Subsidies on offer for services taking:
 
STR_SUBSIDIES_OFFERED_FROM_TO                                   :{ORANGE}{STRING} from {STRING2} to {STRING2}{YELLOW} (by {DATE_SHORT})
 
STR_SUBSIDIES_OFFERED_FROM_TO                                   :{ORANGE}{STRING} from {STRING2} to {STRING2}{YELLOW} ({STRING1})
 
STR_SUBSIDIES_NONE                                              :{ORANGE}- None -
 
STR_SUBSIDIES_SUBSIDISED_TITLE                                  :{BLACK}Services already subsidised:
 
STR_SUBSIDIES_SUBSIDISED_FROM_TO                                :{ORANGE}{STRING} from {STRING2} to {STRING2}{YELLOW} ({COMPANY}{YELLOW}, until {DATE_SHORT})
 
STR_SUBSIDIES_SUBSIDISED_FROM_TO                                :{ORANGE}{STRING} from {STRING2} to {STRING2}{YELLOW} ({COMPANY}{YELLOW}, {STRING1})
 
STR_SUBSIDIES_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER                :{BLACK}Click on service to centre main view on industry/town. Ctrl+Click to open a new viewport on industry/town location
 
STR_SUBSIDIES_OFFERED_EXPIRY_DATE                               :by {DATE_SHORT}
 
STR_SUBSIDIES_OFFERED_EXPIRY_TIME                               :within {UNITS_MONTHS_OR_MINUTES}
 
STR_SUBSIDIES_SUBSIDISED_EXPIRY_DATE                            :until {DATE_SHORT}
 
STR_SUBSIDIES_SUBSIDISED_EXPIRY_TIME                            :{UNITS_MONTHS_OR_MINUTES} remaining
 

	
 
# Story book window
 
STR_STORY_BOOK_CAPTION                                          :{WHITE}{COMPANY} Story Book
 
STR_STORY_BOOK_SPECTATOR_CAPTION                                :{WHITE}Global Story Book
 
STR_STORY_BOOK_SPECTATOR                                        :Global Story Book
 
STR_STORY_BOOK_TITLE                                            :{YELLOW}{RAW_STRING}
 
@@ -3710,13 +3730,13 @@ STR_STATION_VIEW_ACCEPTS_CARGO          
 

	
 
STR_STATION_VIEW_EXCLUSIVE_RIGHTS_SELF                          :{BLACK}This station has exclusive transport rights in this town.
 
STR_STATION_VIEW_EXCLUSIVE_RIGHTS_COMPANY                       :{YELLOW}{COMPANY}{BLACK} bought exclusive transport rights in this town.
 

	
 
STR_STATION_VIEW_RATINGS_BUTTON                                 :{BLACK}Ratings
 
STR_STATION_VIEW_RATINGS_TOOLTIP                                :{BLACK}Show station ratings
 
STR_STATION_VIEW_SUPPLY_RATINGS_TITLE                           :{BLACK}Monthly supply and local rating:
 
STR_STATION_VIEW_SUPPLY_RATINGS_TITLE                           :{BLACK}Supply per {TKM month minute} and local rating:
 
STR_STATION_VIEW_CARGO_SUPPLY_RATING                            :{WHITE}{STRING}: {YELLOW}{COMMA} / {STRING} ({COMMA}%)
 

	
 
STR_STATION_VIEW_GROUP                                          :{BLACK}Group by
 
STR_STATION_VIEW_WAITING_STATION                                :Station: Waiting
 
STR_STATION_VIEW_WAITING_AMOUNT                                 :Amount: Waiting
 
STR_STATION_VIEW_PLANNED_STATION                                :Station: Planned
 
@@ -3771,12 +3791,13 @@ STR_BUOY_VIEW_CHANGE_BUOY_NAME          
 

	
 
STR_EDIT_WAYPOINT_NAME                                          :{WHITE}Edit waypoint name
 

	
 
# Finances window
 
STR_FINANCES_CAPTION                                            :{WHITE}{COMPANY} Finances {BLACK}{COMPANY_NUM}
 
STR_FINANCES_YEAR                                               :{WHITE}{NUM}
 
STR_FINANCES_YEAR_CAPTION                                       :{WHITE}{TKM Year Period}
 

	
 
###length 3
 
STR_FINANCES_REVENUE_TITLE                                      :{WHITE}Revenue
 
STR_FINANCES_OPERATING_EXPENSES_TITLE                           :{WHITE}Operating Expenses
 
STR_FINANCES_CAPITAL_EXPENSES_TITLE                             :{WHITE}Capital Expenses
 

	
 
@@ -3872,13 +3893,13 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SEC
 
STR_COMPANY_INFRASTRUCTURE_VIEW_TRAM_SECT                       :{GOLD}Tram pieces:
 
STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT                      :{GOLD}Water tiles:
 
STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS                          :{WHITE}Canals
 
STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT                    :{GOLD}Stations:
 
STR_COMPANY_INFRASTRUCTURE_VIEW_STATIONS                        :{WHITE}Station tiles
 
STR_COMPANY_INFRASTRUCTURE_VIEW_AIRPORTS                        :{WHITE}Airports
 
STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL                           :{WHITE}{CURRENCY_LONG}/yr
 
STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL                           :{WHITE}{CURRENCY_LONG}/{TKM year period}
 

	
 
# Industry directory
 
STR_INDUSTRY_DIRECTORY_CAPTION                                  :{WHITE}Industries
 
STR_INDUSTRY_DIRECTORY_NONE                                     :{ORANGE}- None -
 
STR_INDUSTRY_DIRECTORY_ITEM_INFO                                :{BLACK}{CARGO_LONG}{RAW_STRING}{YELLOW} ({COMMA}% transported){BLACK}
 
STR_INDUSTRY_DIRECTORY_ITEM_NOPROD                              :{ORANGE}{INDUSTRY}
 
@@ -3891,13 +3912,13 @@ STR_INDUSTRY_DIRECTORY_ACCEPTED_CARGO_FI
 
STR_INDUSTRY_DIRECTORY_PRODUCED_CARGO_FILTER                    :{BLACK}Produced cargo: {SILVER}{STRING}
 
STR_INDUSTRY_DIRECTORY_FILTER_ALL_TYPES                         :All cargo types
 
STR_INDUSTRY_DIRECTORY_FILTER_NONE                              :None
 

	
 
# Industry view
 
STR_INDUSTRY_VIEW_CAPTION                                       :{WHITE}{INDUSTRY}
 
STR_INDUSTRY_VIEW_PRODUCTION_LAST_MONTH_TITLE                   :{BLACK}Production last month:
 
STR_INDUSTRY_VIEW_PRODUCTION_LAST_MONTH_TITLE                   :{BLACK}Production last {TKM month minute}:
 
STR_INDUSTRY_VIEW_TRANSPORTED                                   :{YELLOW}{CARGO_LONG}{RAW_STRING}{BLACK} ({COMMA}% transported)
 
STR_INDUSTRY_VIEW_LOCATION_TOOLTIP                              :{BLACK}Centre the main view on industry location. Ctrl+Click to open a new viewport on industry location
 
STR_INDUSTRY_VIEW_PRODUCTION_LEVEL                              :{BLACK}Production level: {YELLOW}{COMMA}%
 
STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE                    :{YELLOW}The industry has announced imminent closure!
 

	
 
STR_INDUSTRY_VIEW_REQUIRES_N_CARGO                              :{BLACK}Requires: {YELLOW}{STRING}{RAW_STRING}
 
@@ -3932,13 +3953,13 @@ STR_VEHICLE_LIST_AVAILABLE_AIRCRAFT     
 

	
 
STR_VEHICLE_LIST_MANAGE_LIST                                    :{BLACK}Manage list
 
STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP                            :{BLACK}Send instructions to all vehicles in this list
 
STR_VEHICLE_LIST_REPLACE_VEHICLES                               :Replace vehicles
 
STR_VEHICLE_LIST_SEND_FOR_SERVICING                             :Send for servicing
 
STR_VEHICLE_LIST_CREATE_GROUP                                   :Create group
 
STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR                     :{TINY_FONT}{BLACK}Profit this year: {CURRENCY_LONG} (last year: {CURRENCY_LONG})
 
STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR                     :{TINY_FONT}{BLACK}Profit this {TKM year period}: {CURRENCY_LONG} (last {TKM year period}: {CURRENCY_LONG})
 
STR_VEHICLE_LIST_CARGO                                          :[{CARGO_LIST}]
 
STR_VEHICLE_LIST_NAME_AND_CARGO                                 :{STRING1} {STRING1}
 

	
 
STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT                            :Send to depot
 
STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT                     :Send to depot
 
STR_VEHICLE_LIST_SEND_SHIP_TO_DEPOT                             :Send to depot
 
@@ -3977,14 +3998,14 @@ STR_GROUP_DELETE_QUERY_TEXT             
 

	
 
STR_GROUP_ADD_SHARED_VEHICLE                                    :Add shared vehicles
 
STR_GROUP_REMOVE_ALL_VEHICLES                                   :Remove all vehicles
 

	
 
STR_GROUP_RENAME_CAPTION                                        :{BLACK}Rename a group
 

	
 
STR_GROUP_PROFIT_THIS_YEAR                                      :Profit this year:
 
STR_GROUP_PROFIT_LAST_YEAR                                      :Profit last year:
 
STR_GROUP_PROFIT_THIS_YEAR                                      :Profit this {TKM year period}:
 
STR_GROUP_PROFIT_LAST_YEAR                                      :Profit last {TKM year period}:
 
STR_GROUP_OCCUPANCY                                             :Current usage:
 
STR_GROUP_OCCUPANCY_VALUE                                       :{NUM}%
 

	
 
# Build vehicle window
 
###length 4
 
STR_BUY_VEHICLE_TRAIN_RAIL_CAPTION                              :New Rail Vehicles
 
@@ -4005,13 +4026,13 @@ STR_BUY_VEHICLE_AIRCRAFT_CAPTION        
 
STR_PURCHASE_INFO_COST_WEIGHT                                   :{BLACK}Cost: {GOLD}{CURRENCY_LONG}{BLACK} Weight: {GOLD}{WEIGHT_SHORT}
 
STR_PURCHASE_INFO_COST_REFIT_WEIGHT                             :{BLACK}Cost: {GOLD}{CURRENCY_LONG}{BLACK} (Refit Cost: {GOLD}{CURRENCY_LONG}{BLACK}) Weight: {GOLD}{WEIGHT_SHORT}
 
STR_PURCHASE_INFO_SPEED_POWER                                   :{BLACK}Speed: {GOLD}{VELOCITY}{BLACK} Power: {GOLD}{POWER}
 
STR_PURCHASE_INFO_SPEED                                         :{BLACK}Speed: {GOLD}{VELOCITY}
 
STR_PURCHASE_INFO_SPEED_OCEAN                                   :{BLACK}Speed on ocean: {GOLD}{VELOCITY}
 
STR_PURCHASE_INFO_SPEED_CANAL                                   :{BLACK}Speed on canal/river: {GOLD}{VELOCITY}
 
STR_PURCHASE_INFO_RUNNINGCOST                                   :{BLACK}Running Cost: {GOLD}{CURRENCY_LONG}/yr
 
STR_PURCHASE_INFO_RUNNINGCOST                                   :{BLACK}Running Cost: {GOLD}{CURRENCY_LONG}/{TKM year period}
 
STR_PURCHASE_INFO_CAPACITY                                      :{BLACK}Capacity: {GOLD}{CARGO_LONG} {STRING}
 
STR_PURCHASE_INFO_REFITTABLE                                    :(refittable)
 
STR_PURCHASE_INFO_DESIGNED_LIFE                                 :{BLACK}Designed: {GOLD}{NUM}{BLACK} Life: {GOLD}{COMMA} year{P "" s}
 
STR_PURCHASE_INFO_RELIABILITY                                   :{BLACK}Max. Reliability: {GOLD}{COMMA}%
 
STR_PURCHASE_INFO_COST                                          :{BLACK}Cost: {GOLD}{CURRENCY_LONG}
 
STR_PURCHASE_INFO_COST_REFIT                                    :{BLACK}Cost: {GOLD}{CURRENCY_LONG}{BLACK} (Refit Cost: {GOLD}{CURRENCY_LONG}{BLACK})
 
@@ -4198,19 +4219,19 @@ STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE    
 
STR_ENGINE_PREVIEW_ROAD_VEHICLE                                 :road vehicle
 
STR_ENGINE_PREVIEW_TRAM_VEHICLE                                 :tramway vehicle
 

	
 
STR_ENGINE_PREVIEW_AIRCRAFT                                     :aircraft
 
STR_ENGINE_PREVIEW_SHIP                                         :ship
 

	
 
STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER                      :{BLACK}Cost: {CURRENCY_LONG} Weight: {WEIGHT_SHORT}{}Speed: {VELOCITY}  Power: {POWER}{}Running Cost: {CURRENCY_LONG}/yr{}Capacity: {CARGO_LONG}
 
STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE               :{BLACK}Cost: {0:CURRENCY_LONG} Weight: {1:WEIGHT_SHORT}{}Speed: {2:VELOCITY}  Power: {3:POWER}  Max. T.E.: {6:FORCE}{}Running Cost: {4:CURRENCY_LONG}/yr{}Capacity: {5:CARGO_LONG}
 
STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST                   :{BLACK}Cost: {CURRENCY_LONG} Max. Speed: {VELOCITY}{}Capacity: {CARGO_LONG}{}Running Cost: {CURRENCY_LONG}/yr
 
STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_CAP_RUNCOST          :{BLACK}Cost: {CURRENCY_LONG} Max. Speed: {VELOCITY}{}Aircraft type: {STRING}{}Capacity: {CARGO_LONG}, {CARGO_LONG}{}Running Cost: {CURRENCY_LONG}/yr
 
STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST              :{BLACK}Cost: {CURRENCY_LONG} Max. Speed: {VELOCITY}{}Aircraft type: {STRING}{}Capacity: {CARGO_LONG}{}Running Cost: {CURRENCY_LONG}/yr
 
STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_RANGE_CAP_CAP_RUNCOST    :{BLACK}Cost: {CURRENCY_LONG} Max. Speed: {VELOCITY}{}Aircraft type: {STRING} Range: {COMMA} tiles{}Capacity: {CARGO_LONG}, {CARGO_LONG}{}Running Cost: {CURRENCY_LONG}/yr
 
STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_RANGE_CAP_RUNCOST        :{BLACK}Cost: {CURRENCY_LONG} Max. Speed: {VELOCITY}{}Aircraft type: {STRING} Range: {COMMA} tiles{}Capacity: {CARGO_LONG}{}Running Cost: {CURRENCY_LONG}/yr
 
STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER                      :{BLACK}Cost: {CURRENCY_LONG} Weight: {WEIGHT_SHORT}{}Speed: {VELOCITY}  Power: {POWER}{}Running Cost: {CURRENCY_LONG}/{TKM year period}{}Capacity: {CARGO_LONG}
 
STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE               :{BLACK}Cost: {0:CURRENCY_LONG} Weight: {1:WEIGHT_SHORT}{}Speed: {2:VELOCITY}  Power: {3:POWER}  Max. T.E.: {6:FORCE}{}Running Cost: {4:CURRENCY_LONG}/{TKM year period}{}Capacity: {5:CARGO_LONG}
 
STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST                   :{BLACK}Cost: {CURRENCY_LONG} Max. Speed: {VELOCITY}{}Capacity: {CARGO_LONG}{}Running Cost: {CURRENCY_LONG}/{TKM year period}
 
STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_CAP_RUNCOST          :{BLACK}Cost: {CURRENCY_LONG} Max. Speed: {VELOCITY}{}Aircraft type: {STRING}{}Capacity: {CARGO_LONG}, {CARGO_LONG}{}Running Cost: {CURRENCY_LONG}/{TKM year period}
 
STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST              :{BLACK}Cost: {CURRENCY_LONG} Max. Speed: {VELOCITY}{}Aircraft type: {STRING}{}Capacity: {CARGO_LONG}{}Running Cost: {CURRENCY_LONG}/{TKM year period}
 
STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_RANGE_CAP_CAP_RUNCOST    :{BLACK}Cost: {CURRENCY_LONG} Max. Speed: {VELOCITY}{}Aircraft type: {STRING} Range: {COMMA} tiles{}Capacity: {CARGO_LONG}, {CARGO_LONG}{}Running Cost: {CURRENCY_LONG}/{TKM year period}
 
STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_RANGE_CAP_RUNCOST        :{BLACK}Cost: {CURRENCY_LONG} Max. Speed: {VELOCITY}{}Aircraft type: {STRING} Range: {COMMA} tiles{}Capacity: {CARGO_LONG}{}Running Cost: {CURRENCY_LONG}/{TKM year period}
 

	
 
# Autoreplace window
 
STR_REPLACE_VEHICLES_WHITE                                      :{WHITE}Replace {STRING} - {STRING1}
 

	
 
STR_REPLACE_VEHICLE_VEHICLES_IN_USE                             :{YELLOW}Vehicles in use
 
STR_REPLACE_VEHICLE_VEHICLES_IN_USE_TOOLTIP                     :{BLACK}Column with vehicles that you own
 
@@ -4347,42 +4368,45 @@ STR_VEHICLE_DETAILS_CAPTION             
 
###length VEHICLE_TYPES
 
STR_VEHICLE_DETAILS_TRAIN_RENAME                                :{BLACK}Name train
 
STR_VEHICLE_DETAILS_ROAD_VEHICLE_RENAME                         :{BLACK}Name road vehicle
 
STR_VEHICLE_DETAILS_SHIP_RENAME                                 :{BLACK}Name ship
 
STR_VEHICLE_DETAILS_AIRCRAFT_RENAME                             :{BLACK}Name aircraft
 

	
 
STR_VEHICLE_INFO_AGE_RUNNING_COST_YR                            :{BLACK}Age: {LTBLUE}{STRING2}{BLACK}   Running Cost: {LTBLUE}{CURRENCY_LONG}/yr
 
STR_VEHICLE_INFO_AGE                                            :{COMMA} year{P "" s} ({COMMA})
 
STR_VEHICLE_INFO_AGE_RED                                        :{RED}{COMMA} year{P "" s} ({COMMA})
 
STR_VEHICLE_INFO_AGE_RUNNING_COST_YR                            :{BLACK}Age: {LTBLUE}{STRING2}{BLACK}   Running Cost: {LTBLUE}{CURRENCY_LONG}/{TKM year period}
 

	
 
STR_VEHICLE_INFO_MAX_SPEED                                      :{BLACK}Max. speed: {LTBLUE}{VELOCITY}
 
STR_VEHICLE_INFO_MAX_SPEED_TYPE                                 :{BLACK}Max. speed: {LTBLUE}{VELOCITY} {BLACK}Aircraft type: {LTBLUE}{STRING}
 
STR_VEHICLE_INFO_MAX_SPEED_TYPE_RANGE                           :{BLACK}Max. speed: {LTBLUE}{VELOCITY} {BLACK}Aircraft type: {LTBLUE}{STRING} {BLACK}Range: {LTBLUE}{COMMA} tiles
 
STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED                         :{BLACK}Weight: {LTBLUE}{WEIGHT_SHORT} {BLACK}Power: {LTBLUE}{POWER}{BLACK} Max. speed: {LTBLUE}{VELOCITY}
 
STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE                  :{BLACK}Weight: {LTBLUE}{WEIGHT_SHORT} {BLACK}Power: {LTBLUE}{POWER}{BLACK} Max. speed: {LTBLUE}{VELOCITY} {BLACK}Max. T.E.: {LTBLUE}{FORCE}
 

	
 
STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR                     :{BLACK}Profit this year: {LTBLUE}{CURRENCY_LONG} (last year: {CURRENCY_LONG})
 
STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE     :{BLACK}Profit this year: {LTBLUE}{CURRENCY_LONG} (last year: {CURRENCY_LONG}) {BLACK}Min. performance: {LTBLUE}{POWER_TO_WEIGHT}
 
STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR                     :{BLACK}Profit this {TKM year period}: {LTBLUE}{CURRENCY_LONG} (last {TKM year period}: {CURRENCY_LONG})
 
STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE     :{BLACK}Profit this {TKM year period}: {LTBLUE}{CURRENCY_LONG} (last {TKM year period}: {CURRENCY_LONG}) {BLACK}Min. performance: {LTBLUE}{POWER_TO_WEIGHT}
 
STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS                         :{BLACK}Reliability: {LTBLUE}{COMMA}%  {BLACK}Breakdowns since last service: {LTBLUE}{COMMA}
 

	
 
STR_VEHICLE_INFO_BUILT_VALUE                                    :{LTBLUE}{ENGINE} {BLACK}Built: {LTBLUE}{NUM}{BLACK} Value: {LTBLUE}{CURRENCY_LONG}
 
STR_VEHICLE_INFO_NO_CAPACITY                                    :{BLACK}Capacity: {LTBLUE}None{STRING}
 
STR_VEHICLE_INFO_CAPACITY                                       :{BLACK}Capacity: {LTBLUE}{0:CARGO_LONG}{3:STRING}
 
STR_VEHICLE_INFO_CAPACITY_MULT                                  :{BLACK}Capacity: {LTBLUE}{0:CARGO_LONG}{3:STRING} (x{4:NUM})
 
STR_VEHICLE_INFO_CAPACITY_CAPACITY                              :{BLACK}Capacity: {LTBLUE}{CARGO_LONG}, {CARGO_LONG}{STRING}
 

	
 
STR_VEHICLE_INFO_FEEDER_CARGO_VALUE                             :{BLACK}Transfer Credits: {LTBLUE}{CURRENCY_LONG}
 

	
 
STR_VEHICLE_DETAILS_SERVICING_INTERVAL_DAYS                     :{BLACK}Servicing interval: {LTBLUE}{COMMA}{NBSP}days{BLACK}   Last service: {LTBLUE}{DATE_LONG}
 
STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT                  :{BLACK}Servicing interval: {LTBLUE}{COMMA}%{BLACK}   Last service: {LTBLUE}{DATE_LONG}
 
STR_VEHICLE_DETAILS_INCREASE_SERVICING_INTERVAL_TOOLTIP         :{BLACK}Increase servicing interval by 10. Ctrl+Click to increase servicing interval by 5
 
STR_VEHICLE_DETAILS_DECREASE_SERVICING_INTERVAL_TOOLTIP         :{BLACK}Decrease servicing interval by 10. Ctrl+Click to decrease servicing interval by 5
 
STR_VEHICLE_DETAILS_SERVICING_INTERVAL_DAYS                     :{BLACK}Servicing interval: {LTBLUE}{COMMA}{NBSP}days{BLACK}   {STRING1}
 
STR_VEHICLE_DETAILS_SERVICING_INTERVAL_MINUTES                  :{BLACK}Servicing interval: {LTBLUE}{COMMA}{NBSP}minutes{BLACK}   {STRING1}
 
STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT                  :{BLACK}Servicing interval: {LTBLUE}{COMMA}%{BLACK}   {STRING1}
 
STR_VEHICLE_DETAILS_LAST_SERVICE_DATE                           :Last service: {LTBLUE}{DATE_LONG}
 
STR_VEHICLE_DETAILS_LAST_SERVICE_MINUTES_AGO                    :Last service: {LTBLUE}{NUM} minutes ago
 
STR_VEHICLE_DETAILS_INCREASE_SERVICING_INTERVAL_TOOLTIP         :{BLACK}Increase servicing interval by {TKM 10 5}. Ctrl+Click to increase servicing interval by {TKM 5 1}
 
STR_VEHICLE_DETAILS_DECREASE_SERVICING_INTERVAL_TOOLTIP         :{BLACK}Decrease servicing interval by {TKM 10 5}. Ctrl+Click to decrease servicing interval by {TKM 5 1}
 

	
 
STR_SERVICE_INTERVAL_DROPDOWN_TOOLTIP                           :{BLACK}Change servicing interval type
 
STR_VEHICLE_DETAILS_DEFAULT                                     :Default
 
STR_VEHICLE_DETAILS_DAYS                                        :Days
 
STR_VEHICLE_DETAILS_TIME                                        :{TKM Days Minutes}
 
STR_VEHICLE_DETAILS_PERCENT                                     :Percentage
 

	
 
###length VEHICLE_TYPES
 
STR_QUERY_RENAME_TRAIN_CAPTION                                  :{WHITE}Name train
 
STR_QUERY_RENAME_ROAD_VEHICLE_CAPTION                           :{WHITE}Name road vehicle
 
STR_QUERY_RENAME_SHIP_CAPTION                                   :{WHITE}Name ship
src/misc.cpp
Show inline comments
 
@@ -109,14 +109,20 @@ void InitializeGame(uint size_x, uint si
 

	
 
	_newgrf_profilers.clear();
 

	
 
	if (reset_date) {
 
		TimerGameCalendar::Date new_date = TimerGameCalendar::ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1);
 
		TimerGameCalendar::SetDate(new_date, 0);
 
		/* Keep the economy date synced with the calendar date. */
 
		TimerGameEconomy::SetDate(new_date.base(), 0);
 

	
 
		if (TimerGameEconomy::UsingWallclockUnits()) {
 
			/* If using wallclock units, start at year 1. */
 
			TimerGameEconomy::SetDate(TimerGameEconomy::ConvertYMDToDate(1, 0, 1), 0);
 
		} else {
 
			/* Otherwise, we always keep the economy date synced with the calendar date. */
 
			TimerGameEconomy::SetDate(new_date.base(), 0);
 
		}
 
		InitializeOldNames();
 
	}
 

	
 
	LinkGraphSchedule::Clear();
 
	PoolBase::Clean(PT_NORMAL);
 

	
src/order_cmd.cpp
Show inline comments
 
@@ -1842,19 +1842,27 @@ void DeleteVehicleOrders(Vehicle *v, boo
 
		}
 
	}
 
}
 

	
 
/**
 
 * Clamp the service interval to the correct min/max. The actual min/max values
 
 * depend on whether it's in percent or days.
 
 * @param interval proposed service interval
 
 * @return Clamped service interval
 
 * depend on whether it's in days, minutes, or percent.
 
 * @param interval The proposed service interval.
 
 * @param ispercent Whether the interval is a percent.
 
 * @return The service interval clamped to use the chosen units.
 
 */
 
uint16_t GetServiceIntervalClamped(int interval, bool ispercent)
 
{
 
	return ispercent ? Clamp(interval, MIN_SERVINT_PERCENT, MAX_SERVINT_PERCENT) : Clamp(interval, MIN_SERVINT_DAYS, MAX_SERVINT_DAYS);
 
	/* Service intervals are in percents. */
 
	if (ispercent) return Clamp(interval, MIN_SERVINT_PERCENT, MAX_SERVINT_PERCENT);
 

	
 
	/* Service intervals are in minutes. */
 
	if (TimerGameEconomy::UsingWallclockUnits(_game_mode == GM_MENU)) return Clamp(interval, MIN_SERVINT_MINUTES, MAX_SERVINT_MINUTES);
 

	
 
	/* Service intervals are in days. */
 
	return Clamp(interval, MIN_SERVINT_DAYS, MAX_SERVINT_DAYS);
 
}
 

	
 
/**
 
 *
 
 * Check if a vehicle has any valid orders
 
 *
src/order_func.h
Show inline comments
 
@@ -30,12 +30,19 @@ static const uint DEF_SERVINT_DAYS_TRAIN
 
static const uint DEF_SERVINT_DAYS_ROADVEH  = 150;
 
static const uint DEF_SERVINT_DAYS_AIRCRAFT = 100;
 
static const uint DEF_SERVINT_DAYS_SHIPS    = 360;
 
static const uint MIN_SERVINT_DAYS          = 30;
 
static const uint MAX_SERVINT_DAYS          = 800;
 

	
 
static const uint DEF_SERVINT_MINUTES_TRAINS   = 5;
 
static const uint DEF_SERVINT_MINUTES_ROADVEH  = 5;
 
static const uint DEF_SERVINT_MINUTES_AIRCRAFT = 3;
 
static const uint DEF_SERVINT_MINUTES_SHIPS    = 12;
 
static const uint MIN_SERVINT_MINUTES          = 1;
 
static const uint MAX_SERVINT_MINUTES          = 30;
 

	
 
static const uint DEF_SERVINT_PERCENT = 50;
 
static const uint MIN_SERVINT_PERCENT = 5;
 
static const uint MAX_SERVINT_PERCENT = 90;
 

	
 
uint16_t GetServiceIntervalClamped(int interval, bool ispercent);
 

	
src/saveload/afterload.cpp
Show inline comments
 
@@ -732,12 +732,15 @@ bool AfterLoadGame()
 
	if (IsSavegameVersionBefore(SLV_11, 1) || (IsSavegameVersionBefore(SLV_147) && TimerGameCalendar::date_fract > Ticks::DAY_TICKS)) TimerGameCalendar::date_fract /= 885;
 

	
 
	/* Update current year
 
	 * must be done before loading sprites as some newgrfs check it */
 
	TimerGameCalendar::SetDate(TimerGameCalendar::date, TimerGameCalendar::date_fract);
 

	
 
	/* Only new games can use wallclock units. */
 
	if (IsSavegameVersionBefore(SLV_ECONOMY_MODE_TIMEKEEPING_UNITS)) _settings_game.economy.timekeeping_units = TKU_CALENDAR;
 

	
 
	/* Update economy year. If we don't have a separate economy date saved, follow the calendar date. */
 
	if (IsSavegameVersionBefore(SLV_ECONOMY_DATE)) {
 
		TimerGameEconomy::SetDate(TimerGameCalendar::date.base(), TimerGameCalendar::date_fract);
 
	} else {
 
		TimerGameEconomy::SetDate(TimerGameEconomy::date, TimerGameEconomy::date_fract);
 
	}
src/saveload/saveload.h
Show inline comments
 
@@ -366,12 +366,13 @@ enum SaveLoadVersion : uint16_t {
 
	SLV_TIMETABLE_START_TICKS_FIX,          ///< 322  PR#11557 Fix for missing convert timetable start from a date to ticks.
 
	SLV_TIMETABLE_TICKS_TYPE,               ///< 323  PR#11435 Convert timetable current order time to ticks.
 
	SLV_WATER_REGIONS,                      ///< 324  PR#10543 Water Regions for ship pathfinder.
 

	
 
	SLV_WATER_REGION_EVAL_SIMPLIFIED,       ///< 325  PR#11750 Simplified Water Region evaluation.
 
	SLV_ECONOMY_DATE,                       ///< 326  PR#10700 Split calendar and economy timers and dates.
 
	SLV_ECONOMY_MODE_TIMEKEEPING_UNITS,     ///< 327  PR#11341 Mode to display economy measurements in wallclock units.
 

	
 
	SL_MAX_VERSION,                         ///< Highest possible saveload version
 
};
 

	
 
/** Save or load result codes. */
 
enum SaveOrLoadResult {
src/settings_gui.cpp
Show inline comments
 
@@ -2209,12 +2209,13 @@ static SettingsContainer &GetSettingsTre
 
		}
 

	
 
		SettingsPage *environment = main->Add(new SettingsPage(STR_CONFIG_SETTING_ENVIRONMENT));
 
		{
 
			SettingsPage *time = environment->Add(new SettingsPage(STR_CONFIG_SETTING_ENVIRONMENT_TIME));
 
			{
 
				time->Add(new SettingEntry("economy.timekeeping_units"));
 
				time->Add(new SettingEntry("game_creation.ending_year"));
 
				time->Add(new SettingEntry("gui.pause_on_newgame"));
 
				time->Add(new SettingEntry("gui.fast_forward_speed_limit"));
 
			}
 

	
 
			SettingsPage *authorities = environment->Add(new SettingsPage(STR_CONFIG_SETTING_ENVIRONMENT_AUTHORITIES));
src/settings_table.cpp
Show inline comments
 
@@ -127,13 +127,13 @@ static void UpdateConsists(int32_t)
 
	}
 
	InvalidateWindowClassesData(WC_BUILD_VEHICLE, 0);
 
}
 

	
 
/**
 
 * Check and update if needed all vehicle service intervals.
 
 * @param new_value Contains 0 if service intervals are in days, otherwise intervals use percents.
 
 * @param new_value Contains 0 if service intervals are in time (days or real-world minutes), otherwise intervals use percents.
 
 */
 
static void UpdateAllServiceInterval(int32_t new_value)
 
{
 
	bool update_vehicles;
 
	VehicleDefaultSettings *vds;
 
	if (_game_mode == GM_MENU || !Company::IsValidID(_current_company)) {
 
@@ -147,12 +147,18 @@ static void UpdateAllServiceInterval(int
 
	if (new_value != 0) {
 
		/* Service intervals are in percents. */
 
		vds->servint_trains   = DEF_SERVINT_PERCENT;
 
		vds->servint_roadveh  = DEF_SERVINT_PERCENT;
 
		vds->servint_aircraft = DEF_SERVINT_PERCENT;
 
		vds->servint_ships    = DEF_SERVINT_PERCENT;
 
	} else if (TimerGameEconomy::UsingWallclockUnits(_game_mode == GM_MENU)) {
 
		/* Service intervals are in minutes. */
 
		vds->servint_trains   = DEF_SERVINT_MINUTES_TRAINS;
 
		vds->servint_roadveh  = DEF_SERVINT_MINUTES_ROADVEH;
 
		vds->servint_aircraft = DEF_SERVINT_MINUTES_AIRCRAFT;
 
		vds->servint_ships    = DEF_SERVINT_MINUTES_SHIPS;
 
	} else {
 
		/* Service intervals are in days. */
 
		vds->servint_trains   = DEF_SERVINT_DAYS_TRAINS;
 
		vds->servint_roadveh  = DEF_SERVINT_DAYS_ROADVEH;
 
		vds->servint_aircraft = DEF_SERVINT_DAYS_AIRCRAFT;
 
		vds->servint_ships    = DEF_SERVINT_DAYS_SHIPS;
 
@@ -480,7 +486,31 @@ static void UpdateClientConfigValues()
 
	if (_network_server) {
 
		NetworkServerSendConfigUpdate();
 
		SetWindowClassesDirty(WC_CLIENT_LIST);
 
	}
 
}
 

	
 
/**
 
 * Callback for when the player changes the timekeeping units.
 
 * @param Unused.
 
 */
 
static void ChangeTimekeepingUnits(int32_t)
 
{
 
	/* If service intervals are in time units (calendar days or real-world minutes), reset them to the correct defaults. */
 
	if (!_settings_client.company.vehicle.servint_ispercent) {
 
		UpdateAllServiceInterval(0);
 
	}
 

	
 
	InvalidateWindowClassesData(WC_GAME_OPTIONS, 0);
 
}
 

	
 
/**
 
 * Pre-callback check when trying to change the timetable mode. This is locked to Seconds when using wallclock units.
 
 * @param Unused.
 
 * @return True if we allow changing the timetable mode.
 
 */
 
static bool CanChangeTimetableMode(int32_t &)
 
{
 
	return !TimerGameEconomy::UsingWallclockUnits();
 
}
 

	
 
/* End - Callback Functions */
src/settings_type.h
Show inline comments
 
@@ -61,12 +61,18 @@ enum IndustryDensity {
 

	
 
	ID_CUSTOM,    ///< Custom number of industries.
 

	
 
	ID_END,       ///< Number of industry density settings.
 
};
 

	
 
/** Possible values for the "timekeeping_units" setting. */
 
enum TimekeepingUnits : uint8_t {
 
	TKU_CALENDAR = 0,
 
	TKU_WALLCLOCK,
 
};
 

	
 
/** Possible values for "use_relay_service" setting. */
 
enum UseRelayService : uint8_t {
 
	URS_NEVER = 0,
 
	URS_ASK,
 
	URS_ALLOW,
 
};
 
@@ -548,12 +554,13 @@ struct EconomySettings {
 
	bool   allow_town_roads;                 ///< towns are allowed to build roads (always allowed when generating world / in SE)
 
	TownFounding found_town;                 ///< town founding.
 
	bool   station_noise_level;              ///< build new airports when the town noise level is still within accepted limits
 
	uint16_t town_noise_population[4];         ///< population to base decision on noise evaluation (@see town_council_tolerance)
 
	bool   allow_town_level_crossings;       ///< towns are allowed to build level crossings
 
	bool   infrastructure_maintenance;       ///< enable monthly maintenance fee for owner infrastructure
 
	TimekeepingUnits timekeeping_units;      ///< time units to use for the game economy, either calendar or wallclock
 
};
 

	
 
struct LinkGraphSettings {
 
	uint16_t recalc_time;                     ///< time (in days) for recalculating each link graph component.
 
	uint16_t recalc_interval;                 ///< time (in days) between subsequent checks for link graphs to be calculated.
 
	DistributionType distribution_pax;      ///< distribution type for passengers
src/strgen/strgen_base.cpp
Show inline comments
 
@@ -374,12 +374,39 @@ void EmitPlural(Buffer *buffer, char *bu
 
	buffer->AppendUtf8(SCC_PLURAL_LIST);
 
	buffer->AppendByte(_lang.plural_form);
 
	buffer->AppendByte(TranslateArgumentIdx(argidx, offset));
 
	EmitWordList(buffer, words, nw);
 
}
 

	
 
/**
 
 * Handle the selection of timekeeping units based on the timekeeping setting.
 
 * This uses the string control character {TKM [value if calendar] [value if wallclock]}, e.g. {TKM month minute}.
 
 * @param buffer The output buffer
 
 * @param buf    The input buffer
 
 * @param        Unused
 
 */
 
void EmitTKM(Buffer* buffer, char* buf, int)
 
{
 
	/* The correct number of words is 2, but we'll check for more in case of typos. */
 
	std::vector<const char *> words(3, nullptr);
 

	
 
	/* Parse each string. */
 
	uint nw = 0;
 
	for (nw = 0; nw < 3; nw++) {
 
		words[nw] = ParseWord(&buf);
 
		if (words[nw] == nullptr) break;
 
	}
 

	
 
	/* Warn about the wrong number of parameters. */
 
	if (nw != 2) {
 
		StrgenFatal("%s: Invalid number of TKM options. Expecting %d, found %d.", _cur_ident, 2, nw);
 
	}
 

	
 
	buffer->AppendUtf8(SCC_TIMEKEEPING_MODE_LIST);
 
	EmitWordList(buffer, words, 2);
 
}
 

	
 
void EmitGender(Buffer *buffer, char *buf, int)
 
{
 
	int argidx = _cur_argidx;
 
	int offset = 0;
 
	uint nw;
src/strings.cpp
Show inline comments
 
@@ -743,18 +743,27 @@ struct UnitsLong {
 
	StringID s;       ///< String for the short variant of the unit
 
	StringID l;       ///< String for the long variant of the unit
 
	unsigned int decimal_places; ///< Number of decimal places embedded in the value. For example, 1 if the value is in tenths, and 3 if the value is in thousandths.
 
};
 

	
 
/** Unit conversions for velocity. */
 
static const Units _units_velocity[] = {
 
	{ { 1.0      }, STR_UNITS_VELOCITY_IMPERIAL,  0 },
 
	{ { 1.609344 }, STR_UNITS_VELOCITY_METRIC,    0 },
 
	{ { 0.44704  }, STR_UNITS_VELOCITY_SI,        0 },
 
	{ { 0.578125 }, STR_UNITS_VELOCITY_GAMEUNITS, 1 },
 
	{ { 0.868976 }, STR_UNITS_VELOCITY_KNOTS,     0 },
 
static const Units _units_velocity_calendar[] = {
 
	{ { 1.0      }, STR_UNITS_VELOCITY_IMPERIAL,      0 },
 
	{ { 1.609344 }, STR_UNITS_VELOCITY_METRIC,        0 },
 
	{ { 0.44704  }, STR_UNITS_VELOCITY_SI,            0 },
 
	{ { 0.578125 }, STR_UNITS_VELOCITY_GAMEUNITS_DAY, 1 },
 
	{ { 0.868976 }, STR_UNITS_VELOCITY_KNOTS,         0 },
 
};
 

	
 
/** Unit conversions for velocity. */
 
static const Units _units_velocity_realtime[] = {
 
	{ { 1.0      }, STR_UNITS_VELOCITY_IMPERIAL,      0 },
 
	{ { 1.609344 }, STR_UNITS_VELOCITY_METRIC,        0 },
 
	{ { 0.44704  }, STR_UNITS_VELOCITY_SI,            0 },
 
	{ { 0.289352 }, STR_UNITS_VELOCITY_GAMEUNITS_SEC, 1 },
 
	{ { 0.868976 }, STR_UNITS_VELOCITY_KNOTS,         0 },
 
};
 

	
 
/** Unit conversions for power. */
 
static const Units _units_power[] = {
 
	{ { 1.0      }, STR_UNITS_POWER_IMPERIAL, 0 },
 
	{ { 1.01387  }, STR_UNITS_POWER_METRIC,   0 },
 
@@ -799,65 +808,94 @@ static const Units _units_force[] = {
 
static const Units _units_height[] = {
 
	{ { 3.0 }, STR_UNITS_HEIGHT_IMPERIAL, 0 }, // "Wrong" conversion factor for more nicer GUI values
 
	{ { 1.0 }, STR_UNITS_HEIGHT_METRIC,   0 },
 
	{ { 1.0 }, STR_UNITS_HEIGHT_SI,       0 },
 
};
 

	
 
/** Unit conversions for time in calendar days or wallclock seconds */
 
static const Units _units_time_days_or_seconds[] = {
 
	{ { 1 }, STR_UNITS_DAYS,    0 },
 
	{ { 2 }, STR_UNITS_SECONDS, 0 },
 
};
 

	
 
/** Unit conversions for time in calendar months or wallclock minutes */
 
static const Units _units_time_months_or_minutes[] = {
 
	{ { 1 }, STR_UNITS_MONTHS,  0 },
 
	{ { 1 }, STR_UNITS_MINUTES, 0 },
 
};
 

	
 
/** Unit conversions for time in calendar years or economic periods */
 
static const Units _units_time_years_or_periods[] = {
 
	{ { 1 }, STR_UNITS_YEARS,  0 },
 
	{ { 1 }, STR_UNITS_PERIODS, 0 },
 
};
 

	
 
/** Unit conversions for time in calendar years or wallclock minutes */
 
static const Units _units_time_years_or_minutes[] = {
 
	{ { 1  }, STR_UNITS_YEARS,  0 },
 
	{ { 12 }, STR_UNITS_MINUTES, 0 },
 
};
 

	
 
/**
 
 * Get index for velocity conversion units for a vehicle type.
 
 * Get the correct velocity units depending on the vehicle type and whether we're using real-time units.
 
 * @param type VehicleType to convert velocity for.
 
 * @return Index within velocity conversion units for vehicle type.
 
 * @return The Units for the proper vehicle and time mode.
 
 */
 
static byte GetVelocityUnits(VehicleType type)
 
static const Units GetVelocityUnits(VehicleType type)
 
{
 
	if (type == VEH_SHIP || type == VEH_AIRCRAFT) return _settings_game.locale.units_velocity_nautical;
 
	byte setting = (type == VEH_SHIP || type == VEH_AIRCRAFT) ? _settings_game.locale.units_velocity_nautical : _settings_game.locale.units_velocity;
 

	
 
	return _settings_game.locale.units_velocity;
 
	assert(setting < lengthof(_units_velocity_calendar));
 
	assert(setting < lengthof(_units_velocity_realtime));
 

	
 
	if (TimerGameEconomy::UsingWallclockUnits()) return _units_velocity_realtime[setting];
 

	
 
	return _units_velocity_calendar[setting];
 
}
 

	
 
/**
 
 * Convert the given (internal) speed to the display speed.
 
 * @param speed the speed to convert
 
 * @return the converted speed.
 
 */
 
uint ConvertSpeedToDisplaySpeed(uint speed, VehicleType type)
 
{
 
	/* For historical reasons we don't want to mess with the
 
	 * conversion for speed. So, don't round it and keep the
 
	 * original conversion factors instead of the real ones. */
 
	return _units_velocity[GetVelocityUnits(type)].c.ToDisplay(speed, false);
 
	return GetVelocityUnits(type).c.ToDisplay(speed, false);
 
}
 

	
 
/**
 
 * Convert the given display speed to the (internal) speed.
 
 * @param speed the speed to convert
 
 * @return the converted speed.
 
 */
 
uint ConvertDisplaySpeedToSpeed(uint speed, VehicleType type)
 
{
 
	return _units_velocity[GetVelocityUnits(type)].c.FromDisplay(speed);
 
	return GetVelocityUnits(type).c.FromDisplay(speed);
 
}
 

	
 
/**
 
 * Convert the given km/h-ish speed to the display speed.
 
 * @param speed the speed to convert
 
 * @return the converted speed.
 
 */
 
uint ConvertKmhishSpeedToDisplaySpeed(uint speed, VehicleType type)
 
{
 
	return _units_velocity[GetVelocityUnits(type)].c.ToDisplay(speed * 10, false) / 16;
 
	return GetVelocityUnits(type).c.ToDisplay(speed * 10, false) / 16;
 
}
 

	
 
/**
 
 * Convert the given display speed to the km/h-ish speed.
 
 * @param speed the speed to convert
 
 * @return the converted speed.
 
 */
 
uint ConvertDisplaySpeedToKmhishSpeed(uint speed, VehicleType type)
 
{
 
	return _units_velocity[GetVelocityUnits(type)].c.FromDisplay(speed * 16, true, 10);
 
	return GetVelocityUnits(type).c.FromDisplay(speed * 16, true, 10);
 
}
 

	
 
/**
 
 * Parse most format codes within a string and write the result to a buffer.
 
 * @param builder The string builder to write the final string to.
 
 * @param str_arg The original string with format codes.
 
@@ -1331,15 +1369,13 @@ static void FormatString(StringBuilder &
 
				}
 

	
 
				case SCC_VELOCITY: { // {VELOCITY}
 
					int64_t arg = args.GetNextParameter<int64_t>();
 
					// Unpack vehicle type from packed argument to get desired units.
 
					VehicleType vt = static_cast<VehicleType>(GB(arg, 56, 8));
 
					byte units = GetVelocityUnits(vt);
 
					assert(units < lengthof(_units_velocity));
 
					const auto &x = _units_velocity[units];
 
					const auto &x = GetVelocityUnits(vt);
 
					auto tmp_params = MakeParameters(ConvertKmhishSpeedToDisplaySpeed(GB(arg, 0, 56), vt), x.decimal_places);
 
					FormatString(builder, GetStringPtr(x.s), tmp_params);
 
					break;
 
				}
 

	
 
				case SCC_VOLUME_SHORT: { // {VOLUME_SHORT}
 
@@ -1371,12 +1407,49 @@ static void FormatString(StringBuilder &
 
					const auto &x = _units_weight[_settings_game.locale.units_weight];
 
					auto tmp_params = MakeParameters(x.c.ToDisplay(args.GetNextParameter<int64_t>()), x.decimal_places);
 
					FormatString(builder, GetStringPtr(x.l), tmp_params);
 
					break;
 
				}
 

	
 
				case SCC_UNITS_DAYS_OR_SECONDS: { // {UNITS_DAYS_OR_SECONDS}
 
					uint8_t realtime = TimerGameEconomy::UsingWallclockUnits(_game_mode == GM_MENU);
 
					const auto &x = _units_time_days_or_seconds[realtime];
 
					auto tmp_params = MakeParameters(x.c.ToDisplay(args.GetNextParameter<int64_t>()), x.decimal_places);
 
					FormatString(builder, GetStringPtr(x.s), tmp_params);
 
					break;
 
				}
 

	
 
				case SCC_UNITS_MONTHS_OR_MINUTES: { // {UNITS_MONTHS_OR_MINUTES}
 
					uint8_t realtime = TimerGameEconomy::UsingWallclockUnits(_game_mode == GM_MENU);
 
					const auto &x = _units_time_months_or_minutes[realtime];
 
					auto tmp_params = MakeParameters(x.c.ToDisplay(args.GetNextParameter<int64_t>()), x.decimal_places);
 
					FormatString(builder, GetStringPtr(x.s), tmp_params);
 
					break;
 
				}
 

	
 
				case SCC_UNITS_YEARS_OR_PERIODS: { // {UNITS_YEARS_OR_PERIODS}
 
					uint8_t realtime = TimerGameEconomy::UsingWallclockUnits(_game_mode == GM_MENU);
 
					const auto &x = _units_time_years_or_periods[realtime];
 
					auto tmp_params = MakeParameters(x.c.ToDisplay(args.GetNextParameter<int64_t>()), x.decimal_places);
 
					FormatString(builder, GetStringPtr(x.s), tmp_params);
 
					break;
 
				}
 

	
 
				case SCC_UNITS_YEARS_OR_MINUTES: { // {UNITS_YEARS_OR_MINUTES}
 
					uint8_t realtime = TimerGameEconomy::UsingWallclockUnits(_game_mode == GM_MENU);
 
					const auto &x = _units_time_years_or_minutes[realtime];
 
					auto tmp_params = MakeParameters(x.c.ToDisplay(args.GetNextParameter<int64_t>()), x.decimal_places);
 
					FormatString(builder, GetStringPtr(x.s), tmp_params);
 
					break;
 
				}
 

	
 
				case SCC_TIMEKEEPING_MODE_LIST: { // {TKM}
 
					str = ParseStringChoice(str, (uint8_t)TimerGameEconomy::UsingWallclockUnits(_game_mode == GM_MENU), builder);
 
					break;
 
				}
 

	
 
				case SCC_COMPANY_NAME: { // {COMPANY}
 
					const Company *c = Company::GetIfValid(args.GetNextParameter<CompanyID>());
 
					if (c == nullptr) break;
 

	
 
					if (!c->name.empty()) {
 
						auto tmp_params = MakeParameters(c->name);
src/subsidy_gui.cpp
Show inline comments
 
@@ -156,13 +156,21 @@ struct SubsidyListWindow : Window {
 
		uint num = 0;
 
		for (const Subsidy *s : Subsidy::Iterate()) {
 
			if (!s->IsAwarded()) {
 
				if (IsInsideMM(pos, 0, cap)) {
 
					/* Displays the two offered towns */
 
					SetupSubsidyDecodeParam(s, SubsidyDecodeParamType::Gui);
 
					SetDParam(7, TimerGameEconomy::date - ymd.day + s->remaining * 32);
 
					/* If using wallclock units, show minutes remaining. Otherwise show the date when the subsidy ends. */
 
					if (TimerGameEconomy::UsingWallclockUnits()) {
 
						SetDParam(7, STR_SUBSIDIES_OFFERED_EXPIRY_TIME);
 
						SetDParam(8, s->remaining + 1); // We get the rest of the current economy month for free, since the expiration is checked on each new month.
 
					} else {
 
						SetDParam(7, STR_SUBSIDIES_OFFERED_EXPIRY_DATE);
 
						SetDParam(8, TimerGameEconomy::date - ymd.day + s->remaining * 32);
 
					}
 

	
 
					DrawString(tr.left, tr.right, tr.top + pos * GetCharacterHeight(FS_NORMAL), STR_SUBSIDIES_OFFERED_FROM_TO);
 
				}
 
				pos++;
 
				num++;
 
			}
 
		}
 
@@ -180,13 +188,21 @@ struct SubsidyListWindow : Window {
 

	
 
		for (const Subsidy *s : Subsidy::Iterate()) {
 
			if (s->IsAwarded()) {
 
				if (IsInsideMM(pos, 0, cap)) {
 
					SetupSubsidyDecodeParam(s, SubsidyDecodeParamType::Gui);
 
					SetDParam(7, s->awarded);
 
					SetDParam(8, TimerGameEconomy::date - ymd.day + s->remaining * 32);
 
					/* If using wallclock units, show minutes remaining. Otherwise show the date when the subsidy ends. */
 
					if (TimerGameEconomy::UsingWallclockUnits()) {
 
						SetDParam(8, STR_SUBSIDIES_SUBSIDISED_EXPIRY_TIME);
 
						SetDParam(9, s->remaining);
 
					}
 
					else {
 
						SetDParam(8, STR_SUBSIDIES_SUBSIDISED_EXPIRY_DATE);
 
						SetDParam(9, TimerGameEconomy::date - ymd.day + s->remaining * 32);
 
					}
 

	
 
					/* Displays the two connected stations */
 
					DrawString(tr.left, tr.right, tr.top + pos * GetCharacterHeight(FS_NORMAL), STR_SUBSIDIES_SUBSIDISED_FROM_TO);
 
				}
 
				pos++;
 
				num++;
src/table/control_codes.h
Show inline comments
 
@@ -62,12 +62,18 @@ enum StringControlCode {
 
	SCC_WEIGHT_LONG,
 
	SCC_WEIGHT_SHORT,
 
	SCC_FORCE,
 
	SCC_VELOCITY,
 
	SCC_HEIGHT,
 

	
 
	SCC_UNITS_DAYS_OR_SECONDS,
 
	SCC_UNITS_MONTHS_OR_MINUTES,
 
	SCC_UNITS_YEARS_OR_PERIODS,
 
	SCC_UNITS_YEARS_OR_MINUTES,
 
	SCC_TIMEKEEPING_MODE_LIST,
 

	
 
	SCC_DATE_TINY,
 
	SCC_DATE_SHORT,
 
	SCC_DATE_LONG,
 
	SCC_DATE_ISO,
 

	
 
	/* Must be consecutive */
src/table/settings/company_settings.ini
Show inline comments
 
@@ -81,13 +81,13 @@ post_cb  = UpdateAllServiceInterval
 

	
 
[SDT_VAR]
 
var      = vehicle.servint_trains
 
type     = SLE_UINT16
 
flags    = SF_PER_COMPANY | SF_GUI_0_IS_SPECIAL
 
def      = DEF_SERVINT_DAYS_TRAINS
 
min      = MIN_SERVINT_PERCENT
 
min      = MIN_SERVINT_MINUTES
 
max      = MAX_SERVINT_DAYS
 
interval = 1
 
str      = STR_CONFIG_SETTING_SERVINT_TRAINS
 
strhelp  = STR_CONFIG_SETTING_SERVINT_TRAINS_HELPTEXT
 
strval   = STR_CONFIG_SETTING_SERVINT_VALUE
 
pre_cb   = [](auto &new_value) { return CanUpdateServiceInterval(VEH_TRAIN, new_value); }
 
@@ -95,13 +95,13 @@ post_cb  = [](auto new_value) { UpdateSe
 

	
 
[SDT_VAR]
 
var      = vehicle.servint_roadveh
 
type     = SLE_UINT16
 
flags    = SF_PER_COMPANY | SF_GUI_0_IS_SPECIAL
 
def      = DEF_SERVINT_DAYS_ROADVEH
 
min      = MIN_SERVINT_PERCENT
 
min      = MIN_SERVINT_MINUTES
 
max      = MAX_SERVINT_DAYS
 
interval = 1
 
str      = STR_CONFIG_SETTING_SERVINT_ROAD_VEHICLES
 
strhelp  = STR_CONFIG_SETTING_SERVINT_ROAD_VEHICLES_HELPTEXT
 
strval   = STR_CONFIG_SETTING_SERVINT_VALUE
 
pre_cb   = [](auto &new_value) { return CanUpdateServiceInterval(VEH_ROAD, new_value); }
 
@@ -109,13 +109,13 @@ post_cb  = [](auto new_value) { UpdateSe
 

	
 
[SDT_VAR]
 
var      = vehicle.servint_ships
 
type     = SLE_UINT16
 
flags    = SF_PER_COMPANY | SF_GUI_0_IS_SPECIAL
 
def      = DEF_SERVINT_DAYS_SHIPS
 
min      = MIN_SERVINT_PERCENT
 
min      = MIN_SERVINT_MINUTES
 
max      = MAX_SERVINT_DAYS
 
interval = 1
 
str      = STR_CONFIG_SETTING_SERVINT_SHIPS
 
strhelp  = STR_CONFIG_SETTING_SERVINT_SHIPS_HELPTEXT
 
strval   = STR_CONFIG_SETTING_SERVINT_VALUE
 
pre_cb   = [](auto &new_value) { return CanUpdateServiceInterval(VEH_SHIP, new_value); }
 
@@ -123,13 +123,13 @@ post_cb  = [](auto new_value) { UpdateSe
 

	
 
[SDT_VAR]
 
var      = vehicle.servint_aircraft
 
type     = SLE_UINT16
 
flags    = SF_PER_COMPANY | SF_GUI_0_IS_SPECIAL
 
def      = DEF_SERVINT_DAYS_AIRCRAFT
 
min      = MIN_SERVINT_PERCENT
 
min      = MIN_SERVINT_MINUTES
 
max      = MAX_SERVINT_DAYS
 
interval = 1
 
str      = STR_CONFIG_SETTING_SERVINT_AIRCRAFT
 
strhelp  = STR_CONFIG_SETTING_SERVINT_AIRCRAFT_HELPTEXT
 
strval   = STR_CONFIG_SETTING_SERVINT_VALUE
 
pre_cb   = [](auto &new_value) { return CanUpdateServiceInterval(VEH_AIRCRAFT, new_value); }
src/table/settings/economy_settings.ini
Show inline comments
 
@@ -6,12 +6,13 @@
 

	
 
; Economy settings as stored in the main configuration file ("openttd.cfg")
 
; and in the savegame PATS chunk.
 

	
 
[pre-amble]
 
static void TownFoundingChanged(int32_t new_value);
 
static void ChangeTimekeepingUnits(int32_t new_value);
 

	
 
static const SettingVariant _economy_settings_table[] = {
 
[post-amble]
 
};
 
[templates]
 
SDT_BOOL   =   SDT_BOOL(GameSettings, $var,        $flags, $def,                              $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to,        $cat, $extra, $startup),
 
@@ -277,6 +278,19 @@ var      = economy.infrastructure_mainte
 
from     = SLV_166
 
def      = false
 
str      = STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE
 
strhelp  = STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE_HELPTEXT
 
post_cb  = [](auto) { InvalidateWindowClassesData(WC_COMPANY_INFRASTRUCTURE); }
 
cat      = SC_BASIC
 

	
 
[SDT_VAR]
 
var      = economy.timekeeping_units
 
type     = SLE_UINT8
 
flags    = SF_GUI_DROPDOWN | SF_NEWGAME_ONLY | SF_SCENEDIT_TOO
 
def      = TKU_CALENDAR
 
min      = TKU_CALENDAR
 
max      = TKU_WALLCLOCK
 
str      = STR_CONFIG_SETTING_TIMEKEEPING_UNITS
 
strval   = STR_CONFIG_SETTING_TIMEKEEPING_UNITS_CALENDAR
 
strhelp  = STR_CONFIG_SETTING_TIMEKEEPING_UNITS_HELPTEXT
 
post_cb  = ChangeTimekeepingUnits
 
cat      = SC_BASIC
src/table/settings/gui_settings.ini
Show inline comments
 
@@ -4,12 +4,13 @@
 
; See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
;
 

	
 
; GUI settings as stored in the main configuration file ("openttd.cfg").
 

	
 
[pre-amble]
 
static bool CanChangeTimetableMode(int32_t &new_value);
 
static void v_PositionMainToolbar(int32_t new_value);
 
static void v_PositionStatusbar(int32_t new_value);
 
static void RedrawSmallmap(int32_t new_value);
 
static void UpdateLinkgraphColours(int32_t new_value);
 
static void InvalidateCompanyLiveryWindow(int32_t new_value);
 
static void InvalidateNewGRFChangeWindows(int32_t new_value);
 
@@ -427,12 +428,13 @@ flags    = SF_NOT_IN_SAVE | SF_NO_NETWOR
 
def      = 0
 
min      = 0
 
max      = 2
 
str      = STR_CONFIG_SETTING_TIMETABLE_MODE
 
strhelp  = STR_CONFIG_SETTING_TIMETABLE_MODE_HELPTEXT
 
strval   = STR_CONFIG_SETTING_TIMETABLE_MODE_DAYS
 
pre_cb   = CanChangeTimetableMode
 
post_cb  = [](auto) { InvalidateWindowClassesData(WC_VEHICLE_TIMETABLE, VIWD_MODIFY_ORDERS); }
 
cat      = SC_ADVANCED
 

	
 
[SDTC_BOOL]
 
var      = gui.timetable_arrival_departure
 
flags    = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC
src/table/strgen_tables.h
Show inline comments
 
@@ -27,12 +27,13 @@ struct CmdStruct {
 
	uint8_t consumes;
 
	int8_t default_plural_offset;
 
	CmdFlags flags;
 
};
 

	
 
extern void EmitSingleChar(Buffer *buffer, char *buf, int value);
 
extern void EmitTKM(Buffer* buffer, char* buf, int value);
 
extern void EmitPlural(Buffer *buffer, char *buf, int value);
 
extern void EmitGender(Buffer *buffer, char *buf, int value);
 

	
 
static const CmdStruct _cmd_structs[] = {
 
	/* Font size */
 
	{"NORMAL_FONT",       EmitSingleChar, SCC_NORMALFONT,         0, -1, C_NONE},
 
@@ -85,12 +86,19 @@ static const CmdStruct _cmd_structs[] = 
 
	{"WEIGHT_LONG",       EmitSingleChar, SCC_WEIGHT_LONG,        1,  0, C_NONE},
 
	{"WEIGHT_SHORT",      EmitSingleChar, SCC_WEIGHT_SHORT,       1,  0, C_NONE},
 
	{"FORCE",             EmitSingleChar, SCC_FORCE,              1,  0, C_NONE},
 
	{"VELOCITY",          EmitSingleChar, SCC_VELOCITY,           1,  0, C_NONE},
 
	{"HEIGHT",            EmitSingleChar, SCC_HEIGHT,             1,  0, C_NONE},
 

	
 
	{"UNITS_DAYS_OR_SECONDS",   EmitSingleChar, SCC_UNITS_DAYS_OR_SECONDS,   1,  0, C_NONE},
 
	{"UNITS_MONTHS_OR_MINUTES", EmitSingleChar, SCC_UNITS_MONTHS_OR_MINUTES, 1,  0, C_NONE},
 
	{"UNITS_YEARS_OR_PERIODS",  EmitSingleChar, SCC_UNITS_YEARS_OR_PERIODS,  1,  0, C_NONE},
 
	{"UNITS_YEARS_OR_MINUTES",  EmitSingleChar, SCC_UNITS_YEARS_OR_MINUTES,  1,  0, C_NONE},
 

	
 
	{"TKM",                     EmitTKM,  0,                      0, -1, C_DONTCOUNT}, // Timekeeping mode string selection, e.g. "{TKM month minute}"
 

	
 
	{"P",                 EmitPlural,     0,                      0, -1, C_DONTCOUNT}, // plural specifier
 
	{"G",                 EmitGender,     0,                      0, -1, C_DONTCOUNT}, // gender specifier
 

	
 
	{"DATE_TINY",         EmitSingleChar, SCC_DATE_TINY,          1, -1, C_NONE},
 
	{"DATE_SHORT",        EmitSingleChar, SCC_DATE_SHORT,         1, -1, C_CASE},
 
	{"DATE_LONG",         EmitSingleChar, SCC_DATE_LONG,          1, -1, C_CASE},
src/timer/timer_game_calendar.cpp
Show inline comments
 
@@ -31,12 +31,36 @@
 
TimerGameCalendar::Year TimerGameCalendar::year = {};
 
TimerGameCalendar::Month TimerGameCalendar::month = {};
 
TimerGameCalendar::Date TimerGameCalendar::date = {};
 
TimerGameCalendar::DateFract TimerGameCalendar::date_fract = {};
 

	
 
/**
 
 * Converts a Date to a Year, Month & Day.
 
 * @param date the date to convert from
 
 * @returns YearMonthDay representation of the Date.
 
 */
 
/* static */ TimerGameCalendar::YearMonthDay TimerGameCalendar::ConvertDateToYMD(TimerGameCalendar::Date date)
 
{
 
	/* This wrapper function only exists because economy time sometimes does things differently, when using wallclock units. */
 
	return CalendarConvertDateToYMD(date);
 
}
 

	
 
/**
 
 * Converts a tuple of Year, Month and Day to a Date.
 
 * @param year  is a number between 0..MAX_YEAR
 
 * @param month is a number between 0..11
 
 * @param day   is a number between 1..31
 
 * @returns The equivalent date.
 
 */
 
/* static */ TimerGameCalendar::Date TimerGameCalendar::ConvertYMDToDate(TimerGameCalendar::Year year, TimerGameCalendar::Month month, TimerGameCalendar::Day day)
 
{
 
	/* This wrapper function only exists because economy time sometimes does things differently, when using wallclock units. */
 
	return CalendarConvertYMDToDate(year, month, day);
 
}
 

	
 
/**
 
 * Set the date.
 
 * @param date  New date
 
 * @param fract The number of ticks that have passed on this date.
 
 */
 
/* static */ void TimerGameCalendar::SetDate(TimerGameCalendar::Date date, TimerGameCalendar::DateFract fract)
 
{
src/timer/timer_game_calendar.h
Show inline comments
 
@@ -31,12 +31,14 @@ class TimerGameCalendar : public TimerGa
 
public:
 
	static Year year; ///< Current year, starting at 0.
 
	static Month month; ///< Current month (0..11).
 
	static Date date; ///< Current date in days (day counter).
 
	static DateFract date_fract; ///< Fractional part of the day.
 

	
 
	static YearMonthDay ConvertDateToYMD(Date date);
 
	static Date ConvertYMDToDate(Year year, Month month, Day day);
 
	static void SetDate(Date date, DateFract fract);
 
};
 

	
 
/**
 
 * Storage class for Calendar time constants.
 
 */
src/timer/timer_game_common.cpp
Show inline comments
 
@@ -60,13 +60,13 @@ static constexpr uint16_t _accum_days_fo
 
/**
 
 * Converts a Date to a Year, Month & Day.
 
 * @param date the date to convert from
 
 * @returns YearMonthDay representation of the Date.
 
 */
 
template <class T>
 
/* static */ typename TimerGame<T>::YearMonthDay TimerGame<T>::ConvertDateToYMD(Date date)
 
/* static */ typename TimerGame<T>::YearMonthDay TimerGame<T>::CalendarConvertDateToYMD(Date date)
 
{
 
	/* Year determination in multiple steps to account for leap
 
	 * years. First do the large steps, then the smaller ones.
 
	 */
 

	
 
	/* There are 97 leap years in 400 years */
 
@@ -115,26 +115,27 @@ template <class T>
 

	
 
/**
 
 * Converts a tuple of Year, Month and Day to a Date.
 
 * @param year  is a number between 0..MAX_YEAR
 
 * @param month is a number between 0..11
 
 * @param day   is a number between 1..31
 
 * @returns The equivalent date.
 
 */
 
template <class T>
 
/* static */ typename TimerGame<T>::Date TimerGame<T>::ConvertYMDToDate(Year year, Month month, Day day)
 
/* static */ typename TimerGame<T>::Date TimerGame<T>::CalendarConvertYMDToDate(Year year, Month month, Day day)
 
{
 
	/* Day-offset in a leap year */
 
	int days = _accum_days_for_month[month] + day - 1;
 

	
 
	/* Account for the missing of the 29th of February in non-leap years */
 
	if (!IsLeapYear(year) && days >= ACCUM_MAR) days--;
 

	
 
	return DateAtStartOfYear(year) + days;
 
}
 

	
 
/* Create instances of the two template variants that we have.
 
 * This is needed, as this templated functions are not in a header-file. */
 
template TimerGame<struct Calendar>::YearMonthDay TimerGame<struct Calendar>::ConvertDateToYMD(Date date);
 
template TimerGame<struct Economy>::YearMonthDay TimerGame<struct Economy>::ConvertDateToYMD(Date date);
 
template TimerGame<struct Calendar>::YearMonthDay TimerGame<struct Calendar>::CalendarConvertDateToYMD(Date date);
 
template TimerGame<struct Economy>::YearMonthDay TimerGame<struct Economy>::CalendarConvertDateToYMD(Date date);
 

	
 
template TimerGame<struct Calendar>::Date TimerGame<struct Calendar>::ConvertYMDToDate(Year year, Month month, Day day);
 
template TimerGame<struct Economy>::Date TimerGame<struct Economy>::ConvertYMDToDate(Year year, Month month, Day day);
 
template TimerGame<struct Calendar>::Date TimerGame<struct Calendar>::CalendarConvertYMDToDate(Year year, Month month, Day day);
 
template TimerGame<struct Economy>::Date TimerGame<struct Economy>::CalendarConvertYMDToDate(Year year, Month month, Day day);
src/timer/timer_game_common.h
Show inline comments
 
@@ -63,14 +63,14 @@ public:
 
	static constexpr bool IsLeapYear(Year year)
 
	{
 
		int32_t year_as_int = year.base();
 
		return year_as_int % 4 == 0 && (year_as_int % 100 != 0 || year_as_int % 400 == 0);
 
	}
 

	
 
	static YearMonthDay ConvertDateToYMD(Date date);
 
	static Date ConvertYMDToDate(Year year, Month month, Day day);
 
	static YearMonthDay CalendarConvertDateToYMD(Date date);
 
	static Date CalendarConvertYMDToDate(Year year, Month month, Day day);
 

	
 
	/**
 
	 * Calculate the year of a given date.
 
	 * @param date The date to consider.
 
	 * @return the year.
 
	 */
src/timer/timer_game_economy.cpp
Show inline comments
 
@@ -36,12 +36,47 @@
 
TimerGameEconomy::Year TimerGameEconomy::year = {};
 
TimerGameEconomy::Month TimerGameEconomy::month = {};
 
TimerGameEconomy::Date TimerGameEconomy::date = {};
 
TimerGameEconomy::DateFract TimerGameEconomy::date_fract = {};
 

	
 
/**
 
 * Converts a Date to a Year, Month & Day.
 
 * @param date the date to convert from
 
 * @returns YearMonthDay representation of the Date.
 
 */
 
/* static */ TimerGameEconomy::YearMonthDay TimerGameEconomy::ConvertDateToYMD(TimerGameEconomy::Date date)
 
{
 
	/* If we're not using wallclock units, we keep the economy date in sync with the calendar. */
 
	if (!UsingWallclockUnits()) return CalendarConvertDateToYMD(date);
 

	
 
	/* If we're using wallclock units, economy months have 30 days and an economy year has 360 days. */
 
	TimerGameEconomy::YearMonthDay ymd;
 
	ymd.year = TimerGameEconomy::date.base() / EconomyTime::DAYS_IN_ECONOMY_YEAR;
 
	ymd.month = (TimerGameEconomy::date.base() % EconomyTime::DAYS_IN_ECONOMY_YEAR) / EconomyTime::DAYS_IN_ECONOMY_MONTH;
 
	ymd.day = TimerGameEconomy::date.base() % EconomyTime::DAYS_IN_ECONOMY_MONTH;
 
	return ymd;
 
}
 

	
 
/**
 
 * Converts a tuple of Year, Month and Day to a Date.
 
 * @param year  is a number between 0..MAX_YEAR
 
 * @param month is a number between 0..11
 
 * @param day   is a number between 1..31
 
 * @returns The equivalent date.
 
 */
 
/* static */ TimerGameEconomy::Date TimerGameEconomy::ConvertYMDToDate(TimerGameEconomy::Year year, TimerGameEconomy::Month month, TimerGameEconomy::Day day)
 
{
 
	/* If we're not using wallclock units, we keep the economy date in sync with the calendar. */
 
	if (!UsingWallclockUnits()) return CalendarConvertYMDToDate(year, month, day);
 

	
 
	/* If we're using wallclock units, economy months have 30 days and an economy year has 360 days. */
 
	const int total_months = (year.base() * EconomyTime::MONTHS_IN_YEAR) + month;
 
	return (total_months * EconomyTime::DAYS_IN_ECONOMY_MONTH) + day - 1; // Day is 1-indexed but Date is 0-indexed, hence the - 1.
 
}
 

	
 
/**
 
 * Set the date.
 
 * @param date The new date
 
 * @param fract The number of ticks that have passed on this date.
 
 */
 
/* static */ void TimerGameEconomy::SetDate(TimerGameEconomy::Date date, TimerGameEconomy::DateFract fract)
 
{
 
@@ -51,12 +86,24 @@ TimerGameEconomy::DateFract TimerGameEco
 
	TimerGameEconomy::date_fract = fract;
 
	TimerGameEconomy::YearMonthDay ymd = TimerGameEconomy::ConvertDateToYMD(date);
 
	TimerGameEconomy::year = ymd.year;
 
	TimerGameEconomy::month = ymd.month;
 
}
 

	
 
/**
 
 * Check if we are using wallclock units.
 
 * @param newgame Should we check the settings for a new game (since we are in the main menu)?
 
 * @return True if the game is using wallclock units, or false if the game is using calendar units.
 
 */
 
/* static */ bool TimerGameEconomy::UsingWallclockUnits(bool newgame)
 
{
 
	if (newgame) return (_settings_newgame.economy.timekeeping_units == TKU_WALLCLOCK);
 

	
 
	return (_settings_game.economy.timekeeping_units == TKU_WALLCLOCK);
 
}
 

	
 
template<>
 
void IntervalTimer<TimerGameEconomy>::Elapsed(TimerGameEconomy::TElapsed trigger)
 
{
 
	if (trigger == this->period.trigger) {
 
		this->callback(1);
 
	}
src/timer/timer_game_economy.h
Show inline comments
 
@@ -34,15 +34,22 @@ class TimerGameEconomy : public TimerGam
 
public:
 
	static Year year; ///< Current year, starting at 0.
 
	static Month month; ///< Current month (0..11).
 
	static Date date; ///< Current date in days (day counter).
 
	static DateFract date_fract; ///< Fractional part of the day.
 

	
 
	static YearMonthDay ConvertDateToYMD(Date date);
 
	static Date ConvertYMDToDate(Year year, Month month, Day day);
 
	static void SetDate(Date date, DateFract fract);
 
	static bool UsingWallclockUnits(bool newgame = false);
 
};
 

	
 
/**
 
 * Storage class for Economy time constants.
 
 */
 
class EconomyTime : public TimerGameConst<struct Economy> {};
 
class EconomyTime : public TimerGameConst<struct Economy> {
 
public:
 
	static constexpr int DAYS_IN_ECONOMY_YEAR = 360; ///< Days in an economy year, when in wallclock timekeeping mode.
 
	static constexpr int DAYS_IN_ECONOMY_MONTH = 30; ///< Days in an economy month, when in wallclock timekeeping mode.
 
};
 

	
 
#endif /* TIMER_GAME_ECONOMY_H */
src/timetable_gui.cpp
Show inline comments
 
@@ -212,12 +212,18 @@ struct TimetableWindow : Window {
 
			sel_index(-1),
 
			vehicle(Vehicle::Get(window_number)),
 
			show_expected(true)
 
	{
 
		this->CreateNestedTree();
 
		this->vscroll = this->GetScrollbar(WID_VT_SCROLLBAR);
 

	
 
		/* When using wallclock units, we must ensure the client displays timetables in seconds. */
 
		if (TimerGameEconomy::UsingWallclockUnits()) {
 
			_settings_client.gui.timetable_mode = TimetableMode::Seconds;
 
		}
 

	
 
		this->UpdateSelectionStates();
 
		this->FinishInitNested(window_number);
 

	
 
		this->owner = this->vehicle->owner;
 
	}
 

	
src/vehicle.cpp
Show inline comments
 
@@ -192,16 +192,23 @@ bool Vehicle::NeedsServicing() const
 
	/* Stopped or crashed vehicles will not move, as such making unmovable
 
	 * vehicles to go for service is lame. */
 
	if (this->vehstatus & (VS_STOPPED | VS_CRASHED)) return false;
 

	
 
	/* Are we ready for the next service cycle? */
 
	const Company *c = Company::Get(this->owner);
 
	if (this->ServiceIntervalIsPercent() ?
 
			(this->reliability >= this->GetEngine()->reliability * (100 - this->GetServiceInterval()) / 100) :
 
			(this->date_of_last_service + this->GetServiceInterval() >= TimerGameEconomy::date)) {
 
		return false;
 

	
 
	/* Service intervals can be measured in different units, which we handle individually. */
 
	if (this->ServiceIntervalIsPercent()) {
 
		/* Service interval is in percents. */
 
		if (this->reliability >= this->GetEngine()->reliability * (100 - this->GetServiceInterval()) / 100) return false;
 
	} else if (TimerGameEconomy::UsingWallclockUnits()) {
 
		/* Service interval is in minutes. */
 
		if (this->date_of_last_service + (this->GetServiceInterval() * EconomyTime::DAYS_IN_ECONOMY_MONTH) >= TimerGameEconomy::date) return false;
 
	} else {
 
		/* Service interval is in days. */
 
		if (this->date_of_last_service + this->GetServiceInterval() >= TimerGameEconomy::date) return false;
 
	}
 

	
 
	/* If we're servicing anyway, because we have not disabled servicing when
 
	 * there are no breakdowns or we are playing with breakdowns, bail out. */
 
	if (!_settings_game.order.no_servicing_if_no_breakdowns ||
 
			_settings_game.difficulty.vehicle_breakdowns != 0) {
src/vehicle_gui.cpp
Show inline comments
 
@@ -2296,13 +2296,13 @@ extern void DrawTrainDetails(const Train
 
extern void DrawRoadVehDetails(const Vehicle *v, const Rect &r);
 
extern void DrawShipDetails(const Vehicle *v, const Rect &r);
 
extern void DrawAircraftDetails(const Aircraft *v, const Rect &r);
 

	
 
static StringID _service_interval_dropdown[] = {
 
	STR_VEHICLE_DETAILS_DEFAULT,
 
	STR_VEHICLE_DETAILS_DAYS,
 
	STR_VEHICLE_DETAILS_TIME,
 
	STR_VEHICLE_DETAILS_PERCENT,
 
	INVALID_STRING_ID,
 
};
 

	
 
/** Class for managing the vehicle details window. */
 
struct VehicleDetailsWindow : Window {
 
@@ -2428,13 +2428,23 @@ struct VehicleDetailsWindow : Window {
 
				*size = maxdim(*size, d);
 
				break;
 
			}
 

	
 
			case WID_VD_SERVICING_INTERVAL:
 
				SetDParamMaxValue(0, MAX_SERVINT_DAYS); // Roughly the maximum interval
 
				SetDParamMaxValue(1, TimerGameEconomy::DateAtStartOfYear(EconomyTime::MAX_YEAR)); // Roughly the maximum year
 

	
 
				/* Do we show the last serviced value as a date or minutes since service? */
 
				if (TimerGameEconomy::UsingWallclockUnits()) {
 
					SetDParam(1, STR_VEHICLE_DETAILS_LAST_SERVICE_MINUTES_AGO);
 
					/*/ Vehicle was last serviced at year 0, and we're at max year */
 
					SetDParamMaxValue(2, EconomyTime::MONTHS_IN_YEAR * EconomyTime::MAX_YEAR.base());
 
				} else {
 
					SetDParam(1, STR_VEHICLE_DETAILS_LAST_SERVICE_DATE);
 
					/*/ Vehicle was last serviced at year 0, and we're at max year */
 
					SetDParamMaxValue(2, TimerGameEconomy::DateAtStartOfYear(EconomyTime::MAX_YEAR));
 
				}
 
				size->width = std::max(
 
					GetStringBoundingBox(STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT).width,
 
					GetStringBoundingBox(STR_VEHICLE_DETAILS_SERVICING_INTERVAL_DAYS).width
 
				) + padding.width;
 
				size->height = GetCharacterHeight(FS_NORMAL) + padding.height;
 
				break;
 
@@ -2569,14 +2579,28 @@ struct VehicleDetailsWindow : Window {
 
				break;
 
			}
 

	
 
			case WID_VD_SERVICING_INTERVAL: {
 
				/* Draw service interval text */
 
				Rect tr = r.Shrink(WidgetDimensions::scaled.framerect);
 

	
 
				SetDParam(0, v->GetServiceInterval());
 
				SetDParam(1, v->date_of_last_service);
 

	
 
				/* We're using wallclock units. Show minutes since last serviced. */
 
				if (TimerGameEconomy::UsingWallclockUnits()) {
 
					int minutes_since_serviced = (TimerGameEconomy::date - v->date_of_last_service).base() / EconomyTime::DAYS_IN_ECONOMY_MONTH;
 
					SetDParam(1, STR_VEHICLE_DETAILS_LAST_SERVICE_MINUTES_AGO);
 
					SetDParam(2, minutes_since_serviced);
 
					DrawString(tr.left, tr.right, CenterBounds(r.top, r.bottom, GetCharacterHeight(FS_NORMAL)),
 
						v->ServiceIntervalIsPercent() ? STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT : STR_VEHICLE_DETAILS_SERVICING_INTERVAL_MINUTES);
 
					break;
 
				}
 

	
 
				/* We're using calendar dates. Show the date of last service. */
 
				SetDParam(1, STR_VEHICLE_DETAILS_LAST_SERVICE_DATE);
 
				SetDParam(2, v->date_of_last_service);
 
				DrawString(tr.left, tr.right, CenterBounds(r.top, r.bottom, GetCharacterHeight(FS_NORMAL)),
 
						v->ServiceIntervalIsPercent() ? STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT : STR_VEHICLE_DETAILS_SERVICING_INTERVAL_DAYS);
 
				break;
 
			}
 
		}
 
	}
 
@@ -2594,25 +2618,25 @@ struct VehicleDetailsWindow : Window {
 
		/* Disable service-scroller when interval is set to disabled */
 
		this->SetWidgetsDisabledState(!IsVehicleServiceIntervalEnabled(v->type, v->owner),
 
			WID_VD_INCREASE_SERVICING_INTERVAL,
 
			WID_VD_DECREASE_SERVICING_INTERVAL);
 

	
 
		StringID str = v->ServiceIntervalIsCustom() ?
 
			(v->ServiceIntervalIsPercent() ? STR_VEHICLE_DETAILS_PERCENT : STR_VEHICLE_DETAILS_DAYS) :
 
			(v->ServiceIntervalIsPercent() ? STR_VEHICLE_DETAILS_PERCENT : STR_VEHICLE_DETAILS_TIME) :
 
			STR_VEHICLE_DETAILS_DEFAULT;
 
		this->GetWidget<NWidgetCore>(WID_VD_SERVICE_INTERVAL_DROPDOWN)->widget_data = str;
 

	
 
		this->DrawWidgets();
 
	}
 

	
 
	void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
 
	{
 
		switch (widget) {
 
			case WID_VD_INCREASE_SERVICING_INTERVAL:   // increase int
 
			case WID_VD_DECREASE_SERVICING_INTERVAL: { // decrease int
 
				int mod = _ctrl_pressed ? 5 : 10;
 
				int mod = TimerGameEconomy::UsingWallclockUnits() ? (_ctrl_pressed ? 1 : 5) : (_ctrl_pressed ? 5 : 10);
 
				const Vehicle *v = Vehicle::Get(this->window_number);
 

	
 
				mod = (widget == WID_VD_DECREASE_SERVICING_INTERVAL) ? -mod : mod;
 
				mod = GetServiceIntervalClamped(mod + v->GetServiceInterval(), v->ServiceIntervalIsPercent());
 
				if (mod == v->GetServiceInterval()) return;
 

	
src/widgets/graph_widget.h
Show inline comments
 
@@ -24,21 +24,23 @@ enum GraphLegendWidgets : WidgetID {
 
/** Widgets of the #OperatingProfitGraphWindow class, #IncomeGraphWindow class, #DeliveredCargoGraphWindow class, and #CompanyValueGraphWindow class. */
 
enum CompanyValueWidgets : WidgetID {
 
	WID_CV_KEY_BUTTON, ///< Key button.
 
	WID_CV_BACKGROUND, ///< Background of the window.
 
	WID_CV_GRAPH,      ///< Graph itself.
 
	WID_CV_RESIZE,     ///< Resize button.
 
	WID_CV_FOOTER,     ///< Footer.
 
};
 

	
 
/** Widget of the #PerformanceHistoryGraphWindow class. */
 
enum PerformanceHistoryGraphWidgets : WidgetID {
 
	WID_PHG_KEY,                  ///< Key button.
 
	WID_PHG_DETAILED_PERFORMANCE, ///< Detailed performance.
 
	WID_PHG_BACKGROUND,           ///< Background of the window.
 
	WID_PHG_GRAPH,                ///< Graph itself.
 
	WID_PHG_RESIZE,               ///< Resize button.
 
	WID_PHG_FOOTER,               ///< Footer.
 
};
 

	
 
/** Widget of the #PaymentRatesGraphWindow class. */
 
enum CargoPaymentRatesWidgets : WidgetID {
 
	WID_CPR_BACKGROUND,      ///< Background of the window.
 
	WID_CPR_HEADER,          ///< Header.
0 comments (0 inline, 0 general)