#include "stdafx.h" #include "SGameSelectTargetFx.h" #include "KRenderObject.h" #include "SGameViewPort.h" #include "KResourceManager.h" #include "SGameAvatarEx.h" #include "SGameWorld.h" #include "SGameFieldQuestProp.h" #include "Monsterbase.h" #include "SMonsterDB.h" #include "SCreatureDB.h" #include "SPetDB.h" // sonador 10.2.1 팻 시스템 구현 #include "KSeqForm.h" #include "KRenderObjectMesh.h" #include "TerrainProp.h" #include "SDebug_Util.h" /// 2010.10.13 - prodongi #include "SGameManager.h" #include "SSkillDB.h" SGameSelectTargetFx::SGameSelectTargetFx() { m_pGame = NULL; m_pSelectTargetPrimitive = NULL; m_vPos = K3DVector( 0.f, 0.f, 0.f ); m_fHeight = 0.f; m_fSelectTargetRot = 0.f; m_dwTime = 0; m_dwCheckTime = 0; m_bRender = false; m_pTerrainProp = NULL; } SGameSelectTargetFx::~SGameSelectTargetFx() { m_pGame = NULL; m_pTerrainProp = NULL; SAFE_DELETE( m_pSelectTargetPrimitive ); } void SGameSelectTargetFx::Initialize( SGame* pGame, const char* pTextureName ) { m_pGame = pGame; NX3LoadPack loadpack; loadpack.Init(); m_spTexture = KTextureManager::GetManager()->GetTexture( pTextureName, &loadpack, true, KTextureManager::GetManager()->GetMipMapBiasLevel() ); K3DBLENDEDBUMPVERTEX* pVertex = new K3DBLENDEDBUMPVERTEX[c_SelectTargetSegment*c_SelectTargetSegment]; K3DBLENDEDBUMPVERTEX* pTmpVertex = pVertex; int h; for( h = 0; h < c_SelectTargetSegment; h++ ) { for( int w = 0; w < c_SelectTargetSegment; w++) { pTmpVertex->position = K3DVector( 0.f, 0.f, 0.f ); pTmpVertex->normal = K3DVector( 0.f, 1.f, 0.f ); pTmpVertex->color = 0xffffffff; pTmpVertex->texcoord.x = ((float)w / (float)(c_SelectTargetSegment-1) ); pTmpVertex->texcoord.y = ((float)h / (float)(c_SelectTargetSegment-1) ); pTmpVertex->tangent = K3DVector4( 0.f, 0.f, 0.f, 0.f ); pTmpVertex->matrixIndices = 0; pTmpVertex->matrixWeights.x = 0.f; pTmpVertex->matrixWeights.y = 0.f; ++pTmpVertex; } } K3DINDEXED_WATER* pIndexed = new K3DINDEXED_WATER[c_SelectTargetSegmentIndexedCount]; K3DINDEXED_WATER* pTmpIndexed = pIndexed; for( h = 0; h < (c_SelectTargetSegment-1); h++) { for( int w = 0; w < (c_SelectTargetSegment-1); w++) { pTmpIndexed->a = (WORD)((c_SelectTargetSegment*h)+w); pTmpIndexed->b = (WORD)((c_SelectTargetSegment*h)+w+1); pTmpIndexed->c = (WORD)((c_SelectTargetSegment*(h+1))+w); ++pTmpIndexed; pTmpIndexed->a = (WORD)((c_SelectTargetSegment*h)+w+1); pTmpIndexed->b = (WORD)((c_SelectTargetSegment*(h+1))+w+1); pTmpIndexed->c = (WORD)((c_SelectTargetSegment*(h+1))+w); ++pTmpIndexed; } } m_pSelectTargetPrimitive = new SSelectTargetPrimitive; m_pSelectTargetPrimitive->SetVertexBuffer( pVertex ); m_pSelectTargetPrimitive->SetIndexBuffer( pIndexed ); m_pSelectTargetPrimitive->SetTexture( m_spTexture ); m_pSelectTargetPrimitive->SetTransparent( true ); m_pSelectTargetPrimitive->SetBlendMode( K3DMaterial::MBM_SELECT_FX ); /// 2010.10.12 - prodongi m_pSelectTargetPrimitive->setIndexCount(c_SelectTargetSegmentIndexedCount * 3); m_pSelectTargetPrimitive->setVertexCount(c_SelectTargetSegment * c_SelectTargetSegment); } void SGameSelectTargetFx::SetArHandle( AR_HANDLE handle ) { if( handle == 0 ) { m_dwTime = 0; m_fSelectTargetRot = 0.f; } else { if( m_arHandle != handle ) { bool bDefault = true; SGameAvatarEx *pObj = (SGameAvatarEx*)m_pGame->GetGameObject( handle ); if( pObj ) { if( pObj->GetObjType() == TS_ENTER::GAME_SUMMON ) { _SUMMON_INFO_FILE* pSummon = GetCreatureDB().GetCreatureData( pObj->GetInnContentID() ); if( pSummon ) { m_fRadius = pSummon->target_fx_size; bDefault = false; } } else if( pObj->GetObjType() == TS_ENTER::GAME_MOB ) { _MONSTER_INFO_FILE* pMonster = GetMonsterDB().GetMonsterData( pObj->GetInnContentID() ); if( pMonster ) { m_fRadius = pMonster->target_fx_size; bDefault = false; } } else if( pObj->GetObjType() == TS_ENTER::GAME_PET ) // sonador 10.2.1 팻 시스템 구현 { SPetInfoEx Pet = GetPetDB().Find( pObj->GetInnContentID() ); m_fRadius = Pet.getTargetFxSize(); bDefault = false; } else if( pObj->GetObjType() == TS_ENTER::GAME_FIELD_PROP ) { m_fRadius = ((SGameFieldQuestProp*)pObj)->GetTargetFxSize(); bDefault = false; } if( bDefault ) { float fSize = pObj->GetSize() /2.f; float fScale = pObj->GetScale(); m_fRadius = fSize * fScale * GameRule::DEFAULT_UNIT_SIZE; } } } } m_arHandle = handle; } void SGameSelectTargetFx::SetHeight( float fHeight ) { m_fHeight = fHeight; } void SGameSelectTargetFx::SetRotation( DWORD dwTime ) { if( m_dwCheckTime == dwTime ) return; if( m_dwTime == 0 ) m_dwTime = dwTime; if( (dwTime - m_dwTime) < 2000 ) { float fGap = (float)(dwTime - m_dwTime) / 2000; m_fSelectTargetRot = 6.28f * fGap; } else { m_dwTime = dwTime; m_fSelectTargetRot = 0.f; } } /*void SGameSelectTargetFx::Process( DWORD dwTime ) { if( m_arHandle == 0 ) return; SGameAvatarEx *pObj = (SGameAvatarEx*)m_pGame->GetGameObject( m_arHandle ); if( !pObj ) return; m_bRender = pObj->GetVisible(); if( !m_bRender ) { return; } m_vPos = *pObj->GetPosition(); m_vPos.z += m_fHeight; K3DMatrix matParent; K3DMatrixTranslation( matParent, m_vPos.x, m_vPos.y, 0.f ); m_pSelectTargetPrimitive->SetRootMat( &matParent ); K3DVertex pNearVertices[c_SelectTargetSegment*c_SelectTargetSegment]; m_pGame->GetNearVertices( m_vPos.x, m_vPos.y, c_SelectTargetSegment, c_SelectTargetSegment, pNearVertices ); K3DBLENDEDBUMPVERTEX* pVertex = m_pSelectTargetPrimitive->GetVertexBuffer(); for( int h = 0; h < c_SelectTargetSegment; h++ ) { for( int w = 0; w < c_SelectTargetSegment; w++ ) { pVertex->position.x = pNearVertices[(c_SelectTargetSegment*h)+w].x - m_vPos.x; pVertex->position.y = pNearVertices[(c_SelectTargetSegment*h)+w].y - m_vPos.y; pVertex->position.z = pNearVertices[(c_SelectTargetSegment*h)+w].z; pVertex->position.z += m_fHeight; ++pVertex; } } K3DMatrix matTex, matPos, matScal, matRot; K3DMatrixTranslation( matPos, 0.5f, 0.5f, 0.0f ); static float fSize = 35.0f; K3DMatrixScaling( matScal, 1.0f / fSize, -1.0f / fSize, 0.0f ) ; K3DMatrixRotationZ( matRot, m_fSelectTargetRot ); matTex = matScal * matRot * matPos; K3DMatrixTranslation( matPos, 0.0f, 0.0f, 0.0f ); matPos = matPos * matTex; m_pSelectTargetPrimitive->SetTerrainTextureMatrix( matPos ); m_pSelectTargetPrimitive->ClearHeightPropInfo(); static float fTerrainHeight = 0.0f; m_pTerrainProp = ((SGameWorld*)m_pGame)->GetTerrainProp( m_vPos.x, m_vPos.y, fTerrainHeight ); if( !m_pTerrainProp ) return; KSeqForm* pHeightProp = m_pTerrainProp->GetTerrainHeightProp(); if( !pHeightProp ) return; _CID( GETMESH_VERTEXBUFFERS ); _CID( GETMESH_INDEXBUFFERS ); KMsgGET_MESHVERTEXBUFFERS msgGMVB; pHeightProp->Perform(id_GETMESH_VERTEXBUFFERS, msgGMVB); KMsgGET_MESHINDEXBUFFERS msgGMIB; pHeightProp->Perform(id_GETMESH_INDEXBUFFERS, msgGMIB); int size = (int)msgGMVB.vVbStruct.size(); for(int k = 0; k < size; k++) { if(msgGMVB.vVbStruct[k]->nVBCount != msgGMIB.vIbStruct[k]->nIBCount) continue; for(int i = 0; i < msgGMVB.vVbStruct[k]->nVBCount; i++) { HeightPropInfo propinfo; propinfo.m_pVb = (K3DVertexBufferDX*)msgGMVB.vVbStruct[k]->pVBs[i]; propinfo.m_pIb = (K3DIndexBufferDX*)msgGMIB.vIbStruct[k]->pIBs[i]; _CID( GET_MATRIX ); KMsgGET_MATRIX msgMatrix; pHeightProp->Perform(id_GET_MATRIX, msgMatrix); if( msgMatrix.bSuc ) { K3DMatrix matResult; K3DMatrixMultiply( matResult, *msgMatrix.matLocal, *msgMatrix.matRoot ); propinfo.m_matProp = matResult; matResult._41 = matResult._41-m_vPos.x; matResult._42 = matResult._42-m_vPos.y; matResult._43 = 0.0f; matResult = matResult * matTex; propinfo.m_matPropTexture = matResult; m_pSelectTargetPrimitive->SetHeightPropInfo( propinfo ); } } } }*/ void SGameSelectTargetFx::Render( KViewportObject *viewport ) { if( !m_bRender ) return; m_pSelectTargetPrimitive->SetCenterPosition( K3DVector( m_vPos.x, m_vPos.y, m_vPos.z) ); viewport->Register( m_pSelectTargetPrimitive, KRenderObject::RENDEREFX_NONE ); // viewport->Register( m_pSelectTargetPrimitive, KRenderObject::RENDEREFX_SELECTTARGET ); } void SGameSelectTargetFx::Process( DWORD dwTime ) { if( m_arHandle == 0 ) return; if( m_dwCheckTime == dwTime ) return; m_dwCheckTime = dwTime; SGameAvatarEx *pObj = (SGameAvatarEx*)m_pGame->GetGameObject( m_arHandle ); if( !pObj ) return; m_bRender = pObj->GetVisible(); if( !m_bRender ) { return; } m_vPos = *pObj->GetPosition(); m_vPos.z += m_fHeight; K3DVector vMin = K3DVector( m_vPos.x - m_fRadius, m_vPos.y + m_fRadius, 0.f ); K3DVector vMax = K3DVector( m_vPos.x + m_fRadius, m_vPos.y - m_fRadius, 0.f ); ///가로 세로 거리를 세그먼트로 나눈다 float fWidthLength = (vMax.x - vMin.x) / (float)(c_SelectTargetSegment-1); float fHeightLength = (vMin.y - vMax.y) / (float)(c_SelectTargetSegment-1); float fWidthCenter = (vMax.x - vMin.x) / 2.f; float fHeightCenter = (vMin.y - vMax.y) / 2.f; K3DMatrix matRot, matTrans, matParent; K3DMatrixIdentity( matRot ); K3DMatrixRotationZ( matRot, m_fSelectTargetRot ); K3DMatrixTranslation( matParent, m_vPos.x, m_vPos.y, 0.f ); m_pSelectTargetPrimitive->SetRootMat( &matParent ); WORD wTile = 0; K3DBLENDEDBUMPVERTEX* pVertex = m_pSelectTargetPrimitive->GetVertexBuffer(); for( int h = 0; h < c_SelectTargetSegment; h++ ) { for( int w = 0; w < c_SelectTargetSegment; w++ ) { K3DMatrixTranslation( matTrans, (float)(-fWidthCenter ) + (w*fWidthLength), (float)fHeightCenter - (h*fHeightLength), 0.f ); K3DMatrixMultiply( matTrans, matTrans, matRot ); //0,0 으로 땡겨 찍은 좌표 pVertex->position.x = matTrans._41; pVertex->position.y = matTrans._42; //월드로 변환된 좌표 K3DMatrixMultiply( matTrans, matTrans, matParent ); m_pGame->GetHeight( matTrans._41, matTrans._42, pVertex->position.z, wTile ); pVertex->position.z += m_fHeight; ++pVertex; } } } /* void SGameSelectTargetFx::Process( DWORD dwTime ) { SGameObject * pObj = m_pGame->GetGameObject( m_arHandle ); if( !pObj ) return; m_vPos = *pObj->GetPosition(); float fScale = pObj->GetScale() * (float)(GameRule::DEFAULT_UNIT_SIZE); m_vPos.z = 0.f; K3DVector vMin = K3DVector( m_vPos.x - fScale, m_vPos.y + fScale, 0.f ); K3DVector vMax = K3DVector( m_vPos.x + fScale, m_vPos.y - fScale, 0.f ); ///가로 세로 거리를 세그먼트로 나눈다 float fWidthLength = (vMax.x - vMin.x) / (float)(c_SelectTargetSegment-1); float fHeightLength = (vMin.y - vMax.y) / (float)(c_SelectTargetSegment-1); float fWidthCenter = (vMax.x - vMin.x) / 2.f; float fHeightCenter = (vMin.y - vMax.y) / 2.f; K3DMatrix matRot, matParent; K3DMatrixIdentity( matRot ); K3DMatrixRotationZ( &matRot, m_fSelectTargetRot ); K3DMatrixTranslation( &matParent, m_vPos.x, m_vPos.y, 0.f ); K3DBLENDEDBUMPVERTEX* pVertex = m_pVertex; for( int h = 0; h < c_SelectTargetSegment; h++ ) { for( int w = 0; w < c_SelectTargetSegment; w++ ) { K3DMatrix matTrans; K3DMatrixTranslation( &matTrans, (float)(-fWidthCenter ) + (w*fWidthLength), (float)fHeightCenter - (h*fHeightLength), 0.f ); K3DMatrixMultiply( &matTrans, &matTrans, &matRot ); K3DMatrixMultiply( &matTrans, &matTrans, &matParent ); pVertex->position.x = matTrans._41; pVertex->position.y = matTrans._42; m_pGame->GetHeight( pVertex->position.x, pVertex->position.y, pVertex->position.z ); pVertex->position.z += m_fHeight; ++pVertex; } } } */ /* void SGameSelectTargetFx::Process( DWORD dwTime ) { static float fff = 0.01f; if( m_fSelectTargetRot > 6.28f ) m_fSelectTargetRot = 0.f; m_fSelectTargetRot += fff; if( m_pMatrix ) { m_vPos.x = m_pMatrix->_41; m_vPos.y = m_pMatrix->_42; m_fHeight = 0.5f; } K3DVector vMin = K3DVector( m_vPos.x - m_fScale, m_vPos.y + m_fScale, 0.f ); K3DVector vMax = K3DVector( m_vPos.x + m_fScale, m_vPos.y - m_fScale, 0.f ); ///가로 세로 거리를 세그먼트로 나눈다 float fWidthLength = (vMax.x - vMin.x) / (float)(c_SelectTargetSegment-1); float fHeightLength = (vMin.y - vMax.y) / (float)(c_SelectTargetSegment-1); K3DMatrix matRot; K3DMatrixIdentity( matRot ); K3DMatrixRotationZ( &matRot, m_fSelectTargetRot ); static float ff = 0.f; K3DUNLITVERTEX* pVertex = m_pVertex; for( int h = 0; h < c_SelectTargetSegment; h++ ) { for( int w = 0; w < c_SelectTargetSegment; w++ ) { pVertex->pos = K3DVector( (float)(vMin.x + (w*fWidthLength) ), (float)( vMin.y - (h*fHeightLength) ), 0.f ); pVertex->pos.z = m_pGame->GetHeight( pVertex->pos.x, pVertex->pos.y )+m_fHeight; K3DVector vOut = K3DVector( pVertex->normal.x, pVertex->normal.y, 0.f ); K3DVectorTransform( &vOut, &vOut, &matRot ); pVertex->texel.u = vOut.x - ff; pVertex->texel.v = vOut.y - ff; pVertex++; } } }*/ void SGameSelectTargetFx::setMsg( SIMSG_UI_ACT_USESKILL const& msg ) { //memcpy(&m_msg, &msg, sizeof (SIMSG_UI_ACT_USESKILL)); // get range SkillBaseEx* skillBase = GetSkillDB().GetSkillData( msg.nSkillID ); AR_UNIT fireRange = skillBase->GetFireRange(); //m_rangeSqr = fireRange * fireRange; // radius m_fRadius = skillBase->GetFireRange(); } /// cGameRegionSelectTargetFx::cGameRegionSelectTargetFx() { m_pGame = NULL; m_pSelectTargetPrimitive = NULL; m_vPos = K3DVector( 0.f, 0.f, 0.f ); m_fHeight = 0.f; m_bRender = false; m_pTerrainProp = NULL; } cGameRegionSelectTargetFx::~cGameRegionSelectTargetFx() { m_pGame = NULL; m_pTerrainProp = NULL; SAFE_DELETE( m_pSelectTargetPrimitive ); } /// test int segmentNum = 14; int segmentIndexedCount = (segmentNum-1) * (segmentNum-1) * 2; void cGameRegionSelectTargetFx::Initialize(SGame *pGame, const char *pTextureName) { m_pGame = pGame; NX3LoadPack loadpack; loadpack.Init(); m_spTexture = KTextureManager::GetManager()->GetTexture( pTextureName, &loadpack, true, KTextureManager::GetManager()->GetMipMapBiasLevel() ); K3DBLENDEDBUMPVERTEX* pVertex = new K3DBLENDEDBUMPVERTEX[segmentNum*segmentNum]; K3DBLENDEDBUMPVERTEX* pTmpVertex = pVertex; int h; for( h = 0; h < segmentNum; h++ ) { for( int w = 0; w < segmentNum; w++) { pTmpVertex->position = K3DVector( 0.f, 0.f, 0.f ); pTmpVertex->normal = K3DVector( 0.f, 1.f, 0.f ); pTmpVertex->color = 0xffffffff; pTmpVertex->texcoord.x = ((float)w / (float)(segmentNum-1) ); pTmpVertex->texcoord.y = ((float)h / (float)(segmentNum-1) ); pTmpVertex->tangent = K3DVector4( 0.f, 0.f, 0.f, 0.f ); pTmpVertex->matrixIndices = 0; pTmpVertex->matrixWeights.x = 0.f; pTmpVertex->matrixWeights.y = 0.f; ++pTmpVertex; } } K3DINDEXED_WATER* pIndexed = new K3DINDEXED_WATER[segmentIndexedCount]; K3DINDEXED_WATER* pTmpIndexed = pIndexed; for( h = 0; h < (segmentNum-1); h++) { for( int w = 0; w < (segmentNum-1); w++) { pTmpIndexed->a = (WORD)((segmentNum*h)+w); pTmpIndexed->b = (WORD)((segmentNum*h)+w+1); pTmpIndexed->c = (WORD)((segmentNum*(h+1))+w); ++pTmpIndexed; pTmpIndexed->a = (WORD)((segmentNum*h)+w+1); pTmpIndexed->b = (WORD)((segmentNum*(h+1))+w+1); pTmpIndexed->c = (WORD)((segmentNum*(h+1))+w); ++pTmpIndexed; } } m_pSelectTargetPrimitive = new SSelectTargetPrimitive; m_pSelectTargetPrimitive->SetVertexBuffer( pVertex ); m_pSelectTargetPrimitive->SetIndexBuffer( pIndexed ); m_pSelectTargetPrimitive->SetTexture( m_spTexture ); m_pSelectTargetPrimitive->SetTransparent( true ); m_pSelectTargetPrimitive->SetBlendMode( K3DMaterial::MBM_SELECT_FX ); m_pSelectTargetPrimitive->setIndexCount(segmentIndexedCount * 3); m_pSelectTargetPrimitive->setVertexCount(segmentNum * segmentNum); } void cGameRegionSelectTargetFx::Process( K3DVector const& pos, K3DVector const* playerPos ) { if( !m_bRender ) return; m_vPos = pos; m_vPos.z += m_fHeight; procCheckRange(playerPos); K3DVector vMin = K3DVector( m_vPos.x - m_fRadius, m_vPos.y + m_fRadius, 0.f ); K3DVector vMax = K3DVector( m_vPos.x + m_fRadius, m_vPos.y - m_fRadius, 0.f ); ///가로 세로 거리를 세그먼트로 나눈다 float fWidthLength = (vMax.x - vMin.x) / (float)(segmentNum-1); float fHeightLength = (vMin.y - vMax.y) / (float)(segmentNum-1); float fWidthCenter = (vMax.x - vMin.x) / 2.f; float fHeightCenter = (vMin.y - vMax.y) / 2.f; K3DMatrix /*matRot, */matTrans, matParent; //K3DMatrixIdentity( matRot ); //K3DMatrixRotationZ( matRot, m_fSelectTargetRot ); K3DMatrixTranslation( matParent, m_vPos.x, m_vPos.y, 0.f ); m_pSelectTargetPrimitive->SetRootMat( &matParent ); WORD wTile = 0; K3DBLENDEDBUMPVERTEX* pVertex = m_pSelectTargetPrimitive->GetVertexBuffer(); for( int h = 0; h < segmentNum; h++ ) { for( int w = 0; w < segmentNum; w++ ) { K3DMatrixTranslation( matTrans, (float)(-fWidthCenter ) + (w*fWidthLength), (float)fHeightCenter - (h*fHeightLength), 0.f ); //K3DMatrixMultiply( matTrans, matTrans, matRot ); //0,0 으로 땡겨 찍은 좌표 pVertex->position.x = matTrans._41; pVertex->position.y = matTrans._42; //월드로 변환된 좌표 K3DMatrixMultiply( matTrans, matTrans, matParent ); m_pGame->GetHeight( matTrans._41, matTrans._42, pVertex->position.z, wTile ); pVertex->position.z += m_fHeight; ++pVertex; } } } /// 2010.10.13 - prodongi void cGameRegionSelectTargetFx::procCheckRange(K3DVector const* playerPos) { ArPosition _playerPos((AR_UNIT)playerPos->x, (AR_UNIT)playerPos->y); ArPosition _targetPos((AR_UNIT)m_vPos.x, (AR_UNIT)m_vPos.y); AR_UNIT curRangeSqr = _playerPos.GetDistanceSqr(_targetPos); /// 시전 가능 거리 안에 있다, 타겟 이미지 교체 해줘야 된다 if (curRangeSqr <= m_rangeSqr) { SetIsRender(true); } /// 시전 가능 거리 밖에 있다 //else //{ //SetIsRender(false); //} } void cGameRegionSelectTargetFx::Render( KViewportObject *viewport ) { if( !m_bRender ) return; m_pSelectTargetPrimitive->SetCenterPosition( K3DVector( m_vPos.x, m_vPos.y, m_vPos.z) ); viewport->Register( m_pSelectTargetPrimitive, KRenderObject::RENDEREFX_NONE ); // viewport->Register( m_pSelectTargetPrimitive, KRenderObject::RENDEREFX_SELECTTARGET ); } /// 2010.10.13 - prodongi void cGameRegionSelectTargetFx::setMsg(SIMSG_UI_ACT_USESKILL const& msg) { memcpy(&m_msg, &msg, sizeof (SIMSG_UI_ACT_USESKILL)); // get range SkillBaseEx* skillBase = GetSkillDB().GetSkillData(msg.nSkillID); AR_UNIT fireRange = skillBase->GetFireRange(); m_rangeSqr = fireRange * fireRange; // radius m_fRadius = skillBase->var[9] * GameRule::DEFAULT_UNIT_SIZE; } /// 2010.10.13 - prodongi void cGameRegionSelectTargetFx::sendMsg(SGameManager* gameMng) { SetIsRender(false); m_msg.m_targetPos = m_vPos; m_msg.target_handle = 0; gameMng->ProcMsgAtStatic(&m_msg); }