Weather system fixed

Fixed by implementing the cmangos Cata commit
[c13018] Improve Weather handling
and comparing their code with the current system.

Thanks,. cmangos :-)
This commit is contained in:
Charles A Edwards 2016-08-28 11:11:03 +01:00 committed by Antz
parent 3b52b46199
commit 6db0ba8ae9
12 changed files with 55 additions and 93 deletions

View file

@ -4865,17 +4865,17 @@ bool ChatHandler::HandleChangeWeatherCommand(char* args)
// see enum WeatherType // see enum WeatherType
if (!Weather::IsValidWeatherType(type)) if (!Weather::IsValidWeatherType(type))
{
return false; return false;
}
float grade; float grade;
if (!ExtractFloat(&args, grade)) if (!ExtractFloat(&args, grade))
return false; return false;
// 0 to 1, sending -1 is instant good weather // clamp grade from 0 to 1
if (grade < 0.0f || grade > 1.0f) if (grade < 0.0f)
return false; grade = 0.0f;
else if (grade > 1.0f)
grade = 1.0f;
Player* player = m_session->GetPlayer(); Player* player = m_session->GetPlayer();
uint32 zoneId = player->GetZoneId(); uint32 zoneId = player->GetZoneId();
@ -4884,7 +4884,6 @@ bool ChatHandler::HandleChangeWeatherCommand(char* args)
SendSysMessage(LANG_NO_WEATHER); SendSysMessage(LANG_NO_WEATHER);
SetSentErrorMessage(true); SetSentErrorMessage(true);
} }
player->GetMap()->SetWeather(zoneId, (WeatherType)type, grade, false); player->GetMap()->SetWeather(zoneId, (WeatherType)type, grade, false);
return true; return true;

View file

