#include "stdafx.h" #include "SGameAvatarEx.h" #include "SGameFieldQuestProp.h" #include "SFieldPropResourceDB.h" #include "KResourceManager.h" #include "KSeqModel.h" #include "KSeqForm.h" #include "KSeqAvatar.h" #include "SCobManager.h" #include "kviewport.h" #include "SStringDB.h" #include "GameRule.h" #include "SDebug_Util.h" #include "KSeqAvatarEx.h" namespace { const char* c_szDefault = "default"; const char* c_szDefaultLod01 = "default_lod01"; }; /// 2011.01.25 - prodongi char const* SGameFieldQuestProp::defaultKeyName = "default"; char const* SGameFieldQuestProp::activeKeyName = "active"; char const* SGameFieldQuestProp::activeLodKeyName = "activeLod"; SGameFieldQuestProp::SGameFieldQuestProp( int nQuestDBID ) : m_pProp(NULL) ,m_nQuestDBID( nQuestDBID ) ,m_vRotation( 0.f,0.f,0.f ) ,m_vScale( 1.0f, 1.0f, 1.0f ) ,m_fZOffSet( 0.f ) ,m_bTryHeight(false) ,m_nTextID( 0 ) ,m_fTargetFxSize( 8.0f ) ,m_nState(STANDBY_PROP) ,m_dwVisibleTime(2000) ,m_dwStartTime(0) ,m_fCastRange(0.0f) ,m_bVisibleProcess(false) ,m_pSelectCube(NULL) ,m_nActivation_type( CHECK_NONE ) ,m_Activation_value1( 0 ) ,m_Activation_value2( 0 ) ,m_bLockHeight( false ) ,m_fLockHeight( 0.0f ) { m_bIsInit = false; m_fScale = 1.0f; } SGameFieldQuestProp::~SGameFieldQuestProp() { SAFE_DELETE( m_pProp ); SAFE_DELETE( m_pSelectCube ); } bool SGameFieldQuestProp::Deactivate() { if( m_bVisibleProcess ) { m_nState = LEAVE_PROP; SetReservation( true ); } else { SGameAvatarEx::Deactivate(); } return true; } bool SGameFieldQuestProp::Initialize( class K3DRenderDeviceDX *pDevice ) { std::string str = "NotFoundFileName"; FieldPropResource* pQuestPropDB = GetFieldPropResourceDB().GetFieldPropResource( m_nQuestDBID ); if( pQuestPropDB ) { str = pQuestPropDB->file_name; m_nTextID = pQuestPropDB->text_id; m_fTargetFxSize = pQuestPropDB->target_fx_size; m_fCastRange = pQuestPropDB->casting_range * (float)GameRule::DEFAULT_UNIT_SIZE; str += ".cob"; m_nActivation_type = pQuestPropDB->activation_condition; m_Activation_value1 = pQuestPropDB->activation_value1; m_Activation_value2 = pQuestPropDB->activation_value2; if( pQuestPropDB->regen_time != 0 ) { m_bVisibleProcess = true; m_nState = ENTER_PROP; } } else { assert( false && "SGameFieldQuestProp::Initialize" ); return false; } std::vector* coblist = COBManager::GetManager()->Load( str.c_str() ); if( coblist == NULL ) { str += " NotFoundFileName"; _oprint( str.c_str() ); assert( false ); return false; } std::vector::iterator it = coblist->begin(); if( it != coblist->end() ) { COBSET * pPropSet = (*it); if( pPropSet->m_AniList.empty() ) { str += " 애니메이션 정보가 없음"; assert( false && str.c_str() ); return false; } NX3LoadPack loadpack; loadpack.Init(); /// 2011.02.07 - prodongi m_clanType = pPropSet->nClan; if( pPropSet->nClan == GCLAN_PROP_NX3 ) { KSeqModel* pSeqModel= new KSeqModel; for( unsigned int i(0); pPropSet->m_AniList.size()>i; ++i ) { /// 2011.01.26 - prodongi if (0 == i) /// default { pSeqModel->AddAnimation( c_szDefault, pPropSet->m_AniList[i].c_str(), KNX3Manager::SEQTYPE_ALL, &loadpack); } else if (1 == i) /// active { pSeqModel->AddAnimation( activeKeyName, pPropSet->m_AniList[i].c_str(), KNX3Manager::SEQTYPE_ALL, &loadpack); break; } } /// 2011.01.26 퀘스트 프랍에서 실제로 LOD는 안 쓰이고 있다. for( unsigned int i(0); pPropSet->m_LodList.size()>i; ++i ) { /// 2011.01.26 - prodongi if (0 == i) /// default { pSeqModel->AddAnimation( c_szDefaultLod01, pPropSet->m_LodList[i].strName.c_str(), KNX3Manager::SEQTYPE_ALL, &loadpack ); } else if (1 == i) /// active { pSeqModel->AddAnimation( activeLodKeyName, pPropSet->m_LodList[i].strName.c_str(), KNX3Manager::SEQTYPE_ALL, &loadpack ); break; } } pSeqModel->PlayAnimation( 0, c_szDefault, KSeqForm::SEQTYPE_LOOP ); m_pProp = pSeqModel; } else if( pPropSet->nClan == GCLAN_PROP_COB ) { KSeqAvatar* pSeqNAF = new KSeqAvatar; pSeqNAF->Initialize(); for( unsigned int i(0); pPropSet->m_AniList.size()>i; ++i ) { pSeqNAF->AddAnimation( pPropSet->m_AniList[i].c_str(), TRUE ); } assert( pPropSet->m_MeshList.size() && "그래픽 리소스 에러 : Prop Mesh 가 없다." ); for( unsigned int i(0); pPropSet->m_MeshList.size()>i; ++i ) { pSeqNAF->AddMesh( MPART_BODY, pPropSet->m_MeshList[i].c_str() ); break; } int index = 0; std::string strEffPosName; for( unsigned int i(0); pPropSet->m_EffPosList.size()>i; ++i ) { index = pPropSet->m_EffPosList[i].dwIndex; strEffPosName = pPropSet->m_EffPosList[i].strName; pSeqNAF->AddEffectPos( index, strEffPosName.c_str() ); } pSeqNAF->PlayAnimation( GetSafeTickCount(), c_szDefault, KSeqModel::SEQTYPE_LOOP ); m_pProp = pSeqNAF; } else { assert( false && "pPropSet->nClan 알수없는 타입임" ); return false; } m_pSelectCube = new K3DBoundRotCube( pPropSet->fSelCube[0], pPropSet->fSelCube[3], pPropSet->fSelCube[1], pPropSet->fSelCube[4], pPropSet->fSelCube[2], pPropSet->fSelCube[5] ); m_pSelectCube->SetWireColor( KColor( 255, 255, 0, 255 ) ); } else { assert( false && "Cob 데이터가 없습니다" ); return false; } K3DMatrix matWorld, matTrans, matRotation, matScale; K3DMatrixIdentity( matWorld ); K3DMatrixIdentity( matTrans ); K3DMatrixIdentity( matRotation ); K3DMatrixIdentity( matScale ); matTrans = *GetTransform(); matTrans._43 += m_fZOffSet; if( m_bLockHeight ) matTrans._43 += m_fLockHeight; K3DMatrixScaling( matScale, m_vScale.x, m_vScale.y, m_vScale.z ); K3DMatrixRotationYawPitchRoll( matRotation, m_vRotation.x, m_vRotation.y, m_vRotation.z ); matWorld = matScale * matRotation * matTrans; SetTransform( matWorld ); m_pProp->SetTransform( *GetTransform() ); m_pSelectCube->SetTransform( *GetTransform() ); m_bIsInit = true; if( m_bVisibleProcess ) m_pProp->SetVisibility( 0.0f ); else m_pProp->SetVisibility( 1.0f ); return true; } void SGameFieldQuestProp::ClipTest( K3DVector * pFrustum ) { if( !m_bIsActivated || !m_bIsInit ) return; if( m_bTryHeight ) return; m_pProp->ClipTest( pFrustum ); if( !m_pProp->GetIsClip() ) m_xRenderFlag.On( AV_BASIC ); else m_xRenderFlag.Off( AV_BASIC ); } bool SGameFieldQuestProp::CheckCollision( const K3DVector &nv, const K3DVector &fv ) { if( !m_bIsActivated || !m_bIsInit ) return false; if( !m_xRenderFlag.IsOn( AV_BASIC ) ) return false; m_pSelectCube->SetTransform( *GetTransform() ); return m_pSelectCube->CheckCollision( nv, fv ); } bool SGameFieldQuestProp::Process( DWORD time, unsigned long uProcessBitVector ) { if( !m_bIsActivated || !m_bIsInit ) return false; if( m_bTryHeight ) { K3DVector pos = *GetPosition(); if( m_bLockHeight ) { pos.z += m_fZOffSet + m_fLockHeight; SetArObjectPos( pos.x, pos.y, pos.z, GetArObject().layer ); SetPosition( pos ); m_bTryHeight = false; } else { // 2010.09.02 - prodongi /* if( GetOnlyTerrainHeight( pos.x, pos.y, pos.z ) ) { pos.z += m_fZOffSet; SetArObjectPos( pos.x, pos.y, pos.z, GetArObject().layer ); SetPosition( pos ); m_pProp->SetTransform( *GetTransform() ); m_bTryHeight = false; } else { return false; } */ bool ret = false; int isTerrainCheck = GetFieldPropResourceDB().GetTerrainCheck(m_nQuestDBID); if (1 == isTerrainCheck) { WORD tile; float height = 0.0f; if (GetHeight(pos.x, pos.y, height, tile)) { pos.z = height + m_fZOffSet; SetArObjectPos( pos.x, pos.y, pos.z, GetArObject().layer ); SetPosition( pos ); m_pProp->SetTransform( *GetTransform() ); m_bTryHeight = false; ret = true; } } else { if( GetOnlyTerrainHeight( pos.x, pos.y, pos.z ) ) { pos.z += m_fZOffSet; SetArObjectPos( pos.x, pos.y, pos.z, GetArObject().layer ); SetPosition( pos ); m_pProp->SetTransform( *GetTransform() ); m_bTryHeight = false; ret = true; } } if (!ret) return false; } } if( m_nState == ENTER_PROP ) { if( m_dwStartTime == 0 ) m_dwStartTime = time; if( (time-m_dwStartTime) > m_dwVisibleTime ) { m_pProp->SetVisibility( 1.0f ); m_nState = STANDBY_PROP; } else m_pProp->SetVisibility( (float)(time-m_dwStartTime) / m_dwVisibleTime ); } else if( m_nState == LEAVE_PROP ) { if( m_dwStartTime == 0 ) m_dwStartTime = time; if( (time-m_dwStartTime) > m_dwVisibleTime ) { m_pProp->SetVisibility( 0.0f ); m_nState = STANDBY_PROP; SetReservation( false ); SGameAvatarEx::Deactivate(); } else m_pProp->SetVisibility( 1.0f - ((float)(time-m_dwStartTime)/m_dwVisibleTime) ); } else if( m_nState == STANDBY_PROP ) { K3DVector vCameraPos; float fTerrainVisDis; GetTerrainVisibleDistance( vCameraPos, fTerrainVisDis ); float fGapX = vCameraPos.x - GetPosition()->x; float fGapY = vCameraPos.y - GetPosition()->y; float fCameraDist = sqrtf((fGapX * fGapX) + (fGapY * fGapY)); // 프랍의 크기도 고려 float fPropWidth = m_pProp->GetBoundCube()->GetWidth(); float fPropLength = m_pProp->GetBoundCube()->GetLength(); float fRadius = sqrtf((fPropWidth * fPropWidth) + (fPropLength * fPropLength)) / 2.0f; float fDist = fCameraDist - fRadius*2; if(fDist < 0.0f) fDist = 0.0f; static float fPropVisibleRatio = 0.4f; static float fPropAlphaRatio = 0.6f; float fPropVisibleDistance = (fTerrainVisDis * fPropVisibleRatio) * 0.8f; float fPropAlphaDistance = (fPropVisibleDistance * fPropAlphaRatio) * 0.8f; float fPropVisibility = 1.0f; if( fDist > fPropVisibleDistance ) fPropVisibility = 0.f; if( fCameraDist > fPropAlphaDistance ) fPropVisibility = 1.f - ( (fCameraDist - fPropAlphaDistance) / (fPropVisibleDistance - fPropAlphaDistance) ); m_pProp->SetVisibility( fPropVisibility ); } m_pProp->Process( time ); return true; } /* bool SGameFieldQuestProp::Process( DWORD time ) { if( !m_bIsActivated ) return false; if( m_bTryHeight ) { K3DVector pos = *GetPosition(); if( GetHeight( pos.x, pos.y, pos.z ) ) { pos.z += m_fZOffSet; K3DVector vNormal = K3DVector( 0.f, 0.f, 1.f ); K3DVector v1, v2, v3; GetTerrainTriangle( pos.x, pos.y, v1, v2, v3 ); v1=v2-v1; v2=v3-v2; v3=CrossProduct(v2, v1); Normalize(v3); K3DVector vOut = CrossProduct( vNormal, v3 ); float fAngle = DotProduct( vNormal, v3 ); if( vOut.y < 0.0f ) m_vRotation.y = -acosf( fAngle ); else m_vRotation.y = acosf( fAngle ); K3DMatrix matWorld, matTrans, matRotation; K3DMatrixIdentity( matWorld ); K3DMatrixIdentity( matTrans ); K3DMatrixIdentity( matRotation ); K3DMatrixRotationYawPitchRoll( &matRotation, m_vRotation.x, m_vRotation.y, m_vRotation.z ); K3DMatrixTranslation( &matTrans, pos.x, pos.y, pos.z ); K3DMatrixMultiply( &matWorld, &matRotation, &matTrans ); SetArObjectPos( pos.x, pos.y, pos.z, GetArObject().mv.layer ); SetPosition( pos ); SetTransform( matWorld ); m_pProp->SetTransform( *GetTransform() ); m_bTryHeight = false; } else { return false; } } m_pProp->Process( time ); return true; } */ bool SGameFieldQuestProp::Render( unsigned long uRenderBitVector, class KViewportObject** ppViewportList, int nViewportCount) { if( !m_bIsActivated || !m_bIsInit ) return false; if( !m_xRenderFlag.IsOn( AV_BASIC ) ) return false; if(nViewportCount >= 1 && ppViewportList[0] && ppViewportList[0]->GetAttributes() & KViewportObject::VIEWPORT_GAME) m_pProp->Render( ppViewportList[0] ); if(nViewportCount >= 3 && ppViewportList[2] && ppViewportList[2]->GetAttributes() & KViewportObject::VIEWPORT_WATER) m_pProp->Render( ppViewportList[2] ); if(nViewportCount >= 2 && ppViewportList[1] && ppViewportList[1]->GetAttributes() & KViewportObject::VIEWPORT_SHADOW) { if( m_xRenderFlag.IsOn( AV_SHADOW ) ) { DWORD renderFlag = MAKELONG( KRenderObject::RENDEREFX_SHADOW, SHADOW_DY_CAST ); m_pProp->Render( ppViewportList[1], renderFlag ); //등록 } } return true; } bool SGameFieldQuestProp::renderSelect(unsigned long uRenderBitVector, class KViewportObject** ppViewportList, int nViewportCount) { if( !m_bIsActivated || !m_bIsInit ) return false; if( !m_xRenderFlag.IsOn( AV_BASIC ) ) return false; if(nViewportCount >= 1 && ppViewportList[0] && ppViewportList[0]->GetAttributes() & KViewportObject::VIEWPORT_GAME) m_pProp->Render( ppViewportList[0], KRenderObject::RENDEREFX_SELECT ); if(nViewportCount >= 3 && ppViewportList[2] && ppViewportList[2]->GetAttributes() & KViewportObject::VIEWPORT_WATER) m_pProp->Render( ppViewportList[2], KRenderObject::RENDEREFX_SELECT ); return true; } void SGameFieldQuestProp::getBlockLine(int* blockLine) { if (m_pProp) { K3DBoundRotCube* boundCube = m_pProp->GetBoundCube(); if (!boundCube) return ; boundCube->getBlockLine(blockLine); } } const char * SGameFieldQuestProp::GetCobFileName() { if( GetObjType() == TS_ENTER::GAME_FIELD_PROP ) return GetStringDB().GetString( m_nTextID ); return SGameAvatarEx::GetCobFileName(); } /// 2011.01.21 - prodongi bool SGameFieldQuestProp::PlayAnimation(const char *aniKey, int nAniType) { if (!m_pProp) return false; if (!m_pProp->GetAnimationFromSeqObjList(aniKey)) return false; return m_pProp->PlayAnimation( GetSafeTickCount(), aniKey, nAniType); } /// 2011.02.07 - prodongi int SGameFieldQuestProp::GetPropIntervalLength() const { if (!m_pProp) return 0; if (GCLAN_PROP_NX3 == m_clanType) { KSeqModel* model = dynamic_cast(m_pProp); return model->GetCurrentAnimation()->GetInterval().GetLength(); } else if (GCLAN_PROP_COB == m_clanType) { KSeqAvatar* model = dynamic_cast(m_pProp); return model->GetCurrentAnimation()->GetInterval().GetLength(); } return 0; }