/*Loot type MUST be
1-corpse, go
2-skinning/herbalism/minning
3-Fishing
*/
void Player::SendLoot(uint64 guid, uint8 loot_type, uint32 mapid)
{
	Group* m_Group = m_playerInfo->m_Group;

	if(!IsInWorld())
		return;

	Loot* pLoot = NULL;
	uint32 guidtype = GET_TYPE_FROM_GUID(guid);

	int8 loot_method;

	if(m_Group != NULL)
		loot_method = m_Group->GetMethod();
	else
		loot_method = PARTY_LOOT_FFA;

	if(guidtype == HIGHGUID_TYPE_UNIT)
	{
		Creature* pCreature = GetMapMgr()->GetCreature(GET_LOWGUID_PART(guid));
		if(!pCreature)return;
		pLoot = &pCreature->loot;
		m_currentLoot = pCreature->GetGUID();

	}
	else if(guidtype == HIGHGUID_TYPE_GAMEOBJECT)
	{
		GameObject* pGO = GetMapMgr()->GetGameObject(GET_LOWGUID_PART(guid));
		if(!pGO)return;
		pGO->SetByte(GAMEOBJECT_BYTES_1, 0, 0);
		pLoot = &pGO->loot;
		m_currentLoot = pGO->GetGUID();
	}
	else if((guidtype == HIGHGUID_TYPE_PLAYER))
	{
		Player* p = GetMapMgr()->GetPlayer((uint32)guid);
		if(!p)return;
		pLoot = &p->loot;
		m_currentLoot = p->GetGUID();
	}
	else if((guidtype == HIGHGUID_TYPE_CORPSE))
	{
		Corpse* pCorpse = objmgr.GetCorpse((uint32)guid);
		if(!pCorpse)return;
		pLoot = &pCorpse->loot;
		m_currentLoot = pCorpse->GetGUID();
	}
	else if((guidtype == HIGHGUID_TYPE_ITEM))
	{
		Item* pItem = GetItemInterface()->GetItemByGUID(guid);
		if(!pItem)
			return;
		pLoot = pItem->loot;
		m_currentLoot = pItem->GetGUID();
	}

	if(!pLoot)
	{
		// something whack happened.. damn cheaters..
		return;
	}

	// add to looter set
	pLoot->looters.insert(GetLowGUID());

	WorldPacket data, data2(32);
	data.SetOpcode(SMSG_LOOT_RESPONSE);


	m_lootGuid = guid;


	data << uint64(guid);
	data << uint8(loot_type);  //loot_type;
	data << uint32(pLoot->gold);
	data << uint8(0);   //loot size reserve


	std::vector<__LootItem>::iterator iter = pLoot->items.begin();
	uint32 count = 0;
	uint8 slottype = 0;

	for(uint32 x = 0; iter != pLoot->items.end(); iter++, x++)
	{
		if(iter->iItemsCount == 0)
			continue;

		LooterSet::iterator itr = iter->has_looted.find(GetLowGUID());
		if(iter->has_looted.end() != itr)
			continue;

		ItemPrototype* itemProto = iter->item.itemproto;
		if(!itemProto)
			continue;

		// check if it's on ML if so only quest items and ffa loot should be shown based on mob
		if(loot_method == PARTY_LOOT_MASTER && m_Group && m_Group->GetLooter() != m_playerInfo)
			// pass on all ffa_loot and the grey / white items
			if(!iter->ffa_loot && !(itemProto->Quality < m_Group->GetThreshold()))
				continue;

		// team check
		if( itemProto->HasFlag2(ITEM_FLAG2_HORDE_ONLY) && IsTeamAlliance() ) 
			continue; 

		if( itemProto->HasFlag2(ITEM_FLAG2_ALLIANCE_ONLY) && IsTeamHorde() ) 
			continue;

		//quest items check. type 4/5
		//quest items that don't start quests.
		if((itemProto->Bonding == ITEM_BIND_QUEST) && !(itemProto->QuestId) && !HasQuestForItem(itemProto->ItemId))
			continue;
		if((itemProto->Bonding == ITEM_BIND_QUEST2) && !(itemProto->QuestId) && !HasQuestForItem(itemProto->ItemId))
			continue;

		//quest items that start quests need special check to avoid drops all the time.
		if((itemProto->Bonding == ITEM_BIND_QUEST) && (itemProto->QuestId) && GetQuestLogForEntry(itemProto->QuestId))
			continue;
		if((itemProto->Bonding == ITEM_BIND_QUEST2) && (itemProto->QuestId) && GetQuestLogForEntry(itemProto->QuestId))
			continue;

		if((itemProto->Bonding == ITEM_BIND_QUEST) && (itemProto->QuestId) && HasFinishedQuest(itemProto->QuestId))
			continue;
		if((itemProto->Bonding == ITEM_BIND_QUEST2) && (itemProto->QuestId) && HasFinishedQuest(itemProto->QuestId))
			continue;

		//check for starting item quests that need questlines.
		if((itemProto->QuestId && itemProto->Bonding != ITEM_BIND_QUEST && itemProto->Bonding != ITEM_BIND_QUEST2))
		{
			Quest* pQuest = QuestStorage.LookupEntry(itemProto->QuestId);
			if(pQuest)
			{
				uint32 finishedCount = 0;

				//check if its a questline.
				for(uint32 i = 0; i < pQuest->count_requiredquests; i++)
				{
					if(pQuest->required_quests[i])
					{
						if(!HasFinishedQuest(pQuest->required_quests[i]) || GetQuestLogForEntry(pQuest->required_quests[i]))
						{

						}
						else
						{
							finishedCount++;
						}
					}
				}
			}
		}

		slottype = 0;
		if(m_Group != NULL && loot_type < 2)
		{
			switch(loot_method)
			{
				case PARTY_LOOT_MASTER:
					slottype = 2;
					break;
				case PARTY_LOOT_GROUP:
				case PARTY_LOOT_RR:
				case PARTY_LOOT_NBG:
					slottype = 1;
					break;
				default:
					slottype = 0;
					break;
			}
			// only quality items are distributed
			if(itemProto->Quality < m_Group->GetThreshold())
			{
				slottype = 0;
			}

			// if all people passed anyone can loot it? :P
			if(iter->passed)
				slottype = 0;					// All players passed on the loot

			//if it is ffa loot and not an masterlooter
			if(iter->ffa_loot)
				slottype = 0;
		}

		data << uint8(x);
		data << uint32(itemProto->ItemId);
		data << uint32(iter->iItemsCount);  //nr of items of this type
		data << uint32(iter->item.displayid);

		if(iter->iRandomSuffix)
		{
			data << uint32(Item::GenerateRandomSuffixFactor(itemProto));
			data << uint32(-int32(iter->iRandomSuffix->id));
		}
		else if(iter->iRandomProperty)
		{
			data << uint32(0);
			data << uint32(iter->iRandomProperty->ID);
		}
		else
		{
			data << uint32(0);
			data << uint32(0);
		}

		data << slottype;   // "still being rolled for" flag

		if(slottype == 1)
		{
			if(iter->roll == NULL && !iter->passed)
			{
				int32 ipid = 0;
				uint32 factor = 0;
				if(iter->iRandomProperty)
					ipid = iter->iRandomProperty->ID;
				else if(iter->iRandomSuffix)
				{
					ipid = -int32(iter->iRandomSuffix->id);
					factor = Item::GenerateRandomSuffixFactor(iter->item.itemproto);
				}

				if(iter->item.itemproto)
				{
					iter->roll = new LootRoll(60000, (m_Group != NULL ? m_Group->MemberCount() : 1),  guid, x, itemProto->ItemId, factor, uint32(ipid), GetMapMgr());
					data2.Initialize(SMSG_LOOT_START_ROLL);
					data2 << guid;
					data2 << uint32(mapid);
					data2 << uint32(x);
					data2 << uint32(itemProto->ItemId);
					data2 << uint32(factor);
					if(iter->iRandomProperty)
						data2 << uint32(iter->iRandomProperty->ID);
					else if(iter->iRandomSuffix)
						data2 << uint32(ipid);
					else
						data2 << uint32(0);

					data2 << uint32(iter->iItemsCount);
					data2 << uint32(60000);	// countdown
					data2 << uint8(7);		// some sort of flags that require research
				}

				Group* pGroup = m_playerInfo->m_Group;
				if(pGroup)
				{
					pGroup->Lock();
					for(uint32 i = 0; i < pGroup->GetSubGroupCount(); ++i)
					{
						for(GroupMembersSet::iterator itr2 = pGroup->GetSubGroup(i)->GetGroupMembersBegin(); itr2 != pGroup->GetSubGroup(i)->GetGroupMembersEnd(); ++itr2)
						{

							PlayerInfo* pinfo = *itr2;

							if(pinfo->m_loggedInPlayer && pinfo->m_loggedInPlayer->GetItemInterface()->CanReceiveItem(itemProto, iter->iItemsCount) == 0)
							{
								if(pinfo->m_loggedInPlayer->m_passOnLoot)
									iter->roll->PlayerRolled(pinfo->m_loggedInPlayer, 3);		// passed
								else
									pinfo->m_loggedInPlayer->SendPacket(&data2);
							}
							else
								iter->roll->OfflineRoll(pinfo->guid);
						}
					}
					pGroup->Unlock();
				}
				else
				{
					m_session->SendPacket(&data2);
				}
			}
		}
		count++;
	}
	data.wpos(13);
	data << uint8(count);

	m_session->SendPacket(&data);

	SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_LOOTING);
}