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