Jump to content

Instant Pickup


Recommended Posts

  • Bronze

This is the hidden content, please

Metin2 Download

 

Welcome folks!

I brought you a small "system" (would call it modification instead), which will instantly pick up 45 (you can increase or decrease its size).

My goal was not to send packets each time we're trying to pick up items. I did not test it for hours, so I wouldn't recommend using it on a live server without proper tests.

So let's get started!

First, we will start on the client side, and there we will work in the UserInterface project.

Locale_inc.h:

Spoiler
Add: 
#define ENABLE_FAST_PICKUP

 

Packet.h:

Spoiler
Add:

#ifdef ENABLE_FAST_PICKUP
    HEADER_CG_ITEM_PICKUP_ALL                    = 32,
#endif

After: 

    HEADER_CG_QUEST_CONFIRM                     = 31,

Add:
#ifdef ENABLE_FAST_PICKUP
typedef struct command_item_pickup_all
{
	BYTE header;
	DWORD vids[FAST_PICKUP_MAX_NUM];
} TPacketCGItemPickUpAll;
#endif
After:
typedef struct command_item_pickup
{
	BYTE header;
	DWORD vid;
} TPacketCGItemPickUp;

PythonItem.h:

Spoiler
Add:
#ifdef ENABLE_FAST_PICKUP
		bool	GetCloseItems(const TPixelPosition& c_rPixelPosition, std::vector<DWORD>* pdwItemIDs, DWORD dwDistance = 300);
#endif
After:        
bool	GetCloseItem(const TPixelPosition & c_rPixelPosition, DWORD* pdwItemID, DWORD dwDistance=300);          

 

PythonItem.cpp

Spoiler
Add:
#ifdef ENABLE_FAST_PICKUP
bool CPythonItem::GetCloseItems(const TPixelPosition& c_rPixelPosition, std::vector<DWORD>* pdwItemIDs, DWORD dwDistance)
{
	DWORD dwCloseItemDistance = 1000 * 1000;

	TGroundItemInstanceMap::iterator i;
	int counter = 0;
	pdwItemIDs->reserve(FAST_PICKUP_MAX_NUM);
	for (i = m_GroundItemInstanceMap.begin(); i != m_GroundItemInstanceMap.end(); ++i)
	{
		if (counter == FAST_PICKUP_MAX_NUM)
			return true;

		TGroundItemInstance* pInstance = i->second;

		DWORD dwxDistance = DWORD(c_rPixelPosition.x - pInstance->v3EndPosition.x);
		DWORD dwyDistance = DWORD(c_rPixelPosition.y - (-pInstance->v3EndPosition.y));
		DWORD dwDistance = DWORD(dwxDistance * dwxDistance + dwyDistance * dwyDistance);

		if (dwDistance < dwCloseItemDistance)
		{
			pdwItemIDs->emplace_back(i->first);
		}
		counter++;
	}

	return true;
}
#endif
After:
bool CPythonItem::GetCloseMoney(const TPixelPosition & c_rPixelPosition, DWORD * pdwItemID, DWORD dwDistance)
{
	[...] 
}

PythonNetworkStream.h

Spoiler
Add:
#ifdef ENABLE_FAST_PICKUP
		bool SendItemPickUpAllPacket(TPacketCGItemPickUpAll& pack);
#endif
After:
bool SendItemPickUpPacket(DWORD vid);

 

PythonNetworkStreamPhaseGameItem.cpp

Spoiler
Add:
#ifdef ENABLE_FAST_PICKUP
bool CPythonNetworkStream::SendItemPickUpAllPacket(TPacketCGItemPickUpAll& pack)
{
	if (!__CanActMainInstance())
		return true;

	if (!Send(sizeof(TPacketCGItemPickUpAll), &pack))
	{
		Tracen("SendItemPickUpPacket Error");
		return false;
	}

	return SendSequence();
}
#endif
After:
bool CPythonNetworkStream::SendItemPickUpPacket(DWORD vid)
{
	[...]
}

PythonPlayerInput.cpp:

Spoiler
Modify void CPythonPlayer::PickCloseItem() like this:
void CPythonPlayer::PickCloseItem()
{
	CInstanceBase * pkInstMain = NEW_GetMainActorPtr();
	if (!pkInstMain)
		return;

	TPixelPosition kPPosMain;
	pkInstMain->NEW_GetPixelPosition(&kPPosMain);

#ifndef ENABLE_FAST_PICKUP
	DWORD dwItemID;
#endif
	CPythonItem& rkItem=CPythonItem::Instance();
#ifdef ENABLE_FAST_PICKUP
	std::vector<DWORD> itemIds;
	if (!rkItem.GetCloseItems(kPPosMain, &itemIds, __GetPickableDistance()))
		return;

	TPacketCGItemPickUpAll pack;
	pack.header = HEADER_CG_ITEM_PICKUP_ALL;
	memset(pack.vids, 0, sizeof(pack.vids));

	for (int i = 0; i < itemIds.size(); i++)
	{
		if (!itemIds[i] || itemIds[i] == 0)
			continue;
		pack.vids[i] = itemIds[i];
	}

	itemIds.clear();
#else
	if (!rkItem.GetCloseItem(kPPosMain, &dwItemID, __GetPickableDistance()))
		return;
#endif

#ifdef ENABLE_FAST_PICKUP
	CPythonNetworkStream& rkNetStream = CPythonNetworkStream::Instance();
	rkNetStream.SendItemPickUpAllPacket(pack);
#else
	SendClickItemPacket(dwItemID);
#endif
}

