void WorldSession::HandleLootMoneyOpcode( WorldPacket & /*recv_data*/ ) { DEBUG_LOG("WORLD: CMSG_LOOT_MONEY"); Player *player = GetPlayer(); ObjectGuid guid = player->GetLootGUID(); if (guid.IsEmpty()) return; Loot *pLoot = NULL; switch(guid.GetHigh()) { case HIGHGUID_GAMEOBJECT: { GameObject *pGameObject = GetPlayer()->GetMap()->GetGameObject(guid); // not check distance for GO in case owned GO (fishing bobber case, for example) if( pGameObject && (pGameObject->GetOwnerGUID()==_player->GetGUID() || pGameObject->IsWithinDistInMap(_player,INTERACTION_DISTANCE)) ) pLoot = &pGameObject->loot; break; } case HIGHGUID_CORPSE: // remove insignia ONLY in BG { Corpse *bones = _player->GetMap()->GetCorpse(guid); if (bones && bones->IsWithinDistInMap(_player,INTERACTION_DISTANCE) ) pLoot = &bones->loot; break; } case HIGHGUID_ITEM: { if(Item *item = GetPlayer()->GetItemByGuid(guid)) pLoot = &item->loot; break; } case HIGHGUID_UNIT: { Creature* pCreature = GetPlayer()->GetMap()->GetCreature(guid); bool ok_loot = pCreature && pCreature->isAlive() == (player->getClass()==CLASS_ROGUE && pCreature->lootForPickPocketed); if ( ok_loot && pCreature->IsWithinDistInMap(_player,INTERACTION_DISTANCE) ) pLoot = &pCreature->loot ; break; } default: return; // unlootable type } if (pLoot) { if (!guid.IsItem() && player->GetGroup()) //item can be looted only single player { Group *group = player->GetGroup(); std::vector<Player*> playersNear; for(GroupReference *itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* playerGroup = itr->getSource(); if(!playerGroup) continue; if (player->IsWithinDistInMap(playerGroup,sWorld.getConfig(CONFIG_FLOAT_GROUP_XP_DISTANCE),false)) playersNear.push_back(playerGroup); } uint32 money_per_player = uint32((pLoot->gold)/(playersNear.size())); 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 ); data << uint32(money_per_player); (*i)->GetSession()->SendPacket( &data ); } } else { player->ModifyMoney( pLoot->gold ); player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, pLoot->gold); } pLoot->gold = 0; pLoot->NotifyMoneyRemoved(); } }
void WorldSession::HandleLootMoneyOpcode(WorldPacket& /*recvData*/) { TC_LOG_DEBUG("network", "WORLD: CMSG_LOOT_MONEY"); Player* player = GetPlayer(); uint64 guid = player->GetLootGUID(); if (!guid) return; Loot* loot = NULL; bool shareMoney = true; switch (GUID_HIPART(guid)) { case HIGHGUID_GAMEOBJECT: { GameObject* go = GetPlayer()->GetMap()->GetGameObject(guid); // do not check distance for GO if player is the owner of it (ex. fishing bobber) if (go && ((go->GetOwnerGUID() == player->GetGUID() || go->IsWithinDistInMap(player, INTERACTION_DISTANCE)))) loot = &go->loot; break; } case HIGHGUID_CORPSE: // remove insignia ONLY in BG { Corpse* bones = ObjectAccessor::GetCorpse(*player, guid); if (bones && bones->IsWithinDistInMap(player, INTERACTION_DISTANCE)) { loot = &bones->loot; shareMoney = false; } break; } case HIGHGUID_ITEM: { if (Item* item = player->GetItemByGuid(guid)) { loot = &item->loot; shareMoney = false; } break; } case HIGHGUID_UNIT: case HIGHGUID_VEHICLE: { Creature* creature = player->GetMap()->GetCreature(guid); bool lootAllowed = creature && creature->IsAlive() == (player->getClass() == CLASS_ROGUE && creature->lootForPickPocketed); if (lootAllowed && creature->IsWithinDistInMap(player, INTERACTION_DISTANCE)) { loot = &creature->loot; if (creature->IsAlive()) shareMoney = false; } break; } default: return; // unlootable type } if (loot) { loot->NotifyMoneyRemoved(); if (shareMoney && player->GetGroup()) //item, pickpocket and players can be looted only single player { Group* group = player->GetGroup(); std::vector<Player*> playersNear; for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* member = itr->GetSource(); if (!member) continue; if (player->IsWithinDistInMap(member, sWorld->getFloatConfig(CONFIG_GROUP_XP_DISTANCE), false)) playersNear.push_back(member); } uint32 goldPerPlayer = uint32((loot->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); if (Guild* guild = sGuildMgr->GetGuildById((*i)->GetGuildId())) if (uint32 guildGold = CalculatePct(goldPerPlayer, (*i)->GetTotalAuraModifier(SPELL_AURA_DEPOSIT_BONUS_MONEY_IN_GUILD_BANK_ON_LOOT))) guild->HandleMemberDepositMoney(this, guildGold, true); WorldPacket data(SMSG_LOOT_MONEY_NOTIFY, 4 + 1); data << uint32(goldPerPlayer); data << uint8(playersNear.size() <= 1); // Controls the text displayed in chat. 0 is "Your share is..." and 1 is "You loot..." (*i)->GetSession()->SendPacket(&data); } } else { player->ModifyMoney(loot->gold); player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, loot->gold); if (Guild* guild = sGuildMgr->GetGuildById(player->GetGuildId())) if (uint32 guildGold = CalculatePct(loot->gold, player->GetTotalAuraModifier(SPELL_AURA_DEPOSIT_BONUS_MONEY_IN_GUILD_BANK_ON_LOOT))) guild->HandleMemberDepositMoney(this, guildGold, true); WorldPacket data(SMSG_LOOT_MONEY_NOTIFY, 4 + 1); data << uint32(loot->gold); data << uint8(1); // "You loot..." SendPacket(&data); } #ifdef ELUNA sHookMgr->OnLootMoney(player, loot->gold); #endif loot->gold = 0; // Delete the money loot record from the DB if (loot->containerID > 0) loot->DeleteLootMoneyFromContainerItemDB(); // Delete container if empty if (loot->isLooted() && IS_ITEM_GUID(guid)) player->GetSession()->DoLootRelease(guid); } }
void WorldSession::HandleLootMoneyOpcode(WorldPacket & /*recv_data*/) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_LOOT_MONEY"); Player* player = GetPlayer(); uint64 guid = player->GetLootGUID(); if (!guid) return; Loot* loot = NULL; bool shareMoney = true; switch (GUID_HIPART(guid)) { case HIGHGUID_GAMEOBJECT: { GameObject* go = GetPlayer()->GetMap()->GetGameObject(guid); // do not check distance for GO if player is the owner of it (ex. fishing bobber) if (go && ((go->GetOwnerGUID() == player->GetGUID() || go->IsWithinDistInMap(player, INTERACTION_DISTANCE)))) loot = &go->loot; break; } case HIGHGUID_CORPSE: // remove insignia ONLY in BG { Corpse* bones = ObjectAccessor::GetCorpse(*player, guid); if (bones && bones->IsWithinDistInMap(player, INTERACTION_DISTANCE)) { loot = &bones->loot; shareMoney = false; } break; } case HIGHGUID_ITEM: { if (Item* item = player->GetItemByGuid(guid)) { loot = &item->loot; shareMoney = false; } break; } case HIGHGUID_UNIT: { Creature* creature = player->GetMap()->GetCreature(guid); bool lootAllowed = creature && creature->isAlive() == (player->getClass() == CLASS_ROGUE && creature->lootForPickPocketed); if (lootAllowed && creature->IsWithinDistInMap(player, INTERACTION_DISTANCE)) { loot = &creature->loot; if (creature->isAlive()) shareMoney = false; } break; } default: return; // unlootable type } if (loot) { loot->NotifyMoneyRemoved(); if (shareMoney && player->GetGroup()) //item, pickpocket and players can be looted only single player { Group* group = player->GetGroup(); std::vector<Player*> playersNear; for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* member = itr->getSource(); if (!member) continue; if (player->IsWithinDistInMap(member, sWorld->getFloatConfig(CONFIG_GROUP_XP_DISTANCE), false)) playersNear.push_back(member); } uint32 goldPerPlayer = uint32((loot->gold) / (playersNear.size())); for (std::vector<Player*>::const_iterator i = playersNear.begin(); i != playersNear.end(); ++i) { (*i)->ModifyMoney(goldPerPlayer); WorldPacket data(SMSG_LOOT_MONEY_NOTIFY, 4 + 1); data << uint32(goldPerPlayer); data << uint8(playersNear.size() > 1 ? 0 : 1); // Controls the text displayed in chat. 0 is "Your share is..." and 1 is "You loot..." (*i)->GetSession()->SendPacket(&data); } } else { player->ModifyMoney(loot->gold); WorldPacket data(SMSG_LOOT_MONEY_NOTIFY, 4 + 1); data << uint32(loot->gold); data << uint8(1); // "You loot..." SendPacket(&data); } loot->gold = 0; } }
void WorldSession::HandleLootMoneyOpcode(WorldPacket& /*recvData*/) { TC_LOG_DEBUG("network", "WORLD: CMSG_LOOT_MONEY"); Player* player = GetPlayer(); ObjectGuid guid = player->GetLootGUID(); if (!guid) return; Loot* loot = nullptr; bool shareMoney = true; switch (guid.GetHigh()) { case HighGuid::GameObject: { GameObject* go = GetPlayer()->GetMap()->GetGameObject(guid); // do not check distance for GO if player is the owner of it (ex. fishing bobber) if (go && ((go->GetOwnerGUID() == player->GetGUID() || go->IsWithinDistInMap(player, INTERACTION_DISTANCE)))) loot = &go->loot; break; } case HighGuid::Corpse: // remove insignia ONLY in BG { Corpse* bones = ObjectAccessor::GetCorpse(*player, guid); if (bones && bones->IsWithinDistInMap(player, INTERACTION_DISTANCE)) { loot = &bones->loot; shareMoney = false; } break; } case HighGuid::Item: { if (Item* item = player->GetItemByGuid(guid)) { loot = &item->loot; shareMoney = false; } break; } case HighGuid::Unit: case HighGuid::Vehicle: { Creature* creature = player->GetMap()->GetCreature(guid); bool lootAllowed = creature && creature->IsAlive() == (player->getClass() == CLASS_ROGUE && creature->loot.loot_type == LOOT_PICKPOCKETING); if (lootAllowed && creature->IsWithinDistInMap(player, INTERACTION_DISTANCE)) { loot = &creature->loot; if (creature->IsAlive()) shareMoney = false; } else player->SendLootError(guid, lootAllowed ? LOOT_ERROR_TOO_FAR : LOOT_ERROR_DIDNT_KILL); break; } default: return; // unlootable type } if (loot) { loot->NotifyMoneyRemoved(); if (shareMoney && player->GetGroup()) //item, pickpocket and players can be looted only single player { 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->IsAtGroupRewardDistance(member)) playersNear.push_back(member); } uint32 goldPerPlayer = uint32((loot->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); // Controls the text displayed in chat. 0 is "Your share is..." and 1 is "You loot..." (*i)->SendDirectMessage(&data); } } else { player->ModifyMoney(loot->gold); player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, loot->gold); WorldPacket data(SMSG_LOOT_MONEY_NOTIFY, 4 + 1); data << uint32(loot->gold); data << uint8(1); // "You loot..." SendPacket(&data); } loot->gold = 0; // Delete the money loot record from the DB if (loot->containerID > 0) sLootItemStorage->RemoveStoredMoneyForContainer(loot->containerID); // Delete container if empty if (loot->isLooted() && guid.IsItem()) player->GetSession()->DoLootRelease(guid); } }
void WorldSession::HandleLootMoneyOpcode(WorldPackets::Loot::LootMoney& /*packet*/) { TC_LOG_DEBUG("network", "WORLD: CMSG_LOOT_MONEY"); Player* player = GetPlayer(); ObjectGuid guid = player->GetLootGUID(); if (!guid) return; Loot* loot = NULL; bool shareMoney = true; switch (guid.GetHigh()) { case HighGuid::GameObject: { GameObject* go = GetPlayer()->GetMap()->GetGameObject(guid); // do not check distance for GO if player is the owner of it (ex. fishing bobber) if (go && ((go->GetOwnerGUID() == player->GetGUID() || go->IsWithinDistInMap(player, INTERACTION_DISTANCE)))) loot = &go->loot; break; } case HighGuid::Corpse: // remove insignia ONLY in BG { Corpse* bones = ObjectAccessor::GetCorpse(*player, guid); if (bones && bones->IsWithinDistInMap(player, INTERACTION_DISTANCE)) { loot = &bones->loot; shareMoney = false; } break; } case HighGuid::Item: { if (Item* item = player->GetItemByGuid(guid)) { loot = &item->loot; shareMoney = false; } break; } case HighGuid::Creature: case HighGuid::Vehicle: { Creature* creature = player->GetMap()->GetCreature(guid); bool lootAllowed = creature && creature->IsAlive() == (player->getClass() == CLASS_ROGUE && creature->loot.loot_type == LOOT_PICKPOCKETING); if (lootAllowed && creature->IsWithinDistInMap(player, INTERACTION_DISTANCE)) { loot = &creature->loot; if (creature->IsAlive()) shareMoney = false; } else player->SendLootError(guid, lootAllowed ? LOOT_ERROR_TOO_FAR : LOOT_ERROR_DIDNT_KILL); break; } default: return; // unlootable type } if (loot) { loot->NotifyMoneyRemoved(); if (shareMoney && player->GetGroup()) //item, pickpocket and players can be looted only single player { Group* group = player->GetGroup(); std::vector<Player*> playersNear; for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* member = itr->GetSource(); if (!member) continue; if (player->IsWithinDistInMap(member, sWorld->getFloatConfig(CONFIG_GROUP_XP_DISTANCE), false)) playersNear.push_back(member); } uint32 goldPerPlayer = uint32((loot->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); if (Guild* guild = sGuildMgr->GetGuildById((*i)->GetGuildId())) if (uint32 guildGold = CalculatePct(goldPerPlayer, (*i)->GetTotalAuraModifier(SPELL_AURA_DEPOSIT_BONUS_MONEY_IN_GUILD_BANK_ON_LOOT))) guild->HandleMemberDepositMoney(this, guildGold, true); WorldPackets::Loot::LootMoneyNotify packet; packet.Money = goldPerPlayer; packet.SoleLooter = playersNear.size() <= 1 ? true : false; (*i)->SendDirectMessage(packet.Write()); } } else { player->ModifyMoney(loot->gold); player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, loot->gold); if (Guild* guild = sGuildMgr->GetGuildById(player->GetGuildId())) if (uint32 guildGold = CalculatePct(loot->gold, player->GetTotalAuraModifier(SPELL_AURA_DEPOSIT_BONUS_MONEY_IN_GUILD_BANK_ON_LOOT))) guild->HandleMemberDepositMoney(this, guildGold, true); WorldPackets::Loot::LootMoneyNotify packet; packet.Money = loot->gold; packet.SoleLooter = true; // "You loot..." SendPacket(packet.Write()); } loot->gold = 0; // Delete the money loot record from the DB if (!loot->containerID.IsEmpty()) loot->DeleteLootMoneyFromContainerItemDB(); // Delete container if empty if (loot->isLooted() && guid.IsItem()) player->GetSession()->DoLootRelease(guid); } }
void WorldSession::HandleLootMoneyOpcode(WorldPacket& /*recv_data*/) { DEBUG_LOG("WORLD: CMSG_LOOT_MONEY"); Player* player = GetPlayer(); ObjectGuid guid = player->GetLootGuid(); if (!guid) { return; } Loot* pLoot = NULL; Item* pItem = NULL; switch (guid.GetHigh()) { case HIGHGUID_GAMEOBJECT: { GameObject* pGameObject = GetPlayer()->GetMap()->GetGameObject(guid); // not check distance for GO in case owned GO (fishing bobber case, for example) if (pGameObject && (pGameObject->GetOwnerGuid() == _player->GetObjectGuid() || pGameObject->IsWithinDistInMap(_player, INTERACTION_DISTANCE))) { pLoot = &pGameObject->loot; } break; } case HIGHGUID_CORPSE: // remove insignia ONLY in BG { Corpse* bones = _player->GetMap()->GetCorpse(guid); if (bones && bones->IsWithinDistInMap(_player, INTERACTION_DISTANCE)) { pLoot = &bones->loot; } break; } case HIGHGUID_ITEM: { pItem = GetPlayer()->GetItemByGuid(guid); if (!pItem || !pItem->HasGeneratedLoot()) { return; } pLoot = &pItem->loot; break; } case HIGHGUID_UNIT: { Creature* pCreature = GetPlayer()->GetMap()->GetCreature(guid); bool ok_loot = pCreature && pCreature->IsAlive() == (player->getClass() == CLASS_ROGUE && pCreature->lootForPickPocketed); if (ok_loot && pCreature->IsWithinDistInMap(_player, INTERACTION_DISTANCE)) { pLoot = &pCreature->loot ; } break; } default: return; // unlootable type } if (pLoot) { pLoot->NotifyMoneyRemoved(); if (!guid.IsItem() && player->GetGroup()) // item can be looted only single player { Group* group = player->GetGroup(); std::vector<Player*> playersNear; for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* playerGroup = itr->getSource(); if (!playerGroup) { continue; } if (player->IsWithinDistInMap(playerGroup, sWorld.getConfig(CONFIG_FLOAT_GROUP_XP_DISTANCE), false)) { playersNear.push_back(playerGroup); } } uint32 money_per_player = uint32((pLoot->gold) / (playersNear.size())); for (std::vector<Player*>::const_iterator i = playersNear.begin(); i != playersNear.end(); ++i) { (*i)->ModifyMoney(money_per_player); WorldPacket data(SMSG_LOOT_MONEY_NOTIFY, 4); data << uint32(money_per_player); (*i)->GetSession()->SendPacket(&data); } } else { player->ModifyMoney(pLoot->gold); } // Used by Eluna #ifdef ENABLE_ELUNA sEluna->OnLootMoney(player, pLoot->gold); #endif /* ENABLE_ELUNA */ pLoot->gold = 0; if (pItem) { pItem->SetLootState(ITEM_LOOT_CHANGED); } } }
void WorldSession::HandleLootMoneyOpcode(WorldPacket& /*recv_data*/) { sLog.outDebug("WORLD: CMSG_LOOT_MONEY"); Player* player = GetPlayer(); uint64 guid = player->GetLootGUID(); if (!guid) return; Loot* pLoot = NULL; bool shareMoney = true; switch (GUID_HIPART(guid)) { case HIGHGUID_GAMEOBJECT: { GameObject* pGameObject = GetPlayer()->GetMap()->GetGameObject(guid); // not check distance for GO in case owned GO (fishing bobber case, for example) if (pGameObject && ((pGameObject->GetOwnerGUID() == _player->GetGUID() || pGameObject->IsWithinDistInMap(_player, INTERACTION_DISTANCE)))) pLoot = &pGameObject->loot; break; } case HIGHGUID_CORPSE: // remove insignia ONLY in BG { Corpse* bones = ObjectAccessor::GetCorpse(*GetPlayer(), guid); if (bones && bones->IsWithinDistInMap(_player, INTERACTION_DISTANCE)) { pLoot = &bones->loot; shareMoney = false; } break; } case HIGHGUID_ITEM: { if (Item* item = GetPlayer()->GetItemByGuid(guid)) { pLoot = &item->loot; shareMoney = false; } break; } case HIGHGUID_UNIT: { Creature* creature = GetPlayer()->GetMap()->GetCreature(guid); bool ok_loot = creature && creature->IsAlive() == (player->getClass() == CLASS_ROGUE && creature->loot.loot_type == LOOT_SKINNING); if (ok_loot && creature->IsWithinDistInMap(_player, INTERACTION_DISTANCE)) { pLoot = &creature->loot; if (creature->IsAlive()) shareMoney = false; } else player->SendLootError(guid, ok_loot ? LOOT_ERROR_TOO_FAR : LOOT_ERROR_DIDNT_KILL); break; } default: return; // unlootable type } if (pLoot) { pLoot->NotifyMoneyRemoved(); if (shareMoney && player->GetGroup()) //item, pickpocket and players can be looted only single player { Group* group = player->GetGroup(); std::vector<Player*> playersNear; for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* playerGroup = itr->GetSource(); if (!playerGroup) continue; if (player->GetDistance2d(playerGroup) < sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE)) playersNear.push_back(playerGroup); } uint32 money_per_player = uint32((pLoot->gold) / (playersNear.size())); for (std::vector<Player*>::const_iterator i = playersNear.begin(); i != playersNear.end(); ++i) { (*i)->ModifyMoney(money_per_player); WorldPacket data(SMSG_LOOT_MONEY_NOTIFY, 4); data << uint32(money_per_player); (*i)->GetSession()->SendPacket(&data); } } else player->ModifyMoney(pLoot->gold); pLoot->gold = 0; } }
void WorldSession::HandleLootMoneyOpcode(WorldPacket& /*recv_data*/) { DEBUG_LOG("WORLD: CMSG_LOOT_MONEY"); Player* player = GetPlayer(); ObjectGuid guid = player->GetLootGuid(); if (!guid) return; Loot* pLoot = NULL; Item* pItem = NULL; switch (guid.GetHigh()) { case HIGHGUID_GAMEOBJECT: { GameObject* pGameObject = GetPlayer()->GetMap()->GetGameObject(guid); // not check distance for GO in case owned GO (fishing bobber case, for example) if (pGameObject && (pGameObject->GetOwnerGuid() == _player->GetObjectGuid() || pGameObject->IsWithinDistInMap(_player, INTERACTION_DISTANCE))) pLoot = &pGameObject->loot; break; } case HIGHGUID_CORPSE: // remove insignia ONLY in BG { Corpse* bones = _player->GetMap()->GetCorpse(guid); if (bones && bones->IsWithinDistInMap(_player, INTERACTION_DISTANCE)) pLoot = &bones->loot; break; } case HIGHGUID_ITEM: { pItem = GetPlayer()->GetItemByGuid(guid); if (!pItem || !pItem->HasGeneratedLoot()) return; pLoot = &pItem->loot; break; } case HIGHGUID_UNIT: case HIGHGUID_VEHICLE: { Creature* pCreature = GetPlayer()->GetMap()->GetCreature(guid); bool ok_loot = pCreature && pCreature->isAlive() == (player->getClass() == CLASS_ROGUE && pCreature->lootForPickPocketed); if (ok_loot && pCreature->IsWithinDistInMap(_player, INTERACTION_DISTANCE)) pLoot = &pCreature->loot ; break; } default: return; // unlootable type } if (pLoot) { pLoot->NotifyMoneyRemoved(); if (!guid.IsItem() && player->GetGroup()) // item can be looted only single player { Group* group = player->GetGroup(); std::vector<Player*> playersNear; for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* playerGroup = itr->getSource(); if (!playerGroup) continue; if (player->IsWithinDistInMap(playerGroup, sWorld.getConfig(CONFIG_FLOAT_GROUP_XP_DISTANCE), false)) playersNear.push_back(playerGroup); } if (playersNear.size() == 0) { sLog.outError("WorldSession::HandleLootMoneyOpcode %s try aquire group loot without any group member! Cheat attempt assumed.", player->GetObjectGuid().GetString().c_str()); return; } uint64 money_per_player = uint32((pLoot->gold) / (playersNear.size())); for (std::vector<Player*>::const_iterator i = playersNear.begin(); i != playersNear.end(); ++i) { (*i)->ModifyMoney(money_per_player); (*i)->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, money_per_player); if (Guild* guild = sGuildMgr.GetGuildById((*i)->GetGuildId())) if (uint32 guildGold = (*i)->GetTotalAuraModifier(SPELL_AURA_MOD_MONEY_TO_GUILD_BANK) / 100.0f * money_per_player) guild->HandleCashFlow(guildGold, *i); WorldPacket data(SMSG_LOOT_MONEY_NOTIFY, 4+1); data << uint32(money_per_player); data << uint8(playersNear.size() > 1 ? 0 : 1);// 0 is "you share of loot..." (*i)->GetSession()->SendPacket(&data); } } else { player->ModifyMoney(pLoot->gold); player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, pLoot->gold); if (Guild* guild = sGuildMgr.GetGuildById(player->GetGuildId())) if (uint32 guildGold = player->GetTotalAuraModifier(SPELL_AURA_MOD_MONEY_TO_GUILD_BANK) / 100.0f * pLoot->gold) guild->HandleCashFlow(guildGold, player); WorldPacket data(SMSG_LOOT_MONEY_NOTIFY, 4+1); data << uint32(pLoot->gold); data << uint8(1); // 1 is "you loot..." player->GetSession()->SendPacket(&data); } pLoot->gold = 0; if (pItem) pItem->SetLootState(ITEM_LOOT_CHANGED); } }