Jump to content

Tab Targeting (GF v16.1)


Recommended Posts

  • Forum Moderator

M2 Download Center

This is the hidden content, please
( Internal )

This is the hidden content, please
( GitHub )

Tab Targeting: Player has the possibility to select the nearest monster around the character by pressing the Tab key. 
NOTE: Players are not able to select NPCs, metin stones, and players as targets!

This video is from 2017.

 

Edited by VegaS™
  • Metin2 Dev 61
  • Dislove 1
  • Think 2
  • Confused 1
  • Good 31
  • Love 5
  • Love 40
Link to comment
Share on other sites

  • 3 weeks later...
13 hours ago, tierrilopes said:

« Players are not able to select NPCs, Metin Stones and players as target! »

Why not metins? Non-sense.

Jvgsfab.png

That's the way of official, everyone can extend it as they want, for players, stones, npc etc.

Just extend check IsEnemy() IsStone() in line 39 from PythonCharacterManager.cpp (Github), there are more checks if you want:

  • pkInstTarget->IsPC()
  • pkInstTarget->IsStone()
  • pkInstTarget->IsEnemy()
  • pkInstTarget->IsNPC()
  • pkInstTarget->IsPoly()
Edited by Metin2 Dev
Core X - External 2 Internal
  • Metin2 Dev 1
  • Love 1
Link to comment
Share on other sites

  • 3 months later...
  • Honorable Member

Here is the official-like version if someone interested in, yeah, I know, it's weird code.
The official is in the CPythonCharacterManager class I think, I've put it into the CInstanceBase, and they use different map, but doesn't matter.
I did some tests but I didn't stressed out in every situations, so I'm not sure this is safe enough to use.

Spoiler

// InstanceBase.h - public declaration
		DWORD					FindNearestVictimVID(DWORD dwCurrentVID = 0);


//InstanceBaseBattle.cpp - anywhere
const int VICTIM_TARGET_SELECT_RANGE_MAX = 3000;
DWORD CInstanceBase::FindNearestVictimVID(DWORD dwCurrentVID)
{
	CPythonCharacterManager& rkChrMgr = CPythonCharacterManager::Instance();
	CInstanceBase* pkInstSelf = rkChrMgr.GetMainInstancePtr();
	typedef std::map<DWORD, int> TNearestVictimMap;
	TNearestVictimMap mapVictimsVIDDistance;
	for (CPythonCharacterManager::CharacterIterator i = rkChrMgr.CharacterInstanceBegin(); i != rkChrMgr.CharacterInstanceEnd(); ++i)
	{
		CInstanceBase* pkInstEach = *i;
		if (pkInstEach == pkInstSelf || pkInstEach == this)
			continue;
		if (pkInstEach->GetVirtualID() == dwCurrentVID)
			continue;

		int iDistance = int(pkInstEach->NEW_GetDistanceFromDestInstance(*pkInstSelf));
		if (iDistance < VICTIM_TARGET_SELECT_RANGE_MAX && pkInstEach->__GetRaceType() == CActorInstance::TYPE_ENEMY && pkInstEach->CanPickInstance())
		{
			CActorInstance& rkActorSelf = m_GraphicThingInstance;
			CActorInstance& rkActorEach = pkInstEach->GetGraphicThingInstanceRef();

			CPythonBackground& rkBG = CPythonBackground::Instance();
			const D3DXVECTOR3 & rv3PositionSelf = rkActorSelf.GetPosition();
			const D3DXVECTOR3 & rv3PositionEach = rkActorEach.GetPosition();

			int iX = 1, iY = 1;
			int iStep = 100, iRange = 50;

			float fDistanceX = rv3PositionSelf.x - rv3PositionEach.x;
			float fDistanceY = rv3PositionSelf.y - rv3PositionEach.y;

			if (rv3PositionEach.x >= rv3PositionSelf.x)
				fDistanceX = rv3PositionEach.x - rv3PositionSelf.x;
			else
				iX = -iX;

			if (rv3PositionEach.y >= rv3PositionSelf.y)
				fDistanceY = rv3PositionEach.y - rv3PositionSelf.y;
			else
				iY = -iY;

			if (fDistanceX <= fDistanceY)
				iStep = static_cast<int>(fDistanceY);
			else
				iStep = static_cast<int>(fDistanceX);

			float fRangeX = static_cast<float>(iX * iRange);
			float fRangeY = static_cast<float>(iY * iRange);
			bool bIsBlocked = false;

			for (int j = 0; j < iStep; ++j)
			{
				D3DXVECTOR3 v3CheckPosition = D3DXVECTOR3(fRangeX + rv3PositionSelf.x, fRangeY + rv3PositionSelf.y, 0.0f);
				if (rkBG.isAttrOn(v3CheckPosition.x, -v3CheckPosition.y, CTerrainImpl::ATTRIBUTE_BLOCK))
				{
					bIsBlocked = true;
					break;
				}

				bool bCheck = false;
				if (iX >= 0)
					bCheck = rv3PositionEach.x > v3CheckPosition.x;
				else
					bCheck = rv3PositionEach.x < v3CheckPosition.x;

				if (bCheck)
					fRangeX += iX * iRange;

				if (iY >= 0)
					bCheck = rv3PositionEach.y > v3CheckPosition.y;
				else
					bCheck = rv3PositionEach.y < v3CheckPosition.y;

				if (bCheck)
					fRangeY += static_cast<float>(iY * iRange);

				if (iX >= 0)
					bCheck = rv3PositionEach.x > v3CheckPosition.x;
				else
					bCheck = rv3PositionEach.x < v3CheckPosition.x;

				if (!bCheck)
				{
					if (iY >= 0)
						bCheck = rv3PositionEach.y > v3CheckPosition.y;
					else
						bCheck = rv3PositionEach.y < v3CheckPosition.y;

					if (!bCheck)
						break;
				}
			}

			if (!bIsBlocked)
				if (mapVictimsVIDDistance.find(pkInstEach->GetVirtualID()) == mapVictimsVIDDistance.end())
					mapVictimsVIDDistance.insert(TNearestVictimMap::value_type(pkInstEach->GetVirtualID(), iDistance));
		}
	}

	DWORD dwNearestVictimVID = 0;
	int iLowestDistance = VICTIM_TARGET_SELECT_RANGE_MAX;
	for (TNearestVictimMap::iterator it = mapVictimsVIDDistance.begin(); it != mapVictimsVIDDistance.end(); it++)
	{
		CInstanceBase * pkTarget = __FindInstancePtr(it->first);
		if (!pkTarget || pkTarget->IsDead() || pkTarget->GetVirtualID() == dwCurrentVID)
			continue;

		if (it->second < iLowestDistance)
		{
			dwNearestVictimVID = it->first;
			iLowestDistance = it->second;
		}
	}

	mapVictimsVIDDistance.clear();
	return dwNearestVictimVID;
}

 

