1
0
Fork 0

Compare commits

...

4 Commits

Author SHA1 Message Date
Peter Nelson 806d9d7d33
Merge 6fa7dd17e3 into 7c8759552a 2025-07-28 04:50:33 +00:00
translators 7c8759552a Update: Translations from eints
japanese: 40 changes by akaregi
hungarian: 6 changes by nemesbala
2025-07-28 04:48:20 +00:00
Peter Nelson 6fa7dd17e3
Change: Add support for different horizontal graph scales. 2025-07-20 22:37:58 +01:00
Peter Nelson cd95712dd1
Codechange: Extend industry cargo history to 24 years.
Monthly data is stored for the current 24 months.
Quarterly data is stored for a further 2-6 years.
Yearly data is stored for a further 6-24 years.
2025-07-20 22:37:57 +01:00
12 changed files with 426 additions and 63 deletions

View File

@ -8,6 +8,7 @@
/** @file graph_gui.cpp GUI that shows performance graphs. */ /** @file graph_gui.cpp GUI that shows performance graphs. */
#include "stdafx.h" #include "stdafx.h"
#include <ranges>
#include "misc/history_func.hpp" #include "misc/history_func.hpp"
#include "graph_gui.h" #include "graph_gui.h"
#include "window_gui.h" #include "window_gui.h"
@ -174,6 +175,7 @@ protected:
static const int GRAPH_PAYMENT_RATE_STEPS = 20; ///< Number of steps on Payment rate graph. static const int GRAPH_PAYMENT_RATE_STEPS = 20; ///< Number of steps on Payment rate graph.
static const int PAYMENT_GRAPH_X_STEP_DAYS = 10; ///< X-axis step label for cargo payment rates "Days in transit". static const int PAYMENT_GRAPH_X_STEP_DAYS = 10; ///< X-axis step label for cargo payment rates "Days in transit".
static const int PAYMENT_GRAPH_X_STEP_SECONDS = 20; ///< X-axis step label for cargo payment rates "Seconds in transit". static const int PAYMENT_GRAPH_X_STEP_SECONDS = 20; ///< X-axis step label for cargo payment rates "Seconds in transit".
static const int ECONOMY_YEAR_MINUTES = 12; ///< Minutes per economic year.
static const int ECONOMY_QUARTER_MINUTES = 3; ///< Minutes per economic quarter. static const int ECONOMY_QUARTER_MINUTES = 3; ///< Minutes per economic quarter.
static const int ECONOMY_MONTH_MINUTES = 1; ///< Minutes per economic month. static const int ECONOMY_MONTH_MINUTES = 1; ///< Minutes per economic month.
@ -182,6 +184,25 @@ protected:
static const int MIN_GRAPH_NUM_LINES_Y = 9; ///< Minimal number of horizontal lines to draw. 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. static const int MIN_GRID_PIXEL_SIZE = 20; ///< Minimum distance between graph lines.
struct GraphScale {
StringID label = STR_NULL;
uint8_t month_increment = 0;
int16_t x_values_increment = 0;
const HistoryRange *history_range = nullptr;
};
static inline constexpr GraphScale MONTHLY_SCALE_WALLCLOCK[] = {
{STR_GRAPH_LAST_24_MINUTES_TIME_LABEL, HISTORY_MONTH.total_division, ECONOMY_MONTH_MINUTES, &HISTORY_MONTH},
{STR_GRAPH_LAST_72_MINUTES_TIME_LABEL, HISTORY_QUARTER.total_division, ECONOMY_QUARTER_MINUTES, &HISTORY_QUARTER},
{STR_GRAPH_LAST_288_MINUTES_TIME_LABEL, HISTORY_YEAR.total_division, ECONOMY_YEAR_MINUTES, &HISTORY_YEAR},
};
static inline constexpr GraphScale MONTHLY_SCALE_CALENDAR[] = {
{STR_GRAPH_LAST_24_MONTHS, HISTORY_MONTH.total_division, ECONOMY_MONTH_MINUTES, &HISTORY_MONTH},
{STR_GRAPH_LAST_24_QUARTERS, HISTORY_QUARTER.total_division, ECONOMY_QUARTER_MINUTES, &HISTORY_QUARTER},
{STR_GRAPH_LAST_24_YEARS, HISTORY_YEAR.total_division, ECONOMY_YEAR_MINUTES, &HISTORY_YEAR},
};
uint64_t excluded_data = 0; ///< bitmask of datasets hidden by the player. uint64_t excluded_data = 0; ///< bitmask of datasets hidden by the player.
uint64_t excluded_range = 0; ///< bitmask of ranges hidden by the player. uint64_t excluded_range = 0; ///< bitmask of ranges hidden by the player.
uint64_t masked_range = 0; ///< bitmask of ranges that are not available for the current data. uint64_t masked_range = 0; ///< bitmask of ranges that are not available for the current data.
@ -211,7 +232,9 @@ protected:
}; };
std::vector<DataSet> data{}; std::vector<DataSet> data{};
std::span<const StringID> ranges = {}; std::span<const StringID> ranges{};
std::span<const GraphScale> scales{};
uint8_t selected_scale = 0;
uint8_t highlight_data = UINT8_MAX; ///< Data set that should be highlighted, or UINT8_MAX for none. uint8_t highlight_data = UINT8_MAX; ///< Data set that should be highlighted, or UINT8_MAX for none.
uint8_t highlight_range = UINT8_MAX; ///< Data range that should be highlighted, or UINT8_MAX for none. uint8_t highlight_range = UINT8_MAX; ///< Data range that should be highlighted, or UINT8_MAX for none.
@ -617,12 +640,10 @@ protected:
this->SetDirty(); this->SetDirty();
}}; }};
public: void UpdateMatrixSize(WidgetID widget, Dimension &size, Dimension &resize, auto labels)
void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
{ {
switch (widget) { size = {};
case WID_GRAPH_RANGE_MATRIX: for (const StringID &str : labels) {
for (const StringID &str : this->ranges) {
size = maxdim(size, GetStringBoundingBox(str, FS_SMALL)); size = maxdim(size, GetStringBoundingBox(str, FS_SMALL));
} }
@ -630,11 +651,23 @@ public:
size.height += WidgetDimensions::scaled.framerect.Vertical(); size.height += WidgetDimensions::scaled.framerect.Vertical();
/* Set fixed height for number of ranges. */ /* Set fixed height for number of ranges. */
size.height *= static_cast<uint>(std::size(this->ranges)); size.height *= static_cast<uint>(std::size(labels));
resize.width = 0; resize.width = 0;
resize.height = 0; resize.height = 0;
this->GetWidget<NWidgetCore>(WID_GRAPH_RANGE_MATRIX)->SetMatrixDimension(1, ClampTo<uint32_t>(std::size(this->ranges))); this->GetWidget<NWidgetCore>(widget)->SetMatrixDimension(1, ClampTo<uint32_t>(std::size(labels)));
}
public:
void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
{
switch (widget) {
case WID_GRAPH_RANGE_MATRIX:
this->UpdateMatrixSize(widget, size, resize, this->ranges);
break;
case WID_GRAPH_SCALE_MATRIX:
this->UpdateMatrixSize(widget, size, resize, this->scales | std::views::transform(&GraphScale::label));
break; break;
case WID_GRAPH_GRAPH: { case WID_GRAPH_GRAPH: {
@ -701,6 +734,21 @@ public:
break; break;
} }
case WID_GRAPH_SCALE_MATRIX: {
uint line_height = GetCharacterHeight(FS_SMALL) + WidgetDimensions::scaled.framerect.Vertical();
uint8_t selected_month_increment = this->scales[this->selected_scale].month_increment;
Rect line = r.WithHeight(line_height);
for (const auto &scale : this->scales) {
/* Redraw frame if selected */
if (selected_month_increment == scale.month_increment) DrawFrameRect(line, COLOUR_BROWN, FrameFlag::Lowered);
DrawString(line.Shrink(WidgetDimensions::scaled.framerect), scale.label, TC_BLACK, SA_CENTER, false, FS_SMALL);
line = line.Translate(0, line_height);
}
break;
}
default: break; default: break;
} }
} }
@ -722,6 +770,18 @@ public:
break; break;
} }
case WID_GRAPH_SCALE_MATRIX: {
int row = GetRowFromWidget(pt.y, widget, 0, GetCharacterHeight(FS_SMALL) + WidgetDimensions::scaled.framerect.Vertical());
const auto &scale = this->scales[row];
if (this->selected_scale != row) {
this->selected_scale = row;
this->month_increment = scale.month_increment;
this->x_values_increment = scale.x_values_increment;
this->InvalidateData();
}
break;
}
default: break; default: break;
} }
} }
@ -1646,6 +1706,13 @@ struct IndustryProductionGraphWindow : BaseCargoGraphWindow {
this->InitializeWindow(window_number, STR_GRAPH_LAST_24_MINUTES_TIME_LABEL); this->InitializeWindow(window_number, STR_GRAPH_LAST_24_MINUTES_TIME_LABEL);
} }
void OnInit() override
{
this->BaseCargoGraphWindow::OnInit();
this->scales = TimerGameEconomy::UsingWallclockUnits() ? MONTHLY_SCALE_WALLCLOCK : MONTHLY_SCALE_CALENDAR;
}
CargoTypes GetCargoTypes(WindowNumber window_number) const override CargoTypes GetCargoTypes(WindowNumber window_number) const override
{ {
CargoTypes cargo_types{}; CargoTypes cargo_types{};
@ -1673,7 +1740,7 @@ struct IndustryProductionGraphWindow : BaseCargoGraphWindow {
void UpdateStatistics(bool initialize) override void UpdateStatistics(bool initialize) override
{ {
int mo = TimerGameEconomy::month - this->num_vert_lines; int mo = (TimerGameEconomy::month / this->month_increment - this->num_vert_lines) * this->month_increment;
auto yr = TimerGameEconomy::year; auto yr = TimerGameEconomy::year;
while (mo < 0) { while (mo < 0) {
yr--; yr--;
@ -1711,7 +1778,7 @@ struct IndustryProductionGraphWindow : BaseCargoGraphWindow {
transported.dash = 2; transported.dash = 2;
auto transported_filler = Filler{transported, &Industry::ProducedHistory::transported}; auto transported_filler = Filler{transported, &Industry::ProducedHistory::transported};
FillFromHistory<GRAPH_NUM_MONTHS>(p.history, i->valid_history, produced_filler, transported_filler); FillFromHistory<GRAPH_NUM_MONTHS>(p.history, i->valid_history, *this->scales[this->selected_scale].history_range, produced_filler, transported_filler);
} }
for (const auto &a : i->accepted) { for (const auto &a : i->accepted) {
@ -1735,9 +1802,9 @@ struct IndustryProductionGraphWindow : BaseCargoGraphWindow {
auto waiting_filler = Filler{waiting, &Industry::AcceptedHistory::waiting}; auto waiting_filler = Filler{waiting, &Industry::AcceptedHistory::waiting};
if (a.history == nullptr) { if (a.history == nullptr) {
FillFromEmpty<GRAPH_NUM_MONTHS>(i->valid_history, accepted_filler, waiting_filler); FillFromEmpty<GRAPH_NUM_MONTHS>(i->valid_history, *this->scales[this->selected_scale].history_range, accepted_filler, waiting_filler);
} else { } else {
FillFromHistory<GRAPH_NUM_MONTHS>(*a.history, i->valid_history, accepted_filler, waiting_filler); FillFromHistory<GRAPH_NUM_MONTHS>(*a.history, i->valid_history, *this->scales[this->selected_scale].history_range, accepted_filler, waiting_filler);
} }
} }
@ -1758,7 +1825,7 @@ static constexpr NWidgetPart _nested_industry_production_widgets[] = {
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GRAPH_GRAPH), SetMinimalSize(495, 0), SetFill(1, 1), SetResize(1, 1), NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GRAPH_GRAPH), SetMinimalSize(495, 0), SetFill(1, 1), SetResize(1, 1),
NWidget(NWID_VERTICAL), NWidget(NWID_VERTICAL),
NWidget(NWID_SPACER), SetMinimalSize(0, 24), SetFill(0, 1), NWidget(NWID_SPACER), SetMinimalSize(0, 24), SetFill(0, 1),
NWidget(WWT_MATRIX, COLOUR_BROWN, WID_GRAPH_RANGE_MATRIX), SetFill(1, 0), SetResize(0, 0), SetMatrixDataTip(1, 0, STR_GRAPH_CARGO_PAYMENT_TOGGLE_CARGO), NWidget(WWT_MATRIX, COLOUR_BROWN, WID_GRAPH_RANGE_MATRIX), SetFill(1, 0), SetResize(0, 0), SetMatrixDataTip(1, 0, STR_GRAPH_TOGGLE_RANGE),
NWidget(NWID_SPACER), SetMinimalSize(0, 4), NWidget(NWID_SPACER), SetMinimalSize(0, 4),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_GRAPH_ENABLE_CARGOES), SetStringTip(STR_GRAPH_CARGO_ENABLE_ALL, STR_GRAPH_CARGO_TOOLTIP_ENABLE_ALL), SetFill(1, 0), NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_GRAPH_ENABLE_CARGOES), SetStringTip(STR_GRAPH_CARGO_ENABLE_ALL, STR_GRAPH_CARGO_TOOLTIP_ENABLE_ALL), SetFill(1, 0),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_GRAPH_DISABLE_CARGOES), SetStringTip(STR_GRAPH_CARGO_DISABLE_ALL, STR_GRAPH_CARGO_TOOLTIP_DISABLE_ALL), SetFill(1, 0), NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_GRAPH_DISABLE_CARGOES), SetStringTip(STR_GRAPH_CARGO_DISABLE_ALL, STR_GRAPH_CARGO_TOOLTIP_DISABLE_ALL), SetFill(1, 0),
@ -1767,6 +1834,8 @@ static constexpr NWidgetPart _nested_industry_production_widgets[] = {
NWidget(WWT_MATRIX, COLOUR_BROWN, WID_GRAPH_MATRIX), SetFill(1, 0), SetResize(0, 2), SetMatrixDataTip(1, 0, STR_GRAPH_CARGO_PAYMENT_TOGGLE_CARGO), SetScrollbar(WID_GRAPH_MATRIX_SCROLLBAR), NWidget(WWT_MATRIX, COLOUR_BROWN, WID_GRAPH_MATRIX), SetFill(1, 0), SetResize(0, 2), SetMatrixDataTip(1, 0, STR_GRAPH_CARGO_PAYMENT_TOGGLE_CARGO), SetScrollbar(WID_GRAPH_MATRIX_SCROLLBAR),
NWidget(NWID_VSCROLLBAR, COLOUR_BROWN, WID_GRAPH_MATRIX_SCROLLBAR), NWidget(NWID_VSCROLLBAR, COLOUR_BROWN, WID_GRAPH_MATRIX_SCROLLBAR),
EndContainer(), EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 4),
NWidget(WWT_MATRIX, COLOUR_BROWN, WID_GRAPH_SCALE_MATRIX), SetFill(1, 0), SetResize(0, 0), SetMatrixDataTip(1, 0, STR_GRAPH_SELECT_SCALE),
NWidget(NWID_SPACER), SetMinimalSize(0, 24), SetFill(0, 1), NWidget(NWID_SPACER), SetMinimalSize(0, 24), SetFill(0, 1),
EndContainer(), EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(5, 0), SetFill(0, 1), SetResize(0, 1), NWidget(NWID_SPACER), SetMinimalSize(5, 0), SetFill(0, 1), SetResize(0, 1),

View File

@ -1836,7 +1836,7 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type,
p.history[LAST_MONTH].production += ScaleByCargoScale(p.rate * 8, false); p.history[LAST_MONTH].production += ScaleByCargoScale(p.rate * 8, false);
} }
UpdateValidHistory(i->valid_history); UpdateValidHistory(i->valid_history, HISTORY_YEAR, TimerGameEconomy::month);
} }
if (indspec->callback_mask.Test(IndustryCallbackMask::DecideColour)) { if (indspec->callback_mask.Test(IndustryCallbackMask::DecideColour)) {
@ -2488,19 +2488,38 @@ void GenerateIndustries()
_industry_builder.Reset(); _industry_builder.Reset();
} }
template <>
Industry::ProducedHistory SumHistory(std::span<const Industry::ProducedHistory> history)
{
uint32_t production = std::accumulate(std::begin(history), std::end(history), 0, [](uint32_t r, const auto &p) { return r + p.production; });
uint32_t transported = std::accumulate(std::begin(history), std::end(history), 0, [](uint32_t r, const auto &p) { return r + p.transported; });
auto count = std::size(history);
return {.production = ClampTo<uint16_t>(production / count), .transported = ClampTo<uint16_t>(transported / count)};
}
template <>
Industry::AcceptedHistory SumHistory(std::span<const Industry::AcceptedHistory> history)
{
uint32_t accepted = std::accumulate(std::begin(history), std::end(history), 0, [](uint32_t r, const auto &a) { return r + a.accepted; });
uint32_t waiting = std::accumulate(std::begin(history), std::end(history), 0, [](uint32_t r, const auto &a) { return r + a.waiting; });;
auto count = std::size(history);
return {.accepted = ClampTo<uint16_t>(accepted / count), .waiting = ClampTo<uint16_t>(waiting / count)};
}
/** /**
* Monthly update of industry statistics. * Monthly update of industry statistics.
* @param i Industry to update. * @param i Industry to update.
*/ */
static void UpdateIndustryStatistics(Industry *i) static void UpdateIndustryStatistics(Industry *i)
{ {
UpdateValidHistory(i->valid_history); auto month = TimerGameEconomy::month;
UpdateValidHistory(i->valid_history, HISTORY_YEAR, month);
for (auto &p : i->produced) { for (auto &p : i->produced) {
if (IsValidCargoType(p.cargo)) { if (IsValidCargoType(p.cargo)) {
if (p.history[THIS_MONTH].production != 0) i->last_prod_year = TimerGameEconomy::year; if (p.history[THIS_MONTH].production != 0) i->last_prod_year = TimerGameEconomy::year;
RotateHistory(p.history); RotateHistory(p.history, i->valid_history, HISTORY_YEAR, month);
} }
} }
@ -2509,7 +2528,7 @@ static void UpdateIndustryStatistics(Industry *i)
if (a.history == nullptr) continue; if (a.history == nullptr) continue;
(*a.history)[THIS_MONTH].waiting = GetAndResetAccumulatedAverage<uint16_t>(a.accumulated_waiting); (*a.history)[THIS_MONTH].waiting = GetAndResetAccumulatedAverage<uint16_t>(a.accumulated_waiting);
RotateHistory(*a.history); RotateHistory(*a.history, i->valid_history, HISTORY_YEAR, month);
} }
} }

