2 * Copyright (C) 2005-2008 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"
25 #include "WorldSession.h"
29 #include "ObjectMgr.h"
32 /// Create the Weather object
33 Weather::Weather(uint32 zone
, WeatherZoneChances
const* weatherChances
) : m_zone(zone
), m_weatherChances(weatherChances
)
35 m_timer
.SetInterval(sWorld
.getConfig(CONFIG_INTERVAL_CHANGEWEATHER
));
36 m_type
= WEATHER_TYPE_FINE
;
39 sLog
.outDetail("WORLD: Starting weather system for zone %u (change every %u minutes).", m_zone
, (uint32
)(m_timer
.GetInterval() / (1000*MINUTE
)) );
42 /// Launch a weather update
43 bool Weather::Update(time_t diff
)
45 if (m_timer
.GetCurrent()>=0)
47 else m_timer
.SetCurrent(0);
49 ///- If the timer has passed, ReGenerate the weather
53 // update only if Regenerate has changed the weather
56 ///- Weather will be removed if not updated (no players in zone anymore)
64 /// Calculate the new weather
65 bool Weather::ReGenerate()
67 if (!m_weatherChances
)
69 m_type
= WEATHER_TYPE_FINE
;
74 /// Weather statistics:
76 ///- 30% - weather gets better (if not fine) or change weather type
77 ///- 30% - weather worsens (if not fine)
78 ///- 10% - radical change (if not fine)
79 uint32 u
= urand(0, 99);
84 // remember old values
85 WeatherType old_type
= m_type
;
86 float old_grade
= m_grade
;
88 //78 days between January 1st and March 20nd; 365/4=91 days by season
89 // season source http://aa.usno.navy.mil/data/docs/EarthSeasons.html
90 time_t gtime
= sWorld
.GetGameTime();
91 struct tm
* ltime
= localtime(>ime
);
92 uint32 season
= ((ltime
->tm_yday
- 78 + 365)/91)%4;
94 static char const* seasonName
[WEATHER_SEASONS
] = { "spring", "summer", "fall", "winter" };
96 sLog
.outDebug("Generating a change in %s weather for zone %u.", seasonName
[season
], m_zone
);
98 if ((u
< 60) && (m_grade
< 0.33333334f
)) // Get fair
100 m_type
= WEATHER_TYPE_FINE
;
104 if ((u
< 60) && (m_type
!= WEATHER_TYPE_FINE
)) // Get better
106 m_grade
-= 0.33333334f
;
110 if ((u
< 90) && (m_type
!= WEATHER_TYPE_FINE
)) // Get worse
112 m_grade
+= 0.33333334f
;
116 if (m_type
!= WEATHER_TYPE_FINE
)
119 ///- if light -> heavy
120 ///- if medium -> change weather type
121 ///- if heavy -> 50% light, 50% change weather type
123 if (m_grade
< 0.33333334f
)
125 m_grade
= 0.9999f
; // go nuts
130 if (m_grade
> 0.6666667f
)
132 // Severe change, but how severe?
133 uint32 rnd
= urand(0,99);
136 m_grade
-= 0.6666667f
;
140 m_type
= WEATHER_TYPE_FINE
; // clear up
145 // At this point, only weather that isn't doing anything remains but that have weather data
146 uint32 chance1
= m_weatherChances
->data
[season
].rainChance
;
147 uint32 chance2
= chance1
+ m_weatherChances
->data
[season
].snowChance
;
148 uint32 chance3
= chance2
+ m_weatherChances
->data
[season
].stormChance
;
150 uint32 rnd
= urand(0, 99);
152 m_type
= WEATHER_TYPE_RAIN
;
153 else if(rnd
<= chance2
)
154 m_type
= WEATHER_TYPE_SNOW
;
155 else if(rnd
<= chance3
)
156 m_type
= WEATHER_TYPE_STORM
;
158 m_type
= WEATHER_TYPE_FINE
;
160 /// New weather statistics (if not fine):
164 /// If fine 100% sun (no fog)
166 if (m_type
== WEATHER_TYPE_FINE
)
172 m_grade
= rand_norm() * 0.3333f
;
176 // Severe change, but how severe?
179 m_grade
= rand_norm() * 0.3333f
+ 0.3334f
;
181 m_grade
= rand_norm() * 0.3333f
+ 0.6667f
;
184 // return true only in case weather changes
185 return m_type
!= old_type
|| m_grade
!= old_grade
;
188 void Weather::SendWeatherUpdateToPlayer(Player
*player
)
190 WorldPacket
data( SMSG_WEATHER
, (4+4+4) );
192 data
<< uint32(GetWeatherState()) << (float)m_grade
<< uint8(0);
193 player
->GetSession()->SendPacket( &data
);
196 void Weather::SendFineWeatherUpdateToPlayer(Player
*player
)
198 WorldPacket
data( SMSG_WEATHER
, (4+4+4) );
200 data
<< (uint32
)WEATHER_STATE_FINE
<< (float)0.0f
<< uint8(0);
201 player
->GetSession()->SendPacket( &data
);
204 /// Send the new weather to all players in the zone
205 bool Weather::UpdateWeather()
207 Player
* player
= sWorld
.FindPlayerInZone(m_zone
);
211 ///- Send the weather packet to all players in this zone
214 else if (m_grade
< 0)
217 WeatherState state
= GetWeatherState();
219 WorldPacket
data( SMSG_WEATHER
, (4+4+4) );
220 data
<< uint32(state
) << (float)m_grade
<< uint8(0);
221 player
->SendMessageToSet( &data
, true );
227 case WEATHER_STATE_LIGHT_RAIN
:
228 wthstr
= "light rain";
230 case WEATHER_STATE_MEDIUM_RAIN
:
231 wthstr
= "medium rain";
233 case WEATHER_STATE_HEAVY_RAIN
:
234 wthstr
= "heavy rain";
236 case WEATHER_STATE_LIGHT_SNOW
:
237 wthstr
= "light snow";
239 case WEATHER_STATE_MEDIUM_SNOW
:
240 wthstr
= "medium snow";
242 case WEATHER_STATE_HEAVY_SNOW
:
243 wthstr
= "heavy snow";
245 case WEATHER_STATE_LIGHT_SANDSTORM
:
246 wthstr
= "light sandstorm";
248 case WEATHER_STATE_MEDIUM_SANDSTORM
:
249 wthstr
= "medium sandstorm";
251 case WEATHER_STATE_HEAVY_SANDSTORM
:
252 wthstr
= "heavy sandstorm";
254 case WEATHER_STATE_THUNDERS
:
257 case WEATHER_STATE_BLACKRAIN
:
258 wthstr
= "blackrain";
260 case WEATHER_STATE_FINE
:
265 sLog
.outDetail("Change the weather of zone %u to %s.", m_zone
, wthstr
);
271 void Weather::SetWeather(WeatherType type
, float grade
)
273 if(m_type
== type
&& m_grade
== grade
)
281 /// Get the sound number associated with the current weather
282 WeatherState
Weather::GetWeatherState() const
285 return WEATHER_STATE_FINE
;
289 case WEATHER_TYPE_RAIN
:
291 return WEATHER_STATE_LIGHT_RAIN
;
292 else if(m_grade
<0.70f
)
293 return WEATHER_STATE_MEDIUM_RAIN
;
295 return WEATHER_STATE_HEAVY_RAIN
;
296 case WEATHER_TYPE_SNOW
:
298 return WEATHER_STATE_LIGHT_SNOW
;
299 else if(m_grade
<0.70f
)
300 return WEATHER_STATE_MEDIUM_SNOW
;
302 return WEATHER_STATE_HEAVY_SNOW
;
303 case WEATHER_TYPE_STORM
:
305 return WEATHER_STATE_LIGHT_SANDSTORM
;
306 else if(m_grade
<0.70f
)
307 return WEATHER_STATE_MEDIUM_SANDSTORM
;
309 return WEATHER_STATE_HEAVY_SANDSTORM
;
310 case WEATHER_TYPE_BLACKRAIN
:
311 return WEATHER_STATE_BLACKRAIN
;
312 case WEATHER_TYPE_THUNDERS
:
313 return WEATHER_STATE_THUNDERS
;
314 case WEATHER_TYPE_FINE
:
316 return WEATHER_STATE_FINE
;