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 "linkgraph/linkgraph.h"
00022 #include "saveload/saveload.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 int 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 LinkGraph *lg;
00216 FOR_ALL_LINK_GRAPHS(lg) lg->ShiftDates(-days_this_year);
00217
00218 #ifdef ENABLE_NETWORK
00219
00220
00221 NetworkInitChatMessage();
00222 #endif
00223 }
00224
00225 if (_settings_client.gui.auto_euro) CheckSwitchToEuro();
00226 }
00227
00231 static void OnNewMonth()
00232 {
00233 if (_settings_client.gui.autosave != 0 && (_cur_month % _autosave_months[_settings_client.gui.autosave]) == 0) {
00234 _do_autosave = true;
00235 SetWindowDirty(WC_STATUS_BAR, 0);
00236 }
00237
00238 SetWindowClassesDirty(WC_CHEATS);
00239 CompaniesMonthlyLoop();
00240 EnginesMonthlyLoop();
00241 TownsMonthlyLoop();
00242 IndustryMonthlyLoop();
00243 SubsidyMonthlyLoop();
00244 StationMonthlyLoop();
00245 #ifdef ENABLE_NETWORK
00246 if (_network_server) NetworkServerMonthlyLoop();
00247 #endif
00248 }
00249
00253 static void OnNewDay()
00254 {
00255 #ifdef ENABLE_NETWORK
00256 if (_network_server) NetworkServerDailyLoop();
00257 #endif
00258
00259 DisasterDailyLoop();
00260 IndustryDailyLoop();
00261
00262 SetWindowWidgetDirty(WC_STATUS_BAR, 0, 0);
00263 EnginesDailyLoop();
00264
00265
00266 SetWindowClassesDirty(WC_TOWN_VIEW);
00267 }
00268
00273 void IncreaseDate()
00274 {
00275
00276 _tick_counter++;
00277
00278 if (_game_mode == GM_MENU) return;
00279
00280 _date_fract++;
00281 if (_date_fract < DAY_TICKS) return;
00282 _date_fract = 0;
00283
00284
00285 _date++;
00286
00287 YearMonthDay ymd;
00288 ConvertDateToYMD(_date, &ymd);
00289
00290
00291 bool new_month = ymd.month != _cur_month;
00292
00293
00294 bool new_year = ymd.year != _cur_year;
00295
00296
00297 _cur_month = ymd.month;
00298 _cur_year = ymd.year;
00299
00300
00301 OnNewDay();
00302
00303
00304 if (new_month) OnNewMonth();
00305
00306
00307 if (new_year) OnNewYear();
00308 }