- Mesaj
- 354
- Çözümler
- 13
- Beğeni
- 92
- Puan
- 729
- Ticaret Puanı
- 0
Örneğin Mor potu başlangıçta 10 adet verdim ve kilitli şekilde ancak yerden aynı mor pot alınca kilitlilerin üstüne geliyor ve hepsi kilitli oluyor kod kısmı aşağıda ama çalışmadı. ENABLE_BASIC_ITEM_SYSTEM benim eklediğim örnek ama çalışmadı.
1:
#ifdef ENABLE_EXTENDED_COUNT_ITEMS
std::pair<bool, LPITEM> CHARACTER::AutoStackItemProto(DWORD dwItemVnum, short & bCount)
#else
std::pair<bool, LPITEM> CHARACTER::AutoStackItemProto(DWORD dwItemVnum, BYTE & bCount)
#endif
{
TItemTable * p = ITEM_MANAGER::instance().GetTable(dwItemVnum);
if (!p)
return {false, nullptr};
if (p->dwFlags & ITEM_FLAG_STACKABLE && p->bType != ITEM_BLEND)
{
for (int i = 0; i < INVENTORY_MAX_NUM; ++i)
{
LPITEM item = GetInventoryItem(i);
if (!item)
continue;
if (item->GetVnum() == dwItemVnum && FN_check_item_socket(item)
[COLOR=rgb(226, 80, 65)]#ifdef ENABLE_BASIC_ITEM_SYSTEM
&& !item->IsBasicItem()
#endif[/COLOR]
)
{
if (IS_SET(p->dwFlags, ITEM_FLAG_MAKECOUNT))
{
if (bCount < p->alValues[1])
bCount = p->alValues[1];
}
auto bCount2 = MIN(g_bItemCountLimit - item->GetCount(), bCount);
bCount -= bCount2;
item->SetCount(item->GetCount() + bCount2);
if (bCount == 0)
return {true, item};
}
}
}
return {true, nullptr};
}
2:
LPITEM CHARACTER::AutoStackItem(LPITEM item)
{
if (item->IsStackable() && !IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_STACK))
{
auto bCount = item->GetCount();
for (int i = 0; i < INVENTORY_MAX_NUM; ++i)
{
LPITEM item2 = GetInventoryItem(i);
if (!item2)
continue;
if (item == item2)
continue;
if (item2->GetVnum() == item->GetVnum())
{
int j = 0;
for (; j < ITEM_SOCKET_MAX_NUM; ++j)
if (item2->GetSocket(j) != item->GetSocket(j))
break;
if (j != ITEM_SOCKET_MAX_NUM)
continue;
auto bCount2 = MIN(g_bItemCountLimit - item2->GetCount(), bCount);
bCount -= bCount2;
item2->SetCount(item2->GetCount() + bCount2);
if (bCount == 0)
{
M2_DESTROY_ITEM(item);
return item2;
}
}
}
item->SetCount(bCount);
}
return nullptr;
}
3:
#ifdef ENABLE_EXTENDED_COUNT_ITEMS
LPITEM CHARACTER::AutoGiveItem(DWORD dwItemVnum, short bCount, int iRarePct, bool bMsg)
#else
LPITEM CHARACTER::AutoGiveItem(DWORD dwItemVnum, BYTE bCount, int iRarePct, bool bMsg)
#endif
{
auto [foundTable, foundItem] = AutoStackItemProto(dwItemVnum, bCount);
if (!foundTable)
return nullptr;
DBManager::instance().SendMoneyLog(MONEY_LOG_DROP, dwItemVnum, bCount);
if (foundItem)
{
if (bMsg)
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("아이템 획득: %s"), foundItem->GetName());
return foundItem;
}
LPITEM item = ITEM_MANAGER::instance().CreateItem(dwItemVnum, bCount, 0, true);
if (!item)
{
sys_err("cannot create item by vnum %u (name: %s)", dwItemVnum, GetName());
return NULL;
}
auto finalItem = AutoStackItem(item); // @fixme316
if (finalItem)
{
if (bMsg)
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("아이템 획득: %s"), finalItem->GetName());
return finalItem;
}
if (item->GetType() == ITEM_BLEND)
{
for (int i=0; i < INVENTORY_MAX_NUM; i++)
{
LPITEM inv_item = GetInventoryItem(i);
if (inv_item == NULL) continue;
if (inv_item->GetType() == ITEM_BLEND)
{
if (inv_item->GetVnum() == item->GetVnum())
{
if (inv_item->GetSocket(0) == item->GetSocket(0) &&
inv_item->GetSocket(1) == item->GetSocket(1) &&
inv_item->GetSocket(2) == item->GetSocket(2) &&
inv_item->GetCount() < g_bItemCountLimit)
{
inv_item->SetCount(inv_item->GetCount() + item->GetCount());
return inv_item;
}
}
}
}
}
int iEmptyCell = GetEmptyInventoryEx(item);
if (iEmptyCell != -1)
{
if (bMsg)
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("아이템 획득: %s"), item->GetName());
item->AddToCharacter(this, TItemPos(item->GetWindowInventoryEx(), iEmptyCell));
LogManager::instance().ItemLog(this, item, "SYSTEM", item->GetName());
if (item->GetType() == ITEM_USE && item->GetSubType() == USE_POTION)
{
TQuickslot * pSlot;
if (GetQuickslot(0, &pSlot) && pSlot->type == QUICKSLOT_TYPE_NONE)
{
TQuickslot slot;
slot.type = QUICKSLOT_TYPE_ITEM;
slot.pos = iEmptyCell;
SetQuickslot(0, slot);
}
}
}
else
{
item->AddToGround(GetMapIndex(), GetXYZ());
#ifdef ENABLE_NEWSTUFF
item->StartDestroyEvent(g_aiItemDestroyTime[ITEM_DESTROY_TIME_AUTOGIVE]);
#else
item->StartDestroyEvent();
#endif
if (IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_DROP))
item->SetOwnership(this, 300);
else
item->SetOwnership(this, 60);
LogManager::instance().ItemLog(this, item, "SYSTEM_DROP", item->GetName());
}
sys_log(0,
"7: %d %d", dwItemVnum, bCount);
return item;
}