mirror of
https://github.com/brighton-chi/mod-aoe-loot.git
synced 2026-01-13 00:58:34 +00:00
complete refactor
This commit is contained in:
@@ -54,14 +54,6 @@ AoeLoot.DefaultLootMethod = 2
|
|||||||
|
|
||||||
AoeLoot.DefaultLootThreshold = 2
|
AoeLoot.DefaultLootThreshold = 2
|
||||||
|
|
||||||
# AoeLoot.Debug
|
|
||||||
# Description: Enables debugging mode.
|
|
||||||
# Values: 0 = Disabled
|
|
||||||
# 1 = Enabled
|
|
||||||
# Default: 0 (Disabled)
|
|
||||||
|
|
||||||
AoeLoot.Debug = 0
|
|
||||||
|
|
||||||
# Chat Commands
|
# Chat Commands
|
||||||
# .AoeLoot off Disables AoE looting for player
|
# .AoeLoot off Disables AoE looting for player
|
||||||
# .AoeLoot on Enables AoE looting for player (requires module to be enabled)
|
# .AoeLoot on Enables AoE looting for player (requires module to be enabled)
|
||||||
|
|||||||
199
src/aoe_loot.cpp
199
src/aoe_loot.cpp
@@ -1,6 +1,5 @@
|
|||||||
#include "aoe_loot.h"
|
#include "aoe_loot.h"
|
||||||
#include "ScriptMgr.h"
|
#include "ScriptMgr.h"
|
||||||
#include "World.h"
|
|
||||||
#include "LootMgr.h"
|
#include "LootMgr.h"
|
||||||
#include "ServerScript.h"
|
#include "ServerScript.h"
|
||||||
#include "WorldSession.h"
|
#include "WorldSession.h"
|
||||||
@@ -9,12 +8,10 @@
|
|||||||
#include "Chat.h"
|
#include "Chat.h"
|
||||||
#include "ChatCommand.h"
|
#include "ChatCommand.h"
|
||||||
#include "ChatCommandArgs.h"
|
#include "ChatCommandArgs.h"
|
||||||
#include "WorldObjectScript.h"
|
|
||||||
#include "Creature.h"
|
#include "Creature.h"
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "Map.h"
|
#include "Map.h"
|
||||||
#include <fmt/format.h>
|
|
||||||
#include "Corpse.h"
|
#include "Corpse.h"
|
||||||
#include "Group.h"
|
#include "Group.h"
|
||||||
#include "ObjectMgr.h"
|
#include "ObjectMgr.h"
|
||||||
@@ -39,19 +36,12 @@ LootMethod GetLootMethodFromConfig(uint32 configValue)
|
|||||||
{
|
{
|
||||||
switch (configValue)
|
switch (configValue)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0: return FREE_FOR_ALL;
|
||||||
return FREE_FOR_ALL;
|
case 1: return ROUND_ROBIN;
|
||||||
case 1:
|
case 2: return MASTER_LOOT;
|
||||||
return ROUND_ROBIN;
|
case 3: return GROUP_LOOT;
|
||||||
case 2:
|
case 4: return NEED_BEFORE_GREED;
|
||||||
return MASTER_LOOT;
|
default: return GROUP_LOOT;
|
||||||
case 3:
|
|
||||||
return GROUP_LOOT;
|
|
||||||
case 4:
|
|
||||||
return NEED_BEFORE_GREED;
|
|
||||||
default:
|
|
||||||
LOG_WARN("module.aoe_loot", "Invalid AoeLoot.DefaultLootMethod value: {}. Using Group Loot.", configValue);
|
|
||||||
return GROUP_LOOT;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,8 +88,7 @@ bool AoeLootCommandScript::IsAoeLootEnabledForPlayer(Player* player)
|
|||||||
case 2: // Enabled for both solo and group play
|
case 2: // Enabled for both solo and group play
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
default: // Invalid value, default to solo + group
|
default: // Enabled for both solo and group play
|
||||||
LOG_WARN("module.aoe_loot", "Invalid AoeLoot.EnableAOELoot value: {}. Using default (2).", AoeLootMode);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -202,37 +191,14 @@ bool AoeLootCommandScript::EnableAoeLootCommand(ChatHandler* handler, Optional<s
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
Player* player = handler->GetSession()->GetPlayer();
|
Player* player = handler->GetSession()->GetPlayer();
|
||||||
if (!player)
|
if (!player || !IsAoeLootEnabledForPlayer(player))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
uint64 guid = player->GetGUID().GetRawValue();
|
uint64 guid = player->GetGUID().GetRawValue();
|
||||||
|
|
||||||
// Check if AOE loot is enabled server-side
|
|
||||||
if (!IsAoeLootEnabledForPlayer(player))
|
|
||||||
{
|
|
||||||
uint32 AoeLootMode = sConfigMgr->GetOption<uint32>("AoeLoot.EnableAOELoot", 2);
|
|
||||||
switch (AoeLootMode)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
handler->PSendSysMessage("AOE looting is completely disabled on this server.");
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
handler->PSendSysMessage("AOE looting is only available for solo play (you are currently in a group).");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
handler->PSendSysMessage("AOE looting is not available in your current context.");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Thread-safe update
|
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(AoeLootPreferencesMutex);
|
std::lock_guard<std::mutex> lock(AoeLootPreferencesMutex);
|
||||||
playerAoeLootPreferences[guid] = true;
|
playerAoeLootPreferences[guid] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
handler->PSendSysMessage("AOE looting has been enabled for your character. Type: '.AoeLoot off' to turn AoE Looting Off.");
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,7 +219,6 @@ bool AoeLootCommandScript::DisableAoeLootCommand(ChatHandler* handler, Optional<
|
|||||||
playerAoeLootPreferences[guid] = false;
|
playerAoeLootPreferences[guid] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
handler->PSendSysMessage("AOE looting has been disabled for your character. Type: '.AoeLoot on' to turn AoE Looting on.");
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -642,21 +607,14 @@ bool AoeLootCommandScript::TriggerAoeLootCommand(ChatHandler* handler, Optional<
|
|||||||
// Check if AOE loot is enabled for this player's context
|
// Check if AOE loot is enabled for this player's context
|
||||||
if (!IsAoeLootEnabledForPlayer(player))
|
if (!IsAoeLootEnabledForPlayer(player))
|
||||||
{
|
{
|
||||||
handler->PSendSysMessage("AOE looting is not available in your current context.");
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
float range = sConfigMgr->GetOption<float>("AoeLoot.Range", 55.0);
|
float range = sConfigMgr->GetOption<float>("AoeLoot.Range", 55.0);
|
||||||
bool debugMode = sConfigMgr->GetOption<bool>("AoeLoot.Debug", false);
|
|
||||||
|
|
||||||
std::list<Creature*> nearbyCorpses;
|
std::list<Creature*> nearbyCorpses;
|
||||||
player->GetDeadCreatureListInGrid(nearbyCorpses, range);
|
player->GetDeadCreatureListInGrid(nearbyCorpses, range);
|
||||||
|
|
||||||
if (debugMode)
|
|
||||||
{
|
|
||||||
LOG_DEBUG("module.aoe_loot", "AOE Loot: Found {} nearby corpses within range {}.", nearbyCorpses.size(), range);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Filter valid corpses
|
// Filter valid corpses
|
||||||
std::list<Creature*> validCorpses;
|
std::list<Creature*> validCorpses;
|
||||||
for (auto* creature : nearbyCorpses)
|
for (auto* creature : nearbyCorpses)
|
||||||
@@ -664,15 +622,16 @@ bool AoeLootCommandScript::TriggerAoeLootCommand(ChatHandler* handler, Optional<
|
|||||||
if (!player || !creature)
|
if (!player || !creature)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Check if creature is valid for looting by this player
|
|
||||||
if (!player->isAllowedToLoot(creature))
|
if (!player->isAllowedToLoot(creature))
|
||||||
{
|
|
||||||
if (debugMode)
|
|
||||||
LOG_DEBUG("module.aoe_loot", "AOE Loot: Skipping creature {} - not your loot", creature->GetGUID().ToString());
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
if (!creature->hasLootRecipient() || !creature->isTappedBy(player))
|
if (!creature->HasDynamicFlag(UNIT_DYNFLAG_LOOTABLE))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!creature->hasLootRecipient())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!creature->isTappedBy(player))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Get player's group and check loot permissions based on group loot method
|
// Get player's group and check loot permissions based on group loot method
|
||||||
@@ -686,9 +645,6 @@ bool AoeLootCommandScript::TriggerAoeLootCommand(ChatHandler* handler, Optional<
|
|||||||
{
|
{
|
||||||
if (loot->roundRobinPlayer && loot->roundRobinPlayer != player->GetGUID())
|
if (loot->roundRobinPlayer && loot->roundRobinPlayer != player->GetGUID())
|
||||||
{
|
{
|
||||||
if (debugMode)
|
|
||||||
LOG_DEBUG("module.aoe_loot", "AOE Loot: Skipping creature {} - not your turn (Round Robin)", creature->GetGUID().ToString());
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -697,30 +653,14 @@ bool AoeLootCommandScript::TriggerAoeLootCommand(ChatHandler* handler, Optional<
|
|||||||
{
|
{
|
||||||
if (group->GetMasterLooterGuid() != player->GetGUID())
|
if (group->GetMasterLooterGuid() != player->GetGUID())
|
||||||
{
|
{
|
||||||
if (debugMode)
|
|
||||||
LOG_DEBUG("module.aoe_loot", "AOE Loot: Skipping creature {} - not master looter", creature->GetGUID().ToString());
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip if corpse is not lootable
|
|
||||||
if (!creature->HasDynamicFlag(UNIT_DYNFLAG_LOOTABLE))
|
|
||||||
{
|
|
||||||
if (debugMode)
|
|
||||||
LOG_DEBUG("module.aoe_loot", "AOE Loot: Skipping creature {} - not lootable", creature->GetGUID().ToString());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
validCorpses.push_back(creature);
|
validCorpses.push_back(creature);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debugMode)
|
|
||||||
{
|
|
||||||
LOG_DEBUG("module.aoe_loot", "AOE Loot: Found {} valid nearby corpses within range {}.", validCorpses.size(), range);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process all valid corpses
|
// Process all valid corpses
|
||||||
for (auto* creature : validCorpses)
|
for (auto* creature : validCorpses)
|
||||||
{
|
{
|
||||||
@@ -733,35 +673,22 @@ bool AoeLootCommandScript::TriggerAoeLootCommand(ChatHandler* handler, Optional<
|
|||||||
// Double-check distance validation for security
|
// Double-check distance validation for security
|
||||||
if (!ValidateLootingDistance(player, lguid))
|
if (!ValidateLootingDistance(player, lguid))
|
||||||
{
|
{
|
||||||
if (debugMode)
|
|
||||||
LOG_DEBUG("module.aoe_loot", "AOE Loot: Skipping creature {} - too far away", lguid.ToString());
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
player->SetLootGUID(lguid);
|
player->SetLootGUID(lguid);
|
||||||
|
|
||||||
// Process all regular items (includes quest items and FFA items automatically)
|
// Process all loot items
|
||||||
for (uint8 lootSlot = 0; lootSlot < loot->items.size(); ++lootSlot)
|
for (uint8 lootSlot = 0; lootSlot < loot->items.size(); ++lootSlot)
|
||||||
{
|
{
|
||||||
ProcessSingleLootSlot(player, lguid, lootSlot);
|
ProcessSingleLootSlot(player, lguid, lootSlot);
|
||||||
if (debugMode)
|
|
||||||
{
|
|
||||||
LOG_DEBUG("module.aoe_loot", "AOE Loot: looted item from slot {} (ID: {}) from {}", lootSlot, loot->items[lootSlot].itemid, lguid.ToString());
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Always process quest items using Blizzard logic (only for players who need them)
|
|
||||||
ProcessQuestItemsForPlayer(player, lguid, loot);
|
|
||||||
|
|
||||||
// Handle money
|
// Handle money
|
||||||
if (loot->gold > 0)
|
if (loot->gold > 0)
|
||||||
{
|
{
|
||||||
uint32 goldAmount = loot->gold;
|
uint32 goldAmount = loot->gold;
|
||||||
ProcessCreatureGold(player, creature);
|
ProcessCreatureGold(player, creature);
|
||||||
if (debugMode)
|
|
||||||
{
|
|
||||||
LOG_DEBUG("module.aoe_loot", "AOE Loot: Looted {} copper from {}", goldAmount, lguid.ToString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loot->isLooted())
|
if (loot->isLooted())
|
||||||
@@ -772,7 +699,6 @@ bool AoeLootCommandScript::TriggerAoeLootCommand(ChatHandler* handler, Optional<
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display login message to player
|
|
||||||
void AoeLootPlayer::OnPlayerLogin(Player* player)
|
void AoeLootPlayer::OnPlayerLogin(Player* player)
|
||||||
{
|
{
|
||||||
if (!IsAoeLootModuleEnabled())
|
if (!IsAoeLootModuleEnabled())
|
||||||
@@ -801,7 +727,6 @@ void AoeLootPlayer::OnPlayerLogin(Player* player)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -817,96 +742,30 @@ void AoeLootGroupScript::OnCreate(Group* group, Player* leader)
|
|||||||
ApplyDefaultLootSettings(group, leader);
|
ApplyDefaultLootSettings(group, leader);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Quest item processing functions
|
class AoeLootQuestParty : public PlayerScript
|
||||||
bool AoeLootCommandScript::IsQuestItemForPlayer(Player* player, uint32 itemId)
|
|
||||||
{
|
{
|
||||||
if (!player)
|
public:
|
||||||
return false;
|
AoeLootQuestParty() : PlayerScript("AoeLootQuestParty") { }
|
||||||
|
|
||||||
const ItemTemplate* itemTemplate = sObjectMgr->GetItemTemplate(itemId);
|
void OnPlayerBeforeFillQuestLootItem(Player* /*player*/, LootItem& item) override
|
||||||
if (!itemTemplate)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Check if this item starts a quest
|
|
||||||
if (itemTemplate->StartQuest != 0)
|
|
||||||
{
|
{
|
||||||
uint32 questId = itemTemplate->StartQuest;
|
ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(item.itemid);
|
||||||
// Player must NOT have the quest, must NOT have completed it, and must NOT already have the item
|
if (itemTemplate &&
|
||||||
if (!player->HasQuest(questId) &&
|
itemTemplate->Quality == ITEM_QUALITY_NORMAL &&
|
||||||
player->GetQuestStatus(questId) != QUEST_STATUS_COMPLETE &&
|
itemTemplate->Class == ITEM_CLASS_QUEST &&
|
||||||
player->GetItemCount(itemId, true) == 0) // true = include bank
|
itemTemplate->SubClass == ITEM_SUBCLASS_QUEST &&
|
||||||
|
itemTemplate->Bonding == BIND_QUEST_ITEM)
|
||||||
{
|
{
|
||||||
return true;
|
item.freeforall = 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)
|
|
||||||
{
|
|
||||||
if (quest->RequiredItemId[i] == 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AoeLootCommandScript::ProcessQuestItemsForPlayer(Player* player, ObjectGuid lguid, Loot* loot)
|
|
||||||
{
|
|
||||||
if (!player || !loot)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
bool processedAny = false;
|
|
||||||
bool debugMode = sConfigMgr->GetOption<bool>("AoeLoot.Debug", false);
|
|
||||||
|
|
||||||
for (uint8 i = 0; i < loot->quest_items.size(); ++i)
|
|
||||||
{
|
|
||||||
LootItem& questItem = loot->quest_items[i];
|
|
||||||
|
|
||||||
// Check if this quest item is for the current player
|
|
||||||
if (IsQuestItemForPlayer(player, questItem.itemid))
|
|
||||||
{
|
|
||||||
uint8 questLootSlot = loot->items.size() + i;
|
|
||||||
ProcessSingleLootSlot(player, lguid, questLootSlot);
|
|
||||||
processedAny = true;
|
|
||||||
|
|
||||||
if (debugMode)
|
|
||||||
{
|
|
||||||
LOG_DEBUG("module.aoe_loot", "AOE Loot: looted quest item {} from slot {} for player {}",
|
|
||||||
questItem.itemid, questLootSlot, player->GetName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return processedAny;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add script registrations
|
|
||||||
void AddSC_AoeLoot()
|
void AddSC_AoeLoot()
|
||||||
{
|
{
|
||||||
new AoeLootPlayer();
|
new AoeLootPlayer();
|
||||||
new AoeLootServer();
|
new AoeLootServer();
|
||||||
new AoeLootCommandScript();
|
new AoeLootCommandScript();
|
||||||
new AoeLootGroupScript();
|
new AoeLootGroupScript();
|
||||||
|
new AoeLootQuestParty();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,22 +2,14 @@
|
|||||||
#define MODULE_AoeLoot_H
|
#define MODULE_AoeLoot_H
|
||||||
|
|
||||||
#include "ScriptMgr.h"
|
#include "ScriptMgr.h"
|
||||||
#include "Config.h"
|
|
||||||
#include "ServerScript.h"
|
#include "ServerScript.h"
|
||||||
#include "Chat.h"
|
|
||||||
#include "Player.h"
|
|
||||||
#include "Item.h"
|
|
||||||
#include "ScriptedGossip.h"
|
|
||||||
#include "ChatCommand.h"
|
#include "ChatCommand.h"
|
||||||
#include "ChatCommandArgs.h"
|
|
||||||
#include "AccountMgr.h"
|
class Player;
|
||||||
#include "ObjectMgr.h"
|
class Group;
|
||||||
#include "QuestDef.h"
|
class Loot;
|
||||||
#include <vector>
|
class Creature;
|
||||||
#include <list>
|
class ObjectGuid;
|
||||||
#include <map>
|
|
||||||
#include <ObjectGuid.h>
|
|
||||||
#include <mutex>
|
|
||||||
|
|
||||||
using namespace Acore::ChatCommands;
|
using namespace Acore::ChatCommands;
|
||||||
|
|
||||||
@@ -50,10 +42,6 @@ public:
|
|||||||
static bool ProcessCreatureGold(Player* player, Creature* creature);
|
static bool ProcessCreatureGold(Player* player, Creature* creature);
|
||||||
static void ReleaseAndCleanupLoot(ObjectGuid lguid, Player* player, Loot* loot);
|
static void ReleaseAndCleanupLoot(ObjectGuid lguid, Player* player, Loot* loot);
|
||||||
|
|
||||||
// Quest item processing functions
|
|
||||||
static bool IsQuestItemForPlayer(Player* player, uint32 itemId);
|
|
||||||
static bool ProcessQuestItemsForPlayer(Player* player, ObjectGuid lguid, Loot* loot);
|
|
||||||
|
|
||||||
// Validation functions
|
// Validation functions
|
||||||
static bool ValidateLootingDistance(Player* player, ObjectGuid lguid, float maxDistance = 0.0f);
|
static bool ValidateLootingDistance(Player* player, ObjectGuid lguid, float maxDistance = 0.0f);
|
||||||
static bool IsAoeLootEnabledForPlayer(Player* player);
|
static bool IsAoeLootEnabledForPlayer(Player* player);
|
||||||
@@ -64,10 +52,6 @@ class AoeLootGroupScript : public GroupScript
|
|||||||
public:
|
public:
|
||||||
AoeLootGroupScript() : GroupScript("AoeLootGroupScript") {}
|
AoeLootGroupScript() : GroupScript("AoeLootGroupScript") {}
|
||||||
void OnCreate(Group* group, Player* leader) override;
|
void OnCreate(Group* group, Player* leader) override;
|
||||||
|
|
||||||
private:
|
|
||||||
// Helper function to convert config value to LootMethod enum
|
|
||||||
LootMethod GetLootMethodFromConfig(uint32 configValue);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void AddSC_AoeLoot();
|
void AddSC_AoeLoot();
|
||||||
|
|||||||
Reference in New Issue
Block a user