Skip to content

Commit

Permalink
[Expeditions] Store description and leader name on dz (#1294)
Browse files Browse the repository at this point in the history
* Rename dynamic zone source files

* Store description and leader name on dz

Removes the DynamicZoneInfo struct used for switch list window. This
data can be stored on DynamicZone and kept updated by its owning system

* Separate create compass packet method

Cleanup MarkSingleCompassLoc
  • Loading branch information
hgtw committed Mar 16, 2021
1 parent b3fbe1b commit 0d12bf0
Show file tree
Hide file tree
Showing 11 changed files with 92 additions and 88 deletions.
4 changes: 2 additions & 2 deletions zone/CMakeLists.txt
Expand Up @@ -22,7 +22,7 @@ SET(zone_sources
corpse.cpp
data_bucket.cpp
doors.cpp
dynamiczone.cpp
dynamic_zone.cpp
effects.cpp
embparser.cpp
embparser_api.cpp
Expand Down Expand Up @@ -176,7 +176,7 @@ SET(zone_headers
corpse.h
data_bucket.h
doors.h
dynamiczone.h
dynamic_zone.h
embparser.h
embperl.h
embxs.h
Expand Down
94 changes: 48 additions & 46 deletions zone/client.cpp
Expand Up @@ -6161,17 +6161,10 @@ void Client::CheckEmoteHail(Mob *target, const char* message)

void Client::MarkSingleCompassLoc(float in_x, float in_y, float in_z, uint8 count)
{
if (count == 0)
{
m_has_quest_compass = false;
}
else
{
m_has_quest_compass = true;
m_quest_compass.x = in_x;
m_quest_compass.y = in_y;
m_quest_compass.z = in_z;
}
m_has_quest_compass = (count != 0);
m_quest_compass.x = in_x;
m_quest_compass.y = in_y;
m_quest_compass.z = in_z;

SendDzCompassUpdate();
}
Expand Down Expand Up @@ -9862,13 +9855,13 @@ void Client::SendDzCompassUpdate()

for (const auto& client_dz : GetDynamicZones())
{
auto compass = client_dz.dynamic_zone.GetCompassLocation();
if (zone && zone->GetZoneID() == compass.zone_id && zone->GetInstanceID() == 0)
auto compass = client_dz->GetCompassLocation();
if (zone && zone->IsZone(compass.zone_id, 0))
{
DynamicZoneCompassEntry_Struct entry;
entry.dz_zone_id = static_cast<uint16_t>(client_dz.dynamic_zone.GetZoneID());
entry.dz_instance_id = static_cast<uint16_t>(client_dz.dynamic_zone.GetInstanceID());
entry.dz_type = static_cast<uint32_t>(client_dz.dynamic_zone.GetType());
entry.dz_zone_id = client_dz->GetZoneID();
entry.dz_instance_id = client_dz->GetInstanceID();
entry.dz_type = static_cast<uint32_t>(client_dz->GetType());
entry.x = compass.x;
entry.y = compass.y;
entry.z = compass.z;
Expand All @@ -9891,6 +9884,12 @@ void Client::SendDzCompassUpdate()
compass_entries.emplace_back(entry);
}

QueuePacket(CreateCompassPacket(compass_entries).get());
}

std::unique_ptr<EQApplicationPacket> Client::CreateCompassPacket(
const std::vector<DynamicZoneCompassEntry_Struct>& compass_entries)
{
uint32 count = static_cast<uint32_t>(compass_entries.size());
uint32 entries_size = sizeof(DynamicZoneCompassEntry_Struct) * count;
uint32 outsize = sizeof(DynamicZoneCompass_Struct) + entries_size;
Expand All @@ -9899,7 +9898,7 @@ void Client::SendDzCompassUpdate()
outbuf->count = count;
memcpy(outbuf->entries, compass_entries.data(), entries_size);

QueuePacket(outapp.get());
return outapp;
}

void Client::GoToDzSafeReturnOrBind(const DynamicZone& dynamic_zone)
Expand All @@ -9919,17 +9918,17 @@ void Client::GoToDzSafeReturnOrBind(const DynamicZone& dynamic_zone)
}
}

std::vector<DynamicZoneInfo> Client::GetDynamicZones(uint32_t zone_id, int zone_version)
std::vector<DynamicZone*> Client::GetDynamicZones(uint32_t zone_id, int zone_version)
{
std::vector<DynamicZoneInfo> client_dzs;
std::vector<DynamicZone*> client_dzs;

// check client systems for any associated dynamic zones optionally filtered by zone
Expedition* expedition = GetExpedition();
if (expedition &&
(zone_id == 0 || expedition->GetDynamicZone().GetZoneID() == zone_id) &&
(zone_version < 0 || expedition->GetDynamicZone().GetZoneVersion() == zone_version))
{
client_dzs.emplace_back(expedition->GetName(), expedition->GetLeaderName(), expedition->GetDynamicZone());
client_dzs.emplace_back(&expedition->GetDynamicZone());
}

// todo: tasks, missions (shared tasks), and quests with an associated dz to zone_id
Expand All @@ -9955,36 +9954,39 @@ void Client::MovePCDynamicZone(uint32 zone_id, int zone_version, bool msg_if_inv
}
else if (client_dzs.size() == 1)
{
const DynamicZone& dz = client_dzs[0].dynamic_zone;
DynamicZoneLocation zonein = dz.GetZoneInLocation();
ZoneMode zone_mode = dz.HasZoneInLocation() ? ZoneMode::ZoneSolicited : ZoneMode::ZoneToSafeCoords;
MovePC(zone_id, dz.GetInstanceID(), zonein.x, zonein.y, zonein.z, zonein.heading, 0, zone_mode);
auto dz = client_dzs.front();
DynamicZoneLocation zonein = dz->GetZoneInLocation();
ZoneMode zone_mode = dz->HasZoneInLocation() ? ZoneMode::ZoneSolicited : ZoneMode::ZoneToSafeCoords;
MovePC(zone_id, dz->GetInstanceID(), zonein.x, zonein.y, zonein.z, zonein.heading, 0, zone_mode);
}
else
{
LogDynamicZonesDetail(
"Sending DzSwitchListWnd to character [{}] associated with [{}] dynamic zone(s)",
CharacterID(), client_dzs.size());

// more than one dynamic zone to this zone, send out the switchlist window
// note that this will most likely crash clients if they've reloaded the ui
// this occurs on live as well so it may just be a long lasting client bug
uint32 count = static_cast<uint32_t>(client_dzs.size());
uint32 entries_size = sizeof(DynamicZoneChooseZoneEntry_Struct) * count;
uint32 outsize = sizeof(DynamicZoneChooseZone_Struct) + entries_size;
auto outapp = std::make_unique<EQApplicationPacket>(OP_DzChooseZone, outsize);
auto outbuf = reinterpret_cast<DynamicZoneChooseZone_Struct*>(outapp->pBuffer);
outbuf->count = count;
for (int i = 0; i < client_dzs.size(); ++i)
{
outbuf->choices[i].dz_zone_id = client_dzs[i].dynamic_zone.GetZoneID();
outbuf->choices[i].dz_instance_id = client_dzs[i].dynamic_zone.GetInstanceID();
outbuf->choices[i].dz_type = static_cast<uint32_t>(client_dzs[i].dynamic_zone.GetType());
strn0cpy(outbuf->choices[i].description, client_dzs[i].description.c_str(), sizeof(outbuf->choices[i].description));
strn0cpy(outbuf->choices[i].leader_name, client_dzs[i].leader_name.c_str(), sizeof(outbuf->choices[i].leader_name));
}
QueuePacket(outapp.get());
LogDynamicZonesDetail("Sending DzSwitchListWnd to [{}] for zone [{}] with [{}] dynamic zone(s)",
CharacterID(), zone_id, client_dzs.size());

// client has more than one dz for this zone, send out the switchlist window
QueuePacket(CreateDzSwitchListPacket(client_dzs).get());
}
}

std::unique_ptr<EQApplicationPacket> Client::CreateDzSwitchListPacket(
const std::vector<DynamicZone*>& client_dzs)
{
uint32 count = static_cast<uint32_t>(client_dzs.size());
uint32 entries_size = sizeof(DynamicZoneChooseZoneEntry_Struct) * count;
uint32 outsize = sizeof(DynamicZoneChooseZone_Struct) + entries_size;
auto outapp = std::make_unique<EQApplicationPacket>(OP_DzChooseZone, outsize);
auto outbuf = reinterpret_cast<DynamicZoneChooseZone_Struct*>(outapp->pBuffer);
outbuf->count = count;
for (int i = 0; i < client_dzs.size(); ++i)
{
outbuf->choices[i].dz_zone_id = client_dzs[i]->GetZoneID();
outbuf->choices[i].dz_instance_id = client_dzs[i]->GetInstanceID();
outbuf->choices[i].dz_type = static_cast<uint32_t>(client_dzs[i]->GetType());
strn0cpy(outbuf->choices[i].description, client_dzs[i]->GetName().c_str(), sizeof(outbuf->choices[i].description));
strn0cpy(outbuf->choices[i].leader_name, client_dzs[i]->GetLeaderName().c_str(), sizeof(outbuf->choices[i].leader_name));
}
return outapp;
}

void Client::MovePCDynamicZone(const std::string& zone_name, int zone_version, bool msg_if_invalid)
Expand Down
5 changes: 3 additions & 2 deletions zone/client.h
Expand Up @@ -31,7 +31,6 @@ class Object;
class Raid;
class Seperator;
class ServerPacket;
struct DynamicZoneInfo;
struct DynamicZoneLocation;
enum WaterRegionType : int;

Expand Down Expand Up @@ -1356,7 +1355,9 @@ class Client : public Mob
void GoToDzSafeReturnOrBind(const DynamicZone& dynamic_zone);
void MovePCDynamicZone(uint32 zone_id, int zone_version = -1, bool msg_if_invalid = true);
void MovePCDynamicZone(const std::string& zone_name, int zone_version = -1, bool msg_if_invalid = true);
std::vector<DynamicZoneInfo> GetDynamicZones(uint32_t zone_id = 0, int zone_version = -1);
std::vector<DynamicZone*> GetDynamicZones(uint32_t zone_id = 0, int zone_version = -1);
std::unique_ptr<EQApplicationPacket> CreateDzSwitchListPacket(const std::vector<DynamicZone*>& dzs);
std::unique_ptr<EQApplicationPacket> CreateCompassPacket(const std::vector<DynamicZoneCompassEntry_Struct>& entries);

void CalcItemScale();
bool CalcItemScale(uint32 slot_x, uint32 slot_y); // behavior change: 'slot_y' is now [RANGE]_END and not [RANGE]_END + 1
Expand Down
22 changes: 9 additions & 13 deletions zone/client_packet.cpp
Expand Up @@ -5634,30 +5634,26 @@ void Client::Handle_OP_DzAddPlayer(const EQApplicationPacket *app)
void Client::Handle_OP_DzChooseZoneReply(const EQApplicationPacket *app)
{
auto dzmsg = reinterpret_cast<DynamicZoneChooseZoneReply_Struct*>(app->pBuffer);
LogDynamicZones(
"Character [{}] chose DynamicZone [{}]:[{}] type: [{}] with system id: [{}]",
CharacterID(), dzmsg->dz_zone_id, dzmsg->dz_instance_id, dzmsg->dz_type, dzmsg->unknown_id2
);

LogDynamicZones("Character [{}] chose DynamicZone [{}]:[{}] type: [{}] with system id: [{}]",
CharacterID(), dzmsg->dz_zone_id, dzmsg->dz_instance_id, dzmsg->dz_type, dzmsg->unknown_id2);

if (!dzmsg->dz_instance_id || !database.VerifyInstanceAlive(dzmsg->dz_instance_id, CharacterID()))
{
// live just no-ops this without a message
LogDynamicZones(
"Character [{}] chose invalid DynamicZone [{}]:[{}] or is no longer a member",
CharacterID(), dzmsg->dz_zone_id, dzmsg->dz_instance_id
);
LogDynamicZones("Character [{}] chose invalid DynamicZone [{}]:[{}] or is no longer a member",
CharacterID(), dzmsg->dz_zone_id, dzmsg->dz_instance_id);
return;
}

auto client_dzs = GetDynamicZones();
auto it = std::find_if(client_dzs.begin(), client_dzs.end(), [&](const DynamicZoneInfo dz_info) {
return dz_info.dynamic_zone.IsSameDz(dzmsg->dz_zone_id, dzmsg->dz_instance_id);
});
auto it = std::find_if(client_dzs.begin(), client_dzs.end(), [&](const DynamicZone* dz) {
return dz->IsSameDz(dzmsg->dz_zone_id, dzmsg->dz_instance_id); });

if (it != client_dzs.end())
{
DynamicZoneLocation loc = it->dynamic_zone.GetZoneInLocation();
ZoneMode zone_mode = it->dynamic_zone.HasZoneInLocation() ? ZoneMode::ZoneSolicited : ZoneMode::ZoneToSafeCoords;
DynamicZoneLocation loc = (*it)->GetZoneInLocation();
ZoneMode zone_mode = (*it)->HasZoneInLocation() ? ZoneMode::ZoneSolicited : ZoneMode::ZoneToSafeCoords;
MovePC(dzmsg->dz_zone_id, dzmsg->dz_instance_id, loc.x, loc.y, loc.z, loc.heading, 0, zone_mode);
}
}
Expand Down
2 changes: 1 addition & 1 deletion zone/dynamiczone.cpp → zone/dynamic_zone.cpp
Expand Up @@ -18,7 +18,7 @@
*
*/

#include "dynamiczone.h"
#include "dynamic_zone.h"
#include "client.h"
#include "worldserver.h"
#include "zonedb.h"
Expand Down
23 changes: 9 additions & 14 deletions zone/dynamiczone.h → zone/dynamic_zone.h
Expand Up @@ -18,8 +18,8 @@
*
*/

#ifndef DYNAMICZONE_H
#define DYNAMICZONE_H
#ifndef DYNAMIC_ZONE_H
#define DYNAMIC_ZONE_H

#include <chrono>
#include <cstdint>
Expand Down Expand Up @@ -73,6 +73,8 @@ class DynamicZone
uint16_t GetZoneID() const { return static_cast<uint16_t>(m_zone_id); }
uint32_t GetZoneIndex() const { return (m_instance_id << 16) | (m_zone_id & 0xffff); }
uint32_t GetZoneVersion() const { return m_version; }
const std::string& GetLeaderName() const { return m_leader_name; }
const std::string& GetName() const { return m_name; }
DynamicZoneType GetType() const { return m_type; }
DynamicZoneLocation GetCompassLocation() const { return m_compass; }
DynamicZoneLocation GetSafeReturnLocation() const { return m_safereturn; }
Expand All @@ -91,6 +93,8 @@ class DynamicZone
void SaveInstanceMembersToDatabase(const std::vector<uint32_t>& character_ids);
void SendInstanceCharacterChange(uint32_t character_id, bool removed);
void SetCompass(const DynamicZoneLocation& location, bool update_db = false);
void SetLeaderName(const std::string& leader_name) { m_leader_name = leader_name; }
void SetName(const std::string& name) { m_name = name; }
void SetSafeReturn(const DynamicZoneLocation& location, bool update_db = false);
void SetZoneInLocation(const DynamicZoneLocation& location, bool update_db = false);
void SetUpdatedDuration(uint32_t seconds);
Expand All @@ -109,7 +113,9 @@ class DynamicZone
uint32_t m_version = 0;
bool m_never_expires = false;
bool m_has_zonein = false;
DynamicZoneType m_type = DynamicZoneType::None;
std::string m_name;
std::string m_leader_name;
DynamicZoneType m_type{ DynamicZoneType::None };
DynamicZoneLocation m_compass;
DynamicZoneLocation m_safereturn;
DynamicZoneLocation m_zonein;
Expand All @@ -118,15 +124,4 @@ class DynamicZone
std::chrono::time_point<std::chrono::system_clock> m_expire_time;
};

