Files
Leviathan/Client/Game/game/GameSystem/SGameUISyncMng.cpp
T
2026-06-01 12:46:52 +02:00

463 lines
13 KiB
C++

#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;
}
}