Jump to content

Recommended Posts

Hello guys, this is my first post, please excuse any mistakes.

I found this bug in the animation, where the sword size decreases during skill activation and then returns to normal size. I checked and it happens in both the Marty 5.8 and TMP4 clients.
The bug only happens with the male Sura character; the female Sura character is normal.

Has anyone else seen and/or fixed this?
 

 

  • Scream 1
On 11/5/2025 at 4:07 PM, guuspadial said:

Someone sent me the gr2 files and the others that correspond to the skill, I replaced them in the folder and tested them, however, it didn't solve the problem.

sorry delay, i think forgot to share the fix, i think it is enough, let me know if you see other issues, i think this fix will not break other parts of the game, but update me if you see any problem related to this fix.
this fix works in directx9 o

void CActorInstance::UpdateAttachingInstances()
{
	CEffectManager& rkEftMgr=CEffectManager::Instance();

	std::list<TAttachingEffect>::iterator it;
	DWORD dwCurrentTime = CTimer::Instance().GetCurrentMillisecond();
	for (it = m_AttachingEffectList.begin(); it!= m_AttachingEffectList.end();)
	{
		if (EFFECT_LIFE_WITH_MOTION == it->iLifeType)
		{
			++it;
			continue;
		}

		if ((EFFECT_LIFE_NORMAL == it->iLifeType && it->dwEndTime < dwCurrentTime) ||
			!rkEftMgr.IsAliveEffect(it->dwEffectIndex))
		{
			rkEftMgr.DestroyEffectInstance(it->dwEffectIndex);
			it = m_AttachingEffectList.erase(it);
		}
		else
		{
			if (it->isAttaching)
			{
				rkEftMgr.SelectEffectInstance(it->dwEffectIndex);

				if (it->iBoneIndex == -1)
				{
					D3DXMATRIX matTransform;
					matTransform = it->matTranslation;
					matTransform *= m_worldMatrix;
					rkEftMgr.SetEffectInstanceGlobalMatrix(matTransform);
				}
				else
				{
					D3DXMATRIX* pBoneMat;
					if (GetBoneMatrix(it->dwModelIndex, it->iBoneIndex, &pBoneMat))
					{
						D3DXMATRIX matTransform;
						matTransform = *pBoneMat;
#ifdef FIX_WEAPON_UPSCALING
#ifdef DIRECTX9
						D3DXVECTOR3 vScale;
						D3DXQUATERNION qRotation;
						D3DXVECTOR3 vTranslation;
						D3DXMatrixDecompose(&vScale, &qRotation, &vTranslation, &matTransform);

						D3DXMATRIX matRotationOnly, matTranslationOnly;
						D3DXMatrixRotationQuaternion(&matRotationOnly, &qRotation);
						D3DXMatrixTranslation(&matTranslationOnly, vTranslation.x, vTranslation.y, vTranslation.z);
						matTransform = matRotationOnly * matTranslationOnly;
#else
						D3DXVECTOR3 vTranslation(matTransform._41, matTransform._42, matTransform._43);
						D3DXMATRIX matTranslationOnly;
						D3DXMatrixTranslation(&matTranslationOnly, vTranslation.x, vTranslation.y, vTranslation.z);
						D3DXMATRIX matRotationOnly = matTransform;

						matRotationOnly._41 = 0.0f;
						matRotationOnly._42 = 0.0f;
						matRotationOnly._43 = 0.0f;
						matRotationOnly._44 = 1.0f;

						D3DXVECTOR3 vAxisX(matRotationOnly._11, matRotationOnly._12, matRotationOnly._13);
						float fScaleX = D3DXVec3Length(&vAxisX);
						if (fScaleX > 0.0001f)
						{
							matRotationOnly._11 /= fScaleX;
							matRotationOnly._12 /= fScaleX;
							matRotationOnly._13 /= fScaleX;
						}
						D3DXVECTOR3 vAxisY(matRotationOnly._21, matRotationOnly._22, matRotationOnly._23);
						float fScaleY = D3DXVec3Length(&vAxisY);
						if (fScaleY > 0.0001f)
						{
							matRotationOnly._21 /= fScaleY;
							matRotationOnly._22 /= fScaleY;
							matRotationOnly._23 /= fScaleY;
						}
						D3DXVECTOR3 vAxisZ(matRotationOnly._31, matRotationOnly._32, matRotationOnly._33);
						float fScaleZ = D3DXVec3Length(&vAxisZ);
						if (fScaleZ > 0.0001f)
						{
							matRotationOnly._31 /= fScaleZ;
							matRotationOnly._32 /= fScaleZ;
							matRotationOnly._33 /= fScaleZ;
						}
						matTransform = matRotationOnly * matTranslationOnly;
#endif
#endif

						matTransform *= it->matTranslation;
						matTransform *= m_worldMatrix;
						rkEftMgr.SetEffectInstanceGlobalMatrix(matTransform);
					}
					else
					{
						//TraceError("GetBoneMatrix(modelIndex(%d), boneIndex(%d)).NOT_FOUND_BONE",
						//	it->dwModelIndex, it->iBoneIndex);
					}
				}
			}

			++it;
		}
	}
}

