Files
2026-06-01 12:46:52 +02:00

541 lines
14 KiB
C++

#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<COBSET *>* coblist = COBManager::GetManager()->Load( str.c_str() );
if( coblist == NULL )
{
str += " NotFoundFileName";
_oprint( str.c_str() );
assert( false );
return false;
}
std::vector<COBSET *>::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<KSeqModel*>(m_pProp);
return model->GetCurrentAnimation()->GetInterval().GetLength();
}
else if (GCLAN_PROP_COB == m_clanType)
{
KSeqAvatar* model = dynamic_cast<KSeqAvatar*>(m_pProp);
return model->GetCurrentAnimation()->GetInterval().GetLength();
}
return 0;
}