Jump to content

Item not stackable on pickup while in party


Recommended Posts

  • Replies 3
  • Created
  • Last Reply

Top Posters In This Topic

Popular Days

Top Posters In This Topic

40 minutes ago, Filiq said:

post PickupItem function

bool CHARACTER::PickupItem(DWORD dwVID)
{
	LPITEM item = ITEM_MANAGER::instance().FindByVID(dwVID);

	if (!IsPC() || IsObserverMode())
		return false;

	if (!item || !item->GetSectree())
		return false;

	if (item->DistanceValid(this))
	{
		if (item->IsOwnership(this))
		{
			// ??????a AOA????A CI??A ????AIAUAI ????A???o??e
			if (item->GetType() == ITEM_ELK)
			{
				GiveGold(item->GetCount());
				item->RemoveFromGround();

				M2_DESTROY_ITEM(item);

				Save();
			}
			// ??o??uCN ????AIAUAI??o??e
			else
			{
				if (item->IsStackable() && !IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_STACK))
				{
					WORD bCount = item->GetCount();

					for (int i = 0; i < INVENTORY_MAX_NUM; ++i)
					{
						LPITEM item2 = GetInventoryItem(i);

						if (!item2)
							continue;

						if (item2->GetVnum() == item->GetVnum())
						{
							int j;

							for (j = 0; j < ITEM_SOCKET_MAX_NUM; ++j)
								if (item2->GetSocket(j) != item->GetSocket(j))
									break;

							if (j != ITEM_SOCKET_MAX_NUM)
								continue;

							WORD bCount2 = MIN(ITEM_MAX_COUNT - item2->GetCount(), bCount);
							bCount -= bCount2;
#if defined(__EXTENDED_BLEND_AFFECT__)
							if (item2->IsBlendItem() && item->IsBlendItem())
								item2->SetSocket(2, item2->GetSocket(2) + item->GetSocket(2));
							else
								item2->SetCount(item2->GetCount() + bCount2);
#else
							item2->SetCount(item2->GetCount() + bCount2);
#endif

							if (bCount == 0)
							{
#ifdef ENABLE_EXTENDED_BATTLE_PASS
								if (item->IsOwnership(this))
									UpdateExtBattlePassMissionProgress(BP_ITEM_COLLECT, bCount2, item->GetVnum());
#endif
								if (item->GetCount() > 1)
								{
									ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%dx %s received"), item->GetCount(), item2->GetName());
								}
								else
								{
									ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s received"), item2->GetName());	
								}
								M2_DESTROY_ITEM(item);
								if (item2->GetType() == ITEM_QUEST)
									quest::CQuestManager::instance().PickupItem (GetPlayerID(), item2);
								return true;
							}
						}
					}
					
#ifdef ENABLE_SPECIAL_INVENTORY
					for (int i = SPECIAL_INVENTORY_SLOT_START; i < SPECIAL_INVENTORY_SLOT_END; ++i)
					{
						LPITEM item2 = GetInventoryItem(i);

						if (!item2)
						{
							continue;
						}

						if (item2->GetVnum() == item->GetVnum())
						{
							int j;

							for (j = 0; j < ITEM_SOCKET_MAX_NUM; ++j)
							{
								if (item2->GetSocket(j) != item->GetSocket(j))
								{
									break;
								}
							}

							if (j != ITEM_SOCKET_MAX_NUM)
							{
								continue;
							}

							WORD bCount2 = MIN(ITEM_MAX_COUNT - item2->GetCount(), bCount);
							bCount -= bCount2;

							item2->SetCount(item2->GetCount() + bCount2);

							if (bCount == 0)
							{
#ifdef ENABLE_EXTENDED_BATTLE_PASS
								if (item->IsOwnership(this))
									UpdateExtBattlePassMissionProgress(BP_ITEM_COLLECT, bCount2, item->GetVnum());
#endif
								if (item->GetCount() > 1)
								{
									ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%dx %s received"), item->GetCount(), item2->GetName());
								}
								else
								{
									ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s received"), item->GetName());
								}
								M2_DESTROY_ITEM(item);
								if (item2->GetType() == ITEM_QUEST)
									quest::CQuestManager::instance().PickupItem (GetPlayerID(), item2);
								return true;
							}
						}
					}
#endif

					item->SetCount(bCount);
#ifdef ENABLE_EXTENDED_BATTLE_PASS
					if (item->IsOwnership(this))
						UpdateExtBattlePassMissionProgress(BP_ITEM_COLLECT, bCount, item->GetVnum());
#endif
				}

				int iEmptyCell;
				if (item->IsDragonSoul())
				{
					if ((iEmptyCell = GetEmptyDragonSoulInventory(item)) == -1)
					{
						sys_log(0, "No empty ds inventory pid %u size %ud itemid %u", GetPlayerID(), item->GetSize(), item->GetID());
						ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You carry too many Items."));
						return false;
					}
				}
				else
				{
#ifdef ENABLE_SPECIAL_INVENTORY
					if ((iEmptyCell = GetEmptyInventory(item)) == -1)
#else
					if ((iEmptyCell = GetEmptyInventory(item->GetSize())) == -1)
#endif
					{
						sys_log(0, "No empty inventory pid %u size %ud itemid %u", GetPlayerID(), item->GetSize(), item->GetID());
						ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You carry too many Items."));
						return false;
					}
				}

				item->RemoveFromGround();
				
				if (item->IsDragonSoul())
					item->AddToCharacter(this, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyCell));
				else
					item->AddToCharacter(this, TItemPos(INVENTORY, iEmptyCell));
				
#ifndef DISABLE_LOGS
				char szHint[32+1];
				snprintf(szHint, sizeof(szHint), "%s %u %u", item->GetName(), item->GetCount(), item->GetOriginalVnum());
				LogManager::instance().ItemLog(this, item, "GET", szHint);
#endif
				if (item->GetCount() > 1)
				{
					ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%dx %s received"), item->GetCount(), item->GetName());
				}
				else
				{
					ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s received"), item->GetName());
				}
				if (item->GetType() == ITEM_QUEST)
					quest::CQuestManager::instance().PickupItem (GetPlayerID(), item);
			}

			//Motion(MOTION_PICKUP);
			return true;
		}
		else if (!IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_GIVE | ITEM_ANTIFLAG_DROP) && GetParty())
		{
			// 다른 파티원 소유권 아이템을 주으려고 한다면
			NPartyPickupDistribute::FFindOwnership funcFindOwnership(item);

			//GetParty()->ForEachOnlineMember(funcFindOwnership);
			GetParty()->ForEachOnMapMember(funcFindOwnership, GetMapIndex());

			LPCHARACTER owner = funcFindOwnership.owner;
			if (!owner)
				return false;
			
			if (item->IsStackable() && !IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_STACK))
			{
				WORD bCount = item->GetCount();
				for (int i = SPECIAL_INVENTORY_SLOT_START; i < SPECIAL_INVENTORY_SLOT_END; ++i)
				//for (int i = 0; i < INVENTORY_MAX_NUM; ++i) 
				{
					LPITEM item2 = owner->GetInventoryItem(i);

					if (!item2)
					{
						continue;
					}

					if (item2->GetVnum() == item->GetVnum())
					{
						int j;

						for (j = 0; j < ITEM_SOCKET_MAX_NUM; ++j)
							if (item2->GetSocket(j) != item->GetSocket(j))
							{
								break;
							}

						if (j != ITEM_SOCKET_MAX_NUM)
						{
							continue;
						}

						WORD bCount2 = MIN(ITEM_MAX_COUNT - item2->GetCount(), bCount);
						bCount -= bCount2;

						item2->SetCount(item2->GetCount() + bCount2);

						if (bCount == 0)
						{
#ifdef ENABLE_EXTENDED_BATTLE_PASS
							if (item->IsOwnership(this))
								UpdateExtBattlePassMissionProgress(BP_ITEM_COLLECT, bCount2, item->GetVnum());
#endif
							if (owner == this)
							{
								if (item->GetCount() > 1)
								{
									ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%dx %s received"), item->GetCount(), item2->GetName());
								}
								else
								{
									ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s received"), item2->GetName());
								}
							}
							else
							{
								if (item->GetCount() > 1)
								{
									owner->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Received Item: %s, %dx %s "), GetName(), item->GetCount(), item2->GetName());
								}
								else
								{
									owner->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Received Item: %s, %s "), GetName(), item2->GetName());
								}
							}
							M2_DESTROY_ITEM(item);
							return true;
						}
					}
				}
				
/*#ifdef ENABLE_SPECIAL_INVENTORY
				for (int i = 0; i < INVENTORY_MAX_NUM; ++i) 
				{
					LPITEM item2 = GetInventoryItem(i);

					if (!item2)
					{
						continue;
					}

					if (item2->GetVnum() == item->GetVnum())
					{
						
						int j;

						for (j = 0; j < ITEM_SOCKET_MAX_NUM; ++j)
							if (item2->GetSocket(j) != item->GetSocket(j))
							{
								break;
							}

						if (j != ITEM_SOCKET_MAX_NUM)
						{
							continue;
						}

						WORD bCount2 = MIN(ITEM_MAX_COUNT - item2->GetCount(), bCount);
						bCount -= bCount2;

						item2->SetCount(item2->GetCount() + bCount2);
						
						if (bCount == 0)
						{
#ifdef ENABLE_EXTENDED_BATTLE_PASS
							if (item->IsOwnership(this))
								UpdateExtBattlePassMissionProgress(BP_ITEM_COLLECT, bCount2, item->GetVnum());
#endif
							if (owner == this)
							{
								if (item->GetCount() > 1)
								{
									ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%dx %s received"), item->GetCount(), item2->GetName());
								}
								else
								{
									ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s received"), item2->GetName());
								}
							}
							else
							{
								if (item->GetCount() > 1)
								{
									owner->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Received Item: %s, %dx %s "), GetName(), item->GetCount(), item2->GetName());
								}
								else
								{
									owner->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Received Item: %s, %s "), GetName(), item2->GetName());
								}
							}
							M2_DESTROY_ITEM(item);
							return true;
						}
					}
				}
#endif*/

				
				item->SetCount(bCount);
			}



			int iEmptyCell;

			if (item->IsDragonSoul())
			{
				if (!(owner && (iEmptyCell = owner->GetEmptyDragonSoulInventory(item)) != -1))
				{
					owner = this;

					if ((iEmptyCell = GetEmptyDragonSoulInventory(item)) == -1)
					{
						owner->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You carry too many Items."));
						return false;
					}
				}
			}
			else
			{
#ifdef ENABLE_SPECIAL_INVENTORY
				if (!(owner && (iEmptyCell = owner->GetEmptyInventory(item)) != -1))
#else
				if (!(owner && (iEmptyCell = owner->GetEmptyInventory(item->GetSize())) != -1))
#endif
				{
					owner = this;

#ifdef ENABLE_SPECIAL_INVENTORY
					if ((iEmptyCell = GetEmptyInventory(item)) == -1)
#else
					if ((iEmptyCell = GetEmptyInventory(item->GetSize())) == -1)
#endif
					{
						owner->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You carry too many Items."));
						return false;
					}
				}
			}

			item->RemoveFromGround();

			if (item->IsDragonSoul())
				item->AddToCharacter(owner, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyCell));
			else
				item->AddToCharacter(owner, TItemPos(INVENTORY, iEmptyCell));