View File

@ -622,6 +622,14 @@ STR_GRAPH_COMPANY_VALUES_CAPTION :{WHITE}Company
STR_GRAPH_LAST_24_MINUTES_TIME_LABEL :{TINY_FONT}{BLACK}Last 24 minutes STR_GRAPH_LAST_24_MINUTES_TIME_LABEL :{TINY_FONT}{BLACK}Last 24 minutes
STR_GRAPH_LAST_72_MINUTES_TIME_LABEL :{TINY_FONT}{BLACK}Last 72 minutes STR_GRAPH_LAST_72_MINUTES_TIME_LABEL :{TINY_FONT}{BLACK}Last 72 minutes
STR_GRAPH_LAST_288_MINUTES_TIME_LABEL :{TINY_FONT}{BLACK}Last 288 minutes
STR_GRAPH_LAST_24_MONTHS :{TINY_FONT}{BLACK}2 years (monthly)
STR_GRAPH_LAST_24_QUARTERS :{TINY_FONT}{BLACK}6 years (quarterly)
STR_GRAPH_LAST_24_YEARS :{TINY_FONT}{BLACK}24 years (yearly)
STR_GRAPH_TOGGLE_RANGE :Toggle graph for this data range
STR_GRAPH_SELECT_SCALE :Change horizontal scale of graph
STR_GRAPH_CARGO_PAYMENT_RATES_CAPTION :{WHITE}Cargo Payment Rates STR_GRAPH_CARGO_PAYMENT_RATES_CAPTION :{WHITE}Cargo Payment Rates
STR_GRAPH_CARGO_PAYMENT_RATES_DAYS :{TINY_FONT}{BLACK}Days in transit STR_GRAPH_CARGO_PAYMENT_RATES_DAYS :{TINY_FONT}{BLACK}Days in transit