struct DynamicZoneInfo
{
std::string description; // from owning system
std::string leader_name;
DynamicZone dynamic_zone;

DynamicZoneInfo() = default;
DynamicZoneInfo(std::string desc, std::string leader, const DynamicZone& dz)
: description(std::move(desc)), leader_name(std::move(leader)), dynamic_zone(dz) {}
};

#endif
2 changes: 1 addition & 1 deletion zone/entity.cpp
Expand Up @@ -33,7 +33,7 @@
#include "../common/guilds.h"

#include "entity.h"
#include "dynamiczone.h"
#include "dynamic_zone.h"
#include "guild_mgr.h"
#include "petitions.h"
#include "quest_parser_collection.h"
Expand Down
17 changes: 13 additions & 4 deletions zone/expedition.cpp
Expand Up @@ -50,17 +50,25 @@ const int32_t Expedition::REPLAY_TIMER_ID = -1;
const int32_t Expedition::EVENT_TIMER_ID = 1;

Expedition::Expedition(
uint32_t id, const std::string& uuid, const DynamicZone& dynamic_zone, const std::string& expedition_name,
uint32_t id, const std::string& uuid, DynamicZone&& dz, const std::string& expedition_name,
const ExpeditionMember& leader, uint32_t min_players, uint32_t max_players
) :
m_id(id),
m_uuid(uuid),
m_dynamiczone(dynamic_zone),
m_expedition_name(expedition_name),
m_leader(leader),
m_min_players(min_players),
m_max_players(max_players)
{
SetDynamicZone(std::move(dz));
}

