OpenTTD
date.cpp
Go to the documentation of this file.
1 /* $Id: date.cpp 26482 2014-04-23 20:13:33Z rubidium $ */
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();
198 #ifdef ENABLE_NETWORK
200 #endif /* ENABLE_NETWORK */
201 
203 
204  /* check if we reached end of the game */
205  if (_cur_year == ORIGINAL_END_YEAR) {
207  /* check if we reached the maximum year, decrement dates by a year */
208  } else if (_cur_year == MAX_YEAR + 1) {
209  Vehicle *v;
210  int days_this_year;
211 
212  _cur_year--;
213  days_this_year = IsLeapYear(_cur_year) ? DAYS_IN_LEAP_YEAR : DAYS_IN_YEAR;
214  _date -= days_this_year;
215  FOR_ALL_VEHICLES(v) v->date_of_last_service -= days_this_year;
216 
217  LinkGraph *lg;
218  FOR_ALL_LINK_GRAPHS(lg) lg->ShiftDates(-days_this_year);
219 
220 #ifdef ENABLE_NETWORK
221  /* Because the _date wraps here, and text-messages expire by game-days, we have to clean out
222  * all of them if the date is set back, else those messages will hang for ever */
224 #endif /* ENABLE_NETWORK */
225  }
226 
228 }
229 
233 static void OnNewMonth()
234 {
236  _do_autosave = true;
238  }
239 
243  TownsMonthlyLoop();
244  IndustryMonthlyLoop();
247 #ifdef ENABLE_NETWORK
249 #endif /* ENABLE_NETWORK */
250 }
251 
255 static void OnNewDay()
256 {
257 #ifdef ENABLE_NETWORK
259 #endif /* ENABLE_NETWORK */
260 
261  DisasterDailyLoop();
263 
266 
267  /* Refresh after possible snowline change */
269 }
270 
276 {
277  /* increase day, and check if a new day is there? */
278  _tick_counter++;
279 
280  if (_game_mode == GM_MENU) return;
281 
282  _date_fract++;
283  if (_date_fract < DAY_TICKS) return;
284  _date_fract = 0;
285 
286  /* increase day counter */
287  _date++;
288 
289  YearMonthDay ymd;
290  ConvertDateToYMD(_date, &ymd);
291 
292  /* check if we entered a new month? */
293  bool new_month = ymd.month != _cur_month;
294 
295  /* check if we entered a new year? */
296  bool new_year = ymd.year != _cur_year;
297 
298  /* update internal variables before calling the daily/monthly/yearly loops */
299  _cur_month = ymd.month;
300  _cur_year = ymd.year;
301 
302  /* yes, call various daily loops */
303  OnNewDay();
304 
305  /* yes, call various monthly loops */
306  if (new_month) OnNewMonth();
307 
308  /* yes, call various yearly loops */
309  if (new_year) OnNewYear();
310 }
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:275
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:3120
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:1943
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:3238
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:76
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:1953
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:135
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:255
static void OnNewMonth()
Runs various procedures that have to be done monthly.
Definition: date.cpp:233
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:3134
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:57
void SubsidyMonthlyLoop()
Perform the monthly update of open subsidies, and try to create a new one.
Definition: subsidy.cpp:469
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:986
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:3148
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:967
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:278
void EnginesDailyLoop()
Functions used by the IncreaseDate function.
Definition: engine.cpp:799
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