00001
00002
00005 #include "stdafx.h"
00006 #include "openttd.h"
00007 #include "variables.h"
00008 #include "settings_type.h"
00009 #include "network/network.h"
00010 #include "network/network_func.h"
00011 #include "currency.h"
00012 #include "window_func.h"
00013 #include "functions.h"
00014 #include "date_func.h"
00015 #include "vehicle_base.h"
00016 #include "debug.h"
00017 #include "rail_gui.h"
00018 #include "saveload/saveload.h"
00019
00020 Year _cur_year;
00021 Month _cur_month;
00022 Date _date;
00023 DateFract _date_fract;
00024
00025
00026 void SetDate(Date date)
00027 {
00028 YearMonthDay ymd;
00029
00030 _date = date;
00031 ConvertDateToYMD(date, &ymd);
00032 _cur_year = ymd.year;
00033 _cur_month = ymd.month;
00034 }
00035
00036 #define M(a, b) ((a << 5) | b)
00037 static const uint16 _month_date_from_year_day[] = {
00038 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),
00039 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),
00040 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),
00041 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),
00042 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),
00043 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),
00044 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),
00045 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),
00046 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),
00047 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),
00048 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),
00049 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),
00050 };
00051 #undef M
00052
00053 enum {
00054 ACCUM_JAN = 0,
00055 ACCUM_FEB = ACCUM_JAN + 31,
00056 ACCUM_MAR = ACCUM_FEB + 29,
00057 ACCUM_APR = ACCUM_MAR + 31,
00058 ACCUM_MAY = ACCUM_APR + 30,
00059 ACCUM_JUN = ACCUM_MAY + 31,
00060 ACCUM_JUL = ACCUM_JUN + 30,
00061 ACCUM_AUG = ACCUM_JUL + 31,
00062 ACCUM_SEP = ACCUM_AUG + 31,
00063 ACCUM_OCT = ACCUM_SEP + 30,
00064 ACCUM_NOV = ACCUM_OCT + 31,
00065 ACCUM_DEC = ACCUM_NOV + 30,
00066 };
00067
00068 static const uint16 _accum_days_for_month[] = {
00069 ACCUM_JAN, ACCUM_FEB, ACCUM_MAR, ACCUM_APR,
00070 ACCUM_MAY, ACCUM_JUN, ACCUM_JUL, ACCUM_AUG,
00071 ACCUM_SEP, ACCUM_OCT, ACCUM_NOV, ACCUM_DEC,
00072 };
00073
00079 void ConvertDateToYMD(Date date, YearMonthDay *ymd)
00080 {
00081
00082
00083
00084
00085
00086
00087 Year yr = 400 * (date / (DAYS_IN_YEAR * 400 + 97));
00088 int rem = date % (DAYS_IN_YEAR * 400 + 97);
00089 uint16 x;
00090
00091 if (rem >= DAYS_IN_YEAR * 100 + 25) {
00092
00093
00094 yr += 100;
00095 rem -= DAYS_IN_YEAR * 100 + 25;
00096
00097
00098 yr += 100 * (rem / (DAYS_IN_YEAR * 100 + 24));
00099 rem = (rem % (DAYS_IN_YEAR * 100 + 24));
00100 }
00101
00102 if (!IsLeapYear(yr) && rem >= DAYS_IN_YEAR * 4) {
00103
00104 yr += 4;
00105 rem -= DAYS_IN_YEAR * 4;
00106 }
00107
00108
00109 yr += 4 * (rem / (DAYS_IN_YEAR * 4 + 1));
00110 rem = rem % (DAYS_IN_YEAR * 4 + 1);
00111
00112
00113
00114 while (rem >= (IsLeapYear(yr) ? DAYS_IN_LEAP_YEAR : DAYS_IN_YEAR)) {
00115 rem -= IsLeapYear(yr) ? DAYS_IN_LEAP_YEAR : DAYS_IN_YEAR;
00116 yr++;
00117 }
00118
00119
00120 if (!IsLeapYear(yr) && rem >= ACCUM_MAR - 1) rem++;
00121
00122 ymd->year = yr;
00123
00124 x = _month_date_from_year_day[rem];
00125 ymd->month = x >> 5;
00126 ymd->day = x & 0x1F;
00127 }
00128
00135 Date ConvertYMDToDate(Year year, Month month, Day day)
00136 {
00137
00138
00139
00140
00141
00142
00143
00144 int nr_of_leap_years = (year == 0) ? 0 : ((year - 1) / 4 - (year - 1) / 100 + (year - 1) / 400 + 1);
00145
00146
00147 int days = _accum_days_for_month[month] + day - 1;
00148
00149
00150 if (!IsLeapYear(year) && days >= ACCUM_MAR) days--;
00151
00152 return year * DAYS_IN_YEAR + nr_of_leap_years + days;
00153 }
00154
00157 extern void WaypointsDailyLoop();
00158 extern void EnginesDailyLoop();
00159 extern void DisasterDailyLoop();
00160 extern void IndustryDailyLoop();
00161 extern void CompaniesMonthlyLoop();
00162 extern void EnginesMonthlyLoop();
00163 extern void TownsMonthlyLoop();
00164 extern void IndustryMonthlyLoop();
00165 extern void StationMonthlyLoop();
00166
00167 extern void CompaniesYearlyLoop();
00168 extern void VehiclesYearlyLoop();
00169 extern void TownsYearlyLoop();
00170
00171 extern void ShowEndGameChart();
00172
00173
00174 static const Month _autosave_months[] = {
00175 0,
00176 1,
00177 3,
00178 6,
00179 12,
00180 };
00181
00185 static void RunVehicleDayProc(uint daytick)
00186 {
00187 uint total = GetMaxVehicleIndex() + 1;
00188 uint i;
00189
00190 for (i = daytick; i < total; i += DAY_TICKS) {
00191 Vehicle *v = GetVehicle(i);
00192
00193 if (v->IsValid()) {
00194
00195 CheckVehicle32Day(v);
00196 v->OnNewDay();
00197 }
00198 }
00199 }
00200
00201 void IncreaseDate()
00202 {
00203 YearMonthDay ymd;
00204
00205 if (_game_mode == GM_MENU) {
00206 _tick_counter++;
00207 return;
00208 }
00209
00210 RunVehicleDayProc(_date_fract);
00211
00212
00213 _tick_counter++;
00214
00215 _date_fract++;
00216 if (_date_fract < DAY_TICKS) return;
00217 _date_fract = 0;
00218
00219
00220 _date++;
00221
00222 #ifdef ENABLE_NETWORK
00223 NetworkChatMessageDailyLoop();
00224 #endif
00225
00226 DisasterDailyLoop();
00227 WaypointsDailyLoop();
00228 IndustryDailyLoop();
00229
00230 if (_game_mode != GM_MENU) {
00231 InvalidateWindowWidget(WC_STATUS_BAR, 0, 0);
00232 EnginesDailyLoop();
00233 }
00234
00235
00236 ConvertDateToYMD(_date, &ymd);
00237 if (ymd.month == _cur_month) return;
00238 _cur_month = ymd.month;
00239
00240
00241 if (_game_mode != GM_MENU) {
00242 if (_debug_desync_level > 2) {
00243 char name[MAX_PATH];
00244 snprintf(name, lengthof(name), "dmp_cmds_%08x_%08x.sav", _settings_game.game_creation.generation_seed, _date);
00245 SaveOrLoad(name, SL_SAVE, AUTOSAVE_DIR);
00246 }
00247
00248 if (_settings_client.gui.autosave != 0 && (_cur_month % _autosave_months[_settings_client.gui.autosave]) == 0) {
00249 _do_autosave = true;
00250 RedrawAutosave();
00251 }
00252
00253 InvalidateWindowClasses(WC_CHEATS);
00254 CompaniesMonthlyLoop();
00255 EnginesMonthlyLoop();
00256 TownsMonthlyLoop();
00257 IndustryMonthlyLoop();
00258 StationMonthlyLoop();
00259 #ifdef ENABLE_NETWORK
00260 if (_network_server) NetworkServerMonthlyLoop();
00261 #endif
00262 }
00263
00264
00265 if (ymd.year == _cur_year) return;
00266 _cur_year = ymd.year;
00267
00268
00269 CompaniesYearlyLoop();
00270 VehiclesYearlyLoop();
00271 TownsYearlyLoop();
00272 #ifdef ENABLE_NETWORK
00273 if (_network_server) NetworkServerYearlyLoop();
00274 #endif
00275
00276 if (_cur_year == _settings_client.gui.semaphore_build_before) ResetSignalVariant();
00277
00278
00279 if (_cur_year == ORIGINAL_END_YEAR) {
00280 ShowEndGameChart();
00281
00282 } else if (_cur_year == MAX_YEAR + 1) {
00283 Vehicle *v;
00284 uint days_this_year;
00285
00286 _cur_year--;
00287 days_this_year = IsLeapYear(_cur_year) ? DAYS_IN_LEAP_YEAR : DAYS_IN_YEAR;
00288 _date -= days_this_year;
00289 FOR_ALL_VEHICLES(v) v->date_of_last_service -= days_this_year;
00290
00291 #ifdef ENABLE_NETWORK
00292
00293
00294 NetworkInitChatMessage();
00295 #endif
00296 }
00297
00298 if (_settings_client.gui.auto_euro) CheckSwitchToEuro();
00299 }