1 #include "datetimemanager.hpp"
2 
3 #include "../mwbase/environment.hpp"
4 #include "../mwbase/world.hpp"
5 
6 #include "esmstore.hpp"
7 #include "globals.hpp"
8 #include "timestamp.hpp"
9 
10 namespace
11 {
getDaysPerMonth(int month)12     static int getDaysPerMonth(int month)
13     {
14         switch (month)
15         {
16             case 0: return 31;
17             case 1: return 28;
18             case 2: return 31;
19             case 3: return 30;
20             case 4: return 31;
21             case 5: return 30;
22             case 6: return 31;
23             case 7: return 31;
24             case 8: return 30;
25             case 9: return 31;
26             case 10: return 30;
27             case 11: return 31;
28         }
29 
30         throw std::runtime_error ("month out of range");
31     }
32 }
33 
34 namespace MWWorld
35 {
setup(Globals & globalVariables)36     void DateTimeManager::setup(Globals& globalVariables)
37     {
38         mGameHour = globalVariables["gamehour"].getFloat();
39         mDaysPassed = globalVariables["dayspassed"].getInteger();
40         mDay = globalVariables["day"].getInteger();
41         mMonth = globalVariables["month"].getInteger();
42         mYear = globalVariables["year"].getInteger();
43         mTimeScale = globalVariables["timescale"].getFloat();
44     }
45 
setHour(double hour)46     void DateTimeManager::setHour(double hour)
47     {
48         if (hour < 0)
49             hour = 0;
50 
51         int days = static_cast<int>(hour / 24);
52         hour = std::fmod(hour, 24);
53         mGameHour = static_cast<float>(hour);
54 
55         if (days > 0)
56             setDay(days + mDay);
57     }
58 
setDay(int day)59     void DateTimeManager::setDay(int day)
60     {
61         if (day < 1)
62             day = 1;
63 
64         int month = mMonth;
65         while (true)
66         {
67             int days = getDaysPerMonth(month);
68             if (day <= days)
69                 break;
70 
71             if (month < 11)
72             {
73                 ++month;
74             }
75             else
76             {
77                 month = 0;
78                 mYear++;
79             }
80 
81             day -= days;
82         }
83 
84         mDay = day;
85         mMonth = month;
86     }
87 
getTimeStamp() const88     TimeStamp DateTimeManager::getTimeStamp() const
89     {
90         return TimeStamp(mGameHour, mDaysPassed);
91     }
92 
getTimeScaleFactor() const93     float DateTimeManager::getTimeScaleFactor() const
94     {
95         return mTimeScale;
96     }
97 
getEpochTimeStamp() const98     ESM::EpochTimeStamp DateTimeManager::getEpochTimeStamp() const
99     {
100         ESM::EpochTimeStamp timeStamp;
101         timeStamp.mGameHour = mGameHour;
102         timeStamp.mDay = mDay;
103         timeStamp.mMonth = mMonth;
104         timeStamp.mYear = mYear;
105         return timeStamp;
106     }
107 
setMonth(int month)108     void DateTimeManager::setMonth(int month)
109     {
110         if (month < 0)
111             month = 0;
112 
113         int years = month / 12;
114         month = month % 12;
115 
116         int days = getDaysPerMonth(month);
117         if (mDay > days)
118             mDay = days;
119 
120         mMonth = month;
121 
122         if (years > 0)
123             mYear += years;
124     }
125 
advanceTime(double hours,Globals & globalVariables)126     void DateTimeManager::advanceTime(double hours, Globals& globalVariables)
127     {
128         hours += mGameHour;
129         setHour(hours);
130 
131         int days = static_cast<int>(hours / 24);
132         if (days > 0)
133             mDaysPassed += days;
134 
135         globalVariables["gamehour"].setFloat(mGameHour);
136         globalVariables["dayspassed"].setInteger(mDaysPassed);
137         globalVariables["day"].setInteger(mDay);
138         globalVariables["month"].setInteger(mMonth);
139         globalVariables["year"].setInteger(mYear);
140     }
141 
getMonthName(int month) const142     std::string DateTimeManager::getMonthName(int month) const
143     {
144         if (month == -1)
145             month = mMonth;
146 
147         const int months = 12;
148         if (month < 0 || month >= months)
149             return std::string();
150 
151         static const char *monthNames[months] =
152         {
153             "sMonthMorningstar", "sMonthSunsdawn", "sMonthFirstseed", "sMonthRainshand",
154             "sMonthSecondseed", "sMonthMidyear", "sMonthSunsheight", "sMonthLastseed",
155             "sMonthHeartfire", "sMonthFrostfall", "sMonthSunsdusk", "sMonthEveningstar"
156         };
157 
158         const ESM::GameSetting *setting = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(monthNames[month]);
159         return setting->mValue.getString();
160     }
161 
updateGlobalFloat(const std::string & name,float value)162     bool DateTimeManager::updateGlobalFloat(const std::string& name, float value)
163     {
164         if (name=="gamehour")
165         {
166             setHour(value);
167             return true;
168         }
169         else if (name=="day")
170         {
171             setDay(static_cast<int>(value));
172             return true;
173         }
174         else if (name=="month")
175         {
176             setMonth(static_cast<int>(value));
177             return true;
178         }
179         else if (name=="year")
180         {
181             mYear = static_cast<int>(value);
182         }
183         else if (name=="timescale")
184         {
185             mTimeScale = value;
186         }
187         else if (name=="dayspassed")
188         {
189             mDaysPassed = static_cast<int>(value);
190         }
191 
192         return false;
193     }
194 
updateGlobalInt(const std::string & name,int value)195     bool DateTimeManager::updateGlobalInt(const std::string& name, int value)
196     {
197         if (name=="gamehour")
198         {
199             setHour(static_cast<float>(value));
200             return true;
201         }
202         else if (name=="day")
203         {
204             setDay(value);
205             return true;
206         }
207         else if (name=="month")
208         {
209             setMonth(value);
210             return true;
211         }
212         else if (name=="year")
213         {
214             mYear = value;
215         }
216         else if (name=="timescale")
217         {
218             mTimeScale = static_cast<float>(value);
219         }
220         else if (name=="dayspassed")
221         {
222             mDaysPassed = value;
223         }
224 
225         return false;
226     }
227 }
228