View File

@ -697,8 +697,11 @@ STR_GRAPH_CARGO_TOOLTIP_DISABLE_ALL :{BLACK}Ne mutas
STR_GRAPH_CARGO_PAYMENT_TOGGLE_CARGO :{BLACK}Adott rakomány grafikonjának mutatása be/ki STR_GRAPH_CARGO_PAYMENT_TOGGLE_CARGO :{BLACK}Adott rakomány grafikonjának mutatása be/ki
STR_GRAPH_CARGO_PAYMENT_CARGO :{TINY_FONT}{BLACK}{STRING} STR_GRAPH_CARGO_PAYMENT_CARGO :{TINY_FONT}{BLACK}{STRING}
STR_GRAPH_INDUSTRY_CAPTION :{WHITE}{INDUSTRY} - Rakománytörténet
STR_GRAPH_INDUSTRY_RANGE_PRODUCED :Előállított STR_GRAPH_INDUSTRY_RANGE_PRODUCED :Előállított
STR_GRAPH_INDUSTRY_RANGE_TRANSPORTED :Szállítva STR_GRAPH_INDUSTRY_RANGE_TRANSPORTED :Szállítva
STR_GRAPH_INDUSTRY_RANGE_DELIVERED :Leszállítva
STR_GRAPH_INDUSTRY_RANGE_WAITING :Várakozik
STR_GRAPH_PERFORMANCE_DETAIL_TOOLTIP :{BLACK}Részletes teljesítményértékelés mutatása STR_GRAPH_PERFORMANCE_DETAIL_TOOLTIP :{BLACK}Részletes teljesítményértékelés mutatása
@ -4087,6 +4090,8 @@ STR_INDUSTRY_VIEW_PRODUCTION_LAST_MONTH_TITLE :{BLACK}Múlt ha
STR_INDUSTRY_VIEW_PRODUCTION_LAST_MINUTE_TITLE :{BLACK}Termelés az elmúlt percben: STR_INDUSTRY_VIEW_PRODUCTION_LAST_MINUTE_TITLE :{BLACK}Termelés az elmúlt percben:
STR_INDUSTRY_VIEW_TRANSPORTED :{YELLOW}{CARGO_LONG}{STRING}{BLACK} ({COMMA}% elszállítva) STR_INDUSTRY_VIEW_TRANSPORTED :{YELLOW}{CARGO_LONG}{STRING}{BLACK} ({COMMA}% elszállítva)
STR_INDUSTRY_VIEW_LOCATION_TOOLTIP :{BLACK}A fő nézetet a gazdasági épületre állítja. Ctrl+kattintással új nézet nyílik a gazdasági épület helyzeténél STR_INDUSTRY_VIEW_LOCATION_TOOLTIP :{BLACK}A fő nézetet a gazdasági épületre állítja. Ctrl+kattintással új nézet nyílik a gazdasági épület helyzeténél
STR_INDUSTRY_VIEW_CARGO_GRAPH :{BLACK}Rakomány grafikon
STR_INDUSTRY_VIEW_CARGO_GRAPH_TOOLTIP :{BLACK}Megmutatja az iparág rakománytörténetének grafikonját
STR_INDUSTRY_VIEW_PRODUCTION_LEVEL :{BLACK}Termelési szint: {YELLOW}{COMMA}% STR_INDUSTRY_VIEW_PRODUCTION_LEVEL :{BLACK}Termelési szint: {YELLOW}{COMMA}%
STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE :{YELLOW}A gyár bejelentette a közelgő bezárását! STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE :{YELLOW}A gyár bejelentette a közelgő bezárását!
@ -5062,6 +5067,7 @@ STR_ERROR_FLAT_LAND_REQUIRED :{WHITE}Sima tal
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Rossz irányba lejt a föld STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Rossz irányba lejt a föld
STR_ERROR_CAN_T_DO_THIS :{WHITE}Nem teheted ezt... STR_ERROR_CAN_T_DO_THIS :{WHITE}Nem teheted ezt...
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Előbb le kell rombolnod az épületet STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Előbb le kell rombolnod az épületet
STR_ERROR_BUILDING_IS_PROTECTED :{WHITE}... a(z) épület védett
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Nem tisztíthatod meg ezt a területet... STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Nem tisztíthatod meg ezt a területet...
STR_ERROR_SITE_UNSUITABLE :{WHITE}... nem alkalmas rá a hely STR_ERROR_SITE_UNSUITABLE :{WHITE}... nem alkalmas rá a hely
STR_ERROR_ALREADY_BUILT :{WHITE}... már van itt STR_ERROR_ALREADY_BUILT :{WHITE}... már van itt

View File

