/* * Ascent MMORPG Server * Copyright (C) 2005-2007 Ascent Team * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #include "StdAfx.h" initialiseSingleton( WeatherMgr ); void BuildWeatherPacket(WorldPacket * data, uint32 Effect, float Density) { data->Initialize(SMSG_WEATHER); if(Effect == 0) *data << uint32(0) << float(0.0f) << uint8(0); // this is blizzlike! else { uint32 Value; switch(Effect) { case 1: // Rain if(Density > 1.0f) Value = 4; else Value = 3; break; case 2: // Snow if(Density > 1.0f) Value = 7; else Value = 8; break; case 3: // Weak Rain Value = 1; break; default: *data << uint32(0) << float(0.0f) << uint8(0); return; break; } *data << Value << Density << uint8(1); } } WeatherMgr::WeatherMgr() { } WeatherMgr::~WeatherMgr() { std::map::iterator itr; for(itr = m_zoneWeathers.begin(); itr != m_zoneWeathers.end(); itr++) { delete itr->second; } m_zoneWeathers.clear(); } void WeatherMgr::LoadFromDB() { QueryResult *result = WorldDatabase.Query( "SELECT * FROM weather" ); if( !result ) return; do { Field *fields = result->Fetch(); WeatherInfo *wi = new WeatherInfo; wi->m_zoneId = fields[0].GetUInt32(); wi->m_effectValues[0] = fields[1].GetUInt32(); wi->m_effectValues[1] = fields[2].GetUInt32(); wi->m_effectValues[2] = fields[3].GetUInt32(); m_zoneWeathers[wi->m_zoneId] = wi; wi->_GenerateWeather(); } while( result->NextRow() ); delete result; Log.Notice("ObjectMgr", "Weather loaded on %u zones.", m_zoneWeathers.size()); } void WeatherMgr::SendWeather(Player *plr) { std::map::iterator itr; itr = m_zoneWeathers.find(plr->GetZoneId()); if (itr == m_zoneWeathers.end()) { WorldPacket data(SMSG_WEATHER, 9); BuildWeatherPacket(&data, 0, 0); plr->GetSession()->SendPacket( &data ); plr->m_lastSeenWeather = 0; return; } else { itr->second->SendUpdate(plr); } } WeatherInfo::WeatherInfo() { m_currentDensity = 0; m_currentEffect = 0; m_currentTime = 0; m_maxDensity = 0; m_totalTime = 0; m_zoneId = 0; m_increase = true; } WeatherInfo::~WeatherInfo() { } void WeatherInfo::_GenerateWeather() { m_currentTime = 0; m_currentDensity = 0; m_currentEffect = 0; uint32 rv = sRand.randInt(100); std::map::iterator itr; for(itr = m_effectValues.begin(); itr != m_effectValues.end(); itr++) { if (rv <= itr->second) { m_currentEffect = itr->first; break; } else { rv -= itr->second; } } m_maxDensity = sRand.rand(2); //0 - 2 m_totalTime = (sRand.randInt(11) + 5)*1000*60; m_increase = true; SendUpdate(); sEventMgr.AddEvent(this, &WeatherInfo::Update, EVENT_WEATHER_UPDATE, (uint32)(m_totalTime/ceil(m_maxDensity/WEATHER_DENSITY_UPDATE)*2), 0,0); } void WeatherInfo::Update() { if (m_increase) { m_currentDensity += WEATHER_DENSITY_UPDATE; if (m_currentDensity >= m_maxDensity) { m_currentDensity = m_maxDensity; m_increase = false; } } else { m_currentDensity -= WEATHER_DENSITY_UPDATE; if (m_currentDensity <= 0) { m_currentDensity = 0; sEventMgr.RemoveEvents(this, EVENT_WEATHER_UPDATE); _GenerateWeather(); return; } } SendUpdate(); } void WeatherInfo::SendUpdate() { WorldPacket data(SMSG_WEATHER, 9); BuildWeatherPacket(&data, m_currentEffect, m_currentDensity); sWorld.SendZoneMessage(&data, m_zoneId, 0); } void WeatherInfo::SendUpdate(Player *plr) { if(plr->m_lastSeenWeather == m_currentEffect) return; plr->m_lastSeenWeather = m_currentEffect; WorldPacket data(SMSG_WEATHER, 9); BuildWeatherPacket(&data, m_currentEffect, m_currentDensity); plr->GetSession()->SendPacket( &data ); }