#ifndef DISABLE_LOGS
			char szHint[32+1];
			snprintf(szHint, sizeof(szHint), "%s %u %u", item->GetName(), item->GetCount(), item->GetOriginalVnum());
			LogManager::instance().ItemLog(owner, item, "GET", szHint);
#endif
			if (owner == this)
			{
				if (item->GetCount() > 1)
				{
					ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%dx %s received"), item->GetCount(), item->GetName());
				}
				else
				{
					ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s received"), item->GetName());
				}
			}
			else
			{
				if (item->GetCount() > 1)
				{
					owner->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Received Item: %s, %dx %s "), GetName(), item->GetCount(), item->GetName());
				}
				else
				{
					owner->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Received Item: %s, %s "), GetName(), item->GetName());
				}
			}

			if (item->GetType() == ITEM_QUEST)
				quest::CQuestManager::instance().PickupItem (owner->GetPlayerID(), item);

			return true;
		}
	}

	return false;
}

Here looked for multiple days now i cannot find anything 

Link to comment
Share on other sites

yes i found the problem, problem is not with the function, well, with that function, we can see in this else if (!IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_GIVE | ITEM_ANTIFLAG_DROP) && GetParty()) "sub-function" from Pickupitem()

 

 

Spoiler

           item->RemoveFromGround();

 

            if (item->IsDragonSoul())

                item->AddToCharacter(owner, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyCell));

            else

                item->AddToCharacter(owner, TItemPos(INVENTORY, iEmptyCell));

