mirror of
https://github.com/araxiaonline/TrinityCore.git
synced 2026-06-24 07:30:07 -04:00
55ce180f28
- Logging System is asyncronous to improve performance.
- Each msg and Logger has a Log Type and Log Level assigned. Each msg is assigned the Logger of same Log Type or "root" Logger is selected if there is no Logger configured for the given Log Type
- Loggers have a list of Appenders to send the msg to. The Msg in the Logger is not sent to Appenders if the msg LogLevel is lower than Logger LogLevel.
- There are three (at the moment) types of Appenders: Console, File or DB (this is WIP, not working ATM). Msg is not written to the resource if msg LogLevel is lower than Appender LogLevel.
- Appender and Console Log levels can be changed while server is active with command '.set loglevel (a/l) name level'
Explanation of use with Sample config:
Appender.Console.Type=1 (1 = Console)
Appender.Console.Level=2 (2 = Debug)
Appender.Server.Type=2 (2 = File)
Appender.Server.Level=3 (3 = Info)
Appender.Server.File=Server.log
Appender.SQL.Type=2 (2 = File)
Appender.SQL.Level=1 (1 = Trace)
Appender.SQL.File=sql.log
Appenders=Console Server (NOTE: SQL has not been included here... that will make core ignore the config for "SQL" as it's not in this list)
Logger.root.Type=0 (0 = Default - if it's not created by config, server will create it with LogLevel = DISABLED)
Logger.root.Level=5 (5 = Error)
Logger.root.Appenders=Console
Logger.SQL.Type=26 (26 = SQL)
Logger.SQL.Level=3 (2 = Debug)
Logger.SQL.Appenders=Console Server SQL
Logger.SomeRandomName.Type=24 (24 = Guild)
Logger.SomeRandomName.Level=5 (5 = Error)
Loggers=root SQL SomeRandomName
* At loading Appender SQL will be ignored, as it's not present on "Appenders"
* sLog->outDebug(LOG_FILTER_GUILD, "Some log msg related to Guilds")
- Msg is sent to Logger of Type LOG_FILTER_GUILD (24). Logger with name SomeRandomName is found but it's LogLevel = 5 and Msg LogLevel=2... Msg is not logged
* sLog->outError(LOG_FILTER_GUILD, "Some error log msg related to Guilds")
- Msg is sent to Logger of Type LOG_FILTER_GUILD (24). Logger with name SomeRandomeName is found with proper LogLevel but Logger does not have any Appenders assigned to that logger... Msg is not logged
* sLog->outDebug(LOG_FILTER_SQL, "Some msg related to SQLs")
- Msg is sent to Logger SQL (matches type), as it matches LogLevel the msg is sent to Appenders Console, Server and SQL
- Appender Console has lower Log Level: Msg is logged to Console
- Appender Server has higher Log Level: Msg is not logged to file
- Appender SQL has lower Log Level: Msg is logged to file sql.log
* sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Some msg related to Battelgrounds")
- Msg is sent to Logger root (Type 0) as no Logger was found with Type LOG_FILTER_BATTLEGROUND (13). As Logger has higher LogLevel msg is not sent to any appender
* sLog->outError(LOG_FILTER_BATTLEGROUND, "Some error msg related to Battelgrounds")
- Msg is sent to Logger root (Type 0) as no Logger was found with Type LOG_FILTER_BATTLEGROUND (13). Msg has lower LogLevel and is sent to Appender Console
- Appender Console has lower LogLevel: Msg is logged to Console
317 lines
9.0 KiB
C++
Executable File
317 lines
9.0 KiB
C++
Executable File
/*
|
|
* Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
|
|
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
|
*
|
|
* 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 2 of the License, or (at your
|
|
* option) 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 <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/** \file
|
|
\ingroup world
|
|
*/
|
|
|
|
#include "Weather.h"
|
|
#include "WorldPacket.h"
|
|
#include "Player.h"
|
|
#include "World.h"
|
|
#include "Log.h"
|
|
#include "ObjectMgr.h"
|
|
#include "Util.h"
|
|
#include "ScriptMgr.h"
|
|
|
|
/// Create the Weather object
|
|
Weather::Weather(uint32 zone, WeatherData const* weatherChances)
|
|
: m_zone(zone), m_weatherChances(weatherChances)
|
|
{
|
|
m_timer.SetInterval(sWorld->getIntConfig(CONFIG_INTERVAL_CHANGEWEATHER));
|
|
m_type = WEATHER_TYPE_FINE;
|
|
m_grade = 0;
|
|
|
|
sLog->outInfo(LOG_FILTER_GENERAL, "WORLD: Starting weather system for zone %u (change every %u minutes).", m_zone, (uint32)(m_timer.GetInterval() / (MINUTE*IN_MILLISECONDS)));
|
|
}
|
|
|
|
/// 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())
|
|
{
|
|
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 (!UpdateWeather())
|
|
return false;
|
|
}
|
|
}
|
|
|
|
sScriptMgr->OnWeatherUpdate(this, diff);
|
|
return true;
|
|
}
|
|
|
|
/// Calculate the new weather
|
|
bool Weather::ReGenerate()
|
|
{
|
|
if (!m_weatherChances)
|
|
{
|
|
m_type = WEATHER_TYPE_FINE;
|
|
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->outInfo(LOG_FILTER_GENERAL, "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
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
if (m_grade > 0.6666667f)
|
|
{
|
|
// Severe change, but how severe?
|
|
uint32 rnd = urand(0, 99);
|
|
if (rnd < 50)
|
|
{
|
|
m_grade -= 0.6666667f;
|
|
return true;
|
|
}
|
|
}
|
|
m_type = WEATHER_TYPE_FINE; // clear up
|
|
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;
|
|
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
|
|
///- 7% medium
|
|
///- 7% heavy
|
|
/// If fine 100% sun (no fog)
|
|
|
|
if (m_type == WEATHER_TYPE_FINE)
|
|
{
|
|
m_grade = 0.0f;
|
|
}
|
|
else if (u < 90)
|
|
{
|
|
m_grade = (float)rand_norm() * 0.3333f;
|
|
}
|
|
else
|
|
{
|
|
// Severe change, but how severe?
|
|
rnd = urand(0, 99);
|
|
if (rnd < 50)
|
|
m_grade = (float)rand_norm() * 0.3333f + 0.3334f;
|
|
else
|
|
m_grade = (float)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);
|
|
}
|
|
|
|
/// 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)
|
|
{
|
|
case WEATHER_STATE_LIGHT_RAIN:
|
|
wthstr = "light rain";
|
|
break;
|
|
case WEATHER_STATE_MEDIUM_RAIN:
|
|
wthstr = "medium rain";
|
|
break;
|
|
case WEATHER_STATE_HEAVY_RAIN:
|
|
wthstr = "heavy rain";
|
|
break;
|
|
case WEATHER_STATE_LIGHT_SNOW:
|
|
wthstr = "light snow";
|
|
break;
|
|
case WEATHER_STATE_MEDIUM_SNOW:
|
|
wthstr = "medium snow";
|
|
break;
|
|
case WEATHER_STATE_HEAVY_SNOW:
|
|
wthstr = "heavy snow";
|
|
break;
|
|
case WEATHER_STATE_LIGHT_SANDSTORM:
|
|
wthstr = "light sandstorm";
|
|
break;
|
|
case WEATHER_STATE_MEDIUM_SANDSTORM:
|
|
wthstr = "medium sandstorm";
|
|
break;
|
|
case WEATHER_STATE_HEAVY_SANDSTORM:
|
|
wthstr = "heavy sandstorm";
|
|
break;
|
|
case WEATHER_STATE_THUNDERS:
|
|
wthstr = "thunders";
|
|
break;
|
|
case WEATHER_STATE_BLACKRAIN:
|
|
wthstr = "blackrain";
|
|
break;
|
|
case WEATHER_STATE_FINE:
|
|
default:
|
|
wthstr = "fine";
|
|
break;
|
|
}
|
|
sLog->outInfo(LOG_FILTER_GENERAL, "Change the weather of zone %u to %s.", m_zone, wthstr);
|
|
|
|
sScriptMgr->OnWeatherChange(this, state, m_grade);
|
|
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:
|
|
if (m_grade<0.40f)
|
|
return WEATHER_STATE_LIGHT_RAIN;
|
|
else if (m_grade<0.70f)
|
|
return WEATHER_STATE_MEDIUM_RAIN;
|
|
else
|
|
return WEATHER_STATE_HEAVY_RAIN;
|
|
case WEATHER_TYPE_SNOW:
|
|
if (m_grade<0.40f)
|
|
return WEATHER_STATE_LIGHT_SNOW;
|
|
else if (m_grade<0.70f)
|
|
return WEATHER_STATE_MEDIUM_SNOW;
|
|
else
|
|
return WEATHER_STATE_HEAVY_SNOW;
|
|
case WEATHER_TYPE_STORM:
|
|
if (m_grade<0.40f)
|
|
return WEATHER_STATE_LIGHT_SANDSTORM;
|
|
else if (m_grade<0.70f)
|
|
return WEATHER_STATE_MEDIUM_SANDSTORM;
|
|
else
|
|
return WEATHER_STATE_HEAVY_SANDSTORM;
|
|
case WEATHER_TYPE_BLACKRAIN:
|
|
return WEATHER_STATE_BLACKRAIN;
|
|
case WEATHER_TYPE_THUNDERS:
|
|
return WEATHER_STATE_THUNDERS;
|
|
case WEATHER_TYPE_FINE:
|
|
default:
|
|
return WEATHER_STATE_FINE;
|
|
}
|
|
}
|
|
|