feat. Modifying the module logic (#21)

* feat. Modifying the module logic

* Set free loot, if the group has only one member

* Add variable range via configuration file

* Improving script logic

* fatal error: unused variable
This commit is contained in:
Walter Pagani
2024-02-06 05:42:25 -03:00
committed by GitHub
parent 42cc6e602e
commit c5bfaf414d
2 changed files with 112 additions and 51 deletions

View File

@@ -34,3 +34,11 @@ AOELoot.Enable = 1
# #
AOELoot.MailEnable = 1 AOELoot.MailEnable = 1
#
# AOELoot.Range
# Description: Maximum reach range search loot.
# Default: 30.0
#
AOELoot.Range = 30.0

View File

@@ -28,6 +28,8 @@ enum AoeLootString
AOE_ITEM_IN_THE_MAIL AOE_ITEM_IN_THE_MAIL
}; };
typedef std::map<uint32, uint32> AOEContainer;
class AoeLoot_Player : public PlayerScript class AoeLoot_Player : public PlayerScript
{ {
public: public:
@@ -50,53 +52,59 @@ public:
{ {
bool _enable = sConfigMgr->GetOption<bool>("AOELoot.Enable", true); bool _enable = sConfigMgr->GetOption<bool>("AOELoot.Enable", true);
if ((player->GetGroup() && (player->GetGroup()->GetLootMethod() != FREE_FOR_ALL)) || !_enable) if (!_enable)
return; return;
float range = 30.0f; float range = sConfigMgr->GetOption<float>("AOELoot.Range", 30.0);
uint32 gold = 0; uint32 gold = 0;
std::list<Creature*> creaturedie; std::list<Creature*> deadCreatures;
player->GetDeadCreatureListInGrid(creaturedie, range); deadCreatures.clear();
AOEContainer aoeLoot;
player->GetDeadCreatureListInGrid(deadCreatures, range, false);
for (auto const& _creature : creaturedie) for (auto& _creature : deadCreatures)
{
if (player->GetGroup())
{
if (player->GetGroup()->GetMembersCount() > 1)
{
if (_creature->IsDungeonBoss() || _creature->isWorldBoss())
continue;
}
else if (player->GetGroup()->GetMembersCount() == 1)
{
player->GetGroup()->SetLootMethod(FREE_FOR_ALL);
}
}
if (player == _creature->GetLootRecipient() && (_creature->HasDynamicFlag(UNIT_DYNFLAG_LOOTABLE)))
{ {
Loot* loot = &_creature->loot; Loot* loot = &_creature->loot;
gold += loot->gold; gold += loot->gold;
loot->gold = 0; loot->gold = 0;
uint8 lootSlot = 0;
uint32 maxSlot = loot->GetMaxSlotInLootFor(player);
for (uint32 i = 0; i < maxSlot; ++i) for (auto const& item : loot->items)
{ {
if (LootItem* item = loot->LootItemInSlot(i, player)) if (loot->items.size() > 1 && (loot->items[item.itemIndex].itemid == loot->items[item.itemIndex + 1].itemid))
{ continue;
ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(item->itemid);
ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(item.itemid);
if (itemTemplate->MaxCount != 1) if (itemTemplate->MaxCount != 1)
{ {
if (player->AddItem(item->itemid, item->count)) aoeLoot[item.itemid] += (uint32)item.count;
{
player->SendNotifyLootItemRemoved(lootSlot);
player->SendLootRelease(player->GetLootGUID());
}
else if (sConfigMgr->GetOption<bool>("AOELoot.MailEnable", true))
{
player->SendItemRetrievalMail(item->itemid, item->count);
ChatHandler(player->GetSession()).SendSysMessage(AOE_ITEM_IN_THE_MAIL);
}
} }
else else
{ {
if (!player->HasItemCount(item->itemid, 1)) if (!player->HasItemCount(item.itemid, 1, true))
{ aoeLoot[item.itemid] = 1;
player->AddItem(item->itemid, item->count);
} }
player->SendNotifyLootItemRemoved(lootSlot); player->SendNotifyLootItemRemoved(item.itemIndex);
}
player->SendLootRelease(player->GetLootGUID()); player->SendLootRelease(player->GetLootGUID());
}
}
}
if (!loot->empty()) if (!loot->empty())
{ {
@@ -118,14 +126,59 @@ public:
_creature->AllLootRemovedFromCorpse(); _creature->AllLootRemovedFromCorpse();
} }
} }
}
for (auto const& [itemId, count] : aoeLoot)
{
if (!player->AddItem(itemId, count))
{
if (sConfigMgr->GetOption<bool>("AOELoot.MailEnable", true))
{
player->SendItemRetrievalMail(itemId, count);
ChatHandler(player->GetSession()).SendSysMessage(AOE_ITEM_IN_THE_MAIL);
}
}
}
if (player->GetGroup())
{
Group* group = player->GetGroup();
std::vector<Player*> playersNear;
for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
{
Player* member = itr->GetSource();
if (!member)
continue;
if (player->IsAtLootRewardDistance(member))
playersNear.push_back(member);
}
uint32 goldPerPlayer = uint32((gold) / (playersNear.size()));
for (std::vector<Player*>::const_iterator i = playersNear.begin(); i != playersNear.end(); ++i)
{
(*i)->ModifyMoney(goldPerPlayer);
(*i)->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, goldPerPlayer);
WorldPacket data(SMSG_LOOT_MONEY_NOTIFY, 4 + 1);
data << uint32(goldPerPlayer);
data << uint8(playersNear.size() > 1 ? 0 : 1);
(*i)->GetSession()->SendPacket(&data);
}
}
else
{
player->ModifyMoney(gold); player->ModifyMoney(gold);
player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, gold); player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, gold);
WorldPacket data(SMSG_LOOT_MONEY_NOTIFY, 4 + 1); WorldPacket data(SMSG_LOOT_MONEY_NOTIFY, 4 + 1);
data << uint32(gold); data << uint32(gold);
data << uint8(1); data << uint8(1);
player->GetSession()->SendPacket(&data); player->GetSession()->SendPacket(&data);
} }
}
void OnAfterCreatureLoot(Player* player) override void OnAfterCreatureLoot(Player* player) override
{ {