@ -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); 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) 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` // angle to face `obj` to `this`
float angle = rand_norm_f() * 2 * M_PI_F; float angle;
float new_dist = rand_norm_f() * distance; 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_x = x + new_dist * cos(angle);
rand_y = y + new_dist * sin(angle); rand_y = y + new_dist * sin(angle);

View file

@ -538,7 +538,7 @@ class WorldObject : public Object
void UpdateGroundPositionZ(float x, float y, float& z) 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 GetMapId() const { return m_mapId; }
uint32 GetInstanceId() const { return m_InstanceId; } uint32 GetInstanceId() const { return m_InstanceId; }

View file

@ -6947,14 +6947,12 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea)
sOutdoorPvPMgr.HandlePlayerEnterZone(this, newZone); sOutdoorPvPMgr.HandlePlayerEnterZone(this, newZone);
SendInitWorldStates(newZone, newArea); // only if really enters to new zone, not just area change, works strange... 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)) if (sWorld.getConfig(CONFIG_BOOL_WEATHER))
{ {
Weather* wth = GetMap()->GetWeatherSystem()->FindOrCreateWeather(newZone); Weather* wth = GetMap()->GetWeatherSystem()->FindOrCreateWeather(newZone);
wth->SendWeatherUpdateToPlayer(this); wth->SendWeatherUpdateToPlayer(this);
} }
*/
} }
#ifdef ENABLE_ELUNA #ifdef ENABLE_ELUNA

View file

@ -3235,7 +3235,7 @@ enum WeatherType
WEATHER_TYPE_RAIN = 1, WEATHER_TYPE_RAIN = 1,
WEATHER_TYPE_SNOW = 2, WEATHER_TYPE_SNOW = 2,
WEATHER_TYPE_STORM = 3, WEATHER_TYPE_STORM = 3,
WEATHER_TYPE_THUNDERS = 86, WEATHER_TYPE_THUNDER = 86,
WEATHER_TYPE_BLACKRAIN = 90 WEATHER_TYPE_BLACKRAIN = 90
}; };

View file

@ -43,9 +43,9 @@
#include "VMapFactory.h" #include "VMapFactory.h"
#include "MoveMap.h" #include "MoveMap.h"
#include "BattleGround/BattleGroundMgr.h" #include "BattleGround/BattleGroundMgr.h"
#include "Weather.h"
#include "Calendar.h" #include "Calendar.h"
#include "Chat.h" #include "Chat.h"
#include "Weather.h"
#ifdef ENABLE_ELUNA #ifdef ENABLE_ELUNA
#include "LuaEngine.h" #include "LuaEngine.h"
#endif /* ENABLE_ELUNA */ #endif /* ENABLE_ELUNA */
@ -59,26 +59,20 @@ Map::~Map()
UnloadAll(true); UnloadAll(true);
if (!m_scriptSchedule.empty()) if (!m_scriptSchedule.empty())
{
sScriptMgr.DecreaseScheduledScriptCount(m_scriptSchedule.size()); sScriptMgr.DecreaseScheduledScriptCount(m_scriptSchedule.size());
}
if (m_persistentState) if (m_persistentState)
{ m_persistentState->SetUsedByMapState(nullptr); // field pointer can be deleted after this
m_persistentState->SetUsedByMapState(NULL);
} // field pointer can be deleted after this
delete i_data; delete i_data;
i_data = NULL; i_data = nullptr;
// unload instance specific navigation data // unload instance specific navigation data
MMAP::MMapFactory::createOrGetMMapManager()->unloadMapInstance(m_TerrainData->GetMapId(), GetInstanceId()); MMAP::MMapFactory::createOrGetMMapManager()->unloadMapInstance(m_TerrainData->GetMapId(), GetInstanceId());
// release reference count // release reference count
if (m_TerrainData->Release()) if (m_TerrainData->Release())
{
sTerrainMgr.UnloadTerrain(m_TerrainData->GetMapId()); sTerrainMgr.UnloadTerrain(m_TerrainData->GetMapId());
}
delete m_weatherSystem; delete m_weatherSystem;
m_weatherSystem = NULL; 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 = sMapPersistentStateMgr.AddPersistentState(i_mapEntry, GetInstanceId(), GetDifficulty(), 0, IsDungeon());
m_persistentState->SetUsedByMapState(this); m_persistentState->SetUsedByMapState(this);
m_weatherSystem = new WeatherSystem(this);
} }
void Map::InitVisibilityDistance() void Map::InitVisibilityDistance()
@ -591,6 +587,8 @@ void Map::Update(const uint32& t_diff)
if (i_data) if (i_data)
i_data->Update(t_diff); i_data->Update(t_diff);
m_weatherSystem->UpdateWeathers(t_diff);
} }
void Map::Remove(Player* player, bool remove) void Map::Remove(Player* player, bool remove)

View file

@ -55,12 +55,19 @@ Weather::Weather(uint32 zone, WeatherZoneChances const* weatherChances) :
bool Weather::Update(uint32 diff, Map const* _map) bool Weather::Update(uint32 diff, Map const* _map)
{ {
m_timer.Update(diff); m_timer.Update(diff);
///- If the timer has passed, ReGenerate the weather
if (m_timer.Passed())
{
m_timer.Reset();
// update only if Regenerate has changed the weather
if (ReGenerate()) if (ReGenerate())
{ {
///- Weather will be removed if not updated (no players in zone anymore) ///- Weather will be removed if not updated (no players in zone anymore)
if (!SendWeatherForPlayersInZone(_map)) if (!SendWeatherForPlayersInZone(_map))
return false; return false;
} }
}
return true; return true;
} }
@ -158,21 +165,13 @@ bool Weather::ReGenerate()
uint32 rnd = urand(1, 100); uint32 rnd = urand(1, 100);
if (rnd <= chance1) if (rnd <= chance1)
{
m_type = WEATHER_TYPE_RAIN; m_type = WEATHER_TYPE_RAIN;
}
else if (rnd <= chance2) else if (rnd <= chance2)
{
m_type = WEATHER_TYPE_SNOW; m_type = WEATHER_TYPE_SNOW;
}
else if (rnd <= chance3) else if (rnd <= chance3)
{
m_type = WEATHER_TYPE_STORM; m_type = WEATHER_TYPE_STORM;
}
else else
{
m_type = WEATHER_TYPE_FINE; m_type = WEATHER_TYPE_FINE;
}
/// New weather statistics (if not fine): /// New weather statistics (if not fine):
///- 85% light ///- 85% light
@ -353,7 +352,7 @@ WeatherState Weather::GetWeatherState() const
return WEATHER_STATE_HEAVY_SANDSTORM; return WEATHER_STATE_HEAVY_SANDSTORM;
case WEATHER_TYPE_BLACKRAIN: case WEATHER_TYPE_BLACKRAIN:
return WEATHER_STATE_BLACKRAIN; return WEATHER_STATE_BLACKRAIN;
case WEATHER_TYPE_THUNDERS: case WEATHER_TYPE_THUNDER:
return WEATHER_STATE_THUNDERS; return WEATHER_STATE_THUNDERS;
case WEATHER_TYPE_FINE: // fine case WEATHER_TYPE_FINE: // fine
default: default:

View file

@ -33,6 +33,13 @@
#include "SharedDefines.h" #include "SharedDefines.h"
#include "Timer.h" #include "Timer.h"
class Player;
class Map;
// ---------------------------------------------------------
// Actual Weather in one zone
// ---------------------------------------------------------
class Player; class Player;
enum WeatherState enum WeatherState
@ -75,7 +82,7 @@ class Weather
case WEATHER_TYPE_RAIN: case WEATHER_TYPE_RAIN:
case WEATHER_TYPE_SNOW: case WEATHER_TYPE_SNOW:
case WEATHER_TYPE_STORM: case WEATHER_TYPE_STORM:
case WEATHER_TYPE_THUNDERS: case WEATHER_TYPE_THUNDER:
case WEATHER_TYPE_BLACKRAIN: case WEATHER_TYPE_BLACKRAIN:
return true; return true;
default: default:

View file

@ -411,50 +411,6 @@ bool World::RemoveQueuedSession(WorldSession* sess)
return found; 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 /// Initialize config values
void World::LoadConfigSettings(bool reload) void World::LoadConfigSettings(bool reload)
{ {

View file

@ -487,6 +487,9 @@ struct CliCommandHolder
}; };
/// The World /// The World
typedef UNORDERED_MAP<uint32, WorldSession*> SessionMap;
class World class World
{ {
public: public:
@ -510,10 +513,6 @@ class World
uint32 GetMaxActiveSessionCount() const { return m_maxActiveSessionCount; } uint32 GetMaxActiveSessionCount() const { return m_maxActiveSessionCount; }
Player* FindPlayerInZone(uint32 zone); 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) /// Get the active session server limit (or security level limitations)
uint32 GetPlayerAmountLimit() const { return m_playerLimit >= 0 ? m_playerLimit : 0; } uint32 GetPlayerAmountLimit() const { return m_playerLimit >= 0 ? m_playerLimit : 0; }
AccountTypes GetPlayerSecurityLimit() const { return m_playerLimit <= 0 ? AccountTypes(-m_playerLimit) : SEC_PLAYER; } AccountTypes GetPlayerSecurityLimit() const { return m_playerLimit <= 0 ? AccountTypes(-m_playerLimit) : SEC_PLAYER; }
@ -713,9 +712,6 @@ class World
uint32 mail_timer; uint32 mail_timer;
uint32 mail_timer_expires; uint32 mail_timer_expires;
typedef UNORDERED_MAP<uint32, Weather*> WeatherMap;
WeatherMap m_weathers;
typedef UNORDERED_MAP<uint32, WorldSession*> SessionMap;
SessionMap m_sessions; SessionMap m_sessions;
uint32 m_maxActiveSessionCount; uint32 m_maxActiveSessionCount;
uint32 m_maxQueuedSessionCount; uint32 m_maxQueuedSessionCount;

View file

@ -245,7 +245,7 @@ namespace LuaMap
* WEATHER_TYPE_RAIN = 1, * WEATHER_TYPE_RAIN = 1,
* WEATHER_TYPE_SNOW = 2, * WEATHER_TYPE_SNOW = 2,
* WEATHER_TYPE_STORM = 3, * WEATHER_TYPE_STORM = 3,
* WEATHER_TYPE_THUNDERS = 86, * WEATHER_TYPE_THUNDER = 86,
* WEATHER_TYPE_BLACKRAIN = 90 * WEATHER_TYPE_BLACKRAIN = 90
* }; * };
* *

View file

@ -37,7 +37,7 @@
#define CHAR_DB_UPDATE_DESCRIPTION "match_client_limits" #define CHAR_DB_UPDATE_DESCRIPTION "match_client_limits"
#define WORLD_DB_VERSION_NR 21 #define WORLD_DB_VERSION_NR 21
#define WORLD_DB_STRUCTURE_NR 2 #define WORLD_DB_STRUCTURE_NR 3
#define WORLD_DB_CONTENT_NR 3 #define WORLD_DB_CONTENT_NR 0
#define WORLD_DB_UPDATE_DESCRIPTION "script_binding populated" #define WORLD_DB_UPDATE_DESCRIPTION "script_binding populated"
#endif // __REVISION_H__ #endif // __REVISION_H__