#include "StdAfx.h" #include #include "KRenderObjectBone.h" #include "KRenderObjectEtc.h" #include "SGameViewPort.h" #include "KDeviceManager.h" #include "KRenderDeviceDX.h" #include "KResourceManager.h" #include "K3DCamera.h" #include "SGameEnhanceFx.h" #include "resource.h" #include "SGameManager.h" #include "sgame.h" #include "SGameSound.h" #include "SGameEffect.h" #include "GameDefine.h" #include "SGameOption.h" #include "SGameAvatarEx.h" #include #include #include #include "SGameMessage.h" //#include "SGameMessageUI.h" #include "SNetMessage.h" #include "SGameUtil.h" #include "SkillBaseFile.h" #include "STenacityDB.h" #include "SMotionDB.h" //#include "SEnhanceFXDB.h" #include "SUIDisplayInfo.h" #include "SGameMilesSoundMgr.h" /// 2010.11.10 - prodongi #include "SGameLobbyDefine.h" //Explorer #include #include #define S_USER 1000 const char * pEP_Name[] = { "ep_top01_main", "ep_middle01_main", "ep_damage01_main", "ep_bottom01", "ep_ride01_main", "ep_wfx_00_l", "ep_wfx_00", "ep_wfx_00_th", }; const char * pEffectAniKey[] = { "effect_start", "effect_middle", "effect_end" }; extern void SetNavigate( const char * pURL, bool bVisible, int nAddWidth, int nAddHeight ); extern void SetVisibleNavigate( bool bVisible ); extern IWebBrowser2* GetWebBrowser( int nWidth, int nHeight, int nAddWidth, int nAddHeight ); extern void InitWebBrowser( IWebBrowser2* pWebBrowser ); extern void SetWebWindowStyle( HWND hWebBrowser ); extern void SetWebBrowserMovePos( IWebBrowser2* pWebBrowser, int nX, int nY ); extern void SetWebBrowserCenterPos( IWebBrowser2* pWebBrowser, int nW, int nY ); extern void SetWebBrowserVisible( IWebBrowser2* pWebBrowser, bool bVisible ); extern void SetURLNavigate( IWebBrowser2* pWebBrowser, const char * pURL ); extern void CurURLRefresh( IWebBrowser2* pWebBrowser ); extern void CloseWebBrowser( IWebBrowser2* pWebBrowser ); typedef struct _Web_Window_ { _Web_Window_() { nWindowID = 0; pWebBrowserOther = NULL; } int nWindowID; IWebBrowser2* pWebBrowserOther; } WEB_WINDOW; std::vector< WEB_WINDOW > g_vWebWinList; extern HWND g_hWnd; extern IWebBrowser2* g_pWebBrowser; extern VARIANT_BOOL g_IsShowWebBrowser; extern bool g_IsShowWebBrowserChanged; void EraseWebWindow( int nWinID ) { for( unsigned int i(0); g_vWebWinList.size()>i; i++ ) { if( g_vWebWinList[i].nWindowID == nWinID ) { g_vWebWinList.erase( g_vWebWinList.begin()+i ); return; } } } IWebBrowser2* GetWebWindow( int nWinID ) { for( unsigned int i(0); g_vWebWinList.size()>i; i++ ) { if( g_vWebWinList[i].nWindowID == nWinID ) return g_vWebWinList[i].pWebBrowserOther; } return NULL; } void CurOtherURLRefresh( int nWinID ) { IWebBrowser2* pWebBrowserOther = GetWebWindow( nWinID ); if( pWebBrowserOther ) CurURLRefresh( pWebBrowserOther ); } void SetOtherNavigateMove( int nWinID, int nX, int nY ) { IWebBrowser2* pWebBrowserOther = GetWebWindow( nWinID ); if( pWebBrowserOther ) { SetWebBrowserMovePos( pWebBrowserOther, nX, nY ); } } void SetOtherNavigateClose( int nWinID ) { IWebBrowser2* pWebBrowserOther = GetWebWindow( nWinID ); if( pWebBrowserOther ) { SetWebBrowserVisible( pWebBrowserOther, false ); CloseWebBrowser( pWebBrowserOther ); EraseWebWindow( nWinID ); } } void SetOtherNavigate( int nWinID, const char * pURL, int nWidth, int nHeight ) { IWebBrowser2* pWebBrowserOther = GetWebWindow( nWinID ); if( pWebBrowserOther ) { SetWebBrowserVisible( pWebBrowserOther, true ); SetURLNavigate( pWebBrowserOther, pURL ); HWND hWnd = NULL; HRESULT hrGetHWN = pWebBrowserOther->get_HWND( (long*)&hWnd ); if( hrGetHWN == S_OK ) ::BringWindowToTop( hWnd ); } else { WEB_WINDOW web_window; web_window.pWebBrowserOther = GetWebBrowser( nWidth, nHeight, 0, 0 ); web_window.nWindowID = nWinID; g_vWebWinList.push_back( web_window ); if( web_window.pWebBrowserOther ) { InitWebBrowser( web_window.pWebBrowserOther ); HWND hWnd = NULL; HRESULT hrGetHWN = web_window.pWebBrowserOther->get_HWND( (long*)&hWnd ); if( hrGetHWN == S_OK ) { SetWebWindowStyle( hWnd ); ::BringWindowToTop( hWnd ); } SetWebBrowserCenterPos( web_window.pWebBrowserOther, nWidth, nHeight ); SetURLNavigate( web_window.pWebBrowserOther, pURL ); SetWebBrowserVisible( web_window.pWebBrowserOther, true ); } } } //============================================================================= //SGame SGame::SGame ( SGameManager* pGameMng , int nGameType , K3DRenderDeviceDX* pRenderDevice , SSoundManager* pSoundMng , KTextureManager* pTextureMng , KNX3Manager* pNX3Mng , SGameMilesSoundMgr* pMSoundMgr ) : m_pGameMng(pGameMng) ,m_nGameType(nGameType) ,m_pRenderDevice(pRenderDevice) ,m_pSoundMng(pSoundMng) ,m_pTextureMng(pTextureMng) ,m_pNX3Mng(pNX3Mng) ,m_pMSoundMgr(pMSoundMgr) { m_pCamera = new K3DCamera; m_pCamera->Reset(); m_pArObject = NULL; m_dwTime = 0; m_nCurSelect = -1; m_nSpecialSelect = -1; m_nDeltaSpeed = 1; m_fTime = 0.0f; // Current time in seconds m_fAccumTime = 0.0f; // the global time - Speed Tree m_fElapsedTime = 0.0f; // Time elapsed since last frame m_nGameRef = STAGE_LOADING; m_nCheatMode = CHEAT_NONE; m_nEffectID = 0; m_nNewEffectID = 0; m_nAttackEffectID = 0; m_bStopProc = false; m_pViewPort = NULL; m_nNewEnhanceFxID = 0; } SGame::~SGame(void) { SAFE_DELETE(m_pCamera); _AllDelEffect(); AllDelParticle(); } void SGame::SetViewPort( SGameViewPort* pViewPort ) { m_pViewPort = pViewPort; } void SGame::_AllDelEffect() { for( unsigned int i(0); m_vEffectList.size()>i; i++ ) delete m_vEffectList[i]; m_vEffectList.erase( m_vEffectList.begin(), m_vEffectList.end() ); for( unsigned int i(0); m_vNewEffectList.size()>i; i++ ) delete m_vNewEffectList[i]; m_vNewEffectList.erase( m_vNewEffectList.begin(), m_vNewEffectList.end() ); for( unsigned int i(0); m_vAttackEffectList.size()>i; i++ ) delete m_vAttackEffectList[i]; m_vAttackEffectList.erase( m_vAttackEffectList.begin(), m_vAttackEffectList.end() ); } void SGame::AllDelParticle() { std::vector< SGameEnhanceFx* >::iterator iter = m_vEnhanceFxList.begin(); for( ; iter != m_vEnhanceFxList.end(); ) { SAFE_DELETE( (*iter) ); iter = m_vEnhanceFxList.erase(iter); } m_vEnhanceFxList.clear(); m_nNewEnhanceFxID = 0; while( !m_RecycleID.empty() ) m_RecycleID.pop(); } bool SGame::Render( unsigned long uRenderBitVector, KViewportObject** ppViewportList, int nViewportCount ) { //Camera Render for(int vit = 0; vit < nViewportCount; ++vit) { //if(ppViewportList[vit]->GetAttributes() & KViewportObject::VIEWPORT_GAME) // m_pCamera->Render( ppViewportList[vit] ); ppViewportList[vit]->SetCamera(m_pCamera); } return true; } bool SGame::Process( DWORD time, unsigned long uProcessBitVector ) { m_dwTime = time; return true; } void SGame::SetCheatMode( int nMode ) { m_nCheatMode = nMode; } void SGame::SetGameRef( int nGameRef ) { _oprint( "!!!!! SetGameRef : %d\n", nGameRef ); m_nGameRef = nGameRef; } void SGame::SendMsg( SGameObject *pGO, const TS_MESSAGE *msg ) { TS_MESSAGE * pMsg = NULL; //TS_MESSAGE를 구성하여, 보낸다. PendMessage( pMsg ); } void SGame::SendMsg( const TS_MESSAGE *msg ) { PendMessage( msg ); } bool SGame::IsUIWindowOpened( int nWindowID ) { return m_pGameMng->IsUIWindowOpened( nWindowID ); } bool SGame::IsWebPageWndOpened() { return m_pGameMng->IsWebPageWndOpened(); } void SGame::PendMessage( const TS_MESSAGE * pMessage ) { if( IsStopProcess() ) return; // _oprint( "PendMessage : %d\n", pMessage->id ); m_pGameMng->PendMessage( pMessage ); } void SGame::DelOwnerEffect( AR_HANDLE hOwner ) { for( unsigned int i(0); m_vEffectList.size()>i; i++ ) { if( m_vEffectList[i]->GetHandle() == hOwner ) m_vEffectList[i]->SetEnd(); } for( unsigned int i(0); m_vNewEffectList.size()>i; i++ ) { if( m_vNewEffectList[i]->GetOwner() == hOwner ) m_vNewEffectList[i]->ForceEnd(); } for( unsigned int i(0); m_vAttackEffectList.size()>i; i++ ) { if(m_vAttackEffectList[i]->GetCastHandle() == hOwner) m_vAttackEffectList[i]->SetEnd(); } } void SGame::DelEffect( int nEffectID ) { for( unsigned int i(0); m_vEffectList.size()>i; i++ ) { if( m_vEffectList[i]->GetEffectID() == nEffectID ) { m_vEffectList[i]->SetEnd(); break; } } } void SGame::EndLoopFx( int nEffectID ) { for( unsigned int i(0); m_vNewEffectList.size()>i; i++ ) { if( m_vNewEffectList[i]->GetEffectID() == nEffectID ) { m_vNewEffectList[i]->IsLoopFx(false); break; } } } void SGame::AddStateEffect( SGameMessage * pGameMsg ) { if( pGameMsg->nType == MSG_STATE ) { SMSG_STATE * pStateMsg = reinterpret_cast(pGameMsg); SGameAvatarEx* pTarget = (SGameAvatarEx*)GetGameObject( pStateMsg->handle ); if( !pTarget ) return; if( pTarget->IsPendLoading() ) return; StateInfoEx * pState = GetTenacityDB().GetTenacityData( pStateMsg->state_code ); if( !pState ) return; int nFXID = GetTenacityDB().GetFXID( pStateMsg->state_code ); FX_DATA fx_data; fx_data.nStateCode = pStateMsg->state_code; fx_data.nMode = SGameEffectEx::STATE_MODE; fx_data.end_time = pStateMsg->end_time; //상태 이상 종료 시간 fx_data.state_handle = pStateMsg->state_handle;//상태 이상 핸들 fx_data.owner = pStateMsg->handle; fx_data.attack = pStateMsg->handle; fx_data.target = pStateMsg->handle; fx_data.nEffPos = pState->pos_id; fx_data.nFX_ID = nFXID; AddEffect( &fx_data ); } } void SGame::UpdateStateEffect( SGameMessage * pGameMsg ) { if( pGameMsg == NULL ) return; if( pGameMsg->nType == MSG_STATE ) { SMSG_STATE * pStateMsg = reinterpret_cast(pGameMsg); std::vector< SGameEffectEx* >::iterator iter = m_vNewEffectList.begin(); for( ; iter != m_vNewEffectList.end(); ++iter ) { if( (*iter)->GetMode() == SGameEffectEx::STATE_MODE ) { if( (*iter)->GetOwner() == pStateMsg->handle && (*iter)->GetStateHandle() == pStateMsg->state_handle ) { (*iter)->SetEndTime( pStateMsg->end_time ); } } } } } void SGame::DelStateEffect( SGameMessage * pGameMsg ) { if( pGameMsg->nType == MSG_STATE ) { SMSG_STATE * pState = reinterpret_cast(pGameMsg); for( unsigned int i(0); m_vEffectList.size()>i; i++ ) { if( m_vEffectList[i]->GetHandle() == pState->handle && m_vEffectList[i]->GetStateHandle() == pState->state_handle ) { m_vEffectList[i]->SetEnd(); } } std::vector< class SGameEffectEx* >::iterator iter = m_vNewEffectList.begin(); for( ; iter != m_vNewEffectList.end(); ++iter ) { if( (*iter)->GetOwner() == pState->handle && (*iter)->GetStateHandle() == pState->state_handle ) { (*iter)->ForceEnd(); } } } } void SGame::DelStateEffect( int nDelObjType ) { for( unsigned int i(0); m_vEffectList.size()>i; i++ ) { unsigned char Type; int ObjType = IsFriend( m_vEffectList[i]->GetHandle(), Type ); if( ObjType & nDelObjType ) { m_vEffectList[i]->SetEnd(); } } std::vector< class SGameEffectEx* >::iterator iter = m_vNewEffectList.begin(); for( ; iter != m_vNewEffectList.end(); ++iter ) { unsigned char Type; int ObjType = IsFriend( (*iter)->GetOwner(), Type ); if( ObjType & nDelObjType ) { (*iter)->ForceEnd(); } } } SGameEffect* SGame::CreateEffect( const char * pEffectName, int nFlag, AR_HANDLE owner, AR_HANDLE caster, AR_HANDLE target, int nUseBoneIndex, int nAniType, float fPlayRate, AR_TIME end_time, bool bIsOwnerDir ) { // _oprint( "SGame::CreateEffect [c-%u] [o-%u]\n", caster, owner ); SGameAvatarEx* pOwner = (SGameAvatarEx*)GetGameObject( owner ); if( !pOwner ) return NULL; SGameAvatarEx* pCaster = (SGameAvatarEx*)GetGameObject( caster ); if( !pCaster ) return NULL; SGameAvatarEx* pTarget = (SGameAvatarEx*)GetGameObject( target ); if( !pTarget ) return NULL; if( pOwner->GetEffectRef() > 7 ) return NULL; if( CheckCameraDistance( pOwner ) == false ) return NULL; pOwner->EffectAddRef(); SGameEffect * pEffect = new SGameEffect( owner ); pEffect->SetOwner( owner ); pEffect->SetFlag( nFlag ); //따라가기 1, 보통 0 if( m_nCheatMode == CHEAT_NONE ) { pEffect->AddEffect( pEffectName ); //모양 종류 } else { std::string strFileName = pEffectName; if( m_nCheatMode == CHEAT_MODE01 ) { if( strcmp( strFileName.c_str(), "rcfx_ch_standard_damage_01.nx3" ) == 0 ) strFileName = "rcfx_ch_standard_criticaldamage_01.nx3"; } else if( m_nCheatMode == CHEAT_MODE02 ) { if( strcmp( strFileName.c_str(), "rcfx_ch_standard_damage_01.nx3" ) == 0 ) strFileName = "rcfx_ch_standard_damage_plusalpha_01.nx3"; } pEffect->AddEffect( strFileName.c_str() ); } pEffect->PlayAnimation( m_dwTime, nAniType, fPlayRate ); //시작 assert( nUseBoneIndex <= EFFECT_POS_MAX && "The effect position is outdated" ); const K3DMatrix* pEvpMatrix = pOwner->GetEventPointMatrix( nUseBoneIndex ); const K3DMatrix* pEvpAttachMatrix = pOwner->GetEventPointAttachMatrix( nUseBoneIndex ); K3DMatrix mat; //뼈는 위치만 참조 K3DMatrixIdentity( mat ); //방향 구하기 if( bIsOwnerDir ) { pEffect->SetOwnerDirection( pCaster->GetTransform(), (K3DVector*)&pCaster->GetViewVector() ); } else if( caster != target ) { //방향은 caster -> target pEffect->SetDirection( *pCaster->GetPosition(), *pTarget->GetPosition() ); } else { K3DVector spos = pCaster->GetViewVector(); K3DVector tpos = spos; tpos *= 3; pEffect->SetDirection( spos, tpos ); } if( nFlag == 1 ) //따라가기 설정 { if( pEvpAttachMatrix && pEvpMatrix ) pEffect->SetParentMat( pOwner->GetTransform(), pEvpAttachMatrix, pEvpMatrix ); else pEffect->SetParentMat( pOwner->GetTransform(), NULL, NULL ); } else { if( pEvpAttachMatrix && pEvpMatrix ) { K3DMatrixMultiply( mat, *pEvpAttachMatrix, *pOwner->GetTransform() ); K3DMatrixMultiply( mat, *pEvpMatrix, mat ); } else mat = *pOwner->GetTransform(); pEffect->SetTransform( mat ); } if( pOwner->GetArID() != pTarget->GetArID() && nFlag != 2 ) { pEffect->SetTargetScale(pTarget->GetScale(), mat); } pEffect->SetMessageHandler( this ); //상태 이상 지속 시간 if( end_time > 0 ) { pEffect->SetEndTime( end_time ); } if (fabs(pTarget->GetAdjustedScale() - 1.0f) > FLT_EPSILON) { pEffect->SetScalePure(pTarget->GetAdjustedScale()); } return pEffect; } int SGame::AddEffectTest( const char * pFileName, AR_HANDLE hOwner ) { SGameEffect * pEffect = CreateEffect( pFileName, 1, hOwner, hOwner, hOwner, EFFECT_POS_TOP, SEQTYPE_LOOP, 4.8f, 0, 0 ); if( pEffect ) { m_nEffectID++; pEffect->SetEffectID( m_nEffectID ); m_vEffectList.push_back( pEffect ); return m_nEffectID; } return -1; } int SGame::AddEffect( FX_DATA * pFX_data ) { _MOTION_FX_SET* pFXSET = GetMotionFxSetDB().GetFXSet( pFX_data->nFX_ID ); if( pFXSET ) { SGameAvatarEx* pOwner = (SGameAvatarEx*)GetGameObject( pFX_data->owner ); if( !pOwner ) return NULL; SGameAvatarEx* pCaster = (SGameAvatarEx*)GetGameObject( pFX_data->attack ); if( !pCaster ) return NULL; SGameAvatarEx* pTarget = (SGameAvatarEx*)GetGameObject( pFX_data->target ); if( !pTarget ) return NULL; if( pOwner->GetEffectRef() > 7 ) return NULL; if( pFX_data->state_handle == 0 ) { if( CheckCameraDistance( pOwner ) == false ) return NULL; } pOwner->EffectAddRef(); SGameEffectEx * pEffect = new SGameEffectEx( pFX_data, pFXSET ); ++m_nNewEffectID; pEffect->SetOwner( pFX_data->owner ); //지울때 사용 pEffect->SetCaster( pFX_data->attack ); /* KEventPointSeq * pEv = NULL; bool bFindSuc = false; { _CID( REQ_EVPOINT ); KMsgREQ_EVPOINT effect_pos_msg; pOwner->Perform( ANIPART_WEAPON_LEFT , id_REQ_EVPOINT, effect_pos_msg ); pOwner->Perform( ANIPART_WEAPON_RIGHT, id_REQ_EVPOINT, effect_pos_msg ); pOwner->Perform( ANIPART_BIPED, id_REQ_EVPOINT, &effect_pos_msg ); //Effect Pos 위치 계산 해야 한다. for( int i(0); effect_pos_msg.GetPointCount()>i; i++ ) { pEv = effect_pos_msg.GetPoint(i); const char * pName = pEv->GetName(); if( strlen(pName) && _stricmp( pName, pEP_Name[pFX_data->nEffPos] ) == 0 ) { pEffect->SetEventPointSequencer( pEv ); bFindSuc = true; break; } } }*/ const K3DMatrix* pEvpMatrix = pOwner->GetEventPointMatrix( pFX_data->nEffPos ); const K3DMatrix* pEvpAttachMatrix = pOwner->GetEventPointAttachMatrix( pFX_data->nEffPos ); K3DMatrix mat; if( pFX_data->nMode == SGameEffectEx::NORMAL_MODE ) { if( pFX_data->bDir ) { //방향 구하기 if( pFX_data->attack != pFX_data->target ) { //방향은 caster -> target pEffect->SetDirection( *pCaster->GetPosition(), *pTarget->GetPosition() ); } else { K3DVector spos = pCaster->GetViewVector(); K3DVector tpos = spos; tpos *= 3; pEffect->SetDirection( spos, tpos ); } } if( pFXSET->nFollowing == 1 ) { if( pFX_data->nEffPos == EFFECT_POS_W_LEFT || pFX_data->nEffPos == EFFECT_POS_W_RIGHT || pFX_data->nEffPos == EFFECT_POS_W_TWOHAND ) { pEffect->IsWeaponEffectPos(); } pEffect->SetParentMat( pOwner->GetTransform(), pEvpAttachMatrix, pEvpMatrix ); mat = *pOwner->GetTransform(); } else { if( pEvpAttachMatrix && pEvpMatrix ) { K3DMatrixMultiply( mat, *pEvpAttachMatrix, *pOwner->GetTransform() ); K3DMatrixMultiply( mat, *pEvpMatrix, mat ); } else mat = *pOwner->GetTransform(); } } else if( pFX_data->nMode == SGameEffectEx::STATE_MODE ) { pEffect->SetParentMat( pOwner->GetTransform(), pEvpAttachMatrix, pEvpMatrix ); mat = *pOwner->GetTransform(); } if( pOwner->GetArID() != pTarget->GetArID() ) { pEffect->SetTargetScale(pTarget->GetScale(), mat); } pEffect->SetEndTime( pFX_data->end_time ); pEffect->SetMode( pFX_data->nMode ); pEffect->SetStateHandle( pFX_data->state_handle ); pEffect->SetMessageHandler( this ); pEffect->SetTransform( mat ); pEffect->SetEffectID( m_nNewEffectID ); pEffect->PlayAnimation( m_dwTime ); //시작 pEffect->IsLoopFx(pFX_data->bIsLoop); if (fabs(pTarget->GetAdjustedScale() - 1.0f) > FLT_EPSILON) { pEffect->SetScaleAdjust(pTarget->GetAdjustedScale()); } pEffect->setTarget(pFX_data->target); /// 2011.04.04 - prodongi m_vNewEffectList.push_back( pEffect ); return m_nNewEffectID; } return -1; } int SGame::AddEffect( FX_DATA_EX * pFX_data ) //Follow Effect { // _oprint( "AddEffect %s, %d\n", pEffectName, end_time ); SGameEffect * pEffect = CreateEffect( pFX_data->m_pEffectName, pFX_data->m_nFlag, pFX_data->m_owner, pFX_data->m_caster, pFX_data->m_target, pFX_data->m_nUseBoneIndex, pFX_data->m_nAniType, pFX_data->m_fPlayRate, pFX_data->m_end_time, pFX_data->m_bIsOwnerDir ); if( pEffect ) { m_nEffectID++; pEffect->SetEffectID( m_nEffectID ); m_vEffectList.push_back( pEffect ); return m_nEffectID; } return -1; } int SGame::AddEffect( AR_HANDLE hAttacker, AR_HANDLE hTarget, AR_HANDLE hOwner, int nEffectID, int nEffectPos, bool bIsLoopFx ) { FX_DATA fxdata; fxdata.attack = hAttacker; fxdata.target = hTarget; fxdata.owner = hOwner; fxdata.nFX_ID = nEffectID; fxdata.nEffPos = nEffectPos; fxdata.bIsLoop = bIsLoopFx; return AddEffect( &fxdata ); } int SGame::AddAttackEffect( FX_DATA * fxdata ) { SGameAvatarEx* pCaster = (SGameAvatarEx*)GetGameObject(fxdata->attack); if(pCaster) { if(pCaster->GetObjType() != TS_ENTER::GAME_PLAYER || fxdata->keyhandleid == SMotionEventHanderDB::EV_HIT) { if( CheckCameraDistance( pCaster ) ) return AddEffect( fxdata ); else return -1; } if(fxdata->keyhandleid != SMotionEventHanderDB::EV_LEFT_HAND_HIT && fxdata->keyhandleid != SMotionEventHanderDB::EV_RIGHT_HAND_HIT && fxdata->keyhandleid != SMotionEventHanderDB::EV_TWO_HAND_HIT) { if( CheckCameraDistance( pCaster ) ) return AddEffect( fxdata ); else return -1; } } else { return -1; } _MOTION_FX_SET* pFXSET = GetMotionFxSetDB().GetFXSet(fxdata->nFX_ID); if( pFXSET ) { SGameAvatarEx* pTarget = (SGameAvatarEx*)GetGameObject(fxdata->target); if( !pTarget ) return NULL; if( CheckCameraDistance( pCaster ) == false ) return -1; if( pCaster->GetEffectRef() > 7 ) return NULL; const K3DMatrix* pmatEPParent; const K3DMatrix* pmatEpAttach; const K3DMatrix* pmatEpPoint; EFFECT_POS_WEAPON nEffectPosWp; switch(fxdata->keyhandleid) { case SMotionEventHanderDB::EV_LEFT_HAND_HIT: nEffectPosWp = EFFECT_POS_LEFT_WEAPON; break; case SMotionEventHanderDB::EV_RIGHT_HAND_HIT: nEffectPosWp = EFFECT_POS_RIGHT_WEAPON; break; case SMotionEventHanderDB::EV_TWO_HAND_HIT: nEffectPosWp = EFFECT_POS_TWOHAND_WEAPON; break; default: { assert( false ); return AddEffect( fxdata ); } } if(!pCaster->GetWeaponEventPoint(nEffectPosWp) || fxdata->keytime == -1) { return AddEffect( fxdata ); } float fFrame = ((fxdata->keytime*4.8f)/160.0f)+0.05f; //반올림 if(!pCaster->SetFrame((int)fFrame)) { return AddEffect( fxdata ); } pmatEPParent = pCaster->GetWeaponEventPointParentMatrix(nEffectPosWp, EFFECT_POS_WEAPON_EP_END); pmatEpAttach = pCaster->GetWeaponEventPointAttachMatrix(nEffectPosWp, EFFECT_POS_WEAPON_EP_END); pmatEpPoint = pCaster->GetWeaponEventPointMatrix(nEffectPosWp, EFFECT_POS_WEAPON_EP_END); K3DMatrix matWpTransform; K3DMatrixIdentity(matWpTransform); K3DMatrixMultiply(matWpTransform, *pmatEpPoint, *pmatEpAttach); K3DMatrixMultiply(matWpTransform, matWpTransform, *pmatEPParent); K3DVector vWpPos; vWpPos.x = matWpTransform._41; vWpPos.y = matWpTransform._42; vWpPos.z = 0.0f;//matWpTransform._43; K3DVector vCasterPos = *pCaster->GetPosition(); K3DVector vTargetPos = *pTarget->GetPosition(); float fCasterLength = K3DVectorLength((vCasterPos - vWpPos)); float fTargetLength = K3DVectorLength((vCasterPos - vTargetPos)); K3DMatrix matTransform; K3DMatrixIdentity(matTransform); if(fCasterLength < fTargetLength) { //무기 위치와 타겟 위치 중간점에서 이펙트 발생됨 K3DVector vWpPos = K3DVector( matWpTransform._41, matWpTransform._42, 0.0f ); vWpPos = vWpPos + ((vTargetPos-vWpPos)/2.0f); matTransform._41 = vWpPos.x; matTransform._42 = vWpPos.y; matTransform._43 = matWpTransform._43; } else { //위치는 타겟위치 높이는 무기 높이 matTransform._41 = vTargetPos.x; matTransform._42 = vTargetPos.y; matTransform._43 = matWpTransform._43; } SGameEffectEx * pEffect = new SGameEffectEx( fxdata, pFXSET ); ++m_nNewEffectID; pCaster->EffectAddRef(); pEffect->SetOwner( fxdata->attack ); //지울때 사용 if( pCaster->GetArID() != pTarget->GetArID() ) { pEffect->SetTargetScale(pTarget->GetScale(), matTransform); } pEffect->SetEndTime(fxdata->end_time ); pEffect->SetMode(fxdata->nMode); pEffect->SetStateHandle(fxdata->state_handle); pEffect->SetMessageHandler(this); pEffect->SetTransform(matTransform); pEffect->SetEffectID(m_nNewEffectID); pEffect->PlayAnimation(m_dwTime); //시작 pEffect->IsLoopFx(fxdata->bIsLoop); if (fabs(pTarget->GetAdjustedScale() - 1.0f) > FLT_EPSILON) { pEffect->SetScalePure(pTarget->GetAdjustedScale()); } m_vNewEffectList.push_back(pEffect); return m_nNewEffectID; } return -1; } bool SGame::CheckCameraDistance( SGameObject* pObject ) { if( m_pViewPort ) { const K3DVector& vCameraPos = m_pViewPort->GetCameraPos(); float fLength = K3DVectorLength( vCameraPos - *pObject->GetPosition() ); if( fLength > GAME_EFFECT_DISTANCE ) return false; } return true; } void SGame::SendGameInterfaceMsg( struct SGameMessage * game_msg ) { if( m_pGameMng ) m_pGameMng->InterfaceMsg( game_msg ); } unsigned g_userCamStates = 0; enum { PAN_UP = 1<<0, PAN_DOWN = 1<<1, PAN_LEFT = 1<<2, PAN_RIGHT = 1<<3, ZOOM_IN = 1<<4, ZOOM_OUT = 1<<5, TURN_LEFT = 1<<6, TURN_RIGHT = 1<<7, TURN_UP = 1<<8, TURN_DOWN = 1<<9 }; static inline unsigned GetUserCamStateFlag( int key ) { switch ( key ) { case VK_UP: return PAN_UP; case VK_DOWN: return PAN_DOWN; case VK_LEFT: return PAN_LEFT; case VK_RIGHT: return PAN_RIGHT; case VK_PRIOR: return ZOOM_IN; case VK_NEXT: return ZOOM_OUT; case 188: return TURN_LEFT; // '<' case 190: return TURN_RIGHT; // '>' case 191: return TURN_UP; // '/' case 222: return TURN_DOWN; // '/' } return 0; } void SGame::ProcMsgAtStatic( SGameMessage * pGameMsg ) { /// 2010.11.10 - prodongi /* extern bool g_bUserCamMode; if ( !g_bUserCamMode ) return; */ if (g_UserInfo.isMonkeyTail()) { extern bool g_bUserCamMode; if ( !g_bUserCamMode ) return; } switch( pGameMsg->nType ) { case IMSG_KEYDOWN: { SIMSG_KEYDOWN* pMsg = (SIMSG_KEYDOWN*)pGameMsg; g_userCamStates |= GetUserCamStateFlag( LOWORD( pMsg->wParam ) ); break; } case IMSG_KEYUP: { SIMSG_KEYUP* pMsg = (SIMSG_KEYUP*)pGameMsg; g_userCamStates &= ~GetUserCamStateFlag( LOWORD( pMsg->wParam ) ); break; } } int nDeltaSpeed = 1*m_nDeltaSpeed; /// 2010.11.11 - prodongi /* if( g_userCamStates & PAN_UP ) m_pCamera->Pan(0,nDeltaSpeed,0); if( g_userCamStates & PAN_DOWN ) m_pCamera->Pan(0,-nDeltaSpeed,0); if( g_userCamStates & PAN_LEFT ) m_pCamera->Pan(-nDeltaSpeed,0,0); if( g_userCamStates & PAN_RIGHT ) m_pCamera->Pan(nDeltaSpeed,0,0); */ if( g_userCamStates & PAN_UP ) m_pCamera->PanWithCamDir(0, 0, nDeltaSpeed); if( g_userCamStates & PAN_DOWN ) m_pCamera->PanWithCamDir(0,0, -nDeltaSpeed); if( g_userCamStates & PAN_LEFT ) m_pCamera->PanWithCamDir(-nDeltaSpeed,0,0); if( g_userCamStates & PAN_RIGHT ) m_pCamera->PanWithCamDir(nDeltaSpeed,0,0); if( g_userCamStates & ZOOM_IN ) m_pCamera->Pan(0,0,nDeltaSpeed); if( g_userCamStates & ZOOM_OUT ) m_pCamera->Pan(0,0,-nDeltaSpeed); if( g_userCamStates & TURN_LEFT ) //'<' m_pCamera->Turn( (float)(-(float)1 * 3.14/m_nDeltaX) ); if( g_userCamStates & TURN_RIGHT ) //'>' m_pCamera->Turn( (float)( (float)1 * 3.14/m_nDeltaX) ); if( g_userCamStates & TURN_UP ) //'/' m_pCamera->Elevation( (float)( (float)1 * 3.14/m_nDeltaY) ); if( g_userCamStates & TURN_DOWN ) //'/' m_pCamera->Elevation( (float)( -(float)1 * 3.14/m_nDeltaY) ); } void SGame::ReqMove( AR_HANDLE handle, const ArPosition & target, const ArPosition * targetposdata, int count, bool bSpeedSync ) { if( IsStopProcess() ) return; m_pArObject->ReqMove( handle, target, targetposdata, count, bSpeedSync ); } void SGame::Game_Sound_Set_Volume( int nVolume ) { if( m_pMSoundMgr ) m_pMSoundMgr->SetMasterVolume( nVolume ); } void SGame::Game_Env_Off( bool bOnOff ) { if( m_pMSoundMgr ) m_pMSoundMgr->SetEnvMute( bOnOff ); } void SGame::Game_Music_Off( bool bOnOff ) { if( m_pMSoundMgr ) m_pMSoundMgr->SetBgmMute( bOnOff ); } K3DTexture * SGame::CreateBump(K3DRenderDeviceDX *pDevice) { K3DTexture * pBumpTex = NULL; pBumpTex = pDevice->CreateTexture( 512, 512, K3DFMT_V8U8 ); if( pBumpTex == NULL ) return NULL; char *pBuf; int nStride; pBumpTex->LockRect( NULL, (void**)&pBuf, nStride ); assert(pBuf && "pBumpTex->LockRect( NULL, (void**)&pBuf, nStride );"); CHAR* pDst = (CHAR*)pBuf; CHAR iDu, iDv; unsigned int dwHeight, dwWidth; dwHeight = dwWidth = 512; for( DWORD y=0; yUnlock(); return pBumpTex; } void SGame::OnSysCommand( const char *pChat, std::vector< std::string > & vToken ) { std::string strCheat; std::string strCommand = vToken[0].c_str()+2; char szShortTmp[32]; memset( szShortTmp, 0, sizeof(szShortTmp) ); if( strCommand == "set_r" ) //해상도 변경 { if( vToken.size() > 2 ) { if( m_pGameMng ) m_pGameMng->SetResolution( atoi(vToken[1].c_str()), atoi(vToken[2].c_str()) ); GetGameOption().SetResolution_Width ( atoi(vToken[1].c_str()) ); GetGameOption().SetResolution_Height( atoi(vToken[2].c_str()) ); } return; } if( strCommand == "set_w" ) //창/풀 스크린 변경 { ((K3DRenderDeviceDX*) KDeviceManagerDX::GetDeviceManager()->GetRenderDevice())->ToggleFullscreen( (bool) atoi(vToken[1].c_str()) ); GetGameOption().SetWinMode( atoi(vToken[1].c_str()) ); return; } else if( strCommand == "web_toggle") { if( g_pWebBrowser ) { //SetNavigate( "http://itemshop.rappelz.com/" ); if( g_IsShowWebBrowser ) SetVisibleNavigate( false ); else SetVisibleNavigate( true ); } } else if( strCommand == "web_url") { if( vToken.size() > 1 && g_pWebBrowser ) { SetNavigate( vToken[1].c_str(), true, 0, 0 ); } } else if( strCommand == "guild_close" || strCommand == "web_close" ) { SetOtherNavigateClose( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_GUILD_TITLE ); SendGameInterfaceMsg( &SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_GUILD_TITLE, false) ); SendGameInterfaceMsg( &SMSG_SEND_DATA( "web_close" ) ); } else if( strCommand == "web_open") { if( vToken.size() <= 1 ) return; SetOtherNavigate( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_GUILD_TITLE, vToken[1].c_str(), 240, 330 ); } } void SGame::ProcConsole( SGameMessage* pGameMsg ) { if( pGameMsg->nType == MSG_CONSOLE_BUILDER ) { SMSG_CONSOLE_BUILDER* pMsg = static_cast(pGameMsg); } } int SGame::AddEnhanceEffect( SGameAvatarEx* pAvatar, int nWeaponEffectPos, EnhanceFX* pEnhanceFx, int nItemClass ) { int nRecycleID = GetEnhanceRecycleID(); if( nRecycleID == -1 ) nRecycleID = ++m_nNewEnhanceFxID; SGameEnhanceFx* pGameEnhanceFx = new SGameEnhanceFx; pGameEnhanceFx->Init( pAvatar, nWeaponEffectPos, nItemClass ); pGameEnhanceFx->SetEnhanceFxID( nRecycleID ); m_vEnhanceFxList.push_back( pGameEnhanceFx ); return nRecycleID; } void SGame::RemoveEnhanceEffect( int nEnhanceFxID ) { std::vector< SGameEnhanceFx* >::iterator iter = m_vEnhanceFxList.begin(); for( ; iter != m_vEnhanceFxList.end(); ++iter ) { if( nEnhanceFxID == (*iter)->GetEnhanceFxID() ) { (*iter)->SetEnd(true); m_RecycleID.push( nEnhanceFxID ); break; } } } int SGame::GetEnhanceRecycleID() { int nRecycleID = -1; if( !m_RecycleID.empty() ) { nRecycleID = m_RecycleID.front(); m_RecycleID.pop(); } return nRecycleID; } void SGame::SetRenderEnhanceFx( int nEnhanceFxID, bool bRender ) { std::vector< SGameEnhanceFx* >::iterator iter = m_vEnhanceFxList.begin(); for( ; iter != m_vEnhanceFxList.end(); iter++ ) { if( nEnhanceFxID == (*iter)->GetEnhanceFxID() ) { (*iter)->SetRenderFlag( bRender ); break; } } } //파티클 치트 모드 고쳐야하는데 void SGame::ParticleQuality( int nQuality ) { std::vector< class SGameEnhanceFx* >::iterator iter = m_vEnhanceFxList.begin(); for( ; iter != m_vEnhanceFxList.end(); iter++ ) (*iter)->SetParticleQuality( nQuality ); } void SGame::ParticleLifeTime( DWORD dwLifeTime ) { std::vector< class SGameEnhanceFx* >::iterator iter = m_vEnhanceFxList.begin(); for( ; iter != m_vEnhanceFxList.end(); iter++ ) (*iter)->SetLifeTime( dwLifeTime ); } void SGame::ParticleMoveSpeed( float fSpeed ) { std::vector< class SGameEnhanceFx* >::iterator iter = m_vEnhanceFxList.begin(); for( ; iter != m_vEnhanceFxList.end(); iter++ ) (*iter)->SetMoveSpeed( fSpeed ); } void SGame::ParticleSize( float fStartSize, float fEndSize ) { std::vector< class SGameEnhanceFx* >::iterator iter = m_vEnhanceFxList.begin(); for( ; iter != m_vEnhanceFxList.end(); iter++ ) (*iter)->SetSize( fStartSize, fEndSize ); } void SGame::ParticleEmitRadius( K3DVector vEmitRadius ) { std::vector< class SGameEnhanceFx* >::iterator iter = m_vEnhanceFxList.begin(); for( ; iter != m_vEnhanceFxList.end(); iter++ ) (*iter)->SetEmitRadius( vEmitRadius ); } void SGame::ParticleEmitRate( float fMin, float fMax ) { std::vector< class SGameEnhanceFx* >::iterator iter = m_vEnhanceFxList.begin(); for( ; iter != m_vEnhanceFxList.end(); iter++ ) (*iter)->SetEmitRate( fMin, fMax ); } void SGame::ParticleCreateInterval( float fInterval ) { std::vector< class SGameEnhanceFx* >::iterator iter = m_vEnhanceFxList.begin(); for( ; iter != m_vEnhanceFxList.end(); iter++ ) (*iter)->SetCreateInterval( fInterval ); } void SGame::ParticleMinDirection( K3DVector vMinDirection ) { std::vector< class SGameEnhanceFx* >::iterator iter = m_vEnhanceFxList.begin(); for( ; iter != m_vEnhanceFxList.end(); iter++ ) (*iter)->SetMinDirection( vMinDirection ); } void SGame::ParticleMaxDirection( K3DVector vMaxDirection ) { std::vector< class SGameEnhanceFx* >::iterator iter = m_vEnhanceFxList.begin(); for( ; iter != m_vEnhanceFxList.end(); iter++ ) (*iter)->SetMaxDirection( vMaxDirection ); } void SGame::EnhanceFxType( int nType ) { std::vector< class SGameEnhanceFx* >::iterator iter = m_vEnhanceFxList.begin(); for( ; iter != m_vEnhanceFxList.end(); iter++ ) (*iter)->SetEnhanceFxType( nType ); } /* return value 1: 자기자신 2: 파티원 3: 던전시즈 중 길드원 4: NPC 5: 소환크리처 6: 파티원 크리처 7: 던전시즈 중 길드원 크리처*/ //Handle에 해당하는 대상이 친구인지 알아보는 함수 -N4- //평상시엔 파티워 아바타와 크리처 자신의 크리처, 던전 시즈중에는 길드원과 길드원의 크리처도 동료에 포함 int SGame::IsFriend( AR_HANDLE Handle, unsigned char& rType ) { return m_pGameMng->IsFriend(Handle, rType); }