void Expedition::SetDynamicZone(DynamicZone&& dz)
{
dz.SetName(GetName());
dz.SetLeaderName(GetLeaderName());

m_dynamiczone = std::move(dz);
}

Expedition* Expedition::TryCreate(
Expand Down Expand Up @@ -105,7 +113,7 @@ Expedition* Expedition::TryCreate(
auto expedition = std::make_unique<Expedition>(
expedition_id,
expedition_uuid,
dynamiczone,
std::move(dynamiczone),
request.GetExpeditionName(),
ExpeditionMember{ request.GetLeaderID(), request.GetLeaderName() },
request.GetMinPlayers(),
Expand Down Expand Up @@ -219,7 +227,7 @@ void Expedition::CacheExpeditions(MySQLRequestResult& results)
auto dz_iter = dynamic_zones.find(expedition->GetDynamicZoneID());
if (dz_iter != dynamic_zones.end())
{
expedition->m_dynamiczone = dz_iter->second;
expedition->SetDynamicZone(std::move(dz_iter->second));
}

auto lockout_iter = expedition_lockouts.find(expedition->GetID());
Expand Down Expand Up @@ -1137,6 +1145,7 @@ void Expedition::ProcessLeaderChanged(uint32_t new_leader_id)
LogExpeditionsModerate("Replaced [{}] leader [{}] with [{}]", m_id, m_leader.name, new_leader.name);

m_leader = new_leader;
m_dynamiczone.SetLeaderName(m_leader.name);

// update each client's expedition window in this zone
auto outapp_leader = CreateLeaderNamePacket();
Expand Down
7 changes: 4 additions & 3 deletions zone/expedition.h
Expand Up @@ -21,7 +21,7 @@
#ifndef EXPEDITION_H
#define EXPEDITION_H

#include "dynamiczone.h"
#include "dynamic_zone.h"
#include "expedition_lockout_timer.h"
#include "../common/eq_constants.h"
#include <cstdint>
Expand Down Expand Up @@ -76,7 +76,7 @@ class Expedition
{
public:
Expedition() = delete;
Expedition(uint32_t id, const std::string& uuid, const DynamicZone& dz, const std::string& expedition_name,
Expedition(uint32_t id, const std::string& uuid, DynamicZone&& dz, const std::string& expedition_name,
const ExpeditionMember& leader, uint32_t min_players, uint32_t max_players);

static Expedition* TryCreate(Client* requester, DynamicZone& dynamiczone, ExpeditionRequest& request);
Expand Down Expand Up @@ -111,7 +111,7 @@ class Expedition
uint32_t GetMinPlayers() const { return m_min_players; }
uint32_t GetMaxPlayers() const { return m_max_players; }
uint32_t GetMemberCount() const { return static_cast<uint32_t>(m_members.size()); }
const DynamicZone& GetDynamicZone() const { return m_dynamiczone; }
DynamicZone& GetDynamicZone() { return m_dynamiczone; }
const std::string& GetName() const { return m_expedition_name; }
const std::string& GetLeaderName() const { return m_leader.name; }
const std::string& GetUUID() const { return m_uuid; }
Expand Down Expand Up @@ -209,6 +209,7 @@ class Expedition
const std::string& add_char_name, uint32_t add_char_id);
void SendWorldSetSecondsRemaining(uint32_t seconds_remaining);
void SendWorldSettingChanged(uint16_t server_opcode, bool setting_value);
void SetDynamicZone(DynamicZone&& dz);
void TryAddClient(Client* add_client, const std::string& inviter_name,
const std::string& swap_remove_name, Client* leader_client = nullptr);
void UpdateDzDuration(uint32_t new_duration) { m_dynamiczone.SetUpdatedDuration(new_duration); }
Expand Down
2 changes: 1 addition & 1 deletion zone/lua_client.cpp
Expand Up @@ -4,7 +4,7 @@
#include <luabind/luabind.hpp>

#include "client.h"
#include "dynamiczone.h"
#include "dynamic_zone.h"
#include "expedition_lockout_timer.h"
#include "expedition_request.h"
#include "lua_client.h"
Expand Down

0 comments on commit 0d12bf0

Please sign in to comment.