mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-12 01:11:29 +00:00
Truncate expedition members to max on creation
This implements the new behavior from live's September 16, 2020 (test server's September 8, 2020) patch Expeditions can be created even when the client's group or raid exceeds the expedition's max player requirement. Members are added until the max player count is reached and the rest are ignored. Raid members are added ordered by their raid group number with ungrouped members having the lowest priority Rename expedition request method ValidateMembers to CanMembersJoin Change some expedition messages to System color (live changes)
This commit is contained in:
parent
a597753bee
commit
1d24432e47
@ -40,6 +40,8 @@ const char* const EXPEDITION_OTHER_BELONGS = "{} attempted to create an expedi
|
||||
const char* const DZADD_INVITE_WARNING = "Warning! You will be given replay timers for the following events if you enter %s:";
|
||||
const char* const DZADD_INVITE_WARNING_TIMER = "%s - %sD:%sH:%sM";
|
||||
const char* const KICKPLAYERS_EVERYONE = "Everyone";
|
||||
// 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 {}.";
|
||||
|
||||
const int32_t Expedition::REPLAY_TIMER_ID = -1;
|
||||
const int32_t Expedition::EVENT_TIMER_ID = 1;
|
||||
@ -130,10 +132,14 @@ Expedition* Expedition::TryCreate(
|
||||
|
||||
inserted.first->second->SendUpdatesToZoneMembers();
|
||||
inserted.first->second->SendWorldExpeditionUpdate(ServerOP_ExpeditionCreate); // cache in other zones
|
||||
inserted.first->second->SendLeaderMessage(request.GetLeaderClient(),
|
||||
Chat::System, EXPEDITION_AVAILABLE, { request.GetExpeditionName() });
|
||||
|
||||
inserted.first->second->SendLeaderMessage(
|
||||
request.GetLeaderClient(), Chat::Yellow, EXPEDITION_AVAILABLE, { request.GetExpeditionName() }
|
||||
);
|
||||
if (!request.GetNotAllAddedMessage().empty())
|
||||
{
|
||||
Client::SendCrossZoneMessage(request.GetLeaderClient(), request.GetLeaderName(),
|
||||
Chat::System, request.GetNotAllAddedMessage());
|
||||
}
|
||||
|
||||
return inserted.first->second.get();
|
||||
}
|
||||
@ -889,7 +895,7 @@ bool Expedition::ConfirmLeaderCommand(Client* requester)
|
||||
|
||||
if (leader.char_id != requester->CharacterID())
|
||||
{
|
||||
requester->MessageString(Chat::Red, EXPEDITION_NOT_LEADER, leader.name.c_str());
|
||||
requester->MessageString(Chat::System, EXPEDITION_NOT_LEADER, leader.name.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -38,6 +38,7 @@ class ServerPacket;
|
||||
|
||||
extern const char* const DZ_YOU_NOT_ASSIGNED;
|
||||
extern const char* const EXPEDITION_OTHER_BELONGS;
|
||||
extern const char* const CREATE_NOT_ALL_ADDED;
|
||||
|
||||
enum class ExpeditionMemberStatus : uint8_t
|
||||
{
|
||||
|
||||
@ -30,6 +30,8 @@
|
||||
|
||||
extern WorldServer worldserver;
|
||||
|
||||
constexpr char SystemName[] = "expedition";
|
||||
|
||||
struct ExpeditionRequestConflict
|
||||
{
|
||||
std::string character_name;
|
||||
@ -75,7 +77,7 @@ bool ExpeditionRequest::Validate(Client* requester)
|
||||
m_leader = m_requester;
|
||||
m_leader_id = m_requester->CharacterID();
|
||||
m_leader_name = m_requester->GetName();
|
||||
requirements_met = ValidateMembers({m_leader_name});
|
||||
requirements_met = CanMembersJoin({m_leader_name});
|
||||
}
|
||||
|
||||
auto elapsed = benchmark.elapsed();
|
||||
@ -90,16 +92,34 @@ bool ExpeditionRequest::CanRaidRequest(Raid* raid)
|
||||
m_leader_name = raid->leadername;
|
||||
m_leader_id = m_leader ? m_leader->CharacterID() : database.GetCharacterID(raid->leadername);
|
||||
|
||||
std::vector<std::string> member_names;
|
||||
for (int i = 0; i < MAX_RAID_MEMBERS; ++i)
|
||||
// live (as of September 16, 2020) supports creation even if raid count exceeds
|
||||
// expedition max. members are added up to the max ordered by group number.
|
||||
auto raid_members = raid->GetMembers();
|
||||
|
||||
if (raid_members.size() > m_max_players)
|
||||
{
|
||||
if (raid->members[i].membername[0])
|
||||
{
|
||||
member_names.emplace_back(raid->members[i].membername);
|
||||
}
|
||||
// stable_sort not needed, order within a raid group may not be what is displayed
|
||||
std::sort(raid_members.begin(), raid_members.end(),
|
||||
[&](const RaidMember& lhs, const RaidMember& rhs) {
|
||||
if (m_leader_name == lhs.membername) { // leader always added first
|
||||
return true;
|
||||
} else if (m_leader_name == rhs.membername) {
|
||||
return false;
|
||||
}
|
||||
return lhs.GroupNumber < rhs.GroupNumber;
|
||||
});
|
||||
|
||||
m_not_all_added_msg = fmt::format(CREATE_NOT_ALL_ADDED, "raid", SystemName,
|
||||
SystemName, m_max_players, "raid", raid_members.size());
|
||||
}
|
||||
|
||||
return ValidateMembers(member_names);
|
||||
std::vector<std::string> member_names;
|
||||
for (int i = 0; i < raid_members.size() && member_names.size() < m_max_players; ++i)
|
||||
{
|
||||
member_names.emplace_back(raid_members[i].membername);
|
||||
}
|
||||
|
||||
return CanMembersJoin(member_names);
|
||||
}
|
||||
|
||||
bool ExpeditionRequest::CanGroupRequest(Group* group)
|
||||
@ -109,20 +129,31 @@ bool ExpeditionRequest::CanGroupRequest(Group* group)
|
||||
{
|
||||
m_leader = group->GetLeader()->CastToClient();
|
||||
}
|
||||
|
||||
// Group::GetLeaderName() is broken if group formed across zones, ask database instead
|
||||
m_leader_name = m_leader ? m_leader->GetName() : GetGroupLeaderName(group->GetID()); // group->GetLeaderName();
|
||||
m_leader_id = m_leader ? m_leader->CharacterID() : database.GetCharacterID(m_leader_name.c_str());
|
||||
|
||||
std::vector<std::string> member_names;
|
||||
member_names.emplace_back(m_leader_name); // leader always added first
|
||||
|
||||
for (int i = 0; i < MAX_GROUP_MEMBERS; ++i)
|
||||
{
|
||||
if (group->membername[i][0])
|
||||
if (group->membername[i][0] && m_leader_name != group->membername[i])
|
||||
{
|
||||
member_names.emplace_back(group->membername[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return ValidateMembers(member_names);
|
||||
if (member_names.size() > m_max_players)
|
||||
{
|
||||
m_not_all_added_msg = fmt::format(CREATE_NOT_ALL_ADDED, "group", SystemName,
|
||||
SystemName, m_max_players, "group", member_names.size());
|
||||
|
||||
member_names.resize(m_max_players);
|
||||
}
|
||||
|
||||
return CanMembersJoin(member_names);
|
||||
}
|
||||
|
||||
std::string ExpeditionRequest::GetGroupLeaderName(uint32_t group_id)
|
||||
@ -132,7 +163,7 @@ std::string ExpeditionRequest::GetGroupLeaderName(uint32_t group_id)
|
||||
return std::string(leader_name_buffer);
|
||||
}
|
||||
|
||||
bool ExpeditionRequest::ValidateMembers(const std::vector<std::string>& member_names)
|
||||
bool ExpeditionRequest::CanMembersJoin(const std::vector<std::string>& member_names)
|
||||
{
|
||||
if (member_names.empty())
|
||||
{
|
||||
@ -354,7 +385,7 @@ bool ExpeditionRequest::IsPlayerCountValidated(uint32_t member_count)
|
||||
{
|
||||
requirements_met = false;
|
||||
|
||||
SendLeaderMessage(Chat::Red, REQUIRED_PLAYER_COUNT, {
|
||||
SendLeaderMessage(Chat::System, REQUIRED_PLAYER_COUNT, {
|
||||
fmt::format_int(member_count).str(),
|
||||
fmt::format_int(m_min_players).str(),
|
||||
fmt::format_int(m_max_players).str()
|
||||
|
||||
@ -47,13 +47,14 @@ public:
|
||||
Client* GetLeaderClient() const { return m_leader; }
|
||||
uint32_t GetLeaderID() const { return m_leader_id; }
|
||||
const std::string& GetLeaderName() const { return m_leader_name; }
|
||||
const std::string& GetNotAllAddedMessage() const { return m_not_all_added_msg; }
|
||||
uint32_t GetMinPlayers() const { return m_min_players; }
|
||||
uint32_t GetMaxPlayers() const { return m_max_players; }
|
||||
std::vector<ExpeditionMember> GetMembers() const { return m_members; }
|
||||
std::unordered_map<std::string, ExpeditionLockoutTimer> GetLockouts() const { return m_lockouts; }
|
||||
|
||||
private:
|
||||
bool ValidateMembers(const std::vector<std::string>& member_names);
|
||||
bool CanMembersJoin(const std::vector<std::string>& member_names);
|
||||
bool CanRaidRequest(Raid* raid);
|
||||
bool CanGroupRequest(Group* group);
|
||||
bool CheckMembersForConflicts(const std::vector<std::string>& member_names);
|
||||
@ -74,6 +75,7 @@ private:
|
||||
bool m_disable_messages = false;
|
||||
std::string m_expedition_name;
|
||||
std::string m_leader_name;
|
||||
std::string m_not_all_added_msg;
|
||||
std::vector<ExpeditionMember> m_members;
|
||||
std::unordered_map<std::string, ExpeditionLockoutTimer> m_lockouts;
|
||||
};
|
||||
|
||||
@ -1849,3 +1849,16 @@ void Raid::QueueClients(Mob *sender, const EQApplicationPacket *app, bool ack_re
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<RaidMember> Raid::GetMembers() const
|
||||
{
|
||||
std::vector<RaidMember> raid_members;
|
||||
for (int i = 0; i < MAX_RAID_MEMBERS; ++i)
|
||||
{
|
||||
if (members[i].membername[0])
|
||||
{
|
||||
raid_members.emplace_back(members[i]);
|
||||
}
|
||||
}
|
||||
return raid_members;
|
||||
}
|
||||
|
||||
@ -239,6 +239,8 @@ public:
|
||||
|
||||
void QueueClients(Mob *sender, const EQApplicationPacket *app, bool ack_required = true, bool ignore_sender = true, float distance = 0, bool group_only = true);
|
||||
|
||||
std::vector<RaidMember> GetMembers() const;
|
||||
|
||||
RaidMember members[MAX_RAID_MEMBERS];
|
||||
char leadername[64];
|
||||
protected:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user