Live-Like weather. Big thanks to Robregen for figuring out the system!

Included in the required SQL is weather data pulled from NewZone live packets for up to PoP. An update to EQExtractor will be made to grab the rest of the data from existing collects.

Please note: Until weather data is grabbed for zones later than PoP, weather will not work in those zones.
This commit is contained in:
cavedude00
2014-01-20 10:10:39 -08:00
parent 3970bb5955
commit 70f994cda5
18 changed files with 381 additions and 136 deletions
+127 -64
View File
@@ -134,20 +134,6 @@ bool Zone::Bootup(uint32 iZoneID, uint32 iInstanceID, bool iStaticZone) {
}
}
zone->weather_type = database.GetZoneWeather(iZoneID, zone->GetInstanceVersion());
LogFile->write(EQEMuLog::Debug, "Zone: %s has weather of type %i.", zonename, zone->weather_type);
if(zone->weather_type > 3 || zone->weather_type == 0) {
zone->zone_weather = 0;
zone->Weather_Timer->Disable();
LogFile->write(EQEMuLog::Debug, "Zone: %s(%i) has no weather type. The weather timer has been disabled.", zonename, iZoneID);
}
else {
zone->zone_weather = 0;
LogFile->write(EQEMuLog::Debug, "Zone: %s(%i) has weather type = %i. The weather timer has been enabled.", zonename, iZoneID, zone->weather_type);
}
ZoneLoaded = true;
worldserver.SetZone(iZoneID, iInstanceID);
@@ -900,11 +886,11 @@ Zone::Zone(uint32 in_zoneid, uint32 in_instanceid, const char* in_short_name)
long_name = strcpy(new char[18], "Long zone missing");
}
autoshutdown_timer.Start(AUTHENTICATION_TIMEOUT * 1000, false);
Weather_Timer = new Timer((MakeRandomInt(1800, 7200) + 30) * 2000);
Weather_Timer = new Timer(60000);
Weather_Timer->Start();
LogFile->write(EQEMuLog::Debug, "The next weather check for zone: %s will be in %i seconds.", short_name, Weather_Timer->GetRemainingTime()/1000);
weather_type = 0;
zone_weather = 0;
weather_intensity = 0;
blocked_spells = nullptr;
totalBS = 0;
aas = nullptr;
@@ -1365,38 +1351,7 @@ bool Zone::Process() {
if(Weather_Timer->Check()){
Weather_Timer->Disable();
uint16 tmpweather = MakeRandomInt(0, 100);
if(zone->weather_type != 0)
{
if(tmpweather >= 80)
{
// A change in the weather....
uint8 tmpOldWeather = zone_weather;
if(zone->zone_weather == 0)
zone->zone_weather = zone->weather_type;
else
zone->zone_weather = 0;
LogFile->write(EQEMuLog::Debug, "The weather for zone: %s has changed. Old weather was = %i. New weather is = %i", zone->GetShortName(), tmpOldWeather, zone_weather);
this->weatherSend();
}
else
LogFile->write(EQEMuLog::Debug, "The weather for zone: %s is not going to change. Chance was = %i percent.", zone->GetShortName(), tmpweather);
uint32 weatherTime = 0;
if(zone->zone_weather != zone->weather_type)
weatherTime = (MakeRandomInt(1800, 7200) + 30) * 2000;
else
weatherTime = (MakeRandomInt(900, 2700) + 30) * 1000;
Weather_Timer->Start(weatherTime);
LogFile->write(EQEMuLog::Debug, "The next weather check for zone: %s will be in %i seconds.", zone->GetShortName(), Weather_Timer->GetRemainingTime()/1000);
}
this->ChangeWeather();
}
if(qGlobals)
@@ -1426,6 +1381,129 @@ bool Zone::Process() {
return true;
}
void Zone::ChangeWeather()
{
if(!HasWeather())
{
Weather_Timer->Disable();
return;
}
int chance = MakeRandomInt(0, 3);
uint8 rainchance = zone->newzone_data.rain_chance[chance];
uint8 rainduration = zone->newzone_data.rain_duration[chance];
uint8 snowchance = zone->newzone_data.snow_chance[chance];
uint8 snowduration = zone->newzone_data.snow_duration[chance];
uint32 weathertimer = 0;
uint16 tmpweather = MakeRandomInt(0, 100);
uint8 duration = 0;
uint8 tmpOldWeather = zone->zone_weather;
bool changed = false;
if(tmpOldWeather == 0)
{
if(rainchance > 0 || snowchance > 0)
{
uint8 intensity = MakeRandomInt(1, 10);
if((rainchance > snowchance) || (rainchance == snowchance))
{
//It's gunna rain!
if(rainchance >= tmpweather)
{
if(rainduration == 0)
duration = 1;
else
duration = rainduration*3; //Duration is 1 EQ hour which is 3 earth minutes.
weathertimer = (duration*60)*1000;
Weather_Timer->Start(weathertimer);
zone->zone_weather = 1;
zone->weather_intensity = intensity;
changed = true;
}
}
else
{
//It's gunna snow!
if(snowchance >= tmpweather)
{
if(snowduration == 0)
duration = 1;
else
duration = snowduration*3;
weathertimer = (duration*60)*1000;
Weather_Timer->Start(weathertimer);
zone->zone_weather = 2;
zone->weather_intensity = intensity;
changed = true;
}
}
}
}
else
{
changed = true;
//We've had weather, now taking a break
if(tmpOldWeather == 1)
{
if(rainduration == 0)
duration = 1;
else
duration = rainduration*3; //Duration is 1 EQ hour which is 3 earth minutes.
weathertimer = (duration*60)*1000;
Weather_Timer->Start(weathertimer);
zone->zone_weather = 0;
zone->weather_intensity = 0;
}
else if(tmpOldWeather == 2)
{
if(snowduration == 0)
duration = 1;
else
duration = snowduration*3; //Duration is 1 EQ hour which is 3 earth minutes.
weathertimer = (duration*60)*1000;
Weather_Timer->Start(weathertimer);
zone->zone_weather = 0;
zone->weather_intensity = 0;
}
}
if(changed == false)
{
if(weathertimer == 0)
{
uint32 weatherTimerRule = RuleI(Zone, WeatherTimer);
weathertimer = weatherTimerRule*1000;
Weather_Timer->Start(weathertimer);
}
LogFile->write(EQEMuLog::Debug, "The next weather check for zone: %s will be in %i seconds.", zone->GetShortName(), Weather_Timer->GetRemainingTime()/1000);
}
else
{
LogFile->write(EQEMuLog::Debug, "The weather for zone: %s has changed. Old weather was = %i. New weather is = %i The next check will be in %i seconds. Rain chance: %i, Rain duration: %i, Snow chance %i, Snow duration: %i", zone->GetShortName(), tmpOldWeather, zone_weather,Weather_Timer->GetRemainingTime()/1000,rainchance,rainduration,snowchance,snowduration);
this->weatherSend();
}
}
bool Zone::HasWeather()
{
uint8 rain1 = zone->newzone_data.rain_chance[0];
uint8 rain2 = zone->newzone_data.rain_chance[1];
uint8 rain3 = zone->newzone_data.rain_chance[2];
uint8 rain4 = zone->newzone_data.rain_chance[3];
uint8 snow1 = zone->newzone_data.snow_chance[0];
uint8 snow2 = zone->newzone_data.snow_chance[1];
uint8 snow3 = zone->newzone_data.snow_chance[2];
uint8 snow4 = zone->newzone_data.snow_chance[3];
if(rain1 == 0 && rain2 == 0 && rain3 == 0 && rain4 == 0 && snow1 == 0 && snow2 == 0 && snow3 == 0 && snow4 == 0)
return false;
else
return true;
}
void Zone::StartShutdownTimer(uint32 set_time) {
if (set_time > autoshutdown_timer.GetRemainingTime()) {
if (set_time == (RuleI(Zone, AutoShutdownDelay)))
@@ -1807,26 +1885,11 @@ bool ZoneDatabase::GetDecayTimes(npcDecayTimes_Struct* npcCorpseDecayTimes) {
void Zone::weatherSend()
{
/*switch(zone_weather)
{
case 0:
entity_list.Message(0, 0, "The sky clears.");
break;
case 1:
entity_list.Message(0, 0, "Raindrops begin to fall from the sky.");
break;
case 2:
entity_list.Message(0, 0, "Snowflakes begin to fall from the sky.");
break;
default:
entity_list.Message(0, 0, "Strange weather patterns form in the sky. (%i)", zone_weather);
break;
}*/
EQApplicationPacket* outapp = new EQApplicationPacket(OP_Weather, 8);
if(zone_weather>0)
outapp->pBuffer[0] = zone_weather-1;
if(zone_weather>0)
outapp->pBuffer[4] = 0x10+MakeRandomInt(0, 9); // This number changes in the packets, intensity?
outapp->pBuffer[4] = zone->weather_intensity;
entity_list.QueueClients(0, outapp);
safe_delete(outapp);
}