Yeni ek envanter sistemi | K ENVANTER

  • Konbuyu başlatan Konbuyu başlatan Admin
  • Başlangıç tarihi Başlangıç tarihi
  • Cevaplar Cevaplar 0
  • Görüntüleme Görüntüleme 48

Admin

Metin2Lobby
Yönetici
Founder
Katılım
6 Mayıs 2022
Mesajlar
52,647
Ticaret : 1 / 0 / 0
Core hatası vermeyen,bütün hataları fixlenmiş,
herhangi bir bug yaratmayan bir K envanter sistemidir,3500 online'da
Metin2Farm'da denenmiştir.

Saygılarımla,bir rep+i fazla görmeyiniz.

64865_a6d9ab0d8bd7719f1c9cec401dd83a9c.jpg


C++:
"stdafx.h"
"../../libgame/include/grid.h"
"utils.h"
"desc.h"
"desc_client.h"
"char.h"
"item.h"
"item_manager.h"
"packet.h"
"log.h"
"db.h"
"locale_service.h"
"../../common/length.h"
"exchange.h"
"DragonSoul.h"
"questmanager.h" // @fixme150

void exchange_packet(LPCHARACTER ch, BYTE sub_header, bool is_me, DWORD arg1, TItemPos arg2, DWORD arg3, void * pvData = NULL);

// ±³È¯ ÆĞŶ
void exchange_packet(LPCHARACTER ch, BYTE sub_header, bool is_me, DWORD arg1, TItemPos arg2, DWORD arg3, void * pvData)
{
if (!ch->GetDesc())
return;

struct packet_exchange pack_exchg;

pack_exchg.header = HEADER_GC_EXCHANGE;
pack_exchg.sub_header = sub_header;
pack_exchg.is_me = is_me;
pack_exchg.arg1 = arg1;
pack_exchg.arg2 = arg2;
pack_exchg.arg3 = arg3;

if (sub_header == EXCHANGE_SUBHEADER_GC_ITEM_ADD && pvData)
{
thecore_memcpy(&pack_exchg.alSockets, ((LPITEM) pvData)->GetSockets(), sizeof(pack_exchg.alSockets));
thecore_memcpy(&pack_exchg.aAttr, ((LPITEM) pvData)->GetAttributes(), sizeof(pack_exchg.aAttr));
}
else
{
memset(&pack_exchg.alSockets, 0, sizeof(pack_exchg.alSockets));
memset(&pack_exchg.aAttr, 0, sizeof(pack_exchg.aAttr));
}

ch->GetDesc()->Packet(&pack_exchg, sizeof(pack_exchg));
}

// ±³È¯À» ½ÃÀÛ
bool CHARACTER::ExchangeStart(LPCHARACTER victim)
{
if (this == victim) // ÀÚ±â ÀڽŰú´Â ±³È¯À» ¸øÇÑ´Ù.
return false;

if (IsObserverMode())
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("°üÀü »óÅ¿¡¼´Â ±³È¯À» ÇÒ ¼ö ¾ø½À´Ï´Ù."));
return false;
}

if (victim->IsNPC())
return false;

//PREVENT_TRADE_WINDOW
if ( IsOpenSafebox() || GetShopOwner() || GetMyShop() || IsCubeOpen())
{
ChatPacket( CHAT_TYPE_INFO, LC_TEXT("´Ù¸¥ °Å·¡Ã¢ÀÌ ¿·ÁÀÖÀ»°æ¿ì °Å·¡¸¦ ÇÒ¼ö ¾ø½À´Ï´Ù." ) );
return false;
}

if ( victim->IsOpenSafebox() || victim->GetShopOwner() || victim->GetMyShop() || victim->IsCubeOpen() )
{
ChatPacket( CHAT_TYPE_INFO, LC_TEXT("»ó´ë¹æÀÌ ´Ù¸¥ °Å·¡ÁßÀ̶ó °Å·¡¸¦ ÇÒ¼ö ¾ø½À´Ï´Ù." ) );
return false;
}
//END_PREVENT_TRADE_WINDOW
int iDist = DISTANCE_APPROX(GetX() - victim->GetX(), GetY() - victim->GetY());

// °Å¸® üũ
if (iDist >= EXCHANGE_MAX_DISTANCE)
return false;

if (GetExchange())
return false;

if (victim->GetExchange())
{
exchange_packet(this, EXCHANGE_SUBHEADER_GC_ALREADY, 0, 0, NPOS, 0);
return false;
}

if (victim->IsBlockMode(BLOCK_EXCHANGE))
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("»ó´ë¹æÀÌ ±³È¯ °ÅºÎ »óÅÂÀÔ´Ï´Ù."));
return false;
}

SetExchange(M2_NEW CExchange(this));
victim->SetExchange(M2_NEW CExchange(victim));

victim->GetExchange()->SetCompany(GetExchange());
GetExchange()->SetCompany(victim->GetExchange());

//
SetExchangeTime();
victim->SetExchangeTime();

exchange_packet(victim, EXCHANGE_SUBHEADER_GC_START, 0, GetVID(), NPOS, 0);
exchange_packet(this, EXCHANGE_SUBHEADER_GC_START, 0, victim->GetVID(), NPOS, 0);

return true;
}

CExchange::CExchange(LPCHARACTER pOwner)
{
m_pCompany = NULL;

m_bAccept = false;

for (int i = 0; i < EXCHANGE_ITEM_MAX_NUM; ++i)
{
m_apItems = NULL;
m_aItemPos = NPOS;
m_abItemDisplayPos = 0;
}

m_lGold = 0;

m_pOwner = pOwner;
pOwner->SetExchange(this);

m_pGrid = M2_NEW CGrid(4,3);
}

