Nos eltelt már nagyjából 1 hét mióta ezt megcsináltam, szóval itt az ideje publikálni. Szóval akkor
Miről is lesz szó?
Mint azt a cím is mutatja, ezentúl lehetőség lesz 200-nál több tárgyat egyberakni. A leírás alapján nagyából 60k körüli érték a maximum, ugyan is WORD-ot használtam új változótípusnak (unsigned short). Természetesen amire szükségünk lesz hasonlóan a maximum szint megnöveléséhez (http://metin2hungary.net/index.php/topic,190814.msg1004131/topicseen.html#new) az indító és a szerver forrás, illetve majd kicsit bele kell túrni a mysql-be is, szóval navicatot bányásszuk elő. Na vágjunk is bele.
Indító
packet.hKeress rá erre:
typedef struct command_item_drop2és alatta cseréld le ezt:
BYTE count;
erre:
WORD count;
Aztán keress rá erre:
typedef struct command_item_movemajd alatta cseréld le ezt:
BYTE num;
erre:
WORD num;
Majd erre keress rá:
typedef struct SShopItemTableszintén alatta cseréld le ezt:
BYTE count;
erre:
WORD count;
Aztán ez alatt:
typedef struct packet_set_item2cseréld le ezt:
BYTE count;
erre:
WORD count;
Majd ez alatt:
typedef struct packet_update_itemcseréld le ezt:
BYTE count;
erre:
WORD count;
Aztán ez alatt:
typedef struct SEquipmentItemSetcseréld le ezt:
BYTE count;
erre:
WORD count;
PythonNetworkStreamPhaseGame.cpp->RecvExchangePacket funkcióCseréljül le ezt:
CPythonExchange::Instance().SetItemToSelf(iSlotIndex, exchange_packet.arg1, (BYTE) exchange_packet.arg3);
erre:
CPythonExchange::Instance().SetItemToSelf(iSlotIndex, exchange_packet.arg1, (WORD) exchange_packet.arg3);
illetve ezt:
CPythonExchange::Instance().SetItemToTarget(iSlotIndex, exchange_packet.arg1, (BYTE) exchange_packet.arg3);
erre:
CPythonExchange::Instance().SetItemToTarget(iSlotIndex, exchange_packet.arg1, (WORD) exchange_packet.arg3);
pythonexchange.cpp:Ezt:
BYTE CPythonExchange::GetItemCountFromTarget(BYTE pos)
Cseréljük le erre:
WORD CPythonExchange::GetItemCountFromTarget(BYTE pos)
Majd ezt:
BYTE CPythonExchange::GetItemCountFromSelf(BYTE pos)
Erre:
WORD CPythonExchange::GetItemCountFromSelf(BYTE pos)
Aztán ezt:
void CPythonExchange::SetItemToTarget(DWORD pos, DWORD vnum, BYTE count)
Erre:
void CPythonExchange::SetItemToTarget(DWORD pos, DWORD vnum, WORD count)
Végül ezt:
void CPythonExchange::SetItemToSelf(DWORD pos, DWORD vnum, BYTE count)
Erre:
void CPythonExchange::SetItemToSelf(DWORD pos, DWORD vnum, WORD count)
pythonexchange.hEzeket:
BYTE GetItemCountFromTarget(BYTE pos);
BYTE GetItemCountFromSelf(BYTE pos);
void SetItemToTarget(DWORD pos, DWORD vnum, BYTE count);
void SetItemToSelf(DWORD pos, DWORD vnum, BYTE count);
BYTE item_count[EXCHANGE_ITEM_MAX_NUM];
erre:
WORD GetItemCountFromTarget(BYTE pos);
WORD GetItemCountFromSelf(BYTE pos);
void SetItemToTarget(DWORD pos, DWORD vnum, WORD count);
void SetItemToSelf(DWORD pos, DWORD vnum, WORD count);
WORD item_count[EXCHANGE_ITEM_MAX_NUM];
PythonNetworkStreamPhaseGameItem.cppA következő teljes funkciót mindenestül:
bool CPythonNetworkStream::SendShopSellPacketNew
Cseréljük le erre:
bool CPythonNetworkStream::SendShopSellPacketNew(BYTE bySlot, WORD byCount)
{
typedef struct fckOFF
{
BYTE bySlot;
WORD byCount;
} TfckOFF;
if (!__CanActMainInstance())
return true;
TPacketCGShop PacketShop;
PacketShop.header = HEADER_CG_SHOP;
PacketShop.subheader = SHOP_SUBHEADER_CG_SELL2;
TfckOFF second;
second.byCount = byCount;
second.bySlot = bySlot;
if (!Send(sizeof(TPacketCGShop), &PacketShop))
{
Tracef("SendShopSellPacket Error\n");
return false;
}
if (!Send(sizeof(TfckOFF), &second))
{
Tracef("SendShopAddSellPacket Error\n");
return false;
}
/*if (!Send(sizeof(WORD), &byCount))
{
Tracef("SendShopAddSellPacket Error\n");
return false;
}*/
Tracef(" SendShopSellPacketNew(bySlot=%d, byCount=%u)\n", bySlot, byCount);
return SendSequence();
}
Majd ezeket:
bool CPythonNetworkStream::SendItemMovePacket(TItemPos pos, TItemPos change_pos, BYTE num)
bool CPythonNetworkStream::SendSafeBoxItemMovePacket(BYTE bySourcePos, BYTE byTargetPos, BYTE byCount)
Erre:
bool CPythonNetworkStream::SendItemMovePacket(TItemPos pos, TItemPos change_pos, WORD num)
bool CPythonNetworkStream::SendSafeBoxItemMovePacket(BYTE bySourcePos, BYTE byTargetPos, WORD byCount)
pythonplayermodule.cppCseréljük le ezt a funkciót teljesen:
PyObject * playerSetItemCount(PyObject* poSelf, PyObject* poArgs)
Erre:
PyObject * playerSetItemCount(PyObject* poSelf, PyObject* poArgs)
{
switch (PyTuple_Size(poArgs))
{
case 2:
{
int iSlotIndex;
if (!PyTuple_GetInteger(poArgs, 0, &iSlotIndex))
return Py_BuildException();
WORD wCount;
if (!PyTuple_GetInteger(poArgs, 1, &wCount))
return Py_BuildException();
if (0 == wCount)
return Py_BuildException();
CPythonPlayer::Instance().SetItemCount(TItemPos (INVENTORY, iSlotIndex), wCount);
return Py_BuildNone();
}
case 3:
{
TItemPos Cell;
if (!PyTuple_GetByte(poArgs, 0, &Cell.window_type))
return Py_BuildException();
if (!PyTuple_GetInteger(poArgs, 1, &Cell.cell))
return Py_BuildException();
WORD wCount;
if (!PyTuple_GetInteger(poArgs, 2, &wCount))
return Py_BuildException();
CPythonPlayer::Instance().SetItemCount(Cell, wCount);
return Py_BuildNone();
}
default:
return Py_BuildException();
}
}
PythonNetworkStreamModule.cppElőbbihez hasonlóan cseréljük le a következő funkciót teljesen:
PyObject* netSendItemMovePacket(PyObject* poSelf, PyObject* poArgs)
Erre:
PyObject* netSendItemMovePacket(PyObject* poSelf, PyObject* poArgs)
{
TItemPos Cell;
TItemPos ChangeCell;
int num;
switch (PyTuple_Size(poArgs))
{
case 3:
if (!PyTuple_GetInteger(poArgs, 0, &Cell.cell))
return Py_BuildException();
if (!PyTuple_GetInteger(poArgs, 1, &ChangeCell.cell))
return Py_BuildException();
if (!PyTuple_GetInteger(poArgs, 2, &num))
return Py_BuildException();
break;
case 5:
{
if (!PyTuple_GetByte(poArgs, 0, &Cell.window_type))
return Py_BuildException();
if (!PyTuple_GetInteger(poArgs, 1, &Cell.cell))
return Py_BuildException();
if (!PyTuple_GetByte(poArgs, 2, &ChangeCell.window_type))
return Py_BuildException();
if (!PyTuple_GetInteger(poArgs, 3, &ChangeCell.cell))
return Py_BuildException();
if (!PyTuple_GetInteger(poArgs, 4, &num))
return Py_BuildException();
}
break;
default:
return Py_BuildException();
}
CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance();
rkNetStream.SendItemMovePacket(Cell, ChangeCell, (WORD) num);//ez a sor az
return Py_BuildNone();
}
GameType.hKeressünk rá erre:
typedef struct packet_itemMajd alatta írjuk át ezt:
BYTE count;
Erre:
WORD count;
Majd erre keressünk rá:
typedef struct packet_shop_itemMajd alatta írjuk át ezt:
BYTE count;
Erre:
WORD count;
AbstractPlayer.hEzt:
virtual void SetItemCount(TItemPos itemPos, BYTE byCount) = 0;
Erre:
virtual void SetItemCount(TItemPos itemPos, WORD byCount) = 0;
PythonPlayer.cppEzt:
void CPythonPlayer::SetItemCount(TItemPos Cell, BYTE byCount)
Erre:
void CPythonPlayer::SetItemCount(TItemPos Cell, WORD byCount)
PythonPlayer.hEzt:
void SetItemCount(TItemPos Cell, BYTE byCount);
Erre:
void SetItemCount(TItemPos Cell, WORD byCount);
PythonNetworkStream.hEzeket:
bool SendSafeBoxItemMovePacket(BYTE bySourcePos, BYTE byTargetPos, BYTE byCount);
bool SendShopSellPacketNew(BYTE bySlot, BYTE byCount);
bool SendItemMovePacket(TItemPos pos, TItemPos change_pos, BYTE num);
Erre:
bool SendSafeBoxItemMovePacket(BYTE bySourcePos, BYTE byTargetPos, WORD byCount);
bool SendShopSellPacketNew(BYTE bySlot, WORD byCount);
bool SendItemMovePacket(TItemPos pos, TItemPos change_pos, WORD num);
Ezzel kész is van a kliens, lehet fordítani.
Szerver oldal:
common/tables.hErre keress rá:
typedef struct SShopItemTablemajd alatta ezt:
BYTE count;
Írd át erre:
WORD count;
packet.hKeress rá erre:
typedef struct command_item_drop2majd alatta ezt írd át:
BYTE count;
Erre:
WORD count;
Ez alatt:
typedef struct command_item_moveEzt:
BYTE count;
Erre:
WORD count;
Majd ez alatt:
typedef struct packet_item_setEzt:
BYTE count;
Erre:
WORD count;
Aztán ez alatt:
typedef struct packet_item_updateEzt:
BYTE count;
Erre:
WORD count;
Majd ez alatt:
struct packet_shop_itemEzt:
BYTE count;
Erre:
WORD count;
Majd ez alatt:
typedef struct pakcet_view_equipEzt:
BYTE count;
Erre:
WORD count;
input_main.cppA következő funkciót teljesen cseréljük le:
int CInputMain::Shop(LPCHARACTER ch, const char * data, size_t uiBytes)
Erre:
int CInputMain::Shop(LPCHARACTER ch, const char * data, size_t uiBytes)
{
typedef struct fckOFF
{
BYTE bySlot;
WORD byCount;
} TfckOFF;
TPacketCGShop * p = (TPacketCGShop *) data;
if (uiBytes < sizeof(TPacketCGShop))
return -1;
if (test_server)
sys_log(0, "CInputMain::Shop() ==> SubHeader %d", p->subheader);
const char * c_pData = data + sizeof(TPacketCGShop);
uiBytes -= sizeof(TPacketCGShop);
switch (p->subheader)
{
case SHOP_SUBHEADER_CG_END:
sys_log(1, "INPUT: %s SHOP: END", ch->GetName());
CShopManager::instance().StopShopping(ch);
return 0;
case SHOP_SUBHEADER_CG_BUY:
{
if (uiBytes < sizeof(BYTE) + sizeof(BYTE))
return -1;
BYTE bPos = *(c_pData + 1);
sys_log(1, "INPUT: %s SHOP: BUY %d", ch->GetName(), bPos);
CShopManager::instance().Buy(ch, bPos);
return (sizeof(BYTE) + sizeof(BYTE));
}
case SHOP_SUBHEADER_CG_SELL:
{
if (uiBytes < sizeof(BYTE))
return -1;
BYTE pos = *c_pData;
sys_log(0, "INPUT: %s SHOP: SELL", ch->GetName());
CShopManager::instance().Sell(ch, pos);
return sizeof(BYTE);
}
case SHOP_SUBHEADER_CG_SELL2:
{
if (uiBytes < sizeof(TfckOFF))
return -1;
TfckOFF*p2 = (TfckOFF*)c_pData;
/*BYTE pos = *(c_pData++);
WORD count = *(c_pData);*/
sys_log(0, "INPUT: %s SHOP: SELL2", ch->GetName());
CShopManager::instance().Sell(ch, p2->bySlot, p2->byCount);
return sizeof(TfckOFF);
}
default:
sys_err("CInputMain::Shop : Unknown subheader %d : %s", p->subheader, ch->GetName());
break;
}
return 0;
}
shop_manager.cppEzt cseréljük le:
void CShopManager::Sell(LPCHARACTER ch, BYTE bCell, BYTE bCount)
erre:
void CShopManager::Sell(LPCHARACTER ch, BYTE bCell, WORD bCount)
shop.hEz alatt:
typedef struct shop_itemEzt:
BYTE count;
erre:
WORD count;
shop_manager.hEzt:
void Sell(LPCHARACTER ch, BYTE bCell, BYTE bCount=0);
Erre:
void Sell(LPCHARACTER ch, BYTE bCell, WORD bCount=0);
char_item.cppEzt:
bool CHARACTER::DropItem(TItemPos Cell, BYTE bCount)
Erre:
bool CHARACTER::DropItem(TItemPos Cell, WORD bCount)
Majd ezt:
bool CHARACTER::MoveItem(TItemPos Cell, TItemPos DestCell, BYTE count)
Erre:
bool CHARACTER::MoveItem(TItemPos Cell, TItemPos DestCell, WORD count)
Illetve ezen belül ezt:
count = MIN(200 - item2->GetCount(), count);
Erre:
count = MIN(ITEM_MAX_COUNT - item2->GetCount(), count);
Majd ezt:
LPITEM CHARACTER::AutoGiveItem(DWORD dwItemVnum, BYTE bCount, int iRarePct, bool bMsg)
Erre:
LPITEM CHARACTER::AutoGiveItem(DWORD dwItemVnum, WORD bCount, int iRarePct, bool bMsg)
Majd szintén ezen belül ezt:
BYTE bCount2 = MIN(200 - item->GetCount(), bCount);
Erre:
WORD bCount2 = MIN(ITEM_MAX_COUNT - item->GetCount(), bCount);
A
PickupItem funkción belül pedig ezt:
BYTE bCount = item->GetCount();
Erre:
WORD bCount = item->GetCount();
Majd ezt:
BYTE bCount2 = MIN(200 - item2->GetCount(), bCount);
erre:
WORD bCount2 = MIN(ITEM_MAX_COUNT - item2->GetCount(), bCount);
item.cpp->DWORD CItem::GetCount()Ezt:
return MIN(m_dwCount, 200);
Erre:
return MIN(m_dwCount, ITEM_MAX_COUNT);
safebox.cppEzt:
bool CSafebox::MoveItem(BYTE bCell, BYTE bDestCell, BYTE count)
Erre:
bool CSafebox::MoveItem(BYTE bCell, BYTE bDestCell, WORD count)
Majd ezen belül ezt:
count = MIN(200 - item2->GetCount(), count);
Erre:
count = MIN(ITEM_MAX_COUNT - item2->GetCount(), count);
item_lenght.hItt állíthatod be, hogy mennyi legyen a max összerakható mennyiség. Írd át ezt:
ITEM_MAX_COUNT = 200,
Arra amire akarod (én 300-ra írtam át így tesztként)
char.hEzeket:
bool DropItem(TItemPos Cell, BYTE bCount=0);
bool MoveItem(TItemPos pos, TItemPos change_pos, BYTE num);
LPITEM AutoGiveItem(DWORD dwItemVnum, BYTE bCount=1, int iRarePct = -1, bool bMsg = true);
Erre:
bool DropItem(TItemPos Cell, WORD bCount=0);
bool MoveItem(TItemPos pos, TItemPos change_pos, WORD num);
LPITEM AutoGiveItem(DWORD dwItemVnum, WORD bCount=1, int iRarePct = -1, bool bMsg = true);
safebox.hEzt:
bool MoveItem(BYTE bCell, BYTE bDestCell, BYTE count);
Erre:
bool MoveItem(BYTE bCell, BYTE bDestCell, WORD count);
oxevent.cppEzt:
bool COXEventManager::GiveItemToAttender(DWORD dwItemVnum, BYTE count)
Erre:
bool COXEventManager::GiveItemToAttender(DWORD dwItemVnum, WORD count)
oxevent.hEzt:
bool GiveItemToAttender(DWORD dwItemVnum, BYTE count);
Erre:
bool GiveItemToAttender(DWORD dwItemVnum, WORD count);
A szerverrésszel is megvagyunk, a
db-t és a gamefilet is buildeljétek!
Adatbázis
Két egyszerű mozzanatot kell végrehajtanunk.
Item tábla->Desing table: count oszlopnál írjuk át tinyintről smallintre, illetve a lenghtet ha 999 nél nagyobb maximum stacket állítottunk be, akkor írjuk át 3-ról 4-re.shop_item tábla->Desing table: count oszlopnál írjuk át tinyintről smallintre
Ezzel meg is volnánk, külön köszönöm TheSLZ (http://metin2hungary.net/index.php?action=profile;u=109950)-nek, hogy letesztelte nekem az egészet.
Természetesen ebből is készült egy "egész estés" kisfilm, hasonlóan a maximum szinthez, szóval ha nagyon unatkozol, esetleg kukkants rá. Klikk (https://www.youtube.com/watch?v=gnKQyzwlj_k)
Amennyiben kérdés/probléma merülne fel az egésszel kapcsolatban, vagy esetleg valamilyen bugot találtak, PM-ben megtaláltok, illetve segítség->új téma létrehozása. (Az is megeshet, ha nem jó, hogy nem benned van a hiba, csak én felejtettem ki valamit a leírásból.)
További szép estét:
~masodikbela