TrinityCore
Weather.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
22#include "GameTime.h"
23#include "Weather.h"
24#include "Log.h"
25#include "MiscPackets.h"
26#include "Player.h"
27#include "Random.h"
28#include "ScriptMgr.h"
29#include "Util.h"
30#include "World.h"
31
33Weather::Weather(uint32 zoneId, WeatherData const* weatherChances)
34 : m_zone(zoneId), m_weatherChances(weatherChances)
35{
38 m_intensity = 0;
39
40 TC_LOG_INFO("misc", "WORLD: Starting weather system for zone {} (change every {} minutes).", m_zone, (uint32)(m_timer.GetInterval() / (MINUTE*IN_MILLISECONDS)));
41}
42
45{
46 if (m_timer.GetCurrent() >= 0)
47 m_timer.Update(diff);
48 else
50
52 if (m_timer.Passed())
53 {
54 m_timer.Reset();
55 // update only if Regenerate has changed the weather
56 if (ReGenerate())
57 {
59 if (!UpdateWeather())
60 return false;
61 }
62 }
63
64 sScriptMgr->OnWeatherUpdate(this, diff);
65 return true;
66}
67
70{
72 {
74 m_intensity = 0.0f;
75 return false;
76 }
77
83 uint32 u = urand(0, 99);
84
85 if (u < 30)
86 return false;
87
88 // remember old values
89 WeatherType old_type = m_type;
90 float old_intensity = m_intensity;
91
92 //78 days between January 1st and March 20nd; 365/4=91 days by season
93 // season source http://aa.usno.navy.mil/data/docs/EarthSeasons.html
94 time_t gtime = GameTime::GetGameTime();
95 struct tm ltime;
96 localtime_r(&gtime, &ltime);
97 uint32 season = ((ltime.tm_yday - 78 + 365) / 91) % 4;
98
99 static char const* seasonName[WEATHER_SEASONS] = { "spring", "summer", "fall", "winter" };
100
101 TC_LOG_INFO("misc", "Generating a change in {} weather for zone {}.", seasonName[season], m_zone);
102
103 if ((u < 60) && (m_intensity < 0.33333334f)) // Get fair
104 {
106 m_intensity = 0.0f;
107 }
108
109 if ((u < 60) && (m_type != WEATHER_TYPE_FINE)) // Get better
110 {
111 m_intensity -= 0.33333334f;
112 return true;
113 }
114
115 if ((u < 90) && (m_type != WEATHER_TYPE_FINE)) // Get worse
116 {
117 m_intensity += 0.33333334f;
118 return true;
119 }
120
122 {
127
128 if (m_intensity < 0.33333334f)
129 {
130 m_intensity = 0.9999f; // go nuts
131 return true;
132 }
133 else
134 {
135 if (m_intensity > 0.6666667f)
136 {
137 // Severe change, but how severe?
138 uint32 rnd = urand(0, 99);
139 if (rnd < 50)
140 {
141 m_intensity -= 0.6666667f;
142 return true;
143 }
144 }
145 m_type = WEATHER_TYPE_FINE; // clear up
146 m_intensity = 0;
147 }
148 }
149
150 // At this point, only weather that isn't doing anything remains but that have weather data
151 uint32 chance1 = m_weatherChances->data[season].rainChance;
152 uint32 chance2 = chance1 + m_weatherChances->data[season].snowChance;
153 uint32 chance3 = chance2 + m_weatherChances->data[season].stormChance;
154
155 uint32 rnd = urand(1, 100);
156 if (rnd <= chance1)
158 else if (rnd <= chance2)
160 else if (rnd <= chance3)
162 else
164
170
172 {
173 m_intensity = 0.0f;
174 }
175 else if (u < 90)
176 {
177 m_intensity = rand_norm() * 0.3333f;
178 }
179 else
180 {
181 // Severe change, but how severe?
182 rnd = urand(0, 99);
183 if (rnd < 50)
184 m_intensity = rand_norm() * 0.3333f + 0.3334f;
185 else
186 m_intensity = rand_norm() * 0.3333f + 0.6667f;
187 }
188
189 // return true only in case weather changes
190 return m_type != old_type || m_intensity != old_intensity;
191}
192
194{
196 player->SendDirectMessage(weather.Write());
197}
198
200{
202 player->SendDirectMessage(weather.Write());
203}
204
207{
209 if (m_intensity >= 1)
210 m_intensity = 0.9999f;
211 else if (m_intensity < 0)
212 m_intensity = 0.0001f;
213
215
217
218 //- Returns false if there were no players found to update
219 if (!sWorld->SendZoneMessage(m_zone, weather.Write()))
220 return false;
221
223 char const* wthstr;
224 switch (state)
225 {
227 wthstr = "fog";
228 break;
230 wthstr = "light rain";
231 break;
233 wthstr = "medium rain";
234 break;
236 wthstr = "heavy rain";
237 break;
239 wthstr = "light snow";
240 break;
242 wthstr = "medium snow";
243 break;
245 wthstr = "heavy snow";
246 break;
248 wthstr = "light sandstorm";
249 break;
251 wthstr = "medium sandstorm";
252 break;
254 wthstr = "heavy sandstorm";
255 break;
257 wthstr = "thunders";
258 break;
260 wthstr = "blackrain";
261 break;
263 default:
264 wthstr = "fine";
265 break;
266 }
267
268 TC_LOG_INFO("misc", "Change the weather of zone {} to {}.", m_zone, wthstr);
269 sScriptMgr->OnWeatherChange(this, state, m_intensity);
270 return true;
271}
272
274void Weather::SetWeather(WeatherType type, float intensity)
275{
276 if (m_type == type && m_intensity == intensity)
277 return;
278
279 m_type = type;
280 m_intensity = intensity;
282}
283
286{
287 if (m_intensity < 0.27f)
288 return WEATHER_STATE_FINE;
289
290 switch (m_type)
291 {
293 if (m_intensity < 0.40f)
295 else if (m_intensity < 0.70f)
297 else
300 if (m_intensity < 0.40f)
302 else if (m_intensity < 0.70f)
304 else
307 if (m_intensity < 0.40f)
309 else if (m_intensity < 0.70f)
311 else
318 default:
319 return WEATHER_STATE_FINE;
320 }
321}
@ IN_MILLISECONDS
Definition: Common.h:35
@ MINUTE
Definition: Common.h:29
uint32_t uint32
Definition: Define.h:142
#define TC_LOG_INFO(filterType__,...)
Definition: Log.h:159
float rand_norm()
Definition: Random.cpp:75
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:42
#define sScriptMgr
Definition: ScriptMgr.h:1418
WeatherType
@ WEATHER_TYPE_RAIN
@ WEATHER_TYPE_STORM
@ WEATHER_TYPE_FINE
@ WEATHER_TYPE_SNOW
@ WEATHER_TYPE_THUNDERS
@ WEATHER_TYPE_BLACKRAIN
void SendDirectMessage(WorldPacket const *data) const
Definition: Player.cpp:6324
WorldPacket const * Write() override
#define sWorld
Definition: World.h:931
WeatherType m_type
Definition: Weather.h:87
uint32 m_zone
Definition: Weather.h:86
float m_intensity
Definition: Weather.h:88
WeatherState
Definition: Weather.h:46
WeatherSeasonChances data[WEATHER_SEASONS]
Definition: Weather.h:41
#define WEATHER_SEASONS
Definition: Weather.h:31
void SetWeather(WeatherType type, float intensity)
Set the weather.
Definition: Weather.cpp:274
Weather(uint32 zoneId, WeatherData const *weatherChances)
Create the Weather object.
Definition: Weather.cpp:33
uint32 stormChance
Definition: Weather.h:36
static void SendFineWeatherUpdateToPlayer(Player *player)
Definition: Weather.cpp:199
bool UpdateWeather()
Send the new weather to all players in the zone.
Definition: Weather.cpp:206
IntervalTimer m_timer
Definition: Weather.h:89
bool ReGenerate()
Calculate the new weather.
Definition: Weather.cpp:69
WeatherData const * m_weatherChances
Definition: Weather.h:90
WeatherState GetWeatherState() const
Get the sound number associated with the current weather.
Definition: Weather.cpp:285
bool Update(uint32 diff)
Launch a weather update.
Definition: Weather.cpp:44
void SendWeatherUpdateToPlayer(Player *player)
Definition: Weather.cpp:193
@ CONFIG_INTERVAL_CHANGEWEATHER
Definition: World.h:237
@ WEATHER_STATE_THUNDERS
Definition: Weather.h:59
@ WEATHER_STATE_HEAVY_RAIN
Definition: Weather.h:52
@ WEATHER_STATE_HEAVY_SANDSTORM
Definition: Weather.h:58
@ WEATHER_STATE_MEDIUM_SNOW
Definition: Weather.h:54
@ WEATHER_STATE_MEDIUM_RAIN
Definition: Weather.h:51
@ WEATHER_STATE_MEDIUM_SANDSTORM
Definition: Weather.h:57
@ WEATHER_STATE_FINE
Definition: Weather.h:47
@ WEATHER_STATE_LIGHT_SNOW
Definition: Weather.h:53
@ WEATHER_STATE_BLACKRAIN
Definition: Weather.h:60
@ WEATHER_STATE_HEAVY_SNOW
Definition: Weather.h:55
@ WEATHER_STATE_LIGHT_SANDSTORM
Definition: Weather.h:56
@ WEATHER_STATE_FOG
Definition: Weather.h:48
@ WEATHER_STATE_LIGHT_RAIN
Definition: Weather.h:50
time_t GetGameTime()
Definition: GameTime.cpp:44
void SetInterval(time_t interval)
Definition: Timer.h:94
time_t GetCurrent() const
Definition: Timer.h:104
time_t GetInterval() const
Definition: Timer.h:99
bool Passed()
Definition: Timer.h:78
void Update(time_t diff)
Definition: Timer.h:71
void SetCurrent(time_t current)
Definition: Timer.h:89
void Reset()
Definition: Timer.h:83