@ -437,6 +437,7 @@ STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRFの設定
STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :透過表示設定 STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :透過表示設定
STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :街名を表示 STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :街名を表示
STR_SETTINGS_MENU_STATION_NAMES_DISPLAYED :駅名を表示 STR_SETTINGS_MENU_STATION_NAMES_DISPLAYED :駅名を表示
STR_SETTINGS_MENU_STATION_NAMES_BUS :バス停
STR_SETTINGS_MENU_WAYPOINTS_DISPLAYED :中継駅名を表示 STR_SETTINGS_MENU_WAYPOINTS_DISPLAYED :中継駅名を表示
STR_SETTINGS_MENU_SIGNS_DISPLAYED :標識を表示 STR_SETTINGS_MENU_SIGNS_DISPLAYED :標識を表示
STR_SETTINGS_MENU_SHOW_COMPETITOR_SIGNS :競争者の標識と名前を表示 STR_SETTINGS_MENU_SHOW_COMPETITOR_SIGNS :競争者の標識と名前を表示
@ -522,6 +523,7 @@ STR_ABOUT_MENU_ABOUT_OPENTTD :OpenTTDにつ
STR_ABOUT_MENU_SPRITE_ALIGNER :スプライトを整列 STR_ABOUT_MENU_SPRITE_ALIGNER :スプライトを整列
STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :バウンディングボックスの表示切替 STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :バウンディングボックスの表示切替
STR_ABOUT_MENU_TOGGLE_DIRTY_BLOCKS :ダーティーブロックの色付け切替 STR_ABOUT_MENU_TOGGLE_DIRTY_BLOCKS :ダーティーブロックの色付け切替
STR_ABOUT_MENU_TOGGLE_WIDGET_OUTLINES :ウィジェットの枠線の表示切替
###length 31 ###length 31
STR_DAY_NUMBER_1ST :1 STR_DAY_NUMBER_1ST :1
@ -1203,12 +1205,14 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_CENTER :中央
STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :右 STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :右
STR_CONFIG_SETTING_INFINITE_MONEY :無限の資金: {STRING}
STR_CONFIG_SETTING_INFINITE_MONEY_HELPTEXT :無制限の支出を許容し、会社の破産も無効にします
STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :初期の借入最大額: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :初期の借入最大額: {STRING}
STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :初期の借入限度額を設定します (インフレは考慮されません) STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :初期の借入限度額を設定します (インフレは考慮されません)。「借入金なし」に設定した場合、ゲームスクリプトか「無限の資金」オプションによる提供がない限り、資金は利用できなくなります。
STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_VALUE :{CURRENCY_LONG} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_VALUE :{CURRENCY_LONG}
###setting-zero-is-special ###setting-zero-is-special
STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_DISABLED :借入金なし {RED}ゲームスクリプトで資金を受給する必要があります STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_DISABLED :借入金なし
STR_CONFIG_SETTING_INTEREST_RATE :金利: {STRING} STR_CONFIG_SETTING_INTEREST_RATE :金利: {STRING}
STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :借入利率を設定します (インフレ設定を有効にしたときのインフレ率にも影響します) STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :借入利率を設定します (インフレ設定を有効にしたときのインフレ率にも影響します)
@ -1247,7 +1251,7 @@ STR_CONFIG_SETTING_TRAIN_REVERSING_HELPTEXT :設定を有効
STR_CONFIG_SETTING_DISASTERS :災害: {STRING} STR_CONFIG_SETTING_DISASTERS :災害: {STRING}
STR_CONFIG_SETTING_DISASTERS_HELPTEXT :設定を有効にすると時折、乗り物や交通インフラを遮断・破壊する災害が起きるようになります STR_CONFIG_SETTING_DISASTERS_HELPTEXT :設定を有効にすると時折、乗り物や交通インフラを遮断・破壊する災害が起きるようになります
STR_CONFIG_SETTING_CITY_APPROVAL :議会の姿勢: {STRING} STR_CONFIG_SETTING_CITY_APPROVAL :地方自治体の姿勢: {STRING}
STR_CONFIG_SETTING_CITY_APPROVAL_HELPTEXT :会社が街で引き起こした騒音(主に空港)や環境破壊がどの程度、街での評価や更なる建設行為に影響するかを設定します STR_CONFIG_SETTING_CITY_APPROVAL_HELPTEXT :会社が街で引き起こした騒音(主に空港)や環境破壊がどの程度、街での評価や更なる建設行為に影響するかを設定します
STR_CONFIG_SETTING_MAP_HEIGHT_LIMIT :マップ高さ限界: {STRING} STR_CONFIG_SETTING_MAP_HEIGHT_LIMIT :マップ高さ限界: {STRING}
@ -1351,10 +1355,10 @@ STR_CONFIG_SETTING_AUTOSCROLL_MAIN_VIEWPORT_FULLSCREEN :する (フル
STR_CONFIG_SETTING_AUTOSCROLL_MAIN_VIEWPORT :する STR_CONFIG_SETTING_AUTOSCROLL_MAIN_VIEWPORT :する
STR_CONFIG_SETTING_AUTOSCROLL_EVERY_VIEWPORT :する (ビューポートでも有効) STR_CONFIG_SETTING_AUTOSCROLL_EVERY_VIEWPORT :する (ビューポートでも有効)
STR_CONFIG_SETTING_BRIBE :議会の買収: {STRING} STR_CONFIG_SETTING_BRIBE :地方自治体の贈賄: {STRING}
###length 2 ###length 2
STR_CONFIG_SETTING_BRIBE_HELPTEXT :街で議会買収を企てられるようになります。成功すれば街での評判が良くなりますが、地元当局に事が発覚した場合罰金を受けた上評判が悪くなり、その上その街では半年間何もできなくなります STR_CONFIG_SETTING_BRIBE_HELPTEXT :地方自治体への贈賄を企てられるようにします。もし当局に事が発覚した場合、贈賄を試みた会社は当該自治体では半年間何もできなくなります
STR_CONFIG_SETTING_BRIBE_HELPTEXT_MINUTES :会社が議会買収を企てられるようにします。もし当局に事が発覚した場合、買収した会社は当該自治体では半年間何もできなくなります STR_CONFIG_SETTING_BRIBE_HELPTEXT_MINUTES :地方自治体への贈賄を企てられるようにします。もし当局に事が発覚した場合、贈賄を試みた会社は当該自治体では半年間何もできなくなります
STR_CONFIG_SETTING_ALLOW_EXCLUSIVE :独占運送契約の締結: {STRING} STR_CONFIG_SETTING_ALLOW_EXCLUSIVE :独占運送契約の締結: {STRING}
###length 2 ###length 2
@ -1424,6 +1428,7 @@ STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES_HELPTEXT :有効にする
###setting-zero-is-special ###setting-zero-is-special
STR_CONFIG_SETTING_CARGO_SCALE_VALUE :{NUM}%
STR_CONFIG_SETTING_AUTORENEW_VEHICLE :老朽車両の自動交換: {STRING} STR_CONFIG_SETTING_AUTORENEW_VEHICLE :老朽車両の自動交換: {STRING}
STR_CONFIG_SETTING_AUTORENEW_VEHICLE_HELPTEXT :有効にすると、耐用年数を越えた輸送機器は自動で更新されるようになります(交換には一度格納施設に戻る必要があります)。具体的な交換時期は下の設定で変更できます。 STR_CONFIG_SETTING_AUTORENEW_VEHICLE_HELPTEXT :有効にすると、耐用年数を越えた輸送機器は自動で更新されるようになります(交換には一度格納施設に戻る必要があります)。具体的な交換時期は下の設定で変更できます。
@ -1858,7 +1863,7 @@ STR_CONFIG_SETTING_ALLOW_TOWN_ROADS_HELPTEXT :街の自治体
STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS :街路との平面交差を許可: {STRING} STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS :街路との平面交差を許可: {STRING}
STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS_HELPTEXT :有効にすると、会社が作る道路と街路とが交差できるようになります STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS_HELPTEXT :有効にすると、会社が作る道路と街路とが交差できるようになります
STR_CONFIG_SETTING_NOISE_LEVEL :空港建設に対する街の騒音レベル規制: {STRING} STR_CONFIG_SETTING_NOISE_LEVEL :騒音レベルに基づいた空港建設の制限: {STRING}
STR_CONFIG_SETTING_NOISE_LEVEL_HELPTEXT :この設定を無効にすると、街に作れる空港は最大2つまでになります。有効にした場合は、各空港の騒音レベルの総和が街の騒音許容レベル以下になるようにしか建てられません。騒音レベルは空港の大きさ・街からの距離により、騒音許容レベルは街の人口により左右されます STR_CONFIG_SETTING_NOISE_LEVEL_HELPTEXT :この設定を無効にすると、街に作れる空港は最大2つまでになります。有効にした場合は、各空港の騒音レベルの総和が街の騒音許容レベル以下になるようにしか建てられません。騒音レベルは空港の大きさ・街からの距離により、騒音許容レベルは街の人口により左右されます
STR_CONFIG_SETTING_TOWN_FOUNDING :ゲーム中での街新設: {STRING} STR_CONFIG_SETTING_TOWN_FOUNDING :ゲーム中での街新設: {STRING}
@ -1936,9 +1941,9 @@ STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :初期の都市
STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :ゲーム開始時に都市が普通の街に比べて平均して何倍の人口規模になるかを設定します STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :ゲーム開始時に都市が普通の街に比べて平均して何倍の人口規模になるかを設定します
STR_CONFIG_SETTING_LINKGRAPH_RECALC_INTERVAL :行先分配グラフを{STRING}秒毎に更新 STR_CONFIG_SETTING_LINKGRAPH_RECALC_INTERVAL :行先分配グラフを{STRING}秒毎に更新
STR_CONFIG_SETTING_LINKGRAPH_RECALC_INTERVAL_HELPTEXT :行先分配グラフの更新の間の待ち時間。各更新はグラフの一部だけのルートを再計算します。即ち、この設定を〇〇秒に指定する場合、全グラフが〇〇秒毎に更新されるのではありません。間隔が短ければ短いほどCPU時間を消費します。長ければ長いほど貨物流通の新規ルートの行先分配に時間がかかります。 STR_CONFIG_SETTING_LINKGRAPH_RECALC_INTERVAL_HELPTEXT :行先分配グラフの再計算間隔。各計算タイミングでは一部のグラフのみが再計算されます。よって、ここ設定した X 秒ごとにグラフ全体が更新されるというわけではありません。再計算の間隔が短ければ短いほどCPU時間を消費します。長ければ長いほど貨物流通の新規ルートの行先分配に時間がかかります。
STR_CONFIG_SETTING_LINKGRAPH_RECALC_TIME :行先分配の更新に{STRING}秒を割り当て STR_CONFIG_SETTING_LINKGRAPH_RECALC_TIME :行先分配の更新に{STRING}秒を割り当て
STR_CONFIG_SETTING_LINKGRAPH_RECALC_TIME_HELPTEXT :行先分配グラフの更新に割り当てられる時間。更新が始まると、スレッドが生成されて、指定の時間に実行させられます。短ければ短いほど間に合わない可能性が高まります。その場合、ゲームは停止して計算完了を待ちます。長ければ長いほどルート変更の際に行先分配の更新に時間がかかります。 STR_CONFIG_SETTING_LINKGRAPH_RECALC_TIME_HELPTEXT :行先分配グラフの再計算に割り当てられる時間。再計算が始まると、グラフの処理のために指定した生存秒数だけ実行可能なスレッドが作られます。生存秒数が短ければ短いほど再計算が間に合わない可能性が高まります。その際、ゲームは一時停止して計算完了を待ちます。生存秒数が長ければ長いほど、ルート変更の際に行先分配の更新に時間がかかります。
STR_CONFIG_SETTING_DISTRIBUTION_PAX :旅客の行先分配法: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX :旅客の行先分配法: {STRING}
STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :旅客がどのように行き先別に分配されるかを設定します。「対称」ではAからBへ向かう乗客とほぼ同数が、BからAに向かうようになります。 「非対称」ではそれぞれの方向に向かう旅客数は独立に決められます。「無効」では行き先別分配をしなくなります。 STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :旅客がどのように行き先別に分配されるかを設定します。「対称」ではAからBへ向かう乗客とほぼ同数が、BからAに向かうようになります。 「非対称」ではそれぞれの方向に向かう旅客数は独立に決められます。「無効」では行き先別分配をしなくなります。
@ -1954,7 +1959,7 @@ STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :非対称
STR_CONFIG_SETTING_DISTRIBUTION_SYMMETRIC :対称 STR_CONFIG_SETTING_DISTRIBUTION_SYMMETRIC :対称
STR_CONFIG_SETTING_LINKGRAPH_ACCURACY :分配精度: {STRING} STR_CONFIG_SETTING_LINKGRAPH_ACCURACY :分配精度: {STRING}
STR_CONFIG_SETTING_LINKGRAPH_ACCURACY_HELPTEXT :この値を高くすると、リンクグラフ演算の為CPUへの負荷が大きくなります。演算に時間がかかりすぎると、目に見えてタイムラグが起こる場合があります。しかし低い値に設定すると、分配が不正確になり、望まれる場所に貨物が送られなくなる場合があります STR_CONFIG_SETTING_LINKGRAPH_ACCURACY_HELPTEXT :この設定値を高く設定すればするほど、行先分配グラフの計算に要するCPU時間が長くなります。計算に時間がかかりすぎると遅延が発生する可能性があります。一方、設定値を低く設定すると分配が不正確になり、荷物が意図された場所に送られない場合があります。
STR_CONFIG_SETTING_DEMAND_DISTANCE :距離効果: {STRING} STR_CONFIG_SETTING_DEMAND_DISTANCE :距離効果: {STRING}
STR_CONFIG_SETTING_DEMAND_DISTANCE_HELPTEXT :0より大きい値に設定すると、ある貨物の生産先Aと受取可能先Bとの距離がAからBへ送られる貨物量に影響を及ぼすようになります。高い値を設定すればするほど、遠い施設に送られる貨物量は少なくなり、近場の施設に送られる量が大きくなります STR_CONFIG_SETTING_DEMAND_DISTANCE_HELPTEXT :0より大きい値に設定すると、ある貨物の生産先Aと受取可能先Bとの距離がAからBへ送られる貨物量に影響を及ぼすようになります。高い値を設定すればするほど、遠い施設に送られる貨物量は少なくなり、近場の施設に送られる量が大きくなります
@ -2058,8 +2063,10 @@ STR_CONFIG_ERROR_INVALID_BASE_MUSIC_NOT_FOUND :{WHITE}ファ
# Video initalization errors # Video initalization errors
STR_VIDEO_DRIVER_ERROR :{WHITE}ビデオ設定にエラーがあります... STR_VIDEO_DRIVER_ERROR :{WHITE}ビデオ設定にエラーがあります...
STR_VIDEO_DRIVER_ERROR_NO_HARDWARE_ACCELERATION :{WHITE}... 対応する GPU が見つかりません。ハードウェアアクセラレーションは無効になります。 STR_VIDEO_DRIVER_ERROR_NO_HARDWARE_ACCELERATION :{WHITE}... 対応する GPU が見つかりません。ハードウェアアクセラレーションは無効になります。
STR_VIDEO_DRIVER_ERROR_HARDWARE_ACCELERATION_CRASH :{WHITE}... GPUドライバーがゲームをクラッシュさせました。ハードウェアアクセラレーションは無効になりました
# Intro window # Intro window
STR_INTRO_CAPTION :{WHITE}OpenTTD
STR_INTRO_NEW_GAME :{BLACK}新しいゲーム STR_INTRO_NEW_GAME :{BLACK}新しいゲーム
STR_INTRO_LOAD_GAME :{BLACK}ロード STR_INTRO_LOAD_GAME :{BLACK}ロード
@ -2070,6 +2077,7 @@ STR_INTRO_MULTIPLAYER :{BLACK}マル
STR_INTRO_GAME_OPTIONS :{BLACK}基本設定 STR_INTRO_GAME_OPTIONS :{BLACK}基本設定
STR_INTRO_HIGHSCORE :{BLACK}ハイスコア STR_INTRO_HIGHSCORE :{BLACK}ハイスコア
STR_INTRO_HELP :{BLACK}ヘルプとマニュアル
STR_INTRO_ONLINE_CONTENT :{BLACK}オンラインコンテンツの確認 STR_INTRO_ONLINE_CONTENT :{BLACK}オンラインコンテンツの確認
STR_INTRO_QUIT :{BLACK}終了 STR_INTRO_QUIT :{BLACK}終了
@ -2121,14 +2129,14 @@ STR_HELP_WINDOW_COMMUNITY :{BLACK}コミ
STR_CHEATS :{WHITE}サンドボックスのオプション STR_CHEATS :{WHITE}サンドボックスのオプション
STR_CHEAT_MONEY :{LTBLUE}預金残高を{CURRENCY_LONG}増やす STR_CHEAT_MONEY :{LTBLUE}預金残高を{CURRENCY_LONG}増やす
STR_CHEAT_CHANGE_COMPANY :{LTBLUE}会社: {ORANGE}{COMMA}を乗っ取ってプレイする STR_CHEAT_CHANGE_COMPANY :{LTBLUE}会社: {ORANGE}{COMMA}を乗っ取ってプレイする
STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}魔法のブルドーザー(産業拠点等、何でも撤去できる): {ORANGE}{STRING} STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}魔法のブルドーザー(産業拠点など何でも撤去可能): {ORANGE}{STRING}
STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}トンネルの平面交差を許容: {ORANGE}{STRING} STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}トンネルの平面交差を許容: {ORANGE}{STRING}
STR_CHEAT_NO_JETCRASH :{LTBLUE}ジェット機の小型空港での墜落率を減少: {ORANGE}{STRING} STR_CHEAT_NO_JETCRASH :{LTBLUE}ジェット機の小型空港での墜落率を減少: {ORANGE}{STRING}
STR_CHEAT_EDIT_MAX_HL :{LTBLUE}マップの最高高度を変更: {ORANGE}{NUM} STR_CHEAT_EDIT_MAX_HL :{LTBLUE}マップの最高高度を変更: {ORANGE}{NUM}
STR_CHEAT_EDIT_MAX_HL_QUERY_CAPT :{WHITE}マップの最大高度 STR_CHEAT_EDIT_MAX_HL_QUERY_CAPT :{WHITE}マップの最大高度
STR_CHEAT_CHANGE_DATE :{LTBLUE}日付を変更: {ORANGE}{DATE_SHORT} STR_CHEAT_CHANGE_DATE :{LTBLUE}日付を変更: {ORANGE}{DATE_SHORT}
STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}現在日時を変更 STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}現在日時を変更
STR_CHEAT_SETUP_PROD :{LTBLUE}生産量変更: {ORANGE}{STRING} STR_CHEAT_SETUP_PROD :{LTBLUE}産業の生産量変更を有効化: {ORANGE}{STRING}
# Livery window # Livery window
STR_LIVERY_CAPTION :{WHITE}{COMPANY} - 配色 STR_LIVERY_CAPTION :{WHITE}{COMPANY} - 配色
@ -2457,6 +2465,7 @@ STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH :リンクグラ
STR_NETWORK_MESSAGE_CLIENT_LEAVING :退出 STR_NETWORK_MESSAGE_CLIENT_LEAVING :退出
STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {STRING} が参加してきました STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {STRING} が参加してきました
STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {STRING} がゲームに参加してきました (クライアント #{NUM}) STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {STRING} がゲームに参加してきました (クライアント #{NUM})
STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {0:STRING} が{STRING}の経営に参画してきました
STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} がゲームを観覧し始めました STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} がゲームを観覧し始めました
STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} が新会社 (#{NUM}) を設立しました STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} が新会社 (#{NUM}) を設立しました
STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} が退出しました({STRING}) STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} が退出しました({STRING})
@ -2672,6 +2681,7 @@ STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}道路
STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}建設したい橋の種類をクリックしてください STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}建設したい橋の種類をクリックしてください
STR_SELECT_BRIDGE_INFO_NAME :{GOLD}{STRING} STR_SELECT_BRIDGE_INFO_NAME :{GOLD}{STRING}
STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED :{GOLD}{STRING}{} {VELOCITY} STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED :{GOLD}{STRING}{} {VELOCITY}
STR_SELECT_BRIDGE_INFO_NAME_COST :{GOLD}{STRING}{} {WHITE}{CURRENCY_LONG}
STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED_COST :{GOLD}{STRING}{} {VELOCITY} {WHITE}{CURRENCY_LONG} STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED_COST :{GOLD}{STRING}{} {VELOCITY} {WHITE}{CURRENCY_LONG}
STR_BRIDGE_NAME_SUSPENSION_STEEL :吊橋(S造) STR_BRIDGE_NAME_SUSPENSION_STEEL :吊橋(S造)
STR_BRIDGE_NAME_GIRDER_STEEL :桁橋(S造) STR_BRIDGE_NAME_GIRDER_STEEL :桁橋(S造)
@ -3458,7 +3468,7 @@ STR_LOCAL_AUTHORITY_ACTION_ROAD_RECONSTRUCTION :道路補修に
STR_LOCAL_AUTHORITY_ACTION_STATUE_OF_COMPANY :社長の彫像を建設 STR_LOCAL_AUTHORITY_ACTION_STATUE_OF_COMPANY :社長の彫像を建設
STR_LOCAL_AUTHORITY_ACTION_NEW_BUILDINGS :市街地開発に出資 STR_LOCAL_AUTHORITY_ACTION_NEW_BUILDINGS :市街地開発に出資
STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :独占運送契約を締結 STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :独占運送契約を締結
STR_LOCAL_AUTHORITY_ACTION_BRIBE :議会を買収 STR_LOCAL_AUTHORITY_ACTION_BRIBE :地方自治体への贈賄
###next-name-looks-similar ###next-name-looks-similar
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{PUSH_COLOUR}{YELLOW}旅客と貨物を確保する為に、街で新聞広告を実施します。{}より多くの旅客と貨物が自社の交通網を利用するようになります。{}{POP_COLOUR}費用: {CURRENCY_LONG} STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{PUSH_COLOUR}{YELLOW}旅客と貨物を確保する為に、街で新聞広告を実施します。{}より多くの旅客と貨物が自社の交通網を利用するようになります。{}{POP_COLOUR}費用: {CURRENCY_LONG}
@ -3466,7 +3476,7 @@ STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{PUSH_COLOUR}{Y
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{YELLOW}旅客と貨物を確保する為に、街でTV-CMを開始します{}街の中心部の大範囲にある駅の評価が一時的に高まります。{}{POP_COLOUR}費用: {CURRENCY_LONG} STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{YELLOW}旅客と貨物を確保する為に、街でTV-CMを開始します{}街の中心部の大範囲にある駅の評価が一時的に高まります。{}{POP_COLOUR}費用: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}社を称える彫像を建設します{}この街の駅の評価を恒久的に高めます。{}{POP_COLOUR}費用: {CURRENCY_LONG} STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}社を称える彫像を建設します{}この街の駅の評価を恒久的に高めます。{}{POP_COLOUR}費用: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{PUSH_COLOUR}{YELLOW}市街地の開発に出資します{}街の成長速度が一時的に早まります。{}{POP_COLOUR}費用: {CURRENCY_LONG} STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{PUSH_COLOUR}{YELLOW}市街地の開発に出資します{}街の成長速度が一時的に早まります。{}{POP_COLOUR}費用: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{PUSH_COLOUR}{YELLOW}買収を行い、議会内の評判を高めます。注意: 露見した場合は処罰されます{}{POP_COLOUR}費用: {CURRENCY_LONG} STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{PUSH_COLOUR}{YELLOW}贈賄を通じて地方自治体内の評判を高めます。注意: 露見した場合は処罰されます{}{POP_COLOUR}費用: {CURRENCY_LONG}
# Goal window # Goal window
STR_GOALS_CAPTION :{WHITE}{COMPANY} 目標 STR_GOALS_CAPTION :{WHITE}{COMPANY} 目標
@ -4374,6 +4384,7 @@ STR_ORDER_REFIT_STOP_ORDER :({STRING}に改
STR_ORDER_STOP_ORDER :(運用停止) STR_ORDER_STOP_ORDER :(運用停止)
STR_ORDER_GO_TO_STATION :{STRING} {STATION}
STR_ORDER_GO_TO_STATION_CAN_T_USE_STATION :{PUSH_COLOUR}{RED}(駅を使用できません){POP_COLOUR} {STRING} {STATION} STR_ORDER_GO_TO_STATION_CAN_T_USE_STATION :{PUSH_COLOUR}{RED}(駅を使用できません){POP_COLOUR} {STRING} {STATION}
STR_ORDER_IMPLICIT :(自動) STR_ORDER_IMPLICIT :(自動)
@ -4432,6 +4443,7 @@ STR_TIMETABLE_TOOLTIP :{BLACK}ダイ
STR_TIMETABLE_NO_TRAVEL :運行計画無 STR_TIMETABLE_NO_TRAVEL :運行計画無
STR_TIMETABLE_NOT_TIMETABLEABLE :該当区間を運行 (次の手動指令により自動設定) STR_TIMETABLE_NOT_TIMETABLEABLE :該当区間を運行 (次の手動指令により自動設定)
STR_TIMETABLE_TRAVEL_NOT_TIMETABLED :該当区間を運行 (ダイヤ設定無) STR_TIMETABLE_TRAVEL_NOT_TIMETABLED :該当区間を運行 (ダイヤ設定無)
STR_TIMETABLE_TRAVEL_NOT_TIMETABLED_SPEED :最高速度{VELOCITY}で該当区間を運行 (ダイヤ設定無)
STR_TIMETABLE_TRAVEL_FOR :{STRING}で該当区間を運行 STR_TIMETABLE_TRAVEL_FOR :{STRING}で該当区間を運行
STR_TIMETABLE_TRAVEL_FOR_SPEED :{STRING}で該当区間を運行(最高速度{VELOCITY}) STR_TIMETABLE_TRAVEL_FOR_SPEED :{STRING}で該当区間を運行(最高速度{VELOCITY})
STR_TIMETABLE_TRAVEL_FOR_ESTIMATED :運行({0:STRING}・ダイヤ設定無) STR_TIMETABLE_TRAVEL_FOR_ESTIMATED :運行({0:STRING}・ダイヤ設定無)
@ -4525,14 +4537,14 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}下に
STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}選択したAIの順位を下げる STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}選択したAIの順位を下げる
STR_AI_CONFIG_GAMESCRIPT :{SILVER}ゲームスクリプト STR_AI_CONFIG_GAMESCRIPT :{SILVER}ゲームスクリプト
STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}パラメータ STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}パラメータ
STR_AI_CONFIG_AI :{SILVER}AI STR_AI_CONFIG_AI :{SILVER}AI
STR_AI_CONFIG_CHANGE_AI :{BLACK}AIを選択 STR_AI_CONFIG_CHANGE_AI :{BLACK}AIを選択
STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}ゲームスクリプトを選択 STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}ゲームスクリプトを選択
STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}他のスクリプトをロードします。Ctrl+クリックで全ての利用可能バージョンを表示します STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}他のスクリプトをロードします。Ctrl+クリックで全ての利用可能バージョンを表示します
STR_AI_CONFIG_CONFIGURE :{BLACK}設定 STR_AI_CONFIG_CONFIGURE :{BLACK}設定
STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}スクリプトのパラメータを設定します STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}スクリプトのパラメータを設定します
# Available AIs window # Available AIs window
STR_AI_LIST_CAPTION :{WHITE}使用可能な{STRING} STR_AI_LIST_CAPTION :{WHITE}使用可能な{STRING}
@ -4556,8 +4568,8 @@ STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}ハイ
STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}ミニマップのスクリーンショット STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}ミニマップのスクリーンショット
# Script Parameters # Script Parameters
STR_AI_SETTINGS_CAPTION_AI :AI STR_AI_SETTINGS_CAPTION_AI :{WHITE}AIのパラメーター
STR_AI_SETTINGS_CAPTION_GAMESCRIPT :ゲームスクリプト STR_AI_SETTINGS_CAPTION_GAMESCRIPT :{WHITE}ゲームスクリプトのパラメーター
STR_AI_SETTINGS_RESET :{BLACK}リセット STR_AI_SETTINGS_RESET :{BLACK}リセット
STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING}
@ -4638,6 +4650,7 @@ STR_ERROR_SCREENSHOT_FAILED :{WHITE}スク
# Error message titles # Error message titles
STR_ERROR_MESSAGE_CAPTION :{YELLOW}メッセージ STR_ERROR_MESSAGE_CAPTION :{YELLOW}メッセージ
STR_ERROR_MESSAGE_CAPTION_OTHER_COMPANY :{YELLOW}{COMPANY}からのメッセージ
# Generic construction errors # Generic construction errors
STR_ERROR_OFF_EDGE_OF_MAP :{WHITE}マップからはみ出します STR_ERROR_OFF_EDGE_OF_MAP :{WHITE}マップからはみ出します
@ -4656,12 +4669,13 @@ STR_ERROR_TERRAFORM_LIMIT_REACHED :{WHITE}一度
STR_ERROR_CLEARING_LIMIT_REACHED :{WHITE}一度にできる撤去量を越えています STR_ERROR_CLEARING_LIMIT_REACHED :{WHITE}一度にできる撤去量を越えています
STR_ERROR_TREE_PLANT_LIMIT_REACHED :{WHITE}木の本数が多すぎます STR_ERROR_TREE_PLANT_LIMIT_REACHED :{WHITE}木の本数が多すぎます
STR_ERROR_NAME_MUST_BE_UNIQUE :{WHITE}名前は重複してはいけません STR_ERROR_NAME_MUST_BE_UNIQUE :{WHITE}名前は重複してはいけません
STR_ERROR_GENERIC_OBJECT_IN_THE_WAY :{WHITE}{STRING}があります
STR_ERROR_NOT_ALLOWED_WHILE_PAUSED :{WHITE}ポーズ中にはできない行動です STR_ERROR_NOT_ALLOWED_WHILE_PAUSED :{WHITE}ポーズ中にはできない行動です
# Local authority errors # Local authority errors
STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS :{WHITE}{TOWN}議会が反対しています STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS :{WHITE}{TOWN}の地方自治体が反対しています
STR_ERROR_LOCAL_AUTHORITY_REFUSES_AIRPORT :{WHITE}{TOWN}議会はこれ以上の空港建設を認可しない方針です STR_ERROR_LOCAL_AUTHORITY_REFUSES_AIRPORT :{WHITE}{TOWN}の地方自治体はこれ以上の空港建設を許可しません
STR_ERROR_LOCAL_AUTHORITY_REFUSES_NOISE :{WHITE}{TOWN}の地元民が騒音公害を理由に空港建設に反対しています STR_ERROR_LOCAL_AUTHORITY_REFUSES_NOISE :{WHITE}{TOWN}の地方自治体は騒音公害の懸念から空港建設を許可しません
STR_ERROR_BRIBE_FAILED :{WHITE}あなたの行った贈収賄が地元当局に露見しました! STR_ERROR_BRIBE_FAILED :{WHITE}あなたの行った贈収賄が地元当局に露見しました!
# Levelling errors # Levelling errors
@ -5535,3 +5549,8 @@ STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
STR_BADGE_CONFIG_MENU_TOOLTIP :バッジ設定を開く
STR_BADGE_CONFIG_RESET :リセット
STR_BADGE_CONFIG_ICONS :{WHITE}バッジのアイコン
STR_BADGE_CONFIG_FILTERS :{WHITE}バッジのフィルター
STR_BADGE_CONFIG_NAME :名前

