Core/Loot: Fixed gold looting messege sent to player while in group

This commit is contained in:
NoFantasy
2011-05-29 14:32:46 +02:00
committed by Shauren
parent 1d8b298d8e
commit ab15d2526f
@@ -98,33 +98,33 @@ void WorldSession::HandleLootMoneyOpcode(WorldPacket & /*recv_data*/)
{ {
sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_LOOT_MONEY"); sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_LOOT_MONEY");
Player *player = GetPlayer(); Player* player = GetPlayer();
uint64 guid = player->GetLootGUID(); uint64 guid = player->GetLootGUID();
if (!guid) if (!guid)
return; return;
Loot *pLoot = NULL; Loot* loot = NULL;
bool shareMoney = true; bool shareMoney = true;
switch(GUID_HIPART(guid)) switch(GUID_HIPART(guid))
{ {
case HIGHGUID_GAMEOBJECT: case HIGHGUID_GAMEOBJECT:
{ {
GameObject *pGameObject = GetPlayer()->GetMap()->GetGameObject(guid); GameObject* go = GetPlayer()->GetMap()->GetGameObject(guid);
// not check distance for GO in case owned GO (fishing bobber case, for example) // do not check distance for GO if player is the owner of it (ex. fishing bobber)
if (pGameObject && ((pGameObject->GetOwnerGUID() == _player->GetGUID() || pGameObject->IsWithinDistInMap(_player, INTERACTION_DISTANCE)))) if (go && ((go->GetOwnerGUID() == player->GetGUID() || go->IsWithinDistInMap(player, INTERACTION_DISTANCE))))
pLoot = &pGameObject->loot; loot = &go->loot;
break; break;
} }
case HIGHGUID_CORPSE: // remove insignia ONLY in BG case HIGHGUID_CORPSE: // remove insignia ONLY in BG
{ {
Corpse *bones = ObjectAccessor::GetCorpse(*GetPlayer(), guid); Corpse* bones = ObjectAccessor::GetCorpse(*player, guid);
if (bones && bones->IsWithinDistInMap(_player, INTERACTION_DISTANCE)) if (bones && bones->IsWithinDistInMap(player, INTERACTION_DISTANCE))
{ {
pLoot = &bones->loot; loot = &bones->loot;
shareMoney = false; shareMoney = false;
} }
@@ -132,67 +132,72 @@ void WorldSession::HandleLootMoneyOpcode(WorldPacket & /*recv_data*/)
} }
case HIGHGUID_ITEM: case HIGHGUID_ITEM:
{ {
if (Item *item = GetPlayer()->GetItemByGuid(guid)) if (Item* item = player->GetItemByGuid(guid))
{ {
pLoot = &item->loot; loot = &item->loot;
shareMoney = false; shareMoney = false;
} }
break; break;
} }
case HIGHGUID_UNIT: case HIGHGUID_UNIT:
{ {
Creature* pCreature = GetPlayer()->GetMap()->GetCreature(guid); Creature* creature = player->GetMap()->GetCreature(guid);
bool lootAllowed = creature && creature->isAlive() == (player->getClass() == CLASS_ROGUE && creature->lootForPickPocketed);
bool ok_loot = pCreature && pCreature->isAlive() == (player->getClass() == CLASS_ROGUE && pCreature->lootForPickPocketed); if (lootAllowed && creature->IsWithinDistInMap(player, INTERACTION_DISTANCE))
if (ok_loot && pCreature->IsWithinDistInMap(_player, INTERACTION_DISTANCE))
{ {
pLoot = &pCreature->loot ; loot = &creature->loot;
if (pCreature->isAlive()) if (creature->isAlive())
shareMoney = false; shareMoney = false;
} }
break; break;
} }
default: default:
return; // unlootable type return; // unlootable type
} }
if (pLoot) if (loot)
{ {
if (shareMoney && player->GetGroup()) //item, pickpocket and players can be looted only single player if (shareMoney && player->GetGroup()) //item, pickpocket and players can be looted only single player
{ {
Group *group = player->GetGroup(); Group* group = player->GetGroup();
std::vector<Player*> playersNear; std::vector<Player*> playersNear;
for (GroupReference *itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
{ {
Player* playerGroup = itr->getSource(); Player* member = itr->getSource();
if (!playerGroup) if (!member)
continue; continue;
if (player->IsWithinDistInMap(playerGroup, sWorld->getFloatConfig(CONFIG_GROUP_XP_DISTANCE), false))
playersNear.push_back(playerGroup); if (player->IsWithinDistInMap(member, sWorld->getFloatConfig(CONFIG_GROUP_XP_DISTANCE), false))
playersNear.push_back(member);
} }
uint32 money_per_player = uint32((pLoot->gold)/(playersNear.size())); uint32 goldPerPlayer = uint32((loot->gold) / (playersNear.size()));
for (std::vector<Player*>::const_iterator i = playersNear.begin(); i != playersNear.end(); ++i) for (std::vector<Player*>::const_iterator i = playersNear.begin(); i != playersNear.end(); ++i)
{ {
(*i)->ModifyMoney(money_per_player);
(*i)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, money_per_player);
//Offset surely incorrect, but works
WorldPacket data(SMSG_LOOT_MONEY_NOTIFY, 4); WorldPacket data(SMSG_LOOT_MONEY_NOTIFY, 4);
data << uint32(money_per_player); data << uint32(goldPerPlayer);
data << uint8(0); // Controls the text displayed 0 is "Your share is...", 1 "You loot..."
(*i)->GetSession()->SendPacket(&data); (*i)->GetSession()->SendPacket(&data);
(*i)->ModifyMoney(goldPerPlayer);
(*i)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, goldPerPlayer);
} }
} }
else else
{ {
player->ModifyMoney(pLoot->gold); WorldPacket data(SMSG_LOOT_MONEY_NOTIFY, 4);
player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, pLoot->gold); data << uint32(loot->gold);
data << uint8(1);
SendPacket(&data);
player->ModifyMoney(loot->gold);
player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, loot->gold);
} }
pLoot->gold = 0;
pLoot->NotifyMoneyRemoved(); loot->gold = 0;
loot->NotifyMoneyRemoved();
} }
} }