mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-17 07:18:37 +00:00
[Expeditions] Create common dz abstract class (#1312)
This creates an abstract class in common so zone and world can share most of the implementation. World now has access to the same dz data and api as zone. Rename CharacterChange to AddRemoveCharacter for clarity Rename GetRemainingDuration to GetDurationRemaining for consistency Move dynamic zone queries to custom repository methods
This commit is contained in:
+53
-459
@@ -22,30 +22,35 @@
|
||||
#include "client.h"
|
||||
#include "expedition.h"
|
||||
#include "worldserver.h"
|
||||
#include "zonedb.h"
|
||||
#include "../common/eqemu_logsys.h"
|
||||
|
||||
extern WorldServer worldserver;
|
||||
|
||||
DynamicZone::DynamicZone(
|
||||
uint32_t zone_id, uint32_t version, uint32_t duration, DynamicZoneType type
|
||||
) :
|
||||
m_zone_id(zone_id),
|
||||
m_version(version),
|
||||
m_duration(duration),
|
||||
m_type(type)
|
||||
{
|
||||
}
|
||||
// message string 8312 added in September 08 2020 Test patch (used by both dz and shared tasks)
|
||||
const char* const CREATE_NOT_ALL_ADDED = "Not all players in your {} were added to the {}. The {} can take a maximum of {} players, and your {} has {}.";
|
||||
|
||||
DynamicZone::DynamicZone(
|
||||
std::string zone_name, uint32_t version, uint32_t duration, DynamicZoneType type
|
||||
) :
|
||||
DynamicZone(ZoneID(zone_name), version, duration, type)
|
||||
uint32_t zone_id, uint32_t version, uint32_t duration, DynamicZoneType type)
|
||||
{
|
||||
if (!m_zone_id)
|
||||
{
|
||||
LogDynamicZones("Failed to get zone id for zone [{}]", zone_name);
|
||||
}
|
||||
m_zone_id = zone_id;
|
||||
m_zone_version = version;
|
||||
m_duration = std::chrono::seconds(duration);
|
||||
m_type = type;
|
||||
}
|
||||
|
||||
Database& DynamicZone::GetDatabase()
|
||||
{
|
||||
return database;
|
||||
}
|
||||
|
||||
uint16_t DynamicZone::GetCurrentInstanceID()
|
||||
{
|
||||
return zone ? static_cast<uint16_t>(zone->GetInstanceID()) : 0;
|
||||
}
|
||||
|
||||
uint16_t DynamicZone::GetCurrentZoneID()
|
||||
{
|
||||
return zone ? static_cast<uint16_t>(zone->GetZoneID()) : 0;
|
||||
}
|
||||
|
||||
DynamicZone* DynamicZone::FindDynamicZoneByID(uint32_t dz_id)
|
||||
@@ -64,366 +69,43 @@ std::unordered_map<uint32_t, DynamicZone> DynamicZone::LoadMultipleDzFromDatabas
|
||||
{
|
||||
LogDynamicZonesDetail("Loading dynamic zone data for [{}] instances", dynamic_zone_ids.size());
|
||||
|
||||
std::string in_dynamic_zone_ids_query = fmt::format("{}", fmt::join(dynamic_zone_ids, ","));
|
||||
|
||||
std::unordered_map<uint32_t, DynamicZone> dynamic_zones;
|
||||
|
||||
if (!in_dynamic_zone_ids_query.empty())
|
||||
auto entries = DynamicZonesRepository::GetWithInstance(database, dynamic_zone_ids);
|
||||
for (auto& entry : entries)
|
||||
{
|
||||
std::string query = fmt::format(SQL(
|
||||
{} WHERE dynamic_zones.id IN ({});
|
||||
), DynamicZoneSelectQuery(), in_dynamic_zone_ids_query);
|
||||
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (results.Success())
|
||||
{
|
||||
for (auto row = results.begin(); row != results.end(); ++row)
|
||||
{
|
||||
DynamicZone dz;
|
||||
dz.LoadDatabaseResult(row);
|
||||
dynamic_zones.emplace(dz.GetID(), dz);
|
||||
}
|
||||
}
|
||||
dynamic_zones.emplace(entry.id, std::move(entry));
|
||||
}
|
||||
|
||||
return dynamic_zones;
|
||||
}
|
||||
|
||||
uint32_t DynamicZone::Create()
|
||||
void DynamicZone::StartAllClientRemovalTimers()
|
||||
{
|
||||
if (m_id != 0)
|
||||
for (const auto& client_iter : entity_list.GetClientList())
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
if (GetInstanceID() == 0)
|
||||
{
|
||||
CreateInstance();
|
||||
}
|
||||
|
||||
m_id = SaveToDatabase();
|
||||
|
||||
return m_id;
|
||||
}
|
||||
|
||||
uint32_t DynamicZone::CreateInstance()
|
||||
{
|
||||
if (m_instance_id)
|
||||
{
|
||||
LogDynamicZones("CreateInstance failed, instance id [{}] already created", m_instance_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!m_zone_id)
|
||||
{
|
||||
LogDynamicZones("CreateInstance failed, invalid zone id [{}]", m_zone_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t instance_id = 0;
|
||||
if (!database.GetUnusedInstanceID(instance_id)) // todo: doesn't this race with insert?
|
||||
{
|
||||
LogDynamicZones("Failed to find unused instance id");
|
||||
return 0;
|
||||
}
|
||||
|
||||
m_start_time = std::chrono::system_clock::now();
|
||||
auto start_time = std::chrono::system_clock::to_time_t(m_start_time);
|
||||
|
||||
std::string query = fmt::format(SQL(
|
||||
INSERT INTO instance_list
|
||||
(id, zone, version, start_time, duration)
|
||||
VALUES
|
||||
({}, {}, {}, {}, {})
|
||||
), instance_id, m_zone_id, m_version, start_time, m_duration.count());
|
||||
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
{
|
||||
LogDynamicZones("Failed to create instance [{}] for Dynamic Zone [{}]", instance_id, m_zone_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
m_instance_id = instance_id;
|
||||
m_never_expires = false;
|
||||
m_expire_time = m_start_time + m_duration;
|
||||
|
||||
return m_instance_id;
|
||||
}
|
||||
|
||||
std::string DynamicZone::DynamicZoneSelectQuery()
|
||||
{
|
||||
return std::string(SQL(
|
||||
SELECT
|
||||
instance_list.id,
|
||||
instance_list.zone,
|
||||
instance_list.version,
|
||||
instance_list.start_time,
|
||||
instance_list.duration,
|
||||
instance_list.never_expires,
|
||||
dynamic_zones.id,
|
||||
dynamic_zones.type,
|
||||
dynamic_zones.compass_zone_id,
|
||||
dynamic_zones.compass_x,
|
||||
dynamic_zones.compass_y,
|
||||
dynamic_zones.compass_z,
|
||||
dynamic_zones.safe_return_zone_id,
|
||||
dynamic_zones.safe_return_x,
|
||||
dynamic_zones.safe_return_y,
|
||||
dynamic_zones.safe_return_z,
|
||||
dynamic_zones.safe_return_heading,
|
||||
dynamic_zones.zone_in_x,
|
||||
dynamic_zones.zone_in_y,
|
||||
dynamic_zones.zone_in_z,
|
||||
dynamic_zones.zone_in_heading,
|
||||
dynamic_zones.has_zone_in
|
||||
FROM dynamic_zones
|
||||
INNER JOIN instance_list ON dynamic_zones.instance_id = instance_list.id
|
||||
));
|
||||
}
|
||||
|
||||
void DynamicZone::LoadDatabaseResult(MySQLRequestRow& row)
|
||||
{
|
||||
m_instance_id = strtoul(row[0], nullptr, 10);
|
||||
m_zone_id = strtoul(row[1], nullptr, 10);
|
||||
m_version = strtoul(row[2], nullptr, 10);
|
||||
m_start_time = std::chrono::system_clock::from_time_t(strtoul(row[3], nullptr, 10));
|
||||
m_duration = std::chrono::seconds(strtoul(row[4], nullptr, 10));
|
||||
m_expire_time = m_start_time + m_duration;
|
||||
m_never_expires = (strtoul(row[5], nullptr, 10) != 0);
|
||||
m_id = strtoul(row[6], nullptr, 10);
|
||||
m_type = static_cast<DynamicZoneType>(strtoul(row[7], nullptr, 10));
|
||||
m_compass.zone_id = strtoul(row[8], nullptr, 10);
|
||||
m_compass.x = strtof(row[9], nullptr);
|
||||
m_compass.y = strtof(row[10], nullptr);
|
||||
m_compass.z = strtof(row[11], nullptr);
|
||||
m_safereturn.zone_id = strtoul(row[12], nullptr, 10);
|
||||
m_safereturn.x = strtof(row[13], nullptr);
|
||||
m_safereturn.y = strtof(row[14], nullptr);
|
||||
m_safereturn.z = strtof(row[15], nullptr);
|
||||
m_safereturn.heading = strtof(row[16], nullptr);
|
||||
m_zonein.x = strtof(row[17], nullptr);
|
||||
m_zonein.y = strtof(row[18], nullptr);
|
||||
m_zonein.z = strtof(row[19], nullptr);
|
||||
m_zonein.heading = strtof(row[20], nullptr);
|
||||
m_has_zonein = (strtoul(row[21], nullptr, 10) != 0);
|
||||
}
|
||||
|
||||
uint32_t DynamicZone::SaveToDatabase()
|
||||
{
|
||||
LogDynamicZonesDetail("Saving dz instance [{}] to database", m_instance_id);
|
||||
|
||||
if (m_instance_id != 0)
|
||||
{
|
||||
std::string query = fmt::format(SQL(
|
||||
INSERT INTO dynamic_zones
|
||||
(
|
||||
instance_id,
|
||||
type,
|
||||
compass_zone_id,
|
||||
compass_x,
|
||||
compass_y,
|
||||
compass_z,
|
||||
safe_return_zone_id,
|
||||
safe_return_x,
|
||||
safe_return_y,
|
||||
safe_return_z,
|
||||
safe_return_heading,
|
||||
zone_in_x,
|
||||
zone_in_y,
|
||||
zone_in_z,
|
||||
zone_in_heading,
|
||||
has_zone_in
|
||||
)
|
||||
VALUES
|
||||
({}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {});
|
||||
),
|
||||
m_instance_id,
|
||||
static_cast<uint8_t>(m_type),
|
||||
m_compass.zone_id,
|
||||
m_compass.x,
|
||||
m_compass.y,
|
||||
m_compass.z,
|
||||
m_safereturn.zone_id,
|
||||
m_safereturn.x,
|
||||
m_safereturn.y,
|
||||
m_safereturn.z,
|
||||
m_safereturn.heading,
|
||||
m_zonein.x,
|
||||
m_zonein.y,
|
||||
m_zonein.z,
|
||||
m_zonein.heading,
|
||||
m_has_zonein
|
||||
);
|
||||
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (results.Success())
|
||||
if (client_iter.second)
|
||||
{
|
||||
return results.LastInsertedID();
|
||||
client_iter.second->SetDzRemovalTimer(true);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DynamicZone::SaveCompassToDatabase()
|
||||
void DynamicZone::SendInstanceRemoveAllCharacters()
|
||||
{
|
||||
LogDynamicZonesDetail(
|
||||
"Instance [{}] saving compass zone: [{}] xyz: ([{}], [{}], [{}])",
|
||||
m_instance_id, m_compass.zone_id, m_compass.x, m_compass.y, m_compass.z
|
||||
);
|
||||
|
||||
if (m_instance_id != 0)
|
||||
// just remove all clients in bulk instead of only characters assigned to the instance
|
||||
if (IsCurrentZoneDzInstance())
|
||||
{
|
||||
std::string query = fmt::format(SQL(
|
||||
UPDATE dynamic_zones SET
|
||||
compass_zone_id = {},
|
||||
compass_x = {},
|
||||
compass_y = {},
|
||||
compass_z = {}
|
||||
WHERE instance_id = {};
|
||||
),
|
||||
m_compass.zone_id,
|
||||
m_compass.x,
|
||||
m_compass.y,
|
||||
m_compass.z,
|
||||
m_instance_id
|
||||
);
|
||||
|
||||
database.QueryDatabase(query);
|
||||
DynamicZone::StartAllClientRemovalTimers();
|
||||
}
|
||||
else if (GetInstanceID() != 0)
|
||||
{
|
||||
auto pack = CreateServerRemoveAllCharactersPacket();
|
||||
worldserver.SendPacket(pack.get());
|
||||
}
|
||||
}
|
||||
|
||||
void DynamicZone::SaveSafeReturnToDatabase()
|
||||
{
|
||||
LogDynamicZonesDetail(
|
||||
"Instance [{}] saving safereturn zone: [{}] xyzh: ([{}], [{}], [{}], [{}])",
|
||||
m_instance_id, m_safereturn.zone_id, m_safereturn.x, m_safereturn.y, m_safereturn.z, m_safereturn.heading
|
||||
);
|
||||
|
||||
if (m_instance_id != 0)
|
||||
{
|
||||
std::string query = fmt::format(SQL(
|
||||
UPDATE dynamic_zones SET
|
||||
safe_return_zone_id = {},
|
||||
safe_return_x = {},
|
||||
safe_return_y = {},
|
||||
safe_return_z = {},
|
||||
safe_return_heading = {}
|
||||
WHERE instance_id = {};
|
||||
),
|
||||
m_safereturn.zone_id,
|
||||
m_safereturn.x,
|
||||
m_safereturn.y,
|
||||
m_safereturn.z,
|
||||
m_safereturn.heading,
|
||||
m_instance_id
|
||||
);
|
||||
|
||||
database.QueryDatabase(query);
|
||||
}
|
||||
}
|
||||
|
||||
void DynamicZone::SaveZoneInLocationToDatabase()
|
||||
{
|
||||
LogDynamicZonesDetail(
|
||||
"Instance [{}] saving zonein zone: [{}] xyzh: ([{}], [{}], [{}], [{}]) has: [{}]",
|
||||
m_instance_id, m_zone_id, m_zonein.x, m_zonein.y, m_zonein.z, m_zonein.heading, m_has_zonein
|
||||
);
|
||||
|
||||
if (m_instance_id != 0)
|
||||
{
|
||||
std::string query = fmt::format(SQL(
|
||||
UPDATE dynamic_zones SET
|
||||
zone_in_x = {},
|
||||
zone_in_y = {},
|
||||
zone_in_z = {},
|
||||
zone_in_heading = {},
|
||||
has_zone_in = {}
|
||||
WHERE instance_id = {};
|
||||
),
|
||||
m_zonein.x,
|
||||
m_zonein.y,
|
||||
m_zonein.z,
|
||||
m_zonein.heading,
|
||||
m_has_zonein,
|
||||
m_instance_id
|
||||
);
|
||||
|
||||
database.QueryDatabase(query);
|
||||
}
|
||||
}
|
||||
|
||||
void DynamicZone::AddCharacter(uint32_t character_id)
|
||||
{
|
||||
database.AddClientToInstance(m_instance_id, character_id);
|
||||
SendInstanceCharacterChange(character_id, false); // stops client kick timer
|
||||
}
|
||||
|
||||
void DynamicZone::RemoveCharacter(uint32_t character_id)
|
||||
{
|
||||
database.RemoveClientFromInstance(m_instance_id, character_id);
|
||||
SendInstanceCharacterChange(character_id, true); // start client kick timer
|
||||
}
|
||||
|
||||
void DynamicZone::RemoveAllCharacters(bool enable_removal_timers)
|
||||
{
|
||||
if (GetInstanceID() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (enable_removal_timers)
|
||||
{
|
||||
// just remove all clients in bulk instead of only characters assigned to the instance
|
||||
if (IsCurrentZoneDzInstance())
|
||||
{
|
||||
for (const auto& client_iter : entity_list.GetClientList())
|
||||
{
|
||||
if (client_iter.second)
|
||||
{
|
||||
client_iter.second->SetDzRemovalTimer(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (GetInstanceID() != 0)
|
||||
{
|
||||
uint32_t packsize = sizeof(ServerDzCharacter_Struct);
|
||||
auto pack = std::make_unique<ServerPacket>(ServerOP_DzRemoveAllCharacters, packsize);
|
||||
auto packbuf = reinterpret_cast<ServerDzCharacter_Struct*>(pack->pBuffer);
|
||||
packbuf->zone_id = GetZoneID();
|
||||
packbuf->instance_id = GetInstanceID();
|
||||
packbuf->remove = true;
|
||||
packbuf->character_id = 0;
|
||||
worldserver.SendPacket(pack.get());
|
||||
}
|
||||
}
|
||||
|
||||
database.RemoveClientsFromInstance(GetInstanceID());
|
||||
}
|
||||
|
||||
void DynamicZone::SaveInstanceMembersToDatabase(const std::vector<uint32_t>& character_ids)
|
||||
{
|
||||
LogDynamicZonesDetail("Saving [{}] instance members to database", character_ids.size());
|
||||
|
||||
std::string insert_values;
|
||||
for (const auto& character_id : character_ids)
|
||||
{
|
||||
fmt::format_to(std::back_inserter(insert_values), "({}, {}),", m_instance_id, character_id);
|
||||
}
|
||||
|
||||
if (!insert_values.empty())
|
||||
{
|
||||
insert_values.pop_back(); // trailing comma
|
||||
|
||||
std::string query = fmt::format(SQL(
|
||||
REPLACE INTO instance_list_player (id, charid) VALUES {};
|
||||
), insert_values);
|
||||
|
||||
database.QueryDatabase(query);
|
||||
}
|
||||
}
|
||||
|
||||
void DynamicZone::SendInstanceCharacterChange(uint32_t character_id, bool removed)
|
||||
void DynamicZone::SendInstanceAddRemoveCharacter(uint32_t character_id, bool removed)
|
||||
{
|
||||
// if removing, sets removal timer on client inside the instance
|
||||
if (IsCurrentZoneDzInstance())
|
||||
@@ -436,97 +118,16 @@ void DynamicZone::SendInstanceCharacterChange(uint32_t character_id, bool remove
|
||||
}
|
||||
else if (GetInstanceID() != 0)
|
||||
{
|
||||
uint32_t packsize = sizeof(ServerDzCharacter_Struct);
|
||||
auto pack = std::make_unique<ServerPacket>(ServerOP_DzCharacterChange, packsize);
|
||||
auto packbuf = reinterpret_cast<ServerDzCharacter_Struct*>(pack->pBuffer);
|
||||
packbuf->zone_id = GetZoneID();
|
||||
packbuf->instance_id = GetInstanceID();
|
||||
packbuf->remove = removed;
|
||||
packbuf->character_id = character_id;
|
||||
auto pack = CreateServerAddRemoveCharacterPacket(character_id, removed);
|
||||
worldserver.SendPacket(pack.get());
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
m_has_zonein = true;
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
bool DynamicZone::IsInstanceID(uint32_t instance_id) const
|
||||
{
|
||||
return (GetInstanceID() != 0 && GetInstanceID() == instance_id);
|
||||
}
|
||||
|
||||
bool DynamicZone::IsSameDz(uint32_t zone_id, uint32_t instance_id) const
|
||||
{
|
||||
return zone_id == m_zone_id && instance_id == m_instance_id;
|
||||
}
|
||||
|
||||
uint32_t DynamicZone::GetSecondsRemaining() const
|
||||
{
|
||||
auto now = std::chrono::system_clock::now();
|
||||
if (m_expire_time > now)
|
||||
{
|
||||
auto remaining = m_expire_time - now;
|
||||
return static_cast<uint32_t>(std::chrono::duration_cast<std::chrono::seconds>(remaining).count());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DynamicZone::SetSecondsRemaining(uint32_t seconds_remaining)
|
||||
{
|
||||
// async
|
||||
@@ -553,19 +154,9 @@ void DynamicZone::SetUpdatedDuration(uint32_t new_duration)
|
||||
}
|
||||
}
|
||||
|
||||
void DynamicZone::SendWorldSetLocation(uint16_t server_opcode, const DynamicZoneLocation& location)
|
||||
void DynamicZone::SendGlobalLocationChange(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;
|
||||
auto pack = CreateServerDzLocationPacket(server_opcode, location);
|
||||
worldserver.SendPacket(pack.get());
|
||||
}
|
||||
|
||||
@@ -573,7 +164,7 @@ void DynamicZone::HandleWorldMessage(ServerPacket* pack)
|
||||
{
|
||||
switch (pack->opcode)
|
||||
{
|
||||
case ServerOP_DzCharacterChange:
|
||||
case ServerOP_DzAddRemoveCharacter:
|
||||
{
|
||||
auto buf = reinterpret_cast<ServerDzCharacter_Struct*>(pack->pBuffer);
|
||||
Client* client = entity_list.GetClientByCharID(buf->character_id);
|
||||
@@ -588,13 +179,7 @@ void DynamicZone::HandleWorldMessage(ServerPacket* pack)
|
||||
auto buf = reinterpret_cast<ServerDzCharacter_Struct*>(pack->pBuffer);
|
||||
if (buf->remove)
|
||||
{
|
||||
for (const auto& client_list_iter : entity_list.GetClientList())
|
||||
{
|
||||
if (client_list_iter.second)
|
||||
{
|
||||
client_list_iter.second->SetDzRemovalTimer(true);
|
||||
}
|
||||
}
|
||||
DynamicZone::StartAllClientRemovalTimers();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -636,3 +221,12 @@ void DynamicZone::HandleWorldMessage(ServerPacket* pack)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DynamicZone::ProcessCompassChange(const DynamicZoneLocation& location)
|
||||
{
|
||||
DynamicZoneBase::ProcessCompassChange(location);
|
||||
if (m_on_compass_change)
|
||||
{
|
||||
m_on_compass_change();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user