Split date types into calendar and economy dates

See: 735abfe1
pull/661/head
Jonathan G Rennison 3 months ago
parent fad5ee56e7
commit 7ce06e22b8

@ -357,9 +357,9 @@ CommandCost CmdBuildAircraft(TileIndex tile, DoCommandFlag flags, const Engine *
v->SetServiceInterval(Company::Get(_current_company)->settings.vehicle.servint_aircraft);
v->date_of_last_service = _date;
v->date_of_last_service_newgrf = _date;
v->build_year = u->build_year = _cur_year;
v->date_of_last_service = EconTime::CurDate();
v->date_of_last_service_newgrf = CalTime::CurDate();
v->build_year = u->build_year = CalTime::CurYear();
v->sprite_seq.Set(SPR_IMG_QUERY);
u->sprite_seq.Set(SPR_IMG_QUERY);
@ -1669,8 +1669,8 @@ static void AircraftEventHandler_AtTerminal(Aircraft *v, const AirportFTAClass *
if (_settings_game.order.serviceathelipad) {
if (v->subtype == AIR_HELICOPTER && apc->num_helipads > 0) {
/* an excerpt of ServiceAircraft, without the invisibility stuff */
v->date_of_last_service = _date;
v->date_of_last_service_newgrf = _date;
v->date_of_last_service = EconTime::CurDate();
v->date_of_last_service_newgrf = CalTime::CurDate();
v->breakdowns_since_last_service = 0;
v->reliability = v->GetEngine()->reliability;
SetWindowDirty(WC_VEHICLE_DETAILS, v->index);

@ -74,7 +74,7 @@ struct BaseStation : StationPool::PoolItem<&_station_pool> {
TinyString name; ///< Custom name
StringID string_id; ///< Default name (town area) of station
Date build_date; ///< Date of construction
CalTime::Date build_date; ///< Date of construction
Town *town; ///< The town this station is associated with

@ -62,7 +62,7 @@ enum BridgeSpecCtrlFlags {
* Struct containing information about a single bridge type
*/
struct BridgeSpec {
Year avail_year; ///< the year where it becomes available
CalTime::Year avail_year; ///< the year where it becomes available
byte min_length; ///< the minimum length (not counting start and end tile)
uint16_t max_length; ///< the maximum length (not counting start and end tile)
uint16_t price; ///< the price multiplier

@ -1120,7 +1120,7 @@ void TestedEngineDetails::FillDefaultCapacities(const Engine *e)
int DrawVehiclePurchaseInfo(int left, int right, int y, EngineID engine_number, TestedEngineDetails &te)
{
const Engine *e = Engine::Get(engine_number);
YearMonthDay ymd = ConvertDateToYMD(e->intro_date);
CalTime::YearMonthDay ymd = CalTime::ConvertDateToYMD(e->intro_date);
bool refittable = IsArticulatedVehicleRefittable(engine_number);
bool articulated_cargo = false;
@ -1168,7 +1168,7 @@ int DrawVehiclePurchaseInfo(int left, int right, int y, EngineID engine_number,
if (e->type != VEH_TRAIN || e->u.rail.railveh_type != RAILVEH_WAGON) {
/* Design date - Life length */
SetDParam(0, ymd.year);
SetDParam(1, DateDeltaToYears(e->GetLifeLengthInDays()));
SetDParam(1, DateDeltaToYearDelta(e->GetLifeLengthInDays()));
DrawString(left, right, y, STR_PURCHASE_INFO_DESIGNED_LIFE);
y += GetCharacterHeight(FS_NORMAL);

@ -105,19 +105,25 @@ extern void EnginesMonthlyLoop();
static int32_t ClickChangeDateCheat(int32_t p1, int32_t p2)
{
/* Don't allow changing to an invalid year, or the current year. */
p1 = Clamp(p1, MIN_YEAR, MAX_YEAR);
if (p1 == _cur_year) return _cur_year;
p1 = Clamp(p1, CalTime::MIN_YEAR.base(), CalTime::MAX_YEAR.base());
if (p1 == CalTime::CurYear()) return CalTime::CurYear().base();
YearMonthDay ymd = ConvertDateToYMD(_date);
Date new_date = ConvertYMDToDate(p1, ymd.month, ymd.day);
/* Shift cached dates. */
LinkGraphSchedule::instance.ShiftDates(new_date - _date);
ShiftOrderDates(new_date - _date);
ShiftVehicleDates(new_date - _date);
CalTime::Date new_date = CalTime::ConvertYMDToDate(p1, CalTime::CurMonth(), CalTime::CurDay());
/* Change the date. */
SetDate(new_date, _date_fract);
CalTime::Detail::SetDate(new_date, CalTime::CurDateFract());
{
EconTime::Date new_econ_date = new_date.base();
EconTime::DateFract new_econ_date_fract = CalTime::CurDateFract();
/* Shift cached dates. */
LinkGraphSchedule::instance.ShiftDates(new_econ_date - EconTime::CurDate());
ShiftVehicleDates(new_econ_date - EconTime::CurDate());
EconTime::Detail::SetDate(new_econ_date, new_econ_date_fract);
UpdateOrderUIOnDateChange();
}
EnginesMonthlyLoop();
InvalidateWindowClassesData(WC_BUILD_STATION, 0);
@ -125,7 +131,7 @@ static int32_t ClickChangeDateCheat(int32_t p1, int32_t p2)
InvalidateWindowClassesData(WC_BUILD_OBJECT, 0);
ResetSignalVariant();
MarkWholeScreenDirty();
return _cur_year;
return CalTime::CurYear().base();
}
/**
@ -194,7 +200,7 @@ static const CheatEntry _cheats_ui[] = {
{CNM_ALL, SLE_BOOL, STR_CHEAT_NO_JETCRASH, &_cheats.no_jetcrash.value, &_cheats.no_jetcrash.been_used, nullptr },
{CNM_LOCAL_ONLY, SLE_BOOL, STR_CHEAT_SETUP_PROD, &_cheats.setup_prod.value, &_cheats.setup_prod.been_used, &ClickSetProdCheat },
{CNM_LOCAL_ONLY, SLE_UINT8, STR_CHEAT_EDIT_MAX_HL, &_settings_game.construction.map_height_limit, &_cheats.edit_max_hl.been_used, &ClickChangeMaxHlCheat },
{CNM_LOCAL_ONLY, SLE_INT32, STR_CHEAT_CHANGE_DATE, &_cur_date_ymd.year, &_cheats.change_date.been_used, &ClickChangeDateCheat },
{CNM_LOCAL_ONLY, SLE_INT32, STR_CHEAT_CHANGE_DATE, &CalTime::Detail::now.cal_ymd.year, &_cheats.change_date.been_used, &ClickChangeDateCheat },
{CNM_ALL, SLF_ALLOW_CONTROL, STR_CHEAT_INFLATION_COST, &_economy.inflation_prices, &_cheats.inflation_cost.been_used, nullptr },
{CNM_ALL, SLF_ALLOW_CONTROL, STR_CHEAT_INFLATION_INCOME, &_economy.inflation_payment, &_cheats.inflation_income.been_used, nullptr },
{CNM_ALL, SLE_BOOL, STR_CHEAT_STATION_RATING, &_cheats.station_rating.value, &_cheats.station_rating.been_used, nullptr },
@ -304,7 +310,7 @@ struct CheatWindow : Window {
switch (ce->str) {
/* Display date for change date cheat */
case STR_CHEAT_CHANGE_DATE: SetDParam(0, _date); break;
case STR_CHEAT_CHANGE_DATE: SetDParam(0, CalTime::CurDate()); break;
/* Draw coloured flag for change company cheat */
case STR_CHEAT_CHANGE_COMPANY: {
@ -352,7 +358,7 @@ struct CheatWindow : Window {
switch (ce->str) {
/* Display date for change date cheat */
case STR_CHEAT_CHANGE_DATE:
SetDParam(0, ConvertYMDToDate(MAX_YEAR, 11, 31));
SetDParam(0, CalTime::ConvertYMDToDate(CalTime::MAX_YEAR, 11, 31));
width = std::max(width, GetStringBoundingBox(ce->str).width);
break;

@ -615,8 +615,8 @@ struct CommandLogEntry {
uint32_t p2;
uint32_t cmd;
uint64_t p3;
Date date;
DateFract date_fract;
EconTime::Date date;
EconTime::DateFract date_fract;
uint8_t tick_skip_counter;
CompanyID current_company;
CompanyID local_company;
@ -627,7 +627,7 @@ struct CommandLogEntry {
CommandLogEntry() { }
CommandLogEntry(TileIndex tile, uint32_t p1, uint32_t p2, uint64_t p3, uint32_t cmd, CommandLogEntryFlag log_flags, std::string text)
: text(text), tile(tile), p1(p1), p2(p2), cmd(cmd), p3(p3), date(_date), date_fract(_date_fract), tick_skip_counter(_tick_skip_counter),
: text(text), tile(tile), p1(p1), p2(p2), cmd(cmd), p3(p3), date(EconTime::CurDate()), date_fract(EconTime::CurDateFract()), tick_skip_counter(TickSkipCounter()),
current_company(_current_company), local_company(_local_company), log_flags(log_flags), client_id(_cmd_client_id), frame_counter(_frame_counter) { }
};
@ -669,8 +669,8 @@ static void DumpSubCommandLogEntry(char *&buffer, const char *last, const Comman
return (entry.log_flags & CLEF_SCRIPT_ASYNC) ? 'A' : 'a';
};
YearMonthDay ymd = ConvertDateToYMD(entry.date);
buffer += seprintf(buffer, last, "%4i-%02i-%02i, %2i, %3i", ymd.year, ymd.month + 1, ymd.day, entry.date_fract, entry.tick_skip_counter);
EconTime::YearMonthDay ymd = EconTime::ConvertDateToYMD(entry.date);
buffer += seprintf(buffer, last, "%4i-%02i-%02i, %2i, %3i", ymd.year.base(), ymd.month + 1, ymd.day, entry.date_fract, entry.tick_skip_counter);
if (_networking) {
buffer += seprintf(buffer, last, ", %08X", entry.frame_counter);
}
@ -923,8 +923,9 @@ static void AppendCommandLogEntry(const CommandCost &res, TileIndex tile, uint32
if (_networking && cmd_log.count > 0) {
CommandLogEntry &current = cmd_log.log[(cmd_log.next - 1) % cmd_log.log.size()];
if (current.log_flags & CLEF_ONLY_SENDING && ((current.log_flags ^ log_flags) & ~(CLEF_SCRIPT | CLEF_MY_CMD)) == CLEF_ONLY_SENDING &&
current.tile == tile && current.p1 == p1 && current.p2 == p2 && current.p3 == p3 && ((current.cmd ^ cmd) & ~CMD_NETWORK_COMMAND) == 0 && current.date == _date &&
current.date_fract == _date_fract && current.tick_skip_counter == _tick_skip_counter &&
current.tile == tile && current.p1 == p1 && current.p2 == p2 && current.p3 == p3 && ((current.cmd ^ cmd) & ~CMD_NETWORK_COMMAND) == 0 &&
current.date == EconTime::CurDate() && current.date_fract == EconTime::CurDateFract() &&
current.tick_skip_counter == TickSkipCounter() &&
current.frame_counter == _frame_counter &&
current.current_company == _current_company && current.local_company == _local_company) {
current.log_flags |= log_flags | CLEF_TWICE;

@ -86,7 +86,7 @@ struct CompanyProperties {
std::array<Owner, MAX_COMPANY_SHARE_OWNERS> share_owners; ///< Owners of the shares of the company. #INVALID_OWNER if nobody has bought them yet.
Year inaugurated_year; ///< Year of starting the company.
CalTime::Year inaugurated_year; ///< Year of starting the company.
byte months_of_bankruptcy; ///< Number of months that the company is unable to pay its debts
CompanyID bankrupt_last_asked; ///< Which company was most recently asked about buying it?

@ -596,7 +596,7 @@ Company *DoStartupNewCompany(DoStartupNewCompanyFlag flags, CompanyID company)
c->avail_railtypes = GetCompanyRailTypes(c->index);
c->avail_roadtypes = GetCompanyRoadTypes(c->index);
c->inaugurated_year = _cur_year;
c->inaugurated_year = CalTime::CurYear();
/* If starting a player company in singleplayer and a favorite company manager face is selected, choose it. Otherwise, use a random face.
* In a network game, we'll choose the favorite face later in CmdCompanyCtrl to sync it to all clients. */

@ -420,10 +420,10 @@ struct CompanyFinancesWindow : Window {
case WID_CF_EXPS_PRICE2:
case WID_CF_EXPS_PRICE3: {
const Company *c = Company::Get((CompanyID)this->window_number);
int age = std::min(_cur_year - c->inaugurated_year, 2);
YearDelta age = std::min<YearDelta>(CalTime::CurYear() - c->inaugurated_year, 2);
int wid_offset = widget - WID_CF_EXPS_PRICE1;
if (wid_offset <= age) {
DrawYearColumn(r, _cur_year - (age - wid_offset), c->yearly_expenses[age - wid_offset]);
if (wid_offset <= age.base()) {
DrawYearColumn(r, CalTime::CurYear().base() - (age.base() - wid_offset), c->yearly_expenses[age.base() - wid_offset]);
}
break;
}
@ -1859,7 +1859,7 @@ struct CompanyInfrastructureWindow : Window
}
/* Get the date introduced railtypes as well. */
this->railtypes = AddDateIntroducedRailTypes(this->railtypes, MAX_DATE);
this->railtypes = AddDateIntroducedRailTypes(this->railtypes, CalTime::MAX_DATE);
/* Find the used roadtypes. */
for (const Engine *e : Engine::IterateType(VEH_ROAD)) {
@ -1869,7 +1869,7 @@ struct CompanyInfrastructureWindow : Window
}
/* Get the date introduced roadtypes as well. */
this->roadtypes = AddDateIntroducedRoadTypes(this->roadtypes, MAX_DATE);
this->roadtypes = AddDateIntroducedRoadTypes(this->roadtypes, CalTime::MAX_DATE);
this->roadtypes &= ~_roadtypes_hidden_mask;
}

@ -1596,7 +1596,7 @@ DEF_CONSOLE_CMD(ConGetDate)
return true;
}
IConsolePrintF(CC_DEFAULT, "Date: %04d-%02d-%02d", _cur_date_ymd.year, _cur_date_ymd.month + 1, _cur_date_ymd.day);
IConsolePrintF(CC_DEFAULT, "Date: %04d-%02d-%02d", CalTime::CurYear().base(), CalTime::CurMonth() + 1, CalTime::CurDay());
return true;
}
@ -1912,7 +1912,7 @@ DEF_CONSOLE_CMD(ConCompanies)
IConsolePrintF(CC_INFO, "#:%d(%s) Company Name: '%s' Year Founded: %d Money: " OTTD_PRINTF64 " Loan: " OTTD_PRINTF64 " Value: " OTTD_PRINTF64 " (T:%d, R:%d, P:%d, S:%d) %s",
c->index + 1, GetStringPtr(STR_COLOUR_DARK_BLUE + _company_colours[c->index]), company_name.c_str(),
c->inaugurated_year, (int64_t)c->money, (int64_t)c->current_loan, (int64_t)CalculateCompanyValue(c),
c->inaugurated_year.base(), (int64_t)c->money, (int64_t)c->current_loan, (int64_t)CalculateCompanyValue(c),
c->group_all[VEH_TRAIN].num_vehicle,
c->group_all[VEH_ROAD].num_vehicle,
c->group_all[VEH_AIRCRAFT].num_vehicle,
@ -2489,7 +2489,7 @@ DEF_CONSOLE_CMD(ConMergeLinkgraphJobsAsap)
return true;
}
for (LinkGraphJob *lgj : LinkGraphJob::Iterate()) lgj->ShiftJoinDate((NowDateTicks() - lgj->JoinDateTicks()).base() / DAY_TICKS);
for (LinkGraphJob *lgj : LinkGraphJob::Iterate()) lgj->ShiftJoinDate((EconTime::CurDateTicks() - lgj->JoinDateTicks()).base() / DAY_TICKS);
return true;
}
@ -2562,11 +2562,12 @@ DEF_CONSOLE_CMD(ConRunTileLoopTile)
DEF_CONSOLE_CMD(ConGetFullDate)
{
if (argc == 0) {
IConsoleHelp("Returns the current full date (year-month-day, date fract, tick skip, counter) of the game. Usage: 'getfulldate'");
IConsoleHelp("Returns the current full date (year-month-day, date fract, tick skip counter/subtick) of the game. Usage: 'getfulldate'");
return true;
}
IConsolePrintF(CC_DEFAULT, "Date: %04d-%02d-%02d, %i, %i", _cur_date_ymd.year, _cur_date_ymd.month + 1, _cur_date_ymd.day, _date_fract, _tick_skip_counter);
IConsolePrintF(CC_DEFAULT, "Calendar Date: %04d-%02d-%02d, %i, %i", CalTime::CurYear().base(), CalTime::CurMonth() + 1, CalTime::CurDay(), CalTime::CurDateFract(), CalTime::Detail::now.sub_date_fract);
IConsolePrintF(CC_DEFAULT, "Economy Date: %04d-%02d-%02d, %i, %i", EconTime::CurYear().base(), EconTime::CurMonth() + 1, EconTime::CurDay(), EconTime::CurDateFract(), TickSkipCounter());
return true;
}
@ -2735,12 +2736,12 @@ DEF_CONSOLE_CMD(ConDumpLinkgraphJobs)
IConsolePrintF(CC_DEFAULT, PRINTF_SIZE " link graph jobs", LinkGraphJob::GetNumItems());
for (const LinkGraphJob *lgj : LinkGraphJob::Iterate()) {
YearMonthDay start_ymd = ConvertDateToYMD(lgj->StartDateTicks().ToDate());
YearMonthDay join_ymd = ConvertDateToYMD(lgj->JoinDateTicks().ToDate());
EconTime::YearMonthDay start_ymd = EconTime::ConvertDateToYMD(lgj->StartDateTicks().ToDate());
EconTime::YearMonthDay join_ymd = EconTime::ConvertDateToYMD(lgj->JoinDateTicks().ToDate());
IConsolePrintF(CC_DEFAULT, " Job: %5u, nodes: %u, cost: " OTTD_PRINTF64U ", start: (" OTTD_PRINTF64 ", %4i-%02i-%02i, %i), end: (" OTTD_PRINTF64 ", %4i-%02i-%02i, %i), duration: " OTTD_PRINTF64,
lgj->index, lgj->Graph().Size(), lgj->Graph().CalculateCostEstimate(),
lgj->StartDateTicks().base(), start_ymd.year, start_ymd.month + 1, start_ymd.day, lgj->StartDateTicks().ToDateFractRemainder(),
lgj->JoinDateTicks().base(), join_ymd.year, join_ymd.month + 1, join_ymd.day, lgj->JoinDateTicks().ToDateFractRemainder(),
lgj->StartDateTicks().base(), start_ymd.year.base(), start_ymd.month + 1, start_ymd.day, lgj->StartDateTicks().ToDateFractRemainder(),
lgj->JoinDateTicks().base(), join_ymd.year.base(), join_ymd.month + 1, join_ymd.day, lgj->JoinDateTicks().ToDateFractRemainder(),
(lgj->JoinDateTicks() - lgj->StartDateTicks()).base());
}
return true;
@ -2883,7 +2884,7 @@ DEF_CONSOLE_CMD(ConDumpBridgeTypes)
if (grfid != 0) grfids.insert(grfid);
IConsolePrintF(CC_DEFAULT, " %02u Year: %7u, Min: %3u, Max: %5u, Flags: %02X, Ctrl Flags: %c%c%c%c, Pillars: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X, GRF: %08X, %s",
(uint) bt,
spec->avail_year,
spec->avail_year.base(),
spec->min_length,
spec->max_length,
spec->flags,
@ -3663,17 +3664,17 @@ static bool ConConditionalCommon(byte argc, char *argv[], int value, const char
DEF_CONSOLE_CMD(ConIfYear)
{
return ConConditionalCommon(argc, argv, _cur_date_ymd.year, "the current year (in game)", "if_year");
return ConConditionalCommon(argc, argv, CalTime::CurYear().base(), "the current year (in game)", "if_year");
}
DEF_CONSOLE_CMD(ConIfMonth)
{
return ConConditionalCommon(argc, argv, _cur_date_ymd.month + 1, "the current month (in game)", "if_month");
return ConConditionalCommon(argc, argv, CalTime::CurMonth() + 1, "the current month (in game)", "if_month");
}
DEF_CONSOLE_CMD(ConIfDay)
{
return ConConditionalCommon(argc, argv, _cur_date_ymd.day, "the current day of the month (in game)", "if_day");
return ConConditionalCommon(argc, argv, CalTime::CurDay(), "the current day of the month (in game)", "if_day");
}
DEF_CONSOLE_CMD(ConIfHour)

@ -486,9 +486,9 @@ char *CrashLog::LogRecentNews(char *buffer, const char *last) const
int i = 0;
for (NewsItem *news = _latest_news; i < 32 && news != nullptr; news = news->prev, i++) {
YearMonthDay ymd = ConvertDateToYMD(news->date);
CalTime::YearMonthDay ymd = CalTime::ConvertDateToYMD(news->date);
buffer += seprintf(buffer, last, "(%i-%02i-%02i) StringID: %u, Type: %u, Ref1: %u, %u, Ref2: %u, %u\n",
ymd.year, ymd.month + 1, ymd.day, news->string_id, news->type,
ymd.year.base(), ymd.month + 1, ymd.day, news->string_id, news->type,
news->reftype1, news->ref1, news->reftype2, news->ref2);
}
buffer += seprintf(buffer, last, "\n");
@ -559,7 +559,8 @@ char *CrashLog::FillCrashLog(char *buffer, const char *last)
buffer = this->TryCrashLogFaultSection(buffer, last, "times", [](CrashLog *self, char *buffer, const char *last) -> char * {
buffer += UTCTime::Format(buffer, last, "Crash at: %Y-%m-%d %H:%M:%S (UTC)\n");
buffer += seprintf(buffer, last, "In game date: %i-%02i-%02i (%i, %i) (DL: %u)\n", _cur_date_ymd.year, _cur_date_ymd.month + 1, _cur_date_ymd.day, _date_fract, _tick_skip_counter, DayLengthFactor());
buffer += seprintf(buffer, last, "In game date: %i-%02i-%02i (%i, %i) (DL: %u)\n", EconTime::CurYear().base(), EconTime::CurMonth() + 1, EconTime::CurDay(), EconTime::CurDateFract(), TickSkipCounter(), DayLengthFactor());
buffer += seprintf(buffer, last, "Calendar date: %i-%02i-%02i (%i, %i)\n", CalTime::CurYear().base(), CalTime::CurMonth() + 1, CalTime::CurDay(), CalTime::CurDateFract(), CalTime::Detail::now.sub_date_fract);
LogGameLoadDateTimes(buffer, last);
return buffer;
});
@ -650,6 +651,27 @@ char *CrashLog::FillCrashLog(char *buffer, const char *last)
return buffer;
}
static char *LogDesyncDateHeader(char *buffer, const char *last)
{
extern uint32_t _frame_counter;
buffer += seprintf(buffer, last, "In game date: %i-%02i-%02i (%i, %i) (DL: %u), %08X\n",
EconTime::CurYear().base(), EconTime::CurMonth() + 1, EconTime::CurDay(), EconTime::CurDateFract(), TickSkipCounter(), DayLengthFactor(), _frame_counter);
buffer += seprintf(buffer, last, "Calendar date: %i-%02i-%02i (%i, %i)\n", CalTime::CurYear().base(), CalTime::CurMonth() + 1, CalTime::CurDay(), CalTime::CurDateFract(), CalTime::Detail::now.sub_date_fract);
LogGameLoadDateTimes(buffer, last);
if (_networking && !_network_server) {
extern EconTime::Date _last_sync_date;
extern EconTime::DateFract _last_sync_date_fract;
extern uint8_t _last_sync_tick_skip_counter;
extern uint32_t _last_sync_frame_counter;
EconTime::YearMonthDay ymd = EconTime::ConvertDateToYMD(_last_sync_date);
buffer += seprintf(buffer, last, "Last sync at: %i-%02i-%02i (%i, %i), %08X\n",
ymd.year.base(), ymd.month + 1, ymd.day, _last_sync_date_fract, _last_sync_tick_skip_counter, _last_sync_frame_counter);
}
return buffer;
}
/**
* Fill the crash log buffer with all data of a desync event.
* @param buffer The begin where to write at.
@ -673,22 +695,8 @@ char *CrashLog::FillDesyncCrashLog(char *buffer, const char *last, const DesyncE
if (_network_server && !info.desync_frame_info.empty()) {
buffer += seprintf(buffer, last, "%s\n", info.desync_frame_info.c_str());
}
buffer = LogDesyncDateHeader(buffer, last);
extern uint32_t _frame_counter;
buffer += seprintf(buffer, last, "In game date: %i-%02i-%02i (%i, %i) (DL: %u), %08X\n",
_cur_date_ymd.year, _cur_date_ymd.month + 1, _cur_date_ymd.day, _date_fract, _tick_skip_counter, DayLengthFactor(), _frame_counter);
LogGameLoadDateTimes(buffer, last);
if (!_network_server) {
extern Date _last_sync_date;
extern DateFract _last_sync_date_fract;
extern uint8_t _last_sync_tick_skip_counter;
extern uint32_t _last_sync_frame_counter;
YearMonthDay ymd = ConvertDateToYMD(_last_sync_date);
buffer += seprintf(buffer, last, "Last sync at: %i-%02i-%02i (%i, %i), %08X\n",
ymd.year, ymd.month + 1, ymd.day, _last_sync_date_fract, _last_sync_tick_skip_counter, _last_sync_frame_counter);
}
if (info.client_id >= 0) {
buffer += seprintf(buffer, last, "Client #%d, \"%s\"\n", info.client_id, info.client_name != nullptr ? info.client_name : "");
}
@ -735,21 +743,7 @@ char *CrashLog::FillInconsistencyLog(char *buffer, const char *last, const Incon
buffer += WriteScopeLog(buffer, last);
#endif
extern uint32_t _frame_counter;
buffer += seprintf(buffer, last, "In game date: %i-%02i-%02i (%i, %i) (DL: %u), %08X\n",
_cur_date_ymd.year, _cur_date_ymd.month + 1, _cur_date_ymd.day, _date_fract, _tick_skip_counter, DayLengthFactor(), _frame_counter);
LogGameLoadDateTimes(buffer, last);
if (_networking && !_network_server) {
extern Date _last_sync_date;
extern DateFract _last_sync_date_fract;
extern uint8_t _last_sync_tick_skip_counter;
extern uint32_t _last_sync_frame_counter;
YearMonthDay ymd = ConvertDateToYMD(_last_sync_date);
buffer += seprintf(buffer, last, "Last sync at: %i-%02i-%02i (%i, %i), %08X\n",
ymd.year, ymd.month + 1, ymd.day, _last_sync_date_fract, _last_sync_tick_skip_counter, _last_sync_frame_counter);
}
buffer = LogDesyncDateHeader(buffer, last);
buffer += seprintf(buffer, last, "\n");
buffer = this->LogOpenTTDVersion(buffer, last);

@ -126,10 +126,10 @@ uint64_t GetMaskOfAllowedCurrencies()
uint i;
for (i = 0; i < CURRENCY_END; i++) {
Year to_euro = _currency_specs[i].to_euro;
CalTime::Year to_euro = _currency_specs[i].to_euro;
if (to_euro != CF_NOEURO && to_euro != CF_ISEURO && _cur_year >= to_euro) continue;
if (to_euro == CF_ISEURO && _cur_year < 2000) continue;
if (to_euro != CF_NOEURO && to_euro != CF_ISEURO && CalTime::CurYear() >= to_euro) continue;
if (to_euro == CF_ISEURO && CalTime::CurYear() < 2000) continue;
SetBit(mask, i);
}
SetBit(mask, CURRENCY_CUSTOM); // always allow custom currency
@ -143,7 +143,7 @@ void CheckSwitchToEuro()
{
if (_currency_specs[_settings_game.locale.currency].to_euro != CF_NOEURO &&
_currency_specs[_settings_game.locale.currency].to_euro != CF_ISEURO &&
_cur_year >= _currency_specs[_settings_game.locale.currency].to_euro) {
CalTime::CurYear() >= _currency_specs[_settings_game.locale.currency].to_euro) {
_settings_game.locale.currency = 2; // this is the index of euro above.
AddNewsItem(STR_NEWS_EURO_INTRODUCTION, NT_ECONOMY, NF_NORMAL);
}

@ -73,7 +73,7 @@ enum Currencies {
struct CurrencySpec {
uint16_t rate; ///< The conversion rate compared to the base currency.
std::string separator; ///< The thousands separator for this currency.
Year to_euro; ///< %Year of switching to the Euro. May also be #CF_NOEURO or #CF_ISEURO.
CalTime::Year to_euro; ///< %Year of switching to the Euro. May also be #CF_NOEURO or #CF_ISEURO.
std::string prefix; ///< Prefix to apply when formatting money in this currency.
std::string suffix; ///< Suffix to apply when formatting money in this currency.
std::string code; ///< 3 letter untranslated code to identify the currency.
@ -91,7 +91,7 @@ struct CurrencySpec {
CurrencySpec() = default;
CurrencySpec(uint16_t rate, const char *separator, Year to_euro, const char *prefix, const char *suffix, const char *code, byte symbol_pos, StringID name) :
CurrencySpec(uint16_t rate, const char *separator, CalTime::Year to_euro, const char *prefix, const char *suffix, const char *code, byte symbol_pos, StringID name) :
rate(rate), separator(separator), to_euro(to_euro), prefix(prefix), suffix(suffix), code(code), symbol_pos(symbol_pos), name(name)
{
}

@ -27,16 +27,19 @@
#include "safeguards.h"
YearMonthDay _cur_date_ymd; ///< Current date as YearMonthDay struct
Date _date; ///< Current date in days (day counter)
DateFract _date_fract; ///< Fractional part of the day.
uint64_t _tick_counter; ///< Ever incrementing tick counter for setting off various events
uint8_t _tick_skip_counter; ///< Counter for ticks, when only vehicles are moving and nothing else happens
uint64_t _scaled_tick_counter; ///< Tick counter in daylength-scaled ticks
StateTicks _state_ticks; ///< Current state tick
StateTicksDelta _state_ticks_offset; ///< Offset to add when calculating a StateTicks value from a date/date fract/tick skip counter
uint8_t _effective_day_length; ///< Current effective day length
uint32_t _quit_after_days; ///< Quit after this many days of run time
uint32_t _quit_after_days; ///< Quit after this many days of run time
CalTime::State CalTime::Detail::now;
EconTime::State EconTime::Detail::now;
namespace DateDetail {
StateTicksDelta _state_ticks_offset; ///< Offset to add when calculating a StateTicks value from an economy date, date fract and tick skip counter
uint8_t _tick_skip_counter; ///< Counter for ticks, when only vehicles are moving and nothing else happens
uint8_t _effective_day_length; ///< Current effective day length
};
extern void ClearOutOfDateSignalSpeedRestrictions();
@ -55,7 +58,7 @@ void CheckStateTicksWrap()
return;
}
_state_ticks_offset -= tick_adjust;
DateDetail::_state_ticks_offset -= tick_adjust;
_state_ticks -= tick_adjust;
_game_load_state_ticks -= tick_adjust;
@ -74,31 +77,61 @@ void CheckStateTicksWrap()
* @param date New date
* @param fract The number of ticks that have passed on this date.
*/
void SetDate(Date date, DateFract fract)
void CalTime::Detail::SetDate(CalTime::Date date, CalTime::DateFract fract)
{
assert(fract < DAY_TICKS);
_date = date;
_date_fract = fract;
YearMonthDay ymd = ConvertDateToYMD(date);
_cur_date_ymd = ymd;
RecalculateStateTicksOffset();
CalTime::Detail::now.cal_date = date;
CalTime::Detail::now.cal_date_fract = fract;
CalTime::Detail::now.cal_ymd = CalTime::ConvertDateToYMD(date);
UpdateCachedSnowLine();
}
void EconTime::Detail::SetDate(EconTime::Date date, EconTime::DateFract fract)
{
assert(fract < DAY_TICKS);
EconTime::Detail::now.econ_date = date;
EconTime::Detail::now.econ_date_fract = fract;
EconTime::Detail::now.econ_ymd = EconTime::ConvertDateToYMD(date);
RecalculateStateTicksOffset();
}
CalTime::State CalTime::Detail::NewState(CalTime::Year year)
{
CalTime::State state{};
state.cal_ymd = { year, 0, 1 };
state.cal_date = CalTime::ConvertYMDToDate(year, 0, 1);
return state;
}
EconTime::State EconTime::Detail::NewState(EconTime::Year year)
{
EconTime::State state{};
state.econ_ymd = { year, 0, 1 };
state.econ_date = EconTime::ConvertYMDToDate(year, 0, 1);
return state;
}
StateTicks GetStateTicksFromCurrentDateWithoutOffset()
{
return ((int64_t)(DateToDateTicks(_date, _date_fract).base()) * DayLengthFactor()) + _tick_skip_counter;
return ((int64_t)(EconTime::DateToDateTicks(EconTime::CurDate(), EconTime::CurDateFract()).base()) * DayLengthFactor()) + TickSkipCounter();
}
void RecalculateStateTicksOffset()
{
_state_ticks_offset = _state_ticks - GetStateTicksFromCurrentDateWithoutOffset();
DateDetail::_state_ticks_offset = _state_ticks - GetStateTicksFromCurrentDateWithoutOffset();
}
void UpdateEffectiveDayLengthFactor()
{
_effective_day_length = _settings_game.EffectiveDayLengthFactor();
DateDetail::_effective_day_length = _settings_game.EffectiveDayLengthFactor();
}
CalTime::Date StateTicksToCalendarDate(StateTicks ticks)
{
/* Process the same as calendar time (for now) */
return StateTicksToDate(ticks).base();
}
#define M(a, b) ((a << 5) | b)
@ -145,14 +178,14 @@ static const uint16_t _accum_days_for_month[] = {
* @param date the date to convert from
* @param ymd the year, month and day to write to
*/
YearMonthDay ConvertDateToYMD(Date date)
CalTime::YearMonthDay CalTime::ConvertDateToYMD(CalTime::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 */
Year yr = 400 * (date.base() / (DAYS_IN_YEAR * 400 + 97));
CalTime::Year yr = 400 * (date.base() / (DAYS_IN_YEAR * 400 + 97));
int rem = date.base() % (DAYS_IN_YEAR * 400 + 97);
uint16_t x;
@ -167,7 +200,7 @@ YearMonthDay ConvertDateToYMD(Date date)
rem = (rem % (DAYS_IN_YEAR * 100 + 24));
}
if (!IsLeapYear(yr) && rem >= DAYS_IN_YEAR * 4) {
if (!CalTime::IsLeapYear(yr) && rem >= DAYS_IN_YEAR * 4) {
/* The first 4 year of the century are not always a leap year */
yr += 4;
rem -= DAYS_IN_YEAR * 4;
@ -179,15 +212,15 @@ YearMonthDay ConvertDateToYMD(Date date)
/* The last (max 3) years to account for; the first one
* can be, but is not necessarily a leap year */
while (rem >= (IsLeapYear(yr) ? DAYS_IN_LEAP_YEAR : DAYS_IN_YEAR)) {
rem -= IsLeapYear(yr) ? DAYS_IN_LEAP_YEAR : DAYS_IN_YEAR;
while (rem >= (CalTime::IsLeapYear(yr) ? DAYS_IN_LEAP_YEAR : DAYS_IN_YEAR)) {
rem -= CalTime::IsLeapYear(yr) ? DAYS_IN_LEAP_YEAR : DAYS_IN_YEAR;
yr++;
}
/* Skip the 29th of February in non-leap years */
if (!IsLeapYear(yr) && rem >= ACCUM_MAR - 1) rem++;
if (!CalTime::IsLeapYear(yr) && rem >= ACCUM_MAR - 1) rem++;
YearMonthDay ymd;
CalTime::YearMonthDay ymd;
ymd.year = yr;
x = _month_date_from_year_day[rem];
@ -203,7 +236,7 @@ YearMonthDay ConvertDateToYMD(Date date)
* @param month is a number between 0..11
* @param day is a number between 1..31
*/
Date ConvertYMDToDate(Year year, Month month, Day day)
CalTime::Date CalTime::ConvertYMDToDate(CalTime::Year year, CalTime::Month month, CalTime::Day day)
{
/* Day-offset in a leap year */
int days = _accum_days_for_month[month] + day - 1;
@ -211,7 +244,20 @@ Date ConvertYMDToDate(Year year, Month month, Day day)
/* Account for the missing of the 29th of February in non-leap years */
if (!IsLeapYear(year) && days >= ACCUM_MAR) days--;
return DateAtStartOfYear(year) + days;
return CalTime::DateAtStartOfYear(year) + days;
}
EconTime::YearMonthDay EconTime::ConvertDateToYMD(EconTime::Date date)
{
/* Process the same as calendar time (for now) */
CalTime::YearMonthDay ymd = CalTime::ConvertDateToYMD(date.base());
return { ymd.year.base(), ymd.month, ymd.day };
}
EconTime::Date EconTime::ConvertYMDToDate(EconTime::Year year, EconTime::Month month, EconTime::Day day)
{
/* Process the same as calendar time (for now) */
return CalTime::ConvertYMDToDate(year.base(), month, day).base();
}
/** Functions used by the IncreaseDate function */
@ -220,7 +266,8 @@ extern void EnginesDailyLoop();
extern void DisasterDailyLoop();
extern void IndustryDailyLoop();
extern void CompaniesMonthlyLoop();
extern void CompaniesCalendarMonthlyLoop();
extern void CompaniesEconomyMonthlyLoop();
extern void EnginesMonthlyLoop();
extern void TownsMonthlyLoop();
extern void IndustryMonthlyLoop();
@ -237,83 +284,106 @@ extern void ShowEndGameChart();
/**
* Runs various procedures that have to be done yearly
*/
static void OnNewYear()
static void OnNewCalendarYear()
{
CompaniesYearlyLoop();
VehiclesYearlyLoop();
TownsYearlyLoop();
InvalidateWindowClassesData(WC_BUILD_STATION);
InvalidateWindowClassesData(WC_BUS_STATION);
InvalidateWindowClassesData(WC_TRUCK_STATION);
if (_network_server) NetworkServerYearlyLoop();
if (_network_server) NetworkServerCalendarYearlyLoop();
if (_cur_date_ymd.year == _settings_client.gui.semaphore_build_before) ResetSignalVariant();
if (CalTime::CurYear() == _settings_client.gui.semaphore_build_before) ResetSignalVariant();
/* check if we reached end of the game (end of ending year); 0 = never */
if (_cur_date_ymd.year == _settings_game.game_creation.ending_year + 1 && _settings_game.game_creation.ending_year != 0) {
if (CalTime::CurYear() == _settings_game.game_creation.ending_year + 1 && _settings_game.game_creation.ending_year != 0) {
ShowEndGameChart();
}
/* check if we reached the maximum year, decrement dates by a year */
if (_cur_date_ymd.year == MAX_YEAR + 1) {
int days_this_year;
if (CalTime::CurYear() == CalTime::MAX_YEAR + 1) {
CalTime::Detail::now.cal_ymd.year--;
int days_this_year = CalTime::IsLeapYear(CalTime::Detail::now.cal_ymd.year) ? DAYS_IN_LEAP_YEAR : DAYS_IN_YEAR;
CalTime::Detail::now.cal_date -= days_this_year;
}
_cur_date_ymd.year--;
days_this_year = IsLeapYear(_cur_date_ymd.year) ? DAYS_IN_LEAP_YEAR : DAYS_IN_YEAR;
_date -= days_this_year;
if (_settings_client.gui.auto_euro) CheckSwitchToEuro();
IConsoleCmdExec("exec scripts/on_newyear.scr 0");
}
/**
* Runs various procedures that have to be done yearly
*/
static void OnNewEconomyYear()
{
CompaniesYearlyLoop();
VehiclesYearlyLoop();
TownsYearlyLoop();
if (_network_server) NetworkServerEconomyYearlyLoop();
/* check if we reached the maximum year, decrement dates by a year */
if (EconTime::CurYear() == EconTime::MAX_YEAR + 1) {
EconTime::Detail::now.econ_ymd.year--;
int days_this_year = EconTime::IsLeapYear(EconTime::Detail::now.econ_ymd.year) ? DAYS_IN_LEAP_YEAR : DAYS_IN_YEAR;
EconTime::Detail::now.econ_date -= days_this_year;
LinkGraphSchedule::instance.ShiftDates(-days_this_year);
ShiftOrderDates(-days_this_year);
UpdateOrderUIOnDateChange();
ShiftVehicleDates(-days_this_year);
RecalculateStateTicksOffset();
/* Because the _date wraps here, and text-messages expire by game-days, we have to clean out
* all of them if the date is set back, else those messages will hang for ever */
NetworkInitChatMessage();
}
CheckStateTicksWrap();
if (_settings_client.gui.auto_euro) CheckSwitchToEuro();
IConsoleCmdExec("exec scripts/on_newyear.scr 0");
}
/**
* Runs various procedures that have to be done monthly
*/
static void OnNewMonth()
static void OnNewCalendarMonth()
{
SetWindowClassesDirty(WC_CHEATS);
CompaniesMonthlyLoop();
CompaniesCalendarMonthlyLoop();
EnginesMonthlyLoop();
IConsoleCmdExec("exec scripts/on_newmonth.scr 0");
}
/**
* Runs various procedures that have to be done monthly
*/
static void OnNewEconomyMonth()
{
CompaniesEconomyMonthlyLoop();
TownsMonthlyLoop();
IndustryMonthlyLoop();
SubsidyMonthlyLoop();
StationMonthlyLoop();
if (_network_server) NetworkServerMonthlyLoop();
IConsoleCmdExec("exec scripts/on_newmonth.scr 0");
if (_network_server) NetworkServerEconomyMonthlyLoop();
}
/**
* Runs various procedures that have to be done daily
*/
static void OnNewCalendarDay()
{
if (!_settings_time.time_in_minutes || _settings_client.gui.date_with_time > 0) {
SetWindowWidgetDirty(WC_STATUS_BAR, 0, WID_S_LEFT);
}
/* Refresh after possible snowline change */
SetWindowClassesDirty(WC_TOWN_VIEW);
IConsoleCmdExec("exec scripts/on_newday.scr 0");
}
/**
* Runs various procedures that have to be done daily
*/
static void OnNewDay()
static void OnNewEconomyDay()
{
if (_network_server) NetworkServerDailyLoop();
if (_network_server) NetworkServerEconomyDailyLoop();
DisasterDailyLoop();
IndustryDailyLoop();
StationDailyLoop();
if (!_settings_time.time_in_minutes || _settings_client.gui.date_with_time > 0) {
SetWindowWidgetDirty(WC_STATUS_BAR, 0, WID_S_LEFT);
}
EnginesDailyLoop();
ClearOutOfDateSignalSpeedRestrictions();
/* Refresh after possible snowline change */
SetWindowClassesDirty(WC_TOWN_VIEW);
IConsoleCmdExec("exec scripts/on_newday.scr 0");
if (_quit_after_days > 0) {
if (--_quit_after_days == 0) {
DEBUG(misc, 0, "Quitting as day limit reached");
@ -322,48 +392,84 @@ static void OnNewDay()
}
}
/**
* Increases the tick counter, increases date and possibly calls
* procedures that have to be called daily, monthly or yearly.
*/
void IncreaseDate()
static void IncreaseCalendarDate()
{
/* increase day, and check if a new day is there? */
_tick_counter++;
if (_game_mode == GM_MENU || _game_mode == GM_BOOTSTRAP) return;
_date_fract++;
if (_date_fract < DAY_TICKS) return;
_date_fract = 0;
CalTime::Detail::now.cal_date_fract++;
if (CalTime::Detail::now.cal_date_fract < DAY_TICKS) return;
CalTime::Detail::now.cal_date_fract = 0;
/* increase day counter */
_date++;
CalTime::Detail::now.cal_date++;
YearMonthDay ymd = ConvertDateToYMD(_date);
CalTime::YearMonthDay ymd = CalTime::ConvertDateToYMD(CalTime::Detail::now.cal_date);
/* check if we entered a new month? */
bool new_month = ymd.month != _cur_date_ymd.month;
bool new_month = ymd.month != CalTime::Detail::now.cal_ymd.month;
/* check if we entered a new year? */
bool new_year = ymd.year != _cur_date_ymd.year;
bool new_year = ymd.year != CalTime::Detail::now.cal_ymd.year;
/* update internal variables before calling the daily/monthly/yearly loops */
_cur_date_ymd = ymd;
CalTime::Detail::now.cal_ymd = ymd;
UpdateCachedSnowLine();
/* yes, call various daily loops */
OnNewDay();
OnNewCalendarDay();
/* yes, call various monthly loops */
if (new_month) OnNewMonth();
if (new_month) OnNewCalendarMonth();
/* yes, call various yearly loops */
if (new_year) OnNewYear();
if (new_year) OnNewCalendarYear();
}
static void IncreaseEconomyDate()
{
EconTime::Detail::now.econ_date_fract++;
if (EconTime::Detail::now.econ_date_fract < DAY_TICKS) return;
EconTime::Detail::now.econ_date_fract = 0;
/* increase day counter */
EconTime::Detail::now.econ_date++;
EconTime::YearMonthDay ymd = EconTime::ConvertDateToYMD(EconTime::Detail::now.econ_date);
/* check if we entered a new month? */
bool new_month = ymd.month != EconTime::Detail::now.econ_ymd.month;
/* check if we entered a new year? */
bool new_year = ymd.year != EconTime::Detail::now.econ_ymd.year;
/* update internal variables before calling the daily/monthly/yearly loops */
EconTime::Detail::now.econ_ymd = ymd;
/* yes, call various daily loops */
OnNewEconomyDay();
/* yes, call various monthly loops */
if (new_month) OnNewEconomyMonth();
/* yes, call various yearly loops */
if (new_year) OnNewEconomyYear();
}
/**
* Increases the tick counter, increases date and possibly calls
* procedures that have to be called daily, monthly or yearly.
*/
void IncreaseDate()
{
/* increase day, and check if a new day is there? */
_tick_counter++;
if (_game_mode == GM_MENU || _game_mode == GM_BOOTSTRAP) return;
IncreaseCalendarDate();
IncreaseEconomyDate();
}
const char *debug_date_dumper::HexDate(Date date, DateFract date_fract, uint8_t tick_skip_counter)
const char *debug_date_dumper::HexDate(EconTime::Date date, EconTime::DateFract date_fract, uint8_t tick_skip_counter)
{
seprintf(this->buffer, lastof(this->buffer), "date{%08x; %02x; %02x}", date.base(), date_fract, tick_skip_counter);
return this->buffer;

@ -12,97 +12,63 @@
#include "date_type.h"
#include "settings_type.h"
#include <utility>
extern YearMonthDay _cur_date_ymd;
extern Date _date;
extern DateFract _date_fract;
extern uint64_t _tick_counter;
extern uint8_t _tick_skip_counter;
extern uint64_t _scaled_tick_counter;
extern StateTicks _state_ticks;
extern StateTicksDelta _state_ticks_offset;
extern uint32_t _quit_after_days;
void SetDate(Date date, DateFract fract);
YearMonthDay ConvertDateToYMD(Date date);
Date ConvertYMDToDate(Year year, Month month, Day day);
namespace DateDetail {
extern StateTicksDelta _state_ticks_offset;
extern uint8_t _tick_skip_counter;
extern uint8_t _effective_day_length;
};
StateTicks GetStateTicksFromCurrentDateWithoutOffset();
void RecalculateStateTicksOffset();
inline Date ConvertYMDToDate(const YearMonthDay &ymd)
inline uint8_t TickSkipCounter()
{
return ConvertYMDToDate(ymd.year, ymd.month, ymd.day);
return DateDetail::_tick_skip_counter;
}
#define _cur_year (_cur_date_ymd.year)
inline uint8_t DayLengthFactor()
{
extern uint8_t _effective_day_length;
return _effective_day_length;
return DateDetail::_effective_day_length;
}
void UpdateEffectiveDayLengthFactor();
/**
* Checks whether the given year is a leap year or not.
* @param yr The year to check.
* @return True if \c yr is a leap year, otherwise false.
*/
inline bool IsLeapYear(Year yr)
{
return yr % 4 == 0 && (yr % 100 != 0 || yr % 400 == 0);
}
inline Date StateTicksToDate(StateTicks ticks)
{
return (ticks.base() - _state_ticks_offset.base()) / (DAY_TICKS * DayLengthFactor());
}
inline StateTicks DateToStateTicks(Date date)
inline constexpr YearDelta DateDeltaToYearDelta(DateDelta date)
{
return ((int64_t)date.base() * DAY_TICKS * DayLengthFactor()) + _state_ticks_offset.base();
}
inline DateTicks StateTicksToDateTicks(StateTicks ticks)
{
return (ticks.base() - _state_ticks_offset.base()) / DayLengthFactor();
return date.base() / DAYS_IN_LEAP_YEAR;
}
inline StateTicks DateTicksToStateTicks(DateTicks date_ticks)
inline constexpr DateTicksDelta DateDeltaToDateTicksDelta(DateDelta date, uint16_t fract = 0)
{
return ((int64_t)date_ticks.base() * DayLengthFactor()) + _state_ticks_offset.base();
return ((int64_t)date.base() * DAY_TICKS) + fract;
}
/**
* Calculate the year of a given date.
* @param date The date to consider.
* @return the year.
*/
inline constexpr Year DateToYear(Date date)
inline EconTime::Date StateTicksToDate(StateTicks ticks)
{
return date.base() / DAYS_IN_LEAP_YEAR;
return (ticks.base() - DateDetail::_state_ticks_offset.base()) / (DAY_TICKS * DayLengthFactor());
}
inline constexpr Year DateDeltaToYears(DateDelta date)
{
return date.base() / DAYS_IN_LEAP_YEAR;
}
CalTime::Date StateTicksToCalendarDate(StateTicks ticks);
inline constexpr DateTicks DateToDateTicks(Date date, DateFract fract = 0)
inline StateTicks DateToStateTicks(EconTime::Date date)
{
return ((int64_t)date.base() * DAY_TICKS) + fract;
return ((int64_t)date.base() * DAY_TICKS * DayLengthFactor()) + DateDetail::_state_ticks_offset.base();
}
inline constexpr DateTicksDelta DateDeltaToDateTicksDelta(DateDelta date, DateFract fract = 0)
inline EconTime::DateTicks StateTicksToDateTicks(StateTicks ticks)
{
return ((int64_t)date.base() * DAY_TICKS) + fract;
return (ticks.base() - DateDetail::_state_ticks_offset.base()) / DayLengthFactor();
}
inline DateTicks NowDateTicks()
inline StateTicks DateTicksToStateTicks(EconTime::DateTicks date_ticks)
{
return DateToDateTicks(_date, _date_fract);
return ((int64_t)date_ticks.base() * DayLengthFactor()) + DateDetail::_state_ticks_offset.base();
}
inline Ticks TimetableDisplayUnitSize()
@ -115,9 +81,9 @@ inline Ticks TimetableDisplayUnitSize()
}
struct debug_date_dumper {
const char *HexDate(Date date, DateFract date_fract, uint8_t tick_skip_counter);
const char *HexDate(EconTime::Date date, EconTime::DateFract date_fract, uint8_t tick_skip_counter);
inline const char *HexDate() { return this->HexDate(_date, _date_fract, _tick_skip_counter); }
inline const char *HexDate() { return this->HexDate(EconTime::CurDate(), EconTime::CurDateFract(), TickSkipCounter()); }
private:
char buffer[24];

@ -24,10 +24,10 @@
/** Window to select a date graphically by using dropdowns */
struct SetDateWindow : Window {
SetTickCallback *callback; ///< Callback to call when a date has been selected
YearMonthDay date; ///< The currently selected date
Year min_year; ///< The minimum year in the year dropdown
Year max_year; ///< The maximum year (inclusive) in the year dropdown
SetTickCallback *callback; ///< Callback to call when a date has been selected
EconTime::YearMonthDay date; ///< The currently selected date
EconTime::Year min_year; ///< The minimum year in the year dropdown
EconTime::Year max_year; ///< The maximum year (inclusive) in the year dropdown
/**
* Create the new 'set date' window
@ -39,12 +39,12 @@ struct SetDateWindow : Window {
* @param max_year the maximum year (inclusive) to show in the year dropdown
* @param callback the callback to call once a date has been selected
*/
SetDateWindow(WindowDesc *desc, WindowNumber window_number, Window *parent, Date initial_date, Year min_year, Year max_year,
SetDateWindow(WindowDesc *desc, WindowNumber window_number, Window *parent, EconTime::Date initial_date, EconTime::Year min_year, EconTime::Year max_year,
SetTickCallback *callback, StringID button_text, StringID button_tooltip) :
Window(desc),
callback(callback),
min_year(std::max(MIN_YEAR, min_year)),
max_year(std::min(MAX_YEAR, max_year))
min_year(std::max(EconTime::MIN_YEAR, min_year)),
max_year(std::min(EconTime::MAX_YEAR, max_year))
{
assert(this->min_year <= this->max_year);
this->parent = parent;
@ -56,8 +56,8 @@ struct SetDateWindow : Window {
}
this->FinishInitNested(window_number);
if (initial_date == 0) initial_date = _date;
this->date = ConvertDateToYMD(initial_date);
if (initial_date == 0) initial_date = EconTime::CurDate();
this->date = EconTime::ConvertDateToYMD(initial_date);
this->date.year = Clamp(this->date.year, min_year, max_year);
}
@ -94,11 +94,11 @@ struct SetDateWindow : Window {
break;
case WID_SD_YEAR:
for (Year i = this->min_year; i <= this->max_year; i++) {
for (EconTime::Year i = this->min_year; i <= this->max_year; i++) {
SetDParam(0, i);
list.push_back(std::make_unique<DropDownListStringItem>(STR_JUST_INT, i, false));
list.push_back(std::make_unique<DropDownListStringItem>(STR_JUST_INT, i.base(), false));
}
selected = this->date.year;
selected = this->date.year.base();
break;
}
@ -124,7 +124,7 @@ struct SetDateWindow : Window {
break;
case WID_SD_YEAR:
SetDParamMaxValue(0, this->max_year);
SetDParamMaxValue(0, this->max_year.base());
d = maxdim(d, GetStringBoundingBox(STR_JUST_INT));
break;
}
@ -153,7 +153,7 @@ struct SetDateWindow : Window {
break;
case WID_SD_SET_DATE:
if (this->callback != nullptr) {
this->callback(this, DateToStateTicks(ConvertYMDToDate(this->date.year, this->date.month, this->date.day)));
this->callback(this, DateToStateTicks(EconTime::ConvertYMDToDate(this->date.year, this->date.month, this->date.day)));
}
this->Close();
break;
@ -184,7 +184,7 @@ struct SetMinutesWindow : SetDateWindow
TickMinutes minutes;
/** Constructor. */
SetMinutesWindow(WindowDesc *desc, WindowNumber window_number, Window *parent, StateTicks initial_tick, Year min_year, Year max_year,
SetMinutesWindow(WindowDesc *desc, WindowNumber window_number, Window *parent, StateTicks initial_tick, EconTime::Year min_year, EconTime::Year max_year,
SetTickCallback *callback, StringID button_text, StringID button_tooltip) :
SetDateWindow(desc, window_number, parent, 0, min_year, max_year, callback, button_text, button_tooltip),
minutes(_settings_time.ToTickMinutes(initial_tick))
@ -366,7 +366,7 @@ static WindowDesc _set_minutes_desc(__FILE__, __LINE__,
* @param max_year the maximum year (inclusive) to show in the year dropdown
* @param callback the callback to call once a date has been selected
*/
void ShowSetDateWindow(Window *parent, int window_number, StateTicks initial_tick, Year min_year, Year max_year,
void ShowSetDateWindow(Window *parent, int window_number, StateTicks initial_tick, EconTime::Year min_year, EconTime::Year max_year,
SetTickCallback *callback, StringID button_text, StringID button_tooltip)
{
CloseWindowByClass(WC_SET_DATE);

@ -20,7 +20,7 @@
*/
typedef void SetTickCallback(const Window *w, StateTicks tick);
void ShowSetDateWindow(Window *parent, int window_number, StateTicks initial_tick, Year min_year, Year max_year, SetTickCallback *callback,
void ShowSetDateWindow(Window *parent, int window_number, StateTicks initial_tick, EconTime::Year min_year, EconTime::Year max_year, SetTickCallback *callback,
StringID button_text = STR_NULL, StringID button_tooltip = STR_NULL);
#endif /* DATE_GUI_H */

@ -26,116 +26,310 @@ static const int MONTHS_IN_YEAR = 12; ///< months per year
static const int SECONDS_PER_DAY = 2; ///< approximate seconds per day, not for precise calculations
typedef uint16_t DateFract; ///< The fraction of a date we're in, i.e. the number of ticks since the last date changeover
typedef int32_t Ticks; ///< The type to store ticks in
using Ticks = int32_t; ///< The type to store ticks in
static constexpr Ticks INVALID_TICKS = -1; ///< Representation of an invalid number of ticks
typedef int32_t Year; ///< Type for the year, note: 0 based, i.e. starts at the year 0.
typedef uint8_t Month; ///< Type for the month, note: 0 based, i.e. 0 = January, 11 = December.
typedef uint8_t Day; ///< Type for the day of the month, note: 1 based, first day of a month is 1.
/* The type to store our dates in */
using YearDelta = StrongType::Typedef<int32_t, struct YearDeltaTag, StrongType::Compare, StrongType::IntegerScalable>;
using DateDelta = StrongType::Typedef<int32_t, struct DateDeltaTag, StrongType::Compare, StrongType::IntegerScalable>;
using Date = StrongType::Typedef<int32_t, struct DateTag, StrongType::Compare, StrongType::IntegerDelta<DateDelta>>;
/* Mixin for DateTicks */
struct DateTicksOperations {
template <typename TType, typename TBaseType>
struct mixin {
private:
TBaseType GetBase() const { return static_cast<const TType &>(*this).base(); }
public:
Date ToDate() const { return this->GetBase() / DAY_TICKS; }
DateFract ToDateFractRemainder() const { return this->GetBase() % DAY_TICKS; }
using DateTicksDelta = StrongType::Typedef<int64_t, struct DateTicksDeltaTag, StrongType::Compare, StrongType::IntegerScalable>;
namespace DateDetail {
/* Mixin for DateTicks */
template <typename TDate, typename TDateFract>
struct DateTicksOperations {
template <typename TType, typename TBaseType>
struct mixin {
private:
TBaseType GetBase() const { return static_cast<const TType &>(*this).base(); }
public:
TDate ToDate() const { return this->GetBase() / DAY_TICKS; }
TDateFract ToDateFractRemainder() const { return this->GetBase() % DAY_TICKS; }
};
};
template <typename T>
struct BaseTime {
/* The type to store our dates in */
template <class ST> struct DateDeltaTag;
template <class ST> struct DateTag;
using Date = StrongType::Typedef<int32_t, struct DateTag<T>, StrongType::Compare, StrongType::IntegerDelta<DateDelta>>;
using DateFract = uint16_t; ///< The fraction of a date we're in, i.e. the number of ticks since the last date changeover
/* The type to store dates in when tick-precision is required */
template <class ST> struct DateTicksTag;
using DateTicks = StrongType::Typedef<int64_t, struct DateTicksTag<T>, StrongType::Compare, StrongType::IntegerDelta<DateTicksDelta>, DateTicksOperations<Date, DateFract>>;
static constexpr DateTicks DateToDateTicks(Date date, DateFract fract = 0)
{
return ((int64_t)date.base() * DAY_TICKS) + fract;
}
/* Year type */
template <class ST> struct YearTag;
using Year = StrongType::Typedef<int32_t, struct YearTag<T>, StrongType::Compare, StrongType::IntegerDelta<YearDelta>>;
using Month = uint8_t; ///< Type for the month, note: 0 based, i.e. 0 = January, 11 = December.
using Day = uint8_t; ///< Type for the day of the month, note: 1 based, first day of a month is 1.
/**
* Data structure to convert between Date and triplet (year, month, and day).
* @see ConvertDateToYMD(), ConvertYMDToDate()
*/
struct YearMonthDay {
Year year; ///< Year (0...)
Month month; ///< Month (0..11)
Day day; ///< Day (1..31)
};
struct Detail {
/**
* Calculate the date of the first day of a given year.
* @param year the year to get the first day of.
* @return the date.
*/
static constexpr Date DateAtStartOfCalendarYear(Year year)
{
int32_t year_as_int = year.base();
uint number_of_leap_years = (year == 0) ? 0 : ((year_as_int - 1) / 4 - (year_as_int - 1) / 100 + (year_as_int - 1) / 400 + 1);
/* Hardcode the number of days in a year because we can't access CalendarTime from here. */
return (365 * year_as_int) + number_of_leap_years;
}
};
/**
* Checks whether the given year is a leap year or not.
* @param year The year to check.
* @return True if \c year is a leap year, otherwise false.
*/
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);
}
/*
* ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR and DAYS_TILL_ORIGINAL_BASE_YEAR are
* primarily used for loading newgrf and savegame data and returning some
* newgrf (callback) functions that were in the original (TTD) inherited
* format, where '_date == 0' meant that it was 1920-01-01.
*/
/** The minimum starting year/base year of the original TTD */
static constexpr Year ORIGINAL_BASE_YEAR = 1920;
/** The original ending year */
static constexpr Year ORIGINAL_END_YEAR = 2051;
/** The maximum year of the original TTD */
static constexpr Year ORIGINAL_MAX_YEAR = 2090;
/**
* The offset in days from the '_date == 0' till
* 'ConvertYMDToDate(ORIGINAL_BASE_YEAR, 0, 1)'
*/
static constexpr Date DAYS_TILL_ORIGINAL_BASE_YEAR = Detail::DateAtStartOfCalendarYear(ORIGINAL_BASE_YEAR);
static constexpr Date MIN_DATE = 0;
/** The absolute minimum & maximum years in OTTD */
static constexpr Year MIN_YEAR = 0;
/** The default starting year */
static constexpr Year DEF_START_YEAR = 1950;
/** The default scoring end year */
static constexpr Year DEF_END_YEAR = ORIGINAL_END_YEAR - 1;
/**
* MAX_YEAR, nicely rounded value of the number of years that can
* be encoded in a single 32 bits date, about 2^31 / 366 years.
*/
static constexpr Year MAX_YEAR = 5000000;
/** The number of days till the last day */
static constexpr Date MAX_DATE = Detail::DateAtStartOfCalendarYear(MAX_YEAR + 1) - 1;
static constexpr Year INVALID_YEAR = -1; ///< Representation of an invalid year
static constexpr Date INVALID_DATE = -1; ///< Representation of an invalid date
static constexpr DateTicks INVALID_DATE_TICKS = -1; ///< Representation of an invalid date ticks
};
};
/* The type to store dates in when tick-precision is required */
using DateTicksDelta = StrongType::Typedef<int64_t, struct DateTicksDeltaTag, StrongType::Compare, StrongType::IntegerScalable>;
using DateTicks = StrongType::Typedef<int64_t, struct DateTicksTag, StrongType::Compare, StrongType::IntegerDelta<DateTicksDelta>, DateTicksOperations>;
struct CalTime : public DateDetail::BaseTime<struct CalendarTimeTag> {
using ParentBaseTime = DateDetail::BaseTime<struct CalendarTimeTag>;
/* Mixin for StateTicksDelta */
struct StateTicksDeltaOperations {
template <typename TType, typename TBaseType>
struct mixin {
private:
TBaseType GetBase() const { return static_cast<const TType &>(*this).base(); }
/* Use a state struct to make backup/restore/init simpler */
struct State {
YearMonthDay cal_ymd;
Date cal_date;
DateFract cal_date_fract;
uint16_t sub_date_fract; ///< Subpart of date_fract that we use when calendar days are slower than economy days.
};
/* Use a detail struct/namespace to more easily control writes */
struct Detail {
static State now;
static void SetDate(Date date, DateFract fract);
static State NewState(Year year);
};
static inline const YearMonthDay &CurYMD() { return Detail::now.cal_ymd; }
static inline Year CurYear() { return Detail::now.cal_ymd.year; }
static inline Month CurMonth() { return Detail::now.cal_ymd.month; }
static inline Day CurDay() { return Detail::now.cal_ymd.day; }
static inline Date CurDate() { return Detail::now.cal_date; }
static inline DateFract CurDateFract() { return Detail::now.cal_date_fract; }
static YearMonthDay ConvertDateToYMD(Date date);
static Date ConvertYMDToDate(Year year, Month month, Day day);
static inline Date ConvertYMDToDate(const YearMonthDay &ymd)
{
return ConvertYMDToDate(ymd.year, ymd.month, ymd.day);
}
/**
* Calculate the year of a given date.
* @param date The date to consider.
* @return the year.
*/
static constexpr Year DateToYear(Date date)
{
return date.base() / DAYS_IN_LEAP_YEAR;
}
/**
* Calculate the date of the first day of a given year.
* @param year the year to get the first day of.
* @return the date.
*/
static constexpr Date DateAtStartOfYear(Year year)
{
return ParentBaseTime::Detail::DateAtStartOfCalendarYear(year);
}
};
struct EconTime : public DateDetail::BaseTime<struct EconTimeTag> {
/* Use a state struct to make backup/restore/init simpler */
struct State {
YearMonthDay econ_ymd;
Date econ_date;
DateFract econ_date_fract;
};
/* Use a detail struct/namespace to more easily control writes */
struct Detail {
static State now;
static void SetDate(Date date, DateFract fract);
static State NewState(Year year);
};
static inline const YearMonthDay &CurYMD() { return Detail::now.econ_ymd; }
static inline Year CurYear() { return Detail::now.econ_ymd.year; }
static inline Month CurMonth() { return Detail::now.econ_ymd.month; }
static inline Day CurDay() { return Detail::now.econ_ymd.day; }
static inline Date CurDate() { return Detail::now.econ_date; }
static inline DateFract CurDateFract() { return Detail::now.econ_date_fract; }
static inline DateTicks CurDateTicks() { return DateToDateTicks(CurDate(), CurDateFract()); }
static YearMonthDay ConvertDateToYMD(Date date);
static Date ConvertYMDToDate(Year year, Month month, Day day);
static inline Date ConvertYMDToDate(const YearMonthDay &ymd)
{
return ConvertYMDToDate(ymd.year, ymd.month, ymd.day);
}
};
namespace DateDetail {
/* Mixin for StateTicksDelta */
struct StateTicksDeltaOperations {
template <typename TType, typename TBaseType>
struct mixin {
private:
TBaseType GetBase() const { return static_cast<const TType &>(*this).base(); }
public:
template<typename T>
T AsTicksT() const { return ClampTo<T>(this->GetBase()); }
public:
template<typename T>
T AsTicksT() const { return ClampTo<T>(this->GetBase()); }
Ticks AsTicks() const { return this->AsTicksT<Ticks>(); }
Ticks AsTicks() const { return this->AsTicksT<Ticks>(); }
};
};
};
/* The type to store state ticks (this always ticks at the same rate regardless of day length, even in the scenario editor */
using StateTicksDelta = StrongType::Typedef<int64_t, struct StateTicksDeltaTag, StrongType::Compare, StrongType::IntegerScalable, StateTicksDeltaOperations>;
using StateTicksDelta = StrongType::Typedef<int64_t, struct StateTicksDeltaTag, StrongType::Compare, StrongType::IntegerScalable, DateDetail::StateTicksDeltaOperations>;
using StateTicks = StrongType::Typedef<int64_t, struct StateTicksTag, StrongType::Compare, StrongType::IntegerDelta<StateTicksDelta>>;
/* Mixin for TickMinutes, ClockFaceMinutes */
template <bool TNegativeCheck>
struct MinuteOperations {
template <typename TType, typename TBaseType>
struct mixin {
private:
TBaseType GetBase() const
{
TBaseType value = static_cast<const TType &>(*this).base();
if constexpr (TNegativeCheck) {
if (value < 0) {
value = (value % 1440) + 1440;
namespace DateDetail {
/* Mixin for TickMinutes, ClockFaceMinutes */
template <bool TNegativeCheck>
struct MinuteOperations {
template <typename TType, typename TBaseType>
struct mixin {
private:
TBaseType GetBase() const
{
TBaseType value = static_cast<const TType &>(*this).base();
if constexpr (TNegativeCheck) {
if (value < 0) {
value = (value % 1440) + 1440;
}
}
return value;
}
return value;
}
public:
int ClockMinute() const { return this->GetBase() % 60; }
int ClockHour() const { return (this->GetBase() / 60) % 24; }
int ClockHHMM() const { return (this->ClockHour() * 100) + this->ClockMinute(); }
public:
int ClockMinute() const { return this->GetBase() % 60; }
int ClockHour() const { return (this->GetBase() / 60) % 24; }
int ClockHHMM() const { return (this->ClockHour() * 100) + this->ClockMinute(); }
};
};
};
/* Mixin for ClockFaceMinutes */
struct ClockFaceMinuteOperations {
template <typename TType, typename TBaseType>
struct mixin {
static constexpr TType FromClockFace(int hours, int minutes)
{
return (TBaseType(hours) * 60) + minutes;
}
/* Mixin for ClockFaceMinutes */
struct ClockFaceMinuteOperations {
template <typename TType, typename TBaseType>
struct mixin {
static constexpr TType FromClockFace(int hours, int minutes)
{
return (TBaseType(hours) * 60) + minutes;
}
};
};
};
/* The type to store general clock-face minutes in (i.e. 0..1440) */
using ClockFaceMinutes = StrongType::Typedef<int, struct ClockFaceMinutesTag, StrongType::Compare, StrongType::Integer, MinuteOperations<false>, ClockFaceMinuteOperations>;
/* Mixin for TickMinutes */
struct TickMinuteOperations {
template <typename TType, typename TBaseType>
struct mixin {
private:
TBaseType GetBase() const { return static_cast<const TType &>(*this).base(); }
public:
TType ToSameDayClockTime(int hour, int minute) const
{
TBaseType day = DivTowardsNegativeInf<TBaseType>(this->GetBase(), 1440);
return (day * 1440) + (hour * 60) + minute;
}
using ClockFaceMinutes = StrongType::Typedef<int, struct ClockFaceMinutesTag, StrongType::Compare, StrongType::Integer, DateDetail::MinuteOperations<false>, DateDetail::ClockFaceMinuteOperations>;
namespace DateDetail {
/* Mixin for TickMinutes */
struct TickMinuteOperations {
template <typename TType, typename TBaseType>
struct mixin {
private:
TBaseType GetBase() const { return static_cast<const TType &>(*this).base(); }
public:
TType ToSameDayClockTime(int hour, int minute) const
{
TBaseType day = DivTowardsNegativeInf<TBaseType>(this->GetBase(), 1440);
return (day * 1440) + (hour * 60) + minute;
}
ClockFaceMinutes ToClockFaceMinutes() const
{
TBaseType minutes = this->GetBase() % 1440;
if (minutes < 0) minutes += 1440;
return minutes;
}
ClockFaceMinutes ToClockFaceMinutes() const
{
TBaseType minutes = this->GetBase() % 1440;
if (minutes < 0) minutes += 1440;
return minutes;
}
};
};
};
/* The type to store StateTicks-based minutes in */
using TickMinutes = StrongType::Typedef<int64_t, struct TickMinutesTag, StrongType::Compare, StrongType::Integer, MinuteOperations<true>, TickMinuteOperations>;
using TickMinutes = StrongType::Typedef<int64_t, struct TickMinutesTag, StrongType::Compare, StrongType::Integer, DateDetail::MinuteOperations<true>, DateDetail::TickMinuteOperations>;
static const int STATION_RATING_TICKS = 185; ///< cycle duration for updating station rating
static const int STATION_ACCEPTANCE_TICKS = 250; ///< cycle duration for updating station acceptance
@ -145,75 +339,7 @@ static const int INDUSTRY_PRODUCE_TICKS = 256; ///< cycle duration for industr
static const int TOWN_GROWTH_TICKS = 70; ///< cycle duration for towns trying to grow. (this originates from the size of the town array in TTD
static const int INDUSTRY_CUT_TREE_TICKS = INDUSTRY_PRODUCE_TICKS * 2; ///< cycle duration for lumber mill's extra action
/*
* ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR and DAYS_TILL_ORIGINAL_BASE_YEAR are
* primarily used for loading newgrf and savegame data and returning some
* newgrf (callback) functions that were in the original (TTD) inherited
* format, where '_date == 0' meant that it was 1920-01-01.
*/
/** The minimum starting year/base year of the original TTD */
static constexpr Year ORIGINAL_BASE_YEAR = 1920;
/** The original ending year */
static constexpr Year ORIGINAL_END_YEAR = 2051;
/** The maximum year of the original TTD */
static constexpr Year ORIGINAL_MAX_YEAR = 2090;
/**
* Calculate the date of the first day of a given year.
* @param year the year to get the first day of.
* @return the date.
*/
static constexpr Date DateAtStartOfYear(Year year)
{
int32_t year_as_int = year;
uint number_of_leap_years = (year == 0) ? 0 : ((year_as_int - 1) / 4 - (year_as_int - 1) / 100 + (year_as_int - 1) / 400 + 1);
/* Hardcode the number of days in a year because we can't access CalendarTime from here. */
return (365 * year_as_int) + number_of_leap_years;
}
/**
* The offset in days from the '_date == 0' till
* 'ConvertYMDToDate(ORIGINAL_BASE_YEAR, 0, 1)'
*/
static constexpr Date DAYS_TILL_ORIGINAL_BASE_YEAR = DateAtStartOfYear(ORIGINAL_BASE_YEAR);
static constexpr Date MIN_DATE = 0;
/** The absolute minimum & maximum years in OTTD */
static constexpr Year MIN_YEAR = 0;
/** The default starting year */
static constexpr Year DEF_START_YEAR = 1950;
/** The default scoring end year */
static constexpr Year DEF_END_YEAR = ORIGINAL_END_YEAR - 1;
/**
* MAX_YEAR, nicely rounded value of the number of years that can
* be encoded in a single 32 bits date, about 2^31 / 366 years.
*/
static const Year MAX_YEAR = 5000000;
/** The number of days till the last day */
static constexpr Date MAX_DATE = DateAtStartOfYear(MAX_YEAR + 1) - 1;
/** An initial value for StateTicks when starting a new game */
static constexpr StateTicks INITIAL_STATE_TICKS_VALUE = 1 << 24;
/**
* Data structure to convert between Date and triplet (year, month, and day).
* @see ConvertDateToYMD(), ConvertYMDToDate()
*/
struct YearMonthDay {
Year year; ///< Year (0...)
Month month; ///< Month (0..11)
Day day; ///< Day (1..31)
};
static constexpr Year INVALID_YEAR = -1; ///< Representation of an invalid year
static constexpr Date INVALID_DATE = -1; ///< Representation of an invalid date
static constexpr DateTicks INVALID_DATE_TICKS = -1; ///< Representation of an invalid date ticks
static constexpr Ticks INVALID_TICKS = -1; ///< Representation of an invalid number of ticks
#endif /* DATE_TYPE_H */

@ -321,8 +321,8 @@ const char *log_prefix::GetLogPrefix()
}
struct DesyncMsgLogEntry {
Date date;
DateFract date_fract;
EconTime::Date date;
EconTime::DateFract date_fract;
uint8_t tick_skip_counter;
uint32_t src_id;
std::string msg;
@ -330,7 +330,7 @@ struct DesyncMsgLogEntry {
DesyncMsgLogEntry() { }
DesyncMsgLogEntry(std::string msg)
: date(_date), date_fract(_date_fract), tick_skip_counter(_tick_skip_counter), src_id(0), msg(msg) { }
: date(EconTime::CurDate()), date_fract(EconTime::CurDateFract()), tick_skip_counter(TickSkipCounter()), src_id(0), msg(msg) { }
};
struct DesyncMsgLog {
@ -385,12 +385,12 @@ void ClearDesyncMsgLog()
char *DumpDesyncMsgLog(char *buffer, const char *last)
{
buffer = _desync_msg_log.Dump(buffer, last, "Desync Msg Log", [](int display_num, char *buffer, const char *last, const DesyncMsgLogEntry &entry) -> int {
YearMonthDay ymd = ConvertDateToYMD(entry.date);
return seprintf(buffer, last, "%5u | %4i-%02i-%02i, %2i, %3i | %s\n", display_num, ymd.year, ymd.month + 1, ymd.day, entry.date_fract, entry.tick_skip_counter, entry.msg.c_str());
EconTime::YearMonthDay ymd = EconTime::ConvertDateToYMD(entry.date);
return seprintf(buffer, last, "%5u | %4i-%02i-%02i, %2i, %3i | %s\n", display_num, ymd.year.base(), ymd.month + 1, ymd.day, entry.date_fract, entry.tick_skip_counter, entry.msg.c_str());
});
buffer = _remote_desync_msg_log.Dump(buffer, last, "Remote Client Desync Msg Log", [](int display_num, char *buffer, const char *last, const DesyncMsgLogEntry &entry) -> int {
YearMonthDay ymd = ConvertDateToYMD(entry.date);
return seprintf(buffer, last, "%5u | Client %5u | %4i-%02i-%02i, %2i, %3i | %s\n", display_num, entry.src_id, ymd.year, ymd.month + 1, ymd.day, entry.date_fract, entry.tick_skip_counter, entry.msg.c_str());
EconTime::YearMonthDay ymd = EconTime::ConvertDateToYMD(entry.date);
return seprintf(buffer, last, "%5u | Client %5u | %4i-%02i-%02i, %2i, %3i | %s\n", display_num, entry.src_id, ymd.year.base(), ymd.month + 1, ymd.day, entry.date_fract, entry.tick_skip_counter, entry.msg.c_str());
});
return buffer;
}
@ -403,7 +403,7 @@ void LogDesyncMsg(std::string msg)
_desync_msg_log.LogMsg(DesyncMsgLogEntry(std::move(msg)));
}
void LogRemoteDesyncMsg(Date date, DateFract date_fract, uint8_t tick_skip_counter, uint32_t src_id, std::string msg)
void LogRemoteDesyncMsg(EconTime::Date date, EconTime::DateFract date_fract, uint8_t tick_skip_counter, uint32_t src_id, std::string msg)
{
DesyncMsgLogEntry entry(std::move(msg));
entry.date = date;

@ -856,8 +856,8 @@ DepartureList* MakeDepartureList(StationID station, const std::vector<const Vehi
for (uint i = 0; i < next_orders.size(); ++i) {
OrderDate *od = next_orders[i];
DateTicks lod = least_order->expected_tick - least_order->lateness;
DateTicks odd = od->expected_tick - od->lateness;
Ticks lod = least_order->expected_tick - least_order->lateness;
Ticks odd = od->expected_tick - od->lateness;
if (type == D_ARRIVAL) {
lod -= least_order->scheduled_waiting_time > 0 ? least_order->scheduled_waiting_time : least_order->order->GetWaitTime();

@ -23,7 +23,7 @@ struct Depot : DepotPool::PoolItem<&_depot_pool> {
TileIndex xy;
Town *town;
TinyString name;
Date build_date; ///< Date of construction
CalTime::Date build_date; ///< Date of construction
Depot(TileIndex xy = INVALID_TILE) : xy(xy) {}
~Depot();

@ -946,8 +946,8 @@ static void Disaster_CoalMine_Init()
struct Disaster {
DisasterInitProc *init_proc; ///< The init function for this disaster.
Year min_year; ///< The first year this disaster will occur.
Year max_year; ///< The last year this disaster will occur.
CalTime::Year min_year; ///< The first year this disaster will occur.
CalTime::Year max_year; ///< The last year this disaster will occur.
};
static const Disaster _disasters[] = {
@ -967,7 +967,7 @@ void DoDisaster()
byte j = 0;
for (size_t i = 0; i != lengthof(_disasters); i++) {
if (_cur_year >= _disasters[i].min_year && _cur_year < _disasters[i].max_year) buf[j++] = (byte)i;
if (CalTime::CurYear() >= _disasters[i].min_year && CalTime::CurYear() < _disasters[i].max_year) buf[j++] = (byte)i;
}
if (j == 0) return;

@ -806,7 +806,7 @@ static void CompaniesGenStatistics()
cur_company.Restore();
/* Only run the economic statics and update company stats every 3rd month (1st of quarter). */
if (!HasBit(1 << 0 | 1 << 3 | 1 << 6 | 1 << 9, _cur_date_ymd.month)) return;
if ((EconTime::CurMonth() % 3) == 0) return;
for (Company *c : Company::Iterate()) {
/* Drop the oldest history off the end */
@ -851,9 +851,9 @@ bool AddInflation(bool check_year)
* it impossible due to the diverging cost and income rates.
*/
if (_settings_game.economy.inflation_fixed_dates) {
if (check_year && (_cur_year < ORIGINAL_BASE_YEAR || _cur_year >= ORIGINAL_MAX_YEAR)) return true;
if (check_year && (CalTime::CurYear() < CalTime::ORIGINAL_BASE_YEAR || CalTime::CurYear() >= CalTime::ORIGINAL_MAX_YEAR)) return true;
} else {
if (check_year && (_cur_year - _settings_game.game_creation.starting_year) >= (ORIGINAL_MAX_YEAR - ORIGINAL_BASE_YEAR)) return true;
if (check_year && (CalTime::CurYear() - _settings_game.game_creation.starting_year) >= (CalTime::ORIGINAL_MAX_YEAR - CalTime::ORIGINAL_BASE_YEAR)) return true;
}
if (_economy.inflation_prices == MAX_INFLATION || _economy.inflation_payment == MAX_INFLATION) return true;
@ -964,8 +964,8 @@ static void CompaniesPayInterest()
if (c->money < 0) {
yearly_fee += -c->money *_economy.interest_rate / 100;
}
Money up_to_previous_month = yearly_fee * _cur_date_ymd.month / 12;
Money up_to_this_month = yearly_fee * (_cur_date_ymd.month + 1) / 12;
Money up_to_previous_month = yearly_fee * EconTime::CurMonth() / 12;
Money up_to_this_month = yearly_fee * (EconTime::CurMonth() + 1) / 12;
SubtractMoneyFromCompany(CommandCost(EXPENSES_LOAN_INTEREST, up_to_this_month - up_to_previous_month));
@ -1048,7 +1048,7 @@ void StartupEconomy()
if (_settings_game.economy.inflation && _settings_game.economy.inflation_fixed_dates) {
/* Apply inflation that happened before our game start year. */
int months = (std::min(_cur_year, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR) * 12;
int months = (std::min(CalTime::CurYear(), CalTime::ORIGINAL_MAX_YEAR) - CalTime::ORIGINAL_BASE_YEAR).base() * 12;
for (int i = 0; i < months; i++) {
AddInflation(false);
}
@ -1197,7 +1197,7 @@ uint DeliverGoodsToIndustryNearestFirst(const Station *st, CargoID cargo_type, u
uint amount = std::min(num_pieces, 0xFFFFu - ind->incoming_cargo_waiting[cargo_index]);
ind->incoming_cargo_waiting[cargo_index] += amount;
ind->last_cargo_accepted_at[cargo_index] = _date;
ind->last_cargo_accepted_at[cargo_index] = EconTime::CurDate();
num_pieces -= amount;
accepted += amount;
@ -1242,7 +1242,7 @@ uint DeliverGoodsToIndustryEqually(const Station *st, CargoID cargo_type, uint n
if (e.delivered == 0) return;
include(_cargo_delivery_destinations, e.ind);
e.ind->incoming_cargo_waiting[e.cargo_index] += e.delivered;
e.ind->last_cargo_accepted_at[e.cargo_index] = _date;
e.ind->last_cargo_accepted_at[e.cargo_index] = EconTime::CurDate();
AddCargoDelivery(cargo_type, company, e.delivered, SourceType::Industry, source, st, e.ind->index);
};
@ -2191,7 +2191,7 @@ static void LoadUnloadVehicle(Vehicle *front)
/* if last speed is 0, we treat that as if no vehicle has ever visited the station. */
ge->last_speed = ClampTo<uint8_t>(t);
ge->last_age = ClampTo<uint8_t>(_cur_year - front->build_year);
ge->last_age = ClampTo<uint8_t>(DateDeltaToYearDelta(front->age));
assert(v->cargo_cap >= v->cargo.StoredCount());
/* Capacity available for loading more cargo. */
@ -2451,14 +2451,21 @@ void LoadUnloadStation(Station *st)
/**
* Monthly update of the economic data (of the companies as well as economic fluctuations).
*/
void CompaniesMonthlyLoop()
void CompaniesCalendarMonthlyLoop()
{
CompaniesPayInterest();
CompaniesGenStatistics();
if (_settings_game.economy.inflation) {
AddInflation();
RecomputePrices();
}
}
/**
* Monthly update of the economic data (of the companies as well as economic fluctuations).
*/
void CompaniesEconomyMonthlyLoop()
{
CompaniesPayInterest();
CompaniesGenStatistics();
HandleEconomyFluctuations();
}
@ -2518,7 +2525,7 @@ CommandCost CmdBuyShareInCompany(TileIndex tile, DoCommandFlag flags, uint32_t p
if (c == nullptr || !_settings_game.economy.allow_shares || _current_company == target_company) return CMD_ERROR;
/* Protect new companies from hostile takeovers */
if (_cur_year - c->inaugurated_year < _settings_game.economy.min_years_for_shares) return_cmd_error(STR_ERROR_PROTECTED);
if (CalTime::CurYear() - c->inaugurated_year < _settings_game.economy.min_years_for_shares) return_cmd_error(STR_ERROR_PROTECTED);
/* Those lines are here for network-protection (clients can be slow) */
if (GetAmountOwnedBy(c, COMPANY_SPECTATOR) == 0) return cost;

@ -45,7 +45,7 @@ EngineOverrideManager _engine_mngr;
* Year that engine aging stops. Engines will not reduce in reliability
* and no more engines will be introduced
*/
static Year _year_engine_aging_stops;
static CalTime::Year _year_engine_aging_stops;
/** Number of engines of each vehicle type in original engine data */
const uint8_t _engine_counts[4] = {
@ -487,7 +487,7 @@ uint Engine::GetDisplayMaxTractiveEffort() const
DateDelta Engine::GetLifeLengthInDays() const
{
/* Assume leap years; this gives the player a bit more than the given amount of years, but never less. */
return static_cast<int32_t>(this->info.lifelength + _settings_game.vehicle.extend_vehicle_life) * DAYS_IN_LEAP_YEAR;
return (this->info.lifelength + _settings_game.vehicle.extend_vehicle_life).base() * DAYS_IN_LEAP_YEAR;
}
/**
@ -651,8 +651,8 @@ static void ClearLastVariant(EngineID engine_id, VehicleType type)
static void RetireEngineIfPossible(Engine *e, int age_threshold)
{
if (_settings_game.vehicle.no_expire_vehicles_after > 0) {
YearMonthDay ymd = ConvertDateToYMD(e->intro_date);
if ((ymd.year * 12) + ymd.month + age_threshold >= _settings_game.vehicle.no_expire_vehicles_after * 12) return;
CalTime::YearMonthDay ymd = CalTime::ConvertDateToYMD(e->intro_date);
if ((ymd.year.base() * 12) + ymd.month + age_threshold >= _settings_game.vehicle.no_expire_vehicles_after.base() * 12) return;
}
e->company_avail = 0;
@ -724,7 +724,7 @@ void SetYearEngineAgingStops()
if (e->type == VEH_TRAIN && e->u.rail.railveh_type == RAILVEH_WAGON) continue;
/* Base year ending date on half the model life */
YearMonthDay ymd = ConvertDateToYMD(ei->base_intro + (static_cast<int32_t>(ei->lifelength) * DAYS_IN_LEAP_YEAR) / 2);
CalTime::YearMonthDay ymd = CalTime::ConvertDateToYMD(ei->base_intro + (ei->lifelength.base() * DAYS_IN_LEAP_YEAR) / 2);
_year_engine_aging_stops = std::max(_year_engine_aging_stops, ymd.year);
}
@ -736,7 +736,7 @@ void SetYearEngineAgingStops()
* @param aging_date The date used for age calculations.
* @param seed Random seed.
*/
void StartupOneEngine(Engine *e, Date aging_date, const YearMonthDay &aging_ymd, uint32_t seed, Date no_introduce_after_date)
void StartupOneEngine(Engine *e, CalTime::Date aging_date, const CalTime::YearMonthDay &aging_ymd, uint32_t seed, CalTime::Date no_introduce_after_date)
{
const EngineInfo *ei = &e->info;
@ -758,11 +758,11 @@ void StartupOneEngine(Engine *e, Date aging_date, const YearMonthDay &aging_ymd,
/* Don't randomise the start-date in the first two years after gamestart to ensure availability
* of engines in early starting games.
* Note: TTDP uses fixed 1922 */
e->intro_date = ei->base_intro <= ConvertYMDToDate(_settings_game.game_creation.starting_year + 2, 0, 1) ? ei->base_intro : (DateDelta)GB(r, 0, 9) + ei->base_intro;
if (e->intro_date <= _date && e->intro_date <= no_introduce_after_date) {
YearMonthDay intro_ymd = ConvertDateToYMD(e->intro_date);
int aging_months = aging_ymd.year * 12 + aging_ymd.month;
int intro_months = intro_ymd.year * 12 + intro_ymd.month;
e->intro_date = ei->base_intro <= CalTime::ConvertYMDToDate(_settings_game.game_creation.starting_year + 2, 0, 1) ? ei->base_intro : (DateDelta)GB(r, 0, 9) + ei->base_intro;
if (e->intro_date <= CalTime::CurDate() && e->intro_date <= no_introduce_after_date) {
CalTime::YearMonthDay intro_ymd = CalTime::ConvertDateToYMD(e->intro_date);
int aging_months = aging_ymd.year.base() * 12 + aging_ymd.month;
int intro_months = intro_ymd.year.base() * 12 + intro_ymd.month;
if (intro_ymd.day > 1) intro_months++; // Engines are introduced at the first month start at/after intro date.
e->age = aging_months - intro_months;
e->company_avail = MAX_UVALUE(CompanyMask);
@ -777,7 +777,7 @@ void StartupOneEngine(Engine *e, Date aging_date, const YearMonthDay &aging_ymd,
SetRandomSeed(_settings_game.game_creation.generation_seed ^ seed ^
(re->index << 16) ^ (re->info.base_intro.base() << 12) ^ (re->info.decay_speed << 8) ^
(re->info.lifelength << 4) ^ re->info.retire_early ^
(re->info.lifelength.base() << 4) ^ re->info.retire_early ^
e->type ^
e->GetGRFID());
@ -799,7 +799,7 @@ void StartupOneEngine(Engine *e, Date aging_date, const YearMonthDay &aging_ymd,
e->reliability_final = GB(r, 16, 14) + RELIABILITY_FINAL;
e->duration_phase_1 = GB(r, 0, 5) + 7;
e->duration_phase_2 = std::max(0, int(GB(r, 5, 4)) + ei->base_life * 12 - 96);
e->duration_phase_2 = std::max(0, int(GB(r, 5, 4)) + ei->base_life.base() * 12 - 96);
e->duration_phase_3 = GB(r, 9, 7) + 120;
RestoreRandomSeeds(saved_seeds);
@ -820,16 +820,16 @@ void StartupOneEngine(Engine *e, Date aging_date, const YearMonthDay &aging_ymd,
void StartupEngines()
{
/* Aging of vehicles stops, so account for that when starting late */
Year aging_stop_year = _year_engine_aging_stops;
CalTime::Year aging_stop_year = _year_engine_aging_stops;
if (_settings_game.vehicle.no_introduce_vehicles_after > 0 && _settings_game.vehicle.no_expire_vehicles_after > 0) {
aging_stop_year = std::min<Year>(aging_stop_year, std::max<Year>(_settings_game.vehicle.no_introduce_vehicles_after, _settings_game.vehicle.no_expire_vehicles_after));
aging_stop_year = std::min<CalTime::Year>(aging_stop_year, std::max<CalTime::Year>(_settings_game.vehicle.no_introduce_vehicles_after, _settings_game.vehicle.no_expire_vehicles_after));
}
const Date aging_date = std::min(_date, ConvertYMDToDate(aging_stop_year, 0, 1));
const YearMonthDay aging_ymd = ConvertDateToYMD(aging_date);
const CalTime::Date aging_date = std::min(CalTime::CurDate(), CalTime::ConvertYMDToDate(aging_stop_year, 0, 1));
const CalTime::YearMonthDay aging_ymd = CalTime::ConvertDateToYMD(aging_date);
Date no_introduce_after_date = INT_MAX;
CalTime::Date no_introduce_after_date = INT_MAX;
if (_settings_game.vehicle.no_introduce_vehicles_after > 0) {
no_introduce_after_date = ConvertYMDToDate(_settings_game.vehicle.no_introduce_vehicles_after, 0, 1) - 1;
no_introduce_after_date = CalTime::ConvertYMDToDate(_settings_game.vehicle.no_introduce_vehicles_after, 0, 1) - 1;
}
uint32_t seed = Random();
@ -994,11 +994,11 @@ static bool IsVehicleTypeDisabled(VehicleType type, bool ai)
void EnginesDailyLoop()
{
for (Company *c : Company::Iterate()) {
c->avail_railtypes = AddDateIntroducedRailTypes(c->avail_railtypes, _date);
c->avail_roadtypes = AddDateIntroducedRoadTypes(c->avail_roadtypes, _date);
c->avail_railtypes = AddDateIntroducedRailTypes(c->avail_railtypes, CalTime::CurDate());
c->avail_roadtypes = AddDateIntroducedRoadTypes(c->avail_roadtypes, CalTime::CurDate());
}
if (_cur_year >= _year_engine_aging_stops) return;
if (CalTime::CurYear() >= _year_engine_aging_stops) return;
for (Engine *e : Engine::Iterate()) {
EngineID i = e->index;
@ -1160,11 +1160,11 @@ static void NewVehicleAvailable(Engine *e)
if (e->type == VEH_TRAIN) {
/* maybe make another rail type available */
assert(e->u.rail.railtype < RAILTYPE_END);
for (Company *c : Company::Iterate()) c->avail_railtypes = AddDateIntroducedRailTypes(c->avail_railtypes | GetRailTypeInfo(e->u.rail.railtype)->introduces_railtypes, _date);
for (Company *c : Company::Iterate()) c->avail_railtypes = AddDateIntroducedRailTypes(c->avail_railtypes | GetRailTypeInfo(e->u.rail.railtype)->introduces_railtypes, CalTime::CurDate());
} else if (e->type == VEH_ROAD) {
/* maybe make another road type available */
assert(e->u.road.roadtype < ROADTYPE_END);
for (Company *c : Company::Iterate()) c->avail_roadtypes = AddDateIntroducedRoadTypes(c->avail_roadtypes | GetRoadTypeInfo(e->u.road.roadtype)->introduces_roadtypes, _date);
for (Company *c : Company::Iterate()) c->avail_roadtypes = AddDateIntroducedRoadTypes(c->avail_roadtypes | GetRoadTypeInfo(e->u.road.roadtype)->introduces_roadtypes, CalTime::CurDate());
}
/* Only broadcast event if AIs are able to build this vehicle type. */
@ -1189,13 +1189,13 @@ static void NewVehicleAvailable(Engine *e)
/** Monthly update of the availability, reliability, and preview offers of the engines. */
void EnginesMonthlyLoop()
{
if (_cur_year < _year_engine_aging_stops) {
Date no_introduce_after = INT_MAX;
if (CalTime::CurYear() < _year_engine_aging_stops) {
CalTime::Date no_introduce_after = INT_MAX;
if (_settings_game.vehicle.no_introduce_vehicles_after > 0) {
if (_settings_game.vehicle.no_expire_vehicles_after > 0 && _cur_year >= std::max<Year>(_settings_game.vehicle.no_introduce_vehicles_after, _settings_game.vehicle.no_expire_vehicles_after)) {
if (_settings_game.vehicle.no_expire_vehicles_after > 0 && CalTime::CurYear() >= std::max<CalTime::Year>(_settings_game.vehicle.no_introduce_vehicles_after, _settings_game.vehicle.no_expire_vehicles_after)) {
return;
}
no_introduce_after = ConvertYMDToDate(_settings_game.vehicle.no_introduce_vehicles_after, 0, 1) - 1;
no_introduce_after = CalTime::ConvertYMDToDate(_settings_game.vehicle.no_introduce_vehicles_after, 0, 1) - 1;
}
bool refresh = false;
@ -1212,10 +1212,10 @@ void EnginesMonthlyLoop()
if (e->intro_date > no_introduce_after) continue;
if (!(e->flags & ENGINE_AVAILABLE) && _date >= (e->intro_date + DAYS_IN_YEAR)) {
if (!(e->flags & ENGINE_AVAILABLE) && CalTime::CurDate() >= (e->intro_date + DAYS_IN_YEAR)) {
/* Introduce it to all companies */
NewVehicleAvailable(e);
} else if (!(e->flags & (ENGINE_AVAILABLE | ENGINE_EXCLUSIVE_PREVIEW)) && _date >= e->intro_date) {
} else if (!(e->flags & (ENGINE_AVAILABLE | ENGINE_EXCLUSIVE_PREVIEW)) && CalTime::CurDate() >= e->intro_date) {
/* Introduction date has passed...
* Check if it is allowed to build this vehicle type at all
* based on the current game settings. If not, it does not
@ -1372,7 +1372,7 @@ bool IsEngineRefittable(EngineID engine)
*/
void CheckEngines()
{
Date min_date = INT32_MAX;
CalTime::Date min_date = INT32_MAX;
for (const Engine *e : Engine::Iterate()) {
if (!e->IsEnabled()) continue;

@ -44,7 +44,7 @@ struct EngineRefitCapacityValue {
struct Engine : EnginePool::PoolItem<&_engine_pool> {
TinyString name; ///< Custom name of engine.
Date intro_date; ///< Date of introduction of the engine.
CalTime::Date intro_date; ///< Date of introduction of the engine.
int32_t age; ///< Age of the engine in months.
uint16_t reliability; ///< Current reliability of the engine.
uint16_t reliability_spd_dec; ///< Speed of reliability decay between services (per day).

@ -27,7 +27,7 @@ bool IsEngineBuildable(EngineID engine, VehicleType type, CompanyID company);
bool IsEngineRefittable(EngineID engine);
void SetYearEngineAgingStops();
void CalcEngineReliability(Engine *e, bool new_month);
void StartupOneEngine(Engine *e, Date aging_date, const YearMonthDay &aging_ymd, uint32_t seed, Date no_introduce_after_date);
void StartupOneEngine(Engine *e, CalTime::Date aging_date, const CalTime::YearMonthDay &aging_ymd, uint32_t seed, CalTime::Date no_introduce_after_date);
uint GetTotalCapacityOfArticulatedParts(EngineID engine);

@ -141,9 +141,9 @@ DECLARE_ENUM_AS_BIT_SET(ExtraEngineFlags);
* @see table/engines.h
*/
struct EngineInfo {
Date base_intro; ///< Basic date of engine introduction (without random parts).
Year lifelength; ///< Lifetime of a single vehicle
Year base_life; ///< Basic duration of engine availability (without random parts). \c 0xFF means infinite life.
CalTime::Date base_intro; ///< Basic date of engine introduction (without random parts).
YearDelta lifelength; ///< Lifetime of a single vehicle
YearDelta base_life; ///< Basic duration of engine availability (without random parts). \c 0xFF means infinite life.
byte decay_speed;
byte load_amount;
byte climates; ///< Climates supported by the engine.

@ -22,8 +22,8 @@ GameEventFlags _game_events_since_load;
GameEventFlags _game_events_overall;
time_t _game_load_time;
YearMonthDay _game_load_cur_date_ymd;
DateFract _game_load_date_fract;
EconTime::YearMonthDay _game_load_cur_date_ymd;
EconTime::DateFract _game_load_date_fract;
uint8_t _game_load_tick_skip_counter;
StateTicks _game_load_state_ticks;
@ -47,8 +47,8 @@ char *DumpGameEventFlags(GameEventFlags events, char *b, const char *last)
struct SpecialEventLogEntry {
std::string msg;
Date date;
DateFract date_fract;
EconTime::Date date;
EconTime::DateFract date_fract;
uint8_t tick_skip_counter;
CompanyID current_company;
CompanyID local_company;
@ -56,7 +56,7 @@ struct SpecialEventLogEntry {
SpecialEventLogEntry() { }
SpecialEventLogEntry(std::string msg)
: msg(std::move(msg)), date(_date), date_fract(_date_fract), tick_skip_counter(_tick_skip_counter),
: msg(std::move(msg)), date(EconTime::CurDate()), date_fract(EconTime::CurDateFract()), tick_skip_counter(TickSkipCounter()),
current_company(_current_company), local_company(_local_company) { }
};
@ -95,9 +95,9 @@ char *DumpSpecialEventsLog(char *buffer, const char *last)
}
const SpecialEventLogEntry &entry = _special_event_log.log[log_index];
YearMonthDay ymd = ConvertDateToYMD(entry.date);
EconTime::YearMonthDay ymd = EconTime::ConvertDateToYMD(entry.date);
buffer += seprintf(buffer, last, " %3u | %4i-%02i-%02i, %2i, %3i | cc: %3u, lc: %3u | %s\n",
i, ymd.year, ymd.month + 1, ymd.day, entry.date_fract, entry.tick_skip_counter, (uint) entry.current_company, (uint) entry.local_company, entry.msg.c_str());
i, ymd.year.base(), ymd.month + 1, ymd.day, entry.date_fract, entry.tick_skip_counter, (uint) entry.current_company, (uint) entry.local_company, entry.msg.c_str());
}
return buffer;
}
@ -111,7 +111,7 @@ void LogGameLoadDateTimes(char *buffer, const char *last)
{
if (_game_load_time != 0) {
buffer += seprintf(buffer, last, "Game loaded at: %i-%02i-%02i (%i, %i), (" OTTD_PRINTF64 " state ticks ago), ",
_game_load_cur_date_ymd.year, _game_load_cur_date_ymd.month + 1, _game_load_cur_date_ymd.day,
_game_load_cur_date_ymd.year.base(), _game_load_cur_date_ymd.month + 1, _game_load_cur_date_ymd.day,
_game_load_date_fract, _game_load_tick_skip_counter, (_state_ticks - _game_load_state_ticks).base());
buffer += UTCTime::Format(buffer, last, _game_load_time, "%Y-%m-%d %H:%M:%S");
buffer += seprintf(buffer, last, "\n");

@ -31,8 +31,8 @@ extern GameEventFlags _game_events_since_load;
extern GameEventFlags _game_events_overall;
extern time_t _game_load_time;
extern YearMonthDay _game_load_cur_date_ymd;
extern DateFract _game_load_date_fract;
extern EconTime::YearMonthDay _game_load_cur_date_ymd;
extern EconTime::DateFract _game_load_date_fract;
extern uint8_t _game_load_tick_skip_counter;
extern StateTicks _game_load_state_ticks;

@ -535,7 +535,7 @@ public:
/* Start date (if available) */
if (_load_check_data.settings.game_creation.starting_year != 0) {
SetDParam(0, ConvertYMDToDate(_load_check_data.settings.game_creation.starting_year, 0, 1));
SetDParam(0, CalTime::ConvertYMDToDate(_load_check_data.settings.game_creation.starting_year, 0, 1));
DrawString(tr, STR_NETWORK_SERVER_LIST_START_DATE);
tr.top += GetCharacterHeight(FS_NORMAL);
}

@ -211,7 +211,7 @@ static void _GenerateWorld()
if (_debug_desync_level > 0) {
char name[MAX_PATH];
seprintf(name, lastof(name), "dmp_cmds_%08x_%08x.sav", _settings_game.game_creation.generation_seed, _date.base());
seprintf(name, lastof(name), "dmp_cmds_%08x_%08x.sav", _settings_game.game_creation.generation_seed, EconTime::CurDate().base());
SaveOrLoad(name, SLO_SAVE, DFT_GAME_FILE, AUTOSAVE_DIR, false, SMF_ZSTD_OK);
}
} catch (AbortGenerateWorldSignal&) {

@ -482,7 +482,7 @@ struct GenerateLandscapeWindow : public Window {
void SetStringParameters(WidgetID widget) const override
{
switch (widget) {
case WID_GL_START_DATE_TEXT: SetDParam(0, ConvertYMDToDate(_settings_newgame.game_creation.starting_year, 0, 1)); break;
case WID_GL_START_DATE_TEXT: SetDParam(0, CalTime::ConvertYMDToDate(_settings_newgame.game_creation.starting_year, 0, 1)); break;
case WID_GL_MAPSIZE_X_PULLDOWN: SetDParam(0, 1LL << _settings_newgame.game_creation.map_x); break;
case WID_GL_MAPSIZE_Y_PULLDOWN: SetDParam(0, 1LL << _settings_newgame.game_creation.map_y); break;
case WID_GL_HEIGHTMAP_HEIGHT_TEXT: SetDParam(0, _settings_newgame.game_creation.heightmap_height); break;
@ -619,8 +619,8 @@ struct GenerateLandscapeWindow : public Window {
this->SetWidgetDisabledState(WID_GL_HEIGHTMAP_HEIGHT_DOWN, _settings_newgame.game_creation.heightmap_height <= MIN_HEIGHTMAP_HEIGHT);
this->SetWidgetDisabledState(WID_GL_HEIGHTMAP_HEIGHT_UP, _settings_newgame.game_creation.heightmap_height >= GetMapHeightLimit());
}
this->SetWidgetDisabledState(WID_GL_START_DATE_DOWN, _settings_newgame.game_creation.starting_year <= MIN_YEAR);
this->SetWidgetDisabledState(WID_GL_START_DATE_UP, _settings_newgame.game_creation.starting_year >= MAX_YEAR);
this->SetWidgetDisabledState(WID_GL_START_DATE_DOWN, _settings_newgame.game_creation.starting_year <= CalTime::MIN_YEAR);
this->SetWidgetDisabledState(WID_GL_START_DATE_UP, _settings_newgame.game_creation.starting_year >= CalTime::MAX_YEAR);
this->SetWidgetDisabledState(WID_GL_SNOW_COVERAGE_DOWN, _settings_newgame.game_creation.snow_coverage <= 0 || _settings_newgame.game_creation.landscape != LT_ARCTIC);
this->SetWidgetDisabledState(WID_GL_SNOW_COVERAGE_UP, _settings_newgame.game_creation.snow_coverage >= 100 || _settings_newgame.game_creation.landscape != LT_ARCTIC);
this->SetWidgetDisabledState(WID_GL_DESERT_COVERAGE_DOWN, _settings_newgame.game_creation.desert_coverage <= 0 || _settings_newgame.game_creation.landscape != LT_TROPIC);
@ -660,7 +660,7 @@ struct GenerateLandscapeWindow : public Window {
break;
case WID_GL_START_DATE_TEXT:
SetDParam(0, ConvertYMDToDate(MAX_YEAR, 0, 1));
SetDParam(0, CalTime::ConvertYMDToDate(CalTime::MAX_YEAR, 0, 1));
d = GetStringBoundingBox(STR_JUST_DATE_LONG);
break;
@ -835,7 +835,7 @@ struct GenerateLandscapeWindow : public Window {
if (!(this->flags & WF_TIMEOUT) || this->timeout_timer <= 1) {
this->HandleButtonClick(widget);
_settings_newgame.game_creation.starting_year = Clamp(_settings_newgame.game_creation.starting_year + widget - WID_GL_START_DATE_TEXT, MIN_YEAR, MAX_YEAR);
_settings_newgame.game_creation.starting_year = Clamp(_settings_newgame.game_creation.starting_year + widget - WID_GL_START_DATE_TEXT, CalTime::MIN_YEAR, CalTime::MAX_YEAR);
this->InvalidateData();
}
_left_button_clicked = false;
@ -1079,7 +1079,7 @@ struct GenerateLandscapeWindow : public Window {
/* An empty string means revert to the default */
switch (this->widget_id) {
case WID_GL_HEIGHTMAP_HEIGHT_TEXT: value = MAP_HEIGHT_LIMIT_AUTO_MINIMUM; break;
case WID_GL_START_DATE_TEXT: value = DEF_START_YEAR; break;
case WID_GL_START_DATE_TEXT: value = CalTime::DEF_START_YEAR.base(); break;
case WID_GL_SNOW_COVERAGE_TEXT: value = DEF_SNOW_COVERAGE; break;
case WID_GL_DESERT_COVERAGE_TEXT: value = DEF_DESERT_COVERAGE; break;
case WID_GL_TOWN_PULLDOWN: value = 1; break;
@ -1100,7 +1100,7 @@ struct GenerateLandscapeWindow : public Window {
case WID_GL_START_DATE_TEXT:
this->SetWidgetDirty(WID_GL_START_DATE_TEXT);
_settings_newgame.game_creation.starting_year = Clamp(value, MIN_YEAR, MAX_YEAR);
_settings_newgame.game_creation.starting_year = Clamp<CalTime::Year>(value, CalTime::MIN_YEAR, CalTime::MAX_YEAR);
break;
case WID_GL_SNOW_COVERAGE_TEXT:
@ -1238,7 +1238,7 @@ struct CreateScenarioWindow : public Window
{
switch (widget) {
case WID_CS_START_DATE_TEXT:
SetDParam(0, ConvertYMDToDate(_settings_newgame.game_creation.starting_year, 0, 1));
SetDParam(0, CalTime::ConvertYMDToDate(_settings_newgame.game_creation.starting_year, 0, 1));
break;
case WID_CS_MAPSIZE_X_PULLDOWN:
@ -1257,8 +1257,8 @@ struct CreateScenarioWindow : public Window
void OnPaint() override
{
this->SetWidgetDisabledState(WID_CS_START_DATE_DOWN, _settings_newgame.game_creation.starting_year <= MIN_YEAR);
this->SetWidgetDisabledState(WID_CS_START_DATE_UP, _settings_newgame.game_creation.starting_year >= MAX_YEAR);
this->SetWidgetDisabledState(WID_CS_START_DATE_DOWN, _settings_newgame.game_creation.starting_year <= CalTime::MIN_YEAR);
this->SetWidgetDisabledState(WID_CS_START_DATE_UP, _settings_newgame.game_creation.starting_year >= CalTime::MAX_YEAR);
this->SetWidgetDisabledState(WID_CS_FLAT_LAND_HEIGHT_DOWN, _settings_newgame.game_creation.se_flat_world_height <= 0);
this->SetWidgetDisabledState(WID_CS_FLAT_LAND_HEIGHT_UP, _settings_newgame.game_creation.se_flat_world_height >= GetMapHeightLimit());
@ -1281,7 +1281,7 @@ struct CreateScenarioWindow : public Window
break;
case WID_CS_START_DATE_TEXT:
SetDParam(0, ConvertYMDToDate(MAX_YEAR, 0, 1));
SetDParam(0, CalTime::ConvertYMDToDate(CalTime::MAX_YEAR, 0, 1));
str = STR_JUST_DATE_LONG;
break;
@ -1339,7 +1339,7 @@ struct CreateScenarioWindow : public Window
this->HandleButtonClick(widget);
this->SetDirty();
_settings_newgame.game_creation.starting_year = Clamp(_settings_newgame.game_creation.starting_year + widget - WID_CS_START_DATE_TEXT, MIN_YEAR, MAX_YEAR);
_settings_newgame.game_creation.starting_year = Clamp(_settings_newgame.game_creation.starting_year + widget - WID_CS_START_DATE_TEXT, CalTime::MIN_YEAR, CalTime::MAX_YEAR);
}
_left_button_clicked = false;
break;
@ -1394,7 +1394,7 @@ struct CreateScenarioWindow : public Window
switch (this->widget_id) {
case WID_CS_START_DATE_TEXT:
this->SetWidgetDirty(WID_CS_START_DATE_TEXT);
_settings_newgame.game_creation.starting_year = Clamp(value, MIN_YEAR, MAX_YEAR);
_settings_newgame.game_creation.starting_year = Clamp<CalTime::Year>(value, CalTime::MIN_YEAR, CalTime::MAX_YEAR);
break;
case WID_CS_FLAT_LAND_HEIGHT_TEXT:

@ -184,8 +184,8 @@ protected:
byte num_vert_lines;
/* The starting month and year that values are plotted against. */
byte month;
Year year;
EconTime::Month month;
EconTime::Year year;
bool draw_dates = true; ///< Should we draw months and years on the time axis?
@ -395,8 +395,8 @@ protected:
if (this->draw_dates) {
x = r.left;
y = r.bottom + ScaleGUITrad(2);
byte month = this->month;
Year year = this->year;
EconTime::Month month = this->month;
EconTime::Year year = this->year;
for (int i = 0; i < this->num_on_x_axis; i++) {
SetDParam(0, month + STR_MONTH_ABBREV_JAN);
SetDParam(1, year);
@ -518,8 +518,8 @@ public:
/* Draw x-axis labels and markings for graphs based on financial quarters and years. */
if (this->draw_dates) {
byte month = this->month;
Year year = this->year;
EconTime::Month month = this->month;
EconTime::Year year = this->year;
for (int i = 0; i < this->num_on_x_axis; i++) {
SetDParam(0, month + STR_MONTH_ABBREV_JAN);
SetDParam(1, year);
@ -598,8 +598,8 @@ public:
nums = std::min(this->num_vert_lines, std::max(nums, c->num_valid_stat_ent));
}
int mo = (_cur_date_ymd.month / 3 - nums) * 3;
int yr = _cur_year;
int mo = (EconTime::CurMonth() / 3 - nums) * 3;
EconTime::Year yr = EconTime::CurYear();
while (mo < 0) {
yr--;
mo += 12;
@ -950,8 +950,8 @@ struct DeliveredCargoGraphWindow : ExcludingCargoBaseGraphWindow {
nums = std::min(this->num_vert_lines, std::max(nums, c->num_valid_stat_ent));
}
int mo = (_cur_date_ymd.month / 3 - nums) * 3;
int yr = _cur_year;
int mo = (EconTime::CurMonth() / 3 - nums) * 3;
EconTime::Year yr = EconTime::CurYear();
while (mo < 0) {
yr--;
mo += 12;

@ -104,8 +104,8 @@ DECLARE_ENUM_AS_BIT_SET(HouseCtrlFlags)
struct HouseSpec {
/* Standard properties */
Year min_year; ///< introduction year of the house
Year max_year; ///< last year it can be built
CalTime::Year min_year; ///< introduction year of the house
CalTime::Year max_year; ///< last year it can be built
byte population; ///< population (Zero on other tiles in multi tile house.)
byte removal_cost; ///< cost multiplier for removing it
StringID building_name; ///< building name

@ -21,7 +21,7 @@
typedef Pool<Industry, IndustryID, 64, 64000> IndustryPool;
extern IndustryPool _industry_pool;
static const Year PROCESSING_INDUSTRY_ABANDONMENT_YEARS = 5; ///< If a processing industry doesn't produce for this many consecutive years, it may close.
static const YearDelta PROCESSING_INDUSTRY_ABANDONMENT_YEARS = 5; ///< If a processing industry doesn't produce for this many consecutive years, it may close.
/**
* Production level maximum, minimum and default values.
@ -63,7 +63,7 @@ DECLARE_ENUM_AS_BIT_SET(IndustryControlFlags);
struct Industry : IndustryPool::PoolItem<&_industry_pool> {
IndustryType type; ///< Type of industry.
Owner owner; ///< Owner of the industry. Which SHOULD always be (imho) OWNER_NONE
Date construction_date; ///< Date of the construction of the industry
CalTime::Date construction_date; ///< Date of the construction of the industry
TileArea location; ///< Location of the industry
Town *town; ///< Nearest town
Station *neutral_station; ///< Associated neutral station
@ -84,7 +84,7 @@ struct Industry : IndustryPool::PoolItem<&_industry_pool> {
uint16_t counter; ///< used for animation and/or production (if available cargo)
byte prod_level; ///< general production level
Colours random_colour; ///< randomized colour of the industry, for display purpose
Year last_prod_year; ///< last year of production
EconTime::Year last_prod_year; ///< last year of production
byte was_cargo_delivered; ///< flag that indicate this has been the closest industry chosen for cargo delivery by a station. see DeliverGoodsToIndustry
IndustryControlFlags ctlflags; ///< flags overriding standard behaviours
@ -95,7 +95,7 @@ struct Industry : IndustryPool::PoolItem<&_industry_pool> {
byte selected_layout; ///< Which tile layout was used when creating the industry
Owner exclusive_supplier; ///< Which company has exclusive rights to deliver cargo (INVALID_OWNER = anyone)
Owner exclusive_consumer; ///< Which company has exclusive rights to take cargo (INVALID_OWNER = anyone)
Date last_cargo_accepted_at[INDUSTRY_NUM_INPUTS]; ///< Last day each cargo type was accepted by this industry
EconTime::Date last_cargo_accepted_at[INDUSTRY_NUM_INPUTS]; ///< Last day each cargo type was accepted by this industry
std::string text; ///< General text with additional information.
uint16_t random; ///< Random value used for randomisation of all kinds of things

@ -1853,11 +1853,11 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type,
i->counter = GB(r, 4, 12);
i->random = initial_random_bits;
i->was_cargo_delivered = false;
i->last_prod_year = _cur_year;
i->last_prod_year = EconTime::CurYear();
i->founder = founder;
i->ctlflags = INDCTL_NONE;
i->construction_date = _date;
i->construction_date = CalTime::CurDate();
i->construction_type = (_game_mode == GM_EDITOR) ? ICT_SCENARIO_EDITOR :
(_generating_world ? ICT_MAP_GENERATION : ICT_NORMAL_GAMEPLAY);
@ -2393,8 +2393,8 @@ static uint16_t GetIndustryGamePlayProbability(IndustryType it, byte *min_number
const IndustrySpec *ind_spc = GetIndustrySpec(it);
byte chance = ind_spc->appear_ingame[_settings_game.game_creation.landscape];
if (!ind_spc->enabled || ind_spc->layouts.empty() ||
((ind_spc->behaviour & INDUSTRYBEH_BEFORE_1950) && _cur_year > 1950) ||
((ind_spc->behaviour & INDUSTRYBEH_AFTER_1960) && _cur_year < 1960) ||
((ind_spc->behaviour & INDUSTRYBEH_BEFORE_1950) && CalTime::CurYear() > 1950) ||
((ind_spc->behaviour & INDUSTRYBEH_AFTER_1960) && CalTime::CurYear() < 1960) ||
(chance = GetIndustryProbabilityCallback(it, IACT_RANDOMCREATION, chance)) == 0) {
*min_number = 0;
return 0;
@ -2566,7 +2566,7 @@ static void UpdateIndustryStatistics(Industry *i)
if (i->produced_cargo[j] != INVALID_CARGO) {
byte pct = 0;
if (i->this_month_production[j] != 0) {
i->last_prod_year = _cur_year;
i->last_prod_year = EconTime::CurYear();
pct = ClampTo<byte>(i->this_month_transported[j] * 256 / i->this_month_production[j]);
}
i->last_month_pct_transported[j] = pct;
@ -2993,7 +2993,7 @@ static void ChangeIndustryProduction(Industry *i, bool monthly)
}
if (!callback_enabled && (indspec->life_type & INDUSTRYLIFE_PROCESSING)) {
if ((_cur_year - i->last_prod_year) >= PROCESSING_INDUSTRY_ABANDONMENT_YEARS && Chance16(1, original_economy ? 2 : 180)) {
if ((EconTime::CurYear() - i->last_prod_year) >= PROCESSING_INDUSTRY_ABANDONMENT_YEARS && Chance16(1, original_economy ? 2 : 180)) {
closeit = true;
}
}

@ -562,7 +562,7 @@ byte GetSnowLineUncached()
{
if (_snow_line == nullptr) return _settings_game.game_creation.snow_line_height;
return _snow_line->table[_cur_date_ymd.month][_cur_date_ymd.day];
return _snow_line->table[CalTime::CurMonth()][CalTime::CurDay()];
}
void UpdateCachedSnowLine()
@ -754,7 +754,7 @@ void RunTileLoop(bool apply_day_length)
/* We update every tile every 256 ticks, so divide the map size by 2^8 = 256 */
uint count;
if (apply_day_length && DayLengthFactor() > 1) {
count = _tile_loop_counts[_tick_skip_counter];
count = _tile_loop_counts[TickSkipCounter()];
if (count == 0) return;
} else {
count = 1 << (MapLogX() + MapLogY() - 8);

@ -30,7 +30,7 @@ inline void LinkGraph::BaseNode::Init(TileIndex xy, StationID st, uint demand)
this->supply = 0;
this->demand = demand;
this->station = st;
this->last_update = INVALID_DATE;
this->last_update = EconTime::INVALID_DATE;
}
/**
@ -42,13 +42,13 @@ void LinkGraph::ShiftDates(DateDelta interval)
{
for (NodeID node1 = 0; node1 < this->Size(); ++node1) {
BaseNode &source = this->nodes[node1];
if (source.last_update != INVALID_DATE) source.last_update += interval;
if (source.last_update != EconTime::INVALID_DATE) source.last_update += interval;
}
for (auto &it : this->edges) {
BaseEdge &edge = it.second;
if (edge.last_unrestricted_update != INVALID_DATE) edge.last_unrestricted_update += interval;
if (edge.last_restricted_update != INVALID_DATE) edge.last_restricted_update += interval;
if (edge.last_aircraft_update != INVALID_DATE) edge.last_aircraft_update += interval;
if (edge.last_unrestricted_update != EconTime::INVALID_DATE) edge.last_unrestricted_update += interval;
if (edge.last_restricted_update != EconTime::INVALID_DATE) edge.last_restricted_update += interval;
if (edge.last_aircraft_update != EconTime::INVALID_DATE) edge.last_aircraft_update += interval;
}
}
@ -172,9 +172,9 @@ static void AddEdge(LinkGraph::BaseEdge &edge, uint capacity, uint usage, uint32
edge.capacity = capacity;
edge.usage = usage;
edge.travel_time_sum = static_cast<uint64_t>(travel_time) * capacity;
if (mode & EUM_UNRESTRICTED) edge.last_unrestricted_update = _date;
if (mode & EUM_RESTRICTED) edge.last_restricted_update = _date;
if (mode & EUM_AIRCRAFT) edge.last_aircraft_update = _date;
if (mode & EUM_UNRESTRICTED) edge.last_unrestricted_update = EconTime::CurDate();
if (mode & EUM_RESTRICTED) edge.last_restricted_update = EconTime::CurDate();
if (mode & EUM_AIRCRAFT) edge.last_aircraft_update = EconTime::CurDate();
}
/**
@ -250,9 +250,9 @@ void LinkGraph::Edge::Update(uint capacity, uint usage, uint32_t travel_time, Ed
}
edge.usage = std::max(edge.usage, usage);
}
if (mode & EUM_UNRESTRICTED) edge.last_unrestricted_update = _date;
if (mode & EUM_RESTRICTED) edge.last_restricted_update = _date;
if (mode & EUM_AIRCRAFT) edge.last_aircraft_update = _date;
if (mode & EUM_UNRESTRICTED) edge.last_unrestricted_update = EconTime::CurDate();
if (mode & EUM_RESTRICTED) edge.last_restricted_update = EconTime::CurDate();
if (mode & EUM_AIRCRAFT) edge.last_aircraft_update = EconTime::CurDate();
}
/**
@ -279,10 +279,10 @@ void AdjustLinkGraphStateTicksBase(StateTicksDelta delta)
void LinkGraphFixupLastCompressionAfterLoad()
{
/* last_compression was previously a Date, change it to a StateTicks */
for (LinkGraph *lg : LinkGraph::Iterate()) lg->last_compression = DateToStateTicks((Date)lg->last_compression.base());
for (LinkGraph *lg : LinkGraph::Iterate()) lg->last_compression = DateToStateTicks((EconTime::Date)lg->last_compression.base());
for (LinkGraphJob *lgj : LinkGraphJob::Iterate()) {
LinkGraph *lg = &(const_cast<LinkGraph &>(lgj->Graph()));
lg->last_compression = DateToStateTicks((Date)lg->last_compression.base());
lg->last_compression = DateToStateTicks((EconTime::Date)lg->last_compression.base());
}
}

@ -57,7 +57,7 @@ public:
uint demand; ///< Acceptance at the station.
StationID station; ///< Station ID.
TileIndex xy; ///< Location of the station referred to by the node.
Date last_update; ///< When the supply was last updated.
EconTime::Date last_update; ///< When the supply was last updated.
void Init(TileIndex xy = INVALID_TILE, StationID st = INVALID_STATION, uint demand = 0);
};
@ -71,18 +71,18 @@ public:
uint capacity; ///< Capacity of the link.
uint usage; ///< Usage of the link.
uint64_t travel_time_sum; ///< Sum of the travel times of the link, in ticks.
Date last_unrestricted_update; ///< When the unrestricted part of the link was last updated.
Date last_restricted_update; ///< When the restricted part of the link was last updated.
Date last_aircraft_update; ///< When aircraft capacity of the link was last updated.
EconTime::Date last_unrestricted_update; ///< When the unrestricted part of the link was last updated.
EconTime::Date last_restricted_update; ///< When the restricted part of the link was last updated.
EconTime::Date last_aircraft_update; ///< When aircraft capacity of the link was last updated.
void Init()
{
this->capacity = 0;
this->usage = 0;
this->travel_time_sum = 0;
this->last_unrestricted_update = INVALID_DATE;
this->last_restricted_update = INVALID_DATE;
this->last_aircraft_update = INVALID_DATE;
this->last_unrestricted_update = EconTime::INVALID_DATE;
this->last_restricted_update = EconTime::INVALID_DATE;
this->last_aircraft_update = EconTime::INVALID_DATE;
}
BaseEdge() { this->Init(); }
@ -130,25 +130,25 @@ public:
* Get the date of the last update to the edge's unrestricted capacity.
* @return Last update.
*/
Date LastUnrestrictedUpdate() const { return this->edge->last_unrestricted_update; }
EconTime::Date LastUnrestrictedUpdate() const { return this->edge->last_unrestricted_update; }
/**
* Get the date of the last update to the edge's restricted capacity.
* @return Last update.
*/
Date LastRestrictedUpdate() const { return this->edge->last_restricted_update; }
EconTime::Date LastRestrictedUpdate() const { return this->edge->last_restricted_update; }
/**
* Get the date of the last update to the edge's aircraft capacity.
* @return Last update.
*/
Date LastAircraftUpdate() const { return this->edge->last_aircraft_update; }
EconTime::Date LastAircraftUpdate() const { return this->edge->last_aircraft_update; }
/**
* Get the date of the last update to any part of the edge's capacity.
* @return Last update.
*/
Date LastUpdate() const { return std::max(this->edge->last_unrestricted_update, this->edge->last_restricted_update); }
EconTime::Date LastUpdate() const { return std::max(this->edge->last_unrestricted_update, this->edge->last_restricted_update); }
};
/**
@ -192,7 +192,7 @@ public:
* Get node's last update.
* @return Last update.
*/
Date LastUpdate() const { return this->node.last_update; }
EconTime::Date LastUpdate() const { return this->node.last_update; }
/**
* Get the location of the station associated with the node.
@ -219,9 +219,9 @@ public:
*/
Edge(BaseEdge &edge) : EdgeWrapper<BaseEdge>(edge) {}
void Update(uint capacity, uint usage, uint32_t time, EdgeUpdateMode mode);
void Restrict() { this->edge->last_unrestricted_update = INVALID_DATE; }
void Release() { this->edge->last_restricted_update = INVALID_DATE; }
void ClearAircraft() { this->edge->last_aircraft_update = INVALID_DATE; }
void Restrict() { this->edge->last_unrestricted_update = EconTime::INVALID_DATE; }
void Release() { this->edge->last_restricted_update = EconTime::INVALID_DATE; }
void ClearAircraft() { this->edge->last_aircraft_update = EconTime::INVALID_DATE; }
};
/**
@ -261,7 +261,7 @@ public:
void UpdateSupply(uint supply)
{
this->node.supply += supply;
this->node.last_update = _date;
this->node.last_update = EconTime::CurDate();
}
/**

@ -26,10 +26,10 @@ INSTANTIATE_POOL_METHODS(LinkGraphJob)
*/
/* static */ Path *Path::invalid_path = new Path(INVALID_NODE, true);
static DateTicks GetLinkGraphJobJoinDateTicks(uint duration_multiplier)
static EconTime::DateTicks GetLinkGraphJobJoinDateTicks(uint duration_multiplier)
{
DateTicksDelta ticks = (_settings_game.linkgraph.recalc_time * DAY_TICKS * duration_multiplier) / (SECONDS_PER_DAY * _settings_game.economy.day_length_factor);
return ticks + NowDateTicks();
return ticks + EconTime::CurDateTicks();
}
/**
@ -44,7 +44,7 @@ LinkGraphJob::LinkGraphJob(const LinkGraph &orig, uint duration_multiplier) :
link_graph(orig),
settings(_settings_game.linkgraph),
join_date_ticks(GetLinkGraphJobJoinDateTicks(duration_multiplier)),
start_date_ticks(NowDateTicks()),
start_date_ticks(EconTime::CurDateTicks()),
job_completed(false),
job_aborted(false)
{
@ -130,14 +130,14 @@ void LinkGraphJob::FinaliseJob()
LinkGraph::ConstEdge lg_edge = lg->GetConstEdge(edge.From(), edge.To());
if (st2 == nullptr || st2->goods[this->Cargo()].link_graph != this->link_graph.index ||
st2->goods[this->Cargo()].node != edge.To() ||
lg_edge.LastUpdate() == INVALID_DATE) {
lg_edge.LastUpdate() == EconTime::INVALID_DATE) {
/* Edge has been removed. Delete flows. */
StationIDStack erased = flows.DeleteFlows(to);
/* Delete old flows for source stations which have been deleted
* from the new flows. This avoids flow cycles between old and
* new flows. */
while (!erased.IsEmpty()) geflows.erase(erased.Pop());
} else if (lg_edge.LastUnrestrictedUpdate() == INVALID_DATE) {
} else if (lg_edge.LastUnrestrictedUpdate() == EconTime::INVALID_DATE) {
/* Edge is fully restricted. */
flows.RestrictFlows(to);
}
@ -242,7 +242,7 @@ void LinkGraphJob::Init()
distance_anno = calculate_distance();
}
if (edge.LastAircraftUpdate() != INVALID_DATE && aircraft_link_scale > 100) {
if (edge.LastAircraftUpdate() != EconTime::INVALID_DATE && aircraft_link_scale > 100) {
distance_anno *= aircraft_link_scale;
distance_anno /= 100;
}

@ -139,8 +139,8 @@ protected:
std::shared_ptr<LinkGraphJobGroup> group; ///< Job group thread the job is running in or nullptr if it's running in the main thread.
const LinkGraphSettings settings; ///< Copy of _settings_game.linkgraph at spawn time.
DateTicks join_date_ticks; ///< Date when the job is to be joined.
DateTicks start_date_ticks; ///< Date when the job was started.
EconTime::DateTicks join_date_ticks; ///< Date when the job is to be joined.
EconTime::DateTicks start_date_ticks; ///< Date when the job was started.
NodeAnnotationVector nodes; ///< Extra node data necessary for link graph calculation.
EdgeAnnotationVector edges; ///< Edge data necessary for link graph calculation.
std::atomic<bool> job_completed; ///< Is the job still running. This is accessed by multiple threads and reads may be stale.
@ -263,7 +263,7 @@ public:
* settings have to be brutally const-casted in order to populate them.
*/
LinkGraphJob() : settings(_settings_game.linkgraph),
join_date_ticks(INVALID_DATE_TICKS), start_date_ticks(INVALID_DATE_TICKS), job_completed(false), job_aborted(false) {}
join_date_ticks(EconTime::INVALID_DATE_TICKS), start_date_ticks(EconTime::INVALID_DATE_TICKS), job_completed(false), job_aborted(false) {}
LinkGraphJob(const LinkGraph &orig, uint duration_multiplier);
~LinkGraphJob();
@ -298,19 +298,19 @@ public:
* @param tick_offset Optional number of ticks to add to the current date
* @return True if job should be finished by now, false if not.
*/
inline bool IsScheduledToBeJoined(int tick_offset = 0) const { return this->join_date_ticks <= NowDateTicks() + tick_offset; }
inline bool IsScheduledToBeJoined(int tick_offset = 0) const { return this->join_date_ticks <= EconTime::CurDateTicks() + tick_offset; }
/**
* Get the date when the job should be finished.
* @return Join date.
*/
inline DateTicks JoinDateTicks() const { return join_date_ticks; }
inline EconTime::DateTicks JoinDateTicks() const { return join_date_ticks; }
/**
* Get the date when the job was started.
* @return Start date.
*/
inline DateTicks StartDateTicks() const { return start_date_ticks; }
inline EconTime::DateTicks StartDateTicks() const { return start_date_ticks; }
/**
* Change the start and join dates on date cheating.

@ -87,7 +87,7 @@ void LinkGraphSchedule::SpawnNext()
lg->index, lg->Size(), cost, duration_multiplier);
} else {
// find right place to insert
auto iter = std::upper_bound(this->running.begin(), this->running.end(), job->JoinDateTicks(), [](DateTicks a, const std::unique_ptr<LinkGraphJob> &b) {
auto iter = std::upper_bound(this->running.begin(), this->running.end(), job->JoinDateTicks(), [](EconTime::DateTicks a, const std::unique_ptr<LinkGraphJob> &b) {
return a < b->JoinDateTicks();
});
this->running.insert(iter, std::move(job));
@ -281,11 +281,11 @@ void LinkGraphJobGroup::JoinThread()
std::vector<LinkGraphJob *> bucket;
uint bucket_cost = 0;
DateTicks bucket_join_date = 0;
EconTime::DateTicks bucket_join_date = 0;
auto flush_bucket = [&]() {
if (!bucket_cost) return;
DEBUG(linkgraph, 2, "LinkGraphJobGroup::ExecuteJobSet: Creating Job Group: jobs: " PRINTF_SIZE ", cost: %u, join after: " OTTD_PRINTF64,
bucket.size(), bucket_cost, (bucket_join_date - NowDateTicks()).base());
bucket.size(), bucket_cost, (bucket_join_date - EconTime::CurDateTicks()).base());
auto group = std::make_shared<LinkGraphJobGroup>(constructor_token(), std::move(bucket));
group->SpawnThread();
bucket_cost = 0;
@ -318,12 +318,12 @@ void StateGameLoop_LinkGraphPauseControl()
if (!LinkGraphSchedule::instance.IsJoinWithUnfinishedJobDue()) {
DoCommandP(0, PM_PAUSED_LINK_GRAPH, 0, CMD_PAUSE);
}
} else if (_pause_mode == PM_UNPAUSED && _tick_skip_counter == 0) {
} else if (_pause_mode == PM_UNPAUSED && TickSkipCounter() == 0) {
if (DayLengthFactor() == 1) {
if (_date_fract != LinkGraphSchedule::SPAWN_JOIN_TICK - 2) return;
if (_date.base() % _settings_game.linkgraph.recalc_interval != (_settings_game.linkgraph.recalc_interval / SECONDS_PER_DAY) / 2) return;
if (EconTime::CurDateFract() != LinkGraphSchedule::SPAWN_JOIN_TICK - 2) return;
if (EconTime::CurDate().base() % _settings_game.linkgraph.recalc_interval != (_settings_game.linkgraph.recalc_interval / SECONDS_PER_DAY) / 2) return;
} else {
int date_ticks = (NowDateTicks() - (LinkGraphSchedule::SPAWN_JOIN_TICK - 2)).base();
int date_ticks = (EconTime::CurDateTicks() - (LinkGraphSchedule::SPAWN_JOIN_TICK - 2)).base();
int interval = std::max<int>(2, (_settings_game.linkgraph.recalc_interval * DAY_TICKS / (SECONDS_PER_DAY * DayLengthFactor())));
if (date_ticks % interval != interval / 2) return;
}
@ -356,12 +356,12 @@ void OnTick_LinkGraph()
int offset;
int interval;
if (DayLengthFactor() == 1) {
if (_date_fract != LinkGraphSchedule::SPAWN_JOIN_TICK) return;
if (EconTime::CurDateFract() != LinkGraphSchedule::SPAWN_JOIN_TICK) return;
interval = _settings_game.linkgraph.recalc_interval / SECONDS_PER_DAY;
offset = _date.base() % interval;
offset = EconTime::CurDate().base() % interval;
} else {
interval = std::max<int>(2, (_settings_game.linkgraph.recalc_interval * DAY_TICKS / (SECONDS_PER_DAY * DayLengthFactor())));
offset = (NowDateTicks() - LinkGraphSchedule::SPAWN_JOIN_TICK).base() % interval;
offset = (EconTime::CurDateTicks() - LinkGraphSchedule::SPAWN_JOIN_TICK).base() % interval;
}
if (offset == 0) {
LinkGraphSchedule::instance.SpawnNext();

@ -31,7 +31,7 @@ struct LoadCheckData {
std::string error_msg; ///< Data to pass to SetDParamStr when displaying #error.
uint32_t map_size_x, map_size_y;
Date current_date;
CalTime::Date current_date;
GameSettings settings;

@ -129,11 +129,12 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin
_pause_mode = PM_UNPAUSED;
_pause_countdown = 0;
_game_speed = 100;
CalTime::Detail::now.sub_date_fract = 0;
_tick_counter = 0;
_tick_skip_counter = 0;
DateDetail::_tick_skip_counter = 0;
_scaled_tick_counter = 0;
_state_ticks = INITIAL_STATE_TICKS_VALUE;
_state_ticks_offset = 0;
DateDetail::_state_ticks_offset = 0;
_cur_tileloop_tile = 1;
_aux_tileloop_tile = 1;
_thd.redsq = INVALID_TILE;
@ -156,7 +157,10 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin
_newgrf_profilers.clear();
if (reset_date) {
SetDate(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1), 0);
CalTime::Detail::SetDate(CalTime::ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1), 0);
{
EconTime::Detail::SetDate(CalTime::CurDate().base(), 0);
}
InitializeOldNames();
} else {
RecalculateStateTicksOffset();

@ -156,7 +156,7 @@ public:
/* Because build_date is not set yet in every TileDesc, we make sure it is empty */
TileDesc td;
td.build_date = INVALID_DATE;
td.build_date = CalTime::INVALID_DATE;
/* Most tiles have only one owner, but
* - drivethrough roadstops can be build on town owned roads (up to 2 owners) and
@ -247,7 +247,7 @@ public:
this->landinfo_data.push_back(GetString(STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY));
/* Build date */
if (td.build_date != INVALID_DATE) {
if (td.build_date != CalTime::INVALID_DATE) {
SetDParam(0, td.build_date);
this->landinfo_data.push_back(GetString(STR_LAND_AREA_INFORMATION_BUILD_DATE));
}

@ -131,7 +131,7 @@ void CheckGameCompatibility(NetworkGameInfo &ngi, bool extended)
void FillStaticNetworkServerGameInfo()
{
_network_game_info.use_password = !_settings_client.network.server_password.empty();
_network_game_info.start_date = ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1);
_network_game_info.start_date = CalTime::ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1);
_network_game_info.clients_max = _settings_client.network.max_clients;
_network_game_info.companies_max = _settings_client.network.max_companies;
_network_game_info.map_width = MapSizeX();
@ -157,7 +157,7 @@ const NetworkServerGameInfo *GetCurrentNetworkServerGameInfo()
*/
_network_game_info.companies_on = (byte)Company::GetNumItems();
_network_game_info.spectators_on = NetworkSpectatorCount();
_network_game_info.game_date = _date;
_network_game_info.game_date = CalTime::CurDate();
_network_game_info.ticks_playing = _scaled_tick_counter;
return &_network_game_info;
}
@ -336,7 +336,7 @@ void SerializeNetworkGameInfoExtended(Packet *p, const NetworkServerGameInfo *in
*/
void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info, const GameInfoNewGRFLookupTable *newgrf_lookup_table)
{
static const Date MAX_DATE = ConvertYMDToDate(MAX_YEAR, 11, 31); // December is month 11
static const CalTime::Date MAX_DATE = CalTime::ConvertYMDToDate(CalTime::MAX_YEAR, 11, 31); // December is month 11
byte game_info_version = p->Recv_uint8();
NewGRFSerializationType newgrf_serialisation = NST_GRFID_MD5;
@ -427,8 +427,8 @@ void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info, const GameInfo
info->clients_on = p->Recv_uint8 ();
info->spectators_on = p->Recv_uint8 ();
if (game_info_version < 3) { // 16 bits dates got scrapped and are read earlier
info->game_date = p->Recv_uint16() + DAYS_TILL_ORIGINAL_BASE_YEAR;
info->start_date = p->Recv_uint16() + DAYS_TILL_ORIGINAL_BASE_YEAR;
info->game_date = p->Recv_uint16() + CalTime::DAYS_TILL_ORIGINAL_BASE_YEAR;
info->start_date = p->Recv_uint16() + CalTime::DAYS_TILL_ORIGINAL_BASE_YEAR;
}
if (game_info_version < 6) while (p->Recv_uint8() != 0) {} // Used to contain the map-name.
@ -456,7 +456,7 @@ void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info, const GameInfo
*/
void DeserializeNetworkGameInfoExtended(Packet *p, NetworkGameInfo *info)
{
static const Date MAX_DATE = ConvertYMDToDate(MAX_YEAR, 11, 31); // December is month 11
static const CalTime::Date MAX_DATE = CalTime::ConvertYMDToDate(CalTime::MAX_YEAR, 11, 31); // December is month 11
const uint8_t version = p->Recv_uint8();
if (version > SERVER_GAME_INFO_EXTENDED_MAX_VERSION) return; // Unknown version

@ -94,8 +94,8 @@ enum NewGRFSerializationType {
*/
struct NetworkServerGameInfo {
GRFConfig *grfconfig; ///< List of NewGRF files used
Date start_date; ///< When the game started
Date game_date; ///< Current date
CalTime::Date start_date; ///< When the game started
CalTime::Date game_date; ///< Current date
uint64_t ticks_playing; ///< Amount of ticks the game has been running unpaused.
uint32_t map_width; ///< Map width
uint32_t map_height; ///< Map height

@ -87,8 +87,8 @@ NetworkAddressList _broadcast_list; ///< List of broadcast a
uint32_t _sync_seed_1; ///< Seed to compare during sync checks.
uint64_t _sync_state_checksum; ///< State checksum to compare during sync checks.
uint32_t _sync_frame; ///< The frame to perform the sync check.
Date _last_sync_date; ///< The game date of the last successfully received sync frame
DateFract _last_sync_date_fract; ///< "
EconTime::Date _last_sync_date; ///< The game date of the last successfully received sync frame
EconTime::DateFract _last_sync_date_fract; ///< "
uint8_t _last_sync_tick_skip_counter; ///< "
uint32_t _last_sync_frame_counter; ///< "
bool _network_first_time; ///< Whether we have finished joining or not.
@ -1160,19 +1160,19 @@ void NetworkGameLoop()
if (_network_server) {
/* Log the sync state to check for in-syncedness of replays. */
if (_date_fract == 0 && _tick_skip_counter == 0) {
if (EconTime::CurDateFract() == 0 && TickSkipCounter() == 0) {
/* We don't want to log multiple times if paused. */
static Date last_log;
if (last_log != _date) {
static EconTime::Date last_log;
if (last_log != EconTime::CurDate()) {
DEBUG(desync, 2, "sync: %s; %08x; %08x", debug_date_dumper().HexDate(), _random.state[0], _random.state[1]);
last_log = _date;
last_log = EconTime::CurDate();
}
}
#ifdef DEBUG_DUMP_COMMANDS
/* Loading of the debug commands from -ddesync>=1 */
static FILE *f = FioFOpenFile("commands.log", "rb", SAVE_DIR);
static Date next_date = 0;
static EconTime::Date next_date = 0;
static uint next_date_fract;
static uint next_tick_skip_counter;
static std::unique_ptr<CommandPacket> cp;
@ -1184,7 +1184,7 @@ void NetworkGameLoop()
}
while (f != nullptr && !feof(f)) {
if (_date == next_date && _date_fract == next_date_fract) {
if (EconTime::CurDate() == next_date && EconTime::CurDateFract() == next_date_fract) {
if (cp != nullptr) {
NetworkSendCommand(cp->tile, cp->p1, cp->p2, cp->p3, cp->cmd & ~CMD_FLAGS_MASK, nullptr, cp->text.c_str(), cp->company, cp->aux_data.get());
DEBUG(net, 0, "injecting: %s; %02x; %06x; %08x; %08x; " OTTD_PRINTFHEX64PAD " %08x; \"%s\"%s (%s)",

@ -179,7 +179,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendWelcome()
p->Send_string(""); // Used to be map-name.
p->Send_uint32(_settings_game.game_creation.generation_seed);
p->Send_uint8 (_settings_game.game_creation.landscape);
p->Send_uint32(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1).base());
p->Send_uint32(CalTime::ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1).base());
p->Send_uint16(MapSizeX());
p->Send_uint16(MapSizeY());
@ -209,7 +209,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendDate()
{
Packet *p = new Packet(ADMIN_PACKET_SERVER_DATE);
p->Send_uint32(_date.base());
p->Send_uint32(CalTime::CurDate().base());
this->SendPacket(p);
return NETWORK_RECV_STATUS_OKAY;
@ -330,7 +330,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyInfo(const Company
p->Send_string(GetString(STR_PRESIDENT_NAME));
p->Send_uint8 (c->colour);
p->Send_bool (NetworkCompanyIsPassworded(c->index));
p->Send_uint32(c->inaugurated_year);
p->Send_uint32(c->inaugurated_year.base());
p->Send_bool (c->is_ai);
p->Send_uint8 (CeilDiv(c->months_of_bankruptcy, 3)); // send as quarters_of_bankruptcy

@ -25,8 +25,8 @@ struct NetworkClientInfo : NetworkClientInfoPool::PoolItem<&_networkclientinfo_p
ClientID client_id; ///< Client identifier (same as ClientState->client_id)
std::string client_name; ///< Name of the client
CompanyID client_playas; ///< As which company is this client playing (CompanyID)
Date join_date; ///< Gamedate the client has joined
DateFract join_date_fract;
EconTime::Date join_date; ///< Gamedate the client has joined
EconTime::DateFract join_date_fract;
uint8_t join_tick_skip_counter;
uint32_t join_frame;

@ -347,9 +347,9 @@ void ClientNetworkGameSocketHandler::ClientError(NetworkRecvStatus res)
CrashLog::WriteDesyncSavegame(desync_log.c_str(), deferred_save.name_buffer.c_str());
return false;
}
_last_sync_date = _date;
_last_sync_date_fract = _date_fract;
_last_sync_tick_skip_counter = _tick_skip_counter;
_last_sync_date = EconTime::CurDate();
_last_sync_date_fract = EconTime::CurDateFract();
_last_sync_tick_skip_counter = TickSkipCounter();
_last_sync_frame_counter = _sync_frame;
_network_sync_records.clear();
_network_sync_record_counts.clear();
@ -636,9 +636,9 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendDesyncLog(const std::strin
NetworkRecvStatus ClientNetworkGameSocketHandler::SendDesyncMessage(const char *msg)
{
Packet *p = new Packet(PACKET_CLIENT_DESYNC_MSG, SHRT_MAX);
p->Send_uint32(_date.base());
p->Send_uint16(_date_fract);
p->Send_uint8(_tick_skip_counter);
p->Send_uint32(EconTime::CurDate().base());
p->Send_uint16(EconTime::CurDateFract());
p->Send_uint8(TickSkipCounter());
p->Send_string(msg);
my_client->SendPacket(p);
return NETWORK_RECV_STATUS_OKAY;

@ -70,9 +70,10 @@ void NetworkPrintClients();
void NetworkHandlePauseChange(PauseMode prev_mode, PauseMode changed_mode);
/*** Commands ran by the server ***/
void NetworkServerDailyLoop();
void NetworkServerMonthlyLoop();
void NetworkServerYearlyLoop();
void NetworkServerEconomyDailyLoop();
void NetworkServerEconomyMonthlyLoop();
void NetworkServerEconomyYearlyLoop();
void NetworkServerCalendarYearlyLoop();
void NetworkServerSendConfigUpdate();
void NetworkServerUpdateGameInfo();
void NetworkServerShowStatusToConsole();

@ -397,7 +397,7 @@ protected:
if (const NWidgetBase *nwid = this->GetWidget<NWidgetBase>(WID_NG_DATE); nwid->current_x != 0) {
/* current date */
Rect date = nwid->GetCurrentRect();
YearMonthDay ymd = ConvertDateToYMD(cur_item->info.game_date);
CalTime::YearMonthDay ymd = CalTime::ConvertDateToYMD(cur_item->info.game_date);
SetDParam(0, ymd.year);
DrawString(date.left, date.right, y + text_y_offset, STR_JUST_INT, TC_BLACK, SA_HOR_CENTER);
}
@ -405,8 +405,8 @@ protected:
if (const NWidgetBase *nwid = this->GetWidget<NWidgetBase>(WID_NG_YEARS); nwid->current_x != 0) {
/* number of years the game is running */
Rect years = nwid->GetCurrentRect();
YearMonthDay ymd_cur = ConvertDateToYMD(cur_item->info.game_date);
YearMonthDay ymd_start = ConvertDateToYMD(cur_item->info.start_date);
CalTime::YearMonthDay ymd_cur = CalTime::ConvertDateToYMD(cur_item->info.game_date);
CalTime::YearMonthDay ymd_start = CalTime::ConvertDateToYMD(cur_item->info.start_date);
SetDParam(0, ymd_cur.year - ymd_start.year);
DrawString(years.left, years.right, y + text_y_offset, STR_JUST_INT, TC_BLACK, SA_HOR_CENTER);
}

@ -31,7 +31,7 @@ void ShowSurveyResultTextfileWindow();
/** Company information stored at the client side */
struct NetworkCompanyInfo : NetworkCompanyStats {
std::string company_name; ///< Company name
Year inaugurated_year; ///< What year the company started in
CalTime::Year inaugurated_year; ///< What year the company started in
Money company_value; ///< The company value
Money money; ///< The amount of money the company has
Money income; ///< How much did the company earn last year

@ -76,10 +76,10 @@ extern NetworkAddressList _broadcast_list;
extern uint32_t _sync_seed_1;
extern uint64_t _sync_state_checksum;
extern uint32_t _sync_frame;
extern Date _last_sync_date;
extern DateFract _last_sync_date_fract;
extern uint8_t _last_sync_tick_skip_counter;
extern uint32_t _last_sync_frame_counter;
extern EconTime::Date _last_sync_date;
extern EconTime::DateFract _last_sync_date_fract;
extern uint8_t _last_sync_tick_skip_counter;
extern uint32_t _last_sync_frame_counter;
extern bool _network_first_time;
/* Vars needed for the join-GUI */
extern NetworkJoinStatus _network_join_status;

@ -1017,9 +1017,9 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_JOIN(Packet *p)
assert(NetworkClientInfo::CanAllocateItem());
NetworkClientInfo *ci = new NetworkClientInfo(this->client_id);
this->SetInfo(ci);
ci->join_date = _date;
ci->join_date_fract = _date_fract;
ci->join_tick_skip_counter = _tick_skip_counter;
ci->join_date = EconTime::CurDate();
ci->join_date_fract = EconTime::CurDateFract();
ci->join_tick_skip_counter = TickSkipCounter();
ci->join_frame = _frame_counter;
ci->client_name = client_name;
ci->client_playas = playas;
@ -1322,13 +1322,13 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_DESYNC_LOG(Pack
NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_DESYNC_MSG(Packet *p)
{
Date date = p->Recv_uint32();
DateFract date_fract = p->Recv_uint16();
EconTime::Date date = p->Recv_uint32();
EconTime::DateFract date_fract = p->Recv_uint16();
uint8_t tick_skip_counter = p->Recv_uint8();
std::string msg;
p->Recv_string(msg);
DEBUG(desync, 0, "Client-id %d desync msg: %s", this->client_id, msg.c_str());
extern void LogRemoteDesyncMsg(Date date, DateFract date_fract, uint8_t tick_skip_counter, uint32_t src_id, std::string msg);
extern void LogRemoteDesyncMsg(EconTime::Date date, EconTime::DateFract date_fract, uint8_t tick_skip_counter, uint32_t src_id, std::string msg);
LogRemoteDesyncMsg(date, date_fract, tick_skip_counter, this->client_id, std::move(msg));
return NETWORK_RECV_STATUS_OKAY;
}
@ -1829,8 +1829,8 @@ void NetworkUpdateClientInfo(ClientID client_id)
/** Check if we want to restart the map */
static void NetworkCheckRestartMap()
{
if (_settings_client.network.restart_game_year != 0 && _cur_year >= _settings_client.network.restart_game_year) {
DEBUG(net, 3, "Auto-restarting map: year %d reached", _cur_year);
if (_settings_client.network.restart_game_year != 0 && CalTime::CurYear() >= _settings_client.network.restart_game_year) {
DEBUG(net, 3, "Auto-restarting map: year %d reached", CalTime::CurYear().base());
_settings_newgame.game_creation.generation_seed = GENERATE_NEW_SEED;
switch(_file_to_saveload.abstract_ftype) {
@ -2149,25 +2149,30 @@ void NetworkServer_Tick(bool send_frame)
}
/** Yearly "callback". Called whenever the year changes. */
void NetworkServerYearlyLoop()
void NetworkServerCalendarYearlyLoop()
{
NetworkCheckRestartMap();
}
/** Yearly "callback". Called whenever the year changes. */
void NetworkServerEconomyYearlyLoop()
{
NetworkAdminUpdate(ADMIN_FREQUENCY_ANUALLY);
}
/** Monthly "callback". Called whenever the month changes. */
void NetworkServerMonthlyLoop()
void NetworkServerEconomyMonthlyLoop()
{
NetworkAutoCleanCompanies();
NetworkAdminUpdate(ADMIN_FREQUENCY_MONTHLY);
if ((_cur_date_ymd.month % 3) == 0) NetworkAdminUpdate(ADMIN_FREQUENCY_QUARTERLY);
if ((CalTime::CurMonth() % 3) == 0) NetworkAdminUpdate(ADMIN_FREQUENCY_QUARTERLY);
}
/** Daily "callback". Called whenever the date changes. */
void NetworkServerDailyLoop()
void NetworkServerEconomyDailyLoop()
{
NetworkAdminUpdate(ADMIN_FREQUENCY_DAILY);
if ((_date.base() % 7) == 3) NetworkAdminUpdate(ADMIN_FREQUENCY_WEEKLY);
if ((CalTime::CurDate().base() % 7) == 3) NetworkAdminUpdate(ADMIN_FREQUENCY_WEEKLY);
}
/**
@ -2458,9 +2463,9 @@ char *NetworkServerDumpClients(char *buffer, const char *last)
ci->client_name.c_str(),
ci->client_playas);
if (ci->join_date != 0) {
YearMonthDay ymd = ConvertDateToYMD(ci->join_date);
EconTime::YearMonthDay ymd = EconTime::ConvertDateToYMD(ci->join_date);
buffer += seprintf(buffer, last, ", joined: %4i-%02i-%02i, %i, %i, frame: %08X",
ymd.year, ymd.month + 1, ymd.day, ci->join_date_fract, ci->join_tick_skip_counter, ci->join_frame);
ymd.year.base(), ymd.month + 1, ymd.day, ci->join_date_fract, ci->join_tick_skip_counter, ci->join_frame);
}
buffer += seprintf(buffer, last, "\n");
}

@ -950,7 +950,7 @@ static ChangeInfoResult CommonVehicleChangeInfo(EngineInfo *ei, int prop, const
{
switch (prop) {
case 0x00: // Introduction date
ei->base_intro = buf->ReadWord() + DAYS_TILL_ORIGINAL_BASE_YEAR;
ei->base_intro = buf->ReadWord() + CalTime::DAYS_TILL_ORIGINAL_BASE_YEAR;
break;
case 0x02: // Decay speed
@ -2166,7 +2166,7 @@ static ChangeInfoResult BridgeChangeInfo(uint brid, int numinfo, int prop, const
case 0x08: { // Year of availability
/* We treat '0' as always available */
byte year = buf->ReadByte();
bridge->avail_year = (year > 0 ? ORIGINAL_BASE_YEAR + year : 0);
bridge->avail_year = (year > 0 ? CalTime::ORIGINAL_BASE_YEAR + year : 0);
break;
}
@ -2227,7 +2227,7 @@ static ChangeInfoResult BridgeChangeInfo(uint brid, int numinfo, int prop, const
break;
case 0x0F: // Long format year of availability (year since year 0)
bridge->avail_year = Clamp(buf->ReadDWord(), MIN_YEAR, MAX_YEAR);
bridge->avail_year = Clamp<CalTime::Year>(buf->ReadDWord(), CalTime::MIN_YEAR, CalTime::MAX_YEAR);
break;
case 0x10: { // purchase string
@ -2426,8 +2426,8 @@ static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, con
case 0x0A: { // Availability years
uint16_t years = buf->ReadWord();
housespec->min_year = GB(years, 0, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 0, 8);
housespec->max_year = GB(years, 8, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 8, 8);
housespec->min_year = GB(years, 0, 8) > 150 ? CalTime::MAX_YEAR : CalTime::ORIGINAL_BASE_YEAR + GB(years, 0, 8);
housespec->max_year = GB(years, 8, 8) > 150 ? CalTime::MAX_YEAR : CalTime::ORIGINAL_BASE_YEAR + GB(years, 8, 8);
break;
}
@ -2764,7 +2764,7 @@ static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, co
case 0x0F: { // Euro introduction dates
uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
Year year_euro = buf->ReadWord();
CalTime::Year year_euro = buf->ReadWord();
if (curidx < CURRENCY_END) {
_currency_specs[curidx].to_euro = year_euro;
@ -4033,7 +4033,7 @@ static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, c
case 0x0C:
as->min_year = buf->ReadWord();
as->max_year = buf->ReadWord();
if (as->max_year == 0xFFFF) as->max_year = MAX_YEAR;
if (as->max_year == 0xFFFF) as->max_year = CalTime::MAX_YEAR;
break;
case 0x0D:
@ -7404,16 +7404,16 @@ bool GetGlobalVariable(byte param, uint32_t *value, const GRFFile *grffile)
switch (param) {
case 0x00: // current date
*value = std::max<DateDelta>(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0).base();
*value = std::max<DateDelta>(CalTime::CurDate() - CalTime::DAYS_TILL_ORIGINAL_BASE_YEAR, 0).base();
return true;
case 0x01: // current year
*value = Clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR;
*value = (Clamp(CalTime::CurYear(), CalTime::ORIGINAL_BASE_YEAR, CalTime::ORIGINAL_MAX_YEAR) - CalTime::ORIGINAL_BASE_YEAR).base();
return true;
case 0x02: { // detailed date information: month of year (bit 0-7), day of month (bit 8-12), leap year (bit 15), day of year (bit 16-24)
Date start_of_year = ConvertYMDToDate(_cur_date_ymd.year, 0, 1);
*value = _cur_date_ymd.month | (_cur_date_ymd.day - 1) << 8 | (IsLeapYear(_cur_date_ymd.year) ? 1 << 15 : 0) | (_date - start_of_year).base() << 16;
CalTime::Date start_of_year = CalTime::ConvertYMDToDate(CalTime::CurYear(), 0, 1);
*value = CalTime::CurMonth() | (CalTime::CurDay() - 1) << 8 | (CalTime::IsLeapYear(CalTime::CurYear()) ? 1 << 15 : 0) | (CalTime::CurDate() - start_of_year).base() << 16;
return true;
}
@ -7426,7 +7426,7 @@ bool GetGlobalVariable(byte param, uint32_t *value, const GRFFile *grffile)
return true;
case 0x09: // date fraction
*value = _date_fract * 885;
*value = CalTime::CurDateFract() * 885;
return true;
case 0x0A: // animation counter
@ -7519,11 +7519,11 @@ bool GetGlobalVariable(byte param, uint32_t *value, const GRFFile *grffile)
return true;
case 0x23: // long format date
*value = _date.base();
*value = CalTime::CurDate().base();
return true;
case 0x24: // long format year
*value = _cur_year;
*value = CalTime::CurYear().base();
return true;
default: return false;
@ -8137,7 +8137,7 @@ static uint32_t GetPatchVariable(uint8_t param)
{
switch (param) {
/* start year - 1920 */
case 0x0B: return std::max(_settings_game.game_creation.starting_year, ORIGINAL_BASE_YEAR) - ORIGINAL_BASE_YEAR;
case 0x0B: return (std::max(_settings_game.game_creation.starting_year, CalTime::ORIGINAL_BASE_YEAR) - CalTime::ORIGINAL_BASE_YEAR).base();
/* freight trains weight factor */
case 0x0E: return _settings_game.vehicle.freight_trains;
@ -10896,7 +10896,7 @@ static bool IsHouseSpecValid(HouseSpec *hs, const HouseSpec *next1, const HouseS
*/
static void EnsureEarlyHouse(HouseZones bitmask)
{
Year min_year = MAX_YEAR;
CalTime::Year min_year = CalTime::MAX_YEAR;
for (int i = 0; i < NUM_HOUSES; i++) {
HouseSpec *hs = HouseSpec::Get(i);
@ -11600,22 +11600,19 @@ void LoadNewGRF(uint load_index, uint num_baseset)
* so all NewGRFs are loaded equally. For this we use the
* start date of the game and we set the counters, etc. to
* 0 so they're the same too. */
YearMonthDay date_ymd = _cur_date_ymd;
Date date = _date;
DateFract date_fract = _date_fract;
uint64_t tick_counter = _tick_counter;
uint8_t tick_skip_counter = _tick_skip_counter;
CalTime::State cal_state = CalTime::Detail::now;
EconTime::State econ_state = EconTime::Detail::now;
uint8_t tick_skip_counter = DateDetail::_tick_skip_counter;
uint64_t tick_counter = _tick_counter;
uint64_t scaled_tick_counter = _scaled_tick_counter;
StateTicks state_ticks = _state_ticks;
StateTicksDelta state_ticks_offset = _state_ticks_offset;
byte display_opt = _display_opt;
StateTicksDelta state_ticks_offset = DateDetail::_state_ticks_offset;
byte display_opt = _display_opt;
if (_networking) {
_cur_date_ymd = { _settings_game.game_creation.starting_year, 0, 1};
_date = ConvertYMDToDate(_cur_date_ymd);
_date_fract = 0;
CalTime::Detail::now = CalTime::Detail::NewState(_settings_game.game_creation.starting_year);
EconTime::Detail::now = EconTime::Detail::NewState(_settings_game.game_creation.starting_year.base());
_tick_counter = 0;
_tick_skip_counter = 0;
_scaled_tick_counter = 0;
_state_ticks = 0;
_display_opt = 0;
@ -11718,14 +11715,13 @@ void LoadNewGRF(uint load_index, uint num_baseset)
AfterLoadGRFs();
/* Now revert back to the original situation */
_cur_date_ymd = date_ymd;
_date = date;
_date_fract = date_fract;
CalTime::Detail::now = cal_state;
EconTime::Detail::now = econ_state;
DateDetail::_tick_skip_counter = tick_skip_counter;
_tick_counter = tick_counter;
_tick_skip_counter = tick_skip_counter;
_scaled_tick_counter = scaled_tick_counter;
_state_ticks = state_ticks;
_state_ticks_offset = state_ticks_offset;
DateDetail::_state_ticks_offset = state_ticks_offset;
_display_opt = display_opt;
UpdateCachedSnowLine();
}

@ -81,9 +81,9 @@ AirportSpec AirportSpec::specs[NUM_AIRPORTS]; ///< Airport specifications.
bool AirportSpec::IsAvailable() const
{
if (!this->enabled) return false;
if (_cur_year < this->min_year) return false;
if (CalTime::CurYear() < this->min_year) return false;
if (_settings_game.station.never_expire_airports) return true;
return _cur_year <= this->max_year;
return CalTime::CurYear() <= this->max_year;
}
/**
@ -169,7 +169,7 @@ void AirportOverrideManager::SetEntitySpec(AirportSpec *as)
case 0x7C: return (this->st->airport.psa != nullptr) ? this->st->airport.psa->GetValue(parameter) : 0;
case 0xF0: return this->st->facilities;
case 0xFA: return ClampTo<uint16_t>((this->st->build_date - DAYS_TILL_ORIGINAL_BASE_YEAR).base());
case 0xFA: return ClampTo<uint16_t>((this->st->build_date - CalTime::DAYS_TILL_ORIGINAL_BASE_YEAR).base());
}
return this->st->GetNewGRFVariable(this->ro, variable, parameter, &(extra->available));

@ -108,8 +108,8 @@ struct AirportSpec {
byte size_y; ///< size of airport in y direction
byte noise_level; ///< noise that this airport generates
byte catchment; ///< catchment area of this airport
Year min_year; ///< first year the airport is available
Year max_year; ///< last year the airport is available
CalTime::Year min_year; ///< first year the airport is available
CalTime::Year max_year; ///< last year the airport is available
StringID name; ///< name of this airport
TTDPAirportType ttd_airport_type; ///< ttdpatch airport type (Small/Large/Helipad/Oilrig)
AirportClassID cls_id; ///< the class to which this airport type belongs

@ -700,7 +700,7 @@ static uint32_t VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *objec
}
case 0x48: return v->GetEngine()->flags; // Vehicle Type Info
case 0x49: return v->build_year;
case 0x49: return v->build_year.base();
case 0x4A:
switch (v->type) {
@ -912,8 +912,8 @@ static uint32_t VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *objec
}
return (variable - 0x80) == 0x10 ? ticks : GB(ticks, 8, 8);
}
case 0x12: return ClampTo<uint16_t>(v->date_of_last_service_newgrf - DAYS_TILL_ORIGINAL_BASE_YEAR);
case 0x13: return GB(ClampTo<uint16_t>(v->date_of_last_service_newgrf - DAYS_TILL_ORIGINAL_BASE_YEAR), 8, 8);
case 0x12: return ClampTo<uint16_t>(v->date_of_last_service_newgrf - CalTime::DAYS_TILL_ORIGINAL_BASE_YEAR);
case 0x13: return GB(ClampTo<uint16_t>(v->date_of_last_service_newgrf - CalTime::DAYS_TILL_ORIGINAL_BASE_YEAR), 8, 8);
case 0x14: return v->GetServiceInterval();
case 0x15: return GB(v->GetServiceInterval(), 8, 8);
case 0x16: return v->last_station_visited;
@ -974,7 +974,7 @@ static uint32_t VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *objec
case 0x41: return GB(ClampTo<uint16_t>(v->age), 8, 8);
case 0x42: return ClampTo<uint16_t>(v->max_age);
case 0x43: return GB(ClampTo<uint16_t>(v->max_age), 8, 8);
case 0x44: return Clamp(v->build_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR;
case 0x44: return (Clamp(v->build_year, CalTime::ORIGINAL_BASE_YEAR, CalTime::ORIGINAL_MAX_YEAR) - CalTime::ORIGINAL_BASE_YEAR).base();
case 0x45: return v->unitnumber;
case 0x46: return v->GetEngine()->grf_prop.local_id;
case 0x47: return GB(v->GetEngine()->grf_prop.local_id, 8, 8);
@ -1117,11 +1117,11 @@ static uint32_t VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *objec
}
}
case 0x48: return Engine::Get(this->self_type)->flags; // Vehicle Type Info
case 0x49: return _cur_year; // 'Long' format build year
case 0x4B: return _date.base(); // Long date of last service
case 0x92: return ClampTo<uint16_t>(_date - DAYS_TILL_ORIGINAL_BASE_YEAR); // Date of last service
case 0x93: return GB(ClampTo<uint16_t>(_date - DAYS_TILL_ORIGINAL_BASE_YEAR), 8, 8);
case 0xC4: return Clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR; // Build year
case 0x49: return CalTime::CurYear().base(); // 'Long' format build year
case 0x4B: return CalTime::CurDate().base(); // Long date of last service
case 0x92: return ClampTo<uint16_t>(CalTime::CurDate() - CalTime::DAYS_TILL_ORIGINAL_BASE_YEAR); // Date of last service
case 0x93: return GB(ClampTo<uint16_t>(CalTime::CurDate() - CalTime::DAYS_TILL_ORIGINAL_BASE_YEAR), 8, 8);
case 0xC4: return (Clamp(CalTime::CurYear(), CalTime::ORIGINAL_BASE_YEAR, CalTime::ORIGINAL_MAX_YEAR) - CalTime::ORIGINAL_BASE_YEAR).base(); // Build year
case 0xC6: return Engine::Get(this->self_type)->grf_prop.local_id;
case 0xC7: return GB(Engine::Get(this->self_type)->grf_prop.local_id, 8, 8);
case 0xDA: return INVALID_VEHICLE; // Next vehicle

@ -334,7 +334,7 @@ static uint32_t GetDistanceFromNearbyHouse(uint8_t parameter, TileIndex tile, Ho
case 0x40: return (IsTileType(this->tile, MP_HOUSE) ? GetHouseBuildingStage(this->tile) : 0) | TileHash2Bit(TileX(this->tile), TileY(this->tile)) << 2;
/* Building age. */
case 0x41: return IsTileType(this->tile, MP_HOUSE) ? GetHouseAge(this->tile) : 0;
case 0x41: return IsTileType(this->tile, MP_HOUSE) ? GetHouseAge(this->tile).base() : 0;
/* Town zone */
case 0x42: return GetTownRadiusGroup(this->town, this->tile);

@ -422,16 +422,16 @@ uint32_t IndustriesScopeResolver::GetCountAndDistanceOfClosestInstance(byte para
case 0xA6: return indspec->grf_prop.local_id;
case 0xA7: return this->industry->founder;
case 0xA8: return this->industry->random_colour;
case 0xA9: return ClampTo<uint8_t>(this->industry->last_prod_year - ORIGINAL_BASE_YEAR);
case 0xA9: return ClampTo<uint8_t>(this->industry->last_prod_year - EconTime::ORIGINAL_BASE_YEAR);
case 0xAA: return this->industry->counter;
case 0xAB: return GB(this->industry->counter, 8, 8);
case 0xAC: return this->industry->was_cargo_delivered;
case 0xB0: return ClampTo<uint16_t>(this->industry->construction_date - DAYS_TILL_ORIGINAL_BASE_YEAR); // Date when built since 1920 (in days)
case 0xB0: return ClampTo<uint16_t>(this->industry->construction_date - CalTime::DAYS_TILL_ORIGINAL_BASE_YEAR); // Date when built since 1920 (in days)
case 0xB3: return this->industry->construction_type; // Construction type
case 0xB4: {
Date *latest = std::max_element(this->industry->last_cargo_accepted_at, endof(this->industry->last_cargo_accepted_at));
return ClampTo<uint16_t>((*latest) - DAYS_TILL_ORIGINAL_BASE_YEAR); // Date last cargo accepted since 1920 (in days)
EconTime::Date *latest = std::max_element(this->industry->last_cargo_accepted_at, endof(this->industry->last_cargo_accepted_at));
return ClampTo<uint16_t>((*latest) - EconTime::DAYS_TILL_ORIGINAL_BASE_YEAR); // Date last cargo accepted since 1920 (in days)
}
}

@ -84,7 +84,7 @@ bool ObjectSpec::IsEverAvailable() const
*/
bool ObjectSpec::WasEverAvailable() const
{
return this->IsEverAvailable() && (_date > this->introduction_date || (_settings_game.construction.ignore_object_intro_dates && !_generating_world));
return this->IsEverAvailable() && ((CalTime::CurDate() > this->introduction_date) || (_settings_game.construction.ignore_object_intro_dates && !_generating_world));
}
/**
@ -94,8 +94,8 @@ bool ObjectSpec::WasEverAvailable() const
bool ObjectSpec::IsAvailable() const
{
return this->WasEverAvailable() &&
(_date < this->end_of_life_date || this->end_of_life_date < this->introduction_date + 365 ||
(_settings_game.construction.no_expire_objects_after != 0 && _cur_year >= _settings_game.construction.no_expire_objects_after));
((CalTime::CurDate() < this->end_of_life_date) || (this->end_of_life_date < this->introduction_date + 365) ||
(_settings_game.construction.no_expire_objects_after != 0 && CalTime::CurYear() >= _settings_game.construction.no_expire_objects_after));
}
/**
@ -281,7 +281,7 @@ static uint32_t GetCountAndDistanceOfClosestInstance(uint32_t local_id, uint32_t
break;
/* Construction date */
case 0x42: return _date.base();
case 0x42: return CalTime::CurDate().base();
/* Object founder information */
case 0x44: return _current_company;

@ -100,8 +100,8 @@ struct ObjectSpec {
uint8_t size; ///< The size of this objects; low nibble for X, high nibble for Y.
uint8_t build_cost_multiplier; ///< Build cost multiplier per tile.
uint8_t clear_cost_multiplier; ///< Clear cost multiplier per tile.
Date introduction_date; ///< From when can this object be built.
Date end_of_life_date; ///< When can't this object be built anymore.
CalTime::Date introduction_date;///< From when can this object be built.
CalTime::Date end_of_life_date; ///< When can't this object be built anymore.
ObjectFlags flags; ///< Flags/settings related to the object.
ObjectCtrlFlags ctrl_flags; ///< Extra control flags.
uint8_t edge_foundation[4]; ///< Edge foundation flags

@ -34,7 +34,7 @@
case 0x40: return 0;
case 0x41: return 0;
case 0x42: return 0;
case 0x43: return _date.base();
case 0x43: return CalTime::CurDate().base();
case 0x44: return HZB_TOWN_EDGE;
case A2VRI_RAILTYPE_SIGNAL_RESTRICTION_INFO: return 0;
case A2VRI_RAILTYPE_SIGNAL_CONTEXT: return this->signal_context;
@ -50,7 +50,7 @@
case 0x42: return IsLevelCrossingTile(this->tile) && IsCrossingBarred(this->tile);
case 0x43:
if (IsRailDepotTile(this->tile)) return Depot::GetByTile(this->tile)->build_date.base();
return _date.base();
return CalTime::CurDate().base();
case 0x44: {
const Town *t = nullptr;
if (IsRailDepotTile(this->tile)) {

@ -255,7 +255,7 @@ uint32_t RoadStopScopeResolver::GetVariable(uint16_t variable, uint32_t paramete
case 0xF0: return this->st == nullptr ? 0 : this->st->facilities; // facilities
case 0xFA: return ClampTo<uint16_t>((this->st == nullptr ? _date : this->st->build_date) - DAYS_TILL_ORIGINAL_BASE_YEAR); // build date
case 0xFA: return ClampTo<uint16_t>((this->st == nullptr ? CalTime::CurDate() : this->st->build_date) - CalTime::DAYS_TILL_ORIGINAL_BASE_YEAR); // build date
}
if (this->st != nullptr) return this->st->GetNewGRFVariable(this->ro, variable, parameter, &(extra->available));

@ -30,7 +30,7 @@
case 0x40: return 0;
case 0x41: return 0;
case 0x42: return 0;
case 0x43: return _date.base();
case 0x43: return CalTime::CurDate().base();
case 0x44: return HZB_TOWN_EDGE;
}
}
@ -41,7 +41,7 @@
case 0x42: return IsLevelCrossingTile(this->tile) && IsCrossingBarred(this->tile);
case 0x43:
if (IsRoadDepotTile(this->tile)) return Depot::GetByTile(this->tile)->build_date.base();
return _date.base();
return CalTime::CurDate().base();
case 0x44: {
const Town *t = nullptr;
if (IsRoadDepotTile(this->tile)) {

@ -323,7 +323,7 @@ uint32_t StationScopeResolver::GetNearbyStationInfo(uint32_t parameter, StationS
}
break;
case 0xFA: return ClampTo<uint16_t>(_date - DAYS_TILL_ORIGINAL_BASE_YEAR); // Build date, clamped to a 16 bit value
case 0xFA: return ClampTo<uint16_t>(CalTime::CurDate() - CalTime::DAYS_TILL_ORIGINAL_BASE_YEAR); // Build date, clamped to a 16 bit value
}
extra->available = false;
@ -424,7 +424,7 @@ uint32_t StationScopeResolver::GetNearbyStationInfo(uint32_t parameter, StationS
case 0x84: return this->st->string_id;
case 0x86: return 0;
case 0xF0: return this->st->facilities;
case 0xFA: return ClampTo<uint16_t>(this->st->build_date - DAYS_TILL_ORIGINAL_BASE_YEAR);
case 0xFA: return ClampTo<uint16_t>(this->st->build_date - CalTime::DAYS_TILL_ORIGINAL_BASE_YEAR);
}
return this->st->GetNewGRFVariable(this->ro, variable, parameter, &(extra->available));

@ -1005,7 +1005,7 @@ uint RemapNewGRFStringControlCode(uint scc, std::string *buffer, const char **st
/* Dates from NewGRFs have 1920-01-01 as their zero point, convert it to OpenTTD's epoch. */
case SCC_NEWGRF_PRINT_WORD_DATE_LONG:
case SCC_NEWGRF_PRINT_WORD_DATE_SHORT: parameters.SetParam(0, _newgrf_textrefstack.PopUnsignedWord() + DAYS_TILL_ORIGINAL_BASE_YEAR); break;
case SCC_NEWGRF_PRINT_WORD_DATE_SHORT: parameters.SetParam(0, _newgrf_textrefstack.PopUnsignedWord() + CalTime::DAYS_TILL_ORIGINAL_BASE_YEAR); break;
case SCC_NEWGRF_DISCARD_WORD: _newgrf_textrefstack.PopUnsignedWord(); break;

@ -692,7 +692,7 @@ static void MoveToNextTickerItem()
const NewsType type = ni->type;
/* check the date, don't show too old items */
if (_date - _news_type_data[type].age > ni->date) continue;
if (_scaled_tick_counter - ni->creation_tick > _news_type_data[type].age * DAY_TICKS) continue;
switch (_news_type_data[type].GetDisplay()) {
default: NOT_REACHED();
@ -729,7 +729,7 @@ static void MoveToNextNewsItem()
const NewsType type = ni->type;
/* check the date, don't show too old items */
if (_date - _news_type_data[type].age > ni->date) continue;
if (_scaled_tick_counter - ni->creation_tick > _news_type_data[type].age * DAY_TICKS) continue;
switch (_news_type_data[type].GetDisplay()) {
default: NOT_REACHED();
@ -806,10 +806,10 @@ static void DeleteNewsItem(NewsItem *ni)
* @see NewsSubtype
*/
NewsItem::NewsItem(StringID string_id, NewsType type, NewsFlag flags, NewsReferenceType reftype1, uint32_t ref1, NewsReferenceType reftype2, uint32_t ref2, const NewsAllocatedData *data) :
string_id(string_id), date(_date), type(type), flags(flags), reftype1(reftype1), reftype2(reftype2), ref1(ref1), ref2(ref2), data(data)
string_id(string_id), date(CalTime::CurDate()), creation_tick(_scaled_tick_counter), type(type), flags(flags), reftype1(reftype1), reftype2(reftype2), ref1(ref1), ref2(ref2), data(data)
{
/* show this news message in colour? */
if (_cur_year >= _settings_client.gui.coloured_news_year) this->flags |= NF_INCOLOUR;
if (CalTime::CurYear() >= _settings_client.gui.coloured_news_year) this->flags |= NF_INCOLOUR;
CopyOutDParam(this->params, 10);
}
@ -995,7 +995,7 @@ static void RemoveOldNewsItems()
NewsItem *next;
for (NewsItem *cur = _oldest_news; _total_news > MIN_NEWS_AMOUNT && cur != nullptr; cur = next) {
next = cur->next;
if (_date - _news_type_data[cur->type].age * _settings_client.gui.news_message_timeout > cur->date) DeleteNewsItem(cur);
if (_scaled_tick_counter - cur->creation_tick > (uint)(_news_type_data[cur->type].age * _settings_client.gui.news_message_timeout * DAY_TICKS)) DeleteNewsItem(cur);
}
}
@ -1021,9 +1021,9 @@ void NewsLoop()
static byte _last_clean_month = 0;
if (_last_clean_month != _cur_date_ymd.month) {
if (_last_clean_month != EconTime::CurMonth()) {
RemoveOldNewsItems();
_last_clean_month = _cur_date_ymd.month;
_last_clean_month = EconTime::CurMonth();
}
if (ReadyForNextTickerItem()) MoveToNextTickerItem();
@ -1143,7 +1143,7 @@ struct MessageHistoryWindow : Window {
/* Months are off-by-one, so it's actually 8. Not using
* month 12 because the 1 is usually less wide. */
SetDParam(0, ConvertYMDToDate(ORIGINAL_MAX_YEAR, 7, 30));
SetDParam(0, CalTime::ConvertYMDToDate(CalTime::ORIGINAL_MAX_YEAR, 7, 30));
this->date_width = GetStringBoundingBox(STR_JUST_DATE_TINY).width + WidgetDimensions::scaled.hsep_wide;
size->height = 4 * resize->height + WidgetDimensions::scaled.framerect.Vertical(); // At least 4 lines are visible.

@ -129,7 +129,8 @@ struct NewsItem {
NewsItem *prev; ///< Previous news item
NewsItem *next; ///< Next news item
StringID string_id; ///< Message text
Date date; ///< Date of the news
CalTime::Date date; ///< Date of the news
uint64_t creation_tick; ///< Tick when news was created
NewsType type; ///< Type of the news
NewsFlag flags; ///< NewsFlags bits @see NewsFlag

@ -25,7 +25,7 @@ struct Object : ObjectPool::PoolItem<&_object_pool> {
ObjectType type; ///< Type of the object
Town *town; ///< Town the object is built in
TileArea location; ///< Location of the object
Date build_date; ///< Date of construction
CalTime::Date build_date; ///< Date of construction
byte colour; ///< Colour of the object, for display purpose
byte view; ///< The view setting for this object

@ -143,7 +143,7 @@ void BuildObject(ObjectType type, TileIndex tile, CompanyID owner, Town *town, u
o->type = type;
o->location = ta;
o->town = town == nullptr ? CalcClosestTownFromTile(tile) : town;
o->build_date = _date;
o->build_date = CalTime::CurDate();
o->view = view;
/* If nothing owns the object, the colour will be random. Otherwise

@ -624,7 +624,7 @@ void OpenBrowser(const std::string &url)
/** Callback structure of statements to be executed after the NewGRF scan. */
struct AfterNewGRFScan : NewGRFScanCallback {
Year startyear = INVALID_YEAR; ///< The start year.
CalTime::Year startyear = CalTime::INVALID_YEAR; ///< The start year.
uint32_t generation_seed = GENERATE_NEW_SEED; ///< Seed for the new game.
std::string dedicated_host; ///< Hostname for the dedicated server.
uint16_t dedicated_port = 0; ///< Port for the dedicated server.
@ -673,7 +673,7 @@ struct AfterNewGRFScan : NewGRFScanCallback {
MusicDriver::GetInstance()->SetVolume(_settings_client.music.music_vol);
SetEffectVolume(_settings_client.music.effect_vol);
if (startyear != INVALID_YEAR) IConsoleSetSetting("game_creation.starting_year", startyear);
if (startyear != CalTime::INVALID_YEAR) IConsoleSetSetting("game_creation.starting_year", startyear.base());
if (generation_seed != GENERATE_NEW_SEED) _settings_newgame.game_creation.generation_seed = generation_seed;
if (!dedicated_host.empty()) {
@ -1127,7 +1127,7 @@ static void OnStartScenario()
/* Make sure all industries were built "this year", to avoid too early closures. (#9918) */
for (Industry *i : Industry::Iterate()) {
i->last_prod_year = _cur_year;
i->last_prod_year = EconTime::CurYear();
}
}
@ -1442,7 +1442,7 @@ void SwitchToMode(SwitchMode new_mode)
if (SafeLoad(_file_to_saveload.name, _file_to_saveload.file_op, _file_to_saveload.detail_ftype, GM_EDITOR, NO_DIRECTORY)) {
SetLocalCompany(OWNER_NONE);
GenerateSavegameId();
_settings_newgame.game_creation.starting_year = _cur_year;
_settings_newgame.game_creation.starting_year = CalTime::CurYear();
/* Cancel the saveload pausing */
DoCommandP(0, PM_PAUSED_SAVELOAD, 0, CMD_PAUSE);
} else {
@ -2126,7 +2126,7 @@ void StateGameLoop()
* to avoid problems with timetables and train speed adaptation
*/
_state_ticks++;
_state_ticks_offset++;
DateDetail::_state_ticks_offset++;
RunTileLoop();
CallVehicleTicks();
@ -2138,10 +2138,10 @@ void StateGameLoop()
CallWindowGameTickEvent();
NewsLoop();
} else {
if (_debug_desync_level > 2 && _tick_skip_counter == 0 && _date_fract == 0 && (_date.base() & 0x1F) == 0) {
if (_debug_desync_level > 2 && DateDetail::_tick_skip_counter == 0 && EconTime::CurDateFract() == 0 && (EconTime::CurDate().base() & 0x1F) == 0) {
/* Save the desync savegame if needed. */
char name[MAX_PATH];
seprintf(name, lastof(name), "dmp_cmds_%08x_%08x.sav", _settings_game.game_creation.generation_seed, _date.base());
seprintf(name, lastof(name), "dmp_cmds_%08x_%08x.sav", _settings_game.game_creation.generation_seed, EconTime::CurDate().base());
SaveOrLoad(name, SLO_SAVE, DFT_GAME_FILE, AUTOSAVE_DIR, false);
}
@ -2152,7 +2152,7 @@ void StateGameLoop()
Backup<CompanyID> cur_company(_current_company, OWNER_NONE, FILE_LINE);
BasePersistentStorageArray::SwitchMode(PSM_ENTER_GAMELOOP);
_tick_skip_counter++;
DateDetail::_tick_skip_counter++;
_scaled_tick_counter++;
if (_game_mode != GM_BOOTSTRAP) {
_state_ticks++; // This must update in lock-step with _tick_skip_counter, such that _state_ticks_offset doesn't need to be changed.
@ -2166,13 +2166,13 @@ void StateGameLoop()
}
RunAuxiliaryTileLoop();
if (_tick_skip_counter < DayLengthFactor()) {
if (DateDetail::_tick_skip_counter < DayLengthFactor()) {
AnimateAnimatedTiles();
RunTileLoop(true);
CallVehicleTicks();
OnTick_Companies(false);
} else {
_tick_skip_counter = 0;
DateDetail::_tick_skip_counter = 0;
IncreaseDate();
AnimateAnimatedTiles();
RunTileLoop(true);

@ -1028,6 +1028,6 @@ public:
inline const DispatchSchedule &GetDispatchScheduleByIndex(uint index) const { return this->dispatch_schedules[index]; }
};
void ShiftOrderDates(DateDelta interval);
void UpdateOrderUIOnDateChange();
#endif /* ORDER_BASE_H */

@ -3147,7 +3147,7 @@ VehicleOrderID ProcessConditionalOrder(const Order *order, const Vehicle *v, Pro
case OCV_RELIABILITY: skip_order = OrderConditionCompare(occ, ToPercent16(v->reliability), value); break;
case OCV_MAX_RELIABILITY: skip_order = OrderConditionCompare(occ, ToPercent16(v->GetEngine()->reliability), value); break;
case OCV_MAX_SPEED: skip_order = OrderConditionCompare(occ, v->GetDisplayMaxSpeed() * 10 / 16, value); break;
case OCV_AGE: skip_order = OrderConditionCompare(occ, DateDeltaToYears(v->age), value); break;
case OCV_AGE: skip_order = OrderConditionCompare(occ, DateDeltaToYearDelta(v->age).base(), value); break;
case OCV_REQUIRES_SERVICE: skip_order = OrderConditionCompare(occ, v->NeedsServicing(), value); break;
case OCV_UNCONDITIONALLY: skip_order = true; break;
case OCV_CARGO_WAITING: {
@ -3221,7 +3221,7 @@ VehicleOrderID ProcessConditionalOrder(const Order *order, const Vehicle *v, Pro
skip_order = ord->UpdateJumpCounter((byte)value, mode == PCO_DRY_RUN);
break;
}
case OCV_REMAINING_LIFETIME: skip_order = OrderConditionCompare(occ, std::max(DateDeltaToYears(v->max_age - v->age + DAYS_IN_LEAP_YEAR - 1), 0), value); break;
case OCV_REMAINING_LIFETIME: skip_order = OrderConditionCompare(occ, std::max(DateDeltaToYearDelta(v->max_age - v->age + DAYS_IN_LEAP_YEAR - 1).base(), 0), value); break;
case OCV_COUNTER_VALUE: {
const TraceRestrictCounter* ctr = TraceRestrictCounter::GetIfValid(GB(order->GetXData(), 16, 16));
if (ctr != nullptr) {
@ -3759,7 +3759,7 @@ CommandCost CmdMassChangeOrder(TileIndex tile, DoCommandFlag flags, uint32_t p1,
return CommandCost();
}
void ShiftOrderDates(DateDelta interval)
void UpdateOrderUIOnDateChange()
{
SetWindowClassesDirty(WC_VEHICLE_ORDERS);
SetWindowClassesDirty(WC_VEHICLE_TIMETABLE);

@ -145,7 +145,7 @@ struct PlanLine {
struct Plan : PlanPool::PoolItem<&_plan_pool> {
Owner owner;
Colours colour;
Date creation_date;
CalTime::Date creation_date;
PlanLineVector lines;
PlanLine *temp_line;
std::string name;
@ -157,7 +157,7 @@ struct Plan : PlanPool::PoolItem<&_plan_pool> {
Plan(Owner owner = INVALID_OWNER)
{
this->owner = owner;
this->creation_date = _date;
this->creation_date = CalTime::CurDate();
this->visible = false;
this->visible_by_all = false;
this->show_lines = false;

@ -311,12 +311,12 @@ bool ValParamRailType(const RailType rail)
* @return The rail types that should be available when date
* introduced rail types are taken into account as well.
*/
RailTypes AddDateIntroducedRailTypes(RailTypes current, Date date)
RailTypes AddDateIntroducedRailTypes(RailTypes current, CalTime::Date date)
{
RailTypes rts = current;
if (_settings_game.vehicle.no_introduce_vehicles_after > 0) {
date = std::min<Date>(date, ConvertYMDToDate(_settings_game.vehicle.no_introduce_vehicles_after, 0, 1) - 1);
date = std::min<CalTime::Date>(date, CalTime::ConvertYMDToDate(_settings_game.vehicle.no_introduce_vehicles_after, 0, 1) - 1);
}
for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) {
@ -325,7 +325,7 @@ RailTypes AddDateIntroducedRailTypes(RailTypes current, Date date)
if (rti->label == 0) continue;
/* Not date introduced. */
if (!IsInsideMM(rti->introduction_date, 0, MAX_DATE.base())) continue;
if (!IsInsideMM(rti->introduction_date, 0, CalTime::MAX_DATE.base())) continue;
/* Not yet introduced at this date. */
if (rti->introduction_date > date) continue;
@ -352,9 +352,9 @@ RailTypes GetCompanyRailTypes(CompanyID company, bool introduces)
{
RailTypes rts = RAILTYPES_NONE;
Date date = _date;
CalTime::Date date = CalTime::CurDate();
if (_settings_game.vehicle.no_introduce_vehicles_after > 0) {
date = std::min<Date>(date, ConvertYMDToDate(_settings_game.vehicle.no_introduce_vehicles_after, 0, 1) - 1);
date = std::min<CalTime::Date>(date, CalTime::ConvertYMDToDate(_settings_game.vehicle.no_introduce_vehicles_after, 0, 1) - 1);
}
for (const Engine *e : Engine::IterateType(VEH_TRAIN)) {
@ -375,7 +375,7 @@ RailTypes GetCompanyRailTypes(CompanyID company, bool introduces)
}
}
if (introduces) return AddDateIntroducedRailTypes(rts, _date);
if (introduces) return AddDateIntroducedRailTypes(rts, CalTime::CurDate());
return rts;
}
@ -403,7 +403,7 @@ RailTypes GetRailTypes(bool introduces)
}
}
if (introduces) return AddDateIntroducedRailTypes(rts, MAX_DATE);
if (introduces) return AddDateIntroducedRailTypes(rts, CalTime::MAX_DATE);
return rts;
}

@ -276,7 +276,7 @@ public:
* The introduction at this date is furthermore limited by the
* #introduction_required_railtypes.
*/
Date introduction_date;
CalTime::Date introduction_date;
/**
* Bitmask of railtypes that are required for this railtype to be introduced
@ -496,7 +496,7 @@ bool HasRailTypeAvail(const CompanyID company, const RailType railtype);
bool HasAnyRailTypesAvail(const CompanyID company);
bool ValParamRailType(const RailType rail);
RailTypes AddDateIntroducedRailTypes(RailTypes current, Date date);
RailTypes AddDateIntroducedRailTypes(RailTypes current, CalTime::Date date);
RailTypes GetCompanyRailTypes(CompanyID company, bool introduces = true);
RailTypes GetRailTypes(bool introduces);

@ -1421,7 +1421,7 @@ CommandCost CmdBuildTrainDepot(TileIndex tile, DoCommandFlag flags, uint32_t p1,
if (flags & DC_EXEC) {
Depot *d = new Depot(tile);
d->build_date = _date;
d->build_date = CalTime::CurDate();
MakeRailDepot(tile, _current_company, d->index, dir, railtype);
MarkTileDirtyByTile(tile);

@ -302,7 +302,7 @@ static void GenericPlaceSignals(TileIndex tile)
if (_cur_signal_type == SIGTYPE_NO_ENTRY) SB(p1, 15, 2, 1); // reverse default signal direction
} else {
SB(p1, 3, 1, _ctrl_pressed);
SB(p1, 4, 1, (_cur_year < _settings_client.gui.semaphore_build_before ? SIG_SEMAPHORE : SIG_ELECTRIC));
SB(p1, 4, 1, (CalTime::CurYear() < _settings_client.gui.semaphore_build_before ? SIG_SEMAPHORE : SIG_ELECTRIC));
SB(p1, 5, 3, GetDefaultSignalType());
SB(p1, 8, 1, 0);
SB(p1, 9, 6, cycle_types);
@ -484,7 +484,7 @@ static void HandleAutoSignalPlacement()
SB(p2, 11, 4, _cur_signal_style);
} else {
SB(p2, 3, 1, 0);
SB(p2, 4, 1, (_cur_year < _settings_client.gui.semaphore_build_before ? SIG_SEMAPHORE : SIG_ELECTRIC));
SB(p2, 4, 1, (CalTime::CurYear() < _settings_client.gui.semaphore_build_before ? SIG_SEMAPHORE : SIG_ELECTRIC));
SB(p2, 6, 1, _ctrl_pressed);
SB(p2, 7, 3, GetDefaultSignalType());
SB(p2, 24, 8, _settings_client.gui.drag_signals_density);
@ -2788,7 +2788,7 @@ static void SetDefaultRailGui()
*/
void ResetSignalVariant(int32_t new_value)
{
SignalVariant new_variant = (_cur_year < _settings_client.gui.semaphore_build_before ? SIG_SEMAPHORE : SIG_ELECTRIC);
SignalVariant new_variant = (CalTime::CurYear() < _settings_client.gui.semaphore_build_before ? SIG_SEMAPHORE : SIG_ELECTRIC);
if (new_variant != _cur_signal_variant) {
Window *w = FindWindowById(WC_BUILD_SIGNAL, 0);

@ -147,7 +147,7 @@ bool HasRoadTypeAvail(const CompanyID company, RoadType roadtype)
if (rti->label == 0) return false;
/* Not yet introduced at this date. */
if (IsInsideMM(rti->introduction_date, 0, MAX_DATE.base()) && rti->introduction_date > _date) return false;
if (IsInsideMM(rti->introduction_date, 0, CalTime::MAX_DATE.base()) && rti->introduction_date > CalTime::CurDate()) return false;
/*
* Do not allow building hidden road types, except when a town may build it.
@ -199,7 +199,7 @@ bool ValParamRoadType(RoadType roadtype)
* @return The road types that should be available when date
* introduced road types are taken into account as well.
*/
RoadTypes AddDateIntroducedRoadTypes(RoadTypes current, Date date)
RoadTypes AddDateIntroducedRoadTypes(RoadTypes current, CalTime::Date date)
{
RoadTypes rts = current;
@ -209,7 +209,7 @@ RoadTypes AddDateIntroducedRoadTypes(RoadTypes current, Date date)
if (rti->label == 0) continue;
/* Not date introduced. */
if (!IsInsideMM(rti->introduction_date, 0, MAX_DATE.base())) continue;
if (!IsInsideMM(rti->introduction_date, 0, CalTime::MAX_DATE.base())) continue;
/* Not yet introduced at this date. */
if (rti->introduction_date > date) continue;
@ -240,7 +240,7 @@ RoadTypes GetCompanyRoadTypes(CompanyID company, bool introduces)
const EngineInfo *ei = &e->info;
if (HasBit(ei->climates, _settings_game.game_creation.landscape) &&
(HasBit(e->company_avail, company) || _date >= e->intro_date + DAYS_IN_YEAR)) {
(HasBit(e->company_avail, company) || CalTime::CurDate() >= e->intro_date + DAYS_IN_YEAR)) {
const RoadVehicleInfo *rvi = &e->u.road;
assert(rvi->roadtype < ROADTYPE_END);
if (introduces) {
@ -251,7 +251,7 @@ RoadTypes GetCompanyRoadTypes(CompanyID company, bool introduces)
}
}
if (introduces) return AddDateIntroducedRoadTypes(rts, _date);
if (introduces) return AddDateIntroducedRoadTypes(rts, CalTime::CurDate());
return rts;
}
@ -277,7 +277,7 @@ RoadTypes GetRoadTypes(bool introduces)
}
}
if (introduces) return AddDateIntroducedRoadTypes(rts, MAX_DATE);
if (introduces) return AddDateIntroducedRoadTypes(rts, CalTime::MAX_DATE);
return rts;
}

@ -201,7 +201,7 @@ public:
* The introduction at this date is furthermore limited by the
* #introduction_required_types.
*/
Date introduction_date;
CalTime::Date introduction_date;
/**
* Bitmask of roadtypes that are required for this roadtype to be introduced

@ -157,7 +157,7 @@ RoadType AllocateRoadType(RoadTypeLabel label, RoadTramType rtt)
rti->flags = ROTFB_NONE;
rti->extra_flags = RXTFB_NONE;
rti->collision_mode = RTCM_NORMAL;
rti->introduction_date = INVALID_DATE;
rti->introduction_date = CalTime::INVALID_DATE;
/* Make us compatible with ourself. */
rti->powered_roadtypes = (RoadTypes)(1ULL << rt);
@ -1768,7 +1768,7 @@ CommandCost CmdBuildRoadDepot(TileIndex tile, DoCommandFlag flags, uint32_t p1,
if (flags & DC_EXEC) {
Depot *dep = new Depot(tile);
dep->build_date = _date;
dep->build_date = CalTime::CurDate();
/* A road depot has two road bits. */
UpdateCompanyRoadInfrastructure(rt, _current_company, ROAD_DEPOT_TRACKBIT_FACTOR);

@ -152,7 +152,7 @@ bool HasRoadTypeAvail(CompanyID company, RoadType roadtype);
bool ValParamRoadType(RoadType roadtype);
RoadTypes GetCompanyRoadTypes(CompanyID company, bool introduces = true);
RoadTypes GetRoadTypes(bool introduces);
RoadTypes AddDateIntroducedRoadTypes(RoadTypes current, Date date);
RoadTypes AddDateIntroducedRoadTypes(RoadTypes current, CalTime::Date date);
void UpdateLevelCrossing(TileIndex tile, bool sound = true, bool force_close = false);
void MarkDirtyAdjacentLevelCrossingTilesOnAdd(TileIndex tile, Axis road_axis);

@ -2333,7 +2333,7 @@ DropDownList GetRoadTypeDropDownList(RoadTramTypes rtts, bool for_replacement, b
DropDownList GetScenRoadTypeDropDownList(RoadTramTypes rtts)
{
RoadTypes avail_roadtypes = GetRoadTypes(false);
avail_roadtypes = AddDateIntroducedRoadTypes(avail_roadtypes, _date);
avail_roadtypes = AddDateIntroducedRoadTypes(avail_roadtypes, CalTime::CurDate());
RoadTypes used_roadtypes = GetRoadTypes(true);
/* Filter listed road types */

@ -318,9 +318,9 @@ CommandCost CmdBuildRoadVehicle(TileIndex tile, DoCommandFlag flags, const Engin
v->SetServiceInterval(Company::Get(v->owner)->settings.vehicle.servint_roadveh);
v->date_of_last_service = _date;
v->date_of_last_service_newgrf = _date;
v->build_year = _cur_year;
v->date_of_last_service = EconTime::CurDate();
v->date_of_last_service_newgrf = CalTime::CurDate();
v->build_year = CalTime::CurYear();
v->sprite_seq.Set(SPR_IMG_QUERY);
v->random_bits = Random();

@ -279,8 +279,8 @@ static void InitializeWindowsAndCaches()
/* For each company, verify (while loading a scenario) that the inauguration date is the current year and set it
* accordingly if it is not the case. No need to set it on companies that are not been used already,
* thus the MIN_YEAR (which is really nothing more than Zero, initialized value) test */
if (_file_to_saveload.abstract_ftype == FT_SCENARIO && c->inaugurated_year != MIN_YEAR) {
c->inaugurated_year = _cur_year;
if (_file_to_saveload.abstract_ftype == FT_SCENARIO && c->inaugurated_year != CalTime::MIN_YEAR) {
c->inaugurated_year = CalTime::CurYear();
}
}
@ -842,14 +842,14 @@ bool AfterLoadGame()
}
/* The value of _date_fract got divided, so make sure that old games are converted correctly. */
if (IsSavegameVersionBefore(SLV_11, 1) || (IsSavegameVersionBefore(SLV_147) && _date_fract > DAY_TICKS)) _date_fract /= 885;
if (IsSavegameVersionBefore(SLV_11, 1) || (IsSavegameVersionBefore(SLV_147) && CalTime::CurDateFract() > DAY_TICKS)) CalTime::Detail::now.cal_date_fract /= 885;
if (SlXvIsFeaturePresent(XSLFI_SPRINGPP) || SlXvIsFeaturePresent(XSLFI_JOKERPP) || SlXvIsFeaturePresent(XSLFI_CHILLPP)) {
assert(DayLengthFactor() >= 1);
_tick_skip_counter = _date_fract % DayLengthFactor();
_date_fract /= DayLengthFactor();
assert(_date_fract < DAY_TICKS);
assert(_tick_skip_counter < DayLengthFactor());
DateDetail::_tick_skip_counter = CalTime::CurDateFract() % DayLengthFactor();
CalTime::Detail::now.cal_date_fract /= DayLengthFactor();
assert(CalTime::CurDateFract() < DAY_TICKS);
assert(TickSkipCounter() < DayLengthFactor());
}
/* Set day length factor to 1 if loading a pre day length savegame */
@ -863,15 +863,23 @@ bool AfterLoadGame()
}
}
if (SlXvIsFeatureMissing(XSLFI_VARIABLE_DAY_LENGTH, 3)) {
_scaled_tick_counter = (uint64_t)((_tick_counter * DayLengthFactor()) + _tick_skip_counter);
_scaled_tick_counter = (uint64_t)((_tick_counter * DayLengthFactor()) + TickSkipCounter());
}
if (SlXvIsFeaturePresent(XSLFI_VARIABLE_DAY_LENGTH, 1, 3)) {
_state_ticks = GetStateTicksFromCurrentDateWithoutOffset() + _state_ticks_offset;
_state_ticks = GetStateTicksFromCurrentDateWithoutOffset() + DateDetail::_state_ticks_offset;
}
/* Update current year
* must be done before loading sprites as some newgrfs check it */
SetDate(_date, _date_fract);
CalTime::Detail::SetDate(CalTime::CurDate(), CalTime::CurDateFract());
if (SlXvIsFeaturePresent(XSLFI_VARIABLE_DAY_LENGTH, 5) || !IsSavegameVersionBefore(SLV_ECONOMY_DATE)) {
EconTime::Detail::SetDate(EconTime::CurDate(), EconTime::CurDateFract());
} else {
/* Set economy date from calendar date */
EconTime::Detail::SetDate(CalTime::CurDate().base(), CalTime::CurDateFract());
}
SetupTileLoopCounts();
/*
@ -917,7 +925,7 @@ bool AfterLoadGame()
}
if (IsSavegameVersionBefore(SLV_ENDING_YEAR)) {
_settings_game.game_creation.ending_year = DEF_END_YEAR;
_settings_game.game_creation.ending_year = CalTime::DEF_END_YEAR;
}
/* Convert linkgraph update settings from days to seconds. */
@ -1804,20 +1812,22 @@ bool AfterLoadGame()
/* Time starts at 0 instead of 1920.
* Account for this in older games by adding an offset */
if (IsSavegameVersionBefore(SLV_31)) {
_date += DAYS_TILL_ORIGINAL_BASE_YEAR.AsDelta();
CalTime::Detail::now.cal_date += CalTime::DAYS_TILL_ORIGINAL_BASE_YEAR.AsDelta();
EconTime::Detail::now.econ_date += EconTime::DAYS_TILL_ORIGINAL_BASE_YEAR.AsDelta();
CalTime::Detail::now.cal_ymd = CalTime::ConvertDateToYMD(CalTime::CurDate());
EconTime::Detail::now.econ_ymd = EconTime::ConvertDateToYMD(EconTime::CurDate());
RecalculateStateTicksOffset();
_cur_date_ymd = ConvertDateToYMD(_date);
UpdateCachedSnowLine();
for (Station *st : Station::Iterate()) st->build_date += DAYS_TILL_ORIGINAL_BASE_YEAR.AsDelta();
for (Waypoint *wp : Waypoint::Iterate()) wp->build_date += DAYS_TILL_ORIGINAL_BASE_YEAR.AsDelta();
for (Engine *e : Engine::Iterate()) e->intro_date += DAYS_TILL_ORIGINAL_BASE_YEAR.AsDelta();
for (Company *c : Company::Iterate()) c->inaugurated_year += ORIGINAL_BASE_YEAR;
for (Industry *i : Industry::Iterate()) i->last_prod_year += ORIGINAL_BASE_YEAR;
for (Station *st : Station::Iterate()) st->build_date += CalTime::DAYS_TILL_ORIGINAL_BASE_YEAR.AsDelta();
for (Waypoint *wp : Waypoint::Iterate()) wp->build_date += CalTime::DAYS_TILL_ORIGINAL_BASE_YEAR.AsDelta();
for (Engine *e : Engine::Iterate()) e->intro_date += CalTime::DAYS_TILL_ORIGINAL_BASE_YEAR.AsDelta();
for (Company *c : Company::Iterate()) c->inaugurated_year += CalTime::ORIGINAL_BASE_YEAR.AsDelta();
for (Industry *i : Industry::Iterate()) i->last_prod_year += CalTime::ORIGINAL_BASE_YEAR.AsDelta();
for (Vehicle *v : Vehicle::Iterate()) {
v->date_of_last_service += DAYS_TILL_ORIGINAL_BASE_YEAR.AsDelta();
v->build_year += ORIGINAL_BASE_YEAR;
v->date_of_last_service += EconTime::DAYS_TILL_ORIGINAL_BASE_YEAR.AsDelta();
v->build_year += CalTime::ORIGINAL_BASE_YEAR.AsDelta();
}
}
@ -2327,7 +2337,7 @@ bool AfterLoadGame()
/* Replace "house construction year" with "house age" */
if (IsTileType(t, MP_HOUSE) && IsHouseCompleted(t)) {
_m[t].m5 = ClampTo<uint8_t>(_cur_year - (_m[t].m5 + ORIGINAL_BASE_YEAR));
_m[t].m5 = ClampTo<uint8_t>(CalTime::CurYear() - (_m[t].m5 + CalTime::ORIGINAL_BASE_YEAR.base()));
}
}
}
@ -2507,7 +2517,7 @@ bool AfterLoadGame()
o->location.tile = t;
o->location.w = size;
o->location.h = size;
o->build_date = _date;
o->build_date = CalTime::CurDate();
o->town = type == OBJECT_STATUE ? Town::Get(_m[t].m2) : CalcClosestTownFromTile(t, UINT_MAX);
_m[t].m2 = o->index;
Object::IncTypeCount(type);
@ -2826,7 +2836,7 @@ bool AfterLoadGame()
}
if (IsSavegameVersionBefore(SLV_142)) {
for (Depot *d : Depot::Iterate()) d->build_date = _date;
for (Depot *d : Depot::Iterate()) d->build_date = CalTime::CurDate();
}
if (SlXvIsFeatureMissing(XSLFI_INFRA_SHARING)) {
@ -3714,7 +3724,7 @@ bool AfterLoadGame()
/* clear the PBS bit, update the end signal state */
for (TileIndex t = 0; t < map_size; t++) {
if (IsTileType(t, MP_TUNNELBRIDGE) && GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL && IsTunnelBridgeWithSignalSimulation(t)) {
SetTunnelBridgeSemaphore(t, _cur_year < _settings_client.gui.semaphore_build_before);
SetTunnelBridgeSemaphore(t, CalTime::CurYear() < _settings_client.gui.semaphore_build_before);
SetTunnelBridgePBS(t, false);
UpdateSignalsOnSegment(t, INVALID_DIAGDIR, GetTileOwner(t));
}
@ -4340,7 +4350,7 @@ bool AfterLoadGame()
if (IsSavegameVersionBefore(SLV_NEWGRF_LAST_SERVICE) && SlXvIsFeatureMissing(XSLFI_NEWGRF_LAST_SERVICE)) {
/* Set service date provided to NewGRF. */
for (Vehicle *v : Vehicle::Iterate()) {
v->date_of_last_service_newgrf = v->date_of_last_service;
v->date_of_last_service_newgrf = v->date_of_last_service.base();
}
}
@ -4425,9 +4435,9 @@ bool AfterLoadGame()
#endif
}
_game_load_cur_date_ymd = _cur_date_ymd;
_game_load_date_fract = _date_fract;
_game_load_tick_skip_counter = _tick_skip_counter;
_game_load_cur_date_ymd = EconTime::CurYMD();
_game_load_date_fract = EconTime::CurDateFract();
_game_load_tick_skip_counter = TickSkipCounter();
_game_load_state_ticks = _state_ticks;
_game_load_time = time(nullptr);

@ -43,7 +43,7 @@ struct ProducedCargo {
struct AcceptedCargo {
CargoID cargo; ///< Cargo type
uint16_t waiting; ///< Amount of cargo waiting to processed
Date last_accepted; ///< Last day cargo was accepted by this industry
EconTime::Date last_accepted; ///< Last day cargo was accepted by this industry
};
class SlIndustryAccepted : public DefaultSaveLoadHandler<SlIndustryAccepted, Industry> {

@ -43,11 +43,14 @@ extern TimeoutTimer<TimerGameTick> _new_competitor_timeout;
namespace upstream_sl {
static const SaveLoad _date_desc[] = {
SLEG_CONDVAR("date", _date, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31),
SLEG_CONDVAR("date", _date, SLE_INT32, SLV_31, SL_MAX_VERSION),
SLEG_VAR("date_fract", _date_fract, SLE_UINT16),
SLEG_CONDVAR("tick_counter", _tick_counter, SLE_FILE_U16 | SLE_VAR_U64, SL_MIN_VERSION, SLV_U64_TICK_COUNTER),
SLEG_CONDVAR("tick_counter", _tick_counter, SLE_UINT64, SLV_U64_TICK_COUNTER, SL_MAX_VERSION),
SLEG_CONDVAR("date", CalTime::Detail::now.cal_date, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31),
SLEG_CONDVAR("date", CalTime::Detail::now.cal_date, SLE_INT32, SLV_31, SL_MAX_VERSION),
SLEG_VAR("date_fract", CalTime::Detail::now.cal_date_fract, SLE_UINT16),
SLEG_CONDVAR("tick_counter", _tick_counter, SLE_FILE_U16 | SLE_VAR_U64, SL_MIN_VERSION, SLV_U64_TICK_COUNTER),
SLEG_CONDVAR("tick_counter", _tick_counter, SLE_UINT64, SLV_U64_TICK_COUNTER, SL_MAX_VERSION),
SLEG_CONDVAR("economy_date", EconTime::Detail::now.econ_date, SLE_INT32, SLV_ECONOMY_DATE, SL_MAX_VERSION),
SLEG_CONDVAR("economy_date_fract", EconTime::Detail::now.econ_date_fract, SLE_UINT16, SLV_ECONOMY_DATE, SL_MAX_VERSION),
SLEG_CONDVAR("calendar_sub_date_fract", CalTime::Detail::now.sub_date_fract, SLE_UINT16, SLV_CALENDAR_SUB_DATE_FRACT, SL_MAX_VERSION),
SLEG_CONDVAR("age_cargo_skip_counter", _age_cargo_skip_counter, SLE_UINT8, SL_MIN_VERSION, SLV_162),
SLEG_CONDVAR("cur_tileloop_tile", _cur_tileloop_tile, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6),
SLEG_CONDVAR("cur_tileloop_tile", _cur_tileloop_tile, SLE_UINT32, SLV_6, SL_MAX_VERSION),
@ -104,7 +107,7 @@ struct DATEChunkHandler : ChunkHandler {
this->LoadCommon(_date_check_desc, _date_check_sl_compat);
if (IsSavegameVersionBefore(SLV_31)) {
_load_check_data.current_date += DAYS_TILL_ORIGINAL_BASE_YEAR.AsDelta();
_load_check_data.current_date += CalTime::DAYS_TILL_ORIGINAL_BASE_YEAR.AsDelta();
}
}
};

@ -178,8 +178,8 @@ static void AddNewScheduledDispatchSchedule(VehicleID vindex)
duration = 24 * 60 * _settings_time.ticks_per_minute;
} else {
/* Set Jan 1st and 365 day */
start_tick = DateToStateTicks(DateAtStartOfYear(_cur_year));
/* Set Jan 1st and 365 day, calendar and economy time must be locked together for this to result in a useful schedule */
start_tick = DateToStateTicks(CalTime::DateAtStartOfYear(CalTime::CurYear()).base());
duration = 365 * DAY_TICKS;
}
@ -280,7 +280,7 @@ struct SchdispatchWindow : GeneralVehicleWindow {
case WID_SCHDISPATCH_MATRIX: {
uint min_height = 0;
SetDParamMaxValue(0, _settings_time.time_in_minutes ? 0 : MAX_YEAR * DAYS_IN_YEAR);
SetDParamMaxValue(0, _settings_time.time_in_minutes ? 0 : EconTime::MAX_YEAR.base() * DAYS_IN_YEAR);
Dimension unumber = GetStringBoundingBox(STR_SCHDISPATCH_DATE_WALLCLOCK_TINY_FLAGGED);
const Sprite *spr = GetSprite(SPR_FLAG_VEH_STOPPED, SpriteType::Normal, ZoomMask(ZOOM_LVL_GUI));
@ -940,7 +940,7 @@ struct SchdispatchWindow : GeneralVehicleWindow {
} else if (_settings_time.time_in_minutes && _settings_client.gui.timetable_start_text_entry) {
ShowQueryString(STR_EMPTY, STR_SCHDISPATCH_ADD_CAPTION, 31, this, CS_NUMERAL, QSF_NONE);
} else {
ShowSetDateWindow(this, v->index | (this->schedule_index << 20), _state_ticks, _cur_year, _cur_year + 15, ScheduleAddCallback, STR_SCHDISPATCH_ADD, STR_SCHDISPATCH_ADD_TOOLTIP);
ShowSetDateWindow(this, v->index | (this->schedule_index << 20), _state_ticks, EconTime::CurYear(), EconTime::CurYear() + 15, ScheduleAddCallback, STR_SCHDISPATCH_ADD, STR_SCHDISPATCH_ADD_TOOLTIP);
}
break;
}
@ -959,7 +959,7 @@ struct SchdispatchWindow : GeneralVehicleWindow {
SetDParam(0, _settings_time.NowInTickMinutes().ClockHHMM());
ShowQueryString(STR_JUST_INT, STR_SCHDISPATCH_START_CAPTION_MINUTE, 31, this, CS_NUMERAL, QSF_ACCEPT_UNCHANGED);
} else {
ShowSetDateWindow(this, v->index | (this->schedule_index << 20), _state_ticks, _cur_year, _cur_year + 15, SetScheduleStartDateCallback, STR_SCHDISPATCH_SET_START, STR_SCHDISPATCH_START_TOOLTIP);
ShowSetDateWindow(this, v->index | (this->schedule_index << 20), _state_ticks, EconTime::CurYear(), EconTime::CurYear() + 15, SetScheduleStartDateCallback, STR_SCHDISPATCH_SET_START, STR_SCHDISPATCH_START_TOOLTIP);
}
break;
}

@ -22,7 +22,7 @@
{
if (bridge_id >= MAX_BRIDGES) return false;
const BridgeSpec *b = ::GetBridgeSpec(bridge_id);
return b->avail_year <= _cur_year && !HasBit(b->ctrl_flags, BSCF_NOT_AVAILABLE_AI_GS);
return b->avail_year <= CalTime::CurYear() && !HasBit(b->ctrl_flags, BSCF_NOT_AVAILABLE_AI_GS);
}
/* static */ bool ScriptBridge::IsBridgeTile(TileIndex tile)

@ -25,7 +25,7 @@
/* static */ ScriptDate::Date ScriptDate::GetCurrentDate()
{
return (ScriptDate::Date)_date.base();
return (ScriptDate::Date)::CalTime::CurDate().base();
}
/* static */ SQInteger ScriptDate::GetDayLengthFactor()
@ -37,15 +37,15 @@
{
if (date < 0) return DATE_INVALID;
::YearMonthDay ymd = ::ConvertDateToYMD(date);
return ymd.year;
::CalTime::YearMonthDay ymd = ::CalTime::ConvertDateToYMD(date);
return ymd.year.base();
}
/* static */ SQInteger ScriptDate::GetMonth(ScriptDate::Date date)
{
if (date < 0) return DATE_INVALID;
::YearMonthDay ymd = ::ConvertDateToYMD(date);
::CalTime::YearMonthDay ymd = ::CalTime::ConvertDateToYMD(date);
return ymd.month + 1;
}
@ -53,7 +53,7 @@
{
if (date < 0) return DATE_INVALID;
::YearMonthDay ymd = ::ConvertDateToYMD(date);
::CalTime::YearMonthDay ymd = ::CalTime::ConvertDateToYMD(date);
return ymd.day;
}
@ -61,9 +61,9 @@
{
if (month < 1 || month > 12) return DATE_INVALID;
if (day_of_month < 1 || day_of_month > 31) return DATE_INVALID;
if (year < 0 || year > MAX_YEAR) return DATE_INVALID;
if (year < 0 || year > CalTime::MAX_YEAR) return DATE_INVALID;
return (ScriptDate::Date)::ConvertYMDToDate(year, month - 1, day_of_month).base();
return (ScriptDate::Date)::CalTime::ConvertYMDToDate(year, month - 1, day_of_month).base();
}
/* static */ SQInteger ScriptDate::GetSystemTime()

@ -31,7 +31,7 @@ public:
* compose valid date values for a known year, month and day.
*/
enum Date {
DATE_INVALID = ::INVALID_DATE.base(), ///< A value representing an invalid date.
DATE_INVALID = ::CalTime::INVALID_DATE.base(), ///< A value representing an invalid date.
};
/**

@ -221,7 +221,7 @@
{
Industry *i = Industry::GetIfValid(industry_id);
if (i == nullptr) return 0;
return i->last_prod_year;
return i->last_prod_year.base();
}
/* static */ ScriptDate::Date ScriptIndustry::GetCargoLastAcceptedDate(IndustryID industry_id, CargoID cargo_type)
@ -230,7 +230,7 @@
if (i == nullptr) return ScriptDate::DATE_INVALID;
if (cargo_type == INVALID_CARGO) {
return (ScriptDate::Date)std::accumulate(std::begin(i->last_cargo_accepted_at), std::end(i->last_cargo_accepted_at), Date(0), [](Date a, Date b) { return std::max(a, b); }).base();
return (ScriptDate::Date)std::accumulate(std::begin(i->last_cargo_accepted_at), std::end(i->last_cargo_accepted_at), EconTime::Date(0), [](EconTime::Date a, EconTime::Date b) { return std::max(a, b); }).base();
} else {
int index = i->GetCargoAcceptedIndex(cargo_type);
if (index < 0) return ScriptDate::DATE_INVALID;

@ -3368,7 +3368,7 @@ struct CustomCurrencyWindow : Window {
this->SetWidgetDisabledState(WID_CC_RATE_DOWN, _custom_currency.rate == 1);
this->SetWidgetDisabledState(WID_CC_RATE_UP, _custom_currency.rate == UINT16_MAX);
this->SetWidgetDisabledState(WID_CC_YEAR_DOWN, _custom_currency.to_euro == CF_NOEURO);
this->SetWidgetDisabledState(WID_CC_YEAR_UP, _custom_currency.to_euro == MAX_YEAR);
this->SetWidgetDisabledState(WID_CC_YEAR_UP, _custom_currency.to_euro == CalTime::MAX_YEAR);
}
void SetStringParameters(WidgetID widget) const override
@ -3475,8 +3475,8 @@ struct CustomCurrencyWindow : Window {
break;
case WID_CC_YEAR_UP:
_custom_currency.to_euro = Clamp(_custom_currency.to_euro + 1, 2000, MAX_YEAR);
if (_custom_currency.to_euro == MAX_YEAR) this->DisableWidget(WID_CC_YEAR_UP);
_custom_currency.to_euro = Clamp<CalTime::Year>(_custom_currency.to_euro + 1, 2000, CalTime::MAX_YEAR);
if (_custom_currency.to_euro == CalTime::MAX_YEAR) this->DisableWidget(WID_CC_YEAR_UP);
this->EnableWidget(WID_CC_YEAR_DOWN);
break;
@ -3522,7 +3522,7 @@ struct CustomCurrencyWindow : Window {
case WID_CC_YEAR: { // Year to switch to euro
int val = atoi(str);
_custom_currency.to_euro = (val < 2000 ? CF_NOEURO : std::min(val, MAX_YEAR));
_custom_currency.to_euro = (val < 2000 ? CF_NOEURO : std::min<CalTime::Year>(val, CalTime::MAX_YEAR));
break;
}
}

@ -244,7 +244,7 @@ struct GUISettings : public TimeSettings {
SignalGUISettings signal_gui_mode; ///< select which signal types are shown in the signal GUI
SignalCycleSettings cycle_signal_types; ///< Which signal types to cycle with the build signal tool.
SignalType default_signal_type; ///< The default signal type, which is set automatically by the last signal used. Not available in Settings.
Year coloured_news_year; ///< when does newspaper become coloured?
CalTime::Year coloured_news_year; ///< when does newspaper become coloured?
bool override_time_settings; ///< Whether to override time display settings stored in savegame.
bool timetable_in_ticks; ///< whether to show the timetable in ticks rather than days
bool timetable_leftover_ticks; ///< whether to show leftover ticks after converting to minutes/days, in the timetable
@ -255,7 +255,7 @@ struct GUISettings : public TimeSettings {
byte drag_signals_density; ///< many signals density
bool drag_signals_fixed_distance; ///< keep fixed distance between signals when dragging
bool drag_signals_skip_stations; ///< continue past station/waypoint tiles when auto-fill dragging signals
Year semaphore_build_before; ///< build semaphore signals automatically before this year
CalTime::Year semaphore_build_before; ///< build semaphore signals automatically before this year
byte news_message_timeout; ///< how much longer than the news message "age" should we keep the message in the history
bool show_track_reservation; ///< highlight reserved tracks.
byte station_numtracks; ///< the number of platforms to default on for rail stations
@ -441,7 +441,7 @@ struct NetworkSettings {
uint8_t autoclean_novehicles; ///< remove companies with no vehicles after this many months
uint8_t max_companies; ///< maximum amount of companies
uint8_t max_clients; ///< maximum amount of clients
Year restart_game_year; ///< year the server restarts
CalTime::Year restart_game_year; ///< year the server restarts
uint8_t min_active_clients; ///< minimum amount of active clients to unpause the game
bool reload_cfg; ///< reload the config file before restarting
std::string last_joined; ///< Last joined server
@ -454,8 +454,8 @@ struct NetworkSettings {
struct GameCreationSettings {
uint32_t generation_seed; ///< noise seed for world generation
uint32_t generation_unique_id; ///< random id to differentiate savegames
Year starting_year; ///< starting date
Year ending_year; ///< scoring end date
CalTime::Year starting_year; ///< starting date
CalTime::Year ending_year; ///< scoring end date
uint8_t map_x; ///< X size of map
uint8_t map_y; ///< Y size of map
byte land_generator; ///< the landscape generator
@ -527,7 +527,7 @@ struct ConstructionSettings {
bool allow_docks_under_bridges; ///< allow docks under bridges
byte purchase_land_permitted; ///< whether and how purchasing land is permitted
bool build_object_area_permitted; ///< whether building objects by area is permitted
Year no_expire_objects_after; ///< do not expire objects after this year
CalTime::Year no_expire_objects_after; ///< do not expire objects after this year
bool ignore_object_intro_dates; ///< allow players to build objects before their introduction dates (does not include during map generation)
bool convert_town_road_no_houses; ///< allow converting town roads to a type which does not allow houses
@ -694,8 +694,8 @@ struct VehicleSettings {
uint8_t freight_trains; ///< value to multiply the weight of cargo by
bool dynamic_engines; ///< enable dynamic allocation of engine data
bool never_expire_vehicles; ///< never expire vehicles
Year no_expire_vehicles_after; ///< do not expire vehicles after this year
Year no_introduce_vehicles_after; ///< do not introduce vehicles after this year
CalTime::Year no_expire_vehicles_after; ///< do not expire vehicles after this year
CalTime::Year no_introduce_vehicles_after; ///< do not introduce vehicles after this year
byte extend_vehicle_life; ///< extend vehicle life by this many years
byte road_side; ///< the side of the road vehicles drive on
uint8_t plane_crashes; ///< number of plane crashes, 0 = none, 1 = reduced, 2 = normal

@ -1196,9 +1196,9 @@ CommandCost CmdBuildShip(TileIndex tile, DoCommandFlag flags, const Engine *e, V
v->state = TRACK_BIT_DEPOT;
v->SetServiceInterval(Company::Get(_current_company)->settings.vehicle.servint_ships);
v->date_of_last_service = _date;
v->date_of_last_service_newgrf = _date;
v->build_year = _cur_year;
v->date_of_last_service = EconTime::CurDate();
v->date_of_last_service_newgrf = CalTime::CurDate();
v->build_year = CalTime::CurYear();
v->sprite_seq.Set(SPR_IMG_QUERY);
v->random_bits = Random();

@ -103,7 +103,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
{ XSLFI_VEHICLE_REPAIR_COST, XSCF_NULL, 2, 2, "vehicle_repair_cost", nullptr, nullptr, nullptr },
{ XSLFI_ENH_VIEWPORT_PLANS, XSCF_IGNORABLE_ALL, 4, 4, "enh_viewport_plans", nullptr, nullptr, "PLAN" },
{ XSLFI_INFRA_SHARING, XSCF_NULL, 2, 2, "infra_sharing", nullptr, nullptr, "CPDP" },
{ XSLFI_VARIABLE_DAY_LENGTH, XSCF_NULL, 4, 4, "variable_day_length", nullptr, nullptr, nullptr },
{ XSLFI_VARIABLE_DAY_LENGTH, XSCF_NULL, 5, 5, "variable_day_length", nullptr, nullptr, nullptr },
{ XSLFI_ORDER_OCCUPANCY, XSCF_NULL, 2, 2, "order_occupancy", nullptr, nullptr, nullptr },
{ XSLFI_MORE_COND_ORDERS, XSCF_NULL, 17, 17, "more_cond_orders", nullptr, nullptr, nullptr },
{ XSLFI_EXTRA_LARGE_MAP, XSCF_NULL, 0, 1, "extra_large_map", nullptr, nullptr, nullptr },

@ -84,14 +84,14 @@ byte _age_cargo_skip_counter; ///< Skip aging of cargo? Used before savegame ver
extern TimeoutTimer<TimerGameTick> _new_competitor_timeout;
static const NamedSaveLoad _date_desc[] = {
NSL("", SLEG_CONDVAR(_date, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31)),
NSL("date", SLEG_CONDVAR(_date, SLE_INT32, SLV_31, SL_MAX_VERSION)),
NSL("date_fract", SLEG_VAR(_date_fract, SLE_UINT16)),
NSL("", SLEG_CONDVAR(CalTime::Detail::now.cal_date, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31)),
NSL("date", SLEG_CONDVAR(CalTime::Detail::now.cal_date, SLE_INT32, SLV_31, SL_MAX_VERSION)),
NSL("date_fract", SLEG_VAR(CalTime::Detail::now.cal_date_fract, SLE_UINT16)),
NSL("", SLEG_CONDVAR_X(_tick_counter, SLE_FILE_U16 | SLE_VAR_U64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_U64_TICK_COUNTER, 0, 0))),
NSL("tick_counter", SLEG_CONDVAR_X(_tick_counter, SLE_UINT64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_U64_TICK_COUNTER))),
NSL("tick_skip_counter", SLEG_CONDVAR_X(_tick_skip_counter, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_VARIABLE_DAY_LENGTH))),
NSL("tick_skip_counter", SLEG_CONDVAR_X(DateDetail::_tick_skip_counter, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_VARIABLE_DAY_LENGTH))),
NSL("scaled_tick_counter", SLEG_CONDVAR_X(_scaled_tick_counter, SLE_UINT64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_VARIABLE_DAY_LENGTH, 3))),
NSL("", SLEG_CONDVAR_X(_state_ticks_offset, SLE_INT64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_VARIABLE_DAY_LENGTH, 3, 3))),
NSL("", SLEG_CONDVAR_X(DateDetail::_state_ticks_offset, SLE_INT64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_VARIABLE_DAY_LENGTH, 3, 3))),
NSL("state_ticks", SLEG_CONDVAR_X(_state_ticks, SLE_INT64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_VARIABLE_DAY_LENGTH, 4))),
NSL("", SLE_CONDNULL(2, SL_MIN_VERSION, SLV_157)), // _vehicle_id_ctr_day
NSL("", SLEG_CONDVAR(_age_cargo_skip_counter, SLE_UINT8, SL_MIN_VERSION, SLV_162)),
@ -122,6 +122,9 @@ static const NamedSaveLoad _date_desc[] = {
/* New (table only) fields below */
NSLT("id", SLEG_CONDSSTR_X(_savegame_id, SLE_STR, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SAVEGAME_ID))),
NSLT("economy_date", SLEG_CONDVAR_X(EconTime::Detail::now.econ_date, SLE_INT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_VARIABLE_DAY_LENGTH, 5))),
NSLT("economy_date_fract", SLEG_CONDVAR_X(EconTime::Detail::now.econ_date_fract, SLE_UINT16, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_VARIABLE_DAY_LENGTH, 5))),
NSLT("calendar_sub_date_fract", SLEG_CONDVAR_X(CalTime::Detail::now.sub_date_fract, SLE_UINT16, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_VARIABLE_DAY_LENGTH, 5))),
};
static const NamedSaveLoad _date_check_desc[] = {
@ -176,7 +179,7 @@ static void Check_DATE()
{
SlLoadTableOrRiffFiltered(_date_check_desc);
if (IsSavegameVersionBefore(SLV_31)) {
_load_check_data.current_date += DAYS_TILL_ORIGINAL_BASE_YEAR.AsDelta();
_load_check_data.current_date += CalTime::DAYS_TILL_ORIGINAL_BASE_YEAR.AsDelta();
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save