Пример #1
0
bool ChatHandler::HandleAddInvItemCommand(const char *args, WorldSession *m_session)
{
	uint32 itemid, count=1;
	int32 randomprop=0;

	if(strlen(args) < 1)
	{
		return false;
	}

	if(sscanf(args, "%u %u %d", &itemid, &count, &randomprop) < 1)
		return false;

	Player * chr = getSelectedChar( m_session, false );
	if ( chr == NULL )
		chr = m_session->GetPlayer();
	
	ItemPrototype* it = ItemPrototypeStorage.LookupEntry(itemid);
	if(it)
	{
		sGMLog.writefromsession(m_session, "used add item command, item id %u [%s] to %s", it->ItemId, it->Name1, chr->GetName());
		Item *item;
		item = objmgr.CreateItem( itemid, chr);
		item->SetUInt32Value(ITEM_FIELD_STACK_COUNT, ((count > it->MaxCount) ? it->MaxCount : count));
		if(it->Bonding==ITEM_BIND_ON_PICKUP)
			item->SoulBind();
		if(randomprop!=0)
		{
			if(randomprop<0)
				item->SetRandomSuffix(abs(int(randomprop)));
			else
				item->SetRandomProperty(randomprop);

			item->ApplyRandomProperties(false);
		}
	  
		if(!chr->GetItemInterface()->AddItemToFreeSlot(item))
		{
			m_session->SendNotification("No free slots were found in your inventory!");
			item->DeleteMe();
			return true;
		}

		char messagetext[512];
		snprintf(messagetext, 512, "Adding item %s (id: %d) to %s's inventory.", GetItemLinkByProto(it, m_session->language).c_str(), (unsigned int)it->ItemId, chr->GetName());
		SystemMessage(m_session, messagetext);
		snprintf(messagetext, 128, "%s added item %d (%s) to your inventory.", m_session->GetPlayer()->GetName(), (unsigned int)itemid, it->Name1);
		snprintf(messagetext, 512, "%s added item %s to your inventory.", m_session->GetPlayer()->GetName(), GetItemLinkByProto(it, chr->GetSession()->language).c_str());
		
		SystemMessageToPlr(chr,  messagetext);

		SlotResult *lr = chr->GetItemInterface()->LastSearchResult();
		chr->GetSession()->SendItemPushResult(item,false,true,false,true,lr->ContainerSlot,lr->Slot,count);

		return true;
	} else {
		RedSystemMessage(m_session, "Item %d is not a valid item!", itemid);
		return true;
	}
}
Пример #2
0
void LootRoll::Finalize()
{
    sEventMgr.RemoveEvents(this);

    // this we will have to finalize with groups types.. for now
    // we'll just assume need before greed. person with highest roll
    // in need gets the item.

    uint32 highest = 0;
    int8 hightype = -1;
    uint64 player = 0;

    WorldPacket data(34);

    /*
        Player * gplr = NULL;
        for(std::map<uint64, uint32>::iterator itr = NeedRolls.begin(); itr != NeedRolls.end(); ++itr)
        {
        gplr = _mgr->GetPlayer((uint32)itr->first);
        if(gplr) break;
        }

        if(!gplr)
        {
        for(std::map<uint64, uint32>::iterator itr = GreedRolls.begin(); itr != GreedRolls.end(); ++itr)
        {
        gplr = _mgr->GetPlayer((uint32)itr->first);
        if(gplr) break;
        }
        }
        */
    for (std::map<uint32, uint32>::iterator itr = m_NeedRolls.begin(); itr != m_NeedRolls.end(); ++itr)
    {
        if (itr->second > highest)
        {
            highest = itr->second;
            player = itr->first;
            hightype = NEED;
        }
        /*
        data.Initialize(SMSG_LOOT_ROLL);
        data << _guid << _slotid << itr->first;
        data << _itemid << _itemunk1 << _itemunk2;
        data << uint8(itr->second) << uint8(NEED);
        if(gplr && gplr->GetGroup())
        gplr->GetGroup()->SendPacketToAll(&data);
        */
    }

    if (!highest)
    {
        for (std::map<uint32, uint32>::iterator itr = m_GreedRolls.begin(); itr != m_GreedRolls.end(); ++itr)
        {
            if (itr->second > highest)
            {
                highest = itr->second;
                player = itr->first;
                hightype = GREED;
            }
            /*
            data.Initialize(SMSG_LOOT_ROLL);
            data << _guid << _slotid << itr->first;
            data << _itemid << _itemunk1 << _itemunk2;
            data << uint8(itr->second) << uint8(GREED);
            if(gplr && gplr->GetGroup())
            gplr->GetGroup()->SendPacketToAll(&data);
            */
        }
    }

    Loot * pLoot = 0;
    uint32 guidtype = GET_TYPE_FROM_GUID(_guid);
    if (guidtype == HIGHGUID_TYPE_UNIT)
    {
        Creature * pc = _mgr->GetCreature(GET_LOWGUID_PART(_guid));
        if (pc) pLoot = &pc->loot;
    }
    else if (guidtype == HIGHGUID_TYPE_GAMEOBJECT)
    {
        GameObject * go = _mgr->GetGameObject(GET_LOWGUID_PART(_guid));
        if (go) pLoot = &go->loot;
    }

    if (!pLoot)
    {
        delete this;
        return;
    }

    if (_slotid >= pLoot->items.size())
    {
        delete this;
        return;
    }

    pLoot->items.at(_slotid).roll = NULL;

    uint32 itemid = pLoot->items.at(_slotid).item.itemproto->ItemId;
    uint32 amt = pLoot->items.at(_slotid).iItemsCount;
    if (!amt)
    {
        delete this;
        return;
    }

    Player * _player = (player) ? _mgr->GetPlayer((uint32)player) : 0;
    if (!player || !_player)
    {
        /* all passed */
        data.Initialize(SMSG_LOOT_ALL_PASSED);
        data << _guid << _groupcount << _itemid << _itemunk1 << _itemunk2;
        std::set<uint32>::iterator pitr = m_passRolls.begin();
        while (_player == NULL && pitr != m_passRolls.end())
            _player = _mgr->GetPlayer((*(pitr++)));

        if (_player != NULL)
        {
            if (_player->InGroup())
                _player->GetGroup()->SendPacketToAll(&data);
            else
                _player->GetSession()->SendPacket(&data);
        }

        /* item can now be looted by anyone :) */
        pLoot->items.at(_slotid).passed = true;
        delete this;
        return;
    }

    pLoot->items.at(_slotid).roll = 0;
    data.Initialize(SMSG_LOOT_ROLL_WON);
    data << _guid << _slotid << _itemid << _itemunk1 << _itemunk2;
    data << _player->GetGUID() << uint8(highest) << uint8(hightype);
    if (_player->InGroup())
        _player->GetGroup()->SendPacketToAll(&data);
    else
        _player->GetSession()->SendPacket(&data);

    ItemPrototype* it = ItemPrototypeStorage.LookupEntry(itemid);

    int8 error;
    if ((error = _player->GetItemInterface()->CanReceiveItem(it, 1)) != 0)
    {
        _player->GetItemInterface()->BuildInventoryChangeError(NULL, NULL, error);
        return;
    }

    Item * add = _player->GetItemInterface()->FindItemLessMax(itemid, amt, false);

    if (!add)
    {
        SlotResult slotresult = _player->GetItemInterface()->FindFreeInventorySlot(it);
        if (!slotresult.Result)
        {
            _player->GetItemInterface()->BuildInventoryChangeError(NULL, NULL, INV_ERR_INVENTORY_FULL);
            return;
        }

        sLog.outDebug("AutoLootItem MISC");
        Item *item = objmgr.CreateItem(itemid, _player);

        item->SetUInt32Value(ITEM_FIELD_STACK_COUNT, amt);
        if (pLoot->items.at(_slotid).iRandomProperty != NULL)
        {
            item->SetRandomProperty(pLoot->items.at(_slotid).iRandomProperty->ID);
            item->ApplyRandomProperties(false);
        }
        else if (pLoot->items.at(_slotid).iRandomSuffix != NULL)
        {
            item->SetRandomSuffix(pLoot->items.at(_slotid).iRandomSuffix->id);
            item->ApplyRandomProperties(false);
        }


        if (_player->GetItemInterface()->SafeAddItem(item, slotresult.ContainerSlot, slotresult.Slot))
        {
            _player->GetSession()->SendItemPushResult(item, false, true, true, true, slotresult.ContainerSlot, slotresult.Slot, 1);
            sQuestMgr.OnPlayerItemPickup(_player, item);
        }
        else
            item->DeleteMe();
    }
    else
    {
        add->SetCount(add->GetUInt32Value(ITEM_FIELD_STACK_COUNT) + amt);
        add->m_isDirty = true;
        sQuestMgr.OnPlayerItemPickup(_player, add);
        _player->GetSession()->SendItemPushResult(add, false, true, true, false, _player->GetItemInterface()->GetBagSlotByGuid(add->GetGUID()), 0xFFFFFFFF, 1);
    }

    pLoot->items.at(_slotid).iItemsCount = 0;
    // this gets sent to all looters
    data.Initialize(SMSG_LOOT_REMOVED);
    data << uint8(_slotid);
    Player * plr;
    for (LooterSet::iterator itr = pLoot->looters.begin(); itr != pLoot->looters.end(); ++itr)
    {
        if ((plr = _player->GetMapMgr()->GetPlayer(*itr)) != 0)
            plr->GetSession()->SendPacket(&data);
    }

    /*WorldPacket idata(45);
    _player->GetSession()->BuildItemPushResult(&idata, _player->GetGUID(), ITEM_PUSH_TYPE_LOOT, amt, itemid, pLoot->items.at(_slotid).iRandomProperty ? pLoot->items.at(_slotid).iRandomProperty->ID : 0);

    if(_player->InGroup())
    _player->GetGroup()->SendPacketToAll(&idata);
    else
    _player->GetSession()->SendPacket(&idata);*/

    delete this;
}
Пример #3
0
void WorldSession::HandleAutostoreLootItemOpcode( WorldPacket & recv_data )
{
	if(!_player->IsInWorld()) return;
//	uint8 slot = 0;
	uint32 itemid = 0;
	uint32 amt = 1;
	uint8 lootSlot = 0;
	uint8 error = 0;
	SlotResult slotresult;

	Item *add;
	Loot *pLoot = NULL;

	if(_player->isCasting())
		_player->InterruptSpell();
	GameObject * pGO = NULL;
	Creature * pCreature = NULL;

	if(UINT32_LOPART(GUID_HIPART(GetPlayer()->GetLootGUID())) == HIGHGUID_UNIT)
	{
		pCreature = _player->GetMapMgr()->GetCreature((uint32)GetPlayer()->GetLootGUID());
		if (!pCreature)return;
		pLoot=&pCreature->loot;	
	}
	else if(UINT32_LOPART(GUID_HIPART(_player->GetLootGUID())) == HIGHGUID_GAMEOBJECT)
	{
		pGO = _player->GetMapMgr()->GetGameObject((uint32)GetPlayer()->GetLootGUID());
		if(!pGO)return;
		pLoot=&pGO->loot;
	}else if( (UINT32_LOPART(GUID_HIPART(_player->GetLootGUID())) == HIGHGUID_ITEM) )
	{
		Item *pItem = _player->GetItemInterface()->GetItemByGUID(_player->GetLootGUID());
		if(!pItem)
			return;
		pLoot = pItem->loot;
	}

	if(!pLoot) return;

	recv_data >> lootSlot;
	if (lootSlot >= pLoot->items.size())
	{
		sLog.outDebug("AutoLootItem: Player %s might be using a hack! (slot %d, size %d)",
						GetPlayer()->GetName(), lootSlot, pLoot->items.size());
		return;
	}

	amt = pLoot->items.at(lootSlot).iItemsCount;

	if (!amt)//Test for party loot
	{  
		GetPlayer()->GetItemInterface()->BuildInventoryChangeError(NULL, NULL,INV_ERR_ALREADY_LOOTED);
		return;
	} 
	itemid = pLoot->items.at(lootSlot).item.itemid;
	ItemPrototype* it = ItemPrototypeStorage.LookupEntry(itemid);

	if((error = _player->GetItemInterface()->CanReceiveItem(it, 1)))
	{
		_player->GetItemInterface()->BuildInventoryChangeError(NULL, NULL, error);
		return;
	}

	if(pGO)
		CALL_GO_SCRIPT_EVENT(pGO, OnLootTaken)(_player, it);
	else if(pCreature)
		CALL_SCRIPT_EVENT(pCreature, OnLootTaken)(_player, it);

	add = GetPlayer()->GetItemInterface()->FindItemLessMax(itemid, amt, false);
	sHookInterface.OnLoot(_player, pCreature, 0, itemid);
	if (!add)
	{
		slotresult = GetPlayer()->GetItemInterface()->FindFreeInventorySlot(it);
		if(!slotresult.Result)
		{
			GetPlayer()->GetItemInterface()->BuildInventoryChangeError(NULL, NULL, INV_ERR_INVENTORY_FULL);
			return;
		}
	
		sLog.outDebug("AutoLootItem MISC");
		Item *item = objmgr.CreateItem( itemid, GetPlayer());
	   
		item->SetUInt32Value(ITEM_FIELD_STACK_COUNT,amt);
		uint32 rndprop=pLoot->items.at(lootSlot).iRandomProperty;
		if(rndprop)
			item->SetUInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID,rndprop);
		item->ApplyRandomProperties();

		GetPlayer()->GetItemInterface()->SafeAddItem(item,slotresult.ContainerSlot, slotresult.Slot);
		
		if (it->Class == 12)		// Quest item
			sQuestMgr.OnPlayerItemPickup(GetPlayer(),item);
	}
	else 
	{	
		add->SetCount(add->GetUInt32Value(ITEM_FIELD_STACK_COUNT) + amt);
		add->m_isDirty = true;
		if (it->Class == 12)		// Quest item
			sQuestMgr.OnPlayerItemPickup(GetPlayer(),add);
	}

	pLoot->items.at(lootSlot).iItemsCount=0;
	// this gets sent to all looters
	WorldPacket data(1);
	data.SetOpcode(SMSG_LOOT_REMOVED);
	data << lootSlot;
	Player * plr;
	for(LooterSet::iterator itr = pLoot->looters.begin(); itr != pLoot->looters.end(); ++itr)
	{
		if((plr = _player->GetMapMgr()->GetPlayer(*itr)))
			plr->GetSession()->SendPacket(&data);
	}

    WorldPacket idata;
    if(it->Class == ITEM_CLASS_QUEST)
    {
        uint32 pcount = _player->GetItemInterface()->GetItemCount(it->ItemId, true);
		BuildItemPushResult(&idata, _player->GetGUID(), ITEM_PUSH_TYPE_LOOT, amt, itemid, pLoot->items.at(lootSlot).iRandomProperty,0xFF,0,0xFFFFFFFF,pcount);
    }
    else BuildItemPushResult(&idata, _player->GetGUID(), ITEM_PUSH_TYPE_LOOT, amt, itemid, pLoot->items.at(lootSlot).iRandomProperty);

	if(_player->InGroup())
		_player->GetGroup()->SendPacketToAll(&idata);
	else
		SendPacket(&idata);
}
Пример #4
0
void LootRoll::Finalize()
{
	if( !mLootLock.AttemptAcquire() ) // only one finalization, please. players on different maps can roll, too, so this is needed.
	{
		sEventMgr.RemoveEvents(this);
		return;
	}

	sEventMgr.RemoveEvents(this);

	// this we will have to finalize with groups types.. for now
	// we'll just assume need before greed. person with highest roll
	// in need gets the item.

	uint32 highest = 0;
	int8 hightype = -1;
	uint64 player = 0;

	WorldPacket data(34);

	for(std::map<uint32, uint32>::iterator itr = m_NeedRolls.begin(); itr != m_NeedRolls.end(); itr++)
	{
		if(itr->second > highest)
		{
			highest = itr->second;
			player = itr->first;
			hightype = NEED;
		}
	}

	if(!highest)
	{
		for(std::map<uint32, uint32>::iterator itr = m_GreedRolls.begin(); itr != m_GreedRolls.end(); itr++)
		{
			if(itr->second > highest)
			{
				highest = itr->second;
				player = itr->first;
				hightype = GREED;
			}
		}

		for(std::map<uint32, uint32>::iterator itr = m_DisenchantRolls.begin(); itr != m_DisenchantRolls.end(); itr++)
		{
			if(itr->second > highest)
			{
				highest = itr->second;
				player = itr->first;
				hightype = DISENCHANT;
			}
		}
	}


	Loot * pLoot = 0;
	uint32 guidtype = GET_TYPE_FROM_GUID(_guid);
	if( guidtype == HIGHGUID_TYPE_CREATURE )
	{
		Creature* pc = _mgr->GetCreature(GET_LOWGUID_PART(_guid));
		if(pc) pLoot = &pc->m_loot;
	}
	else if( guidtype == HIGHGUID_TYPE_GAMEOBJECT )
	{
		GameObject* go = _mgr->GetGameObject(GET_LOWGUID_PART(_guid));
		if(go) pLoot = &go->m_loot;
	}

	if(!pLoot)
	{
		delete this;
		return;
	}

	if(_slotid >= pLoot->items.size())
	{
		delete this;
		return;
	}

	pLoot->items.at(_slotid).roll = NULLROLL;

	uint32 itemid = pLoot->items.at(_slotid).item.itemproto->ItemId;
	uint32 amt = pLoot->items.at(_slotid).StackSize;
	if(!amt)
	{
		delete this;
		return;
	}

	Player* _player = (player) ? _mgr->GetPlayer((uint32)player) : NULLPLR;
	if(!player || !_player)
	{
		/* all passed */
		data.Initialize(SMSG_LOOT_ALL_PASSED);
		data << _guid << _groupcount << _itemid << _randomsuffixid << _randompropertyid;
		set<uint32>::iterator pitr = m_passRolls.begin();
		while(_player == NULL && pitr != m_passRolls.end())
		{
			_player = _mgr->GetPlayer( (*(pitr)) );
			++pitr;
		}

		if( _player != NULL )
		{
			if(_player->InGroup())
				_player->GetGroup()->SendPacketToAll(&data);
			else
				_player->GetSession()->SendPacket(&data);
		}

		/* item can now be looted by anyone :) */
		pLoot->items.at(_slotid).passed = true;
		delete this;
		return;
	}

	pLoot->items.at(_slotid).roll = 0;
	data.Initialize(SMSG_LOOT_ROLL_WON);
	data << _guid << _slotid << _itemid << _randomsuffixid << _randompropertyid;
	data << _player->GetGUID() << uint8(highest) << uint8(hightype);
	if(_player->InGroup())
		_player->GetGroup()->SendPacketToAll(&data);
	else
		_player->GetSession()->SendPacket(&data);

	if(hightype == DISENCHANT)
	{
		//generate Disenchantingloot
		Item * pItem = objmgr.CreateItem( itemid, _player);
		lootmgr.FillItemLoot(&pItem->m_loot, pItem->GetEntry(), _player->GetTeam());

		//add loot
		for(std::vector<__LootItem>::iterator iter=pItem->m_loot.items.begin();iter != pItem->m_loot.items.end();iter++)
		{
			itemid =iter->item.itemproto->ItemId;
			Item * Titem = objmgr.CreateItem( itemid, _player);
			if( Titem == NULLITEM )
				continue;
			if( !_player->GetItemInterface()->AddItemToFreeSlot(Titem) )
			{
				_player->GetSession()->SendNotification("No free slots were found in your inventory, item has been mailed.");
				sMailSystem.DeliverMessage(MAILTYPE_NORMAL, _player->GetGUID(), _player->GetGUID(), "Loot Roll", "Here is your reward.", 0, 0, itemid, 1, true);
			}
			Titem->DeleteMe();
			Titem = NULLITEM;
		}
		pItem->DeleteMe();
		pItem = NULLITEM;

		// Set a looter, doesn't matter who.
		pLoot->items.at(_slotid).has_looted.insert(_player->GetLowGUID());

		//Send "finish" packet
		data.Initialize(SMSG_LOOT_REMOVED);
		data << uint8(_slotid);
		Player* plr;
		for(LooterSet::iterator itr = pLoot->looters.begin(); itr != pLoot->looters.end(); itr++)
		{
			if((plr = _player->GetMapMgr()->GetPlayer(*itr)))
				plr->GetSession()->SendPacket(&data);
		}

		delete this;	//end here and skip the rest
		return;
	}

	ItemPrototype* it = ItemPrototypeStorage.LookupEntry(itemid);

	int8 error;
	if((error = _player->GetItemInterface()->CanReceiveItem(it, 1, NULL)))
	{
		_player->GetItemInterface()->BuildInventoryChangeError(NULLITEM, NULLITEM, error);
		return;
	}

	Item* add = _player->GetItemInterface()->FindItemLessMax(itemid, amt, false);

	if (!add)
	{
		SlotResult slotresult = _player->GetItemInterface()->FindFreeInventorySlot(it);
		if(!slotresult.Result)
		{
			_player->GetSession()->SendNotification("No free slots were found in your inventory, item has been mailed.");
			sMailSystem.DeliverMessage(MAILTYPE_NORMAL, _player->GetGUID(), _player->GetGUID(), "Loot Roll", "Here is your reward.", 0, 0, it->ItemId, 1, true);
			data.Initialize(SMSG_LOOT_REMOVED);
			data << uint8(_slotid);
			Player* plr;
			for(LooterSet::iterator itr = pLoot->looters.begin(); itr != pLoot->looters.end(); itr++)
			{
				if((plr = _player->GetMapMgr()->GetPlayer(*itr)))
					plr->GetSession()->SendPacket(&data);
			}
			delete this;
			return;
		}

		DEBUG_LOG("HandleAutostoreItem","AutoLootItem %u",itemid);
		Item* item = objmgr.CreateItem( itemid, _player);

		item->SetUInt32Value(ITEM_FIELD_STACK_COUNT,amt);
		if(pLoot->items.at(_slotid).iRandomProperty!=NULL)
		{
			item->SetRandomProperty(pLoot->items.at(_slotid).iRandomProperty->ID);
			item->ApplyRandomProperties(false);
		}
		else if(pLoot->items.at(_slotid).iRandomSuffix != NULL)
		{
			item->SetRandomSuffix(pLoot->items.at(_slotid).iRandomSuffix->id);
			item->ApplyRandomProperties(false);
		}


		if( _player->GetItemInterface()->SafeAddItem(item,slotresult.ContainerSlot, slotresult.Slot) )
		{
			_player->GetSession()->SendItemPushResult(item,false,true,true,true,slotresult.ContainerSlot,slotresult.Slot,1);
			sQuestMgr.OnPlayerItemPickup(_player,item);
		}
		else
		{
			item->DeleteMe();
			item = NULLITEM;
		}
	}
	else
	{
		add->SetCount(add->GetUInt32Value(ITEM_FIELD_STACK_COUNT) + amt);
		add->m_isDirty = true;
		sQuestMgr.OnPlayerItemPickup(_player,add);
		_player->GetSession()->SendItemPushResult(add, false, true, true, false, _player->GetItemInterface()->GetBagSlotByGuid(add->GetGUID()), 0xFFFFFFFF, 1);
	}

	// Set a looter, doesn't matter who.
	pLoot->items.at(_slotid).has_looted.insert(_player->GetLowGUID());

	// this gets sent to all looters
	data.Initialize(SMSG_LOOT_REMOVED);
	data << uint8(_slotid);
	Player* plr;
	for(LooterSet::iterator itr = pLoot->looters.begin(); itr != pLoot->looters.end(); itr++)
	{
		if((plr = _player->GetMapMgr()->GetPlayer(*itr)))
			plr->GetSession()->SendPacket(&data);
	}

	delete this;
}