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 (_settings_client.gui.autosave != 0 && (_cur_month % _autosave_months[_settings_client.gui.autosave]) == 0) {
00222 _do_autosave = true;
00223 RedrawAutosave();
00224 }
00225
00226 SetWindowClassesDirty(WC_CHEATS);
00227 CompaniesMonthlyLoop();
00228 SubsidyMonthlyLoop();
00229 EnginesMonthlyLoop();
00230 TownsMonthlyLoop();
00231 IndustryMonthlyLoop();
00232 StationMonthlyLoop();
00233 #ifdef ENABLE_NETWORK
00234 if (_network_server) NetworkServerMonthlyLoop();
00235 #endif
00236 }
00237
00241 static void OnNewDay()
00242 {
00243 #ifdef ENABLE_NETWORK
00244 NetworkChatMessageDailyLoop();
00245 #endif
00246
00247 DisasterDailyLoop();
00248 IndustryDailyLoop();
00249
00250 SetWindowWidgetDirty(WC_STATUS_BAR, 0, 0);
00251 EnginesDailyLoop();
00252
00253
00254 SetWindowClassesDirty(WC_TOWN_VIEW);
00255 }
00256
00261 void IncreaseDate()
00262 {
00263
00264 _tick_counter++;
00265
00266 if (_game_mode == GM_MENU) return;
00267
00268 _date_fract++;
00269 if (_date_fract < DAY_TICKS) return;
00270 _date_fract = 0;
00271
00272
00273 _date++;
00274 OnNewDay();
00275
00276 YearMonthDay ymd;
00277
00278
00279 ConvertDateToYMD(_date, &ymd);
00280 if (ymd.month == _cur_month) return;
00281
00282
00283 _cur_month = ymd.month;
00284 OnNewMonth();
00285
00286
00287 if (ymd.year == _cur_year) return;
00288
00289
00290 _cur_year = ymd.year;
00291 OnNewYear();
00292 }