View File

@ -8,6 +8,7 @@ add_files(
getoptdata.cpp getoptdata.cpp
getoptdata.h getoptdata.h
hashtable.hpp hashtable.hpp
history.cpp
history_func.hpp history_func.hpp
history_type.hpp history_type.hpp
lrucache.hpp lrucache.hpp

View File

@ -0,0 +1,65 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* 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/>.
*/
/** @file history.cpp Implementation of functions for storing historical data. */
#include "../stdafx.h"
#include "../core/bitmath_func.hpp"
#include "history_type.hpp"
#include "history_func.hpp"
#include "../safeguards.h"
/**
* Update mask of valid records for a historical data.
* @note Call only for the largest history range sub-division.
* @param[in,out] valid_history Valid history records.
* @param hr History range to update mask for.
* @param cur_month Current economy month.
*/
void UpdateValidHistory(ValidHistoryMask &valid_history, const HistoryRange &hr, uint cur_month)
{
/* Update for subdivisions first. */
if (hr.hr != nullptr) UpdateValidHistory(valid_history, *hr.hr, cur_month);
/* No need to update if our last entry is marked valid. */
if (HasBit(valid_history, hr.last - 1)) return;
/* Is it the right time for this history range? */
if (cur_month % hr.total_division != 0) return;
/* Is the previous history range valid yet? */
if (hr.division != 1 && !HasBit(valid_history, hr.first - hr.division)) return;
SB(valid_history, hr.first, hr.records, GB(valid_history, hr.first, hr.records) << 1ULL | 1ULL);
}
/**
* Test if history data is valid, without extracting data.
* @param valid_history Mask of valid history records.
* @param hr History range to test.
* @param age Age of data to test.
* @return True iff the data for history range and age is valid.
*/
bool IsValidHistory(ValidHistoryMask valid_history, const HistoryRange &hr, uint age)
{
if (hr.hr == nullptr) {
if (age < hr.periods) {
uint slot = hr.first + age;
return HasBit(valid_history, slot);
}
} else {
if (age * hr.division < static_cast<uint>(hr.hr->periods - hr.division)) {
uint start = age * hr.division + ((TimerGameEconomy::month / hr.hr->division) % hr.division);
return IsValidHistory(valid_history, *hr.hr, start);
}
if (age < hr.periods) {
uint slot = hr.first + age - ((hr.hr->periods / hr.division) - 1);
return HasBit(valid_history, slot);
}
}
return false;
}

View File

@ -15,25 +15,44 @@
#include "../timer/timer_game_economy.h" #include "../timer/timer_game_economy.h"
#include "history_type.hpp" #include "history_type.hpp"
/** void UpdateValidHistory(ValidHistoryMask &valid_history, const HistoryRange &hr, uint cur_month);
* Update mask of valid history records. bool IsValidHistory(ValidHistoryMask valid_history, const HistoryRange &hr, uint age);
* @param[in,out] valid_history Valid history records.
*/
inline void UpdateValidHistory(ValidHistoryMask &valid_history)
{
SB(valid_history, LAST_MONTH, HISTORY_RECORDS - LAST_MONTH, GB(valid_history, LAST_MONTH, HISTORY_RECORDS - LAST_MONTH) << 1ULL | 1ULL);
}
/** /**
* Rotate history. * Sum history data elements.
* @note The summation should prevent overflowing, and perform transformations relevant to the type of data.
* @tparam T type of history data element. * @tparam T type of history data element.
* @param history Historical data to rotate. * @param history History elements to sum.
* @return Sum of history elements.
*/ */
template <typename T> template <typename T>
void RotateHistory(HistoryData<T> &history) T SumHistory(typename std::span<const T> history);
/**
* Rotate historical data.
* @note Call only for the largest history range sub-division.
* @tparam T type of history data element.
* @param history Historical data to rotate.
* @param valid_history Mask of valid history records.
* @param hr History range to rotate..
* @param cur_month Current economy month.
*/
template <typename T>
void RotateHistory(HistoryData<T> &history, ValidHistoryMask valid_history, const HistoryRange &hr, uint cur_month)
{ {
std::rotate(std::rbegin(history), std::rbegin(history) + 1, std::rend(history)); if (hr.hr != nullptr) RotateHistory(history, valid_history, *hr.hr, cur_month);
history[THIS_MONTH] = {}; if (cur_month % hr.total_division != 0) return;
std::move_backward(std::next(std::begin(history), hr.first), std::next(std::begin(history), hr.last - 1), std::next(std::begin(history), hr.last));
if (hr.total_division == 1) {
history[hr.first] = history[hr.first - 1];
history.front() = {};
} else if (HasBit(valid_history, hr.first - hr.division)) {
auto first = std::next(std::begin(history), hr.first - hr.division);
auto last = std::next(first, hr.division);
history[hr.first] = SumHistory<T>(std::span{first, last});
}
} }
/** /**
@ -49,19 +68,60 @@ T GetAndResetAccumulatedAverage(Taccrued &total)
return result; return result;
} }
/**
* Get historical data.
* @tparam T type of history data element.
* @param history History data to extract from.
* @param valid_history Mask of valid history records.
* @param hr History range to get.
* @param age Age of data to get.
* @param cur_month Current economy month.
* @param[out] result Extracted historical data.
* @return True iff the data for this history range and age is valid.
*/
template <typename T>
bool GetHistory(const HistoryData<T> &history, ValidHistoryMask valid_history, const HistoryRange &hr, uint age, T &result)
{
if (hr.hr == nullptr) {
if (age < hr.periods) {
uint slot = hr.first + age;
result = history[slot];
return HasBit(valid_history, slot);
}
} else {
if (age * hr.division < static_cast<uint>(hr.hr->periods - hr.division)) {
bool is_valid = false;
std::array<T, HISTORY_MAX_DIVISION> tmp_result; // No need to clear as we fill every element we use.
uint start = age * hr.division + ((TimerGameEconomy::month / hr.hr->division) % hr.division);
for (auto i = start; i != start + hr.division; ++i) {
is_valid |= GetHistory(history, valid_history, *hr.hr, i, tmp_result[i - start]);
}
result = SumHistory<T>(std::span{std::begin(tmp_result), hr.division});
return is_valid;
}
if (age < hr.periods) {
uint slot = hr.first + age - ((hr.hr->periods / hr.division) - 1);
result = history[slot];
return HasBit(valid_history, slot);
}
}
NOT_REACHED();
}
/** /**
* Fill some data with historical data. * Fill some data with historical data.
* @param history Historical data to fill from. * @param history Historical data to fill from.
* @param valid_history Mask of valid history records. * @param valid_history Mask of valid history records.
* @param hr History range to fill with.
* @param fillers Fillers to fill with history data. * @param fillers Fillers to fill with history data.
*/ */
template <uint N, typename T, typename... Tfillers> template <uint N, typename T, typename... Tfillers>
void FillFromHistory(const HistoryData<T> &history, ValidHistoryMask valid_history, Tfillers... fillers) void FillFromHistory(const HistoryData<T> &history, ValidHistoryMask valid_history, const HistoryRange &hr, Tfillers... fillers)
{ {
T result{};
for (uint i = 0; i != N; ++i) { for (uint i = 0; i != N; ++i) {
if (HasBit(valid_history, N - i)) { if (GetHistory(history, valid_history, hr, N - i - 1, result)) {
auto &data = history[N - i]; (fillers.Fill(i, result), ...);
(fillers.Fill(i, data), ...);
} else { } else {
(fillers.MakeInvalid(i), ...); (fillers.MakeInvalid(i), ...);
} }
@ -71,13 +131,14 @@ void FillFromHistory(const HistoryData<T> &history, ValidHistoryMask valid_histo
/** /**
* Fill some data with empty records. * Fill some data with empty records.
* @param valid_history Mask of valid history records. * @param valid_history Mask of valid history records.
* @param hr History range to fill with.
* @param fillers Fillers to fill with history data. * @param fillers Fillers to fill with history data.
*/ */
template <uint N, typename... Tfillers> template <uint N, typename... Tfillers>
void FillFromEmpty(ValidHistoryMask valid_history, Tfillers... fillers) void FillFromEmpty(ValidHistoryMask valid_history, const HistoryRange &hr, Tfillers... fillers)
{ {
for (uint i = 0; i != N; ++i) { for (uint i = 0; i != N; ++i) {
if (HasBit(valid_history, N - i)) { if (IsValidHistory(valid_history, hr, N - i - 1)) {
(fillers.MakeZero(i), ...); (fillers.MakeZero(i), ...);
} else { } else {
(fillers.MakeInvalid(i), ...); (fillers.MakeInvalid(i), ...);

View File

@ -10,7 +10,37 @@
#ifndef HISTORY_TYPE_HPP #ifndef HISTORY_TYPE_HPP
#define HISTORY_TYPE_HPP #define HISTORY_TYPE_HPP
static constexpr uint8_t HISTORY_RECORDS = 25; struct HistoryRange {
const HistoryRange *hr;
const uint8_t periods; ///< Number of periods for this range.
const uint8_t records; ///< Number of records needed for this range.
const uint8_t first; ///< Index of first element in history data.
const uint8_t last; ///< Index of last element in history data.
const uint8_t division; ///< Number of divisions of the previous history range.
const uint8_t total_division; ///< Number of divisions of the initial history range.
explicit constexpr HistoryRange(uint8_t periods) :
hr(nullptr), periods(periods), records(this->periods), first(1), last(this->first + this->records), division(1), total_division(1)
{
}
constexpr HistoryRange(const HistoryRange &hr, uint8_t division, uint8_t periods) :
hr(&hr), periods(periods), records(this->periods - ((hr.periods / division) - 1)), first(hr.last), last(this->first + this->records),
division(division), total_division(division * hr.total_division)
{
}
};
static constexpr uint8_t HISTORY_PERIODS = 24;
static constexpr HistoryRange HISTORY_MONTH{HISTORY_PERIODS};
static constexpr HistoryRange HISTORY_QUARTER{HISTORY_MONTH, 3, HISTORY_PERIODS};
static constexpr HistoryRange HISTORY_YEAR{HISTORY_QUARTER, 4, HISTORY_PERIODS};
/** Maximum number of divisions from previous history range. */
static constexpr uint8_t HISTORY_MAX_DIVISION = std::max({HISTORY_MONTH.division, HISTORY_QUARTER.division, HISTORY_YEAR.division});
/** Total number of records require for all history data. */
static constexpr uint8_t HISTORY_RECORDS = HISTORY_YEAR.last;
static constexpr uint8_t THIS_MONTH = 0; static constexpr uint8_t THIS_MONTH = 0;
static constexpr uint8_t LAST_MONTH = 1; static constexpr uint8_t LAST_MONTH = 1;

View File

@ -3,6 +3,7 @@ add_test_files(
bitmath_func.cpp bitmath_func.cpp
enum_over_optimisation.cpp enum_over_optimisation.cpp
flatset_type.cpp flatset_type.cpp
history_func.cpp
landscape_partial_pixel_z.cpp landscape_partial_pixel_z.cpp
math_func.cpp math_func.cpp
mock_environment.h mock_environment.h

View File

@ -0,0 +1,83 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* 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/>.
*/
/** @file history_func.cpp Test functionality for misc/history_func. */
#include "../stdafx.h"
#include "../3rdparty/catch2/catch.hpp"
#include "../misc/history_type.hpp"
#include "../misc/history_func.hpp"
#include "../safeguards.h"
template <>
uint16_t SumHistory(std::span<const uint16_t> history)
{
uint32_t total = std::accumulate(std::begin(history), std::end(history), 0, [](uint32_t r, const uint16_t &value) { return r + value; });
return ClampTo<uint16_t>(total);
}
/**
* Helper to get history records and return the value, instead returning its validity.
* @param history History data to extract from.
* @param hr History range to get.
* @param age Age of data to get.
* @return Historical value for the period and age.
*/
template <typename T>
T GetHistory(const HistoryData<T> &history, const HistoryRange &hr, uint age)
{
T result;
GetHistory(history, 0, hr, age, result);
return result;
}
TEST_CASE("History Rotation and Reporting tests")
{
HistoryData<uint16_t> history{};
ValidHistoryMask valid_history = 0;
/* Fill the history with decreasing data points for 24 years of history. This ensures that no data period should
* contain the same value as another period. */
uint16_t i = 12 * HISTORY_PERIODS;
for (uint date = 1; date <= 12 * HISTORY_PERIODS; ++date, --i) {
history[THIS_MONTH] = i;
UpdateValidHistory(valid_history, HISTORY_YEAR, date % 12);
RotateHistory(history, valid_history, HISTORY_YEAR, date % 12);
}
/* With the decreasing sequence, the expected value is triangle number (x*x+n)/2 and the square of the total divisions.
* for quarters: 1 + 2 + 3 = 6, 4 + 5 + 6 = 15, 7 + 8 + 9 = 24, 10 + 11 + 12 = 33
* 13 + 14 + 15 = 42, 16 + 17 + 18 = 51, 19 + 20 + 21 = 60, 22 + 23 + 24 = 69...
* for years: 6 + 15 + 24 + 33 = 78, 42 + 51 + 60 + 69 = 222...
*/
for (uint j = 0; j < HISTORY_PERIODS; ++j) {
CHECK(GetHistory(history, HISTORY_MONTH, j) == (( 1 * 1 + 1) / 2) + 1 * 1 * j);
CHECK(GetHistory(history, HISTORY_QUARTER, j) == (( 3 * 3 + 3) / 2) + 3 * 3 * j);
CHECK(GetHistory(history, HISTORY_YEAR, j) == ((12 * 12 + 12) / 2) + 12 * 12 * j);
}
/* Double-check quarter history matches summed month history. */
CHECK(GetHistory(history, HISTORY_MONTH, 0) + GetHistory(history, HISTORY_MONTH, 1) + GetHistory(history, HISTORY_MONTH, 2) == GetHistory(history, HISTORY_QUARTER, 0));
CHECK(GetHistory(history, HISTORY_MONTH, 3) + GetHistory(history, HISTORY_MONTH, 4) + GetHistory(history, HISTORY_MONTH, 5) == GetHistory(history, HISTORY_QUARTER, 1));
CHECK(GetHistory(history, HISTORY_MONTH, 6) + GetHistory(history, HISTORY_MONTH, 7) + GetHistory(history, HISTORY_MONTH, 8) == GetHistory(history, HISTORY_QUARTER, 2));
CHECK(GetHistory(history, HISTORY_MONTH, 9) + GetHistory(history, HISTORY_MONTH, 10) + GetHistory(history, HISTORY_MONTH, 11) == GetHistory(history, HISTORY_QUARTER, 3));
CHECK(GetHistory(history, HISTORY_MONTH, 12) + GetHistory(history, HISTORY_MONTH, 13) + GetHistory(history, HISTORY_MONTH, 14) == GetHistory(history, HISTORY_QUARTER, 4));
CHECK(GetHistory(history, HISTORY_MONTH, 15) + GetHistory(history, HISTORY_MONTH, 16) + GetHistory(history, HISTORY_MONTH, 17) == GetHistory(history, HISTORY_QUARTER, 5));
CHECK(GetHistory(history, HISTORY_MONTH, 18) + GetHistory(history, HISTORY_MONTH, 19) + GetHistory(history, HISTORY_MONTH, 20) == GetHistory(history, HISTORY_QUARTER, 6));
CHECK(GetHistory(history, HISTORY_MONTH, 21) + GetHistory(history, HISTORY_MONTH, 22) + GetHistory(history, HISTORY_MONTH, 23) == GetHistory(history, HISTORY_QUARTER, 7));
/* Double-check year history matches summed quarter history. */
CHECK(GetHistory(history, HISTORY_QUARTER, 0) + GetHistory(history, HISTORY_QUARTER, 1) + GetHistory(history, HISTORY_QUARTER, 2) + GetHistory(history, HISTORY_QUARTER, 3) == GetHistory(history, HISTORY_YEAR, 0));
CHECK(GetHistory(history, HISTORY_QUARTER, 4) + GetHistory(history, HISTORY_QUARTER, 5) + GetHistory(history, HISTORY_QUARTER, 6) + GetHistory(history, HISTORY_QUARTER, 7) == GetHistory(history, HISTORY_YEAR, 1));
CHECK(GetHistory(history, HISTORY_QUARTER, 8) + GetHistory(history, HISTORY_QUARTER, 9) + GetHistory(history, HISTORY_QUARTER, 10) + GetHistory(history, HISTORY_QUARTER, 11) == GetHistory(history, HISTORY_YEAR, 2));
CHECK(GetHistory(history, HISTORY_QUARTER, 12) + GetHistory(history, HISTORY_QUARTER, 13) + GetHistory(history, HISTORY_QUARTER, 14) + GetHistory(history, HISTORY_QUARTER, 15) == GetHistory(history, HISTORY_YEAR, 3));
CHECK(GetHistory(history, HISTORY_QUARTER, 16) + GetHistory(history, HISTORY_QUARTER, 17) + GetHistory(history, HISTORY_QUARTER, 18) + GetHistory(history, HISTORY_QUARTER, 19) == GetHistory(history, HISTORY_YEAR, 4));
CHECK(GetHistory(history, HISTORY_QUARTER, 20) + GetHistory(history, HISTORY_QUARTER, 21) + GetHistory(history, HISTORY_QUARTER, 22) + GetHistory(history, HISTORY_QUARTER, 23) == GetHistory(history, HISTORY_YEAR, 5));
}

View File

@ -37,6 +37,7 @@ enum GraphWidgets : WidgetID {
WID_GRAPH_MATRIX_SCROLLBAR,///< Cargo list scrollbar. WID_GRAPH_MATRIX_SCROLLBAR,///< Cargo list scrollbar.
WID_GRAPH_RANGE_MATRIX, ///< Range list. WID_GRAPH_RANGE_MATRIX, ///< Range list.
WID_GRAPH_SCALE_MATRIX, ///< Horizontal axis scale list.
WID_PHG_DETAILED_PERFORMANCE, ///< Detailed performance. WID_PHG_DETAILED_PERFORMANCE, ///< Detailed performance.
}; };