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 "economy_func.h"
00023 #ifdef _DEBUG
00024 #include "industry.h"
00025 #include "town.h"
00026 #include "station_base.h"
00027 #include "map_func.h"
00028 #endif
00029
00030 Year _cur_year;
00031 Month _cur_month;
00032 Date _date;
00033 DateFract _date_fract;
00034 uint16 _tick_counter;
00035
00041 void SetDate(Date date, DateFract fract)
00042 {
00043 assert(fract < DAY_TICKS);
00044
00045 YearMonthDay ymd;
00046
00047 _date = date;
00048 _date_fract = fract;
00049 ConvertDateToYMD(date, &ymd);
00050 _cur_year = ymd.year;
00051 _cur_month = ymd.month;
00052 }
00053
00054 #define M(a, b) ((a << 5) | b)
00055 static const uint16 _month_date_from_year_day[] = {
00056 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),
00057 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),
00058 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),
00059 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),
00060 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),
00061 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),
00062 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),
00063 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),
00064 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),
00065 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),
00066 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),
00067 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),
00068 };
00069 #undef M
00070
00071 enum DaysTillMonth {
00072 ACCUM_JAN = 0,
00073 ACCUM_FEB = ACCUM_JAN + 31,
00074 ACCUM_MAR = ACCUM_FEB + 29,
00075 ACCUM_APR = ACCUM_MAR + 31,
00076 ACCUM_MAY = ACCUM_APR + 30,
00077 ACCUM_JUN = ACCUM_MAY + 31,
00078 ACCUM_JUL = ACCUM_JUN + 30,
00079 ACCUM_AUG = ACCUM_JUL + 31,
00080 ACCUM_SEP = ACCUM_AUG + 31,
00081 ACCUM_OCT = ACCUM_SEP + 30,
00082 ACCUM_NOV = ACCUM_OCT + 31,
00083 ACCUM_DEC = ACCUM_NOV + 30,
00084 };
00085
00087 static const uint16 _accum_days_for_month[] = {
00088 ACCUM_JAN, ACCUM_FEB, ACCUM_MAR, ACCUM_APR,
00089 ACCUM_MAY, ACCUM_JUN, ACCUM_JUL, ACCUM_AUG,
00090 ACCUM_SEP, ACCUM_OCT, ACCUM_NOV, ACCUM_DEC,
00091 };
00092
00098 void ConvertDateToYMD(Date date, YearMonthDay *ymd)
00099 {
00100
00101
00102
00103
00104
00105 Year yr = 400 * (date / (DAYS_IN_YEAR * 400 + 97));
00106 int rem = date % (DAYS_IN_YEAR * 400 + 97);
00107 uint16 x;
00108
00109 if (rem >= DAYS_IN_YEAR * 100 + 25) {
00110
00111
00112 yr += 100;
00113 rem -= DAYS_IN_YEAR * 100 + 25;
00114
00115
00116 yr += 100 * (rem / (DAYS_IN_YEAR * 100 + 24));
00117 rem = (rem % (DAYS_IN_YEAR * 100 + 24));
00118 }
00119
00120 if (!IsLeapYear(yr) && rem >= DAYS_IN_YEAR * 4) {
00121
00122 yr += 4;
00123 rem -= DAYS_IN_YEAR * 4;
00124 }
00125
00126
00127 yr += 4 * (rem / (DAYS_IN_YEAR * 4 + 1));
00128 rem = rem % (DAYS_IN_YEAR * 4 + 1);
00129
00130
00131
00132 while (rem >= (IsLeapYear(yr) ? DAYS_IN_LEAP_YEAR : DAYS_IN_YEAR)) {
00133 rem -= IsLeapYear(yr) ? DAYS_IN_LEAP_YEAR : DAYS_IN_YEAR;
00134 yr++;
00135 }
00136
00137
00138 if (!IsLeapYear(yr) && rem >= ACCUM_MAR - 1) rem++;
00139
00140 ymd->year = yr;
00141
00142 x = _month_date_from_year_day[rem];
00143 ymd->month = x >> 5;
00144 ymd->day = x & 0x1F;
00145 }
00146
00153 Date ConvertYMDToDate(Year year, Month month, Day day)
00154 {
00155
00156 int days = _accum_days_for_month[month] + day - 1;
00157
00158
00159 if (!IsLeapYear(year) && days >= ACCUM_MAR) days--;
00160
00161 return DAYS_TILL(year) + days;
00162 }
00163
00166 extern void EnginesDailyLoop();
00167 extern void DisasterDailyLoop();
00168 extern void IndustryDailyLoop();
00169
00170 extern void CompaniesMonthlyLoop();
00171 extern void EnginesMonthlyLoop();
00172 extern void TownsMonthlyLoop();
00173 extern void IndustryMonthlyLoop();
00174 extern void StationMonthlyLoop();
00175 extern void SubsidyMonthlyLoop();
00176
00177 extern void CompaniesYearlyLoop();
00178 extern void VehiclesYearlyLoop();
00179 extern void TownsYearlyLoop();
00180
00181 extern void ShowEndGameChart();
00182
00183
00185 static const Month _autosave_months[] = {
00186 0,
00187 1,
00188 3,
00189 6,
00190 12,
00191 };
00192
00196 static void OnNewYear()
00197 {
00198 CompaniesYearlyLoop();
00199 VehiclesYearlyLoop();
00200 TownsYearlyLoop();
00201 InvalidateWindowClassesData(WC_BUILD_STATION);
00202 #ifdef ENABLE_NETWORK
00203 if (_network_server) NetworkServerYearlyLoop();
00204 #endif
00205
00206 if (_cur_year == _settings_client.gui.semaphore_build_before) ResetSignalVariant();
00207
00208
00209 if (_cur_year == ORIGINAL_END_YEAR) {
00210 ShowEndGameChart();
00211
00212 } else if (_cur_year == MAX_YEAR + 1) {
00213 Vehicle *v;
00214 uint days_this_year;
00215
00216 _cur_year--;
00217 days_this_year = IsLeapYear(_cur_year) ? DAYS_IN_LEAP_YEAR : DAYS_IN_YEAR;
00218 _date -= days_this_year;
00219 FOR_ALL_VEHICLES(v) v->date_of_last_service -= days_this_year;
00220
00221 #ifdef ENABLE_NETWORK
00222
00223
00224 NetworkInitChatMessage();
00225 #endif
00226 }
00227
00228 if (_settings_client.gui.auto_euro) CheckSwitchToEuro();
00229 }
00230
00234 static void OnNewMonth()
00235 {
00236 if (_settings_client.gui.autosave != 0 && (_cur_month % _autosave_months[_settings_client.gui.autosave]) == 0) {
00237 _do_autosave = true;
00238 SetWindowDirty(WC_STATUS_BAR, 0);
00239 }
00240
00241 SetWindowClassesDirty(WC_CHEATS);
00242 CompaniesMonthlyLoop();
00243 EnginesMonthlyLoop();
00244 BEGIN_HEAD_TO_HEAD() {
00245 TownsMonthlyLoop();
00246 IndustryMonthlyLoop();
00247 StationMonthlyLoop();
00248 } END_HEAD_TO_HEAD()
00249 SubsidyMonthlyLoop();
00250 #ifdef ENABLE_NETWORK
00251 if (_network_server) NetworkServerMonthlyLoop();
00252 #endif
00253 }
00254
00258 static void OnNewDay()
00259 {
00260 #ifdef ENABLE_NETWORK
00261 if (_network_server) NetworkServerDailyLoop();
00262 #endif
00263
00264 DisasterDailyLoop();
00265 int32 backup_dcc = _economy.industry_daily_change_counter;
00266 BEGIN_HEAD_TO_HEAD() {
00267 _economy.industry_daily_change_counter = backup_dcc;
00268 IndustryDailyLoop();
00269 } END_HEAD_TO_HEAD()
00270
00271 SetWindowWidgetDirty(WC_STATUS_BAR, 0, 0);
00272 EnginesDailyLoop();
00273
00274
00275 SetWindowClassesDirty(WC_TOWN_VIEW);
00276 }
00277
00282 void IncreaseDate()
00283 {
00284
00285 _tick_counter++;
00286
00287 if (_game_mode == GM_MENU) return;
00288
00289 _date_fract++;
00290 if (_date_fract < DAY_TICKS) return;
00291 _date_fract = 0;
00292
00293
00294 _date++;
00295 OnNewDay();
00296
00297 YearMonthDay ymd;
00298
00299
00300 ConvertDateToYMD(_date, &ymd);
00301 if (ymd.month == _cur_month) return;
00302
00303
00304 _cur_month = ymd.month;
00305 OnNewMonth();
00306
00307
00308 if (ymd.year == _cur_year) return;
00309
00310
00311 _cur_year = ymd.year;
00312 OnNewYear();
00313 }