OpenTTD
date.cpp
Go to the documentation of this file.
1 /* $Id$ */
2 
3 /*
4  * This file is part of OpenTTD.
5  * 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.
6  * 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.
7  * 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/>.
8  */
9 
12 #include "stdafx.h"
13 #include "network/network.h"
14 #include "network/network_func.h"
15 #include "currency.h"
16 #include "window_func.h"
17 #include "settings_type.h"
18 #include "date_func.h"
19 #include "vehicle_base.h"
20 #include "rail_gui.h"
21 #include "linkgraph/linkgraph.h"
22 #include "saveload/saveload.h"
23 
24 #include "safeguards.h"
25 
30 uint16 _tick_counter;
31 
37 void SetDate(Date date, DateFract fract)
38 {
39  assert(fract < DAY_TICKS);
40 
41  YearMonthDay ymd;
42 
43  _date = date;
44  _date_fract = fract;
45  ConvertDateToYMD(date, &ymd);
46  _cur_year = ymd.year;
47  _cur_month = ymd.month;
48 }
49 
50 #define M(a, b) ((a << 5) | b)
51 static const uint16 _month_date_from_year_day[] = {
52  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),
53  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),
54  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),
55  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),
56  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),
57  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),
58  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),
59  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),
60  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),
61  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),
62  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),
63  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),
64 };
65 #undef M
66 
67 enum DaysTillMonth {
68  ACCUM_JAN = 0,
69  ACCUM_FEB = ACCUM_JAN + 31,
70  ACCUM_MAR = ACCUM_FEB + 29,
71  ACCUM_APR = ACCUM_MAR + 31,
72  ACCUM_MAY = ACCUM_APR + 30,
73  ACCUM_JUN = ACCUM_MAY + 31,
74  ACCUM_JUL = ACCUM_JUN + 30,
75  ACCUM_AUG = ACCUM_JUL + 31,
76  ACCUM_SEP = ACCUM_AUG + 31,
77  ACCUM_OCT = ACCUM_SEP + 30,
78  ACCUM_NOV = ACCUM_OCT + 31,
79  ACCUM_DEC = ACCUM_NOV + 30,
80 };
81 
83 static const uint16 _accum_days_for_month[] = {
84  ACCUM_JAN, ACCUM_FEB, ACCUM_MAR, ACCUM_APR,
85  ACCUM_MAY, ACCUM_JUN, ACCUM_JUL, ACCUM_AUG,
86  ACCUM_SEP, ACCUM_OCT, ACCUM_NOV, ACCUM_DEC,
87 };
88 
95 {
96  /* Year determination in multiple steps to account for leap
97  * years. First do the large steps, then the smaller ones.
98  */
99 
100  /* There are 97 leap years in 400 years */
101  Year yr = 400 * (date / (DAYS_IN_YEAR * 400 + 97));
102  int rem = date % (DAYS_IN_YEAR * 400 + 97);
103  uint16 x;
104 
105  if (rem >= DAYS_IN_YEAR * 100 + 25) {
106  /* There are 25 leap years in the first 100 years after
107  * every 400th year, as every 400th year is a leap year */
108  yr += 100;
109  rem -= DAYS_IN_YEAR * 100 + 25;
110 
111  /* There are 24 leap years in the next couple of 100 years */
112  yr += 100 * (rem / (DAYS_IN_YEAR * 100 + 24));
113  rem = (rem % (DAYS_IN_YEAR * 100 + 24));
114  }
115 
116  if (!IsLeapYear(yr) && rem >= DAYS_IN_YEAR * 4) {
117  /* The first 4 year of the century are not always a leap year */
118  yr += 4;
119  rem -= DAYS_IN_YEAR * 4;
120  }
121 
122  /* There is 1 leap year every 4 years */
123  yr += 4 * (rem / (DAYS_IN_YEAR * 4 + 1));
124  rem = rem % (DAYS_IN_YEAR * 4 + 1);
125 
126  /* The last (max 3) years to account for; the first one
127  * can be, but is not necessarily a leap year */
128  while (rem >= (IsLeapYear(yr) ? DAYS_IN_LEAP_YEAR : DAYS_IN_YEAR)) {
130  yr++;
131  }
132 
133  /* Skip the 29th of February in non-leap years */
134  if (!IsLeapYear(yr) && rem >= ACCUM_MAR - 1) rem++;
135 
136  ymd->year = yr;
137 
138  x = _month_date_from_year_day[rem];
139  ymd->month = x >> 5;
140  ymd->day = x & 0x1F;
141 }
142 
149 Date ConvertYMDToDate(Year year, Month month, Day day)
150 {
151  /* Day-offset in a leap year */
152  int days = _accum_days_for_month[month] + day - 1;
153 
154  /* Account for the missing of the 29th of February in non-leap years */
155  if (!IsLeapYear(year) && days >= ACCUM_MAR) days--;
156 
157  return DAYS_TILL(year) + days;
158 }
159 
162 extern void EnginesDailyLoop();
163 extern void DisasterDailyLoop();
164 extern void IndustryDailyLoop();
165 
166 extern void CompaniesMonthlyLoop();
167 extern void EnginesMonthlyLoop();
168 extern void TownsMonthlyLoop();
169 extern void IndustryMonthlyLoop();
170 extern void StationMonthlyLoop();
171 extern void SubsidyMonthlyLoop();
172 
173 extern void CompaniesYearlyLoop();
174 extern void VehiclesYearlyLoop();
175 extern void TownsYearlyLoop();
176 
177 extern void ShowEndGameChart();
178 
179 
181 static const Month _autosave_months[] = {
182  0,
183  1,
184  3,
185  6,
186  12,
187 };
188 
192 static void OnNewYear()
193 {
195  VehiclesYearlyLoop();
196  TownsYearlyLoop();
199 
201 
202  /* check if we reached end of the game */
203  if (_cur_year == ORIGINAL_END_YEAR) {
205  /* check if we reached the maximum year, decrement dates by a year */
206  } else if (_cur_year == MAX_YEAR + 1) {
207  Vehicle *v;
208  int days_this_year;
209 
210  _cur_year--;
211  days_this_year = IsLeapYear(_cur_year) ? DAYS_IN_LEAP_YEAR : DAYS_IN_YEAR;
212  _date -= days_this_year;
213  FOR_ALL_VEHICLES(v) v->date_of_last_service -= days_this_year;
214 
215  LinkGraph *lg;
216  FOR_ALL_LINK_GRAPHS(lg) lg->ShiftDates(-days_this_year);
217 
218  /* Because the _date wraps here, and text-messages expire by game-days, we have to clean out
219  * all of them if the date is set back, else those messages will hang for ever */
221  }
222 
224 }
225 
229 static void OnNewMonth()
230 {
232  _do_autosave = true;
234  }
235 
239  TownsMonthlyLoop();
240  IndustryMonthlyLoop();
244 }
245 
249 static void OnNewDay()
250 {
252 
253  DisasterDailyLoop();
255 
258 
259  /* Refresh after possible snowline change */
261 }
262 
268 {
269  /* increase day, and check if a new day is there? */
270  _tick_counter++;
271 
272  if (_game_mode == GM_MENU) return;
273 
274  _date_fract++;
275  if (_date_fract < DAY_TICKS) return;
276  _date_fract = 0;
277 
278  /* increase day counter */
279  _date++;
280 
281  YearMonthDay ymd;
282  ConvertDateToYMD(_date, &ymd);
283 
284  /* check if we entered a new month? */
285  bool new_month = ymd.month != _cur_month;
286 
287  /* check if we entered a new year? */
288  bool new_year = ymd.year != _cur_year;
289 
290  /* update internal variables before calling the daily/monthly/yearly loops */
291  _cur_month = ymd.month;
292  _cur_year = ymd.year;
293 
294  /* yes, call various daily loops */
295  OnNewDay();
296 
297  /* yes, call various monthly loops */
298  if (new_month) OnNewMonth();
299 
300  /* yes, call various yearly loops */
301  if (new_year) OnNewYear();
302 }
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:267
static const int DAYS_IN_YEAR
days per year
Definition: date_type.h:31
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
Definition: window.cpp:3199
void StationMonthlyLoop()
Monthly loop for stations.
Functions related to dates.
Day day
Day (1..31)
Definition: date_type.h:106
Functions to handle different currencies.
void CompaniesMonthlyLoop()
Monthly update of the economic data (of the companies as well as economic fluctuations).
Definition: economy.cpp:1966
static void OnNewYear()
Runs various procedures that have to be done yearly.
Definition: date.cpp:192
Vehicle data structure.
Definition: vehicle_base.h:212
static const int DAY_TICKS
1 day is 74 ticks; _date_fract used to be uint16 and incremented by 885.
Definition: date_type.h:30
void ShiftDates(int interval)
Shift all dates by given interval.
Definition: linkgraph.cpp:54
int32 Year
Type for the year, note: 0 based, i.e. starts at the year 0.
Definition: date_type.h:20
Year _cur_year
Current year, starting at 0.
Definition: date.cpp:26
void NetworkServerDailyLoop()
Daily "callback".
Functions/types etc.
A connected component of a link graph.
Definition: linkgraph.h:40
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:3318
void SetDate(Date date, DateFract fract)
Set the date.
Definition: date.cpp:37
Functions/types related to saving and loading games.
DateFract _date_fract
Fractional part of the day.
Definition: date.cpp:29
bool auto_euro
automatically switch to euro in 2002
ClientSettings _settings_client
The current settings for this game.
Definition: settings.cpp:80
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:103
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:1958
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:17
#define DAYS_TILL(year)
Calculate the date of the first day of a given year.
Definition: date_type.h:76
Year year
Year (0...)
Definition: date_type.h:104
Basic functions/variables used all over the place.
Build station; Window numbers:
Definition: window_type.h:392
uint8 Month
Type for the month, note: 0 based, i.e. 0 = January, 11 = December.
Definition: date_type.h:21
Month month
Month (0..11)
Definition: date_type.h:105
static bool IsLeapYear(Year yr)
Checks whether the given year is a leap year or not.
Definition: date_func.h:32
void CheckSwitchToEuro()
Verify if the currency chosen by the user is about to be converted to Euro.
Definition: currency.cpp:140
Month _cur_month
Current month (0..11)
Definition: date.cpp:27
uint16 _tick_counter
Ever incrementing (and sometimes wrapping) tick counter for setting off various events.
Definition: date.cpp:30
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:83
static void OnNewDay()
Runs various procedures that have to be done daily.
Definition: date.cpp:249
static void OnNewMonth()
Runs various procedures that have to be done monthly.
Definition: date.cpp:229
GUISettings gui
settings related to the GUI
Cheat window; Window numbers:
Definition: window_type.h:620
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:3213
Base class for all vehicles.
Date date_of_last_service
Last date the vehicle had a service at a depot.
Definition: vehicle_base.h:260
Town view; Window numbers:
Definition: window_type.h:328
static const Month _autosave_months[]
Available settings for autosave intervals.
Definition: date.cpp:181
uint8 Day
Type for the day of the month, note: 1 based, first day of a month is 1.
Definition: date_type.h:22
Statusbar (at the bottom of your screen); Window numbers:
Definition: window_type.h:59
Network functions used by other parts of OpenTTD.
bool _network_server
network-server is active
Definition: network.cpp:55
void SubsidyMonthlyLoop()
Perform the monthly update of open subsidies, and try to create a new one.
Definition: subsidy.cpp:473
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:16
#define FOR_ALL_VEHICLES(var)
Iterate over all vehicles.
Definition: vehicle_base.h:987
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:149
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:3227
Date _date
Current date in days (day counter)
Definition: date.cpp:28
void ConvertDateToYMD(Date date, YearMonthDay *ymd)
Converts a Date to a Year, Month & Day.
Definition: date.cpp:94
void EnginesMonthlyLoop()
Monthly update of the availability, reliability, and preview offers of the engines.
Definition: engine.cpp:979
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:94
bool _do_autosave
are we doing an autosave at the moment?
Definition: saveload.cpp:66
void EnginesDailyLoop()
Functions used by the IncreaseDate function.
Definition: engine.cpp:809
static const int DAYS_IN_LEAP_YEAR
sometimes, you need one day more...
Definition: date_type.h:32
static const Year ORIGINAL_END_YEAR
The original ending year.
Definition: date_type.h:53