Added constants and cleaned up #weather command

This commit is contained in:
Kinglykrab
2022-10-13 17:50:33 -04:00
parent a87a9b3532
commit 2ec85304b7
9 changed files with 287 additions and 143 deletions
+77
View File
@@ -0,0 +1,77 @@
{
"files.associations": {
"any": "cpp",
"array": "cpp",
"atomic": "cpp",
"strstream": "cpp",
"bit": "cpp",
"*.tcc": "cpp",
"bitset": "cpp",
"cctype": "cpp",
"charconv": "cpp",
"chrono": "cpp",
"cinttypes": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"codecvt": "cpp",
"compare": "cpp",
"complex": "cpp",
"concepts": "cpp",
"condition_variable": "cpp",
"csignal": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"deque": "cpp",
"forward_list": "cpp",
"list": "cpp",
"map": "cpp",
"set": "cpp",
"string": "cpp",
"unordered_map": "cpp",
"unordered_set": "cpp",
"vector": "cpp",
"exception": "cpp",
"algorithm": "cpp",
"functional": "cpp",
"iterator": "cpp",
"memory": "cpp",
"memory_resource": "cpp",
"numeric": "cpp",
"random": "cpp",
"ratio": "cpp",
"regex": "cpp",
"string_view": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"fstream": "cpp",
"future": "cpp",
"initializer_list": "cpp",
"iomanip": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"istream": "cpp",
"limits": "cpp",
"mutex": "cpp",
"new": "cpp",
"numbers": "cpp",
"ostream": "cpp",
"semaphore": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"stop_token": "cpp",
"streambuf": "cpp",
"thread": "cpp",
"typeindex": "cpp",
"typeinfo": "cpp",
"valarray": "cpp"
}
}
+18
View File
@@ -513,3 +513,21 @@ std::string EQ::constants::GetObjectTypeName(int object_type)
return std::string(); return std::string();
} }
const std::map<uint8, std::string>& EQ::constants::GetWeatherTypeMap()
{
static const std::map<uint8, std::string> weather_type_map ={
{ WeatherTypes::None, "None" },
{ WeatherTypes::Raining, "Raining" },
{ WeatherTypes::Snowing, "Snowing" }
};
}
std::string EQ::constants::GetWeatherTypeName(uint8 weather_type)
{
if (EQ::ValueWithin(weather_type, WeatherTypes::None, WeatherTypes::Snowing)) {
return EQ::constants::GetWeatherTypeMap().find(weather_type)->second;
}
return std::string();
}
+9
View File
@@ -312,6 +312,12 @@ namespace EQ
NoDeposit NoDeposit
}; };
enum WeatherTypes : uint8 {
None,
Raining,
Snowing
};
const char *GetStanceName(StanceType stance_type); const char *GetStanceName(StanceType stance_type);
int ConvertStanceTypeToIndex(StanceType stance_type); int ConvertStanceTypeToIndex(StanceType stance_type);
@@ -345,6 +351,9 @@ namespace EQ
extern const std::map<int, std::string>& GetObjectTypeMap(); extern const std::map<int, std::string>& GetObjectTypeMap();
std::string GetObjectTypeName(int object_type); std::string GetObjectTypeName(int object_type);
extern const std::map<uint8, std::string>& GetWeatherTypeMap();
std::string GetWeatherTypeName(uint8 weather_type);
const int STANCE_TYPE_FIRST = stancePassive; const int STANCE_TYPE_FIRST = stancePassive;
const int STANCE_TYPE_LAST = stanceBurnAE; const int STANCE_TYPE_LAST = stanceBurnAE;
const int STANCE_TYPE_COUNT = stanceBurnAE; const int STANCE_TYPE_COUNT = stanceBurnAE;
+6 -3
View File
@@ -1746,11 +1746,14 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
outapp = new EQApplicationPacket(OP_Weather, 12); outapp = new EQApplicationPacket(OP_Weather, 12);
Weather_Struct *ws = (Weather_Struct *)outapp->pBuffer; Weather_Struct *ws = (Weather_Struct *)outapp->pBuffer;
ws->val1 = 0x000000FF; ws->val1 = 0x000000FF;
if (zone->zone_weather == 1) { ws->type = 0x31; } // Rain
if (zone->zone_weather == 2) { if (zone->zone_weather == EQ::constants::WeatherTypes::Raining) {
ws->type = 0x31;
} else if (zone->zone_weather == EQ::constants::WeatherTypes::Snowing) {
outapp->pBuffer[8] = 0x01; outapp->pBuffer[8] = 0x01;
ws->type = 0x02; ws->type = EQ::constants::WeatherTypes::Snowing;
} }
outapp->priority = 6; outapp->priority = 6;
QueuePacket(outapp); QueuePacket(outapp);
safe_delete(outapp); safe_delete(outapp);
+86 -49
View File
@@ -2,67 +2,104 @@
void command_weather(Client *c, const Seperator *sep) void command_weather(Client *c, const Seperator *sep)
{ {
if (!(sep->arg[1][0] == '0' || sep->arg[1][0] == '1' || sep->arg[1][0] == '2' || sep->arg[1][0] == '3')) { if (!sep->IsNumber(1)) {
c->Message(Chat::White, "Usage: #weather <0/1/2/3> - Off/Rain/Snow/Manual."); c->Message(Chat::White, "Usage: #weather [0|1|2] - [Off|Rain|Snow]");
c->Message(Chat::White, "Usage: #weather 3 [Type] [Intensity] - Manually set weather type and intensity");
return;
} }
else if (zone->zone_weather == 0) {
if (sep->arg[1][0] == int arguments = sep->argnum;
'3') { // Put in modifications here because it had a very good chance at screwing up the client's weather system if rain was sent during snow -T7 if (arguments == 1) {
if (sep->arg[2][0] != 0 && sep->arg[3][0] != 0) { auto new_weather = static_cast<uint8>(std::stoul(sep->arg[1]));
c->Message(Chat::White, "Sending weather packet... TYPE=%s, INTENSITY=%s", sep->arg[2], sep->arg[3]); uint8 new_intensity = 0;
zone->zone_weather = atoi(sep->arg[2]); std::string weather_message = "The sky clears.";
if (new_weather == EQ::constants::WeatherTypes::Snowing) {
weather_message = "Snowflakes begin to fall from the sky.";
new_weather = EQ::constants::WeatherTypes::Snowing;
new_intensity = 0x02;
} else if (new_weather == EQ::constants::WeatherTypes::Raining) {
weather_message = "Raindrops begin to fall from the sky.";
new_weather = EQ::constants::WeatherTypes::Raining;
new_intensity = 0x01; // This is how it's done in Fear, and you can see a decent distance with it at this value
} else {
c->Message(Chat::White, "Usage: #weather [0|1|2] - [Off|Rain|Snow]");
c->Message(Chat::White, "Usage: #weather 3 [Type] [Intensity] - Manually set weather type and intensity");
return;
}
zone->zone_weather = new_weather;
auto outapp = new EQApplicationPacket(OP_Weather, 8); auto outapp = new EQApplicationPacket(OP_Weather, 8);
outapp->pBuffer[0] = atoi(sep->arg[2]);
outapp->pBuffer[4] = atoi(sep->arg[3]); // This number changes in the packets, intensity? if (new_weather != EQ::constants::WeatherTypes::None) {
if (new_weather == EQ::constants::WeatherTypes::Snowing) {
outapp->pBuffer[0] = EQ::constants::WeatherTypes::Snowing;
}
outapp->pBuffer[4] = new_intensity;
}
c->Message(Chat::White, weather_message.c_str());
entity_list.QueueClients(c, outapp); entity_list.QueueClients(c, outapp);
safe_delete(outapp); safe_delete(outapp);
} else if (arguments == 3) {
auto command_type = static_cast<uint8>(std::stoul(sep->arg[1]));
uint8 new_weather = EQ::constants::WeatherTypes::None;
uint8 new_intensity = 0;
std::string weather_message;
if (zone->zone_weather == EQ::constants::WeatherTypes::None) {
if (command_type > EQ::constants::WeatherTypes::Snowing) {
new_weather = static_cast<uint8>(std::stoul(sep->arg[2]));
new_intensity = static_cast<uint8>(std::stoul(sep->arg[3]));
weather_message = fmt::format(
"Sending {} ({}) with an intensity of {}.",
EQ::constants::GetWeatherTypeName(new_weather),
new_weather,
new_intensity
);
} else if (command_type == EQ::constants::WeatherTypes::Snowing) {
weather_message = "Snowflakes begin to fall from the sky.";
new_weather = EQ::constants::WeatherTypes::Snowing;
new_intensity = 0x02;
} else if (command_type == EQ::constants::WeatherTypes::Raining) {
weather_message = "Raindrops begin to fall from the sky.";
new_weather = EQ::constants::WeatherTypes::Raining;
new_intensity = 0x01; // This is how it's done in Fear, and you can see a decent distance with it at this value
} }
else {
c->Message(Chat::White, "Manual Usage: #weather 3 <type> <intensity>"); zone->zone_weather = new_weather;
}
}
else if (sep->arg[1][0] == '2') {
entity_list.Message(0, 0, "Snowflakes begin to fall from the sky.");
zone->zone_weather = 2;
auto outapp = new EQApplicationPacket(OP_Weather, 8); auto outapp = new EQApplicationPacket(OP_Weather, 8);
outapp->pBuffer[0] = 0x01;
outapp->pBuffer[4] = 0x02; // This number changes in the packets, intensity? if (new_weather != EQ::constants::WeatherTypes::Raining) {
outapp->pBuffer[0] = new_weather;
}
outapp->pBuffer[4] = new_intensity;
c->Message(Chat::White, weather_message.c_str());
entity_list.QueueClients(c, outapp); entity_list.QueueClients(c, outapp);
safe_delete(outapp); safe_delete(outapp);
} } else {
else if (sep->arg[1][0] == '1') {
entity_list.Message(0, 0, "Raindrops begin to fall from the sky.");
zone->zone_weather = 1;
auto outapp = new EQApplicationPacket(OP_Weather, 8); auto outapp = new EQApplicationPacket(OP_Weather, 8);
outapp->pBuffer[4] = 0x01; // This is how it's done in Fear, and you can see a decent distance with it at this value weather_message = "The sky clears.";
entity_list.QueueClients(c, outapp);
safe_delete(outapp); if (zone->zone_weather == EQ::constants::WeatherTypes::Snowing) {
} weather_message = "The sky clears as the snow stops falling.";
}
else {
if (zone->zone_weather == 1) { // Doing this because if you have rain/snow on, you can only turn one off.
entity_list.Message(0, 0, "The sky clears as the rain ceases to fall.");
zone->zone_weather = 0;
auto outapp = new EQApplicationPacket(OP_Weather, 8);
// To shutoff weather you send an empty 8 byte packet (You get this everytime you zone even if the sky is clear)
entity_list.QueueClients(c, outapp);
safe_delete(outapp);
}
else if (zone->zone_weather == 2) {
entity_list.Message(0, 0, "The sky clears as the snow stops falling.");
zone->zone_weather = 0;
auto outapp = new EQApplicationPacket(OP_Weather, 8);
// To shutoff weather you send an empty 8 byte packet (You get this everytime you zone even if the sky is clear)
outapp->pBuffer[0] = 0x01; // Snow has it's own shutoff packet outapp->pBuffer[0] = 0x01; // Snow has it's own shutoff packet
entity_list.QueueClients(c, outapp); } else if (zone->zone_weather == EQ::constants::WeatherTypes::Raining) {
safe_delete(outapp); weather_message = "The sky clears as the rain ceases to fall.";
} }
else {
entity_list.Message(0, 0, "The sky clears."); zone->zone_weather = EQ::constants::WeatherTypes::None;
zone->zone_weather = 0;
auto outapp = new EQApplicationPacket(OP_Weather, 8); c->Message(Chat::White, weather_message.c_str());
// To shutoff weather you send an empty 8 byte packet (You get this everytime you zone even if the sky is clear)
entity_list.QueueClients(c, outapp); entity_list.QueueClients(c, outapp);
safe_delete(outapp); safe_delete(outapp);
} }
} }
+3 -2
View File
@@ -1203,8 +1203,9 @@ luabind::adl::object lua_get_characters_in_instance(lua_State *L, uint16 instanc
} }
int lua_get_zone_weather() { int lua_get_zone_weather() {
if(!zone) if (!zone) {
return 0; return EQ::constants::WeatherTypes::None;
}
return zone->zone_weather; return zone->zone_weather;
} }
+1 -1
View File
@@ -2110,7 +2110,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
#ifdef SPELL_EFFECT_SPAM #ifdef SPELL_EFFECT_SPAM
snprintf(effect_desc, _EDLEN, "Stop Rain"); snprintf(effect_desc, _EDLEN, "Stop Rain");
#endif #endif
zone->zone_weather = 0; zone->zone_weather = EQ::constants::WeatherTypes::None;
zone->weather_intensity = 0; zone->weather_intensity = 0;
zone->weatherSend(); zone->weatherSend();
break; break;
+83 -84
View File
@@ -1027,7 +1027,7 @@ Zone::Zone(uint32 in_zoneid, uint32 in_instanceid, const char* in_short_name)
Weather_Timer = new Timer(60000); Weather_Timer = new Timer(60000);
Weather_Timer->Start(); Weather_Timer->Start();
LogDebug("The next weather check for zone: [{}] will be in [{}] seconds", short_name, Weather_Timer->GetRemainingTime()/1000); LogDebug("The next weather check for zone: [{}] will be in [{}] seconds", short_name, Weather_Timer->GetRemainingTime()/1000);
zone_weather = 0; zone_weather = EQ::constants::WeatherTypes::None;
weather_intensity = 0; weather_intensity = 0;
blocked_spells = nullptr; blocked_spells = nullptr;
zone_total_blocked_spells = 0; zone_total_blocked_spells = 0;
@@ -1705,121 +1705,118 @@ void Zone::ChangeWeather()
} }
int chance = zone->random.Int(0, 3); int chance = zone->random.Int(0, 3);
uint8 rainchance = zone->newzone_data.rain_chance[chance]; auto rain_chance = zone->newzone_data.rain_chance[chance];
uint8 rainduration = zone->newzone_data.rain_duration[chance]; auto rain_duration = zone->newzone_data.rain_duration[chance];
uint8 snowchance = zone->newzone_data.snow_chance[chance]; auto snow_chance = zone->newzone_data.snow_chance[chance];
uint8 snowduration = zone->newzone_data.snow_duration[chance]; auto snow_duration = zone->newzone_data.snow_duration[chance];
uint32 weathertimer = 0; uint32 weather_timer = 0;
uint16 tmpweather = zone->random.Int(0, 100); auto temporary_weather = static_cast<uint8>(zone->random.Int(0, 100));
uint8 duration = 0; uint8 duration = 0;
uint8 tmpOldWeather = zone->zone_weather; auto temporary_old_weather = zone->zone_weather;
bool changed = false; bool changed = false;
if(tmpOldWeather == 0) if (temporary_old_weather == EQ::constants::WeatherTypes::None) {
{ if (rain_chance > 0 || snow_chance > 0) {
if(rainchance > 0 || snowchance > 0) auto intensity = static_cast<uint8>(zone->random.Int(1, 10));
{ if (rain_chance > snow_chance || rain_chance == snow_chance) { // Rain
uint8 intensity = zone->random.Int(1, 10); if (rain_chance >= temporary_weather) {
if((rainchance > snowchance) || (rainchance == snowchance)) if (!rain_duration) {
{
//It's gunna rain!
if(rainchance >= tmpweather)
{
if(rainduration == 0)
duration = 1; duration = 1;
else } else {
duration = rainduration*3; //Duration is 1 EQ hour which is 3 earth minutes. duration = rain_duration * 3; //Duration is 1 EQ hour which is 3 earth minutes.
}
weathertimer = (duration*60)*1000; weather_timer = (duration * 60) * 1000;
Weather_Timer->Start(weathertimer); Weather_Timer->Start(weather_timer);
zone->zone_weather = 1; zone->zone_weather = EQ::constants::WeatherTypes::Raining;
zone->weather_intensity = intensity; zone->weather_intensity = intensity;
changed = true; changed = true;
} }
} } else { // Snow
else if (snow_chance >= temporary_weather) {
{ if (!snow_duration) {
//It's gunna snow!
if(snowchance >= tmpweather)
{
if(snowduration == 0)
duration = 1; duration = 1;
else } else {
duration = snowduration*3; duration = snow_duration * 3; //Duration is 1 EQ hour which is 3 earth minutes.
weathertimer = (duration*60)*1000; }
Weather_Timer->Start(weathertimer);
zone->zone_weather = 2; weather_timer = (duration * 60) * 1000;
Weather_Timer->Start(weather_timer);
zone->zone_weather = EQ::constants::WeatherTypes::Snowing;
zone->weather_intensity = intensity; zone->weather_intensity = intensity;
changed = true; changed = true;
} }
} }
} }
} } else {
else
{
changed = true; changed = true;
//We've had weather, now taking a break //We've had weather, now taking a break
if(tmpOldWeather == 1) if (temporary_old_weather == EQ::constants::WeatherTypes::Raining) {
{ if (!rain_duration) {
if(rainduration == 0)
duration = 1; duration = 1;
else } else {
duration = rainduration*3; //Duration is 1 EQ hour which is 3 earth minutes. duration = rain_duration * 3; //Duration is 1 EQ hour which is 3 earth minutes.
weathertimer = (duration*60)*1000;
Weather_Timer->Start(weathertimer);
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 = (duration * 60) * 1000;
Weather_Timer->Start(weathertimer); Weather_Timer->Start(weather_timer);
zone->weather_intensity = 0;
} else if (temporary_old_weather == EQ::constants::WeatherTypes::Snowing) {
if (!snow_duration) {
duration = 1;
} else {
duration = snow_duration * 3; //Duration is 1 EQ hour which is 3 earth minutes.
}
weather_timer = (duration * 60) * 1000;
Weather_Timer->Start(weather_timer);
zone->weather_intensity = 0; zone->weather_intensity = 0;
} }
} }
if(changed == false) if (!changed) {
{ if (weather_timer == 0) {
if(weathertimer == 0) uint32 weather_timer_rule = RuleI(Zone, WeatherTimer);
{ weather_timer = weather_timer_rule * 1000;
uint32 weatherTimerRule = RuleI(Zone, WeatherTimer); Weather_Timer->Start(weather_timer);
weathertimer = weatherTimerRule*1000;
Weather_Timer->Start(weathertimer);
} }
LogDebug("The next weather check for zone: [{}] will be in [{}] seconds", zone->GetShortName(), Weather_Timer->GetRemainingTime()/1000); LogDebug("The next weather check for zone: [{}] will be in [{}] seconds", zone->GetShortName(), Weather_Timer->GetRemainingTime()/1000);
} } else {
else LogDebug("The weather for zone: [{}] has changed. Old weather was = [{}]. New weather is = [{}] The next check will be in [{}] seconds. Rain chance: [{}], Rain duration: [{}], Snow chance [{}], Snow duration: [{}]", zone->GetShortName(), temporary_old_weather, zone_weather,Weather_Timer->GetRemainingTime()/1000,rain_chance,rain_duration,snow_chance,snow_duration);
{
LogDebug("The weather for zone: [{}] has changed. Old weather was = [{}]. New weather is = [{}] The next check will be in [{}] seconds. Rain chance: [{}], Rain duration: [{}], Snow chance [{}], Snow duration: [{}]", zone->GetShortName(), tmpOldWeather, zone_weather,Weather_Timer->GetRemainingTime()/1000,rainchance,rainduration,snowchance,snowduration);
weatherSend(); weatherSend();
if (zone->weather_intensity == 0) if (zone->weather_intensity == 0) {
{ zone->zone_weather = EQ::constants::WeatherTypes::None;
zone->zone_weather = 0;
} }
} }
} }
bool Zone::HasWeather() bool Zone::HasWeather()
{ {
uint8 rain1 = zone->newzone_data.rain_chance[0]; auto rain_chance_one = zone->newzone_data.rain_chance[0];
uint8 rain2 = zone->newzone_data.rain_chance[1]; auto rain_chance_two = zone->newzone_data.rain_chance[1];
uint8 rain3 = zone->newzone_data.rain_chance[2]; auto rain_chance_three = zone->newzone_data.rain_chance[2];
uint8 rain4 = zone->newzone_data.rain_chance[3]; auto rain_chance_four = 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) auto snow_chance_one = zone->newzone_data.snow_chance[0];
auto snow_chance_two = zone->newzone_data.snow_chance[1];
auto snow_chance_three = zone->newzone_data.snow_chance[2];
auto snow_chance_four = zone->newzone_data.snow_chance[3];
if (
!rain_chance_one &&
!rain_chance_two &&
!rain_chance_three &&
!rain_chance_four &&
!snow_chance_one &&
!snow_chance_two &&
!snow_chance_three &&
!snow_chance_four
) {
return false; return false;
else } else {
return true; return true;
} }
}
void Zone::StartShutdownTimer(uint32 set_time) void Zone::StartShutdownTimer(uint32 set_time)
{ {
@@ -2200,18 +2197,20 @@ bool ZoneDatabase::GetDecayTimes(npcDecayTimes_Struct *npcCorpseDecayTimes)
void Zone::weatherSend(Client *client) void Zone::weatherSend(Client *client)
{ {
auto outapp = new EQApplicationPacket(OP_Weather, 8); auto outapp = new EQApplicationPacket(OP_Weather, 8);
if (zone_weather > 0) { if (zone_weather > EQ::constants::WeatherTypes::None) {
outapp->pBuffer[0] = zone_weather - 1; outapp->pBuffer[0] = zone_weather - 1;
} }
if (zone_weather > 0) {
if (zone_weather > EQ::constants::WeatherTypes::None) {
outapp->pBuffer[4] = zone->weather_intensity; outapp->pBuffer[4] = zone->weather_intensity;
} }
if (client) { if (client) {
client->QueuePacket(outapp); client->QueuePacket(outapp);
} } else {
else {
entity_list.QueueClients(0, outapp); entity_list.QueueClients(0, outapp);
} }
safe_delete(outapp); safe_delete(outapp);
} }
+2 -2
View File
@@ -249,8 +249,8 @@ public:
uint32 GetCurrencyID(uint32 item_id); uint32 GetCurrencyID(uint32 item_id);
uint32 GetCurrencyItemID(uint32 currency_id); uint32 GetCurrencyItemID(uint32 currency_id);
inline bool IsRaining() { return zone_weather == 1; } inline bool IsRaining() { return zone_weather == EQ::constants::WeatherTypes::Raining; }
inline bool IsSnowing() { return zone_weather == 2; } inline bool IsSnowing() { return zone_weather == EQ::constants::WeatherTypes::Snowing; }
std::string GetZoneDescription(); std::string GetZoneDescription();
void SendReloadMessage(std::string reload_type); void SendReloadMessage(std::string reload_type);