diff --git a/src/game/ChatCommands/Level3.cpp b/src/game/ChatCommands/Level3.cpp index 30249bf80..968d585b9 100644 --- a/src/game/ChatCommands/Level3.cpp +++ b/src/game/ChatCommands/Level3.cpp @@ -4865,17 +4865,17 @@ bool ChatHandler::HandleChangeWeatherCommand(char* args) // see enum WeatherType if (!Weather::IsValidWeatherType(type)) - { return false; - } float grade; if (!ExtractFloat(&args, grade)) return false; - // 0 to 1, sending -1 is instant good weather - if (grade < 0.0f || grade > 1.0f) - return false; + // clamp grade from 0 to 1 + if (grade < 0.0f) + grade = 0.0f; + else if (grade > 1.0f) + grade = 1.0f; Player* player = m_session->GetPlayer(); uint32 zoneId = player->GetZoneId(); @@ -4884,7 +4884,6 @@ bool ChatHandler::HandleChangeWeatherCommand(char* args) SendSysMessage(LANG_NO_WEATHER); SetSentErrorMessage(true); } - player->GetMap()->SetWeather(zoneId, (WeatherType)type, grade, false); return true; diff --git a/src/game/Object/Object.cpp b/src/game/Object/Object.cpp index 6f8391729..dd9c20089 100644 --- a/src/game/Object/Object.cpp +++ b/src/game/Object/Object.cpp @@ -1467,7 +1467,7 @@ bool WorldObject::isInBack(WorldObject const* target, float distance, float arc) return IsWithinDist(target, distance) && !HasInArc(2 * M_PI_F - arc, target); } -void WorldObject::GetRandomPoint(float x, float y, float z, float distance, float& rand_x, float& rand_y, float& rand_z) const +void WorldObject::GetRandomPoint(float x, float y, float z, float distance, float& rand_x, float& rand_y, float& rand_z, float minDist /*=0.0f*/, float const* ori /*=nullptr*/) const { if (distance == 0) { @@ -1478,8 +1478,17 @@ void WorldObject::GetRandomPoint(float x, float y, float z, float distance, floa } // angle to face `obj` to `this` - float angle = rand_norm_f() * 2 * M_PI_F; - float new_dist = rand_norm_f() * distance; + float angle; + if (!ori) + angle = rand_norm_f() * 2 * M_PI_F; + else + angle = *ori; + + float new_dist; + if (minDist == 0.0f) + new_dist = rand_norm_f() * distance; + else + new_dist = minDist + rand_norm_f() * (distance - minDist); rand_x = x + new_dist * cos(angle); rand_y = y + new_dist * sin(angle); diff --git a/src/game/Object/Object.h b/src/game/Object/Object.h index 089071813..c01568ddd 100644 --- a/src/game/Object/Object.h +++ b/src/game/Object/Object.h @@ -536,9 +536,9 @@ class WorldObject : public Object bool IsPositionValid() const; void UpdateGroundPositionZ(float x, float y, float& z) const; - void UpdateAllowedPositionZ(float x, float y, float& z, Map* atMap = nullptr) const; + void UpdateAllowedPositionZ(float x, float y, float& z, Map* atMap = nullptr) const; - void GetRandomPoint(float x, float y, float z, float distance, float& rand_x, float& rand_y, float& rand_z) const; + void GetRandomPoint(float x, float y, float z, float distance, float& rand_x, float& rand_y, float& rand_z, float minDist = 0.0f, float const* ori = nullptr) const; uint32 GetMapId() const { return m_mapId; } uint32 GetInstanceId() const { return m_InstanceId; } diff --git a/src/game/Object/Player.cpp b/src/game/Object/Player.cpp index 1478072f2..89515f6f8 100644 --- a/src/game/Object/Player.cpp +++ b/src/game/Object/Player.cpp @@ -6947,14 +6947,12 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea) sOutdoorPvPMgr.HandlePlayerEnterZone(this, newZone); SendInitWorldStates(newZone, newArea); // only if really enters to new zone, not just area change, works strange... -// WEATHER ISSUE - commented out to prevent crash on entering game world - /* + if (sWorld.getConfig(CONFIG_BOOL_WEATHER)) { Weather* wth = GetMap()->GetWeatherSystem()->FindOrCreateWeather(newZone); wth->SendWeatherUpdateToPlayer(this); } - */ } #ifdef ENABLE_ELUNA diff --git a/src/game/Server/SharedDefines.h b/src/game/Server/SharedDefines.h index 1fa333c37..73a5eec30 100644 --- a/src/game/Server/SharedDefines.h +++ b/src/game/Server/SharedDefines.h @@ -3235,7 +3235,7 @@ enum WeatherType WEATHER_TYPE_RAIN = 1, WEATHER_TYPE_SNOW = 2, WEATHER_TYPE_STORM = 3, - WEATHER_TYPE_THUNDERS = 86, + WEATHER_TYPE_THUNDER = 86, WEATHER_TYPE_BLACKRAIN = 90 }; diff --git a/src/game/WorldHandlers/Map.cpp b/src/game/WorldHandlers/Map.cpp index 7fb465a4f..6e5782f0b 100644 --- a/src/game/WorldHandlers/Map.cpp +++ b/src/game/WorldHandlers/Map.cpp @@ -43,9 +43,9 @@ #include "VMapFactory.h" #include "MoveMap.h" #include "BattleGround/BattleGroundMgr.h" -#include "Weather.h" #include "Calendar.h" #include "Chat.h" +#include "Weather.h" #ifdef ENABLE_ELUNA #include "LuaEngine.h" #endif /* ENABLE_ELUNA */ @@ -59,26 +59,20 @@ Map::~Map() UnloadAll(true); if (!m_scriptSchedule.empty()) - { sScriptMgr.DecreaseScheduledScriptCount(m_scriptSchedule.size()); - } if (m_persistentState) - { - m_persistentState->SetUsedByMapState(NULL); - } // field pointer can be deleted after this + m_persistentState->SetUsedByMapState(nullptr); // field pointer can be deleted after this delete i_data; - i_data = NULL; + i_data = nullptr; // unload instance specific navigation data MMAP::MMapFactory::createOrGetMMapManager()->unloadMapInstance(m_TerrainData->GetMapId(), GetInstanceId()); // release reference count if (m_TerrainData->Release()) - { sTerrainMgr.UnloadTerrain(m_TerrainData->GetMapId()); - } delete m_weatherSystem; m_weatherSystem = NULL; @@ -122,6 +116,8 @@ Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode) m_persistentState = sMapPersistentStateMgr.AddPersistentState(i_mapEntry, GetInstanceId(), GetDifficulty(), 0, IsDungeon()); m_persistentState->SetUsedByMapState(this); + + m_weatherSystem = new WeatherSystem(this); } void Map::InitVisibilityDistance() @@ -591,6 +587,8 @@ void Map::Update(const uint32& t_diff) if (i_data) i_data->Update(t_diff); + + m_weatherSystem->UpdateWeathers(t_diff); } void Map::Remove(Player* player, bool remove) diff --git a/src/game/WorldHandlers/Weather.cpp b/src/game/WorldHandlers/Weather.cpp index 0f38a92d9..78cab2105 100644 --- a/src/game/WorldHandlers/Weather.cpp +++ b/src/game/WorldHandlers/Weather.cpp @@ -55,11 +55,18 @@ Weather::Weather(uint32 zone, WeatherZoneChances const* weatherChances) : bool Weather::Update(uint32 diff, Map const* _map) { m_timer.Update(diff); - if (ReGenerate()) + + ///- If the timer has passed, ReGenerate the weather + if (m_timer.Passed()) { - ///- Weather will be removed if not updated (no players in zone anymore) - if (!SendWeatherForPlayersInZone(_map)) - return false; + m_timer.Reset(); + // update only if Regenerate has changed the weather + if (ReGenerate()) + { + ///- Weather will be removed if not updated (no players in zone anymore) + if (!SendWeatherForPlayersInZone(_map)) + return false; + } } return true; } @@ -155,24 +162,16 @@ bool Weather::ReGenerate() 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(1, 100); if (rnd <= chance1) - { m_type = WEATHER_TYPE_RAIN; - } else if (rnd <= chance2) - { m_type = WEATHER_TYPE_SNOW; - } else if (rnd <= chance3) - { m_type = WEATHER_TYPE_STORM; - } else - { m_type = WEATHER_TYPE_FINE; - } /// New weather statistics (if not fine): ///- 85% light @@ -353,7 +352,7 @@ WeatherState Weather::GetWeatherState() const return WEATHER_STATE_HEAVY_SANDSTORM; case WEATHER_TYPE_BLACKRAIN: return WEATHER_STATE_BLACKRAIN; - case WEATHER_TYPE_THUNDERS: + case WEATHER_TYPE_THUNDER: return WEATHER_STATE_THUNDERS; case WEATHER_TYPE_FINE: // fine default: diff --git a/src/game/WorldHandlers/Weather.h b/src/game/WorldHandlers/Weather.h index 8a18d5cb8..c7bbeec52 100644 --- a/src/game/WorldHandlers/Weather.h +++ b/src/game/WorldHandlers/Weather.h @@ -33,6 +33,13 @@ #include "SharedDefines.h" #include "Timer.h" +class Player; +class Map; + +// --------------------------------------------------------- +// Actual Weather in one zone +// --------------------------------------------------------- + class Player; enum WeatherState @@ -75,7 +82,7 @@ class Weather case WEATHER_TYPE_RAIN: case WEATHER_TYPE_SNOW: case WEATHER_TYPE_STORM: - case WEATHER_TYPE_THUNDERS: + case WEATHER_TYPE_THUNDER: case WEATHER_TYPE_BLACKRAIN: return true; default: diff --git a/src/game/WorldHandlers/World.cpp b/src/game/WorldHandlers/World.cpp index c25d5564a..87ab2d502 100644 --- a/src/game/WorldHandlers/World.cpp +++ b/src/game/WorldHandlers/World.cpp @@ -411,50 +411,6 @@ bool World::RemoveQueuedSession(WorldSession* sess) return found; } -/// Find a Weather object by the given zoneid -Weather* World::FindWeather(uint32 id) const -{ - WeatherMap::const_iterator itr = m_weathers.find(id); - - if (itr != m_weathers.end()) - return itr->second; - else - return 0; -} - -/// Remove a Weather object for the given zoneid -void World::RemoveWeather(uint32 id) -{ - // not called at the moment. Kept for completeness - WeatherMap::iterator itr = m_weathers.find(id); - - if (itr != m_weathers.end()) - { - delete itr->second; - m_weathers.erase(itr); - } -} - -/// Add a Weather object to the list -/* - * chucky - delete this? - * this is not in Two -Weather* World::AddWeather(uint32 zone_id) -{ - WeatherZoneChances const* weatherChances = sObjectMgr.GetWeatherChances(zone_id); - - // zone not have weather, ignore - if (!weatherChances) - return NULL; - - Weather* w = new Weather(zone_id, weatherChances); - m_weathers[w->GetZone()] = w; - w->ReGenerate(); - w->UpdateWeather(); - return w; -} -*/ - /// Initialize config values void World::LoadConfigSettings(bool reload) { diff --git a/src/game/WorldHandlers/World.h b/src/game/WorldHandlers/World.h index 8581df617..327fd1769 100644 --- a/src/game/WorldHandlers/World.h +++ b/src/game/WorldHandlers/World.h @@ -487,6 +487,9 @@ struct CliCommandHolder }; /// The World + +typedef UNORDERED_MAP SessionMap; + class World { public: @@ -510,10 +513,6 @@ class World uint32 GetMaxActiveSessionCount() const { return m_maxActiveSessionCount; } Player* FindPlayerInZone(uint32 zone); - Weather* FindWeather(uint32 id) const; - Weather* AddWeather(uint32 zone_id); - void RemoveWeather(uint32 zone_id); - /// Get the active session server limit (or security level limitations) uint32 GetPlayerAmountLimit() const { return m_playerLimit >= 0 ? m_playerLimit : 0; } AccountTypes GetPlayerSecurityLimit() const { return m_playerLimit <= 0 ? AccountTypes(-m_playerLimit) : SEC_PLAYER; } @@ -713,9 +712,6 @@ class World uint32 mail_timer; uint32 mail_timer_expires; - typedef UNORDERED_MAP WeatherMap; - WeatherMap m_weathers; - typedef UNORDERED_MAP SessionMap; SessionMap m_sessions; uint32 m_maxActiveSessionCount; uint32 m_maxQueuedSessionCount; diff --git a/src/modules/Eluna/MapMethods.h b/src/modules/Eluna/MapMethods.h index b1629a27e..5696fed5c 100644 --- a/src/modules/Eluna/MapMethods.h +++ b/src/modules/Eluna/MapMethods.h @@ -245,7 +245,7 @@ namespace LuaMap * WEATHER_TYPE_RAIN = 1, * WEATHER_TYPE_SNOW = 2, * WEATHER_TYPE_STORM = 3, - * WEATHER_TYPE_THUNDERS = 86, + * WEATHER_TYPE_THUNDER = 86, * WEATHER_TYPE_BLACKRAIN = 90 * }; * diff --git a/src/shared/revision.h b/src/shared/revision.h index 4bdf44c09..ebcfcc887 100644 --- a/src/shared/revision.h +++ b/src/shared/revision.h @@ -37,7 +37,7 @@ #define CHAR_DB_UPDATE_DESCRIPTION "match_client_limits" #define WORLD_DB_VERSION_NR 21 - #define WORLD_DB_STRUCTURE_NR 2 - #define WORLD_DB_CONTENT_NR 3 + #define WORLD_DB_STRUCTURE_NR 3 + #define WORLD_DB_CONTENT_NR 0 #define WORLD_DB_UPDATE_DESCRIPTION "script_binding populated" #endif // __REVISION_H__