mirror of
https://github.com/brighton-chi/mod-aoe-loot.git
synced 2026-01-13 00:58:34 +00:00
preserve configured loot method after server restart
This commit is contained in:
374
src/aoe_loot.cpp
374
src/aoe_loot.cpp
@@ -26,11 +26,13 @@ using namespace WorldPackets;
|
||||
|
||||
// Thread-safe player AoE loot preference storage (renamed)
|
||||
std::map<uint64, bool> playerAoeLootPreferences;
|
||||
std::mutex aoeLootPreferencesMutex;
|
||||
std::mutex AoeLootPreferencesMutex;
|
||||
|
||||
// Track groups that have had default loot settings applied by us
|
||||
std::set<uint64> groupsWithAppliedDefaults;
|
||||
std::mutex groupLootMethodMutex;
|
||||
// Helper function to check if loot system module is enabled
|
||||
bool IsAoeLootModuleEnabled()
|
||||
{
|
||||
return sConfigMgr->GetOption<bool>("AoeLoot.EnableMod", true);
|
||||
}
|
||||
|
||||
// Helper function to get configured loot method from config value
|
||||
LootMethod GetLootMethodFromConfig(uint32 configValue)
|
||||
@@ -48,11 +50,33 @@ LootMethod GetLootMethodFromConfig(uint32 configValue)
|
||||
case 4:
|
||||
return NEED_BEFORE_GREED;
|
||||
default:
|
||||
LOG_WARN("module.aoe_loot", "Invalid AOELoot.DefaultLootMethod value: {}. Using Group Loot.", configValue);
|
||||
LOG_WARN("module.aoe_loot", "Invalid AoeLoot.DefaultLootMethod value: {}. Using Group Loot.", configValue);
|
||||
return GROUP_LOOT;
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to apply default loot settings to a group
|
||||
void ApplyDefaultLootSettings(Group* group, Player* leaderOrPlayer)
|
||||
{
|
||||
if (!group || !leaderOrPlayer)
|
||||
return;
|
||||
|
||||
uint32 defaultLootMethodConfig = sConfigMgr->GetOption<uint32>("AoeLoot.DefaultLootMethod", 3);
|
||||
LootMethod lootMethod = GetLootMethodFromConfig(defaultLootMethodConfig);
|
||||
group->SetLootMethod(lootMethod);
|
||||
|
||||
if (lootMethod == NEED_BEFORE_GREED || lootMethod == GROUP_LOOT)
|
||||
{
|
||||
uint32 defaultLootThreshold = sConfigMgr->GetOption<uint32>("AoeLoot.DefaultLootThreshold", 2);
|
||||
group->SetLootThreshold(ItemQualities(defaultLootThreshold));
|
||||
}
|
||||
|
||||
if (lootMethod == MASTER_LOOT)
|
||||
{
|
||||
group->SetMasterLooterGuid(leaderOrPlayer->GetGUID());
|
||||
}
|
||||
}
|
||||
|
||||
// Define the roll vote enum value - use the correct RollVote enum
|
||||
#ifndef NOT_EMITED_YET
|
||||
#define NOT_EMITED_YET RollVote(0)
|
||||
@@ -61,9 +85,9 @@ LootMethod GetLootMethodFromConfig(uint32 configValue)
|
||||
// Helper function to check if AOE loot is enabled for current context
|
||||
bool AoeLootCommandScript::IsAoeLootEnabledForPlayer(Player* player)
|
||||
{
|
||||
uint32 aoeLootMode = sConfigMgr->GetOption<uint32>("AOELoot.Enable", 2);
|
||||
|
||||
switch (aoeLootMode)
|
||||
uint32 AoeLootMode = sConfigMgr->GetOption<uint32>("AoeLoot.EnableAOELoot", 2);
|
||||
|
||||
switch (AoeLootMode)
|
||||
{
|
||||
case 0: // Disabled
|
||||
return false;
|
||||
@@ -75,13 +99,16 @@ bool AoeLootCommandScript::IsAoeLootEnabledForPlayer(Player* player)
|
||||
return true;
|
||||
|
||||
default: // Invalid value, default to solo + group
|
||||
LOG_WARN("module.aoe_loot", "Invalid AOELoot.Enable value: {}. Using default (2).", aoeLootMode);
|
||||
LOG_WARN("module.aoe_loot", "Invalid AoeLoot.EnableAOELoot value: {}. Using default (2).", AoeLootMode);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool AoeLootServer::CanPacketReceive(WorldSession* session, WorldPacket& packet)
|
||||
{
|
||||
if (!IsAoeLootModuleEnabled())
|
||||
return true;
|
||||
|
||||
if (packet.GetOpcode() == CMSG_LOOT)
|
||||
{
|
||||
Player* player = session->GetPlayer();
|
||||
@@ -133,7 +160,7 @@ bool AoeLootServer::CanPacketReceive(WorldSession* session, WorldPacket& packet)
|
||||
|
||||
// Check if player has explicitly disabled AOE loot (thread-safe)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(aoeLootPreferencesMutex);
|
||||
std::lock_guard<std::mutex> lock(AoeLootPreferencesMutex);
|
||||
auto it = playerAoeLootPreferences.find(guid);
|
||||
if (it != playerAoeLootPreferences.end() && !it->second)
|
||||
{
|
||||
@@ -146,7 +173,7 @@ bool AoeLootServer::CanPacketReceive(WorldSession* session, WorldPacket& packet)
|
||||
if (player->GetLootGUID().IsEmpty())
|
||||
{
|
||||
ChatHandler handler(player->GetSession());
|
||||
handler.ParseCommands(".aoeloot lootall");
|
||||
handler.ParseCommands(".AoeLoot lootall");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -154,23 +181,26 @@ bool AoeLootServer::CanPacketReceive(WorldSession* session, WorldPacket& packet)
|
||||
|
||||
ChatCommandTable AoeLootCommandScript::GetCommands() const
|
||||
{
|
||||
static ChatCommandTable aoeLootSubCommandTable =
|
||||
static ChatCommandTable AoeLootSubCommandTable =
|
||||
{
|
||||
{ "lootall", TriggerAoeLootCommand, SEC_PLAYER, Console::No },
|
||||
{ "on", EnableAoeLootCommand, SEC_PLAYER, Console::No },
|
||||
{ "off", DisableAoeLootCommand, SEC_PLAYER, Console::No }
|
||||
};
|
||||
|
||||
static ChatCommandTable aoeLootCommandTable =
|
||||
static ChatCommandTable AoeLootCommandTable =
|
||||
{
|
||||
{ "aoeloot", aoeLootSubCommandTable }
|
||||
{ "AoeLoot", AoeLootSubCommandTable }
|
||||
};
|
||||
|
||||
return aoeLootCommandTable;
|
||||
return AoeLootCommandTable;
|
||||
}
|
||||
|
||||
bool AoeLootCommandScript::EnableAoeLootCommand(ChatHandler* handler, Optional<std::string> /*args*/)
|
||||
bool AoeLootCommandScript::EnableAoeLootCommand(ChatHandler* handler, Optional<std::string>)
|
||||
{
|
||||
if (!IsAoeLootModuleEnabled())
|
||||
return true;
|
||||
|
||||
Player* player = handler->GetSession()->GetPlayer();
|
||||
if (!player)
|
||||
return true;
|
||||
@@ -180,8 +210,8 @@ bool AoeLootCommandScript::EnableAoeLootCommand(ChatHandler* handler, Optional<s
|
||||
// Check if AOE loot is enabled server-side
|
||||
if (!IsAoeLootEnabledForPlayer(player))
|
||||
{
|
||||
uint32 aoeLootMode = sConfigMgr->GetOption<uint32>("AOELoot.Enable", 2);
|
||||
switch (aoeLootMode)
|
||||
uint32 AoeLootMode = sConfigMgr->GetOption<uint32>("AoeLoot.EnableAOELoot", 2);
|
||||
switch (AoeLootMode)
|
||||
{
|
||||
case 0:
|
||||
handler->PSendSysMessage("AOE looting is completely disabled on this server.");
|
||||
@@ -198,16 +228,19 @@ bool AoeLootCommandScript::EnableAoeLootCommand(ChatHandler* handler, Optional<s
|
||||
|
||||
// Thread-safe update
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(aoeLootPreferencesMutex);
|
||||
std::lock_guard<std::mutex> lock(AoeLootPreferencesMutex);
|
||||
playerAoeLootPreferences[guid] = true;
|
||||
}
|
||||
|
||||
handler->PSendSysMessage("AOE looting has been enabled for your character. Type: '.aoeloot off' to turn AoE Looting Off.");
|
||||
handler->PSendSysMessage("AOE looting has been enabled for your character. Type: '.AoeLoot off' to turn AoE Looting Off.");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AoeLootCommandScript::DisableAoeLootCommand(ChatHandler* handler, Optional<std::string> /*args*/)
|
||||
bool AoeLootCommandScript::DisableAoeLootCommand(ChatHandler* handler, Optional<std::string>)
|
||||
{
|
||||
if (!IsAoeLootModuleEnabled())
|
||||
return true;
|
||||
|
||||
Player* player = handler->GetSession()->GetPlayer();
|
||||
if (!player)
|
||||
return true;
|
||||
@@ -216,15 +249,14 @@ bool AoeLootCommandScript::DisableAoeLootCommand(ChatHandler* handler, Optional<
|
||||
|
||||
// Thread-safe update
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(aoeLootPreferencesMutex);
|
||||
std::lock_guard<std::mutex> lock(AoeLootPreferencesMutex);
|
||||
playerAoeLootPreferences[guid] = false;
|
||||
}
|
||||
|
||||
handler->PSendSysMessage("AOE looting has been disabled for your character. Type: '.aoeloot on' to turn AoE Looting on.");
|
||||
handler->PSendSysMessage("AOE looting has been disabled for your character. Type: '.AoeLoot on' to turn AoE Looting on.");
|
||||
return true;
|
||||
}
|
||||
|
||||
// Rename ValidateLootDistance to ValidateLootingDistance
|
||||
bool AoeLootCommandScript::ValidateLootingDistance(Player* player, ObjectGuid lguid, float maxDistance)
|
||||
{
|
||||
if (!player)
|
||||
@@ -232,7 +264,7 @@ bool AoeLootCommandScript::ValidateLootingDistance(Player* player, ObjectGuid lg
|
||||
|
||||
// Use configured AOE distance if no specific distance provided
|
||||
if (maxDistance <= 0.0f)
|
||||
maxDistance = sConfigMgr->GetOption<float>("AOELoot.Range", 55.0f);
|
||||
maxDistance = sConfigMgr->GetOption<float>("AoeLoot.Range", 55.0f);
|
||||
|
||||
if (lguid.IsGameObject())
|
||||
{
|
||||
@@ -277,7 +309,6 @@ bool AoeLootCommandScript::ValidateLootingDistance(Player* player, ObjectGuid lg
|
||||
}
|
||||
}
|
||||
|
||||
// Rename ProcessLootMoney to ProcessCreatureGold
|
||||
bool AoeLootCommandScript::ProcessCreatureGold(Player* player, Creature* creature)
|
||||
{
|
||||
if (!player || !creature)
|
||||
@@ -341,8 +372,7 @@ bool AoeLootCommandScript::ProcessCreatureGold(Player* player, Creature* creatur
|
||||
return true;
|
||||
}
|
||||
|
||||
// Rename ProcessLootRelease to ReleaseAndCleanupLoot
|
||||
void AoeLootCommandScript::ReleaseAndCleanupLoot(ObjectGuid lguid, Player* player, Loot* /*originalLoot*/)
|
||||
void AoeLootCommandScript::ReleaseAndCleanupLoot(ObjectGuid lguid, Player* player, Loot*)
|
||||
{
|
||||
player->SetLootGUID(ObjectGuid::Empty);
|
||||
player->SendLootRelease(lguid);
|
||||
@@ -441,9 +471,11 @@ void AoeLootCommandScript::ReleaseAndCleanupLoot(ObjectGuid lguid, Player* playe
|
||||
}
|
||||
}
|
||||
|
||||
// Rename ProcessLootSlot to ProcessSingleLootSlot
|
||||
bool AoeLootCommandScript::ProcessSingleLootSlot(Player* player, ObjectGuid lguid, uint8 lootSlot)
|
||||
{
|
||||
if (!IsAoeLootModuleEnabled())
|
||||
return true;
|
||||
|
||||
if (!player)
|
||||
return false;
|
||||
|
||||
@@ -600,6 +632,9 @@ bool AoeLootCommandScript::ProcessSingleLootSlot(Player* player, ObjectGuid lgui
|
||||
|
||||
bool AoeLootCommandScript::TriggerAoeLootCommand(ChatHandler* handler, Optional<std::string> /*args*/)
|
||||
{
|
||||
if (!IsAoeLootModuleEnabled())
|
||||
return true;
|
||||
|
||||
Player* player = handler->GetSession()->GetPlayer();
|
||||
if (!player)
|
||||
return true;
|
||||
@@ -611,8 +646,8 @@ bool AoeLootCommandScript::TriggerAoeLootCommand(ChatHandler* handler, Optional<
|
||||
return true;
|
||||
}
|
||||
|
||||
float range = sConfigMgr->GetOption<float>("AOELoot.Range", 55.0);
|
||||
bool debugMode = sConfigMgr->GetOption<bool>("AOELoot.Debug", false);
|
||||
float range = sConfigMgr->GetOption<float>("AoeLoot.Range", 55.0);
|
||||
bool debugMode = sConfigMgr->GetOption<bool>("AoeLoot.Debug", false);
|
||||
|
||||
std::list<Creature*> nearbyCorpses;
|
||||
player->GetDeadCreatureListInGrid(nearbyCorpses, range);
|
||||
@@ -715,25 +750,8 @@ bool AoeLootCommandScript::TriggerAoeLootCommand(ChatHandler* handler, Optional<
|
||||
}
|
||||
}
|
||||
|
||||
// Handle quest items based on configuration
|
||||
if (ShouldProcessQuestItemsSeparately())
|
||||
{
|
||||
// Process quest items separately (default behavior)
|
||||
ProcessQuestItemsForPlayer(player, lguid, loot);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Treat quest items as regular loot (like quest loot party mod)
|
||||
for (uint8 i = 0; i < loot->quest_items.size(); ++i)
|
||||
{
|
||||
uint8 questLootSlot = loot->items.size() + i;
|
||||
ProcessSingleLootSlot(player, lguid, questLootSlot);
|
||||
if (debugMode)
|
||||
{
|
||||
LOG_DEBUG("module.aoe_loot", "AOE Loot: looted quest item (as regular) in slot {}", questLootSlot);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Always process quest items using Blizzard logic (only for players who need them)
|
||||
ProcessQuestItemsForPlayer(player, lguid, loot);
|
||||
|
||||
// Handle money
|
||||
if (loot->gold > 0)
|
||||
@@ -757,14 +775,22 @@ bool AoeLootCommandScript::TriggerAoeLootCommand(ChatHandler* handler, Optional<
|
||||
// Display login message to player
|
||||
void AoeLootPlayer::OnPlayerLogin(Player* player)
|
||||
{
|
||||
// Check if AOE loot is enabled at all (any mode > 0)
|
||||
uint32 aoeLootMode = sConfigMgr->GetOption<uint32>("AOELoot.Enable", 2);
|
||||
|
||||
if (aoeLootMode > 0 && sConfigMgr->GetOption<bool>("AOELoot.Message", true))
|
||||
if (!IsAoeLootModuleEnabled())
|
||||
return;
|
||||
|
||||
// If player is in a group, apply default loot settings
|
||||
if (Group* group = player->GetGroup())
|
||||
{
|
||||
ApplyDefaultLootSettings(group, player);
|
||||
}
|
||||
|
||||
uint32 AoeLootMode = sConfigMgr->GetOption<uint32>("AoeLoot.EnableAOELoot", 2);
|
||||
|
||||
if (AoeLootMode > 0 && sConfigMgr->GetOption<bool>("AoeLoot.Message", true))
|
||||
{
|
||||
std::string message = "AOE looting has been enabled for your character";
|
||||
|
||||
switch (aoeLootMode)
|
||||
switch (AoeLootMode)
|
||||
{
|
||||
case 1:
|
||||
message += " (solo play only)";
|
||||
@@ -774,246 +800,58 @@ void AoeLootPlayer::OnPlayerLogin(Player* player)
|
||||
break;
|
||||
}
|
||||
|
||||
message += ". Type: '.aoeloot off' to turn AoE Looting Off.";
|
||||
message += ". Type: '.AoeLoot off' to turn AoE Looting Off.";
|
||||
ChatHandler(player->GetSession()).PSendSysMessage(message.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// Group script implementation
|
||||
void AoeLootGroupScript::OnCreate(Group* group, Player* leader)
|
||||
{
|
||||
// Only apply default loot method to brand new groups, not reformed/rejoined groups
|
||||
if (!group || !leader)
|
||||
return;
|
||||
|
||||
// Only apply to truly new groups (single member = the leader)
|
||||
// When a player rejoins an existing group, the group already has its loot method preserved
|
||||
if (group->GetMembersCount() > 1)
|
||||
if (!IsAoeLootModuleEnabled())
|
||||
return;
|
||||
|
||||
// Check if this is a playerbot scenario - if the leader is a bot, delay loot method setting
|
||||
// to allow playerbot logic to handle leadership transfers when the player logs in
|
||||
// Note: Since IsBot() may not be available, we'll use a more conservative approach
|
||||
// and only apply defaults when we're certain it's a real player-led group
|
||||
if (!leader->GetSession() || !leader->GetSession()->GetPlayer())
|
||||
{
|
||||
// No valid session - likely a bot or disconnected player
|
||||
// Don't set loot method immediately
|
||||
if (!group || !leader)
|
||||
return;
|
||||
}
|
||||
|
||||
// Apply default loot settings for real player leaders
|
||||
|
||||
// Apply default loot settings to the group
|
||||
ApplyDefaultLootSettings(group, leader);
|
||||
}
|
||||
|
||||
// Handle leadership changes (important for playerbot scenarios)
|
||||
void AoeLootGroupScript::OnChangeLeader(Group* group, ObjectGuid newLeaderGuid, ObjectGuid /*oldLeaderGuid*/)
|
||||
{
|
||||
if (!group)
|
||||
return;
|
||||
|
||||
Player* newLeader = ObjectAccessor::FindPlayer(newLeaderGuid);
|
||||
if (!newLeader)
|
||||
return;
|
||||
|
||||
// Only apply default loot settings if:
|
||||
// 1. The new leader is a real player (has valid session)
|
||||
// 2. The loot method hasn't been manually changed from our defaults
|
||||
if (newLeader->GetSession() && newLeader->GetSession()->GetPlayer())
|
||||
{
|
||||
// Safety check for valid group GUID
|
||||
ObjectGuid groupGuid = group->GetGUID();
|
||||
if (!groupGuid.IsEmpty())
|
||||
{
|
||||
uint64 groupId = groupGuid.GetRawValue();
|
||||
if (groupId != 0) // Additional safety check
|
||||
{
|
||||
try
|
||||
{
|
||||
// Check if this group has had our defaults applied and if they've been changed
|
||||
std::lock_guard<std::mutex> lock(groupLootMethodMutex);
|
||||
if (groupsWithAppliedDefaults.find(groupId) == groupsWithAppliedDefaults.end())
|
||||
{
|
||||
// This group has never had our defaults applied
|
||||
// It's safe to apply our defaults
|
||||
ApplyDefaultLootSettings(group, newLeader);
|
||||
}
|
||||
else if (!IsLootMethodManuallySet(group))
|
||||
{
|
||||
// We've applied defaults before, but they haven't been manually changed
|
||||
// This handles bot-to-player leadership transfers where we want to reapply defaults
|
||||
ApplyDefaultLootSettings(group, newLeader);
|
||||
}
|
||||
// If the loot method has been manually changed, don't override it
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
LOG_ERROR("module.aoe_loot", "Failed to handle leadership change for group {}: {}", groupId, e.what());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_WARN("module.aoe_loot", "Group has invalid GUID (0) in OnChangeLeader");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_WARN("module.aoe_loot", "Group has empty GUID in OnChangeLeader");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle group dissolution - clean up tracking
|
||||
void AoeLootGroupScript::OnDisband(Group* group)
|
||||
{
|
||||
if (!group)
|
||||
return;
|
||||
|
||||
// Remove this group from our tracking when it's disbanded
|
||||
// Safety check for valid group GUID
|
||||
ObjectGuid groupGuid = group->GetGUID();
|
||||
if (!groupGuid.IsEmpty())
|
||||
{
|
||||
uint64 groupId = groupGuid.GetRawValue();
|
||||
if (groupId != 0) // Additional safety check
|
||||
{
|
||||
try
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(groupLootMethodMutex);
|
||||
groupsWithAppliedDefaults.erase(groupId);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
LOG_ERROR("module.aoe_loot", "Failed to clean up tracking for group {}: {}", groupId, e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to apply default loot settings
|
||||
void AoeLootGroupScript::ApplyDefaultLootSettings(Group* group, Player* leader)
|
||||
{
|
||||
if (!group || !leader)
|
||||
return;
|
||||
|
||||
// Get configured default loot method
|
||||
uint32 defaultLootMethodConfig = sConfigMgr->GetOption<uint32>("AOELoot.DefaultLootMethod", 3); // 3 = Group Loot (default)
|
||||
uint32 defaultLootThreshold = sConfigMgr->GetOption<uint32>("AOELoot.DefaultLootThreshold", 2); // Default: Uncommon
|
||||
|
||||
// Set the configured loot method for new groups
|
||||
LootMethod lootMethod = GetLootMethodFromConfig(defaultLootMethodConfig);
|
||||
group->SetLootMethod(lootMethod);
|
||||
|
||||
// If using Need Before Greed or Group Loot, also set the quality threshold
|
||||
if (lootMethod == NEED_BEFORE_GREED || lootMethod == GROUP_LOOT)
|
||||
{
|
||||
group->SetLootThreshold(ItemQualities(defaultLootThreshold));
|
||||
}
|
||||
|
||||
// If using Master Loot, set the leader as master looter
|
||||
if (lootMethod == MASTER_LOOT && leader)
|
||||
{
|
||||
group->SetMasterLooterGuid(leader->GetGUID());
|
||||
}
|
||||
|
||||
// Track that we've applied defaults to this group
|
||||
// Add safety check for valid group GUID
|
||||
ObjectGuid groupGuid = group->GetGUID();
|
||||
if (!groupGuid.IsEmpty())
|
||||
{
|
||||
uint64 groupId = groupGuid.GetRawValue();
|
||||
if (groupId != 0) // Additional safety check
|
||||
{
|
||||
try
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(groupLootMethodMutex);
|
||||
groupsWithAppliedDefaults.insert(groupId);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
LOG_ERROR("module.aoe_loot", "Failed to track group {} in ApplyDefaultLootSettings: {}", groupId, e.what());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_WARN("module.aoe_loot", "Group has invalid GUID (0) in ApplyDefaultLootSettings");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_WARN("module.aoe_loot", "Group has empty GUID in ApplyDefaultLootSettings");
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to check if loot method appears to be manually set
|
||||
bool AoeLootGroupScript::IsLootMethodManuallySet(Group* group)
|
||||
{
|
||||
if (!group)
|
||||
return false;
|
||||
|
||||
// Get our configured defaults
|
||||
uint32 defaultLootMethodConfig = sConfigMgr->GetOption<uint32>("AOELoot.DefaultLootMethod", 3);
|
||||
uint32 defaultLootThreshold = sConfigMgr->GetOption<uint32>("AOELoot.DefaultLootThreshold", 2);
|
||||
|
||||
LootMethod expectedDefaultMethod = GetLootMethodFromConfig(defaultLootMethodConfig);
|
||||
|
||||
// If the current loot method or threshold differs from our defaults,
|
||||
// it was likely changed manually by a player
|
||||
if (group->GetLootMethod() != expectedDefaultMethod)
|
||||
return true;
|
||||
|
||||
// For Group Loot and Need Before Greed, also check the threshold
|
||||
if ((expectedDefaultMethod == GROUP_LOOT || expectedDefaultMethod == NEED_BEFORE_GREED) &&
|
||||
group->GetLootThreshold() != defaultLootThreshold)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Helper function implementation for AoeLootGroupScript
|
||||
LootMethod AoeLootGroupScript::GetLootMethodFromConfig(uint32 configValue)
|
||||
{
|
||||
switch (configValue)
|
||||
{
|
||||
case 0: return FREE_FOR_ALL;
|
||||
case 1: return ROUND_ROBIN;
|
||||
case 2: return MASTER_LOOT;
|
||||
case 3: return GROUP_LOOT;
|
||||
case 4: return NEED_BEFORE_GREED;
|
||||
default: return GROUP_LOOT; // Safe default
|
||||
}
|
||||
}
|
||||
|
||||
// Quest item processing functions
|
||||
bool AoeLootCommandScript::ShouldProcessQuestItemsSeparately()
|
||||
{
|
||||
return !sConfigMgr->GetOption<bool>("AOELoot.QuestItemsAsRegular", false);
|
||||
}
|
||||
|
||||
bool AoeLootCommandScript::IsQuestItemForPlayer(Player* player, uint32 itemId)
|
||||
{
|
||||
if (!player)
|
||||
return false;
|
||||
|
||||
|
||||
const ItemTemplate* itemTemplate = sObjectMgr->GetItemTemplate(itemId);
|
||||
if (!itemTemplate)
|
||||
return false;
|
||||
|
||||
// Check if this item starts a quest or is a quest item
|
||||
|
||||
// Check if this item starts a quest
|
||||
if (itemTemplate->StartQuest != 0)
|
||||
return true;
|
||||
|
||||
{
|
||||
uint32 questId = itemTemplate->StartQuest;
|
||||
// Player must NOT have the quest, must NOT have completed it, and must NOT already have the item
|
||||
if (!player->HasQuest(questId) &&
|
||||
player->GetQuestStatus(questId) != QUEST_STATUS_COMPLETE &&
|
||||
player->GetItemCount(itemId, true) == 0) // true = include bank
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if player has quests requiring this item
|
||||
for (uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot)
|
||||
{
|
||||
uint32 questId = player->GetQuestSlotQuestId(slot);
|
||||
if (questId == 0)
|
||||
continue;
|
||||
|
||||
|
||||
Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
|
||||
if (!quest)
|
||||
continue;
|
||||
|
||||
|
||||
// Check quest objectives for this item
|
||||
for (uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
|
||||
{
|
||||
@@ -1022,7 +860,7 @@ bool AoeLootCommandScript::IsQuestItemForPlayer(Player* player, uint32 itemId)
|
||||
// Check if player still needs this item for the quest
|
||||
uint32 currentCount = player->GetItemCount(itemId, true);
|
||||
uint32 requiredCount = quest->RequiredItemCount[i];
|
||||
|
||||
|
||||
if (currentCount < requiredCount)
|
||||
{
|
||||
return true;
|
||||
@@ -1030,7 +868,7 @@ bool AoeLootCommandScript::IsQuestItemForPlayer(Player* player, uint32 itemId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1040,7 +878,7 @@ bool AoeLootCommandScript::ProcessQuestItemsForPlayer(Player* player, ObjectGuid
|
||||
return false;
|
||||
|
||||
bool processedAny = false;
|
||||
bool debugMode = sConfigMgr->GetOption<bool>("AOELoot.Debug", false);
|
||||
bool debugMode = sConfigMgr->GetOption<bool>("AoeLoot.Debug", false);
|
||||
|
||||
for (uint8 i = 0; i < loot->quest_items.size(); ++i)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user