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
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;

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);
}
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);

View file

@ -538,7 +538,7 @@ class WorldObject : public Object
void UpdateGroundPositionZ(float x, float y, float& z) 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; }

View file

@ -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

View file

@ -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
};

View file

@ -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)

View file

@ -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;
}
@ -158,21 +165,13 @@ bool Weather::ReGenerate()
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:

View file

@ -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:

View file

@ -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)
{

View file

@ -487,6 +487,9 @@ struct CliCommandHolder
};
/// The World
typedef UNORDERED_MAP<uint32, WorldSession*> 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<uint32, Weather*> WeatherMap;
WeatherMap m_weathers;
typedef UNORDERED_MAP<uint32, WorldSession*> SessionMap;
SessionMap m_sessions;
uint32 m_maxActiveSessionCount;
uint32 m_maxQueuedSessionCount;

View file

@ -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
* };
*

View file

@ -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__