diff --git a/zone/expedition.cpp b/zone/expedition.cpp index f3f22fd06..1b134bd28 100644 --- a/zone/expedition.cpp +++ b/zone/expedition.cpp @@ -1642,6 +1642,26 @@ void Expedition::AddLockoutByCharacterName( } } +bool Expedition::HasLockoutByCharacterID( + uint32_t character_id, const std::string& expedition_name, const std::string& event_name) +{ + auto lockouts = Expedition::GetExpeditionLockoutsByCharacterID(character_id); + return std::any_of(lockouts.begin(), lockouts.end(), [&](const ExpeditionLockoutTimer& lockout) { + return lockout.IsSameLockout(expedition_name, event_name); + }); +} + +bool Expedition::HasLockoutByCharacterName( + const std::string& character_name, const std::string& expedition_name, const std::string& event_name) +{ + if (!character_name.empty()) + { + uint32_t character_id = database.GetCharacterID(character_name.c_str()); + return HasLockoutByCharacterID(character_id, expedition_name, event_name); + } + return false; +} + void Expedition::RemoveLockoutsByCharacterID( uint32_t character_id, const std::string& expedition_name, const std::string& event_name) { @@ -2069,6 +2089,10 @@ std::string Expedition::GetLootEventBySpawnID(uint32_t spawn_id) std::vector Expedition::GetExpeditionLockoutsByCharacterID(uint32_t character_id) { std::vector lockouts; + if (character_id == 0) + { + return lockouts; + } auto client = entity_list.GetClientByCharID(character_id); if (client) diff --git a/zone/expedition.h b/zone/expedition.h index 490fd1f44..16e62a5d1 100644 --- a/zone/expedition.h +++ b/zone/expedition.h @@ -84,6 +84,10 @@ public: const std::string& event_name, uint32_t seconds, const std::string& uuid = {}); static void AddLockoutByCharacterName(const std::string& character_name, const std::string& expedition_name, const std::string& event_name, uint32_t seconds, const std::string& uuid = {}); + static bool HasLockoutByCharacterID(uint32_t character_id, + const std::string& expedition_name, const std::string& event_name); + static bool HasLockoutByCharacterName(const std::string& character_name, + const std::string& expedition_name, const std::string& event_name); static void RemoveLockoutsByCharacterID(uint32_t character_id, const std::string& expedition_name = {}, const std::string& event_name = {}); static void RemoveLockoutsByCharacterName(const std::string& character_name, diff --git a/zone/groups.cpp b/zone/groups.cpp index 60a58b99c..4b8e25d09 100644 --- a/zone/groups.cpp +++ b/zone/groups.cpp @@ -18,6 +18,7 @@ #include "../common/global_define.h" #include "../common/eqemu_logsys.h" +#include "expedition.h" #include "masterentity.h" #include "npc_ai.h" #include "../common/packet_functions.h" @@ -2503,3 +2504,24 @@ void Group::QueueClients(Mob *sender, const EQApplicationPacket *app, bool ack_r } } } + +bool Group::DoesAnyMemberHaveExpeditionLockout( + const std::string& expedition_name, const std::string& event_name, int max_check_count) +{ + if (max_check_count <= 0) + { + max_check_count = MAX_GROUP_MEMBERS; + } + + for (int i = 0; i < MAX_GROUP_MEMBERS && i < max_check_count; ++i) + { + if (membername[i][0]) + { + if (Expedition::HasLockoutByCharacterName(membername[i], expedition_name, event_name)) + { + return true; + } + } + } + return false; +} diff --git a/zone/groups.h b/zone/groups.h index 0d39409e0..57dfdbfb6 100644 --- a/zone/groups.h +++ b/zone/groups.h @@ -153,6 +153,8 @@ public: inline int GetMentorPercent() { return mentor_percent; } inline Client *GetMentoree() { return mentoree; } + bool DoesAnyMemberHaveExpeditionLockout(const std::string& expedition_name, const std::string& event_name, int max_check_count = 0); + Mob* members[MAX_GROUP_MEMBERS]; char membername[MAX_GROUP_MEMBERS][64]; uint8 MemberRoles[MAX_GROUP_MEMBERS]; diff --git a/zone/lua_group.cpp b/zone/lua_group.cpp index f297d72f1..2cac41418 100644 --- a/zone/lua_group.cpp +++ b/zone/lua_group.cpp @@ -107,6 +107,18 @@ Lua_Mob Lua_Group::GetMember(int index) { return self->members[index]; } +bool Lua_Group::DoesAnyMemberHaveExpeditionLockout(std::string expedition_name, std::string event_name) +{ + Lua_Safe_Call_Bool(); + return self->DoesAnyMemberHaveExpeditionLockout(expedition_name, event_name); +} + +bool Lua_Group::DoesAnyMemberHaveExpeditionLockout(std::string expedition_name, std::string event_name, int max_check_count) +{ + Lua_Safe_Call_Bool(); + return self->DoesAnyMemberHaveExpeditionLockout(expedition_name, event_name, max_check_count); +} + luabind::scope lua_register_group() { return luabind::class_("Group") .def(luabind::constructor<>()) @@ -129,7 +141,9 @@ luabind::scope lua_register_group() { .def("GetLowestLevel", (int(Lua_Group::*)(void))&Lua_Group::GetLowestLevel) .def("TeleportGroup", (void(Lua_Group::*)(Lua_Mob,uint32,uint32,float,float,float,float))&Lua_Group::TeleportGroup) .def("GetID", (int(Lua_Group::*)(void))&Lua_Group::GetID) - .def("GetMember", (Lua_Mob(Lua_Group::*)(int))&Lua_Group::GetMember); + .def("GetMember", (Lua_Mob(Lua_Group::*)(int))&Lua_Group::GetMember) + .def("DoesAnyMemberHaveExpeditionLockout", (bool(Lua_Group::*)(std::string, std::string))&Lua_Group::DoesAnyMemberHaveExpeditionLockout) + .def("DoesAnyMemberHaveExpeditionLockout", (bool(Lua_Group::*)(std::string, std::string, int))&Lua_Group::DoesAnyMemberHaveExpeditionLockout); } #endif diff --git a/zone/lua_group.h b/zone/lua_group.h index e1aa2a11d..46bc48f50 100644 --- a/zone/lua_group.h +++ b/zone/lua_group.h @@ -44,6 +44,8 @@ public: void TeleportGroup(Lua_Mob sender, uint32 zone_id, uint32 instance_id, float x, float y, float z, float h); int GetID(); Lua_Mob GetMember(int index); + bool DoesAnyMemberHaveExpeditionLockout(std::string expedition_name, std::string event_name); + bool DoesAnyMemberHaveExpeditionLockout(std::string expedition_name, std::string event_name, int max_check_count); }; #endif diff --git a/zone/lua_raid.cpp b/zone/lua_raid.cpp index c181b8bd2..ae01012d5 100644 --- a/zone/lua_raid.cpp +++ b/zone/lua_raid.cpp @@ -132,6 +132,17 @@ int Lua_Raid::GetGroupNumber(int index) { return self->members[index].GroupNumber; } +bool Lua_Raid::DoesAnyMemberHaveExpeditionLockout(std::string expedition_name, std::string event_name) +{ + Lua_Safe_Call_Bool(); + return self->DoesAnyMemberHaveExpeditionLockout(expedition_name, event_name); +} + +bool Lua_Raid::DoesAnyMemberHaveExpeditionLockout(std::string expedition_name, std::string event_name, int max_check_count) +{ + Lua_Safe_Call_Bool(); + return self->DoesAnyMemberHaveExpeditionLockout(expedition_name, event_name, max_check_count); +} luabind::scope lua_register_raid() { return luabind::class_("Raid") @@ -158,7 +169,9 @@ luabind::scope lua_register_raid() { .def("TeleportRaid", (int(Lua_Raid::*)(Lua_Mob,uint32,uint32,float,float,float,float))&Lua_Raid::TeleportRaid) .def("GetID", (int(Lua_Raid::*)(void))&Lua_Raid::GetID) .def("GetMember", (Lua_Client(Lua_Raid::*)(int))&Lua_Raid::GetMember) - .def("GetGroupNumber", (int(Lua_Raid::*)(int))&Lua_Raid::GetGroupNumber); + .def("GetGroupNumber", (int(Lua_Raid::*)(int))&Lua_Raid::GetGroupNumber) + .def("DoesAnyMemberHaveExpeditionLockout", (bool(Lua_Raid::*)(std::string, std::string))&Lua_Raid::DoesAnyMemberHaveExpeditionLockout) + .def("DoesAnyMemberHaveExpeditionLockout", (bool(Lua_Raid::*)(std::string, std::string, int))&Lua_Raid::DoesAnyMemberHaveExpeditionLockout); } #endif diff --git a/zone/lua_raid.h b/zone/lua_raid.h index bc10a729c..9eb100f59 100644 --- a/zone/lua_raid.h +++ b/zone/lua_raid.h @@ -48,6 +48,8 @@ public: int GetID(); Lua_Client GetMember(int index); int GetGroupNumber(int index); + bool DoesAnyMemberHaveExpeditionLockout(std::string expedition_name, std::string event_name); + bool DoesAnyMemberHaveExpeditionLockout(std::string expedition_name, std::string event_name, int max_check_count); }; #endif diff --git a/zone/raids.cpp b/zone/raids.cpp index 386eb70ac..55e6d9e55 100644 --- a/zone/raids.cpp +++ b/zone/raids.cpp @@ -20,6 +20,7 @@ #include "client.h" #include "entity.h" +#include "expedition.h" #include "groups.h" #include "mob.h" #include "raids.h" @@ -1862,3 +1863,29 @@ std::vector Raid::GetMembers() const } return raid_members; } + +bool Raid::DoesAnyMemberHaveExpeditionLockout( + const std::string& expedition_name, const std::string& event_name, int max_check_count) +{ + auto raid_members = GetMembers(); + + if (max_check_count > 0) + { + // priority is leader, group number, then ungrouped members + std::sort(raid_members.begin(), raid_members.end(), + [&](const RaidMember& lhs, const RaidMember& rhs) { + if (lhs.IsRaidLeader) { + return true; + } else if (rhs.IsRaidLeader) { + return false; + } + return lhs.GroupNumber < rhs.GroupNumber; + }); + + raid_members.resize(max_check_count); + } + + return std::any_of(raid_members.begin(), raid_members.end(), [&](const RaidMember& raid_member) { + return Expedition::HasLockoutByCharacterName(raid_member.membername, expedition_name, event_name); + }); +} diff --git a/zone/raids.h b/zone/raids.h index 1e771e03d..a04d1eb54 100644 --- a/zone/raids.h +++ b/zone/raids.h @@ -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); + bool DoesAnyMemberHaveExpeditionLockout(const std::string& expedition_name, const std::string& event_name, int max_check_count = 0); + std::vector GetMembers() const; RaidMember members[MAX_RAID_MEMBERS];