OpenTTD Source 20241222-master-gc72542431a
timer_game_common.h
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#ifndef TIMER_GAME_COMMON_H
11#define TIMER_GAME_COMMON_H
12
13#include "../core/strong_typedef_type.hpp"
14
30template <class T>
31class TimerGame {
32public:
34 template <class ST> struct DateTag;
36
38 using DateFract = uint16_t;
39
41 template <class ST> struct YearTag;
44 using Month = uint8_t;
46 using Day = uint8_t;
47
57
63 static constexpr bool IsLeapYear(Year year)
64 {
65 int32_t year_as_int = year.base();
66 return year_as_int % 4 == 0 && (year_as_int % 100 != 0 || year_as_int % 400 == 0);
67 }
68
69 static YearMonthDay CalendarConvertDateToYMD(Date date);
70 static Date CalendarConvertYMDToDate(Year year, Month month, Day day);
71
77 static constexpr Year DateToYear(Date date)
78 {
79 /* Hardcode the number of days in a year because we can't access CalendarTime from here. */
80 return date.base() / 366;
81 }
82
88 static constexpr Date DateAtStartOfYear(Year year)
89 {
90 int32_t year_as_int = year.base();
91 uint number_of_leap_years = (year == 0) ? 0 : ((year_as_int - 1) / 4 - (year_as_int - 1) / 100 + (year_as_int - 1) / 400 + 1);
92
93 /* Hardcode the number of days in a year because we can't access CalendarTime from here. */
94 return (365 * year_as_int) + number_of_leap_years;
95 }
96
97 enum Trigger {
98 DAY,
99 WEEK,
100 MONTH,
101 QUARTER,
102 YEAR,
103 };
104
105 enum Priority {
107
108 /* All other may have a Random() call in them, so order is important.
109 * For safety, you can only setup a single timer on a single priority. */
110 COMPANY,
111 DISASTER,
112 ENGINE,
113 INDUSTRY,
114 STATION,
115 SUBSIDY,
116 TOWN,
117 VEHICLE,
118 };
119
120 struct TPeriod {
121 Trigger trigger;
122 Priority priority;
123
124 TPeriod(Trigger trigger, Priority priority) : trigger(trigger), priority(priority)
125 {}
126
127 bool operator < (const TPeriod &other) const
128 {
129 if (this->trigger != other.trigger) return this->trigger < other.trigger;
130 return this->priority < other.priority;
131 }
132
133 bool operator == (const TPeriod &other) const
134 {
135 return this->trigger == other.trigger && this->priority == other.priority;
136 }
137 };
138
139 using TElapsed = uint;
140 struct TStorage {};
141};
142
146template <class T>
148public:
149 static constexpr int DAYS_IN_YEAR = 365;
150 static constexpr int DAYS_IN_LEAP_YEAR = 366;
151 static constexpr int MONTHS_IN_YEAR = 12;
152
153 static constexpr int SECONDS_PER_DAY = 2;
154
155 /*
156 * ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR and DAYS_TILL_ORIGINAL_BASE_YEAR are
157 * primarily used for loading newgrf and savegame data and returning some
158 * newgrf (callback) functions that were in the original (TTD) inherited
159 * format, where 'TimerGame<T>::date == 0' meant that it was 1920-01-01.
160 */
161
163 static constexpr typename TimerGame<T>::Year ORIGINAL_BASE_YEAR = 1920;
165 static constexpr typename TimerGame<T>::Year ORIGINAL_END_YEAR = 2051;
167 static constexpr typename TimerGame<T>::Year ORIGINAL_MAX_YEAR = 2090;
168
173 static constexpr typename TimerGame<T>::Year MAX_YEAR = 5000000;
174
176 static constexpr typename TimerGame<T>::Year MIN_YEAR = 0;
177
179 static constexpr typename TimerGame<T>::Year DEF_START_YEAR = 1950;
181 static constexpr typename TimerGame<T>::Year DEF_END_YEAR = ORIGINAL_END_YEAR - 1;
182
185
188
190 static constexpr typename TimerGame<T>::Date MIN_DATE = 0;
191
192 static constexpr typename TimerGame<T>::Year INVALID_YEAR = -1;
193 static constexpr typename TimerGame<T>::Date INVALID_DATE = -1;
194};
195
196#endif /* TIMER_GAME_COMMON_H */
Template class for time constants shared by both Calendar and Economy time.
static constexpr TimerGame< T >::Year DEF_START_YEAR
The default starting year.
static constexpr TimerGame< T >::Date MIN_DATE
The date on January 1, year 0.
static constexpr TimerGame< T >::Year DEF_END_YEAR
The default scoring end year.
static constexpr TimerGame< T >::Year ORIGINAL_MAX_YEAR
The maximum year of the original TTD.
static constexpr int MONTHS_IN_YEAR
months per year
static constexpr TimerGame< T >::Year ORIGINAL_END_YEAR
The original ending year.
static constexpr TimerGame< T >::Year INVALID_YEAR
Representation of an invalid year.
static constexpr TimerGame< T >::Year MIN_YEAR
The absolute minimum year in OTTD.
static constexpr TimerGame< T >::Date INVALID_DATE
Representation of an invalid date.
static constexpr int SECONDS_PER_DAY
approximate seconds per day, not for precise calculations
static constexpr TimerGame< T >::Date MAX_DATE
The date of the last day of the max year.
static constexpr int DAYS_IN_YEAR
days per year
static constexpr TimerGame< T >::Year ORIGINAL_BASE_YEAR
The minimum starting year/base year of the original TTD.
static constexpr TimerGame< T >::Date DAYS_TILL_ORIGINAL_BASE_YEAR
The date of the first day of the original base year.
static constexpr TimerGame< T >::Year MAX_YEAR
MAX_YEAR, nicely rounded value of the number of years that can be encoded in a single 32 bits date,...
static constexpr int DAYS_IN_LEAP_YEAR
sometimes, you need one day more...
Template class for all TimerGame based timers.
static constexpr Year DateToYear(Date date)
Calculate the year of a given date.
static YearMonthDay CalendarConvertDateToYMD(Date date)
Converts a Date to a Year, Month & Day.
static constexpr Date DateAtStartOfYear(Year year)
Calculate the date of the first day of a given year.
uint16_t DateFract
The fraction of a date we're in, i.e.
static Date CalendarConvertYMDToDate(Year year, Month month, Day day)
Converts a tuple of Year, Month and Day to a Date.
@ NONE
These timers can be executed in any order; there is no Random() in them, so order is not relevant.
uint8_t Day
Type for the day of the month, note: 1 based, first day of a month is 1.
uint8_t Month
Type for the month, note: 0 based, i.e.
static constexpr bool IsLeapYear(Year year)
Checks whether the given year is a leap year or not.
Mix-in which makes the new Typedef comparable with itself and its base type.
Mix-in which makes the new Typedef behave more like an integer.
Templated helper to make a type-safe 'typedef' representing a single POD value.
The type to store our dates in.
Data structure to convert between Date and triplet (year, month, and day).
Month month
Month (0..11)
Type for the year, note: 0 based, i.e.