CExchange::~CExchange()
{
M2_DELETE(m_pGrid);
}

bool CExchange::AddItem(TItemPos item_pos, BYTE display_pos)
{
assert(m_pOwner != NULL && GetCompany());

if (!item_pos.IsValidItemPosition())
return false;

// Àåºñ´Â ±³È¯ÇÒ ¼ö ¾øÀ½
if (item_pos.IsEquipPosition())
return false;

LPITEM item;

if (!(item = m_pOwner->GetItem(item_pos)))
return false;

if (IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_GIVE))
{
m_pOwner->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("¾ÆÀÌÅÛÀ» °Ç³×ÁÙ ¼ö ¾ø½À´Ï´Ù."));
return false;
}

if (true == item->isLocked())
{
return false;
}

// ÀÌ¹Ì ±³È¯Ã¢¿¡ Ãß°¡µÈ ¾ÆÀÌÅÛÀΰ¡?
if (item->IsExchanging())
{
sys_log(0, "EXCHANGE under exchanging");
return false;
}

if (!m_pGrid->IsEmpty(display_pos, 1, item->GetSize()))
{
sys_log(0, "EXCHANGE not empty item_pos %d %d %d", display_pos, 1, item->GetSize());
return false;
}

Accept(false);
GetCompany()->Accept(false);

for (int i = 0; i < EXCHANGE_ITEM_MAX_NUM; ++i)
{
if (m_apItems)
continue;

m_apItems = item;
m_aItemPos = item_pos;
m_abItemDisplayPos = display_pos;
m_pGrid->Put(display_pos, 1, item->GetSize());

item->SetExchanging(true);

exchange_packet(m_pOwner,
EXCHANGE_SUBHEADER_GC_ITEM_ADD,
true,
item->GetVnum(),
TItemPos(RESERVED_WINDOW, display_pos),
item->GetCount(),
item);

exchange_packet(GetCompany()->GetOwner(),
EXCHANGE_SUBHEADER_GC_ITEM_ADD,
false,
item->GetVnum(),
TItemPos(RESERVED_WINDOW, display_pos),
item->GetCount(),
item);

sys_log(0, "EXCHANGE AddItem success %s pos(%d, %d) %d", item->GetName(), item_pos.window_type, item_pos.cell, display_pos);

return true;
}

// Ãß°¡ÇÒ °ø°£ÀÌ ¾øÀ½
return false;
}

bool CExchange::RemoveItem(BYTE pos)
{
if (pos >= EXCHANGE_ITEM_MAX_NUM)
return false;

if (!m_apItems[pos])
return false;

TItemPos PosOfInventory = m_aItemPos[pos];
m_apItems[pos]->SetExchanging(false);

m_pGrid->Get(m_abItemDisplayPos[pos], 1, m_apItems[pos]->GetSize());

exchange_packet(GetOwner(), EXCHANGE_SUBHEADER_GC_ITEM_DEL, true, pos, NPOS, 0);
exchange_packet(GetCompany()->GetOwner(), EXCHANGE_SUBHEADER_GC_ITEM_DEL, false, pos, PosOfInventory, 0);

Accept(false);
GetCompany()->Accept(false);

m_apItems[pos] = NULL;
m_aItemPos[pos] = NPOS;
m_abItemDisplayPos[pos] = 0;
return true;
}

bool CExchange::AddGold(long gold)
{
if (gold <= 0)
return false;

if (GetOwner()->GetGold() < gold)
{
// °¡Áö°í ÀÖ´Â µ·ÀÌ ºÎÁ·.
exchange_packet(GetOwner(), EXCHANGE_SUBHEADER_GC_LESS_GOLD, 0, 0, NPOS, 0);
return false;
}

if (m_lGold > 0)
return false;

Accept(false);
GetCompany()->Accept(false);

m_lGold = gold;

exchange_packet(GetOwner(), EXCHANGE_SUBHEADER_GC_GOLD_ADD, true, m_lGold, NPOS, 0);
exchange_packet(GetCompany()->GetOwner(), EXCHANGE_SUBHEADER_GC_GOLD_ADD, false, m_lGold, NPOS, 0);
return true;
}

// µ·ÀÌ ÃæºĞÈ÷ ÀÖ´ÂÁö, ±³È¯ÇÏ·Á´Â ¾ÆÀÌÅÛÀÌ ½ÇÁ¦·Î ÀÖ´ÂÁö È®ÀÎ ÇÑ´Ù.
bool CExchange::Check(int * piItemCount)
{
if (GetOwner()->GetGold() < m_lGold)
return false;

int item_count = 0;

for (int i = 0; i < EXCHANGE_ITEM_MAX_NUM; ++i)
{
if (!m_apItems)
continue;

if (!m_aItemPos.IsValidItemPosition())
return false;

if (m_apItems != GetOwner()->GetItem(m_aItemPos))
return false;

++item_count;
}

*piItemCount = item_count;
return true;
}

