Skip to content

Commit

Permalink
feat. Modifying the module logic (azerothcore#21)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
pangolp authored Feb 6, 2024
1 parent 42cc6e6 commit c5bfaf4
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 46 deletions.
8 changes: 8 additions & 0 deletions conf/mod_aoe_loot.conf.dist
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,11 @@ AOELoot.Enable = 1
#

AOELoot.MailEnable = 1

#
# AOELoot.Range
# Description: Maximum reach range search loot.
# Default: 30.0
#

AOELoot.Range = 30.0
145 changes: 99 additions & 46 deletions src/AoeLoot_SC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ enum AoeLootString
AOE_ITEM_IN_THE_MAIL
};

typedef std::map<uint32, uint32> AOEContainer;

class AoeLoot_Player : public PlayerScript
{
public:
Expand All @@ -50,81 +52,132 @@ class AoeLoot_Player : public PlayerScript
{
bool _enable = sConfigMgr->GetOption<bool>("AOELoot.Enable", true);

if ((player->GetGroup() && (player->GetGroup()->GetLootMethod() != FREE_FOR_ALL)) || !_enable)
if (!_enable)
return;

float range = 30.0f;
float range = sConfigMgr->GetOption<float>("AOELoot.Range", 30.0);

uint32 gold = 0;

std::list<Creature*> creaturedie;
player->GetDeadCreatureListInGrid(creaturedie, range);
std::list<Creature*> deadCreatures;
deadCreatures.clear();
AOEContainer aoeLoot;
player->GetDeadCreatureListInGrid(deadCreatures, range, false);

for (auto const& _creature : creaturedie)
for (auto& _creature : deadCreatures)
{
Loot* loot = &_creature->loot;
gold += loot->gold;
loot->gold = 0;
uint8 lootSlot = 0;
uint32 maxSlot = loot->GetMaxSlotInLootFor(player);
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);
}
}

for (uint32 i = 0; i < maxSlot; ++i)
if (player == _creature->GetLootRecipient() && (_creature->HasDynamicFlag(UNIT_DYNFLAG_LOOTABLE)))
{
if (LootItem* item = loot->LootItemInSlot(i, player))
Loot* loot = &_creature->loot;
gold += loot->gold;
loot->gold = 0;

for (auto const& item : loot->items)
{
ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(item->itemid);
if (loot->items.size() > 1 && (loot->items[item.itemIndex].itemid == loot->items[item.itemIndex + 1].itemid))
continue;

ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(item.itemid);

if (itemTemplate->MaxCount != 1)
{
if (player->AddItem(item->itemid, 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);
}
aoeLoot[item.itemid] += (uint32)item.count;
}
else
{
if (!player->HasItemCount(item->itemid, 1))
if (!player->HasItemCount(item.itemid, 1, true))
aoeLoot[item.itemid] = 1;
}
player->SendNotifyLootItemRemoved(item.itemIndex);
}

player->SendLootRelease(player->GetLootGUID());

if (!loot->empty())
{
if (!_creature->IsAlive())
{
_creature->AllLootRemovedFromCorpse();
_creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
loot->clear();

if (_creature->HasUnitFlag(UNIT_FLAG_SKINNABLE))
{
player->AddItem(item->itemid, item->count);
_creature->RemoveUnitFlag(UNIT_FLAG_SKINNABLE);
}
player->SendNotifyLootItemRemoved(lootSlot);
player->SendLootRelease(player->GetLootGUID());
}
}
else
{
_creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
_creature->AllLootRemovedFromCorpse();
}
}
}

if (!loot->empty())
for (auto const& [itemId, count] : aoeLoot)
{
if (!player->AddItem(itemId, count))
{
if (!_creature->IsAlive())
if (sConfigMgr->GetOption<bool>("AOELoot.MailEnable", true))
{
_creature->AllLootRemovedFromCorpse();
_creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
loot->clear();

if (_creature->HasUnitFlag(UNIT_FLAG_SKINNABLE))
{
_creature->RemoveUnitFlag(UNIT_FLAG_SKINNABLE);
}
player->SendItemRetrievalMail(itemId, count);
ChatHandler(player->GetSession()).SendSysMessage(AOE_ITEM_IN_THE_MAIL);
}
}
else
}

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)
{
_creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
_creature->AllLootRemovedFromCorpse();
(*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->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, gold);

player->ModifyMoney(gold);
player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, gold);
WorldPacket data(SMSG_LOOT_MONEY_NOTIFY, 4 + 1);
data << uint32(gold);
data << uint8(1);
player->GetSession()->SendPacket(&data);
WorldPacket data(SMSG_LOOT_MONEY_NOTIFY, 4 + 1);
data << uint32(gold);
data << uint8(1);
player->GetSession()->SendPacket(&data);
}
}

void OnAfterCreatureLoot(Player* player) override
Expand Down

0 comments on commit c5bfaf4

Please sign in to comment.