Oh, and I'm using it via python:9a9b683db3.png

 

Pseudo.c

Spoiler

int __usercall CInstanceBase::FindNearestVictim@<eax>(_DWORD *a1@<ecx>, int a2@<ebx>, int a3@<edi>, int a4@<esi>, double a5@<st0>)
{
	int *v3Self; // eax
	int *v3Each; // eax
	int *v7; // eax
	int v8; // edx
	int *v9; // ST138_4
	int v10; // ecx
	_DWORD *v11; // ST118_4
	int *v12; // ST110_4
	int *v13; // ST108_4
	int *v14; // ST100_4
	BOOL v16; // [esp+8h] [ebp-268h]
	BOOL v17; // [esp+14h] [ebp-25Ch]
	BOOL v18; // [esp+20h] [ebp-250h]
	BOOL v19; // [esp+2Ch] [ebp-244h]
	_DWORD *v20; // [esp+34h] [ebp-23Ch]
	int v21; // [esp+D8h] [ebp-198h]
	int *v22; // [esp+114h] [ebp-15Ch]
	int v23; // [esp+118h] [ebp-158h]
	char v24; // [esp+158h] [ebp-118h]
	char *v25; // [esp+164h] [ebp-10Ch]
	int v26; // [esp+168h] [ebp-108h]
	int v27; // [esp+16Ch] [ebp-104h]
	int v28; // [esp+170h] [ebp-100h]
	_DWORD *v29; // [esp+174h] [ebp-FCh]
	int v30; // [esp+178h] [ebp-F8h]
	_DWORD *v31; // [esp+17Ch] [ebp-F4h]
	int v32; // [esp+180h] [ebp-F0h]
	int *v33; // [esp+184h] [ebp-ECh]
	char v34; // [esp+18Ah] [ebp-E6h]
	char v35; // [esp+18Bh] [ebp-E5h]
	int v36; // [esp+18Ch] [ebp-E4h]
	int v37; // [esp+190h] [ebp-E0h]
	int v38; // [esp+194h] [ebp-DCh]
	int v39; // [esp+198h] [ebp-D8h]
	int v40; // [esp+19Ch] [ebp-D4h]
	int v41; // [esp+1A0h] [ebp-D0h]
	int v42; // [esp+1A4h] [ebp-CCh]
	int v43; // [esp+1A8h] [ebp-C8h]
	char *v44; // [esp+1ACh] [ebp-C4h]
	int v45; // [esp+1B0h] [ebp-C0h]
	char *v46; // [esp+1B4h] [ebp-BCh]
	char v47; // [esp+1B8h] [ebp-B8h]
	int *v48[2]; // [esp+1C0h] [ebp-B0h]
	char v49; // [esp+1CBh] [ebp-A5h]
	int v3CheckPosX; // [esp+1CCh] [ebp-A4h]
	int v3CheckPosY; // [esp+1D0h] [ebp-A0h]
	int i; // [esp+1D4h] [ebp-9Ch]
	int fDistanceY; // [esp+1D8h] [ebp-98h]
	int iY; // [esp+1DCh] [ebp-94h]
	int iRange; // [esp+1E0h] [ebp-90h]
	int iX; // [esp+1E4h] [ebp-8Ch]
	float fEachX; // [esp+1E8h] [ebp-88h]
	float fEachY; // [esp+1ECh] [ebp-84h]
	int fEachZ; // [esp+1F0h] [ebp-80h]
	_DWORD *rkBG; // [esp+1F4h] [ebp-7Ch]
	int fRangeY; // [esp+1F8h] [ebp-78h]
	float fSelfX; // [esp+1FCh] [ebp-74h]
	float fSelfY; // [esp+200h] [ebp-70h]
	int fSelfZ; // [esp+204h] [ebp-6Ch]
	int fDistanceX; // [esp+208h] [ebp-68h]
	int iStep; // [esp+20Ch] [ebp-64h]
	int fRangeX; // [esp+210h] [ebp-60h]
	char v68; // [esp+217h] [ebp-59h]
	int v69; // [esp+218h] [ebp-58h]
	int v70; // [esp+21Ch] [ebp-54h]
	int v71; // [esp+220h] [ebp-50h]
	char *v72; // [esp+224h] [ebp-4Ch]
	int v73; // [esp+228h] [ebp-48h]
	int mapInstanceDistance; // [esp+22Ch] [ebp-44h]
	int v75; // [esp+244h] [ebp-2Ch]
	unsigned int v76; // [esp+248h] [ebp-28h]
	int v77; // [esp+24Ch] [ebp-24h]
	char *v78; // [esp+250h] [ebp-20h]
	int v79; // [esp+254h] [ebp-1Ch]
	int v80; // [esp+258h] [ebp-18h]
	int *v81[2]; // [esp+25Ch] [ebp-14h]
	int v82; // [esp+26Ch] [ebp-4h]

	v20 = a1;
	v77 = 0;
	v73 = 0;
	v78 = (char *)CPythonCharacterManager::GetMainInstancePtr(a1);
	sub_4995DD0(&mapInstanceDistance, (unsigned __int8 *)&v34, (int)&v35);
	v82 = 0;
	v31 = v20 + 8;
	v33 = (int *)v20[14];
	v32 = *v33;
	TCharacterInstanceMap::begin(&v79, a2, a3, a4, v32, v20 + 8);
	while ( 1 )
	{
		v29 = v20 + 8;
		v30 = v20[14];
		TCharacterInstanceMap::begin(&v47, a2, a3, a4, v30, v20 + 8);
		if ( (unsigned __int8)sub_49741C0(&v47, &v79) )
			break;
		v27 = v79;
		v28 = v80;
		sub_49748A0(&v79, a2, a3, a4);
		v70 = v27;
		v71 = v28;
		v72 = (char *)std::map::DWORD_CInstanceBase::second((int **)&v70, a2, a3, a4)[1];
		if ( v78 )
		{
			CInstanceBase::NEW_GetDistanceFromDestInstance(v72, v78);
			v69 = int(a5);
			if ( v69 < 3000 && !*CInstanceBase::__GetRaceType(v72) && CInstanceBase::CanPickInstance(v72) )
			{
				v3Self = (int *)CGraphicObjectInstance::GetPosition(v78 + 532);
				fSelfX = *(float *)v3Self;
				fSelfY = *((float *)v3Self + 1);
				fSelfZ = v3Self[2];
				v3Each = (int *)CGraphicObjectInstance::GetPosition(v72 + 532);
				fEachX = *(float *)v3Each;
				fEachY = *((float *)v3Each + 1);
				fEachZ = v3Each[2];
				rkBG = 0;
				iX = 1;
				iY = 1;
				fDistanceX = int(fSelfX - fEachX);
				fDistanceY = int(fSelfY - fEachY);
				iStep = 100;
				iRange = 50;
				if ( fEachX >= (double)fSelfX )
					fDistanceX = int(fEachX - fSelfX);
				else
					iX = -iX;
				a5 = fSelfY;
				if ( fEachY >= (double)fSelfY )
				{
					a5 = fEachY - fSelfY;
					fDistanceY = int(a5);
				}
				else
				{
					iY = -iY;
				}
				if ( fDistanceX <= fDistanceY )
					iStep = fDistanceY;
				else
					iStep = fDistanceX;
				fRangeX = iX * iRange;
				fRangeY = iY * iRange;
				v68 = 0;
				for ( i = 0; i < iStep; ++i )
				{
					v3CheckPosX = int((double)fRangeX + fSelfX);
					a5 = (double)fRangeY + fSelfY;
					v3CheckPosY = int(a5);
					if ( CMapManager::isAttrOnInt(rkBG, v3CheckPosX, -v3CheckPosY, 1) )
					{
						v68 = 1;
						break;
					}
					if ( iX >= 0 )
						v19 = fEachX > (double)v3CheckPosX;
					else
						v19 = fEachX < (double)v3CheckPosX;
					if ( v19 )
						fRangeX += iX * iRange;
					if ( iY >= 0 )
						v18 = fEachY > (double)v3CheckPosY;
					else
						v18 = fEachY < (double)v3CheckPosY;
					if ( v18 )
						fRangeY += iY * iRange;
					if ( iX >= 0 )
					{
						a5 = (double)v3CheckPosX;
						v17 = fEachX > a5;
					}
					else
					{
						a5 = (double)v3CheckPosX;
						v17 = fEachX < a5;
					}
					if ( !v17 )
					{
						if ( iY >= 0 )
						{
							a5 = (double)v3CheckPosY;
							v16 = fEachY > a5;
						}
						else
						{
							a5 = (double)v3CheckPosY;
							v16 = fEachY < a5;
						}
						if ( !v16 )
							break;
					}
				}
				if ( !v68 )
				{
					v25 = v72;
					v26 = v69;
					v43 = v69;
					v44 = v72;
					v45 = v69;
					v46 = v72;
					v7 = (int *)sub_4995E70(&mapInstanceDistance, (int)&v24, &v45);
					v8 = v7[1];
					v41 = *v7;
					v42 = v8;
				}
			}
		}
	}
	if ( v76 <= v20[305] )
		sub_4994720((int)(v20 + 299));
	sub_4994890((_DWORD **)&mapInstanceDistance, v81);
	while ( 1 )
	{
		v39 = 0;
		v40 = v75;
		if ( !&mapInstanceDistance )
			dummyshit00(0, v75);
		v39 = mapInstanceDistance;
		if ( !(unsigned __int8)sub_4994F40(&v39, v81) )
			break;
		v9 = sub_49975C0(v81, a2, a3, a4);
		if ( !CInstanceBase::IsDead((_DWORD *)v9[1]) )
		{
			v49 = 0;
			sub_49946C0((_DWORD **)v20 + 299, v48);
			while ( 1 )
			{
				v22 = v20 + 299;
				v10 = v20[304];
				v23 = v20[304];
				v37 = 0;
				v38 = v23;
				if ( v20 == (_DWORD *)-1196 )
					dummyshit00(v10, v23);
				v37 = *v22;
				if ( !(unsigned __int8)sub_4994FA0(v48, (int)v22, &v37) )
					break;
				v11 = (_DWORD *)sub_4996380(v48);
				v12 = sub_49975C0(v81, a2, a3, a4);
				if ( *v11 == CInstanceBase::GetVirtualID((_DWORD *)v12[1]) )
					v49 = 1;
				sub_4996410(v48);
			}
			if ( !v49 )
			{
				v13 = sub_49975C0(v81, a2, a3, a4);
				v77 = CInstanceBase::GetVirtualID((_DWORD *)v13[1]);
				v14 = sub_49975C0(v81, a2, a3, a4);
				Tracenf("Traget Distance %d", *v14);
				break;
			}
		}
		sub_4997630(v81);
	}
	v21 = v20[304];
	if ( v20 == (_DWORD *)-1196 )
		dummyshit00(1, MEMORY[0x14]);
	sub_4995A20(v20 + 299, v20[299], v21, (int)&v77);
	v36 = v77;
	v82 = -1;
	sub_4994810(&mapInstanceDistance);
	return v36;
}

 

 