the item at some point, its removed from ground, and after its verify if is some item for dragon soul, if isn't, is sent to inventory with the help from "AddToCharacter" function,

Spoiler

bool CItem::AddToCharacter(LPCHARACTER ch, TItemPos Cell)

{

    assert(GetSectree() == NULL);

    assert(m_pOwner == NULL);

    WORD pos = Cell.cell;

    BYTE window_type = Cell.window_type;

   

    if (INVENTORY == window_type)

    {

        if (m_wCell >= INVENTORY_MAX_NUM && BELT_INVENTORY_SLOT_START > m_wCell)

        {

            sys_err("CItem::AddToCharacter: cell overflow: %s to %s cell %d", m_pProto->szName, ch->GetName(), m_wCell);

            return false;

        }

    }

    else if (DRAGON_SOUL_INVENTORY == window_type)

    {

        if (m_wCell >= DRAGON_SOUL_INVENTORY_MAX_NUM)

        {

            sys_err("CItem::AddToCharacter: cell overflow: %s to %s cell %d", m_pProto->szName, ch->GetName(), m_wCell);

            return false;

        }

    }

 

    if (ch->GetDesc())

        m_dwLastOwnerPID = ch->GetPlayerID();

 

    event_cancel(&m_pkDestroyEvent);

 

    ch->SetItem(TItemPos(window_type, pos), this);

    m_pOwner = ch;

 

    Save();

    return true;

}

