#include "StdAfx.h" #include "DnHitPropComponent.h" #include "DnWorldActProp.h" CDnHitPropComponent::CDnHitPropComponent(void) : m_LastHitSignalTime( 0 ), m_nLastHitSignalIndex( 0 ), m_pPropMatrixEx( NULL ), m_pDamageBase( NULL ) { } CDnHitPropComponent::~CDnHitPropComponent(void) { } #ifdef PRE_ADD_HIT_PROP_ADD_SE void CDnHitPropComponent::OnSignal( SignalTypeEnum Type, void *pPtr, LOCAL_TIME LocalTime, LOCAL_TIME SignalStartTime, LOCAL_TIME SignalEndTime, int nSignalIndex, DNVector(DnActorHandle)* pvlhHittedActor /*= NULL*/ ) #else void CDnHitPropComponent::OnSignal( SignalTypeEnum Type, void *pPtr, LOCAL_TIME LocalTime, LOCAL_TIME SignalStartTime, LOCAL_TIME SignalEndTime, int nSignalIndex ) #endif // #ifdef PRE_ADD_HIT_PROP_ADD_SE { if( m_hMonster ) *(m_hMonster->GetMatEx()) = *m_pPropMatrixEx; switch( Type ) { case STE_Hit: { if( !m_hMonster ) break; HitStruct *pStruct = (HitStruct *)pPtr; DNVector(DnActorHandle) hVecList; // ÇÁ¶øÀÌ °®°í ÀÖ´Â rotation °ª±îÁö Àû¿ë½Ã۱â À§Çؼ­. MatrixEx CrossTemp = *m_pPropMatrixEx; EtVector3 vOffset = *pStruct->vOffset * m_hProp->GetScale()->y; CrossTemp.MoveLocalZAxis( vOffset.z ); CrossTemp.MoveLocalXAxis( vOffset.x ); CrossTemp.MoveLocalYAxis( vOffset.y ); CDnDamageBase::SHitParam HitParam; HitParam.hWeapon = m_hMonster->GetWeapon(); int nWeaponLength = 0; if( pStruct->bIncludeWeaponLength && HitParam.hWeapon ) nWeaponLength = HitParam.hWeapon->GetWeaponLength(); EtVector3 vPos = CrossTemp.m_vPosition; float fDistanceMax = pStruct->fDistanceMax * m_hProp->GetScale()->y; float fDistanceMin = pStruct->fDistanceMin * m_hProp->GetScale()->y; float fHeightMax = pStruct->fHeightMax * m_hProp->GetScale()->y; float fHeightMin = pStruct->fHeightMin * m_hProp->GetScale()->y; float fDistance = max( fDistanceMax, (fHeightMax - fHeightMin) ); float fXZDistanceSQ = fDistanceMax/* + nWeaponLength*/; float fXZDistanceMinSQ = fDistanceMin; //float fDistance = max( pStruct->fDistanceMax, (pStruct->fHeightMax - pStruct->fHeightMin) ); //float fXZDistanceSQ = pStruct->fDistanceMax + nWeaponLength; //float fXZDistanceMinSQ = pStruct->fDistanceMin; fXZDistanceSQ *= fXZDistanceSQ; fXZDistanceMinSQ *= fXZDistanceMinSQ; CDnActor::ScanActor( m_hMonster->GetRoom(), vPos, fDistance, hVecList ); EtVector3 vDir; EtVector3 vZVec = m_pPropMatrixEx->m_vZAxis; if( pStruct->fCenterAngle != 0.f ) { EtMatrix matRotate; EtMatrixRotationY( &matRotate, EtToRadian( pStruct->fCenterAngle ) ); EtVec3TransformNormal( &vZVec, &vZVec, &matRotate ); #if defined(PRE_FIX_63356) CrossTemp.m_vZAxis = vZVec; #endif // PRE_FIX_63356 } SAABox Box; float fDot; bool bHit = false; bool bFirstHit = true; if( m_LastHitSignalTime > LocalTime ) bFirstHit = false; if( m_nLastHitSignalIndex != nSignalIndex ) { bFirstHit = true; m_nLastHitSignalIndex = nSignalIndex; } HitParam.szActionName = pStruct->szTargetHitAction; HitParam.fDamage = pStruct->fDamageProb * 0.01f; HitParam.fDurability = pStruct->fDurabilityDamageProb * 0.01f; HitParam.vVelocity = *pStruct->vVelocity; HitParam.vResistance = *pStruct->vResistance; HitParam.vPosition = vPos; HitParam.fStiffProb = pStruct->fStiffProb * 0.01f; HitParam.RemainTime = SignalEndTime; HitParam.nDamageType = pStruct->nDamageType; HitParam.nSkillSuperAmmorIndex = pStruct->nApplySuperAmmorIndex - 1; HitParam.nSkillSuperAmmorDamage = pStruct->nApplySuperAmmorDamage; HitParam.DistanceType = (pStruct->nDistanceType == 0) ? CDnDamageBase::DistanceTypeEnum::Melee : CDnDamageBase::DistanceTypeEnum::Range; HitParam.bIgnoreCanHit = ( pStruct->bIgnoreCanHit == TRUE ); HitParam.bIgnoreParring = ( pStruct->bIgnoreParring == TRUE ); // Actor üũ for( DWORD i=0; iIsHittable( m_hMonster, LocalTime, pStruct ) ) continue; switch( hVecList[i]->GetHitCheckType() ) { case CDnActor::HitCheckTypeEnum::BoundingBox: { HitParam.vPosition = vPos; vDir = *hVecList[i]->GetPosition() - vPos; vDir.y = 0.0f; hVecList[i]->GetBoundingBox( Box ); if( CDnActor::SquaredDistance( vPos, Box ) > fXZDistanceSQ ) continue; if( CDnActor::SquaredDistance( vPos, Box, false ) < fXZDistanceMinSQ ) continue; EtVec3Normalize( &vDir, &vDir ); fDot = EtVec3Dot( &vZVec, &vDir ); if( EtToDegree( acos( fDot ) ) > pStruct->fAngle ) continue; if( Box.Min.y < m_pPropMatrixEx->m_vPosition.y + pStruct->fHeightMin && Box.Max.y < m_pPropMatrixEx->m_vPosition.y + pStruct->fHeightMin ) continue; if( Box.Min.y > m_pPropMatrixEx->m_vPosition.y + pStruct->fHeightMax && Box.Max.y > m_pPropMatrixEx->m_vPosition.y + pStruct->fHeightMax ) continue; HitParam.vViewVec = -vDir; } break; case CDnActor::HitCheckTypeEnum::Collision: { SCollisionCapsule Capsule; SCollisionResponse CollisionResult; DNVector(SCollisionResponse) vCollisionResult; // Capsule.Segment.vOrigin = vPos; float fHeight = pStruct->fHeightMax - pStruct->fHeightMin; Capsule.Segment.vOrigin.y = Capsule.Segment.vOrigin.y - ( pStruct->fHeightMin + ( fHeight / 2.f ) ); Capsule.Segment.vDirection = EtVector3( 0.f, fHeight / 2.f, 0.f ); Capsule.fRadius = fDistanceMax; //int nParentBoneIndex = -1; EtVector3 vDestPos; if( hVecList[i]->GetObjectHandle()->CEtCollisionEntity::FindCapsuleCollision( Capsule, CollisionResult, &vCollisionResult ) == false ) continue; if( CollisionResult.pCollisionPrimitive ) { for( UINT k=0 ; kGetBoundingBox( Box ); if( Box.Min.y < vPos.y + pStruct->fHeightMin && Box.Max.y < vPos.y + pStruct->fHeightMin ) { vCollisionResult.erase( vCollisionResult.begin() + k ); k--; continue; } if( Box.Min.y > vPos.y + pStruct->fHeightMax && Box.Max.y > vPos.y + pStruct->fHeightMax ) { vCollisionResult.erase( vCollisionResult.begin() + k ); k--; continue; } DNVector(EtVector3) vPointList; vPointList.push_back( Box.GetCenter() ); #ifdef PRE_FIX_COLMESH_RECTANGLE_HITSIGNAL if( vCollisionResult[k].pCollisionPrimitive->Type == CT_BOX || vCollisionResult[k].pCollisionPrimitive->Type == CT_CAPSULE ) { #else if( vCollisionResult[k].pCollisionPrimitive->Type == CT_BOX ) { #endif // #ifdef PRE_FIX_COLMESH_RECTANGLE_HITSIGNAL Box.GetVertices( vPointList ); } bool bCheck = false; for( DWORD m=0; mCheckCollisionHitCondition(vPos, CrossTemp, vPointList[m], pStruct->fAngle) == true ) { #else if( hVecList[i]->CheckCollisionHitCondition(vPos, *m_pPropMatrixEx, vPointList[m], pStruct->fAngle) == true ) { #endif // PRE_FIX_63356 bCheck = true; break; } } if( bCheck == false ) { vCollisionResult.erase( vCollisionResult.begin() + k ); k--; continue; } HitParam.vBoneIndex.push_back( hVecList[i]->GetObjectHandle()->GetParentBoneIndex( vCollisionResult[k].pCollisionPrimitive ) ); } } if( vCollisionResult.empty() ) continue; //nParentBoneIndex = hVecList[i]->GetObjectHandle()->GetParentBoneIndex( CollisionResult.pCollisionPrimitive ); GetCenterPos( *CollisionResult.pCollisionPrimitive, vDestPos ); HitParam.vPosition = vDestPos; } else { ASSERT( 0 ); } ////////////////////////////////////// if( fDistanceMin > 100.f ) { vCollisionResult.clear(); Capsule.fRadius = pStruct->fDistanceMin; if( hVecList[i]->GetObjectHandle()->CEtCollisionEntity::FindCapsuleCollision( Capsule, CollisionResult, &vCollisionResult ) == true ) { if( CollisionResult.pCollisionPrimitive ) { for( UINT k=0 ; kGetBoundingBox( Box ); if( Box.Min.y < vPos.y + pStruct->fHeightMin && Box.Max.y < vPos.y + pStruct->fHeightMin ) { vCollisionResult.erase( vCollisionResult.begin() + k ); k--; continue; } if( Box.Min.y > vPos.y + pStruct->fHeightMax && Box.Max.y > vPos.y + pStruct->fHeightMax ) { vCollisionResult.erase( vCollisionResult.begin() + k ); k--; continue; } DNVector(EtVector3) vPointList; vPointList.push_back( Box.GetCenter() ); #ifdef PRE_FIX_COLMESH_RECTANGLE_HITSIGNAL if( vCollisionResult[k].pCollisionPrimitive->Type == CT_BOX || vCollisionResult[k].pCollisionPrimitive->Type == CT_CAPSULE ) { #else if( vCollisionResult[k].pCollisionPrimitive->Type == CT_BOX ) { #endif // #ifdef PRE_FIX_COLMESH_RECTANGLE_HITSIGNAL Box.GetVertices( vPointList ); } bool bCheck = false; for( DWORD m=0; mCheckCollisionHitCondition(vPos, CrossTemp, vPointList[m], pStruct->fAngle) == false ) { #else if( hVecList[i]->CheckCollisionHitCondition(vPos, *m_pPropMatrixEx, vPointList[m], pStruct->fAngle) == false ) { #endif // PRE_FIX_63356 #else #if defined(PRE_FIX_63356) if( hVecList[i]->CheckCollisionHitCondition(vPos, CrossTemp, vPointList[m], pStruct->fAngle) == true ) { #else if( hVecList[i]->CheckCollisionHitCondition(vPos, *m_pPropMatrixEx, vPointList[m], pStruct->fAngle) == true ) { #endif // PRE_FIX_63356 #endif // #ifdef PRE_FIX_COLMESH_RECTANGLE_HITSIGNAL bCheck = true; break; } } #ifdef PRE_FIX_COLMESH_RECTANGLE_HITSIGNAL if( bCheck == true ) { #else if( bCheck == false ) { #endif // #ifdef PRE_FIX_COLMESH_RECTANGLE_HITSIGNAL vCollisionResult.erase( vCollisionResult.begin() + k ); k--; continue; } int nBoneIndex = hVecList[i]->GetObjectHandle()->GetParentBoneIndex( vCollisionResult[k].pCollisionPrimitive ); std::vector::iterator it = std::find( HitParam.vBoneIndex.begin(), HitParam.vBoneIndex.end(), nBoneIndex ); if( it != HitParam.vBoneIndex.end() ) { HitParam.vBoneIndex.erase( it ); } } } } } if( HitParam.vBoneIndex.empty() ) continue; } ////////////////////////////////////// //HitParam.nBoneIndex = nParentBoneIndex; HitParam.vViewVec = vPos - vDestPos; EtVec3Normalize( &HitParam.vViewVec, &HitParam.vViewVec ); } break; } HitParam.bFirstHit = bFirstHit; bFirstHit = false; bHit = true; if( !HitParam.szActionName.empty() ) { // this class user must have CDnDamageBase parent class. hVecList[i]->OnDamage( m_pDamageBase, HitParam, pStruct ); #ifdef PRE_ADD_HIT_PROP_ADD_SE if( pvlhHittedActor ) pvlhHittedActor->push_back( hVecList[i] ); #endif // #ifdef PRE_ADD_HIT_PROP_ADD_SE } } if( bHit ) { m_LastHitSignalTime = SignalEndTime; } else m_LastHitSignalTime = -1; } break; } }