#include "stdafx.h" #include "SGameUISyncMng.h" #include "SGameAvatarEx.h" #include "SGameMessage.h" //#include "SGameMessageUI.h" #include "SGame.h" #include "SDebug_Util.h" #include "SLog.h" SGameUISyncMng::SGameUISyncMng( SGame* pGame ) { m_pGame = pGame; } SGameUISyncMng::~SGameUISyncMng() { m_pGame = NULL; m_vHandleInfo.clear(); } void SGameUISyncMng::ProcessHPMP( SGameAvatarEx* pAvatar, UI_SYNC_DATA* pSyncData, UI_SYNC_INFO::TARGET_INFO* pSyncInfo ) { // MAX HP/MP 관련 처리했음. by P.Lotos int nHP = pAvatar->GetHP(); int nMP = pAvatar->GetMP(); if( pSyncInfo->nTarget_maxHp != -1 ) { pAvatar->SetMaxHP( pSyncInfo->nTarget_maxHp ); SDEBUGLOG("HP가 -1이 들어왔음"); } if( pSyncInfo->nTarget_maxMp != -1 ) { pAvatar->SetMaxMP( pSyncInfo->nTarget_maxMp ); } int nMaxHP = pAvatar->GetMaxHP(); int nMaxMP = pAvatar->GetMaxMP(); if( --pSyncData->nMessageCnt > 0 ) { nHP = nHP - pSyncInfo->nDamage; nMP = nMP - pSyncInfo->nMPDamage; // 클라와 서버간에 HP가 다르다면 서버측 기준으로 설정 // MP도 같은 코드를 넣어서 실험해봤는데 싱크에러가 너무많이 떠서 일단 보류... if (nHP != pSyncInfo->nTarget_hp) { // SDEBUGLOG("HP Sync error - Name : %s / Client : %d / Server : %d", pAvatar->GetName(), nHP, pSyncInfo->nTarget_hp); //nHP = pSyncInfo->nTarget_hp; } if( nHP > nMaxHP ) nHP = nMaxHP; else if( nHP <= 0 ) nHP = 0; if( nMP > nMaxMP ) nMP = nMaxMP; else if( nMP <= 0 ) nMP = 0; } else { if( pSyncData->nMessageCnt <= -1 ) { if( pSyncData->nLast_hp != -1 ) { nHP = pSyncData->nLast_hp; } else { nHP = nMaxHP; } if( pSyncData->nLast_mp != -1 ) { nMP = pSyncData->nLast_mp; } else { nMP = nMaxMP; } } else { nHP = pSyncData->nLast_hp; nMP = pSyncData->nLast_mp; } pSyncData->nMessageCnt = 0; if( nHP <= 0 ) { nHP = 0; pAvatar->Dead(); } } pAvatar->SetHP( nHP ); pAvatar->SetMP( nMP ); SendUIMessage( pAvatar, SIMSG_UI_TARGET_STAT::USE_DEF, nHP, nMP ); } void SGameUISyncMng::SendUIMessage( SGameAvatarEx* pAvatar, int nMode, __int64 nHP, __int64 nMP ) { SIMSG_UI_TARGET_STAT ui_sync; //캐스터 처리 ui_sync.handle = pAvatar->GetArID(); ui_sync.m_nMode = nMode; ui_sync.m_nVar1 = nHP; ui_sync.m_nVar2 = nMP; ui_sync.m_nVar3 = pAvatar->GetMaxHP(); ui_sync.m_nVar4 = pAvatar->GetMaxMP(); m_pGame->ProcMsgAtStatic( &ui_sync ); } void SGameUISyncMng::SendUIMessage( SGameAvatarEx* pAvatar, int nMode, int nPer, __int64 nExp, __int64 nJp ) { SIMSG_UI_TARGET_STAT ui_sync; //캐스터 처리 ui_sync.handle = pAvatar->GetArID(); ui_sync.m_nMode = nMode; ui_sync.m_nVar1 = nPer; ui_sync.m_nVar2 = nExp; ui_sync.m_nVar3 = nJp; ui_sync.m_nVar4 = 0; m_pGame->ProcMsgAtStatic( &ui_sync ); } void SGameUISyncMng::ProcUiSyncMsg( SGameAvatarEx* pCaster, AR_HANDLE target, int nUseType ) { UI_SYNC_DATA* pUISyncData = pCaster->GetUISyncData(); assert( pUISyncData && "SGameUISyncMng::ProcUiSyncMsg pUISyncData == NULL" ); std::vector< UI_SYNC_INFO >::iterator itSync = pUISyncData->vinfo_list.begin(); for( ;itSync != pUISyncData->vinfo_list.end(); ) { if( (*itSync).nMode == SIMSG_UI_TARGET_STAT::USE_DEF || (*itSync).nMode == SIMSG_UI_TARGET_STAT::USE_STATE_DMG ) { if( (*itSync).nMode != nUseType ) { ++itSync; continue; } bool bCheck = false; std::vector< UI_SYNC_INFO::TARGET_INFO >::iterator iter = (*itSync).vTargetInfo.begin(); for( ; iter != (*itSync).vTargetInfo.end(); ) { if( (*iter).hTarget != target ) { // 셀프타겟, 광역스킬의 경우 삭제가 안 되서 루프 끝나고 size가 1이상이라 ProcessHPMP로 안 빠지던 버그 수정 //if ( target != INFINITE_TIME) //{ // iter = (*itSync).vTargetInfo.erase( iter ); // continue; //} 왜 이게 들어가있는지 헷갈려서 빼버림 -_- } bCheck = true; SGameAvatarEx* pTarget = (SGameAvatarEx*)m_pGame->GetGameObject( (*iter).hTarget ); if( pTarget ) { UI_SYNC_DATA* pTargetUISyncData = pTarget->GetUISyncData(); assert( pTargetUISyncData && "SGameUISyncMng::ProcUiSyncMsg pTargetUISyncData == NULL" ); ProcessHPMP( pTarget, pTargetUISyncData, &(*iter) ); } iter = (*itSync).vTargetInfo.erase( iter ); // break; } if( (*itSync).vTargetInfo.size() == 0 ) { // ProcessHPMP( pCaster, pUISyncData, &pUISyncData->vinfo_list[0].CasterInfo ); ProcessHPMP( pCaster, pUISyncData, &(*itSync).CasterInfo ); itSync = pUISyncData->vinfo_list.erase( itSync ); // break; } // else if( bCheck ) // break; } else ++itSync; } } void SGameUISyncMng::ProcessUIMsg( DWORD dwTime ) { if( m_vHandleInfo.empty() ) return; std::vector< AR_HANDLE >::iterator itHandle = m_vHandleInfo.begin(); for( ; itHandle != m_vHandleInfo.end(); ) { SGameAvatarEx* pAvatar = (SGameAvatarEx*)m_pGame->GetGameObject( (*itHandle) ); if( pAvatar == NULL ) { assert( pAvatar && "SGameUISyncMng::ProcessUIMsg pAvatar == NULL" ); itHandle = m_vHandleInfo.erase( itHandle ); continue; } UI_SYNC_DATA* pUISyncData = pAvatar->GetUISyncData(); if( pUISyncData == NULL ) { assert( pUISyncData && "SGameUISyncMng::ProcessUIMsg pUISyncData == NULL" ); itHandle = m_vHandleInfo.erase( itHandle ); continue; } std::vector< UI_SYNC_INFO >::iterator itinfo_list = pUISyncData->vinfo_list.begin(); for( ; itinfo_list != pUISyncData->vinfo_list.end(); ) { // floyd 2010. 5. 13 베트라얄 버그 관련 서버와 클라이언트의 아바타 피통 싱크를 맞추기 위해서 지연 적용되던 HP정보를 즉시 적용으로 수정 /* if( dwTime - (*itinfo_list).dwTime < 10000 && ( (*itinfo_list).nMode == SIMSG_UI_TARGET_STAT::USE_DEF || (*itinfo_list).nMode == SIMSG_UI_TARGET_STAT::USE_STATE_DMG ) ) { // 10초 이전이고, 어택 싱크 처리해야 하는 경우라면 ”?by P.Lotos break; } */ switch( (*itinfo_list).nMode ) { case SIMSG_UI_TARGET_STAT::USE_DEF: { // 여기 오시는 USE_DEF 님은 10초 넘어서 오시는 분 by P.Lotos std::vector< UI_SYNC_INFO::TARGET_INFO >::iterator ittargetinfo = (*itinfo_list).vTargetInfo.begin(); for( ; ittargetinfo != (*itinfo_list).vTargetInfo.end(); ++ittargetinfo) { SGameAvatarEx* pTarget = (SGameAvatarEx*)m_pGame->GetGameObject( (*ittargetinfo).hTarget ); if( pTarget ) { UI_SYNC_DATA* pSyncData = pTarget->GetUISyncData(); assert( pSyncData && "pSyncData" ); ProcessHPMP( pTarget, pSyncData, &(*ittargetinfo) ); } } ProcessHPMP( pAvatar, pUISyncData, &(*itinfo_list).CasterInfo ); itinfo_list = pUISyncData->vinfo_list.erase( itinfo_list ); } break; case SIMSG_UI_TARGET_STAT::USE_HPMP: { ProcessHPMP( pAvatar, pUISyncData, &(*itinfo_list).CasterInfo ); itinfo_list = pUISyncData->vinfo_list.erase( itinfo_list ); } break; case SIMSG_UI_TARGET_STAT::USE_STATE_DMG: { ProcessHPMP( pAvatar, pUISyncData, &(*itinfo_list).CasterInfo ); itinfo_list = pUISyncData->vinfo_list.erase( itinfo_list ); } break; case SIMSG_UI_TARGET_STAT::USE_EXP: { if( ( dwTime - (*itinfo_list).dwTime ) >= 2000 ) { //공격보다 먼저 오므로, 인터페이스 딜레이 주기 위함 SendUIMessage( pAvatar, SIMSG_UI_TARGET_STAT::USE_EXP, (*itinfo_list).CasterInfo.nTarget_hp, (*itinfo_list).CasterInfo.nTarget_mp ); itinfo_list = pUISyncData->vinfo_list.erase( itinfo_list ); } else ++itinfo_list; } break; case SIMSG_UI_TARGET_STAT::USE_EXP_JP_BONUS_PCBANG: { if( ( dwTime - (*itinfo_list).dwTime ) >= 2300 ) { SendUIMessage( pAvatar, SIMSG_UI_TARGET_STAT::USE_EXP_JP_BONUS_PCBANG, (*itinfo_list).CasterInfo.nDamage, (*itinfo_list).CasterInfo.nTarget_hp, (*itinfo_list).CasterInfo.nTarget_mp ); itinfo_list = pUISyncData->vinfo_list.erase( itinfo_list ); } else ++itinfo_list; } break; case SIMSG_UI_TARGET_STAT::USE_EXP_JP_BONUS_STAMINA: { if( ( dwTime - (*itinfo_list).dwTime ) >= 2600 ) { SendUIMessage( pAvatar, SIMSG_UI_TARGET_STAT::USE_EXP_JP_BONUS_STAMINA, (*itinfo_list).CasterInfo.nDamage, (*itinfo_list).CasterInfo.nTarget_hp, (*itinfo_list).CasterInfo.nTarget_mp ); itinfo_list = pUISyncData->vinfo_list.erase( itinfo_list ); } else ++itinfo_list; } break; case SIMSG_UI_TARGET_STAT::USE_EXP_JP_BONUS_PREMIUM_PCBANG: { if( ( dwTime - (*itinfo_list).dwTime ) >= 2900 ) { SendUIMessage( pAvatar, SIMSG_UI_TARGET_STAT::USE_EXP_JP_BONUS_PREMIUM_PCBANG, (*itinfo_list).CasterInfo.nDamage, (*itinfo_list).CasterInfo.nTarget_hp, (*itinfo_list).CasterInfo.nTarget_mp ); itinfo_list = pUISyncData->vinfo_list.erase( itinfo_list ); } else ++itinfo_list; } break; case SIMSG_UI_TARGET_STAT::USE_EXP_JP_BONUS_OGOK:// 오곡크래커 관련 2009.04.14 sfreer { if( ( dwTime - (*itinfo_list).dwTime ) >= 3200 ) { SendUIMessage( pAvatar, SIMSG_UI_TARGET_STAT::USE_EXP_JP_BONUS_OGOK, (*itinfo_list).CasterInfo.nDamage, (*itinfo_list).CasterInfo.nTarget_hp, (*itinfo_list).CasterInfo.nTarget_mp ); itinfo_list = pUISyncData->vinfo_list.erase( itinfo_list ); } else ++itinfo_list; } break; // 2010.10.01 왜 시간이 300씩 증가하는지 모르겠음,,- prodongi case SIMSG_UI_TARGET_STAT::USE_EXP_JP_BONUS_SUPER_SAVE: { if( ( dwTime - (*itinfo_list).dwTime ) >= 3500 ) { SendUIMessage( pAvatar, SIMSG_UI_TARGET_STAT::USE_EXP_JP_BONUS_SUPER_SAVE, (*itinfo_list).CasterInfo.nDamage, (*itinfo_list).CasterInfo.nTarget_hp, (*itinfo_list).CasterInfo.nTarget_mp ); itinfo_list = pUISyncData->vinfo_list.erase( itinfo_list ); } else ++itinfo_list; } break; default: { ++itinfo_list; } break; } } if( pUISyncData->vinfo_list.empty() ) itHandle = m_vHandleInfo.erase( itHandle ); else ++itHandle; } } void SGameUISyncMng::AddHandle( AR_HANDLE hHandle ) { std::vector< AR_HANDLE >::iterator itHandle = m_vHandleInfo.begin(); for( ; itHandle != m_vHandleInfo.end(); ++itHandle ) { if( (*itHandle) == hHandle ) return; } m_vHandleInfo.push_back( hHandle ); } void SGameUISyncMng::LeaveHandle( AR_HANDLE hHandle ) { if( m_vHandleInfo.empty() ) return; std::vector< AR_HANDLE >::iterator itHandle = m_vHandleInfo.begin(); for( ; itHandle != m_vHandleInfo.end(); ++itHandle ) { if( (*itHandle) == hHandle ) { SGameAvatarEx* pAvatar = (SGameAvatarEx*)m_pGame->GetGameObject( hHandle ); if( pAvatar == NULL ) { assert( pAvatar && "SGameUISyncMng::LeaveHandle pAvatar == NULL" ); itHandle = m_vHandleInfo.erase( itHandle ); break; } UI_SYNC_DATA* pUISyncData = pAvatar->GetUISyncData(); if( pUISyncData == NULL ) { assert( pUISyncData && "SGameUISyncMng::LeaveHandle pUISyncData == NULL" ); itHandle = m_vHandleInfo.erase( itHandle ); break; } std::vector< UI_SYNC_INFO >::iterator itinfo_list = pUISyncData->vinfo_list.begin(); for( ; itinfo_list != pUISyncData->vinfo_list.end(); ) { if( (*itinfo_list).nMode == SIMSG_UI_TARGET_STAT::USE_DEF ) { std::vector< UI_SYNC_INFO::TARGET_INFO >::iterator ittargetinfo = (*itinfo_list).vTargetInfo.begin(); for( ; ittargetinfo != (*itinfo_list).vTargetInfo.end(); ++ittargetinfo) { SGameAvatarEx* pTarget = (SGameAvatarEx*)m_pGame->GetGameObject( (*ittargetinfo).hTarget ); if( pTarget ) { UI_SYNC_DATA* pSyncData = pTarget->GetUISyncData(); assert( pSyncData && "pSyncData" ); ProcessHPMP( pTarget, pSyncData, &(*ittargetinfo) ); } } itinfo_list = pUISyncData->vinfo_list.erase( itinfo_list ); } else ++itinfo_list; } itHandle = m_vHandleInfo.erase( itHandle ); break; } } } void SGameUISyncMng::LeaveUISyncMsg( SGameAvatarEx* pAvatar ) { UI_SYNC_DATA* pUISyncData = pAvatar->GetUISyncData(); if( pUISyncData == NULL ) { assert( pUISyncData && "SGameUISyncMng::LeaveUISyncMsg pUISyncData == NULL" ); return; } std::vector< UI_SYNC_INFO >::iterator itinfo_list = pUISyncData->vinfo_list.begin(); for( ; itinfo_list != pUISyncData->vinfo_list.end(); ) { if( (*itinfo_list).nMode == SIMSG_UI_TARGET_STAT::USE_DEF ) { std::vector< UI_SYNC_INFO::TARGET_INFO >::iterator ittargetinfo = (*itinfo_list).vTargetInfo.begin(); for( ; ittargetinfo != (*itinfo_list).vTargetInfo.end(); ++ittargetinfo) { SGameAvatarEx* pTarget = (SGameAvatarEx*)m_pGame->GetGameObject( (*ittargetinfo).hTarget ); if( pTarget ) { UI_SYNC_DATA* pSyncData = pTarget->GetUISyncData(); assert( pSyncData && "pSyncData" ); ProcessHPMP( pTarget, pSyncData, &(*ittargetinfo) ); } } itinfo_list = pUISyncData->vinfo_list.erase( itinfo_list ); } else ++itinfo_list; } }