[Expeditions] Decouple dz updates from expeditions (#1303)

Use internal dz messages to process duration and location changes

Add world DynamicZone class (later this will inherit from a base)

Add FindDynamicZoneByID to get dz from zone and world system caches
This commit is contained in:
hg
2021-03-28 19:14:36 -04:00
committed by GitHub
parent dbb9c1d4f4
commit d9e23a0303
21 changed files with 350 additions and 286 deletions
+101 -7
View File
@@ -20,6 +20,7 @@
#include "dynamic_zone.h"
#include "client.h"
#include "expedition.h"
#include "worldserver.h"
#include "zonedb.h"
#include "../common/eqemu_logsys.h"
@@ -37,20 +38,27 @@ DynamicZone::DynamicZone(
}
DynamicZone::DynamicZone(
std::string zone_shortname, uint32_t version, uint32_t duration, DynamicZoneType type
std::string zone_name, uint32_t version, uint32_t duration, DynamicZoneType type
) :
m_version(version),
m_duration(duration),
m_type(type)
DynamicZone(ZoneID(zone_name), version, duration, type)
{
m_zone_id = ZoneID(zone_shortname.c_str());
if (!m_zone_id)
{
LogDynamicZones("Failed to get zone id for zone [{}]", zone_shortname);
LogDynamicZones("Failed to get zone id for zone [{}]", zone_name);
}
}
DynamicZone* DynamicZone::FindDynamicZoneByID(uint32_t dz_id)
{
auto expedition = Expedition::FindCachedExpeditionByDynamicZoneID(dz_id);
if (expedition)
{
return &expedition->GetDynamicZone();
}
// todo: other system caches
return nullptr;
}
std::unordered_map<uint32_t, DynamicZone> DynamicZone::LoadMultipleDzFromDatabase(
const std::vector<uint32_t>& dynamic_zone_ids)
{
@@ -443,12 +451,23 @@ void DynamicZone::SetCompass(const DynamicZoneLocation& location, bool update_db
{
m_compass = location;
if (m_on_compass_change)
{
m_on_compass_change();
}
if (update_db)
{
SaveCompassToDatabase();
SendWorldSetLocation(ServerOP_DzSetCompass, location);
}
}
void DynamicZone::SetCompass(uint32_t zone_id, float x, float y, float z, bool update_db)
{
SetCompass({ zone_id, x, y, z, 0.0f }, update_db);
}
void DynamicZone::SetSafeReturn(const DynamicZoneLocation& location, bool update_db)
{
m_safereturn = location;
@@ -456,9 +475,15 @@ void DynamicZone::SetSafeReturn(const DynamicZoneLocation& location, bool update
if (update_db)
{
SaveSafeReturnToDatabase();
SendWorldSetLocation(ServerOP_DzSetSafeReturn, location);
}
}
void DynamicZone::SetSafeReturn(uint32_t zone_id, float x, float y, float z, float heading, bool update_db)
{
SetSafeReturn({ zone_id, x, y, z, heading }, update_db);
}
void DynamicZone::SetZoneInLocation(const DynamicZoneLocation& location, bool update_db)
{
m_zonein = location;
@@ -467,9 +492,15 @@ void DynamicZone::SetZoneInLocation(const DynamicZoneLocation& location, bool up
if (update_db)
{
SaveZoneInLocationToDatabase();
SendWorldSetLocation(ServerOP_DzSetZoneIn, location);
}
}
void DynamicZone::SetZoneInLocation(float x, float y, float z, float heading, bool update_db)
{
SetZoneInLocation({ 0, x, y, z, heading }, update_db);
}
bool DynamicZone::IsCurrentZoneDzInstance() const
{
return (zone && zone->GetInstanceID() != 0 && zone->GetInstanceID() == GetInstanceID());
@@ -496,6 +527,17 @@ uint32_t DynamicZone::GetSecondsRemaining() const
return 0;
}
void DynamicZone::SetSecondsRemaining(uint32_t seconds_remaining)
{
// async
constexpr uint32_t pack_size = sizeof(ServerDzSetDuration_Struct);
auto pack = std::make_unique<ServerPacket>(ServerOP_DzSetSecondsRemaining, pack_size);
auto buf = reinterpret_cast<ServerDzSetDuration_Struct*>(pack->pBuffer);
buf->dz_id = GetID();
buf->seconds = seconds_remaining;
worldserver.SendPacket(pack.get());
}
void DynamicZone::SetUpdatedDuration(uint32_t new_duration)
{
// preserves original start time, just modifies duration and expire time
@@ -511,6 +553,22 @@ void DynamicZone::SetUpdatedDuration(uint32_t new_duration)
}
}
void DynamicZone::SendWorldSetLocation(uint16_t server_opcode, const DynamicZoneLocation& location)
{
uint32_t pack_size = sizeof(ServerDzLocation_Struct);
auto pack = std::make_unique<ServerPacket>(server_opcode, pack_size);
auto buf = reinterpret_cast<ServerDzLocation_Struct*>(pack->pBuffer);
buf->dz_id = GetID();
buf->sender_zone_id = zone ? zone->GetZoneID() : 0;
buf->sender_instance_id = zone ? zone->GetInstanceID() : 0;
buf->zone_id = location.zone_id;
buf->x = location.x;
buf->y = location.y;
buf->z = location.z;
buf->heading = location.heading;
worldserver.SendPacket(pack.get());
}
void DynamicZone::HandleWorldMessage(ServerPacket* pack)
{
switch (pack->opcode)
@@ -540,5 +598,41 @@ void DynamicZone::HandleWorldMessage(ServerPacket* pack)
}
break;
}
case ServerOP_DzDurationUpdate:
{
auto buf = reinterpret_cast<ServerDzSetDuration_Struct*>(pack->pBuffer);
auto dz = DynamicZone::FindDynamicZoneByID(buf->dz_id);
if (dz)
{
dz->SetUpdatedDuration(buf->seconds);
}
break;
}
case ServerOP_DzSetCompass:
case ServerOP_DzSetSafeReturn:
case ServerOP_DzSetZoneIn:
{
auto buf = reinterpret_cast<ServerDzLocation_Struct*>(pack->pBuffer);
if (zone && !zone->IsZone(buf->sender_zone_id, buf->sender_instance_id))
{
auto dz = DynamicZone::FindDynamicZoneByID(buf->dz_id);
if (dz)
{
if (pack->opcode == ServerOP_DzSetCompass)
{
dz->SetCompass(buf->zone_id, buf->x, buf->y, buf->z, false);
}
else if (pack->opcode == ServerOP_DzSetSafeReturn)
{
dz->SetSafeReturn(buf->zone_id, buf->x, buf->y, buf->z, buf->heading, false);
}
else if (pack->opcode == ServerOP_DzSetZoneIn)
{
dz->SetZoneInLocation(buf->x, buf->y, buf->z, buf->heading, false);
}
}
}
break;
}
}
}