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 #include "cargodest_func.h"
00023
00024 Year _cur_year;
00025 Month _cur_month;
00026 Date _date;
00027 DateFract _date_fract;
00028 uint16 _tick_counter;
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 Month _autosave_months[] = {
00180 0,
00181 1,
00182 3,
00183 6,
00184 12,
00185 };
00186
00190 static void OnNewYear()
00191 {
00192 CompaniesYearlyLoop();
00193 VehiclesYearlyLoop();
00194 TownsYearlyLoop();
00195 InvalidateWindowClassesData(WC_BUILD_STATION);
00196 #ifdef ENABLE_NETWORK
00197 if (_network_server) NetworkServerYearlyLoop();
00198 #endif
00199
00200 if (_cur_year == _settings_client.gui.semaphore_build_before) ResetSignalVariant();
00201
00202
00203 if (_cur_year == ORIGINAL_END_YEAR) {
00204 ShowEndGameChart();
00205
00206 } else if (_cur_year == MAX_YEAR + 1) {
00207 Vehicle *v;
00208 uint days_this_year;
00209
00210 _cur_year--;
00211 days_this_year = IsLeapYear(_cur_year) ? DAYS_IN_LEAP_YEAR : DAYS_IN_YEAR;
00212 _date -= days_this_year;
00213 FOR_ALL_VEHICLES(v) v->date_of_last_service -= days_this_year;
00214
00215 #ifdef ENABLE_NETWORK
00216
00217
00218 NetworkInitChatMessage();
00219 #endif
00220 }
00221
00222 if (_settings_client.gui.auto_euro) CheckSwitchToEuro();
00223 }
00224
00228 static void OnNewMonth()
00229 {
00230 if (_settings_client.gui.autosave != 0 && (_cur_month % _autosave_months[_settings_client.gui.autosave]) == 0) {
00231 _do_autosave = true;
00232 SetWindowDirty(WC_STATUS_BAR, 0);
00233 }
00234
00235 SetWindowClassesDirty(WC_CHEATS);
00236 CompaniesMonthlyLoop();
00237 SubsidyMonthlyLoop();
00238 EnginesMonthlyLoop();
00239 TownsMonthlyLoop();
00240 IndustryMonthlyLoop();
00241 StationMonthlyLoop();
00242 UpdateCargoLinks();
00243 #ifdef ENABLE_NETWORK
00244 if (_network_server) NetworkServerMonthlyLoop();
00245 #endif
00246 }
00247
00251 static void OnNewDay()
00252 {
00253 #ifdef ENABLE_NETWORK
00254 if (_network_server) NetworkServerDailyLoop();
00255 #endif
00256
00257 DisasterDailyLoop();
00258 IndustryDailyLoop();
00259
00260 SetWindowWidgetDirty(WC_STATUS_BAR, 0, 0);
00261 EnginesDailyLoop();
00262
00263
00264 SetWindowClassesDirty(WC_TOWN_VIEW);
00265 }
00266
00271 void IncreaseDate()
00272 {
00273
00274 _tick_counter++;
00275
00276 if (_game_mode == GM_MENU) return;
00277
00278 _date_fract++;
00279 if (_date_fract < DAY_TICKS) return;
00280 _date_fract = 0;
00281
00282
00283 _date++;
00284 OnNewDay();
00285
00286 YearMonthDay ymd;
00287
00288
00289 ConvertDateToYMD(_date, &ymd);
00290 if (ymd.month == _cur_month) return;
00291
00292
00293 _cur_month = ymd.month;
00294 OnNewMonth();
00295
00296
00297 if (ymd.year == _cur_year) return;
00298
00299
00300 _cur_year = ymd.year;
00301 OnNewYear();
00302 }