2 * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include "WorldPacket.h"
28 #include "ObjectMgr.h"
31 /// Create the Weather object
32 Weather::Weather(uint32 zone
, WeatherZoneChances
const* weatherChances
) : m_zone(zone
), m_weatherChances(weatherChances
)
34 m_timer
.SetInterval(sWorld
.getConfig(CONFIG_INTERVAL_CHANGEWEATHER
));
35 m_type
= WEATHER_TYPE_FINE
;
38 sLog
.outDetail("WORLD: Starting weather system for zone %u (change every %u minutes).", m_zone
, (uint32
)(m_timer
.GetInterval() / (MINUTE
*IN_MILISECONDS
)) );
41 /// Launch a weather update
42 bool Weather::Update(uint32 diff
)
44 if (m_timer
.GetCurrent()>=0)
46 else m_timer
.SetCurrent(0);
48 ///- If the timer has passed, ReGenerate the weather
52 // update only if Regenerate has changed the weather
55 ///- Weather will be removed if not updated (no players in zone anymore)
63 /// Calculate the new weather
64 bool Weather::ReGenerate()
66 if (!m_weatherChances
)
68 m_type
= WEATHER_TYPE_FINE
;
73 /// Weather statistics:
75 ///- 30% - weather gets better (if not fine) or change weather type
76 ///- 30% - weather worsens (if not fine)
77 ///- 10% - radical change (if not fine)
78 uint32 u
= urand(0, 99);
83 // remember old values
84 WeatherType old_type
= m_type
;
85 float old_grade
= m_grade
;
87 //78 days between January 1st and March 20nd; 365/4=91 days by season
88 // season source http://aa.usno.navy.mil/data/docs/EarthSeasons.html
89 time_t gtime
= sWorld
.GetGameTime();
90 struct tm
* ltime
= localtime(>ime
);
91 uint32 season
= ((ltime
->tm_yday
- 78 + 365)/91)%4;
93 static char const* seasonName
[WEATHER_SEASONS
] = { "spring", "summer", "fall", "winter" };
95 sLog
.outDebug("Generating a change in %s weather for zone %u.", seasonName
[season
], m_zone
);
97 if ((u
< 60) && (m_grade
< 0.33333334f
)) // Get fair
99 m_type
= WEATHER_TYPE_FINE
;
103 if ((u
< 60) && (m_type
!= WEATHER_TYPE_FINE
)) // Get better
105 m_grade
-= 0.33333334f
;
109 if ((u
< 90) && (m_type
!= WEATHER_TYPE_FINE
)) // Get worse
111 m_grade
+= 0.33333334f
;
115 if (m_type
!= WEATHER_TYPE_FINE
)
118 ///- if light -> heavy
119 ///- if medium -> change weather type
120 ///- if heavy -> 50% light, 50% change weather type
122 if (m_grade
< 0.33333334f
)
124 m_grade
= 0.9999f
; // go nuts
129 if (m_grade
> 0.6666667f
)
131 // Severe change, but how severe?
132 uint32 rnd
= urand(0,99);
135 m_grade
-= 0.6666667f
;
139 m_type
= WEATHER_TYPE_FINE
; // clear up
144 // At this point, only weather that isn't doing anything remains but that have weather data
145 uint32 chance1
= m_weatherChances
->data
[season
].rainChance
;
146 uint32 chance2
= chance1
+ m_weatherChances
->data
[season
].snowChance
;
147 uint32 chance3
= chance2
+ m_weatherChances
->data
[season
].stormChance
;
149 uint32 rnd
= urand(0, 99);
151 m_type
= WEATHER_TYPE_RAIN
;
152 else if(rnd
<= chance2
)
153 m_type
= WEATHER_TYPE_SNOW
;
154 else if(rnd
<= chance3
)
155 m_type
= WEATHER_TYPE_STORM
;
157 m_type
= WEATHER_TYPE_FINE
;
159 /// New weather statistics (if not fine):
163 /// If fine 100% sun (no fog)
165 if (m_type
== WEATHER_TYPE_FINE
)
171 m_grade
= rand_norm() * 0.3333f
;
175 // Severe change, but how severe?
178 m_grade
= rand_norm() * 0.3333f
+ 0.3334f
;
180 m_grade
= rand_norm() * 0.3333f
+ 0.6667f
;
183 // return true only in case weather changes
184 return m_type
!= old_type
|| m_grade
!= old_grade
;
187 void Weather::SendWeatherUpdateToPlayer(Player
*player
)
189 WorldPacket
data( SMSG_WEATHER
, (4+4+1) );
191 data
<< uint32(GetWeatherState()) << (float)m_grade
<< uint8(0);
192 player
->GetSession()->SendPacket( &data
);
195 void Weather::SendFineWeatherUpdateToPlayer(Player
*player
)
197 WorldPacket
data( SMSG_WEATHER
, (4+4+1) );
199 data
<< (uint32
)WEATHER_STATE_FINE
<< (float)0.0f
<< uint8(0);
200 player
->GetSession()->SendPacket( &data
);
203 /// Send the new weather to all players in the zone
204 bool Weather::UpdateWeather()
206 Player
* player
= sWorld
.FindPlayerInZone(m_zone
);
210 ///- Send the weather packet to all players in this zone
213 else if (m_grade
< 0)
216 WeatherState state
= GetWeatherState();
218 WorldPacket
data( SMSG_WEATHER
, (4+4+1) );
219 data
<< uint32(state
) << (float)m_grade
<< uint8(0);
220 player
->SendMessageToSet( &data
, true );
226 case WEATHER_STATE_LIGHT_RAIN
:
227 wthstr
= "light rain";
229 case WEATHER_STATE_MEDIUM_RAIN
:
230 wthstr
= "medium rain";
232 case WEATHER_STATE_HEAVY_RAIN
:
233 wthstr
= "heavy rain";
235 case WEATHER_STATE_LIGHT_SNOW
:
236 wthstr
= "light snow";
238 case WEATHER_STATE_MEDIUM_SNOW
:
239 wthstr
= "medium snow";
241 case WEATHER_STATE_HEAVY_SNOW
:
242 wthstr
= "heavy snow";
244 case WEATHER_STATE_LIGHT_SANDSTORM
:
245 wthstr
= "light sandstorm";
247 case WEATHER_STATE_MEDIUM_SANDSTORM
:
248 wthstr
= "medium sandstorm";
250 case WEATHER_STATE_HEAVY_SANDSTORM
:
251 wthstr
= "heavy sandstorm";
253 case WEATHER_STATE_THUNDERS
:
256 case WEATHER_STATE_BLACKRAIN
:
257 wthstr
= "blackrain";
259 case WEATHER_STATE_FINE
:
264 sLog
.outDetail("Change the weather of zone %u to %s.", m_zone
, wthstr
);
270 void Weather::SetWeather(WeatherType type
, float grade
)
272 if(m_type
== type
&& m_grade
== grade
)
280 /// Get the sound number associated with the current weather
281 WeatherState
Weather::GetWeatherState() const
284 return WEATHER_STATE_FINE
;
288 case WEATHER_TYPE_RAIN
:
290 return WEATHER_STATE_LIGHT_RAIN
;
291 else if(m_grade
<0.70f
)
292 return WEATHER_STATE_MEDIUM_RAIN
;
294 return WEATHER_STATE_HEAVY_RAIN
;
295 case WEATHER_TYPE_SNOW
:
297 return WEATHER_STATE_LIGHT_SNOW
;
298 else if(m_grade
<0.70f
)
299 return WEATHER_STATE_MEDIUM_SNOW
;
301 return WEATHER_STATE_HEAVY_SNOW
;
302 case WEATHER_TYPE_STORM
:
304 return WEATHER_STATE_LIGHT_SANDSTORM
;
305 else if(m_grade
<0.70f
)
306 return WEATHER_STATE_MEDIUM_SANDSTORM
;
308 return WEATHER_STATE_HEAVY_SANDSTORM
;
309 case WEATHER_TYPE_BLACKRAIN
:
310 return WEATHER_STATE_BLACKRAIN
;
311 case WEATHER_TYPE_THUNDERS
:
312 return WEATHER_STATE_THUNDERS
;
313 case WEATHER_TYPE_FINE
:
315 return WEATHER_STATE_FINE
;