StdAfx.h

Spoiler
Add:
#ifdef ENABLE_FAST_PICKUP
	FAST_PICKUP_MAX_NUM = 45,
#endif
After:
	PLAYER_NAME_MAX_LEN = 12,

 

 

 

And now the server side.

common/serivice.h or common/CommonDefines.h

Spoiler
Add:
#define ENABLE_FAST_PICKUP

 

common/length.h

Spoiler
Add:
#ifdef ENABLE_FAST_PICKUP
	FAST_PICKUP_MAX_NUM = 45,
#endif
After:
BELT_INVENTORY_SLOT_COUNT = BELT_INVENTORY_SLOT_WIDTH * BELT_INVENTORY_SLOT_HEIGHT,

 

packet.h

Spoiler
Add:
#ifdef ENABLE_FAST_PICKUP
	HEADER_CG_ITEM_PICKUP_ALL		= 32,
#endif
After:
	HEADER_CG_QUEST_CONFIRM			= 31,

Add:
#ifdef ENABLE_FAST_PICKUP
typedef struct command_item_pickup_all
{
	BYTE header;
	DWORD vids[FAST_PICKUP_MAX_NUM];
} TPacketCGItemPickupAll;
#endif
After:
typedef struct command_item_pickup
{
	BYTE 	header;
	DWORD	vid;
} TPacketCGItemPickup;

 

packet_info.cpp

Spoiler
Add:
#ifdef ENABLE_FAST_PICKUP
	Set(HEADER_CG_ITEM_PICKUP_ALL, sizeof(TPacketCGItemPickupAll), "ItemPickup", true);
#endif
After:
	Set(HEADER_CG_ITEM_PICKUP, sizeof(TPacketCGItemPickup), "ItemPickup", true);

 

input.h

Spoiler
Add:
#ifdef ENABLE_FAST_PICKUP
		void		ItemPickupAll(LPCHARACTER ch, const char* data);
#endif
After:
		void		ItemPickup(LPCHARACTER ch, const char * data);

 

input_main.cpp

Spoiler
Add:
#ifdef ENABLE_FAST_PICKUP
void CInputMain::ItemPickupAll(LPCHARACTER ch, const char* data)
{
	struct command_item_pickup_all* pinfo = (struct command_item_pickup_all*)data;
	if (!ch)
		return;

	for (int i = 0; i < FAST_PICKUP_MAX_NUM; i++)
	{
		if (!ch->PickupItem(pinfo->vids[i]))
			return;
	}
}
#endif
After:
void CInputMain::ItemPickup(LPCHARACTER ch, const char * data)
{
	struct command_item_pickup * pinfo = (struct command_item_pickup*) data;
	if (ch)
		ch->PickupItem(pinfo->vid);
}
      
Add:
#ifdef ENABLE_FAST_PICKUP
		case HEADER_CG_ITEM_PICKUP_ALL:
			if (!ch->IsObserverMode())
				ItemPickupAll(ch, c_pData);
			break;
#endif     
After:
		case HEADER_CG_ITEM_PICKUP:
			if (!ch->IsObserverMode())
				ItemPickup(ch, c_pData);
			break;

 

Good look with the system and please if there's any bug leave a comment so I can fix it.

Have a good day!

 

  • Metin2 Dev 52
  • Eyes 1
  • Dislove 1
  • Not Good 1
  • Think 1
  • Good 9
  • Love 1
  • Love 25
Link to comment
Share on other sites

  • Premium

That part for packet:

DWORD vids[FAST_PICKUP_MAX_NUM];

is not really good.

You will end up sending 45 item vids even if there is only one item available to pickup (of course 44 of them will be 0).

 

You should change your packet from static size to dynamic size and send only as much vids as needed.

  • Good 3
  • Love 1
Link to comment
Share on other sites

  • 1 month later...
On 11/1/2022 at 11:50 PM, Lufbert said:

That part for packet:

DWORD vids[FAST_PICKUP_MAX_NUM];

is not really good.

You will end up sending 45 item vids even if there is only one item available to pickup (of course 44 of them will be 0).

 

You should change your packet from static size to dynamic size and send only as much vids as needed.

how to do that properly like u said?

  • Metin2 Dev 1
Link to comment
Share on other sites



×
×
  • 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.