Jump to content

Fix Pickup Distances Bug


valdirk2

Recommended Posts

Well, first I had a BUG on a client, if there were a lot of items on the floor, I kept pressing Z to pick up the items, until suddenly he stopped picking up. Then, I found that the function that maps the items that were nearby simply sent the package to pick up an item that was too far away and ignored those that were really close.

 

I searched a lot on google for a solution, I saw two or three post with this same bug, but without solution.

 

I know almost nothing about C ++, but I managed and managed to solve it. If anyone has an idea, or any better way to resolve it, please leave your idea.

 

 

So what did I do?

 

Spoiler

locale_inc.h

Add:
 


#define ENABLE_FIX_PICKITEM



PythonItem.cpp
 

Search and replace the entire function:

 




bool CPythonItem::GetCloseItem(const TPixelPosition & c_rPixelPosition, DWORD * pdwItemID, DWORD dwDistance)
{
    DWORD dwCloseItemID = 0;
    DWORD dwCloseItemDistance = 1000 * 1000;

    TGroundItemInstanceMap::iterator i;
    for (i = m_GroundItemInstanceMap.begin(); i != m_GroundItemInstanceMap.end(); ++i)
    {
        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 (dwxDistance*dwxDistance + dwyDistance*dwyDistance < dwCloseItemDistance)
        {
            dwCloseItemID = i->first;
            dwCloseItemDistance = dwDistance;
        }
    }

    if (dwCloseItemDistance>float(dwDistance)*float(dwDistance))
        return false;

    *pdwItemID=dwCloseItemID;

    return true;
}


for this:
 


#ifdef ENABLE_FIX_PICKITEM
int DISTANCE_APPROX(int dx, int dy)
{
	int min, max;

	if (dx < 0)
		dx = -dx;

	if (dy < 0)
		dy = -dy;

	if (dx < dy)
	{
		min = dx;
		max = dy;
	}
	else
	{
		min = dy;
		max = dx;
	}

	// coefficients equivalent to ( 123/128 * max ) and ( 51/128 * min )
	return (((max << 8) + (max << 3) - (max << 4) - (max << 1) +
		(min << 7) - (min << 5) + (min << 3) - (min << 1)) >> 8);
}

bool CPythonItem::GetCloseItem(const TPixelPosition& c_rPixelPosition, DWORD* pdwItemID, DWORD dwDistance)
{
	DWORD dwCloseItemID = 0;
	DWORD dwCloseItemDistance = 0;
	int aproMin = 0;

	TGroundItemInstanceMap::iterator i;
	for (i = m_GroundItemInstanceMap.begin(); i != m_GroundItemInstanceMap.end(); ++i)
	{
		TGroundItemInstance* pInstance = i->second;

		int iDist = DISTANCE_APPROX((int)c_rPixelPosition.x - (int)pInstance->v3EndPosition.x, (int)c_rPixelPosition.y - (-(int)pInstance->v3EndPosition.y));
		if (aproMin == 0)
			aproMin = iDist;
		if (aproMin >= iDist) {
			aproMin = iDist;
			dwCloseItemID = i->first;
			dwCloseItemDistance = iDist;
		}
	}

	if (dwCloseItemDistance > 300)
		return false;

	*pdwItemID = dwCloseItemID;

	return true;
}
#else
bool CPythonItem::GetCloseItem(const TPixelPosition& c_rPixelPosition, DWORD* pdwItemID, DWORD dwDistance)
{
	DWORD dwCloseItemID = 0;
	DWORD dwCloseItemDistance = 1000 * 1000;

	TGroundItemInstanceMap::iterator i;
	for (i = m_GroundItemInstanceMap.begin(); i != m_GroundItemInstanceMap.end(); ++i)
	{
		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 (dwxDistance * dwxDistance + dwyDistance * dwyDistance < dwCloseItemDistance)
		{
			dwCloseItemID = i->first;
			dwCloseItemDistance = dwDistance;
		}
	}

	if (dwCloseItemDistance > float(dwDistance) * float(dwDistance))
		return false;

	*pdwItemID = dwCloseItemID;

	return true;
}
#endif

 

 

With that he will always pick the item that is at a closer average distance, different from the other function that I did not understand well how it worked...
As I said, I am very lay with C ++, but there is a solution to a bug that I solved.

Edited by valdirk2
Fixing tutorial
  • Metin2 Dev 1
  • Angry 2
  • Good 2
  • Love 4
Link to comment
Share on other sites

  • Silver

 

2 hours ago, valdirk2 said:

Where is this fix? I spent two hours searching on google and didn't find any correction, if someone did a fix better than mine, I definitely want to use it.

Whats wrong with you ?

Lead @ another famous Metin2 Forum did create this code.

Pay him respect with a mention or i report your "fix" for being stolen

  • Think 1
Link to comment
Share on other sites

  • 3 weeks later...
On 11/1/2020 at 10:11 PM, Lead0b110010100 said:

Hey Lead here from the other board. I don't think he has stolen it from me, maybe he got the idea from there and then coded it himself.

I would recognize my own code style if he had really copied it one for one.

I didn't really copy it, I spent hours researching some fix about it ... and I didn't find it, and if I had found it I would have saved myself 4 hours trying to solve it hahahaha
But if you had the same idea as me, I believe I'm on the right path xD

  • Love 2
Link to comment
Share on other sites

  • 5 months later...

Announcements



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