Edited by Metin2 Dev
Core X - External 2 Internal
  • Confused 1
  • Good 1
  • Love 6
Link to comment
Share on other sites

  • 4 weeks later...
  • Active Member
On 7/15/2018 at 5:33 AM, xP3NG3Rx said:

Here is the official-like version if someone interested in, yeah, I know, it's weird code.
The official is in the CPythonCharacterManager class I think, I've put it into the CInstanceBase, and they use different map, but doesn't matter.
I did some tests but I didn't stressed out in every situations, so I'm not sure this is safe enough to use.

  Reveal hidden contents


// InstanceBase.h - public declaration
		DWORD					FindNearestVictimVID(DWORD dwCurrentVID = 0);


//InstanceBaseBattle.cpp - anywhere
const int VICTIM_TARGET_SELECT_RANGE_MAX = 3000;
DWORD CInstanceBase::FindNearestVictimVID(DWORD dwCurrentVID)
{
	CPythonCharacterManager& rkChrMgr = CPythonCharacterManager::Instance();
	CInstanceBase* pkInstSelf = rkChrMgr.GetMainInstancePtr();
	typedef std::map<DWORD, int> TNearestVictimMap;
	TNearestVictimMap mapVictimsVIDDistance;
	for (CPythonCharacterManager::CharacterIterator i = rkChrMgr.CharacterInstanceBegin(); i != rkChrMgr.CharacterInstanceEnd(); ++i)
	{
		CInstanceBase* pkInstEach = *i;
		if (pkInstEach == pkInstSelf || pkInstEach == this)
			continue;
		if (pkInstEach->GetVirtualID() == dwCurrentVID)
			continue;

		int iDistance = int(pkInstEach->NEW_GetDistanceFromDestInstance(*pkInstSelf));
		if (iDistance < VICTIM_TARGET_SELECT_RANGE_MAX && pkInstEach->__GetRaceType() == CActorInstance::TYPE_ENEMY && pkInstEach->CanPickInstance())
		{
			CActorInstance& rkActorSelf = m_GraphicThingInstance;
			CActorInstance& rkActorEach = pkInstEach->GetGraphicThingInstanceRef();

			CPythonBackground& rkBG = CPythonBackground::Instance();
			const D3DXVECTOR3 & rv3PositionSelf = rkActorSelf.GetPosition();
			const D3DXVECTOR3 & rv3PositionEach = rkActorEach.GetPosition();

			int iX = 1, iY = 1;
			int iStep = 100, iRange = 50;

			float fDistanceX = rv3PositionSelf.x - rv3PositionEach.x;
			float fDistanceY = rv3PositionSelf.y - rv3PositionEach.y;

			if (rv3PositionEach.x >= rv3PositionSelf.x)
				fDistanceX = rv3PositionEach.x - rv3PositionSelf.x;
			else
				iX = -iX;

			if (rv3PositionEach.y >= rv3PositionSelf.y)
				fDistanceY = rv3PositionEach.y - rv3PositionSelf.y;
			else
				iY = -iY;

			if (fDistanceX <= fDistanceY)
				iStep = static_cast<int>(fDistanceY);
			else
				iStep = static_cast<int>(fDistanceX);

			float fRangeX = static_cast<float>(iX * iRange);
			float fRangeY = static_cast<float>(iY * iRange);
			bool bIsBlocked = false;

			for (int j = 0; j < iStep; ++j)
			{
				D3DXVECTOR3 v3CheckPosition = D3DXVECTOR3(fRangeX + rv3PositionSelf.x, fRangeY + rv3PositionSelf.y, 0.0f);
				if (rkBG.isAttrOn(v3CheckPosition.x, -v3CheckPosition.y, CTerrainImpl::ATTRIBUTE_BLOCK))
				{
					bIsBlocked = true;
					break;
				}

				bool bCheck = false;
				if (iX >= 0)
					bCheck = rv3PositionEach.x > v3CheckPosition.x;
				else
					bCheck = rv3PositionEach.x < v3CheckPosition.x;

				if (bCheck)
					fRangeX += iX * iRange;

				if (iY >= 0)
					bCheck = rv3PositionEach.y > v3CheckPosition.y;
				else
					bCheck = rv3PositionEach.y < v3CheckPosition.y;

				if (bCheck)
					fRangeY += static_cast<float>(iY * iRange);

				if (iX >= 0)
					bCheck = rv3PositionEach.x > v3CheckPosition.x;
				else
					bCheck = rv3PositionEach.x < v3CheckPosition.x;

				if (!bCheck)
				{
					if (iY >= 0)
						bCheck = rv3PositionEach.y > v3CheckPosition.y;
					else
						bCheck = rv3PositionEach.y < v3CheckPosition.y;

					if (!bCheck)
						break;
				}
			}

			if (!bIsBlocked)
				if (mapVictimsVIDDistance.find(pkInstEach->GetVirtualID()) == mapVictimsVIDDistance.end())
					mapVictimsVIDDistance.insert(TNearestVictimMap::value_type(pkInstEach->GetVirtualID(), iDistance));
		}
	}

	DWORD dwNearestVictimVID = 0;
	int iLowestDistance = VICTIM_TARGET_SELECT_RANGE_MAX;
	for (TNearestVictimMap::iterator it = mapVictimsVIDDistance.begin(); it != mapVictimsVIDDistance.end(); it++)
	{
		CInstanceBase * pkTarget = __FindInstancePtr(it->first);
		if (!pkTarget || pkTarget->IsDead() || pkTarget->GetVirtualID() == dwCurrentVID)
			continue;

		if (it->second < iLowestDistance)
		{
			dwNearestVictimVID = it->first;
			iLowestDistance = it->second;
		}
	}

	mapVictimsVIDDistance.clear();
	return dwNearestVictimVID;
}

 