bool CExchange::CheckSpace()
{
static CGrid s_grid1(INVENTORY_PAGE_COLUMN, INVENTORY_PAGE_ROW);
static CGrid s_grid2(INVENTORY_PAGE_COLUMN, INVENTORY_PAGE_ROW);
static CGrid s_grid3(INVENTORY_PAGE_COLUMN, INVENTORY_PAGE_ROW);
static CGrid s_grid4(INVENTORY_PAGE_COLUMN, INVENTORY_PAGE_ROW);
static CGrid s_grid5(INVENTORY_PAGE_COLUMN, INVENTORY_PAGE_ROW);

ENABLE_SPLIT_INVENTORY_SYSTEM
LPCHARACTER me = GetOwner();
static CGrid s_grid6(5, SKILL_BOOK_INVENTORY_MAX_NUM / 5 / 4);
static CGrid s_grid7(5, SKILL_BOOK_INVENTORY_MAX_NUM / 5 / 4);
static CGrid s_grid8(5, SKILL_BOOK_INVENTORY_MAX_NUM / 5 / 4);
static CGrid s_grid9(5, UPGRADE_ITEMS_INVENTORY_MAX_NUM / 5 / 4);
static CGrid s_grid10(5, UPGRADE_ITEMS_INVENTORY_MAX_NUM / 5 / 4);
static CGrid s_grid11(5, UPGRADE_ITEMS_INVENTORY_MAX_NUM / 5 / 4);
static CGrid s_grid12(5, STONE_INVENTORY_MAX_NUM / 5 / 4);
static CGrid s_grid13(5, STONE_INVENTORY_MAX_NUM / 5 / 4);
static CGrid s_grid14(5, STONE_INVENTORY_MAX_NUM / 5 / 4);
static CGrid s_grid15(5, BOX_INVENTORY_MAX_NUM / 5 / 4);
static CGrid s_grid16(5, BOX_INVENTORY_MAX_NUM / 5 / 4);
static CGrid s_grid17(5, BOX_INVENTORY_MAX_NUM / 5 / 4);
static CGrid s_grid18(5, EFSUN_INVENTORY_MAX_NUM / 5 / 4);
static CGrid s_grid19(5, EFSUN_INVENTORY_MAX_NUM / 5 / 4);
static CGrid s_grid20(5, EFSUN_INVENTORY_MAX_NUM / 5 / 4);
static CGrid s_grid21(5, CICEK_INVENTORY_MAX_NUM / 5 / 4);
static CGrid s_grid22(5, CICEK_INVENTORY_MAX_NUM / 5 / 4);
static CGrid s_grid23(5, CICEK_INVENTORY_MAX_NUM / 5 / 4);


s_grid1.Clear();
s_grid2.Clear();
s_grid3.Clear();
s_grid4.Clear();
s_grid5.Clear();

ENABLE_SPLIT_INVENTORY_SYSTEM
s_grid6.Clear();
s_grid7.Clear();
s_grid8.Clear();
s_grid9.Clear();
s_grid10.Clear();
s_grid11.Clear();
s_grid12.Clear();
s_grid13.Clear();
s_grid14.Clear();
s_grid15.Clear();
s_grid16.Clear();
s_grid17.Clear();
s_grid18.Clear();
s_grid19.Clear();
s_grid20.Clear();
s_grid21.Clear();
s_grid22.Clear();
s_grid23.Clear();


LPCHARACTER victim = GetCompany()->GetOwner();
LPITEM item;

int i;

for (i = 0; i < INVENTORY_PAGE_SIZE*1; ++i)
{
if (!(item = victim->GetInventoryItem(i)))
continue;

s_grid1.Put(i, 1, item->GetSize());
}
for (i = INVENTORY_PAGE_SIZE*1; i < INVENTORY_PAGE_SIZE*2; ++i)
{
if (!(item = victim->GetInventoryItem(i)))
continue;

s_grid2.Put(i - INVENTORY_PAGE_SIZE*1, 1, item->GetSize());
}
for (i = INVENTORY_PAGE_SIZE*2; i < INVENTORY_PAGE_SIZE*3; ++i)
{
if (!(item = victim->GetInventoryItem(i)))
continue;

s_grid3.Put(i - INVENTORY_PAGE_SIZE*2, 1, item->GetSize());
}
for (i = INVENTORY_PAGE_SIZE*3; i < INVENTORY_PAGE_SIZE*4; ++i)
{
if (!(item = victim->GetInventoryItem(i)))
continue;

s_grid4.Put(i - INVENTORY_PAGE_SIZE*3, 1, item->GetSize());
}
for (i = INVENTORY_PAGE_SIZE * 4; i < INVENTORY_PAGE_SIZE * 5; ++i)
{
if (!(item = victim->GetInventoryItem(i)))
continue;

s_grid5.Put(i - INVENTORY_PAGE_SIZE * 4, 1, item->GetSize());
}

ENABLE_SPLIT_INVENTORY_SYSTEM
int b;
int v;
int u;
int r;
int a;
int l;
const int perPageSkillBookSlotCount = 45;
const int perPageUpgradeItemsSlotCount = 45;
const int perPageStoneSlotCount = 45;
const int perPageBoxSlotCount = 45;
const int perPageEfsunSlotCount = 45;
const int perPageCicekSlotCount = 45;
for (b = 0; b < SKILL_BOOK_INVENTORY_MAX_NUM; ++b) {
if (!(item = me->GetSkillBookInventoryItem(b)))
continue;

BYTE itemSize = item->GetSize();

if (i < perPageSkillBookSlotCount) // Notice: This is adjusted for 3 Pages only!
s_grid6.Put(i, 1, itemSize);
else if (i < perPageSkillBookSlotCount * 2)
s_grid7.Put(i - perPageSkillBookSlotCount, 1, itemSize);
else if (i < perPageSkillBookSlotCount * 3)
s_grid8.Put(i - perPageSkillBookSlotCount * 2, 1, itemSize);
}

for (v = 0; v < UPGRADE_ITEMS_INVENTORY_MAX_NUM; ++v) {
if (!(item = me->GetUpgradeItemsInventoryItem(v)))
continue;

BYTE itemSize = item->GetSize();

if (i < perPageUpgradeItemsSlotCount) // Notice: This is adjusted for 3 Pages only!
s_grid9.Put(i, 1, itemSize);
else if (i < perPageUpgradeItemsSlotCount * 2)
s_grid10.Put(i - perPageUpgradeItemsSlotCount, 1, itemSize);
else if (i < perPageUpgradeItemsSlotCount * 3)
s_grid11.Put(i - perPageUpgradeItemsSlotCount * 2, 1, itemSize);
}

for (u = 0; u < STONE_INVENTORY_MAX_NUM; ++u) {
if (!(item = me->GetStoneInventoryItem(u)))
continue;

BYTE itemSize = item->GetSize();

if (i < perPageStoneSlotCount) // Notice: This is adjusted for 3 Pages only!
s_grid12.Put(i, 1, itemSize);
else if (i < perPageStoneSlotCount * 2)
s_grid13.Put(i - perPageStoneSlotCount, 1, itemSize);
else if (i < perPageStoneSlotCount * 3)
s_grid14.Put(i - perPageStoneSlotCount * 2, 1, itemSize);
}

for (r = 0; r < BOX_INVENTORY_MAX_NUM; ++r) {
if (!(item = me->GetBoxInventoryItem(r)))
continue;

BYTE itemSize = item->GetSize();

if (i < perPageBoxSlotCount) // Notice: This is adjusted for 3 Pages only!
s_grid15.Put(i, 1, itemSize);
else if (i < perPageBoxSlotCount * 2)
s_grid16.Put(i - perPageBoxSlotCount, 1, itemSize);
else if (i < perPageBoxSlotCount * 3)
s_grid17.Put(i - perPageBoxSlotCount * 2, 1, itemSize);
}

for (a = 0; a < EFSUN_INVENTORY_MAX_NUM; ++a) {
if (!(item = me->GetEfsunInventoryItem(a)))
continue;

BYTE itemSize = item->GetSize();

if (i < perPageEfsunSlotCount) // Notice: This is adjusted for 3 Pages only!
s_grid18.Put(i, 1, itemSize);
else if (i < perPageEfsunSlotCount * 2)
s_grid19.Put(i - perPageEfsunSlotCount, 1, itemSize);
else if (i < perPageEfsunSlotCount * 3)
s_grid20.Put(i - perPageEfsunSlotCount * 2, 1, itemSize);
}

for (l = 0; l < CICEK_INVENTORY_MAX_NUM; ++l) {
if (!(item = me->GetCicekInventoryItem(l)))
continue;

BYTE itemSize = item->GetSize();

if (i < perPageCicekSlotCount) // Notice: This is adjusted for 3 Pages only!
s_grid21.Put(i, 1, itemSize);
else if (i < perPageCicekSlotCount * 2)
s_grid22.Put(i - perPageCicekSlotCount, 1, itemSize);
else if (i < perPageCicekSlotCount * 3)
s_grid23.Put(i - perPageCicekSlotCount * 2, 1, itemSize);
}


// ¾Æ... ¹º°¡ °³º´½Å °°Áö¸¸... ¿ëÈ¥¼® Àκ¥À» ³ë¸Ö Àκ¥ º¸°í µû¶ó ¸¸µç ³» À߸øÀÌ´Ù ¤Ğ¤Ğ
static std::vector <WORD> s_vDSGrid(DRAGON_SOUL_INVENTORY_MAX_NUM);

// ÀÏ´Ü ¿ëÈ¥¼®À» ±³È¯ÇÏÁö ¾ÊÀ» °¡´É¼ºÀÌ Å©¹Ç·Î, ¿ëÈ¥¼® Àκ¥ º¹»ç´Â ¿ëÈ¥¼®ÀÌ ÀÖÀ» ¶§ Çϵµ·Ï ÇÑ´Ù.
bool bDSInitialized = false;

for (i = 0; i < EXCHANGE_ITEM_MAX_NUM; ++i)
{
if (!(item = m_apItems))
continue;

if (item->IsDragonSoul())
{
if (!victim->DragonSoul_IsQualified())
{
return false;
}

if (!bDSInitialized)
{
bDSInitialized = true;
victim->CopyDragonSoulItemGrid(s_vDSGrid);
}

bool bExistEmptySpace = false;
WORD wBasePos = DSManager::instance().GetBasePosition(item);
if (wBasePos >= DRAGON_SOUL_INVENTORY_MAX_NUM)
return false;

for (int i = 0; i < DRAGON_SOUL_BOX_SIZE; i++)
{
WORD wPos = wBasePos + i;
if (0 == s_vDSGrid[wPos]) // @fixme159 (wBasePos to wPos)
{
bool bEmpty = true;
for (int j = 1; j < item->GetSize(); j++)
{
if (s_vDSGrid[wPos + j * DRAGON_SOUL_BOX_COLUMN_NUM])
{
bEmpty = false;
break;
}
}
if (bEmpty)
{
for (int j = 0; j < item->GetSize(); j++)
{
s_vDSGrid[wPos + j * DRAGON_SOUL_BOX_COLUMN_NUM] = wPos + 1;
}
bExistEmptySpace = true;
break;
}
}
if (bExistEmptySpace)
break;
}
if (!bExistEmptySpace)
return false;
}
ENABLE_SPLIT_INVENTORY_SYSTEM
else if (item->IsSkillBook())
{
BYTE itemSize = item->GetSize();
int iPos = s_grid6.FindBlank(1, itemSize);
if (iPos >= 0) {
s_grid6.Put(iPos, 1, itemSize);
continue;
}

iPos = s_grid7.FindBlank(1, itemSize);
if (iPos >= 0) {
s_grid7.Put(iPos, 1, itemSize);
continue;
}

iPos = s_grid8.FindBlank(1, itemSize);
if (iPos >= 0) {
s_grid8.Put(iPos, 1, itemSize);
continue;
}

return false;
}
else if (item->IsUpgradeItem())
{
BYTE itemSize = item->GetSize();
int iPos = s_grid9.FindBlank(1, itemSize);
if (iPos >= 0) {
s_grid9.Put(iPos, 1, itemSize);
continue;
}

iPos = s_grid10.FindBlank(1, itemSize);
if (iPos >= 0) {
s_grid10.Put(iPos, 1, itemSize);
continue;
}

iPos = s_grid11.FindBlank(1, itemSize);
if (iPos >= 0) {
s_grid11.Put(iPos, 1, itemSize);
continue;
}

return false;
}
else if (item->IsStone())
{
BYTE itemSize = item->GetSize();
int iPos = s_grid12.FindBlank(1, itemSize);
if (iPos >= 0) {
s_grid12.Put(iPos, 1, itemSize);
continue;
}

iPos = s_grid13.FindBlank(1, itemSize);
if (iPos >= 0) {
s_grid13.Put(iPos, 1, itemSize);
continue;
}

iPos = s_grid14.FindBlank(1, itemSize);
if (iPos >= 0) {
s_grid14.Put(iPos, 1, itemSize);
continue;
}

return false;
}
else if (item->IsBox())
{
BYTE itemSize = item->GetSize();
int iPos = s_grid15.FindBlank(1, itemSize);
if (iPos >= 0) {
s_grid15.Put(iPos, 1, itemSize);
continue;
}

iPos = s_grid16.FindBlank(1, itemSize);
if (iPos >= 0) {
s_grid16.Put(iPos, 1, itemSize);
continue;
}

iPos = s_grid17.FindBlank(1, itemSize);
if (iPos >= 0) {
s_grid17.Put(iPos, 1, itemSize);
continue;
}

return false;
}
else if (item->IsEfsun())
{
BYTE itemSize = item->GetSize();
int iPos = s_grid18.FindBlank(1, itemSize);
if (iPos >= 0) {
s_grid18.Put(iPos, 1, itemSize);
continue;
}

iPos = s_grid19.FindBlank(1, itemSize);
if (iPos >= 0) {
s_grid19.Put(iPos, 1, itemSize);
continue;
}

iPos = s_grid20.FindBlank(1, itemSize);
if (iPos >= 0) {
s_grid20.Put(iPos, 1, itemSize);
continue;
}

return false;
}
else if (item->IsCicek())
{
BYTE itemSize = item->GetSize();
int iPos = s_grid21.FindBlank(1, itemSize);
if (iPos >= 0) {
s_grid21.Put(iPos, 1, itemSize);
continue;
}

iPos = s_grid22.FindBlank(1, itemSize);
if (iPos >= 0) {
s_grid22.Put(iPos, 1, itemSize);
continue;
}

iPos = s_grid23.FindBlank(1, itemSize);
if (iPos >= 0) {
s_grid23.Put(iPos, 1, itemSize);
continue;
}

return false;
}

else
{
int iPos;

if ((iPos = s_grid1.FindBlank(1, item->GetSize())) >= 0)
{
s_grid1.Put(iPos, 1, item->GetSize());
}
else if ((iPos = s_grid2.FindBlank(1, item->GetSize())) >= 0)
{
s_grid2.Put(iPos, 1, item->GetSize());
}
else if ((iPos = s_grid3.FindBlank(1, item->GetSize())) >= 0)
{
s_grid3.Put(iPos, 1, item->GetSize());
}
else if ((iPos = s_grid4.FindBlank(1, item->GetSize())) >= 0)
{
s_grid4.Put(iPos, 1, item->GetSize());
}
else if ((iPos = s_grid4.FindBlank(1, item->GetSize())) >= 0)
{
s_grid5.Put(iPos, 1, item->GetSize());
}
else
return false;
}
}

return true;
}

