OpenTTD
date.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of OpenTTD.
3  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6  */
7 
10 #include "stdafx.h"
11 #include "network/network.h"
12 #include "network/network_func.h"
13 #include "currency.h"
14 #include "window_func.h"
15 #include "settings_type.h"
16 #include "date_func.h"
17 #include "vehicle_base.h"
18 #include "rail_gui.h"
19 #include "linkgraph/linkgraph.h"
20 #include "saveload/saveload.h"
21 
22 #include "safeguards.h"
23 
28 uint16 _tick_counter;
29 
35 void SetDate(Date date, DateFract fract)
36 {
37  assert(fract < DAY_TICKS);
38 
39  YearMonthDay ymd;
40 
41  _date = date;
42  _date_fract = fract;
43  ConvertDateToYMD(date, &ymd);
44  _cur_year = ymd.year;
45  _cur_month = ymd.month;
46 }
47 
48 #define M(a, b) ((a << 5) | b)
49 static const uint16 _month_date_from_year_day[] = {
50  M( 0, 1), M( 0, 2), M( 0, 3), M( 0, 4), M( 0, 5), M( 0, 6), M( 0, 7), M( 0, 8), M( 0, 9), M( 0, 10), M( 0, 11), M( 0, 12), M( 0, 13), M( 0, 14), M( 0, 15), M( 0, 16), M( 0, 17), M( 0, 18), M( 0, 19), M( 0, 20), M( 0, 21), M( 0, 22), M( 0, 23), M( 0, 24), M( 0, 25), M( 0, 26), M( 0, 27), M( 0, 28), M( 0, 29), M( 0, 30), M( 0, 31),
51  M( 1, 1), M( 1, 2), M( 1, 3), M( 1, 4), M( 1, 5), M( 1, 6), M( 1, 7), M( 1, 8), M( 1, 9), M( 1, 10), M( 1, 11), M( 1, 12), M( 1, 13), M( 1, 14), M( 1, 15), M( 1, 16), M( 1, 17), M( 1, 18), M( 1, 19), M( 1, 20), M( 1, 21), M( 1, 22), M( 1, 23), M( 1, 24), M( 1, 25), M( 1, 26), M( 1, 27), M( 1, 28), M( 1, 29),
52  M( 2, 1), M( 2, 2), M( 2, 3), M( 2, 4), M( 2, 5), M( 2, 6), M( 2, 7), M( 2, 8), M( 2, 9), M( 2, 10), M( 2, 11), M( 2, 12), M( 2, 13), M( 2, 14), M( 2, 15), M( 2, 16), M( 2, 17), M( 2, 18), M( 2, 19), M( 2, 20), M( 2, 21), M( 2, 22), M( 2, 23), M( 2, 24), M( 2, 25), M( 2, 26), M( 2, 27), M( 2, 28), M( 2, 29), M( 2, 30), M( 2, 31),
53  M( 3, 1), M( 3, 2), M( 3, 3), M( 3, 4), M( 3, 5), M( 3, 6), M( 3, 7), M( 3, 8), M( 3, 9), M( 3, 10), M( 3, 11), M( 3, 12), M( 3, 13), M( 3, 14), M( 3, 15), M( 3, 16), M( 3, 17), M( 3, 18), M( 3, 19), M( 3, 20), M( 3, 21), M( 3, 22), M( 3, 23), M( 3, 24), M( 3, 25), M( 3, 26), M( 3, 27), M( 3, 28), M( 3, 29), M( 3, 30),
54  M( 4, 1), M( 4, 2), M( 4, 3), M( 4, 4), M( 4, 5), M( 4, 6), M( 4, 7), M( 4, 8), M( 4, 9), M( 4, 10), M( 4, 11), M( 4, 12), M( 4, 13), M( 4, 14), M( 4, 15), M( 4, 16), M( 4, 17), M( 4, 18), M( 4, 19), M( 4, 20), M( 4, 21), M( 4, 22), M( 4, 23), M( 4, 24), M( 4, 25), M( 4, 26), M( 4, 27), M( 4, 28), M( 4, 29), M( 4, 30), M( 4, 31),
55  M( 5, 1), M( 5, 2), M( 5, 3), M( 5, 4), M( 5, 5), M( 5, 6), M( 5, 7), M( 5, 8), M( 5, 9), M( 5, 10), M( 5, 11), M( 5, 12), M( 5, 13), M( 5, 14), M( 5, 15), M( 5, 16), M( 5, 17), M( 5, 18), M( 5, 19), M( 5, 20), M( 5, 21), M( 5, 22), M( 5, 23), M( 5, 24), M( 5, 25), M( 5, 26), M( 5, 27), M( 5, 28), M( 5, 29), M( 5, 30),
56  M( 6, 1), M( 6, 2), M( 6, 3), M( 6, 4), M( 6, 5), M( 6, 6), M( 6, 7), M( 6, 8), M( 6, 9), M( 6, 10), M( 6, 11), M( 6, 12), M( 6, 13), M( 6, 14), M( 6, 15), M( 6, 16), M( 6, 17), M( 6, 18), M( 6, 19), M( 6, 20), M( 6, 21), M( 6, 22), M( 6, 23), M( 6, 24), M( 6, 25), M( 6, 26), M( 6, 27), M( 6, 28), M( 6, 29), M( 6, 30), M( 6, 31),
57  M( 7, 1), M( 7, 2), M( 7, 3), M( 7, 4), M( 7, 5), M( 7, 6), M( 7, 7), M( 7, 8), M( 7, 9), M( 7, 10), M( 7, 11), M( 7, 12), M( 7, 13), M( 7, 14), M( 7, 15), M( 7, 16), M( 7, 17), M( 7, 18), M( 7, 19), M( 7, 20), M( 7, 21), M( 7, 22), M( 7, 23), M( 7, 24), M( 7, 25), M( 7, 26), M( 7, 27), M( 7, 28), M( 7, 29), M( 7, 30), M( 7, 31),
58  M( 8, 1), M( 8, 2), M( 8, 3), M( 8, 4), M( 8, 5), M( 8, 6), M( 8, 7), M( 8, 8), M( 8, 9), M( 8, 10), M( 8, 11), M( 8, 12), M( 8, 13), M( 8, 14), M( 8, 15), M( 8, 16), M( 8, 17), M( 8, 18), M( 8, 19), M( 8, 20), M( 8, 21), M( 8, 22), M( 8, 23), M( 8, 24), M( 8, 25), M( 8, 26), M( 8, 27), M( 8, 28), M( 8, 29), M( 8, 30),
59  M( 9, 1), M( 9, 2), M( 9, 3), M( 9, 4), M( 9, 5), M( 9, 6), M( 9, 7), M( 9, 8), M( 9, 9), M( 9, 10), M( 9, 11), M( 9, 12), M( 9, 13), M( 9, 14), M( 9, 15), M( 9, 16), M( 9, 17), M( 9, 18), M( 9, 19), M( 9, 20), M( 9, 21), M( 9, 22), M( 9, 23), M( 9, 24), M( 9, 25), M( 9, 26), M( 9, 27), M( 9, 28), M( 9, 29), M( 9, 30), M( 9, 31),
60  M(10, 1), M(10, 2), M(10, 3), M(10, 4), M(10, 5), M(10, 6), M(10, 7), M(10, 8), M(10, 9), M(10, 10), M(10, 11), M(10, 12), M(10, 13), M(10, 14), M(10, 15), M(10, 16), M(10, 17), M(10, 18), M(10, 19), M(10, 20), M(10, 21), M(10, 22), M(10, 23), M(10, 24), M(10, 25), M(10, 26), M(10, 27), M(10, 28), M(10, 29), M(10, 30),
61  M(11, 1), M(11, 2), M(11, 3), M(11, 4), M(11, 5), M(11, 6), M(11, 7), M(11, 8), M(11, 9), M(11, 10), M(11, 11), M(11, 12), M(11, 13), M(11, 14), M(11, 15), M(11, 16), M(11, 17), M(11, 18), M(11, 19), M(11, 20), M(11, 21), M(11, 22), M(11, 23), M(11, 24), M(11, 25), M(11, 26), M(11, 27), M(11, 28), M(11, 29), M(11, 30), M(11, 31),
62 };
63 #undef M
64 
65 enum DaysTillMonth {
66  ACCUM_JAN = 0,
67  ACCUM_FEB = ACCUM_JAN + 31,
68  ACCUM_MAR = ACCUM_FEB + 29,
69  ACCUM_APR = ACCUM_MAR + 31,
70  ACCUM_MAY = ACCUM_APR + 30,
71  ACCUM_JUN = ACCUM_MAY + 31,
72  ACCUM_JUL = ACCUM_JUN + 30,
73  ACCUM_AUG = ACCUM_JUL + 31,
74  ACCUM_SEP = ACCUM_AUG + 31,
75  ACCUM_OCT = ACCUM_SEP + 30,
76  ACCUM_NOV = ACCUM_OCT + 31,
77  ACCUM_DEC = ACCUM_NOV + 30,
78 };
79 
81 static const uint16 _accum_days_for_month[] = {
82  ACCUM_JAN, ACCUM_FEB, ACCUM_MAR, ACCUM_APR,
83  ACCUM_MAY, ACCUM_JUN, ACCUM_JUL, ACCUM_AUG,
84  ACCUM_SEP, ACCUM_OCT, ACCUM_NOV, ACCUM_DEC,
85 };
86 
93 {
94  /* Year determination in multiple steps to account for leap
95  * years. First do the large steps, then the smaller ones.
96  */
97 
98  /* There are 97 leap years in 400 years */
99  Year yr = 400 * (date / (DAYS_IN_YEAR * 400 + 97));
100  int rem = date % (DAYS_IN_YEAR * 400 + 97);
101  uint16 x;
102 
103  if (rem >= DAYS_IN_YEAR * 100 + 25) {
104  /* There are 25 leap years in the first 100 years after
105  * every 400th year, as every 400th year is a leap year */
106  yr += 100;
107  rem -= DAYS_IN_YEAR * 100 + 25;
108 
109  /* There are 24 leap years in the next couple of 100 years */
110  yr += 100 * (rem / (DAYS_IN_YEAR * 100 + 24));
111  rem = (rem % (DAYS_IN_YEAR * 100 + 24));
112  }
113 
114  if (!IsLeapYear(yr) && rem >= DAYS_IN_YEAR * 4) {
115  /* The first 4 year of the century are not always a leap year */
116  yr += 4;
117  rem -= DAYS_IN_YEAR * 4;
118  }
119 
120  /* There is 1 leap year every 4 years */
121  yr += 4 * (rem / (DAYS_IN_YEAR * 4 + 1));
122  rem = rem % (DAYS_IN_YEAR * 4 + 1);
123 
124  /* The last (max 3) years to account for; the first one
125  * can be, but is not necessarily a leap year */
126  while (rem >= (IsLeapYear(yr) ? DAYS_IN_LEAP_YEAR : DAYS_IN_YEAR)) {
128  yr++;
129  }
130 
131  /* Skip the 29th of February in non-leap years */
132  if (!IsLeapYear(yr) && rem >= ACCUM_MAR - 1) rem++;
133 
134  ymd->year = yr;
135 
136  x = _month_date_from_year_day[rem];
137  ymd->month = x >> 5;
138  ymd->day = x & 0x1F;
139 }
140 
147 Date ConvertYMDToDate(Year year, Month month, Day day)
148 {
149  /* Day-offset in a leap year */
150  int days = _accum_days_for_month[month] + day - 1;
151 
152  /* Account for the missing of the 29th of February in non-leap years */
153  if (!IsLeapYear(year) && days >= ACCUM_MAR) days--;
154 
155  return DAYS_TILL(year) + days;
156 }
157 
160 extern void EnginesDailyLoop();
161 extern void DisasterDailyLoop();
162 extern void IndustryDailyLoop();
163 
164 extern void CompaniesMonthlyLoop();
165 extern void EnginesMonthlyLoop();
166 extern void TownsMonthlyLoop();
167 extern void IndustryMonthlyLoop();
168 extern void StationMonthlyLoop();
169 extern void SubsidyMonthlyLoop();
170 
171 extern void CompaniesYearlyLoop();
172 extern void VehiclesYearlyLoop();
173 extern void TownsYearlyLoop();
174 
175 extern void ShowEndGameChart();
176 
177 
179 static const Month _autosave_months[] = {
180  0,
181  1,
182  3,
183  6,
184  12,
185 };
186 
190 static void OnNewYear()
191 {
193  VehiclesYearlyLoop();
194  TownsYearlyLoop();
197 
199 
200  /* check if we reached end of the game */
201  if (_cur_year == ORIGINAL_END_YEAR) {
203  /* check if we reached the maximum year, decrement dates by a year */
204  } else if (_cur_year == MAX_YEAR + 1) {
205  int days_this_year;
206 
207  _cur_year--;
208  days_this_year = IsLeapYear(_cur_year) ? DAYS_IN_LEAP_YEAR : DAYS_IN_YEAR;
209  _date -= days_this_year;
210  for (Vehicle *v : Vehicle::Iterate()) v->date_of_last_service -= days_this_year;
211  for (LinkGraph *lg : LinkGraph::Iterate()) lg->ShiftDates(-days_this_year);
212 
213  /* Because the _date wraps here, and text-messages expire by game-days, we have to clean out
214  * all of them if the date is set back, else those messages will hang for ever */
216  }
217 
219 }
220 
224 static void OnNewMonth()
225 {
227  _do_autosave = true;
229  }
230 
234  TownsMonthlyLoop();
235  IndustryMonthlyLoop();
239 }
240 
244 static void OnNewDay()
245 {
247 
248  DisasterDailyLoop();
250 
253 
254  /* Refresh after possible snowline change */
256 }
257 
263 {
264  /* increase day, and check if a new day is there? */
265  _tick_counter++;
266 
267  if (_game_mode == GM_MENU) return;
268 
269  _date_fract++;
270  if (_date_fract < DAY_TICKS) return;
271  _date_fract = 0;
272 
273  /* increase day counter */
274  _date++;
275 
276  YearMonthDay ymd;
277  ConvertDateToYMD(_date, &ymd);
278 
279  /* check if we entered a new month? */
280  bool new_month = ymd.month != _cur_month;
281 
282  /* check if we entered a new year? */
283  bool new_year = ymd.year != _cur_year;
284 
285  /* update internal variables before calling the daily/monthly/yearly loops */
286  _cur_month = ymd.month;
287  _cur_year = ymd.year;
288 
289  /* yes, call various daily loops */
290  OnNewDay();
291 
292  /* yes, call various monthly loops */
293  if (new_month) OnNewMonth();
294 
295  /* yes, call various yearly loops */
296  if (new_year) OnNewYear();
297 }
void CompaniesYearlyLoop()
A year has passed, update the economic data of all companies, and perhaps show the financial overview...
void IncreaseDate()
Increases the tick counter, increases date and possibly calls procedures that have to be called daily...
Definition: date.cpp:262
static const int DAYS_IN_YEAR
days per year
Definition: date_type.h:29
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
Definition: window.cpp:3215
void StationMonthlyLoop()
Monthly loop for stations.
Functions related to dates.
Day day
Day (1..31)
Definition: date_type.h:104
Functions to handle different currencies.
void CompaniesMonthlyLoop()
Monthly update of the economic data (of the companies as well as economic fluctuations).
Definition: economy.cpp:1948
static void OnNewYear()
Runs various procedures that have to be done yearly.
Definition: date.cpp:190
Vehicle data structure.
Definition: vehicle_base.h:210
static const int DAY_TICKS
1 day is 74 ticks; _date_fract used to be uint16 and incremented by 885.
Definition: date_type.h:28
int32 Year
Type for the year, note: 0 based, i.e. starts at the year 0.
Definition: date_type.h:18
Year _cur_year
Current year, starting at 0.
Definition: date.cpp:24
void NetworkServerDailyLoop()
Daily "callback".
Functions/types etc.
A connected component of a link graph.
Definition: linkgraph.h:38
void InvalidateWindowClassesData(WindowClass cls, int data, bool gui_scope)
Mark window data of all windows of a given class as invalid (in need of re-computing) Note that by de...
Definition: window.cpp:3334
void SetDate(Date date, DateFract fract)
Set the date.
Definition: date.cpp:35
Functions/types related to saving and loading games.
DateFract _date_fract
Fractional part of the day.
Definition: date.cpp:27
bool auto_euro
automatically switch to euro in 2002
ClientSettings _settings_client
The current settings for this game.
Definition: settings.cpp:78
Types related to global configuration settings.
void NetworkServerYearlyLoop()
Yearly "callback".
Definition of base types and functions in a cross-platform compatible way.
Data structure to convert between Date and triplet (year, month, and day).
Definition: date_type.h:101
A number of safeguards to prevent using unsafe methods.
bool ResetSignalVariant(int32 p)
Updates the current signal variant used in the signal GUI to the one adequate to current year...
Definition: rail_gui.cpp:1959
Year semaphore_build_before
build semaphore signals automatically before this year
uint16 DateFract
The fraction of a date we&#39;re in, i.e. the number of ticks since the last date changeover.
Definition: date_type.h:15
#define DAYS_TILL(year)
Calculate the date of the first day of a given year.
Definition: date_type.h:74
Year year
Year (0...)
Definition: date_type.h:102
Basic functions/variables used all over the place.
Build station; Window numbers:
Definition: window_type.h:390
uint8 Month
Type for the month, note: 0 based, i.e. 0 = January, 11 = December.
Definition: date_type.h:19
Month month
Month (0..11)
Definition: date_type.h:103
static bool IsLeapYear(Year yr)
Checks whether the given year is a leap year or not.
Definition: date_func.h:30
void CheckSwitchToEuro()
Verify if the currency chosen by the user is about to be converted to Euro.
Definition: currency.cpp:138
Month _cur_month
Current month (0..11)
Definition: date.cpp:25
uint16 _tick_counter
Ever incrementing (and sometimes wrapping) tick counter for setting off various events.
Definition: date.cpp:28
void ShowEndGameChart()
Show the endgame victory screen in 2050.
void NetworkInitChatMessage()
Initialize all buffers of the chat visualisation.
static const uint16 _accum_days_for_month[]
Number of days to pass from the first day in the year before reaching the first of a month...
Definition: date.cpp:81
static void OnNewDay()
Runs various procedures that have to be done daily.
Definition: date.cpp:244
static void OnNewMonth()
Runs various procedures that have to be done monthly.
Definition: date.cpp:224
GUISettings gui
settings related to the GUI
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
Definition: pool_type.hpp:340
Cheat window; Window numbers:
Definition: window_type.h:618
void SetWindowWidgetDirty(WindowClass cls, WindowNumber number, byte widget_index)
Mark a particular widget in a particular window as dirty (in need of repainting)
Definition: window.cpp:3229
Base class for all vehicles.
Town view; Window numbers:
Definition: window_type.h:326
static const Month _autosave_months[]
Available settings for autosave intervals.
Definition: date.cpp:179
uint8 Day
Type for the day of the month, note: 1 based, first day of a month is 1.
Definition: date_type.h:20
Statusbar (at the bottom of your screen); Window numbers:
Definition: window_type.h:57
Network functions used by other parts of OpenTTD.
bool _network_server
network-server is active
Definition: network.cpp:53
void SubsidyMonthlyLoop()
Perform the monthly update of open subsidies, and try to create a new one.
Definition: subsidy.cpp:466
void IndustryDailyLoop()
Daily handler for the industry changes Taking the original map size of 256*256, the number of random ...
Declaration of link graph classes used for cargo distribution.
int32 Date
The type to store our dates in.
Definition: date_type.h:14
void NetworkServerMonthlyLoop()
Monthly "callback".
Date ConvertYMDToDate(Year year, Month month, Day day)
Converts a tuple of Year, Month and Day to a Date.
Definition: date.cpp:147
Window functions not directly related to making/drawing windows.
void SetWindowClassesDirty(WindowClass cls)
Mark all windows of a particular class as dirty (in need of repainting)
Definition: window.cpp:3243
Date _date
Current date in days (day counter)
Definition: date.cpp:26
void ConvertDateToYMD(Date date, YearMonthDay *ymd)
Converts a Date to a Year, Month & Day.
Definition: date.cpp:92
void EnginesMonthlyLoop()
Monthly update of the availability, reliability, and preview offers of the engines.
Definition: engine.cpp:966
byte autosave
how often should we do autosaves?
static const Year MAX_YEAR
MAX_YEAR, nicely rounded value of the number of years that can be encoded in a single 32 bits date...
Definition: date_type.h:92
bool _do_autosave
are we doing an autosave at the moment?
Definition: saveload.cpp:64
void EnginesDailyLoop()
Functions used by the IncreaseDate function.
Definition: engine.cpp:801
static const int DAYS_IN_LEAP_YEAR
sometimes, you need one day more...
Definition: date_type.h:30
static const Year ORIGINAL_END_YEAR
The original ending year.
Definition: date_type.h:51