Oh, and I'm using it via python:9a9b683db3.png

 

Pseudo.c

  Hide contents


int __usercall CInstanceBase::FindNearestVictim@<eax>(_DWORD *a1@<ecx>, int a2@<ebx>, int a3@<edi>, int a4@<esi>, double a5@<st0>)
{
	int *v3Self; // eax
	int *v3Each; // eax
	int *v7; // eax
	int v8; // edx
	int *v9; // ST138_4
	int v10; // ecx
	_DWORD *v11; // ST118_4
	int *v12; // ST110_4
	int *v13; // ST108_4
	int *v14; // ST100_4
	BOOL v16; // [esp+8h] [ebp-268h]
	BOOL v17; // [esp+14h] [ebp-25Ch]
	BOOL v18; // [esp+20h] [ebp-250h]
	BOOL v19; // [esp+2Ch] [ebp-244h]
	_DWORD *v20; // [esp+34h] [ebp-23Ch]
	int v21; // [esp+D8h] [ebp-198h]
	int *v22; // [esp+114h] [ebp-15Ch]
	int v23; // [esp+118h] [ebp-158h]
	char v24; // [esp+158h] [ebp-118h]
	char *v25; // [esp+164h] [ebp-10Ch]
	int v26; // [esp+168h] [ebp-108h]
	int v27; // [esp+16Ch] [ebp-104h]
	int v28; // [esp+170h] [ebp-100h]
	_DWORD *v29; // [esp+174h] [ebp-FCh]
	int v30; // [esp+178h] [ebp-F8h]
	_DWORD *v31; // [esp+17Ch] [ebp-F4h]
	int v32; // [esp+180h] [ebp-F0h]
	int *v33; // [esp+184h] [ebp-ECh]
	char v34; // [esp+18Ah] [ebp-E6h]
	char v35; // [esp+18Bh] [ebp-E5h]
	int v36; // [esp+18Ch] [ebp-E4h]
	int v37; // [esp+190h] [ebp-E0h]
	int v38; // [esp+194h] [ebp-DCh]
	int v39; // [esp+198h] [ebp-D8h]
	int v40; // [esp+19Ch] [ebp-D4h]
	int v41; // [esp+1A0h] [ebp-D0h]
	int v42; // [esp+1A4h] [ebp-CCh]
	int v43; // [esp+1A8h] [ebp-C8h]
	char *v44; // [esp+1ACh] [ebp-C4h]
	int v45; // [esp+1B0h] [ebp-C0h]
	char *v46; // [esp+1B4h] [ebp-BCh]
	char v47; // [esp+1B8h] [ebp-B8h]
	int *v48[2]; // [esp+1C0h] [ebp-B0h]
	char v49; // [esp+1CBh] [ebp-A5h]
	int v3CheckPosX; // [esp+1CCh] [ebp-A4h]
	int v3CheckPosY; // [esp+1D0h] [ebp-A0h]
	int i; // [esp+1D4h] [ebp-9Ch]
	int fDistanceY; // [esp+1D8h] [ebp-98h]
	int iY; // [esp+1DCh] [ebp-94h]
	int iRange; // [esp+1E0h] [ebp-90h]
	int iX; // [esp+1E4h] [ebp-8Ch]
	float fEachX; // [esp+1E8h] [ebp-88h]
	float fEachY; // [esp+1ECh] [ebp-84h]
	int fEachZ; // [esp+1F0h] [ebp-80h]
	_DWORD *rkBG; // [esp+1F4h] [ebp-7Ch]
	int fRangeY; // [esp+1F8h] [ebp-78h]
	float fSelfX; // [esp+1FCh] [ebp-74h]
	float fSelfY; // [esp+200h] [ebp-70h]
	int fSelfZ; // [esp+204h] [ebp-6Ch]
	int fDistanceX; // [esp+208h] [ebp-68h]
	int iStep; // [esp+20Ch] [ebp-64h]
	int fRangeX; // [esp+210h] [ebp-60h]
	char v68; // [esp+217h] [ebp-59h]
	int v69; // [esp+218h] [ebp-58h]
	int v70; // [esp+21Ch] [ebp-54h]
	int v71; // [esp+220h] [ebp-50h]
	char *v72; // [esp+224h] [ebp-4Ch]
	int v73; // [esp+228h] [ebp-48h]
	int mapInstanceDistance; // [esp+22Ch] [ebp-44h]
	int v75; // [esp+244h] [ebp-2Ch]
	unsigned int v76; // [esp+248h] [ebp-28h]
	int v77; // [esp+24Ch] [ebp-24h]
	char *v78; // [esp+250h] [ebp-20h]
	int v79; // [esp+254h] [ebp-1Ch]
	int v80; // [esp+258h] [ebp-18h]
	int *v81[2]; // [esp+25Ch] [ebp-14h]
	int v82; // [esp+26Ch] [ebp-4h]

	v20 = a1;
	v77 = 0;
	v73 = 0;
	v78 = (char *)CPythonCharacterManager::GetMainInstancePtr(a1);
	sub_4995DD0(&mapInstanceDistance, (unsigned __int8 *)&v34, (int)&v35);
	v82 = 0;
	v31 = v20 + 8;
	v33 = (int *)v20[14];
	v32 = *v33;
	TCharacterInstanceMap::begin(&v79, a2, a3, a4, v32, v20 + 8);
	while ( 1 )
	{
		v29 = v20 + 8;
		v30 = v20[14];
		TCharacterInstanceMap::begin(&v47, a2, a3, a4, v30, v20 + 8);
		if ( (unsigned __int8)sub_49741C0(&v47, &v79) )
			break;
		v27 = v79;
		v28 = v80;
		sub_49748A0(&v79, a2, a3, a4);
		v70 = v27;
		v71 = v28;
		v72 = (char *)std::map::DWORD_CInstanceBase::second((int **)&v70, a2, a3, a4)[1];
		if ( v78 )
		{
			CInstanceBase::NEW_GetDistanceFromDestInstance(v72, v78);
			v69 = int(a5);
			if ( v69 < 3000 && !*CInstanceBase::__GetRaceType(v72) && CInstanceBase::CanPickInstance(v72) )
			{
				v3Self = (int *)CGraphicObjectInstance::GetPosition(v78 + 532);
				fSelfX = *(float *)v3Self;
				fSelfY = *((float *)v3Self + 1);
				fSelfZ = v3Self[2];
				v3Each = (int *)CGraphicObjectInstance::GetPosition(v72 + 532);
				fEachX = *(float *)v3Each;
				fEachY = *((float *)v3Each + 1);
				fEachZ = v3Each[2];
				rkBG = 0;
				iX = 1;
				iY = 1;
				fDistanceX = int(fSelfX - fEachX);
				fDistanceY = int(fSelfY - fEachY);
				iStep = 100;
				iRange = 50;
				if ( fEachX >= (double)fSelfX )
					fDistanceX = int(fEachX - fSelfX);
				else
					iX = -iX;
				a5 = fSelfY;
				if ( fEachY >= (double)fSelfY )
				{
					a5 = fEachY - fSelfY;
					fDistanceY = int(a5);
				}
				else
				{
					iY = -iY;
				}
				if ( fDistanceX <= fDistanceY )
					iStep = fDistanceY;
				else
					iStep = fDistanceX;
				fRangeX = iX * iRange;
				fRangeY = iY * iRange;
				v68 = 0;
				for ( i = 0; i < iStep; ++i )
				{
					v3CheckPosX = int((double)fRangeX + fSelfX);
					a5 = (double)fRangeY + fSelfY;
					v3CheckPosY = int(a5);
					if ( CMapManager::isAttrOnInt(rkBG, v3CheckPosX, -v3CheckPosY, 1) )
					{
						v68 = 1;
						break;
					}
					if ( iX >= 0 )
						v19 = fEachX > (double)v3CheckPosX;
					else
						v19 = fEachX < (double)v3CheckPosX;
					if ( v19 )
						fRangeX += iX * iRange;
					if ( iY >= 0 )
						v18 = fEachY > (double)v3CheckPosY;
					else
						v18 = fEachY < (double)v3CheckPosY;
					if ( v18 )
						fRangeY += iY * iRange;
					if ( iX >= 0 )
					{
						a5 = (double)v3CheckPosX;
						v17 = fEachX > a5;
					}
					else
					{
						a5 = (double)v3CheckPosX;
						v17 = fEachX < a5;
					}
					if ( !v17 )
					{
						if ( iY >= 0 )
						{
							a5 = (double)v3CheckPosY;
							v16 = fEachY > a5;
						}
						else
						{
							a5 = (double)v3CheckPosY;
							v16 = fEachY < a5;
						}
						if ( !v16 )
							break;
					}
				}
				if ( !v68 )
				{
					v25 = v72;
					v26 = v69;
					v43 = v69;
					v44 = v72;
					v45 = v69;
					v46 = v72;
					v7 = (int *)sub_4995E70(&mapInstanceDistance, (int)&v24, &v45);
					v8 = v7[1];
					v41 = *v7;
					v42 = v8;
				}
			}
		}
	}
	if ( v76 <= v20[305] )
		sub_4994720((int)(v20 + 299));
	sub_4994890((_DWORD **)&mapInstanceDistance, v81);
	while ( 1 )
	{
		v39 = 0;
		v40 = v75;
		if ( !&mapInstanceDistance )
			dummyshit00(0, v75);
		v39 = mapInstanceDistance;
		if ( !(unsigned __int8)sub_4994F40(&v39, v81) )
			break;
		v9 = sub_49975C0(v81, a2, a3, a4);
		if ( !CInstanceBase::IsDead((_DWORD *)v9[1]) )
		{
			v49 = 0;
			sub_49946C0((_DWORD **)v20 + 299, v48);
			while ( 1 )
			{
				v22 = v20 + 299;
				v10 = v20[304];
				v23 = v20[304];
				v37 = 0;
				v38 = v23;
				if ( v20 == (_DWORD *)-1196 )
					dummyshit00(v10, v23);
				v37 = *v22;
				if ( !(unsigned __int8)sub_4994FA0(v48, (int)v22, &v37) )
					break;
				v11 = (_DWORD *)sub_4996380(v48);
				v12 = sub_49975C0(v81, a2, a3, a4);
				if ( *v11 == CInstanceBase::GetVirtualID((_DWORD *)v12[1]) )
					v49 = 1;
				sub_4996410(v48);
			}
			if ( !v49 )
			{
				v13 = sub_49975C0(v81, a2, a3, a4);
				v77 = CInstanceBase::GetVirtualID((_DWORD *)v13[1]);
				v14 = sub_49975C0(v81, a2, a3, a4);
				Tracenf("Traget Distance %d", *v14);
				break;
			}
		}
		sub_4997630(v81);
	}
	v21 = v20[304];
	if ( v20 == (_DWORD *)-1196 )
		dummyshit00(1, MEMORY[0x14]);
	sub_4995A20(v20 + 299, v20[299], v21, (int)&v77);
	v36 = v77;
	v82 = -1;
	sub_4994810(&mapInstanceDistance);
	return v36;
}

 

 

