Forum Moderator VegaS™ 10281 Posted March 17, 2018 Forum Moderator Share Posted March 17, 2018 (edited) M2 Download Center This is the hidden content, please Sign In or Sign Up ( Internal ) This is the hidden content, please Sign In or Sign Up ( 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 September 16, 2021 by VegaS™ 68 1 2 1 31 5 40 Check my GitHub Profile Click to find all the threads started by me [TOOL] Text file loader + JSON Link to comment Share on other sites More sharing options...
Sebypunct 24 Posted March 21, 2018 Share Posted March 21, 2018 Nice thanks Link to comment Share on other sites More sharing options...
Driguezgames 5 Posted April 7, 2018 Share Posted April 7, 2018 Works very good thanks Link to comment Share on other sites More sharing options...
Premium tierrilopes 452 Posted April 7, 2018 Premium Share Posted April 7, 2018 « Players are not able to select NPCs, Metin Stones and players as target! » Why not metins? Non-sense. Link to comment Share on other sites More sharing options...
Tasho 243 Posted April 7, 2018 Share Posted April 7, 2018 (edited) 13 hours ago, tierrilopes said: « Players are not able to select NPCs, Metin Stones and players as target! » Why not metins? Non-sense. https://board.en.metin2.gameforge.com/index.php/Thread/86760-Game-Version-16-1/ 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 August 20, 2022 by Metin2 Dev Core X - External 2 Internal 1 1 Link to comment Share on other sites More sharing options...
Premium tierrilopes 452 Posted April 7, 2018 Premium Share Posted April 7, 2018 No need to use IsEnemy to have it work for mobs and metins. Just wanted to know why, ty Link to comment Share on other sites More sharing options...
Honorable Member xP3NG3Rx 19685 Posted July 15, 2018 Honorable Member Share Posted July 15, 2018 (edited) 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: 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 August 25, 2022 by Metin2 Dev Core X - External 2 Internal 1 1 6 Link to comment Share on other sites More sharing options...
Active Member Helia01 2134 Posted August 6, 2018 Active Member Share Posted August 6, 2018 (edited) 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: 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 September 3, 2022 by Metin2 Dev Core X - External 2 Internal 1 Link to comment Share on other sites More sharing options...
Premium North 1178 Posted August 6, 2018 Premium Share Posted August 6, 2018 (edited) 3 hours ago, Helia01 said: i test you version. and i have bug. target only 2 no more!https://metin2.download/picture/vuw6j9F89wP0I01J7ZoFRsuDptSdj5P3/.gif how fix it? const int VICTIM_TARGET_SELECT_RANGE_MAX = 3000; Edited September 3, 2022 by Metin2 Dev Core X - External 2 Internal 1 Link to comment Share on other sites More sharing options...
Active Member Helia01 2134 Posted August 6, 2018 Active Member Share Posted August 6, 2018 2 hours ago, Fleon said: const int VICTIM_TARGET_SELECT_RANGE_MAX = 3000; i try change this.. And this don't work. 1 Link to comment Share on other sites More sharing options...
Honorable Member xP3NG3Rx 19685 Posted August 6, 2018 Honorable Member Share Posted August 6, 2018 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. 1 Link to comment Share on other sites More sharing options...
Active Member Helia01 2134 Posted August 6, 2018 Active Member Share Posted August 6, 2018 (edited) 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 September 3, 2022 by Metin2 Dev Core X - External 2 Internal 3 Link to comment Share on other sites More sharing options...
alio0o33 5 Posted July 5, 2019 Share Posted July 5, 2019 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 More sharing options...
HITRON 695 Posted March 29, 2020 Share Posted March 29, 2020 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. Link to comment Share on other sites More sharing options...
Forum Moderator VegaS™ 10281 Posted April 4, 2020 Author Forum Moderator Share Posted April 4, 2020 (edited) 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 Sign In or Sign Up Edited August 22, 2020 by VegaS™ 18 9 18 Check my GitHub Profile Click to find all the threads started by me [TOOL] Text file loader + JSON Link to comment Share on other sites More sharing options...
emre 3 Posted November 19, 2020 Share Posted November 19, 2020 Thanks Link to comment Share on other sites More sharing options...
CjMt2 20 Posted November 24, 2021 Share Posted November 24, 2021 choose the monster but do not attack Link to comment Share on other sites More sharing options...
Recommended Posts