// ±³È¯ ³¡ (¾ÆÀÌÅÛ°ú µ· µîÀ» ½ÇÁ¦·Î ¿Å±ä´Ù)
bool CExchange::Done()
{
int empty_pos, i;
LPITEM item;

LPCHARACTER victim = GetCompany()->GetOwner();

for (i = 0; i < EXCHANGE_ITEM_MAX_NUM; ++i)
{
if (!(item = m_apItems))
continue;

if (item->IsDragonSoul())
empty_pos = victim->GetEmptyDragonSoulInventory(item);
ENABLE_SPLIT_INVENTORY_SYSTEM
else if (item->IsSkillBook())
empty_pos = victim->GetEmptySkillBookInventory(item->GetSize());
else if (item->IsUpgradeItem())
empty_pos = victim->GetEmptyUpgradeItemsInventory(item->GetSize());
else if (item->IsStone())
empty_pos = victim->GetEmptyStoneInventory(item->GetSize());
else if (item->IsBox())
empty_pos = victim->GetEmptyBoxInventory(item->GetSize());
else if (item->IsEfsun())
empty_pos = victim->GetEmptyEfsunInventory(item->GetSize());
else if (item->IsCicek())
empty_pos = victim->GetEmptyCicekInventory(item->GetSize());

else
empty_pos = victim->GetEmptyInventory(item->GetSize());

if (empty_pos < 0)
{
sys_err("Exchange::Done : Cannot find blank position in inventory %s <-> %s item %s",
m_pOwner->GetName(), victim->GetName(), item->GetName());
continue;
}

assert(empty_pos >= 0);

if (item->GetVnum() == 90008 || item->GetVnum() == 90009) // VCARD
{
VCardUse(m_pOwner, victim, item);
continue;
}

m_pOwner->SyncQuickslot(QUICKSLOT_TYPE_ITEM, item->GetCell(), 255);

item->RemoveFromCharacter();
if (item->IsDragonSoul())
item->AddToCharacter(victim, TItemPos(DRAGON_SOUL_INVENTORY, empty_pos));
ENABLE_SPLIT_INVENTORY_SYSTEM
else if (item->IsSkillBook())
item->AddToCharacter(victim, TItemPos(INVENTORY, empty_pos));
else if (item->IsUpgradeItem())
item->AddToCharacter(victim, TItemPos(INVENTORY, empty_pos));
else if (item->IsStone())
item->AddToCharacter(victim, TItemPos(INVENTORY, empty_pos));
else if (item->IsBox())
item->AddToCharacter(victim, TItemPos(INVENTORY, empty_pos));
else if (item->IsEfsun())
item->AddToCharacter(victim, TItemPos(INVENTORY, empty_pos));
else if (item->IsCicek())
item->AddToCharacter(victim, TItemPos(INVENTORY, empty_pos));

else
item->AddToCharacter(victim, TItemPos(INVENTORY, empty_pos));
ITEM_MANAGER::instance().FlushDelayedSave(item);

item->SetExchanging(false);
{
char exchange_buf[51];

snprintf(exchange_buf, sizeof(exchange_buf), "%s %u %u", item->GetName(), GetOwner()->GetPlayerID(), item->GetCount());
LogManager::instance().ItemLog(victim, item, "EXCHANGE_TAKE", exchange_buf);

snprintf(exchange_buf, sizeof(exchange_buf), "%s %u %u", item->GetName(), victim->GetPlayerID(), item->GetCount());
LogManager::instance().ItemLog(GetOwner(), item, "EXCHANGE_GIVE", exchange_buf);

if (item->GetVnum() >= 80003 && item->GetVnum() <= 80007)
{
LogManager::instance().GoldBarLog(victim->GetPlayerID(), item->GetID(), EXCHANGE_TAKE, "");
LogManager::instance().GoldBarLog(GetOwner()->GetPlayerID(), item->GetID(), EXCHANGE_GIVE, "");
}
}

m_apItems = NULL;
}

if (m_lGold)
{
GetOwner()->PointChange(POINT_GOLD, -m_lGold, true);
victim->PointChange(POINT_GOLD, m_lGold, true);

if (m_lGold > 1000)
{
char exchange_buf[51];
snprintf(exchange_buf, sizeof(exchange_buf), "%u %s", GetOwner()->GetPlayerID(), GetOwner()->GetName());
LogManager::instance().CharLog(victim, m_lGold, "EXCHANGE_GOLD_TAKE", exchange_buf);

snprintf(exchange_buf, sizeof(exchange_buf), "%u %s", victim->GetPlayerID(), victim->GetName());
LogManager::instance().CharLog(GetOwner(), m_lGold, "EXCHANGE_GOLD_GIVE", exchange_buf);
}
}

m_pGrid->Clear();
return true;
}

