[Expeditions] Store description and leader name on dz (#1294)

* 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
This commit is contained in:
hg 2021-03-16 01:00:55 -04:00 committed by GitHub
parent b3fbe1b015
commit 0d12bf0b1f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 91 additions and 87 deletions

View File

@ -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
@ -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

View File

@ -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();
}
@ -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;
@ -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;
@ -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)
@ -9919,9 +9918,9 @@ 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();
@ -9929,7 +9928,7 @@ std::vector<DynamicZoneInfo> Client::GetDynamicZones(uint32_t zone_id, int zone_
(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
@ -9955,38 +9954,41 @@ 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());
LogDynamicZonesDetail("Sending DzSwitchListWnd to [{}] for zone [{}] with [{}] dynamic zone(s)",
CharacterID(), zone_id, 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());
// 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)
{
auto zone_id = ZoneID(zone_name.c_str());

View File

@ -31,7 +31,6 @@ class Object;
class Raid;
class Seperator;
class ServerPacket;
struct DynamicZoneInfo;
struct DynamicZoneLocation;
enum WaterRegionType : int;
@ -1356,7 +1355,9 @@ public:
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

View File

@ -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);
}
}

View File

@ -18,7 +18,7 @@
*
*/
#include "dynamiczone.h"
#include "dynamic_zone.h"
#include "client.h"
#include "worldserver.h"
#include "zonedb.h"

View File

@ -18,8 +18,8 @@
*
*/
#ifndef DYNAMICZONE_H
#define DYNAMICZONE_H
#ifndef DYNAMIC_ZONE_H
#define DYNAMIC_ZONE_H
#include <chrono>
#include <cstdint>
@ -73,6 +73,8 @@ public:
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; }
@ -91,6 +93,8 @@ public:
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);
@ -109,7 +113,9 @@ private:
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;
@ -118,15 +124,4 @@ private:
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

View File

@ -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"

View File

@ -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(
@ -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(),
@ -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());
@ -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();

View File

@ -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>
@ -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);
@ -111,7 +111,7 @@ public:
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; }
@ -209,6 +209,7 @@ private:
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); }

View File

@ -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"

View File

@ -33,7 +33,7 @@
#include "spawn2.h"
#include "spawngroup.h"
#include "aa_ability.h"
#include "dynamiczone.h"
#include "dynamic_zone.h"
#include "pathfinder_interface.h"
#include "global_loot_manager.h"