i test you version.
and i have bug.

target only 2 no more!
https://metin2.download/picture/vuw6j9F89wP0I01J7ZoFRsuDptSdj5P3/.gif

how fix it?

Edited by Metin2 Dev
Core X - External 2 Internal
  • Metin2 Dev 1
Link to comment
Share on other sites

  • Active Member
1 hour ago, xP3NG3Rx said:

This is not selecting all enemies in your range, always choosing the closest target only. If the closest is the target, then it select the second one.

but you said that this is a (LIKE GF) version.

(CHECK REAL GF VERSION)
https://metin2.download/picture/dVTkF4gduH5qv24fAUvGwXq1qo9w02hh/.gif

Edited by Metin2 Dev
Core X - External 2 Internal
  • Love 3
Link to comment
Share on other sites

  • 10 months later...

thank you

it's work

but when i click Tab      syserr give me this

0705 13:48:48521 :: Traceback (most recent call last):

0705 13:48:48521 ::   File "game.py", line 834, in SetHPTargetBoard

0705 13:48:48521 ::   File "uiTarget.py", line 252, in SetEnemyVID

0705 13:48:48521 ::   File "uiTarget.py", line 276, in SetRaceElement

0705 13:48:48522 :: AttributeError
0705 13:48:48523 :: : 
0705 13:48:48523 :: 'module' object has no attribute 'GetVnumByVID'
0705 13:48:48523 :: 

how fix it  ?!

Link to comment
Share on other sites

  • 8 months later...
  • Forum Moderator
On 3/29/2020 at 9:31 AM, HITRON said:

I think the whole thing is wrong, cause there is not check for Ninja's when they are using Bow / Arrow and increase the Distance between the targets that they can reach with Tab so there is just a "Default" distance.

 

  • PythonCharacterManager.cpp

Search for:

			if (fRadiusDistance < 1500.0f)
				m_vecTargetInstance.push_back(pkInstTarget);

Replace it with:

This is the hidden content, please

Edited by VegaS™
  • Metin2 Dev 18
  • Good 9
  • Love 18
Link to comment
Share on other sites

  • 7 months later...
  • 1 year 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.