in this function we dont have nothing about to combine(i dont know what word to use) items.

now how you can fix this?

 

in Pickupitem if the item its pickup by the owner in this "sub-function": if (item->IsStackable() && !IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_STACK))

we found this: item2->SetCount(item2->GetCount() + bCount2);

item2 means, the slot from inventory with that item

in the () means inventory slot + count item from the ground

 

Spoiler

bool CItem::SetCount(DWORD count)

{

    if (GetType() == ITEM_ELK)

    {

        m_dwCount = MIN(count, INT_MAX);

    }

    else

    {

        m_dwCount = MIN(count, ITEM_MAX_COUNT);

    }

 

    if (count == 0 && m_pOwner)

    {

        if (GetSubType() == USE_ABILITY_UP || GetSubType() == USE_POTION || GetVnum() == 70020)

        {

            LPCHARACTER pOwner = GetOwner();

            WORD wCell = GetCell();

 

            RemoveFromCharacter();

 

            if (!IsDragonSoul())

            {

                LPITEM pItem = pOwner->FindSpecifyItem(GetVnum());

 

                if (NULL != pItem)

                {

                    pOwner->ChainQuickslotItem(pItem, QUICKSLOT_TYPE_ITEM, wCell);

                }

                else

                {

                    pOwner->SyncQuickslot(QUICKSLOT_TYPE_ITEM, wCell, 255);

                }

            }

 

            M2_DESTROY_ITEM(this);

        }

        else

        {

            if (!IsDragonSoul())

            {

                m_pOwner->SyncQuickslot(QUICKSLOT_TYPE_ITEM, m_wCell, 255);

            }

            M2_DESTROY_ITEM(RemoveFromCharacter());

        }

 

        return false;

    }

 

    UpdatePacket();

 

    Save();

    return true;

}

we can see here in this function, the items give with her, are stackable?

 

sorry for the english, its not very good ik. 

 

I think i give you too much of information, but i tell you all of this to know how to fix the bug, if you dont succeed in the end, i will do it for you, but try.

Edited by Filiq
i think this is a common problem, cuz in my source code i have the same bug
Link to comment
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

Announcements



  • Similar Content

  • Activity

    1. 60

      Inbuild GR2 Animation

    2. 2

      wait() function bug

    3. 0

      Remove Party Role Bonuses

    4. 1

      Fix CBar3D

    5. 2

      set_quest_state not working

  • Recently Browsing

    • No registered users viewing this page.
×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.