// ±³È¯À» µ¿ÀÇ
bool CExchange::Accept(bool bAccept)
{
if (m_bAccept == bAccept)
return true;

m_bAccept = bAccept;

// µÑ ´Ù µ¿ÀÇ ÇßÀ¸¹Ç·Î ±³È¯ ¼º¸³
if (m_bAccept && GetCompany()->m_bAccept)
{
int iItemCount;

LPCHARACTER victim = GetCompany()->GetOwner();

//PREVENT_PORTAL_AFTER_EXCHANGE
GetOwner()->SetExchangeTime();
victim->SetExchangeTime();
//END_PREVENT_PORTAL_AFTER_EXCHANGE

// @fixme150 BEGIN
if (quest::CQuestManager::instance().GetPCForce(GetOwner()->GetPlayerID())->IsRunning() == true)
{
GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot trade if you're using quests"));
victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot trade if the other part using quests"));
goto EXCHANGE_END;
}
else if (quest::CQuestManager::instance().GetPCForce(victim->GetPlayerID())->IsRunning() == true)
{
victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot trade if you're using quests"));
GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot trade if the other part using quests"));
goto EXCHANGE_END;
}
// @fixme150 END

// exchange_check ¿¡¼´Â ±³È¯ÇÒ ¾ÆÀÌÅÛµéÀÌ Á¦ÀÚ¸®¿¡ ÀÖ³ª È®ÀÎÇϰí,
// ¿¤Å©µµ ÃæºĞÈ÷ ÀÖ³ª È®ÀÎÇÑ´Ù, µÎ¹øÂ° ÀÎÀÚ·Î ±³È¯ÇÒ ¾ÆÀÌÅÛ °³¼ö
// ¸¦ ¸®ÅÏÇÑ´Ù.
if (!Check(&iItemCount))
{
GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("µ·ÀÌ ºÎÁ·Çϰųª ¾ÆÀÌÅÛÀÌ Á¦ÀÚ¸®¿¡ ¾ø½À´Ï´Ù."));
victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("»ó´ë¹æÀÇ µ·ÀÌ ºÎÁ·Çϰųª ¾ÆÀÌÅÛÀÌ Á¦ÀÚ¸®¿¡ ¾ø½À´Ï´Ù."));
goto EXCHANGE_END;
}

