DragonNest/GameCommon/DnBubbleSystem.cpp

564 lines
31 KiB
C++
Raw Normal View History

2024-12-20 16:56:44 +08:00
<EFBFBD><EFBFBD>#include "StdAfx.h"
#include "DnBubbleSystem.h"
#include "DnBubbleConditionChecker.h"
#include "DnObserverEventMessage.h"
#include "DnBubbleEventHandler.h"
#include "DnBubble.h"
#include "DnTableDB.h"
#include "DnPlayerActor.h"
#include "Stream.h"
#ifdef _CLIENT
#include "../Client/DragonNest/DnInterface.h"
#endif
namespace BubbleSystem
{
CDnBubbleSystem::S_DEFINED_BUBBLE_EVENT::~S_DEFINED_BUBBLE_EVENT( void )
{
SAFE_DELETE_PVEC( vlpConditions );
SAFE_DELETE_PVEC( vlpEventHandlers );
}
CDnBubbleSystem::CDnBubbleSystem( void )
{
}
CDnBubbleSystem::~CDnBubbleSystem( void )
{
RemoveAllBubbles( false );
// }Ǵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>X<EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD>P<EFBFBD> t<EFBFBD><EFBFBD>.
SAFE_DELETE_PVEC( m_vlpDefinedBubbleEvent );
//map<int, IDnBubbleEventHandler*>::iterator iter = m_mapBubbleRemoveEventHandlers.begin();
//for( iter; iter != m_mapBubbleRemoveEventHandlers.end(); ++iter )
//{
// SAFE_DELETE( iter->second );
//}
}
void CDnBubbleSystem::Initialize( DnActorHandle hActor )
{
// <EFBFBD><EFBFBD><EFBFBD> <EFBFBD>̬<EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̹ <EFBFBD>̬<EFBFBD>. t<EFBFBD>|<EFBFBD><EFBFBD><EFBFBD> (ӷ<EFBFBD>̹ <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
#ifdef _GAMESERVER
// ֬<EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD>¤<EFBFBD>\<EFBFBD>@<EFBFBD> <EFBFBD><EFBFBD><EFBFBD>̹ <EFBFBD><EFBFBD><EFBFBD>.
if( false == hActor->IsPlayerActor() )
return;
m_hActor = hActor;
// t<EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> t<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> L<EFBFBD>t<EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>|<EFBFBD> <EFBFBD><EFBFBD><EFBFBD>@<EFBFBD><EFBFBD> p<EFBFBD>t<EFBFBD>0<EFBFBD>|<EFBFBD> l<EFBFBD>1<EFBFBD>t<EFBFBD> `<EFBFBD>.
DNTableFileFormat* pBubbleTable = GetDNTable( CDnTableDB::TSKILLBUBBLE );
char acBuffer[ 512 ] = { 0 };
int iItemCount = pBubbleTable->GetItemCount();
for( int iIndex = 0; iIndex < iItemCount; ++iIndex )
{
int iBubbleTableID = pBubbleTable->GetItemID( iIndex );
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD>\<EFBFBD>t<EFBFBD> <EFBFBD>ǔ<EFBFBD><EFBFBD><EFBFBD> U<EFBFBD>x<EFBFBD>. <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ιD<EFBFBD><EFBFBD><EFBFBD>t<EFBFBD> #<EFBFBD><EFBFBD><EFBFBD>.
// 0 t<EFBFBD>t<EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD>\<EFBFBD> <EFBFBD><EFBFBD>L<EFBFBD>. <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD>\<EFBFBD>t<EFBFBD> <EFBFBD>\<EFBFBD><EFBFBD><EFBFBD>t<EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD>פ Ѭ<EFBFBD>|<EFBFBD> <EFBFBD><EFBFBD>8<EFBFBD><EFBFBD> t<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD≯̹ <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
int iNeedJobCode = pBubbleTable->GetFieldFromLablePtr( iBubbleTableID, "_NeedJob" )->GetInteger();
if( 0 < iNeedJobCode )
{
CDnPlayerActor* pPlayerActor = static_cast<CDnPlayerActor*>(m_hActor.GetPointer());
bool bAvailableJob = pPlayerActor->IsPassJob( iNeedJobCode );
if( false == bAvailableJob )
{
// <EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD>q<EFBFBD><EFBFBD><EFBFBD><EFBFBD> J<EFBFBD>L<EFBFBD>.
continue;
}
}
// <EFBFBD><EFBFBD>\<EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD>X<EFBFBD> l<EFBFBD><EFBFBD> <EFBFBD><EFBFBD>1<EFBFBD>.
S_DEFINED_BUBBLE_EVENT* pNewBubbleInfo = new S_DEFINED_BUBBLE_EVENT;
pNewBubbleInfo->iTableID = iBubbleTableID;
// p<EFBFBD>t<EFBFBD> <EFBFBD><EFBFBD><EFBFBD>|<EFBFBD> l<EFBFBD>1<EFBFBD>.
for( int i = 0; i < 5; ++i )
{
sprintf_s( acBuffer, "_ConditionType%d", i+1 );
int iConditionType = pBubbleTable->GetFieldFromLablePtr( iBubbleTableID, acBuffer )->GetInteger();
sprintf_s( acBuffer, "_ConditionFactor%d", i+1 );
string strArgument = pBubbleTable->GetFieldFromLablePtr( iBubbleTableID, acBuffer )->GetString();
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> NULL t<EFBFBD>|<EFBFBD>t<EFBFBD> L<EFBFBD>t<EFBFBD><EFBFBD><EFBFBD><EFBFBD> p<EFBFBD>t<EFBFBD> <EFBFBD>Ѕ<EFBFBD>t<EFBFBD> 0 <<EFBFBD>\<EFBFBD> K<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ňǔ<EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD>. <EFBFBD><EFBFBD> D<EFBFBD><EFBFBD>ň<EFBFBD>L<EFBFBD>.
IDnConditionChecker* pConditionChecker = IDnConditionChecker::Create( iConditionType, strArgument.c_str() );
if( pConditionChecker )
{
pNewBubbleInfo->vlpConditions.push_back( pConditionChecker );
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD>D<EFBFBD> <EFBFBD>t<EFBFBD> p<EFBFBD>t<EFBFBD> <EFBFBD>Ѕ<EFBFBD><EFBFBD><EFBFBD> 0<EFBFBD>|<EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>@<EFBFBD> X<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǔ<EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>|<EFBFBD> <EFBFBD><EFBFBD>0<EFBFBD><EFBFBD> <EFBFBD>Ű<EFBFBD>t<EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
// <EFBFBD> p<EFBFBD>t<EFBFBD>ļ\<EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǔ<EFBFBD> <EFBFBD><EFBFBD><EFBFBD> T<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD>Ѕ<EFBFBD>ļ\<EFBFBD> <EFBFBD>,<EFBFBD><EFBFBD><EFBFBD><EFBFBD> H<EFBFBD>.
int iEventType = _GetRelatedEventMessageType( iConditionType );
if( NONE_BUBBLE_EVENT_MESSAGE != iEventType )
m_mmapDefinedByEvent.insert( make_pair(iEventType, pNewBubbleInfo) );
//////////////////////////////////////////////////////////////////////////
}
else
break;
}
// <EFBFBD><EFBFBD><EFBFBD> x<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>|<EFBFBD> l<EFBFBD>1<EFBFBD>.
for( int i = 0; i < 5; ++i )
{
sprintf_s( acBuffer, "_BubbleType%d", i+1 );
int iEventHandlerType = pBubbleTable->GetFieldFromLablePtr( iBubbleTableID, acBuffer )->GetInteger();
sprintf_s( acBuffer, "_BubbleFactor%d", i+1 );
string strArgument = pBubbleTable->GetFieldFromLablePtr( iBubbleTableID, acBuffer )->GetString();
IDnBubbleEventHandler* pEventHandler = IDnBubbleEventHandler::Create( iEventHandlerType, hActor, strArgument.c_str() );
if( pEventHandler )
{
pNewBubbleInfo->vlpEventHandlers.push_back( pEventHandler );
_OnCreateEventHandler( pBubbleTable, iBubbleTableID, pEventHandler, strArgument.c_str() );
}
else
break;
}
m_vlpDefinedBubbleEvent.push_back( pNewBubbleInfo );
}
#endif
}
void CDnBubbleSystem::_OnCreateEventHandler( DNTableFileFormat* pBubbleTable, int iBubbleTableID, IDnBubbleEventHandler* pEventHandler, const char* pArgument )
{
#ifdef _GAMESERVER
// <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> x<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<EFBFBD>t<EFBFBD> D<EFBFBD>t<EFBFBD>X<EFBFBD> <EFBFBD><EFBFBD><EFBFBD>ij <EFBFBD><EFBFBD><EFBFBD>t<EFBFBD><EFBFBD><EFBFBD><EFBFBD>. <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> D<EFBFBD>t<EFBFBD>X<EFBFBD> <EFBFBD><EFBFBD><EFBFBD>ij t<EFBFBD>|<EFBFBD>\<EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
if( BUBBLE_HANDLER::GETTING_BUBBLE == pEventHandler->GetType() )
{
int iIconIndex = pBubbleTable->GetFieldFromLablePtr( iBubbleTableID, "_IconIndex" )->GetInteger();
static_cast<CDnGettingBubbleHandler*>(pEventHandler)->SetIconIndex( iIconIndex );
}
#endif // #ifdef _GAMESERVER
//// <EFBFBD><EFBFBD><EFBFBD>\<EFBFBD> x<EFBFBD>\<EFBFBD> <EFBFBD><EFBFBD><EFBFBD>Ш<EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD>D<EFBFBD> <EFBFBD>p<EFBFBD>`<EFBFBD> L<EFBFBD> 0<EFBFBD>\<EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD>¤<EFBFBD>\<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> t<EFBFBD><EFBFBD>\<EFBFBD><EFBFBD><EFBFBD>.
//if( BUBBLE_HANDLER::ADD_STATE_EFFECT == pEventHandler->GetType() )
//{
// // <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, t<EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>Ш<EFBFBD><EFBFBD><EFBFBD>ij <EFBFBD>p<EFBFBD>X<EFBFBD>ij]<EFBFBD> p<EFBFBD>t<EFBFBD> <EFBFBD>Ѕ<EFBFBD> <EFBFBD> <EFBFBD><EFBFBD><EFBFBD> x<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>.
// IDnBubbleEventHandler* pRemoveEventHandler = IDnBubbleEventHandler::Create( BUBBLE_HANDLER::REMOVE_STATE_EFFECT, m_hActor, pArgument );
// m_mapBubbleRemoveEventHandlers[ static_cast<CDnAddStateEffectHandler*>(pEventHandler)->GetBubbleTypeID() ] = pRemoveEventHandler;
//}
}
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> T<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȕ<EFBFBD> <EFBFBD><EFBFBD>@<EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD>D<EFBFBD> <EFBFBD>t<EFBFBD> <EFBFBD><EFBFBD><EFBFBD>|<EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɴ<EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
// EVENT_BUBBLE_ON_USE_SKILL T<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> $<EFBFBD>t<EFBFBD> ON_USE_SKILL p<EFBFBD>t<EFBFBD><<EFBFBD>\<EFBFBD> <EFBFBD>,<EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD>X<EFBFBD> <EFBFBD><EFBFBD><EFBFBD>\<EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD>\<EFBFBD><EFBFBD><EFBFBD>.
// 0<EFBFBD>|<EFBFBD><EFBFBD> <EFBFBD><EFBFBD>0<EFBFBD><EFBFBD><EFBFBD> Ȭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> J<EFBFBD>@<EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>t<EFBFBD> <EFBFBD>ܴ<EFBFBD><EFBFBD> X՘<EFBFBD>)<EFBFBD>@<EFBFBD> <EFBFBD>Ǵ<EFBFBD>|<EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD>̬<EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> t<EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD>@<EFBFBD> <EFBFBD><EFBFBD>h<EFBFBD> <EFBFBD>ij <EFBFBD><EFBFBD><EFBFBD><EFBFBD>..
int CDnBubbleSystem::_GetRelatedEventMessageType( int iConditionType )
{
int iResultMessageType = NONE_BUBBLE_EVENT_MESSAGE;
switch( iConditionType )
{
case ON_USE_SKILL:
{
iResultMessageType = EVENT_BUBBLE_ON_USE_SKILL;
}
break;
case BLOCK_SUCCESS:
{
iResultMessageType = EVENT_BUBBLE_BLOCK_SUCCESS;
}
break;
case BUBBLE_COUNT_UPDATED:
{
iResultMessageType = EVENT_BUBBLE_COUNT_UPDATED;
}
break;
case PARRING_SUCCESS:
{
iResultMessageType = EVENT_BUBBLE_PARRING_SUCCESS;
}
break;
case COOLTIME_PARRING_SUCCESS:
{
iResultMessageType = EVENT_BUBBLE_COOLTIME_PARRING_SUCCESS;
}
break;
case DO_NORMAL_ATTACK:
{
iResultMessageType = EVENT_ONCHANGEACTION;
}
break;
case PLAYER_KILL_TARGET_ON_GHOUL_MODE:
{
iResultMessageType = EVENT_PLAYER_KILL_TARGET;
}
break;
case ON_USE_SKILL_WITH_SPECIFIC_SKILLLEVEL:
{
iResultMessageType = EVENT_BUBBLE_ON_USE_SKILL;
}
case ONCRITICALHIT:
{
iResultMessageType = EVENT_ONCRITICALHIT;
}
break;
}
return iResultMessageType;
}
void CDnBubbleSystem::Clear( void )
{
RemoveAllBubbles();
}
void CDnBubbleSystem::SetDurationTime( int iBubbleTypeID, float fDurationTime )
{
// <EFBFBD><EFBFBD>8<EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>X<EFBFBD> <EFBFBD>ɍ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>D<EFBFBD> <EFBFBD><EFBFBD>\<EFBFBD> <EFBFBD>Ŕ<EFBFBD> <EFBFBD><EFBFBD><EFBFBD>X<EFBFBD> <EFBFBD>ɍ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><<EFBFBD>\<EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD>h<EFBFBD>.
deque<CDnBubble*>& dqBubbles = m_mapBubblesByTypeID[ iBubbleTypeID ];
for( int i = 0; i < (int)dqBubbles.size(); ++i )
{
CDnBubble* pBubble = dqBubbles.at( i );
pBubble->SetDurationTime( fDurationTime );
}
}
void CDnBubbleSystem::_CreateBubble( const S_CREATE_BUBBLE& Info )
{
CDnBubble* pNewBubble = _CreateNewBubble( Info );
_OnCreatedBubble( pNewBubble );
}
CDnBubble* CDnBubbleSystem::_CreateNewBubble( const S_CREATE_BUBBLE &Info )
{
CDnBubble* pNewBubble = new CDnBubble;
pNewBubble->SetTypeID( Info.iBubbleTypeID );
pNewBubble->SetIconIndex( Info.iIconIndex );
m_mapBubblesByTypeID[ Info.iBubbleTypeID ].push_front( pNewBubble );
SetDurationTime( Info.iBubbleTypeID, Info.fDurationTime );
return pNewBubble;
}
void CDnBubbleSystem::_OnCreatedBubble( CDnBubble* pCreatedBubble )
{
// <EFBFBD><EFBFBD><EFBFBD> /<EFBFBD><EFBFBD> 1<EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD>̬<EFBFBD>.
if( pCreatedBubble )
{
boost::shared_ptr<IDnObserverNotifyEvent> pEvent( IDnObserverNotifyEvent::Create( EVENT_BUBBLE_COUNT_UPDATED ) );
pEvent->SetBubbleTypeID( pCreatedBubble->GetTypeID() );
OnEvent( pEvent );
}
}
//void CDnBubbleSystem::_OnRemoveBubble( CDnBubble* pBubbleToRemove )
//{
// // TODO: L<EFBFBD>t<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD>X<EFBFBD><EFBFBD><EFBFBD>\<EFBFBD> X՘<EFBFBD>X<EFBFBD> <EFBFBD><EFBFBD><EFBFBD>t<EFBFBD> <EFBFBD>p<EFBFBD> <EFBFBD> L<EFBFBD> <EFBFBD><EFBFBD><EFBFBD>Ш<EFBFBD><EFBFBD><EFBFBD>|<EFBFBD> <EFBFBD>ɰ<EFBFBD>p<EFBFBD><EFBFBD><EFBFBD> h<EFBFBD>..
// // <EFBFBD><EFBFBD><EFBFBD>\<EFBFBD> <EFBFBD><EFBFBD><EFBFBD>Ш<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD>ȴ<EFBFBD><EFBFBD>ɔ<EFBFBD> p<EFBFBD>|<EFBFBD>t<EFBFBD> <EFBFBD><EFBFBD>@<EFBFBD> /<EFBFBD><EFBFBD> 0<EFBFBD><EFBFBD><<EFBFBD>\<EFBFBD> 0<EFBFBD>t<EFBFBD> /<EFBFBD><EFBFBD> 0<EFBFBD><EFBFBD>X<EFBFBD> <EFBFBD><EFBFBD><EFBFBD>Ш<EFBFBD><EFBFBD><EFBFBD> <EFBFBD>ɰ<EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>Ш<EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD>\<EFBFBD> <EFBFBD><EFBFBD><EFBFBD>t<EFBFBD>|<EFBFBD> h<EFBFBD>.
//
//}
void CDnBubbleSystem::_OnRemovedBubbles( int iBubbleTypeID, int iCount )
{
//map<int, IDnBubbleEventHandler*>::iterator iter = m_mapBubbleRemoveEventHandlers.find( iBubbleTypeID );
//if( m_mapBubbleRemoveEventHandlers.end() != iter )
//{
// iter->second->ProcessEvent( this, NULL );
//}
// <EFBFBD><EFBFBD><EFBFBD> /<EFBFBD><EFBFBD> 1<EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD>̬<EFBFBD>.
boost::shared_ptr<IDnObserverNotifyEvent> pEvent( IDnObserverNotifyEvent::Create( EVENT_BUBBLE_COUNT_UPDATED ) );
pEvent->SetBubbleTypeID( iBubbleTypeID );
OnEvent( pEvent );
}
int CDnBubbleSystem::GetBubbleCountByTypeID( int iBubbleTypeID )
{
int iResult = 0;
BubblesByTypeID_iter iter= m_mapBubblesByTypeID.find( iBubbleTypeID );
if( m_mapBubblesByTypeID.end() != iter )
{
iResult = (int)iter->second.size();
}
return iResult;
}
void CDnBubbleSystem::GetAllAppliedBubbles( /*OUT*/ vector<S_BUBBLE_INFO>& vlBubbleInfos )
{
BubblesByTypeID_iter iter = m_mapBubblesByTypeID.begin();
for( iter; iter != m_mapBubblesByTypeID.end(); ++iter )
{
// <EFBFBD><EFBFBD> <EFBFBD>@<EFBFBD> <EFBFBD> <EFBFBD><EFBFBD><EFBFBD>ļ\<EFBFBD> <EFBFBD>ɍ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>t<EFBFBD> <EFBFBD><EFBFBD>@<EFBFBD> <EFBFBD><EFBFBD>@<EFBFBD> 4<EFBFBD><EFBFBD><EFBFBD>X<EFBFBD><EFBFBD><EFBFBD> <<EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><<EFBFBD>\<EFBFBD> <EFBFBD><EFBFBD><EFBFBD>\<EFBFBD><EFBFBD><EFBFBD>.
CDnBubble* pBubble = iter->second.front();
S_BUBBLE_INFO Info;
Info.iBubbleTypeID = pBubble->GetTypeID();
Info.iCount = (int)iter->second.size();
Info.iIconIndex = pBubble->GetIconIndex();
Info.fDurationTime = pBubble->GetDurationTime();
Info.fRemainTime = pBubble->GetRemainTime();
vlBubbleInfos.push_back( Info );
#ifdef _CLIENT
//GetInterface().SetBubble(Info.iCount,Info.fRemainTime,Info.fDurationTime);
#endif
}
}
void CDnBubbleSystem::AddBubble( const S_CREATE_BUBBLE& Info )
{
_CreateBubble( Info );
}
void CDnBubbleSystem::AddBubbleAndCountRevision( const S_CREATE_BUBBLE& Info )
{
_CreateBubble( Info );
RevisionBubbleCount( Info );
}
void CDnBubbleSystem::RevisionBubbleCount( const S_CREATE_BUBBLE& Info )
{
// <EFBFBD><EFBFBD><EFBFBD>X<EFBFBD> /<EFBFBD><EFBFBD>\<EFBFBD> <EFBFBD><EFBFBD><EFBFBD> /<EFBFBD><EFBFBD>|<EFBFBD> ޹<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
std::deque<CDnBubble*>& dqBubbles = m_mapBubblesByTypeID[ Info.iBubbleTypeID ];
int iClientBubbleCount = (int)dqBubbles.size();
if( iClientBubbleCount < Info.iServerBubbleCount )
{
int iAddCount = Info.iServerBubbleCount - iClientBubbleCount;
for( int i = 0; i < iAddCount; ++i )
_CreateNewBubble( Info );
}
else
if( iClientBubbleCount > Info.iServerBubbleCount )
{
int iRemoveCount = iClientBubbleCount - Info.iServerBubbleCount;
RemoveBubbleByTypeID( Info.iBubbleTypeID, iRemoveCount );
}
}
void CDnBubbleSystem::RemoveBubbleByTypeID( int iBubbleTypeID, int iRemoveCount )
{
BubblesByTypeID_iter iter= m_mapBubblesByTypeID.find( iBubbleTypeID );
if( m_mapBubblesByTypeID.end() != iter )
{
// <EFBFBD><EFBFBD> <EFBFBD>@<EFBFBD> <EFBFBD> <EFBFBD><EFBFBD><EFBFBD>ļ\<EFBFBD> <EFBFBD>ɍ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>t<EFBFBD> <EFBFBD><EFBFBD>@<EFBFBD> <EFBFBD><EFBFBD>@<EFBFBD> 4<EFBFBD><EFBFBD><EFBFBD>X<EFBFBD><EFBFBD><EFBFBD> <<EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><<EFBFBD>\<EFBFBD> <EFBFBD><EFBFBD><EFBFBD>\<EFBFBD><EFBFBD><EFBFBD>.
std::deque<CDnBubble*>& dqpBubbles = iter->second;
for( int i = 0; i < iRemoveCount; ++i )
{
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD>X<EFBFBD>t<EFBFBD> <EFBFBD><EFBFBD><EFBFBD>.
//_OnRemoveBubble( &dqpBubbles.back() );
dqpBubbles.pop_back();
}
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD>Ѕ<EFBFBD>X<EFBFBD> <EFBFBD><EFBFBD><EFBFBD>t<EFBFBD> <EFBFBD><EFBFBD>P<EFBFBD> <EFBFBD>Ŵ<EFBFBD><EFBFBD><EFBFBD>t<EFBFBD> <EFBFBD><EFBFBD>L<EFBFBD>t<EFBFBD><EFBFBD> <EFBFBD>p<EFBFBD>.
if( dqpBubbles.empty() )
m_mapBubblesByTypeID.erase( iter );
_OnRemovedBubbles( iBubbleTypeID, iRemoveCount );
}
}
void CDnBubbleSystem::RemoveAllBubbleByTypeID( int iBubbleTypeID )
{
BubblesByTypeID_iter iter= m_mapBubblesByTypeID.find( iBubbleTypeID );
if( m_mapBubblesByTypeID.end() != iter )
{
int iRemovedBubbleCount = (int)iter->second.size();
SAFE_DELETE_PVEC( iter->second );
m_mapBubblesByTypeID.erase( iter );
_OnRemovedBubbles( iBubbleTypeID, iRemovedBubbleCount );
}
}
void CDnBubbleSystem::RemoveAllBubbles( bool bHandleRemoveEvent /*= true*/ )
{
//SAFE_DELETE_PVEC( m_vlpBubbles );
BubblesByTypeID_iter iter = m_mapBubblesByTypeID.begin();
for( iter; iter != m_mapBubblesByTypeID.end(); ++iter )
{
int iBubbleTypeID = iter->first;
int iRemovedBubbleCount = (int)iter->second.size();
SAFE_DELETE_PVEC( iter->second );
// <EFBFBD><EFBFBD>x<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 8֜<EFBFBD><EFBFBD><EFBFBD><EFBFBD>t<EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD>x<EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD>̬<EFBFBD>|<EFBFBD> X<EFBFBD><EFBFBD><EFBFBD> J<EFBFBD>ij]<EFBFBD> \<EFBFBD><EFBFBD><EFBFBD>.
if( bHandleRemoveEvent )
_OnRemovedBubbles( iter->first, iRemovedBubbleCount );
}
//m_vlpBubbles.clear();
m_mapBubblesByTypeID.clear();
}
CDnBubble* CDnBubbleSystem::GetBubble( int iBubbleTypeID )
{
CDnBubble* pResult = NULL;
BubblesByTypeID_iter iter= m_mapBubblesByTypeID.find( iBubbleTypeID );
if( m_mapBubblesByTypeID.end() != iter )
{
std::deque<CDnBubble*>& dqBubbles = iter->second;
if( dqBubbles.empty() )
{
pResult = dqBubbles.front();
}
}
return pResult;
}
void CDnBubbleSystem::Process( LOCAL_TIME LocalTime, float fDelta )
{
BubblesByTypeID_iter iter = m_mapBubblesByTypeID.begin();
for( iter; iter != m_mapBubblesByTypeID.end(); )
{
std::deque<CDnBubble*>& dqpBubbles = iter->second;
int iNumBubbles = (int)dqpBubbles.size();
std::deque<CDnBubble*>::iterator iterDeque = dqpBubbles.begin();
for( iterDeque; iterDeque != iter->second.end(); )
{
CDnBubble* pBubble = *iterDeque;
pBubble->Process( LocalTime, fDelta );
if( pBubble->IsEnd() )
{
iterDeque = dqpBubbles.erase( iterDeque );
continue;
}
++iterDeque;
}
int iNumRemoved = iNumBubbles - (int)dqpBubbles.size();
if( 0 < iNumRemoved )
_OnRemovedBubbles( iter->first, iNumRemoved );
if( dqpBubbles.empty() )
iter = m_mapBubblesByTypeID.erase( iter );
else
++iter;
}
}
void CDnBubbleSystem::OnEvent( boost::shared_ptr<::IDnObserverNotifyEvent>& pEvent )
{
IDnObserverNotifyEvent* pEventObject = pEvent.get();
if( pEvent == NULL )
return;
std::pair<DefinedByEventMMap_iter, DefinedByEventMMap_iter> iter_pair = m_mmapDefinedByEvent.equal_range( pEvent->GetEventType() );
DefinedByEventMMap_iter iter = iter_pair.first;
for( iter; iter != iter_pair.second; ++iter )
{
S_DEFINED_BUBBLE_EVENT* pDefinedEventInfo = iter->second;
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> p<EFBFBD>t<EFBFBD>t<EFBFBD> <EFBFBD><EFBFBD>q<EFBFBD><EFBFBD><EFBFBD>.
bool bResult = true;
int iNumConditions = (int)pDefinedEventInfo->vlpConditions.size();
for( int iCondition = 0; iCondition < iNumConditions; ++iCondition )
{
IDnConditionChecker* pCondition = pDefinedEventInfo->vlpConditions.at( iCondition );
bResult = pCondition->IsSatisfy( this, pEventObject );
if( false == bResult )
break;
}
// p<EFBFBD>t<EFBFBD>t<EFBFBD> X՘<EFBFBD>|<EFBFBD>ij <EFBFBD><EFBFBD>q<EFBFBD><EFBFBD><EFBFBD><EFBFBD> J<EFBFBD><<EFBFBD>t<EFBFBD> t<EFBFBD> <EFBFBD>X<EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>D<EFBFBD> 4<EFBFBD><EFBFBD>\<EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD>..
if( false == bResult )
continue;
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> p<EFBFBD>t<EFBFBD>t<EFBFBD> <EFBFBD><EFBFBD>q<EFBFBD>(<EFBFBD>. p<EFBFBD>t<EFBFBD>0<EFBFBD><EFBFBD><EFBFBD> <EFBFBD>X<EFBFBD><EFBFBD><EFBFBD>\<EFBFBD> <EFBFBD>‰<EFBFBD>..
int iNumEventHandler = (int)pDefinedEventInfo->vlpEventHandlers.size();
for( int iEventHandler = 0; iEventHandler < iNumEventHandler; ++iEventHandler )
{
IDnBubbleEventHandler* pEventHandler = pDefinedEventInfo->vlpEventHandlers.at( iEventHandler );
pEventHandler->ProcessEvent( this, pEventObject );
}
}
}
#ifdef _GAMESERVER
void CDnBubbleSystem::AddBubbleStateBlow( int iBubbleTypeID, int iBlowID )
{
m_mapBubbleStateBlowsByBubbleType[ iBubbleTypeID ].push_back( iBlowID );
}
void CDnBubbleSystem::RemoveBubbleStateBlow( int iBubbleTypeID )
{
map<int, vector<int> >::iterator iter = m_mapBubbleStateBlowsByBubbleType.find( iBubbleTypeID );
if( m_mapBubbleStateBlowsByBubbleType.end() != iter )
{
vector<int>& vlBlowIDs = iter->second;
for( int i = 0; i < (int)vlBlowIDs.size(); ++i )
{
int iBlowID = vlBlowIDs.at( i );
m_hActor->CmdRemoveStateEffectFromID( iBlowID ); // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> \<EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> <EFBFBD>P<EFBFBD>p<EFBFBD> U<EFBFBD>x<EFBFBD> t<EFBFBD><EFBFBD>|<EFBFBD> h<EFBFBD>.
}
iter->second.clear();
}
}
#else
void CDnBubbleSystem::CreateBubbleFromPacketStream( ::CPacketCompressStream* pStream )
{
if( NULL == pStream )
return;
S_CREATE_BUBBLE Info;
pStream->Read( &Info.iBubbleTypeID, sizeof(int) );
pStream->Read( &Info.iIconIndex, sizeof(int) );
pStream->Read( &Info.fDurationTime, sizeof(float) );
pStream->Read( &Info.iServerBubbleCount, sizeof(int) );
this->AddBubbleAndCountRevision( Info );
}
void CDnBubbleSystem::RefreshBubbleDurationTimeFromPacketStream( ::CPacketCompressStream* pStream )
{
if( NULL == pStream )
return;
S_CREATE_BUBBLE Info;
pStream->Read( &Info.iBubbleTypeID, sizeof(int) );
pStream->Read( &Info.iIconIndex, sizeof(int) );
pStream->Read( &Info.fDurationTime, sizeof(float) );
pStream->Read( &Info.iServerBubbleCount, sizeof(int) );
SetDurationTime( Info.iBubbleTypeID, Info.fDurationTime );
RevisionBubbleCount( Info );
}
#endif // #ifdef _GAMESERVER
} // namespace BubbleSystem