in simple terms the weapon attached to the hand bone inherited a matrix in which the scale of the bone was shrunk (probably to create an effect of gradual genesis of the skill starting from that bone, so that it did not appear out of nowhere too abruptly), consequently the weapon inheriting this matrix was shrunk, the fix consists simply in removing the information on the scale from the matrix.
(remember to enable the macro FIX_WEAPON_UPSCALING and DIRECTX9 if you use this dx version)

Edited by StormyFF
  • Love 1
3 minutes ago, guuspadial said:

tkx

void CGrannyModelInstance::UpdateWorldMatrices(const D3DXMATRIX* c_pWorldMatrix)  // FIX_WEAPON_UPSCALING
{
	// NO_MESH_BUG_FIX
	if (!m_meshMatrices)
		return;
	// END_OF_NO_MESH_BUG_FIX

	assert(m_pModel != NULL);
	assert(ms_lpd3dMatStack != NULL);

	int meshCount = m_pModel->GetMeshCount();

	granny_matrix_4x4* pgrnMatCompositeBuffer = GrannyGetWorldPoseComposite4x4Array(__GetWorldPosePtr());
	D3DXMATRIX* boneMatrices = (D3DXMATRIX*)pgrnMatCompositeBuffer;

	for (int i = 0; i < meshCount; ++i)
	{
		D3DXMATRIX& rWorldMatrix = m_meshMatrices[i];

		const CGrannyMesh* pMesh = m_pModel->GetMeshPointer(i);

		// WORK

#if GrannyProductMinorVersion==4
		int* boneIndices = __GetMeshBoneIndices(i);
#elif GrannyProductMinorVersion==11 || GrannyProductMinorVersion==9 || GrannyProductMinorVersion==8 || GrannyProductMinorVersion==7
		const granny_int32x* boneIndices = __GetMeshBoneIndices(i);
#else
#error "unknown granny version"
#endif

		if (pMesh->CanDeformPNTVertices())
		{
			rWorldMatrix = *c_pWorldMatrix;
		}
		else
		{
#if GrannyProductMinorVersion==4
			int iBone = *boneIndices;
#elif GrannyProductMinorVersion==11 || GrannyProductMinorVersion==9 || GrannyProductMinorVersion==8 || GrannyProductMinorVersion==7
			const granny_int32x iBone = *boneIndices;
#else
#error "unknown granny version"
#endif

			D3DXMATRIX matBoneTransform = boneMatrices[iBone];

			D3DXVECTOR3 vTranslation(matBoneTransform._41, matBoneTransform._42, matBoneTransform._43);

			D3DXVec3Normalize((D3DXVECTOR3*)&matBoneTransform._11, (D3DXVECTOR3*)&matBoneTransform._11);
			D3DXVec3Normalize((D3DXVECTOR3*)&matBoneTransform._21, (D3DXVECTOR3*)&matBoneTransform._21);
			D3DXVec3Normalize((D3DXVECTOR3*)&matBoneTransform._31, (D3DXVECTOR3*)&matBoneTransform._31);
			matBoneTransform._41 = vTranslation.x;
			matBoneTransform._42 = vTranslation.y;
			matBoneTransform._43 = vTranslation.z;
			D3DXMatrixMultiply(&rWorldMatrix, &matBoneTransform, c_pWorldMatrix);
	}
}

#ifdef _TEST
	TEST_matWorld = *c_pWorldMatrix;
#endif
}
void CActorInstance::UpdateAttachingInstances()
{
	CEffectManager& rkEftMgr = CEffectManager::Instance();

	std::list<TAttachingEffect>::iterator it;
	DWORD dwCurrentTime = CTimer::Instance().GetCurrentMillisecond();
	for (it = m_AttachingEffectList.begin(); it != m_AttachingEffectList.end();)
	{
		if (EFFECT_LIFE_WITH_MOTION == it->iLifeType)
		{
			++it;
			continue;
		}

		if ((EFFECT_LIFE_NORMAL == it->iLifeType && it->dwEndTime < dwCurrentTime) ||
			!rkEftMgr.IsAliveEffect(it->dwEffectIndex))
		{
			rkEftMgr.DestroyEffectInstance(it->dwEffectIndex);
			it = m_AttachingEffectList.erase(it);
		}
		else
		{
			if (it->isAttaching)
			{
				rkEftMgr.SelectEffectInstance(it->dwEffectIndex);

				if (it->iBoneIndex == -1)
				{
					D3DXMATRIX matTransform;
					matTransform = it->matTranslation;
					matTransform *= m_worldMatrix;
					rkEftMgr.SetEffectInstanceGlobalMatrix(matTransform);
				}
				else
				{
					D3DXMATRIX* pBoneMat;
					if (GetBoneMatrix(it->dwModelIndex, it->iBoneIndex, &pBoneMat))
					{
						D3DXMATRIX matTransform;
						matTransform = *pBoneMat;

#ifdef FIX_WEAPON_UPSCALING

						D3DXVECTOR3 vTranslation(matTransform._41, matTransform._42, matTransform._43);
						D3DXMATRIX matTranslationOnly;
						D3DXMatrixTranslation(&matTranslationOnly, vTranslation.x, vTranslation.y, vTranslation.z);
						D3DXMATRIX matRotationOnly = matTransform;

						matRotationOnly._41 = 0.0f;
						matRotationOnly._42 = 0.0f;
						matRotationOnly._43 = 0.0f;
						matRotationOnly._44 = 1.0f;

						D3DXVECTOR3 vAxisX(matRotationOnly._11, matRotationOnly._12, matRotationOnly._13);
						float fScaleX = D3DXVec3Length(&vAxisX);
						if (fScaleX > 0.0001f)
						{
							matRotationOnly._11 /= fScaleX;
							matRotationOnly._12 /= fScaleX;
							matRotationOnly._13 /= fScaleX;
						}
						D3DXVECTOR3 vAxisY(matRotationOnly._21, matRotationOnly._22, matRotationOnly._23);
						float fScaleY = D3DXVec3Length(&vAxisY);
						if (fScaleY > 0.0001f)
						{
							matRotationOnly._21 /= fScaleY;
							matRotationOnly._22 /= fScaleY;
							matRotationOnly._23 /= fScaleY;
						}
						D3DXVECTOR3 vAxisZ(matRotationOnly._31, matRotationOnly._32, matRotationOnly._33);
						float fScaleZ = D3DXVec3Length(&vAxisZ);
						if (fScaleZ > 0.0001f)
						{
							matRotationOnly._31 /= fScaleZ;
							matRotationOnly._32 /= fScaleZ;
							matRotationOnly._33 /= fScaleZ;
						}
						matTransform = matRotationOnly * matTranslationOnly;

#endif

						matTransform *= it->matTranslation;
						matTransform *= m_worldMatrix;
						rkEftMgr.SetEffectInstanceGlobalMatrix(matTransform);
					}
					else
					{
						//TraceError("GetBoneMatrix(modelIndex(%d), boneIndex(%d)).NOT_FOUND_BONE",
						//    it->dwModelIndex, it->iBoneIndex);
					}
				}
			}

			++it;
		}
	}
}

if you have problems you can try fix this bug in this way  (i can t ensure it will not broke some parts of your game, but atm i fixed in this way and i don t display any visual bug).
https://youtu.be/A1Qspj2jenc

  • Love 2

Don't use any images from : imgur, turkmmop, freakgamers, inforge, hizliresim... Or your content will be deleted without notice...
Use : https://metin2.download/media/add/

Please use https://metin2.download/ when uploading files smaller than 100MB, otherwise the approval will take longer due to manual upload.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
×
×
  • 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.