// ¸®ÅÏ ¹ŞÀº ¾ÆÀÌÅÛ °³¼ö·Î »ó´ë¹æÀÇ ¼ÒÁöǰ¿¡ ³²Àº ÀÚ¸®°¡ ÀÖ³ª È®ÀÎÇÑ´Ù.
if (!CheckSpace())
{
GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("»ó´ë¹æÀÇ ¼ÒÁöǰ¿¡ ºó °ø°£ÀÌ ¾ø½À´Ï´Ù."));
victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("¼ÒÁöǰ¿¡ ºó °ø°£ÀÌ ¾ø½À´Ï´Ù."));
goto EXCHANGE_END;
}

// »ó´ë¹æµµ ¸¶Âù°¡Áö·Î..
if (!GetCompany()->Check(&iItemCount))
{
victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("µ·ÀÌ ºÎÁ·Çϰųª ¾ÆÀÌÅÛÀÌ Á¦ÀÚ¸®¿¡ ¾ø½À´Ï´Ù."));
GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("»ó´ë¹æÀÇ µ·ÀÌ ºÎÁ·Çϰųª ¾ÆÀÌÅÛÀÌ Á¦ÀÚ¸®¿¡ ¾ø½À´Ï´Ù."));
goto EXCHANGE_END;
}

