diff options
Diffstat (limited to 'src/game/Weather.cpp')
-rw-r--r-- | src/game/Weather.cpp | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/src/game/Weather.cpp b/src/game/Weather.cpp index 9eb8e523997..5d8d1fbd9ba 100644 --- a/src/game/Weather.cpp +++ b/src/game/Weather.cpp @@ -17,9 +17,11 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + /** \file \ingroup world */ + #include "Weather.h" #include "WorldPacket.h" #include "Player.h" @@ -27,20 +29,24 @@ #include "Log.h" #include "ObjectMgr.h" #include "Util.h" + /// Create the Weather object Weather::Weather(uint32 zone, WeatherZoneChances const* weatherChances) : m_zone(zone), m_weatherChances(weatherChances) { m_timer.SetInterval(sWorld.getConfig(CONFIG_INTERVAL_CHANGEWEATHER)); m_type = WEATHER_TYPE_FINE; m_grade = 0; + sLog.outDetail("WORLD: Starting weather system for zone %u (change every %u minutes).", m_zone, (uint32)(m_timer.GetInterval() / (MINUTE*IN_MILISECONDS)) ); } + /// Launch a weather update bool Weather::Update(uint32 diff) { if (m_timer.GetCurrent()>=0) m_timer.Update(diff); else m_timer.SetCurrent(0); + ///- If the timer has passed, ReGenerate the weather if(m_timer.Passed()) { @@ -55,6 +61,7 @@ bool Weather::Update(uint32 diff) } return true; } + /// Calculate the new weather bool Weather::ReGenerate() { @@ -64,45 +71,56 @@ bool Weather::ReGenerate() m_grade = 0.0f; return false; } + /// Weather statistics: ///- 30% - no change ///- 30% - weather gets better (if not fine) or change weather type ///- 30% - weather worsens (if not fine) ///- 10% - radical change (if not fine) uint32 u = urand(0, 99); + if (u < 30) return false; + // remember old values WeatherType old_type = m_type; float old_grade = m_grade; + //78 days between January 1st and March 20nd; 365/4=91 days by season // season source http://aa.usno.navy.mil/data/docs/EarthSeasons.html time_t gtime = sWorld.GetGameTime(); struct tm * ltime = localtime(>ime); uint32 season = ((ltime->tm_yday - 78 + 365)/91)%4; + static char const* seasonName[WEATHER_SEASONS] = { "spring", "summer", "fall", "winter" }; + sLog.outDebug("Generating a change in %s weather for zone %u.", seasonName[season], m_zone); + if ((u < 60) && (m_grade < 0.33333334f)) // Get fair { m_type = WEATHER_TYPE_FINE; m_grade = 0.0f; } + if ((u < 60) && (m_type != WEATHER_TYPE_FINE)) // Get better { m_grade -= 0.33333334f; return true; } + if ((u < 90) && (m_type != WEATHER_TYPE_FINE)) // Get worse { m_grade += 0.33333334f; return true; } + if (m_type != WEATHER_TYPE_FINE) { /// Radical change: ///- if light -> heavy ///- if medium -> change weather type ///- if heavy -> 50% light, 50% change weather type + if (m_grade < 0.33333334f) { m_grade = 0.9999f; // go nuts @@ -124,10 +142,12 @@ bool Weather::ReGenerate() m_grade = 0; } } + // At this point, only weather that isn't doing anything remains but that have weather data uint32 chance1 = m_weatherChances->data[season].rainChance; uint32 chance2 = chance1+ m_weatherChances->data[season].snowChance; uint32 chance3 = chance2+ m_weatherChances->data[season].stormChance; + uint32 rnd = urand(0, 99); if(rnd <= chance1) m_type = WEATHER_TYPE_RAIN; @@ -137,11 +157,13 @@ bool Weather::ReGenerate() m_type = WEATHER_TYPE_STORM; else m_type = WEATHER_TYPE_FINE; + /// New weather statistics (if not fine): ///- 85% light ///- 7% medium ///- 7% heavy /// If fine 100% sun (no fog) + if (m_type == WEATHER_TYPE_FINE) { m_grade = 0.0f; @@ -159,36 +181,46 @@ bool Weather::ReGenerate() else m_grade = rand_norm() * 0.3333f + 0.6667f; } + // return true only in case weather changes return m_type != old_type || m_grade != old_grade; } + void Weather::SendWeatherUpdateToPlayer(Player *player) { WorldPacket data( SMSG_WEATHER, (4+4+4) ); + data << uint32(GetWeatherState()) << (float)m_grade << uint8(0); player->GetSession()->SendPacket( &data ); } + void Weather::SendFineWeatherUpdateToPlayer(Player *player) { WorldPacket data( SMSG_WEATHER, (4+4+4) ); + data << (uint32)WEATHER_STATE_FINE << (float)0.0f << uint8(0); player->GetSession()->SendPacket( &data ); } + /// Send the new weather to all players in the zone bool Weather::UpdateWeather() { Player* player = sWorld.FindPlayerInZone(m_zone); if(!player) return false; + ///- Send the weather packet to all players in this zone if (m_grade >= 1) m_grade = 0.9999f; else if (m_grade < 0) m_grade = 0.0001f; + WeatherState state = GetWeatherState(); + WorldPacket data( SMSG_WEATHER, (4+4+4) ); data << uint32(state) << (float)m_grade << uint8(0); player->SendMessageToSet( &data, true ); + ///- Log the event char const* wthstr; switch(state) @@ -232,22 +264,27 @@ bool Weather::UpdateWeather() break; } sLog.outDetail("Change the weather of zone %u to %s.", m_zone, wthstr); + return true; } + /// Set the weather void Weather::SetWeather(WeatherType type, float grade) { if(m_type == type && m_grade == grade) return; + m_type = type; m_grade = grade; UpdateWeather(); } + /// Get the sound number associated with the current weather WeatherState Weather::GetWeatherState() const { if (m_grade<0.27f) return WEATHER_STATE_FINE; + switch(m_type) { case WEATHER_TYPE_RAIN: |