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