if (!GetCompany()->CheckSpace())
{
victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("»ó´ë¹æÀÇ ¼ÒÁöǰ¿¡ ºó °ø°£ÀÌ ¾ø½À´Ï´Ù."));
GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("¼ÒÁöǰ¿¡ ºó °ø°£ÀÌ ¾ø½À´Ï´Ù."));
goto EXCHANGE_END;
}

if (db_clientdesc->GetSocket() == INVALID_SOCKET)
{
sys_err("Cannot use exchange feature while DB cache connection is dead.");
victim->ChatPacket(CHAT_TYPE_INFO, "Unknown error");
GetOwner()->ChatPacket(CHAT_TYPE_INFO, "Unknown error");
goto EXCHANGE_END;
}

if (Done())
{
if (m_lGold) // µ·ÀÌ ÀÖÀ» ‹š¸¸ ÀúÀå
GetOwner()->Save();

if (GetCompany()->Done())
{
if (GetCompany()->m_lGold) // µ·ÀÌ ÀÖÀ» ¶§¸¸ ÀúÀå
victim->Save();

// INTERNATIONAL_VERSION
GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s ´Ô°úÀÇ ±³È¯ÀÌ ¼º»ç µÇ¾ú½À´Ï´Ù."), victim->GetName());
victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s ´Ô°úÀÇ ±³È¯ÀÌ ¼º»ç µÇ¾ú½À´Ï´Ù."), GetOwner()->GetName());
// END_OF_INTERNATIONAL_VERSION
}
}

EXCHANGE_END:
Cancel();
return false;
}
else
{
// ¾Æ´Ï¸é accept¿¡ ´ëÇÑ ÆĞŶÀ» º¸³»ÀÚ.
exchange_packet(GetOwner(), EXCHANGE_SUBHEADER_GC_ACCEPT, true, m_bAccept, NPOS, 0);
exchange_packet(GetCompany()->GetOwner(), EXCHANGE_SUBHEADER_GC_ACCEPT, false, m_bAccept, NPOS, 0);
return true;
}
}

// ±³È¯ Ãë¼Ò
void CExchange::Cancel()
{
exchange_packet(GetOwner(), EXCHANGE_SUBHEADER_GC_END, 0, 0, NPOS, 0);
GetOwner()->SetExchange(NULL);

for (int i = 0; i < EXCHANGE_ITEM_MAX_NUM; ++i)
{
if (m_apItems)
m_apItems->SetExchanging(false);
}

if (GetCompany())
{
GetCompany()->SetCompany(NULL);
GetCompany()->Cancel();
}

M2_DELETE(this);







Kod:
char_item.cpp & char.h Açılır

BYTE bCell -> UINT bCell
BYTE bDestCell -> UINT bDestCell

Şeklinde tümünü değiştirsin





İNDİRME LİNKİ



64867_2510235b1c5be4cc70075c5a1a25fce3.png

Yeni Ek Envanter Sistemi | K ENVANTER

Metin2 Lobby olarak sunucu geliştiricileri için yenilikçi ve kullanıcı dostu çözümler geliştirmeye devam ediyoruz. Bu bağlamda, K ENVANTER adlı yeni ek envanter sistemi tüm Metin2 özel sunucularında kullanılmak üzere tasarlandı. Bu sistem, hem oyun içi deneyimi artırmayı hem de geliştiricilerin mevcut sistemlere entegre edebilmesini kolaylaştırmayı hedeflemektedir.

K ENVANTER Nedir?
K ENVANTER; Metin2 oyununda standart envanterin dışında ek alanlar sunan, oyuncuların daha fazla eşya taşımalarını ve organize bir şekilde kullanmalarını sağlayan gelişmiş bir sistemdir. Bu sistem sayesinde oyuncular, standart envanterin sınırlarını aşarak envanterlerini genişletebilir, farklı kategorilerde eşyalar saklayabilirler.

Özellikleri Nelerdir?
Oyuncuya ek envanter alanları sağlar.
Eşya organizasyonu için kategorilendirme destekleri sunar.
C++ tabanlı sunucu tarafında kolay entegrasyon imkanı sunar.
Python GUI ile kullanıcı arayüzü özelleştirilebilir.
Uiscript dosyalarıyla istemci tarafında sorunsuz entegrasyon sağlar.
DB Core ile veritabanı senkronizasyonu sağlanır.

Neden K ENVANTER?
Geleneksel Metin2 sunucularında envanter sınırlamaları oyuncuların deneyimini olumsuz etkileyebiliyor. Özellikle PVP sunucularında eşya miktarı arttıkça bu durum daha da hissediliyor. K ENVANTER ile bu sorun çözülüyor. Geliştiriciler, sistemi mevcut kaynak kodlarına kolayca entegre edebilirken, oyuncular ise daha rahat ve organize bir oyun içi envanter yapısıyla karşılaşmaktadır.

Kurulum ve Entegrasyon
K ENVANTER, game src ve client src ile uyumlu çalışacak şekilde tasarlanmıştır. Kurulum için gerekli kaynak kodlar C++ ve Python tabanlıdır. Py Root ve Pack yapılarıyla birlikte sistemin kurulumu oldukça basitleştirilmiştir. Geliştiriciler, Martysama tarzı modüler yapı sayesinde sistemi kolayca özelleştirebilir ve test edebilirler.

Veritabanı Entegrasyonu
Sistem, DB Core yapısını kullanarak envanter verilerinin güvenli ve hızlı bir şekilde saklanmasını sağlar. Auth ve Game sunucuları arasında veri akışı optimize edilmiştir. Bu sayede hem performans hem de güvenlik açısından güçlü bir altyapı oluşturulmuştur.

Kullanıcı Arayüzü ve Deneyimi
K ENVANTER, kullanıcı dostu bir arayüz sunar. Py GUI ve uiscript tabanlı olarak geliştirilen arayüz, farklı çözünürlüklerde ve ekran boyutlarında sorunsuz çalışır. Oyuncular, yeni envanter alanlarını kolayca erişebilir ve eşyalarını kategorilere ayırabilirler. Bu sayede oyun içi zaman yönetimi ve ekipman seçimi daha verimli hale gelir.

Destek ve Geliştirme
Metin2 geliştiricileri için sürekli güncellenen bu sistem, Metin2 Lobby forumları üzerinden desteklenmektedir. Topluluk tarafından öneriler doğrultusunda yeni özellikler eklenmekte ve sistem sürekli geliştirilmektedir. Geliştiriciler, source edit ve compile süreçlerinde kolaylıklar sunan bu yapıyı forumlarımızdan indirebilir ve projelerine entegre edebilirler.

Sonuç
K ENVANTER, Metin2 özel sunucularında yeni nesil envanter yönetim sistemidir. Hem geliştirici hem de oyuncu odaklı düşünilerek tasarlanmış bu sistem, sunucu sahiplerine avantajlar sunarken, oyunculara da daha iyi bir deneyim kazandırmaktadır. Gelişmiş altyapısı, kolay entegrasyonu ve kullanıcı dostu arayüzü ile K ENVANTER, Metin2 geliştirme dünyasında önemli bir adım olarak öne çıkmaktadır.


New Additional Inventory System | K INVENTORY

Metin2 Lobby continues to develop innovative and user-friendly solutions for server developers. In this context, the new additional inventory system called K INVENTORY has been designed for use on all Metin2 private servers. This system aims to enhance the in-game experience while also making it easier for developers to integrate with existing systems.

What is K INVENTORY?
K INVENTORY is an advanced system that provides extra inventory slots beyond the standard Metin2 inventory, allowing players to carry more items and manage them in an organized manner. With this system, players can expand their inventories beyond the limits of the default one and store items in different categories.

Features Include:
Provides additional inventory slots for players.
Offers category support for item organization.
Enables easy integration into server-side code based on C++.
The user interface can be customized via Python GUI.
Ensures smooth client-side integration with uiscript files.
Database synchronization provided through DB Core.

Why Choose K INVENTORY?
In traditional Metin2 servers, inventory limitations can negatively impact player experience. Especially in PVP-oriented servers, this becomes more noticeable as item quantity increases. K INVENTORY solves this issue. Developers can easily integrate the system into their existing source codes, while players benefit from a more comfortable and organized in-game inventory structure.

Installation and Integration
Designed to work seamlessly with game src and client src, K INVENTORY uses C++ and Python-based source codes for its implementation. Installation has been simplified with Py Root and Pack structures. Thanks to modular designs like Martysama, developers can customize and test the system easily.

Database Integration
Using the DB Core structure, the system ensures secure and fast storage of inventory data. Data flow between Auth and Game servers has been optimized, creating a robust infrastructure in terms of both performance and security.

User Interface and Experience
K INVENTORY offers a user-friendly interface. Developed based on Py GUI and uiscript, the interface works smoothly across various resolutions and screen sizes. Players can access new inventory slots easily and sort items into categories, resulting in better in-game time management and equipment selection.

Support and Development
Continuously updated for Metin2 developers, this system is supported via Metin2 Lobby forums. Based on community feedback and suggestions, new features are added and the system is constantly improved. Developers can download this structure from our forums and integrate it into their projects, benefiting from the simplified source edit and compile processes.

Conclusion
K INVENTORY is the next-generation inventory management system for Metin2 private servers. Designed with both developer and player needs in mind, this system offers advantages to server owners while providing players with a better gaming experience. With its advanced infrastructure, easy integration, and user-friendly interface, K INVENTORY stands out as an important step forward in the world of Metin2 development.​
 

Şuan Bu Konuyu Görüntüleyen Kullanıcılar (Toplam : 0, Üye : 0, Misafir : 0)

Geri
Üst Alt