Files
mir_server/server/LogicServer/entitysystem/ObserverSystem.cpp
aixianling 5c9f1dae4a init
2025-01-09 17:45:40 +08:00

1643 lines
51 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "StdAfx.h"
#include "ObserverSystem.h"
//内存池
EntityVector* CObserverSystem::s_seqVisibleList = NULL;
CVector<EntityHandleTag>* CObserverSystem::s_OBEntityList;
SequenceEntityList CObserverSystem::s_orderVisibleSet;
//广播接口
void CObserverSystem::BroadCast(char * pBuff, SIZE_T nSize, bool bToSelf, bool bToNewAppearEntity/*= true*/)
{
if(m_pEntity == NULL)
{
return;
}
CEntityManager* em = GetGlobalLogicEngine()->GetEntityMgr();
INT_PTR nSelfType = m_pEntity->GetHandle().GetType() ; //自己的类型
if (!((CActor*)m_pEntity)->CanNetworkCutDown())
{ //老的广播消息
EntityHandle handle = m_pEntity->GetHandle();
for (INT_PTR i = 0; i < m_sEntityList.count(); i++)
{
EntityHandle handle = m_sEntityList[i].m_handle;
if (handle.GetType() != enActor)
{
continue;
}
if(bToNewAppearEntity || (!bToNewAppearEntity && m_sEntityList[i].m_tag == eENTITY_APPEAR_UNCHANGE))
{
CActor * pActor =(CActor *) em->GetEntity(handle);
if(pActor)
{
pActor->SendData(pBuff,nSize);
}
}
}
if(bToSelf && nSelfType == enActor)
{
((CActor *)m_pEntity)->SendData(pBuff,nSize);
}
}
else
{
if(nSelfType != enActor)
{
return;
}
if(bToSelf)
{
((CActor *)m_pEntity)->SendData(pBuff, nSize);
}
//特殊场景的广播消息
{
//扩大范围检索
DECLARE_TIME_PROF("get list");
CFuBenManager* fm = GetGlobalLogicEngine()->GetFuBenMgr();
fm->GetSeqVisibleList(m_pEntity, s_orderVisibleSet, -BIG_MOVE_GRID_COL_RADIO,
BIG_MOVE_GRID_COL_RADIO, -BIG_MOVE_GRID_COL_RADIO, BIG_MOVE_GRID_COL_RADIO);
}
SequenceEntityListIter itcheck = s_orderVisibleSet.begin();
for(; itcheck != s_orderVisibleSet.end(); itcheck++)
{
EntityHandle newHandle = *itcheck;
if (newHandle.GetType() != enActor)//不是玩家
{
continue;
}
CEntity *pEntity = em->GetEntity(newHandle);
if (!pEntity)
{
OutputMsg(rmError, _T("视野里出现的实体的指针为空3977938, type = %d"), newHandle.GetType());
continue;
}
EntityHandle myHandle = m_pEntity->GetHandle();
//if(bToNewAppearEntity || (!bToNewAppearEntity && m_sEntityList[i].m_tag == eENTITY_APPEAR_UNCHANGE))
if (((CActor *)pEntity)->OnCheckCanSeeEntity(myHandle))
{
((CActor *)pEntity)->SendData(pBuff, nSize);
}
}
}
}
void CObserverSystem::Clear()
{
CEntityManager* em = GetGlobalLogicEngine()->GetEntityMgr();
EntityHandle handle = m_pEntity->GetHandle();
if (enActor == handle.GetType())
{
for (INT_PTR i = 0; i < m_sEntityList.count(); i++)
{
if (m_sEntityList[i].m_handle != handle)
{
CEntity *pEntity = em->GetEntity(m_sEntityList[i].m_handle);
if(pEntity)
{
EntityDisappear(m_sEntityList[i].m_handle);
}
}
}
}
m_sEntityList.clear();
}
void CObserverSystem::ClearEntityList()
{
m_sEntityList.clear();
}
void CObserverSystem::BroadCastEntityMsg(const CEntityMsg &msg, bool boToSelf)
{
if(m_pEntity == NULL )return;
CEntityManager* em = GetGlobalLogicEngine()->GetEntityMgr();
////遍历可视范围的玩家
for (INT_PTR i = 0; i < m_sEntityList.count(); i++)
{
CEntity *pEntity = em->GetEntity(m_sEntityList[i].m_handle);
if(pEntity)
{
pEntity->PostEntityMsg(msg);
}
}
if (boToSelf) m_pEntity->PostEntityMsg(msg);
}
void CObserverSystem::OnEvent(INT_PTR nEventID,INT_PTR nParam1,INT_PTR nParam2,void * pData)
{
INT_PTR nSelfType = m_pEntity->GetHandle().GetType() ; //自己的类型
if( nSelfType != enActor && nSelfType != enPet) return;
}
// TODO 这里要优化性能
void CObserverSystem::onActorAppear(CActor* pActor)
{
EntityHandleTag entityTag;
entityTag.m_handle = pActor->GetHandle();
entityTag.m_tag = eENTITY_APPEAR_UNCHANGE;
EntityHandle handle = pActor->GetHandle();
for (INT_PTR i = 0; i < m_sEntityList.count(); i++)
{
if (m_sEntityList[i].m_handle == handle)
{
return;
}
}
m_sEntityList.push(entityTag);
}
void CObserverSystem::onActorDisappear(CActor* pActor)
{
//INT_PTR nType = m_pEntity->GetType();
// 在原来的列表中找此实体
EntityHandle handle = pActor->GetHandle();
std::vector<EntityHandleTagEx> tmpEntityList; // 周围实体列表(采取数组的方式存储)
for (INT_PTR i = 0; i < m_sEntityList.count(); i++)
{
EntityHandleTagEx tmp;
tmp.m_tag = m_sEntityList[i].m_tag;
tmp.m_handle = m_sEntityList[i].m_handle;
tmp.type = eENTITY_SPC_NULL;
tmpEntityList.push_back(tmp);
if (m_sEntityList[i].m_handle == handle)
{
m_sEntityList.remove(i);
return;
}
}
TRACE( _T("can't find actor(%I64x) entity in visible list!"), Uint64(handle));
}
int StrengthCompareFn(const void* lhs, const void* rhs)
{
__int64 nLVal = *((__int64 *)lhs);
__int64 nRVal = *((__int64 *)rhs);
if (nLVal < nRVal)
return -1;
else if (nLVal == nRVal)
return 0;
return 1;
}
//定时调用
VOID CObserverSystem::OnTimeCheck(TICKCOUNT nTick)
{
DECLARE_TIME_PROF("CObserverSystem::OnTimeCheck");
if(m_pEntity == NULL )
{
return;
}
EntityHandle hSelfHandle = m_pEntity->GetHandle();
int nSelfType = hSelfHandle.GetType();
bool bIsActor = (enActor == nSelfType) ? true : false;
INT_PTR nOldUserCount = 0; // 本次更新中没有发生变化的实体数量
// 对于NPC和采集怪都不用处理
if (enNpc == nSelfType)
{
return;
}
else
{
if (enActor == nSelfType && ((CActor*)m_pEntity)->CanNetworkCutDown())
{
NetworkCutDown(nTick);
return;
}
}
CEntityManager* em = GetGlobalLogicEngine()->GetEntityMgr();
bool bActorInNearby = true;
if (enActor != nSelfType) // // 对于怪物,直接保存周围玩家列表
{
// 此方式为定时去更新实体列表。 当前采取玩家更新观察者的时候去主动更新其他实体的观察者列表
nOldUserCount = m_sEntityList.count();
}
else
{
{
DECLARE_TIME_PROF("get list");
CFuBenManager* fm = GetGlobalLogicEngine()->GetFuBenMgr();
fm->GetSeqVisibleList(m_pEntity, s_orderVisibleSet, -MOVE_GRID_ROW_RADIO,
MOVE_GRID_ROW_RADIO, -MIN_MOVE_GRID_COL_RADIO, MIN_MOVE_GRID_COL_RADIO);
}
INT_PTR nNewEntityCount = s_orderVisibleSet.size();
{
DECLARE_TIME_PROF("other handle size");
EntityHandleTag entityTag;
entityTag.m_handle = EntityHandle();
entityTag.m_tag = eENTITY_APPEAR_NEW;
s_OBEntityList->clear();
INT_PTR nOldEntityCount = m_sEntityList.count(); // 上次周围实体数量
INT_PTR i = 0;
SequenceEntityListIter iter = s_orderVisibleSet.begin();
SequenceEntityListIter iterEnd = s_orderVisibleSet.end();
#ifndef _DEBUG
// const char * name = m_pEntity->GetEntityName();
// OutputMsg(rmTip,_T("\n【%s】位置检查, 上一次%d人, 新检测%d人!!"), name,
// nOldEntityCount,
// nNewEntityCount
// );
// for (size_t i = 0; i < m_sEntityList.count(); i++)
// {
// CEntity *pEntity = em->GetEntity(m_sEntityList[i].m_handle);
// const char * tname = pEntity ? pEntity->GetEntityName() : "no actor";
// OutputMsg(rmTip, _T("上一次: %s"), tname);
// }
// for (; iter != iterEnd; iter++)
// {
// CEntity *pEntity = em->GetEntity(*iter);
// const char * tname = pEntity ? pEntity->GetEntityName() : "no actor";
// OutputMsg(rmTip, _T("新检测: %s"), tname);
// }
#endif
// 比较
iter = s_orderVisibleSet.begin();
while (i < nOldEntityCount && iter != iterEnd)
{
EntityHandle newHandle = *iter;
EntityHandleTag& tag = m_sEntityList[i];
CEntity *pEntity = em->GetEntity(newHandle);
#ifndef _DEBUG
// if (pEntity)
// {
// int nScenceId = pEntity->GetSceneID();//pEntity->m_entityPos.pScene->m_pSrcSceneData->nScenceId;
// }
// EntityHandle oldHandler = tag.m_handle;
#endif
if (tag.m_handle == newHandle)
{
bool canSee = pEntity ? m_pEntity->CanSee(pEntity) : false;
if (!pEntity)
{
OutputMsg(rmError, _T("视野里出现的实体的指针为空,type=%d"), newHandle.GetType());
CScene* pScene = m_pEntity->GetScene();
if (pScene)
pScene->ClearIncorrectHandle(m_pEntity);
}
if (canSee)
{
tag.m_tag = eENTITY_APPEAR_UNCHANGE;
s_OBEntityList->push(tag);
}
else
{
EntityDisappear(newHandle);
}
nOldUserCount++;
i++;
++iter;
}
else if (tag.m_handle < newHandle)
{
EntityDisappear(tag.m_handle);
i++;
}
else /*if (tag.m_handle > tmpHandle)*/
{
if (newHandle == hSelfHandle)
{
++iter;
continue;
}
bool bCanSee = pEntity ? m_pEntity->CanSee(pEntity) : false;
if (!pEntity)
{
OutputMsg(rmError, _T("视野里出现的实体的指针为空,type=%d"), newHandle.GetType());
CScene* pScene = m_pEntity->GetScene();
if (pScene)
pScene->ClearIncorrectHandle(m_pEntity);
}
if (bCanSee)
{
EntityAppear(newHandle, pEntity);
entityTag.m_handle = newHandle;
s_OBEntityList->push(entityTag);
}
++iter;
}
}
// 剩余未消失完的,全部消失
while (i < nOldEntityCount)
{
EntityDisappear(m_sEntityList[i].m_handle);
++i;
}
// 剩余未出现完的,全部出现
while (iter != iterEnd)
{
EntityHandle newHandle = *iter;
if (newHandle == hSelfHandle)
{
++iter;
continue;
}
CEntity *pEntity = em->GetEntity(newHandle);
bool canSee = pEntity ? m_pEntity->CanSee(pEntity) : false;
if (!pEntity)
{
OutputMsg(rmError, _T("视野里出现的实体的指针为空,type=%d"), newHandle.GetType());
CScene* pScene = m_pEntity->GetScene();
if (pScene)
pScene->ClearIncorrectHandle(m_pEntity);
}
if (canSee)
{
EntityAppear(newHandle, pEntity);
entityTag.m_handle = newHandle;
s_OBEntityList->push(entityTag);
}
++iter;
}
// 切换s_OBEntityList和m_sEntityList
{
m_sEntityList.clear();
m_sEntityList.addList(*s_OBEntityList);
}
}
}
//跨地图传送需要在npc出现后 才给客户端发送 传送结果
if(bIsActor)
{
((CActor*)m_pEntity)->GetQuestSystem()->SendQuestTelResult();
((CActor*)m_pEntity)->GetMoveSystem()->SendHandFlyShoesRelust();
}
if (enActor != nSelfType && !bActorInNearby)
return;
CheckEntitypPropery(nOldUserCount, m_sEntityList);
}
void CObserverSystem::NetworkCutDown(TICKCOUNT nTick)
{
int limit_count = ((CActor*)m_pEntity)->CanNetworkCutDownDisplayCount();//限制数量
bool limit_full = false;//是否人数已满
EntityHandle hSelfHandle = m_pEntity->GetHandle();
int nSelfType = hSelfHandle.GetType();
bool bIsActor = (enActor == nSelfType) ? true : false;
INT_PTR nOldUserCount = 0; // 本次更新中没有发生变化的实体数量
// 对于NPC和采集怪都不用处理
if (enNpc == nSelfType) return;
CEntityManager* em = GetGlobalLogicEngine()->GetEntityMgr();
bool bActorInNearby = true;
if (enActor != nSelfType) // // 对于怪物,直接保存周围玩家列表
{
// 此方式为定时去更新实体列表。 当前采取玩家更新观察者的时候去主动更新其他实体的观察者列表
nOldUserCount = m_sEntityList.count();
}
else
{
{
DECLARE_TIME_PROF("get list");
CFuBenManager* fm = GetGlobalLogicEngine()->GetFuBenMgr();
fm->GetSeqVisibleList(m_pEntity, s_orderVisibleSet, -MOVE_GRID_ROW_RADIO,
MOVE_GRID_ROW_RADIO, -MIN_MOVE_GRID_COL_RADIO, MIN_MOVE_GRID_COL_RADIO);
}
INT_PTR nNewEntityCount = s_orderVisibleSet.size();
{
DECLARE_TIME_PROF("other handle size");
EntityHandleTag entityTag;
entityTag.m_handle = EntityHandle();
entityTag.m_tag = eENTITY_APPEAR_NEW;
s_OBEntityList->clear();
INT_PTR nOldEntityCount = m_sEntityList.count(); // 上次周围实体数量
INT_PTR i = 0;
SequenceEntityListIter iter = s_orderVisibleSet.begin();
SequenceEntityListIter iterEnd = s_orderVisibleSet.end();
std::vector<EntityHandleTagEx> tmpEntityList; // 周围实体列表(采取数组的方式存储)
std::map<unsigned long long, unsigned long long> tmpMapList;
std::map<unsigned long long, unsigned long long> tmpAllMapList;
//OutputMsg(rmWaning, _T("%lld视野里出现的实体数量 %lld"), nTick, (unsigned long long)nOldEntityCount);
// CScene* pScene = m_pEntity->GetScene();
// if (pScene)
// {
// CFuBen * pFb= pScene->GetFuBen();
// if(pFb)
// {
// OutputMsg(rmWaning, _T("%lld特殊场景场景 %lld 副本 %lld"), nTick, (int)pScene->GetSceneId(), (int)pFb->GetFbId());
// }
// }
for(INT_PTR i = 0 ; i < nOldEntityCount; i++)
{
bool is_special = false;
EntityHandleTag& tag = m_sEntityList[i];
unsigned long long handle001 = (unsigned long long)tag.m_handle.GetHandle();
if (tmpAllMapList.insert(std::make_pair(handle001, handle001)).second)
{
//OutputMsg(rmWaning, _T("%lld++++++++++++++ 进入管理的对象000 %lld"), nTick, handle001);
}
else
{
OutputMsg(rmWaning, _T("%lld特殊场景重复id000 %lld"), nTick, handle001);
}
//OutputMsg(rmWaning, _T("%lld视野的实体009999 %lld"), nTick, (unsigned long long)tag.m_handle.GetHandle());
CEntity *pEntity = em->GetEntity(tag.m_handle);
bool canSee = pEntity ? m_pEntity->CanSee(pEntity) : false;
if (!pEntity)
{
OutputMsg(rmError, _T("%lld视野里出现的实体的指针为空1,type=%d"), nTick, tag.m_handle.GetType());
CScene* pScene = m_pEntity->GetScene();
if (pScene)
{
pScene->ClearIncorrectHandle(m_pEntity);
((CActor*)m_pEntity)->OnClearCanSeeEntity(tag.m_handle);
}
}
if (!canSee)
{
EntityDisappear(tag.m_handle);
((CActor*)m_pEntity)->OnClearCanSeeEntity(tag.m_handle);
//OutputMsg(rmError, _T("%lld视野里出现的实体准备消失001 %lld"), nTick, (unsigned long long)tag.m_handle.GetHandle());
//tmpEntityList.push_back(tag);
continue; //自然消失的
}
//特殊怪物ID
if ( pEntity && pEntity->GetType() == enMonster)// && pEntity->GetProperty<unsigned int>(PROP_ENTITY_ID) == 385)
{
is_special = true;
}
if(!is_special && limit_count <= s_OBEntityList->count())
//if(!is_special && limit_count <= s_OBEntityList->count())
{
limit_full = true;//人数满
//EntityDisappear(tag.m_handle);
EntityHandleTagEx tmp;
tmp.m_handle = tag.m_handle;
tmp.m_tag = tag.m_tag;
tmp.type = eENTITY_SPC_FULL_DEL;
tmpEntityList.push_back(tmp);
//OutputMsg(rmError, _T("%lld视野里出现的实体准备消失002 %lld"), nTick,(unsigned long long)tag.m_handle.GetHandle());
continue;
}
// if ( pEntity && pEntity->GetType() == enMonster)
// {
// OutputMsg(rmWaning, _T("%lld---------1655165--------场景中得怪物ID %lld "), nTick, (int)pEntity->GetProperty<unsigned int>(PROP_ENTITY_ID));
bool CanFind = false;
SequenceEntityListIter itNew = s_orderVisibleSet.begin();
for(; itNew != iterEnd; itNew++)
{
EntityHandle newHandle = *itNew;
if (tag.m_handle == newHandle)//老的新的对上了
{
tag.m_tag = eENTITY_APPEAR_UNCHANGE;
nOldUserCount++;
CanFind = true;
// EntityHandleTagEx tmp;
// tmp.m_tag = tag.m_tag;
// tmp.m_handle = tag.m_handle;
unsigned long long handle = (unsigned long long)tag.m_handle.GetHandle();
if (tmpMapList.insert(std::make_pair(handle, handle)).second)
{
//OutputMsg(rmWaning, _T("%lld进入管理的对象001 %lld"), nTick, handle);
s_OBEntityList->push(tag);
}
else
{
OutputMsg(rmError, _T("%lld重复id001 %lld"), nTick, handle);
}
//OutputMsg(rmTip, _T("%lld--------------视野里出现的加入新实体准备001 %lld"), nTick, (unsigned long long)tag.m_handle.GetHandle());
break;
}
}
if (!CanFind)
{
EntityHandleTagEx tmp;
tmp.m_tag = tag.m_tag;
tmp.m_handle = tag.m_handle;
tmp.type = eENTITY_SPC_OLD_DEL;
//EntityDisappear(tag.m_handle);
tmpEntityList.push_back(tmp);
//OutputMsg(rmError, _T("%lld视野里出现的实体准备消失003 %lld"), nTick, (unsigned long long)tag.m_handle.GetHandle());
}
}
for(INT_PTR i = 0 ; i < tmpEntityList.size(); i++)
{
EntityHandleTagEx& tag = tmpEntityList[i];
EntityDisappear(tag.m_handle);
((CActor*)m_pEntity)->OnClearCanSeeEntity(tag.m_handle);
}
nOldEntityCount = m_sEntityList.count();//实体变量已经变化
//OutputMsg(rmError, _T("%lld视野里出现的实体数量变化221 %d"), nTick, (int)tmpMapList.size());
//OutputMsg(rmError, _T("%lld视野里出现的实体数量变化222 %lld"), nTick, (unsigned long long)nOldEntityCount);
EntityHandle bEntBuffer[300];
EntityHandle bEntData[300];
memset(bEntBuffer, 0, sizeof(bEntBuffer));
memset(bEntData, 0, sizeof(bEntData));
SequenceEntityListIter itcheck = s_orderVisibleSet.begin();
int bNewCount = 0;
for(; itcheck != iterEnd; itcheck++)
{
if(bNewCount > 300)
{
break;
}
EntityHandle newHandle = *itcheck;
//unsigned long long handleTmp = (unsigned long long)newHandle.GetHandle();
bEntData[bNewCount] = newHandle;
bNewCount ++;
}
BYTE bRandCount = 0, bPosition = 0;
if(bNewCount > 0)
{
do
{
bPosition = rand() % (bNewCount - bRandCount);
bEntBuffer[bRandCount++] = bEntData[bPosition];
bEntData[bPosition] = bEntData[bNewCount - bRandCount];
} while (bRandCount < bNewCount);
}
//itcheck = s_orderVisibleSet.begin();
//for(; itcheck != iterEnd; itcheck++)
for(int k = 0; k < bRandCount; k++)
{
//EntityHandle newHandle = *itcheck;
EntityHandle& newHandle = bEntBuffer[k];
bool is_special = false;
if (newHandle == hSelfHandle)//自己的 不判断
{
//++itcheck;
continue;
}
unsigned long long handle001 = (unsigned long long)newHandle.GetHandle();
if(tmpAllMapList.find(handle001) != tmpAllMapList.end())
{
continue;//已经处理过了
}
// for(INT_PTR i = 0 ; i < nOldEntityCount; i++)
// {
// EntityHandleTag& tagtmp = m_sEntityList[i];
// if (tagtmp.m_handle == newHandle)//老的新的对上了
// {
// continue;//已经处理过了
// }
// }
for(INT_PTR i = 0 ; i < tmpEntityList.size(); i++)
{
EntityHandleTagEx& tagtmp = tmpEntityList[i];
if (tagtmp.m_handle == newHandle)
{
continue;//已经处理过了
}
}
CEntity *pEntity = em->GetEntity(newHandle);
if (!pEntity)
{
OutputMsg(rmError, _T("%lld视野里出现的实体的指针为空222, type = %d"), nTick, newHandle.GetType());
CScene* pScene = m_pEntity->GetScene();
if (pScene)
{
pScene->ClearIncorrectHandle(m_pEntity);
((CActor*)m_pEntity)->OnClearCanSeeEntity(newHandle);
}
//EntityDisappear(newHandle);
continue;
}
bool canSee = pEntity ? m_pEntity->CanSee(pEntity) : false;
if (!canSee)
{
//EntityDisappear(newHandle);
continue;
}
//特殊怪物ID
if ( pEntity && pEntity->GetType() == enMonster)// && pEntity->GetProperty<unsigned int>(PROP_ENTITY_ID) == 386)
{
is_special = true;
}
if(!is_special && limit_count <= s_OBEntityList->count())
{
limit_full = true;//人数满
//EntityDisappear(newHandle);
continue;
}
((CActor*)m_pEntity)->OnAddCanSeeEntity(newHandle);
EntityAppear(newHandle, pEntity);
entityTag.m_handle = newHandle;
// EntityHandleTagEx tmp;
// tmp.m_tag = entityTag.m_tag;
// tmp.m_handle = entityTag.m_handle;
unsigned long long handle = (unsigned long long)entityTag.m_handle.GetHandle();
if (tmpMapList.insert(std::make_pair(handle, handle)).second)
{
//OutputMsg(rmWaning, _T("%lld进入管理的对象222 %lld"), nTick, handle);
s_OBEntityList->push(entityTag);
}
else
{
OutputMsg(rmError, _T("%lld重复id222 %lld"), nTick, handle);
}
//OutputMsg(rmTip, _T("%lld--------------视野里出现的加入新实体准备222 %lld"), nTick, (unsigned long long)entityTag.m_handle.GetHandle());
}
// 切换s_OBEntityList和m_sEntityList
{
m_sEntityList.clear();
m_sEntityList.addList(*s_OBEntityList);
}
nOldEntityCount = m_sEntityList.count();//实体变量已经变化
}
}
//跨地图传送需要在npc出现后 才给客户端发送 传送结果
if(bIsActor)
{
((CActor*)m_pEntity)->GetQuestSystem()->SendQuestTelResult();
((CActor*)m_pEntity)->GetMoveSystem()->SendHandFlyShoesRelust();
}
if (enActor != nSelfType && !bActorInNearby)
return;
CheckEntitypPropery(nOldUserCount, m_sEntityList);
}
void CObserverSystem::UpdateActorEntityProp()
{
CheckEntitypPropery(m_sEntityList.count(), m_sEntityList);
}
//检测实体的属性的改变,如果改变了,需要通知视野里的玩家更新属性
void CObserverSystem::CheckEntitypPropery(INT_PTR nOldUserCount, CVector<EntityHandleTag> &vecVisiblePlayers)
{
if(m_pEntity == NULL) return ;
if(m_pEntity->IsInited() == false)
return;
int nActorType = m_pEntity->GetHandle().GetType();
if (nActorType == enActor)
{
if (((CActor*)m_pEntity)->OnGetIsTestSimulator()
|| ((CActor*)m_pEntity)->OnGetIsSimulator())
{
return;
}
}
CUpdateMask *pMask = (CUpdateMask *)m_pEntity->GetPropertyPtr() ; //本身就是一个更新集合
INT_PTR nUsedCount = pMask->GetUsedCount();
if(nUsedCount == 0) return; //没有更新
unsigned int nTeamId = 0;
CTeam *pTeam = NULL;
INT_PTR nTeamOnlinePlayerCnt = 0;
if (m_pEntity->GetHandle().GetType() == enActor)
{
// 计算属性数量
INT_PTR nSendCount = 0; //需要向客户端广播的属性的个数
INT_PTR nTotalCount = nUsedCount << 3; //*8
for (INT_PTR i=0;i < nTotalCount; i++)
{
if(pMask->GetUpdateMaskFlag(i))
nSendCount++;
}
// 打包属性
CActor *pActor = (CActor *) m_pEntity;
nTeamId = pActor->GetProperty<int>(PROP_ACTOR_TEAM_ID);
pTeam = GetGlobalLogicEngine()->GetTeamMgr().GetTeam(nTeamId);
if (pTeam)
{
nTeamOnlinePlayerCnt = pTeam->GetOnlineUserCount();
}
if (nSendCount > 0)
{
// 发给玩家自己
CActorPacket pack;
CDataPacket &packet = pActor->AllocPacket(pack);
packet <<BYTE(enDefaultEntitySystemID) <<(BYTE)(sMainactorPropertyChange) << (BYTE)nSendCount; //主角的属性发生改变
for(INT_PTR i=0;i < nTotalCount; i++)
{
if(pMask->GetUpdateMaskFlag(i))
{
packet << (unsigned char) (i);
/*
if(i==9 )
{
OutputMsg(rmWaning,_T("HP"));
}
if (i==133 || i == 134)
{
OutputMsg(rmWaning,_T("HPMMMMMMMMMMMMMMMM="));
}
*/
/*
高频调用方法,需要增加条件筛选掉不必要处理的逻辑。
否则可会导致导量时出现服务器负载过重的情况。
*/
const char * dataPtr = pActor->GetPropertyPtr()->GetValuePtr(i); //*2
packet.writeBuf(dataPtr,4); //
}
}
pack.flush();
}
}
CUpdateMask *pBroadCastMask= m_pEntity->GetBroadCastMask();
if(pBroadCastMask ==NULL) return;
*pMask &= *pBroadCastMask; //与运算
nUsedCount = pMask->GetUsedCount();
if (nUsedCount > 0)
SendPropChangeToOwner(); // 广播给归属者(如果归属者不在附近)
// 视野内部没有玩家并且没有在队伍中
if(nOldUserCount == 0 && nTeamOnlinePlayerCnt <= 0)
{
pMask->ClearUpdateMask(); //zac这句代码会导致一个bug在同屏瞬移中会暂时把玩家的可视列表清空如果这个时候属性改变则无法通知到同屏的玩家所以这里不需要清除updatemask
return; //视野里没有玩家就算属性改变了也不处理
}
char buff[1024];
CDataPacket data(buff,sizeof(buff));//把玩家的数据发过去
if(nUsedCount >0)
{
INT_PTR nTotalCount = nUsedCount << 3; //*8
INT_PTR nSendCount =0; //需要向客户端广播的属性的个数
for(INT_PTR i=0;i < nTotalCount; i++)
{
if(pMask->GetUpdateMaskFlag(i))
{
nSendCount ++;
}
}
if(nSendCount >0)
{
data <<BYTE(enDefaultEntitySystemID) << BYTE(sEntityPropertyChange) << Uint64(m_pEntity->GetHandle());
data << (BYTE) nSendCount;
for(INT_PTR i=0;i < nTotalCount; i++)
{
if(pMask->GetUpdateMaskFlag(i))
{
const char* dataPtr = m_pEntity->GetPropertyPtr()->GetValuePtr(i); //*2
data << (unsigned char ) i;
/*
if(i==7 && m_pEntity->GetType() ==enMonster )
{
unsigned int nHp = *(int*)dataPtr;
OutputMsg(rmWaning,_T("HP=%d"),nHp);
}
*/
data.writeBuf(dataPtr,4); //这里要改一下
}
}
// 广播给周围玩家
BroadCast(data.getMemoryPtr(), data.getPosition());
// 广播给队友
if (nTeamOnlinePlayerCnt > 1 && pTeam)
{
if (pMask->GetUpdateMaskFlag(PROP_CREATURE_HP))//只更新血量
{
pTeam->BroadcastUpdateMember((CActor*)m_pEntity, PROP_CREATURE_HP);
}
}
}
pMask->ClearUpdateMask();
}
}
bool CObserverSystem::IsOwnerActor()
{
bool bOwnerIsActor = false; // 是否归属者者是玩家
// 归属者对象指针
INT_PTR nType = m_pEntity->GetType() ;
if (nType== enMonster)
{
/*CEntity *pOwner = GetEntityFromHandle(((CMonster *)m_pEntity)->GetOwner());
if (pOwner && pOwner->GetType() == enActor)
{
bOwnerIsActor = true;
pOwnerActor = (CActor *)pOwner;
}*/
EntityHandle hOwner = ((CMonster *)m_pEntity)->GetOwner();
if (!hOwner.IsNull() && hOwner.GetType() == enActor)
bOwnerIsActor = true;
}
else if(nType ==enPet || nType == enHero)
{
return true;
}
return bOwnerIsActor;
}
void CObserverSystem::SendPropChangeToOwner()
{
if (!IsOwnerActor()) return;
CUpdateMask *pMask = (CUpdateMask *)m_pEntity->GetPropertyPtr();
CUpdateMask *pBroadCastMask = m_pEntity->GetBroadCastMask();
if (!pMask || !pBroadCastMask) return;
*pMask &= *pBroadCastMask;
UINT_PTR nUsedCount = pMask->GetUsedCount();
if (nUsedCount <= 0)
return;
INT_PTR nTotalCount = nUsedCount << 3;
INT_PTR nSendCount = 0;
for (INT_PTR i=0;i < nTotalCount; i++)
{
if(pMask->GetUpdateMaskFlag(i))
nSendCount ++;
}
if (nSendCount <= 0)
return;
CActor *pOwnerActor =NULL;
if(m_pEntity->IsMonster())
{
pOwnerActor= (CActor *)GetEntityFromHandle(((CMonster *)m_pEntity)->GetOwner());
}
else if (m_pEntity->GetType() == enHero)
{
pOwnerActor= ((CHero*)m_pEntity)->GetMaster();
}
if (!pOwnerActor ) return;
if(pOwnerActor->IsInited() ==false) return;
// 同步属性更新到归属者
char buff[1024];
CDataPacket data(buff, sizeof(buff));
data <<BYTE(enDefaultEntitySystemID) << BYTE(sBabyPropChange) << Uint64(m_pEntity->GetHandle());
data << (BYTE) nSendCount;
for (INT_PTR i = 0; i < nTotalCount; i++)
{
if(pMask->GetUpdateMaskFlag(i))
{
const char* dataPtr = m_pEntity->GetPropertyPtr()->GetValuePtr(i);
data << (unsigned char)i;
data.writeBuf(dataPtr, 4);
}
}
pOwnerActor->SendData(data.getMemoryPtr(), data.getPosition());
}
void CObserverSystem::SendPosChangeToOwner()
{
//客户端其他地方实现了,不使用
/*INT_PTR nType = m_pEntity->GetType() ;
bool bOwnerIsActor =false;
CActor *pOwnerActor =NULL;
if ( nType== enMonster)
{
EntityHandle hOwner = ((CMonster *)m_pEntity)->GetOwner();
if (!hOwner.IsNull() && hOwner.GetType() == enActor)
{
pOwnerActor = (CActor *)GetEntityFromHandle(hOwner);
}
}
else if(nType ==enPet )
{
pOwnerActor = ((CPet*)m_pEntity)->GetMaster();
}
else if(nType ==enHero)
{
pOwnerActor = ((CHero*)m_pEntity)->GetMaster();
}
else
{
return;
}
if (!pOwnerActor || !pOwnerActor->IsInited()) return;
char buff[1024];
CDataPacket data(buff, sizeof(buff));
data <<BYTE(enDefaultEntitySystemID) << BYTE(sBabyPosChange) << Uint64(m_pEntity->GetHandle());
int nPosX, nPosY, nSceneId = -1;
m_pEntity->GetPosition(nPosX, nPosY);
CScene *pScene = m_pEntity->GetScene();
if (pScene)
nSceneId = pScene->GetSceneId();
data << (unsigned short)nPosX << (unsigned short)nPosY << nSceneId;
pOwnerActor->SendData(data.getMemoryPtr(), data.getPosition()); */
}
void CObserverSystem::EntityAppearActor(const EntityHandle &handle, CActor* pOtherActor)
{
if(!m_pEntity || !pOtherActor)
{
return;
}
int nActorType = m_pEntity->GetHandle().GetType();
if (nActorType == enActor)
{
if (((CActor*)m_pEntity)->OnGetIsTestSimulator()
|| ((CActor*)m_pEntity)->OnGetIsSimulator())
{
return;
}
}
CActor *pSelf = (CActor *) m_pEntity;
CScene* pScene = pOtherActor->GetScene();
WORD nPosX = (WORD)pOtherActor->GetProperty<int>(PROP_ENTITY_POSX);
WORD nPosY = (WORD)pOtherActor->GetProperty<int>(PROP_ENTITY_POSY);
int nSex = pOtherActor->GetProperty<int>(PROP_ACTOR_SEX);
INT_PTR nType = handle.GetType();
CActorPacket pack;
CDataPacket &data = pSelf->AllocPacket(pack);
CActorProperty * pProperty = (CActorProperty *) pOtherActor->GetPropertyPtr(); //玩家的属性集
data <<BYTE(enDefaultEntitySystemID) <<(BYTE)sOtherActorAppear; //是别的玩家出现了
data <<(Uint64) handle ; //玩家句柄
bool isset = false;
if (pScene)
{
SCENEAREA* pArea = pScene->GetAreaAttri(nPosX, nPosY);
if (pScene->HasMapAttribute(nPosX, nPosY, aaChangeName, pArea) )
{
AreaAttri& attri = pArea->attri[aaChangeName];
if (nSex >= attri.nCount) nSex = attri.nCount - 1;
int nIdx = attri.pValues[nSex];
if (LPCTSTR pName = GetLogicServer()->GetDataProvider()->GetChangeName(nIdx-1))
{
data.writeString(pName);
isset = true;
}
}
}
if (!isset)
data.writeString(pOtherActor->GetShowName()); //玩家的名字写入
data <<nPosX; //x
data <<nPosY; //y
data <<(int)pOtherActor->GetProperty<int>(PROP_ENTITY_MODELID); //模型id
data << (unsigned)pOtherActor->GetProperty<unsigned>(PROP_CREATURE_HP); //当前的血
data << (unsigned)pOtherActor->GetProperty<unsigned>(PROP_CREATURE_MP); //当前的蓝
data << (unsigned)pOtherActor->GetProperty<unsigned>(PROP_CREATURE_MAXHP); //最大的血
data << (unsigned)pOtherActor->GetProperty<unsigned>(PROP_CREATURE_MAXMP); //最大的蓝
data << (WORD) pOtherActor->GetProperty<unsigned>(PROP_CREATURE_MOVEONESLOTTIME); //移动速度
data << (BYTE) nSex; //性别
data << (BYTE) pOtherActor->GetProperty<unsigned>(PROP_ACTOR_VOCATION); //职业
data << (WORD) pOtherActor->GetProperty<unsigned>(PROP_CREATURE_LEVEL); //等级
data << (unsigned int)pOtherActor->GetProperty<unsigned>(PROP_ACTOR_CIRCLE); //转数
int nWeapon = pOtherActor->GetProperty<int>(PROP_ACTOR_WEAPONAPPEARANCE); //武器外观
int nSwing = pOtherActor->GetProperty<int>(PROP_ACTOR_SWINGAPPEARANCE); //翅膀外观
if (pOtherActor->IsSceneChangeModel())
{
nSwing = 0;
}
data << (int)nWeapon; //武器外观
data << (int)nSwing; //翅膀外观
data << (int)pOtherActor->GetProperty<int>(PROP_ACTOR_SOCIALMASK); //玩家社会关系
data << (WORD)pOtherActor->GetProperty<int>(PROP_ENTITY_ICON); //头像ID
data << (WORD)pOtherActor->GetProperty<int>(PROP_CREATURE_ATTACK_SPEED);//攻击速度
data << (BYTE)pOtherActor->GetProperty<unsigned int>(PROP_ENTITY_DIR); //下发朝向
data << (unsigned int)pOtherActor->GetProperty<unsigned int>(PROP_CREATURE_STATE); //状态
data << (unsigned int)0;
data << (int)pOtherActor->GetProperty<int>(PROP_ACTOR_TEAM_ID); //队伍的ID
data << (BYTE) pOtherActor->GetProperty<unsigned int>(PROP_ACTOR_ZY); //阵营类型
data << (unsigned int)pOtherActor->GetProperty<unsigned int>(PROP_ACTOR_CURNEWTITLE);//头衔
data << (unsigned int)(GetNameColorLookedByOther(pOtherActor->GetHandle(), m_pEntity->GetHandle()));//名字颜色
data << (unsigned int)pOtherActor->GetProperty<unsigned int>(PROP_ACTOR_SUPPER_PLAY_LVL);//超玩俱乐部等级
data << (unsigned int)pOtherActor->GetProperty<unsigned int>(PROP_ACTOR_SOLDIERSOULAPPEARANCE); //兵魂外观
data << (WORD)pOtherActor->GetProperty<unsigned int>(PROP_ACTOR_WEAPON_ID); //正在装备的武器id
data << (unsigned int)pOtherActor->GetProperty<unsigned int>(PROP_ACTOR_GUILD_ID); //行会ID
data << (unsigned int)pOtherActor->GetProperty<unsigned int>(PROP_ACTOR_MONSTER_MODELID); //怪物模型id
data << (unsigned int)pOtherActor->GetProperty<unsigned int>(PROP_ACTOR_MERITORIOUSPOINT); //累计功勋
data << (unsigned int)pOtherActor->GetProperty<unsigned int>(PROP_ACTOR_NEXT_SKILL_FLAG); //战士下一次技能flag
data << (unsigned int)pOtherActor->GetProperty<unsigned int>(PROP_ACTOR_EVIL_PK_STATUS); //恶意PK状态
data << (unsigned int)pOtherActor->GetProperty<unsigned int>(PROP_ACTOR_PK_VALUE); //PK值
pOtherActor->GetBuffSystem()->AppendBuffData(data); //玩家的Buff数据
data << (unsigned int)pOtherActor->GetProperty<unsigned int>(PROP_ENTITY_ID); //玩家id
data << (unsigned int)pOtherActor->GetProperty<unsigned int>(PROP_ACTOR_AREA_ATTR); //区域属性存储位
data << (unsigned int)pOtherActor->GetProperty<unsigned int>(PROP_ACTOR_AREA_ATTR_0);
data << (unsigned int)pOtherActor->GetProperty<unsigned int>(PROP_ACTOR_NORMAL_ATK_ACC);
data << (unsigned int)pOtherActor->GetProperty<unsigned int>(PROP_ACTOR_FRENZY);
data << (unsigned int)pOtherActor->GetProperty<unsigned int>(PROP_ACTOR_OFFICE);
////宠物系统非 ai宠物
data << (int)pOtherActor->GetProperty<int>(PROP_ACTOR_LOOT_PET_ID);
data << (int)pOtherActor->GetProperty<int>(PROP_ACTOR_CURCUSTOMTITLE);
pack.flush();
}
void CObserverSystem::EntityAppearDropItem(const EntityHandle &handle, CEntity* pItem)
{
if(!m_pEntity|| !pItem)return;
CActor *pSelf = (CActor *) m_pEntity;
INT_PTR nType = handle.GetType();
CActorPacket pack;
CDataPacket &data =pSelf->AllocPacket(pack);
CDropItemEntity* pOtherItem = (CDropItemEntity*)pItem;
data <<BYTE(enLootSystemID) <<(BYTE)sDropItemAppear; //
data << (unsigned int) handle.GetIndex();
CUserItem * pUserItem = pOtherItem->GetItem();
int nLeftTime = 0;
unsigned int nMasterId = pOtherItem->GetMasterActorId();
if (!nMasterId || nMasterId != m_pEntity->GetId())
{
nLeftTime = pOtherItem->GetCanPickUpTime() - GetGlobalLogicEngine()->getTickCount();
}
unsigned int nTeamId = pOtherItem->GetTeamId();
unsigned int mytemid = pSelf->GetProperty<unsigned int >(PROP_ACTOR_TEAM_ID);
if (nTeamId && nTeamId == mytemid)
{
nLeftTime = 0;
// nLeftTime = pOtherItem->GetCanPickUpTime() - GetGlobalLogicEngine()->getTickCount();
}
if(nLeftTime < 0)
nLeftTime = 0;
if(pUserItem)
{
data <<(WORD)pUserItem->wItemId; //物品id
data <<(WORD)pOtherItem->GetProperty<int>(PROP_ENTITY_POSX); //坐标x
data <<(WORD)pOtherItem->GetProperty<unsigned int>(PROP_ENTITY_POSY); //坐标y
data << (unsigned int)(nLeftTime/1000); //剩余时间
data << (BYTE)(*(char*)pUserItem->cBestAttr); //是否极品
data << (WORD)1; //数量
}
else
{
if (pOtherItem->GetMoneyType() == mtYuanbao) data <<(WORD)65535; //代表元宝
else data <<(WORD)65534; //代表金币
data <<(WORD)pOtherItem->GetProperty<int>(PROP_ENTITY_POSX); //坐标x
data <<(WORD)pOtherItem->GetProperty<unsigned int>(PROP_ENTITY_POSY); //坐标y
data << (unsigned int)(nLeftTime/1000); //剩余时间
data << (BYTE)0; //是否极品
data << (WORD)pOtherItem->GetMoneyCount(); //数量
}
pack.flush();
}
void CObserverSystem::EntityAppearSpecialEntity(const EntityHandle &handle, CEntity* pSpecialEntity)
{
if(!m_pEntity|| !pSpecialEntity)return;
CActor *pSelf = (CActor *) m_pEntity;
INT_PTR nType = handle.GetType();
CActorPacket pack;
CDataPacket &data =pSelf->AllocPacket(pack);
data <<BYTE(enDefaultEntitySystemID) <<(BYTE)sSpecialEntityAppear;
data <<(Uint64) handle ;
data << (WORD)pSpecialEntity->GetProperty<int>(PROP_ENTITY_MODELID); //模型的ID
data <<(WORD)pSpecialEntity->GetProperty<int>(PROP_ENTITY_POSX); //坐标x
data <<(WORD)pSpecialEntity->GetProperty<unsigned int>(PROP_ENTITY_POSY); //坐标y
data.writeString(pSpecialEntity->GetEntityName());
pack.flush();
}
void CObserverSystem::EntityAppearMonster(const EntityHandle &handle, CEntity* pEntity)
{
if(!m_pEntity|| !pEntity)
{
return;
}
int nActorType = m_pEntity->GetHandle().GetType();
if (nActorType == enActor)
{
if (((CActor*)m_pEntity)->OnGetIsTestSimulator()
|| ((CActor*)m_pEntity)->OnGetIsSimulator())
{
return;
}
}
CActor *pSelf = (CActor *) m_pEntity;
INT_PTR nType = handle.GetType();
CActorPacket pack;
CDataPacket &data =pSelf->AllocPacket(pack);
data <<(BYTE)enDefaultEntitySystemID <<(BYTE)sMonsterAppear;
bool isMonster = pEntity->IsMonster();
data << (BYTE)nType; // 类型
data << (Uint64) handle; // 句柄
char sAllName[128];
const char *pMasterName = 0;
WORD nMonsterId = 0;
if (isMonster)
{
EntityHandle hMonster = ((CMonster *)pEntity)->GetOwner();
if (!hMonster.IsNull())
{
CEntity *pMaster = GetEntityFromHandle(hMonster);
if (pMaster && ! pEntity->GetAttriFlag().DenyShowMasterName)
pMasterName = pMaster->GetEntityName();
}
}
if(pEntity->GetAttriFlag().DenyShowName)
{
sprintf_s(sAllName, sizeof(sAllName), " \\");
}
else
{
sprintf_s(sAllName,sizeof(sAllName),"%s\\%s",pEntity->GetShowName(), pMasterName ? pMasterName : pEntity->GetTitle());
}
data.writeString(sAllName); //怪物名字
data <<(WORD)pEntity->GetProperty<int>(PROP_ENTITY_POSX); //坐标x
data <<(WORD)pEntity->GetProperty<unsigned int>(PROP_ENTITY_POSY); //坐标y
data <<(unsigned)pEntity->GetProperty<unsigned int>(PROP_ENTITY_MODELID);//模型id
data << (BYTE)pEntity->GetProperty<unsigned int>(PROP_ENTITY_DIR); //方向
data << (WORD) pEntity->GetProperty<unsigned>(PROP_CREATURE_LEVEL); //等级
data << (unsigned)pEntity->GetProperty<unsigned>(PROP_CREATURE_HP); //当前hp
data << (unsigned)pEntity->GetProperty<unsigned>(PROP_CREATURE_MP); //当前mp
data << (unsigned)pEntity->GetProperty<unsigned>(PROP_CREATURE_MAXHP); //最大的血
data << (unsigned)pEntity->GetProperty<unsigned>(PROP_CREATURE_MAXMP); //最大的蓝
data << (WORD) pEntity->GetProperty<unsigned>(PROP_CREATURE_MOVEONESLOTTIME); //移动速度
data << (WORD) pEntity->GetProperty<unsigned>(PROP_CREATURE_ATTACK_SPEED); //攻击速度
data << (unsigned int) pEntity->GetProperty<unsigned int>(PROP_CREATURE_STATE); //状态
data << (unsigned int) GetMonsterNameColorByOther(pEntity->GetHandle(), m_pEntity->GetHandle()); //名字颜色
data << (WORD)pEntity->GetProperty<unsigned int>(PROP_ENTITY_ID); //怪物id
data << (unsigned int)pEntity->GetProperty<unsigned int>(PROP_MONSTER_LIVE_TIMEOUT); //怪物生命到期时间
((CAnimal*)pEntity)->GetBuffSystem()->AppendBuffData(data);
data << (BYTE)((CMonster *)pEntity)->GetMonsterType();
unsigned int nBelongActorId = pEntity->GetProperty<unsigned int>(PROP_MONSTER_BELONG_ID);
data << nBelongActorId; // 非活动副本Boss归属处理
//OutputMsg(rmTip,"EntityAppearMonster, entityId=%d, entityName=%s, nLiveTimeout=%u",
// pEntity->GetId(), pEntity->GetEntityName(), nLiveTimeout);
pack.flush();
}
void CObserverSystem::EntityAppearPet(const EntityHandle &handle, CEntity* pEntity)
{
if(!m_pEntity|| !pEntity)return;
CActor *pSelf = (CActor *) m_pEntity;
INT_PTR nType = handle.GetType();
CActorPacket pack;
CDataPacket &data =pSelf->AllocPacket(pack);
data <<(BYTE)enDefaultEntitySystemID <<(BYTE)sPetAppear;
data << (BYTE)nType;
data <<(Uint64) handle; // 句柄
char sAllName[128] = {0};
unsigned int nMonsterId = 0;
CActor * pOwner = ((CPet *)pEntity)->GetMaster();
if (pOwner != NULL)
{
sprintf_s(sAllName, sizeof(sAllName), "%s\\%s",pEntity->GetEntityName(), pOwner->GetEntityName());
data.writeString(sAllName);
}
else
{
data.writeString(pEntity->GetShowName());
}
data <<(WORD)pEntity->GetProperty<int>(PROP_ENTITY_POSX); //坐标x
data <<(WORD)pEntity->GetProperty<unsigned int>(PROP_ENTITY_POSY); //坐标y
data <<(unsigned)pEntity->GetProperty<unsigned int>(PROP_ENTITY_MODELID); //模型id
data << (BYTE)pEntity->GetProperty<unsigned int>(PROP_ENTITY_DIR); //朝向
data << (BYTE) pEntity->GetProperty<unsigned>(PROP_CREATURE_LEVEL); //等级
data << (unsigned)pEntity->GetProperty<unsigned>(PROP_CREATURE_HP); //当前Hp
data << (unsigned)pEntity->GetProperty<unsigned>(PROP_CREATURE_MP); //当前Mp
data << (unsigned)pEntity->GetProperty<unsigned>(PROP_CREATURE_MAXHP); //最大的血
data << (unsigned)pEntity->GetProperty<unsigned>(PROP_CREATURE_MAXMP); //最大的蓝
data << (WORD) pEntity->GetProperty<unsigned>(PROP_CREATURE_MOVEONESLOTTIME); //移动速度
data << (WORD) pEntity->GetProperty<unsigned>(PROP_CREATURE_ATTACK_SPEED); //攻击速度
data << (unsigned int) pEntity->GetProperty<unsigned int>(PROP_CREATURE_STATE); //状态
data << (unsigned int) ((CPet*)pEntity)->GetColor(); //颜色
if(pOwner)
{
data << (Uint64) pOwner->GetHandle(); //主人句柄
}
else
{
data << (Uint64)0;
}
data <<(WORD)pEntity->GetProperty<unsigned int>(PROP_ENTITY_ID); //宠物id
((CAnimal*)pEntity)->GetBuffSystem()->AppendBuffData(data);
pack.flush();
}
void CObserverSystem::EntityAppearSlave(const EntityHandle &handle, CEntity* pEntity)
{
if(!m_pEntity|| !pEntity)return;
CActor *pSelf = (CActor *) m_pEntity;
INT_PTR nType = handle.GetType();
CActorPacket pack;
CDataPacket &data =pSelf->AllocPacket(pack);
data <<(BYTE)enDefaultEntitySystemID <<(BYTE)sEntityAppear;
data << (BYTE)nType;
data <<(Uint64) handle;
char sAllName[128] = {0};
unsigned int nMonsterId = 0;
if(nType == enPet)
{
CActor * pOwner = ((CPet *)pEntity)->GetMaster();
if (pOwner != NULL && pOwner->IsSceneChangeModel())
{
sprintf_s(sAllName, sizeof(sAllName), "\\%s",pEntity->GetShowName(), pOwner->GetEntityName());
data.writeString(sAllName);
}
else
{
data.writeString(pEntity->GetShowName());
}
}
else
{
if (nType == enHero && ((CHero*)pEntity)->GetMaster())
{
data.writeString(pEntity->GetShowName());
}else
{
data.writeString(pEntity->GetEntityName());
}
}
data <<(WORD)pEntity->GetProperty<int>(PROP_ENTITY_POSX); //坐标
data <<(WORD)pEntity->GetProperty<unsigned int>(PROP_ENTITY_POSY); //坐标
data <<(unsigned)pEntity->GetProperty<unsigned int>(PROP_ENTITY_MODELID); //模型id
data << (BYTE)pEntity->GetProperty<unsigned int>(PROP_ENTITY_DIR); //朝向
nMonsterId = pEntity->GetProperty<unsigned int>(PROP_ENTITY_ID);
data << (BYTE) pEntity->GetProperty<unsigned>(PROP_CREATURE_LEVEL);
data << (unsigned)pEntity->GetProperty<unsigned>(PROP_CREATURE_HP);
data << (unsigned)pEntity->GetProperty<unsigned>(PROP_CREATURE_MP);
data << (unsigned)pEntity->GetProperty<unsigned>(PROP_CREATURE_MAXHP); //最大的血
data << (unsigned)pEntity->GetProperty<unsigned>(PROP_CREATURE_MAXMP); //最大的蓝
data << (WORD) pEntity->GetProperty<unsigned>(PROP_CREATURE_MOVEONESLOTTIME); //移动速度
data << (WORD) pEntity->GetProperty<unsigned>(PROP_CREATURE_ATTACK_SPEED); //攻击速度
data << (unsigned int) pEntity->GetProperty<unsigned int>(PROP_CREATURE_STATE); //状态
data << (unsigned int) pEntity->GetProperty<unsigned int>(PROP_CREATURE_COLOR); //添加了颜色
data << (unsigned int)0;
if(nType == enHero)
{
data << (unsigned int)0;
}
else
{
data << ((CPet*)pEntity)->GetColor();
}
BYTE byMTAT = 0;
byMTAT = (BYTE)((CAnimal*)pEntity)->GetAttackType();
data << byMTAT;
if(nType == enHero)
{
CHero *pHero = ((CHero *)pEntity);
const CHeroSystem::HERODATA* pHeroData = pHero->GetHeroPtr();
if(pHeroData)
{
data << (BYTE)pHeroData->data.bSex; //性别
data << (BYTE)pHeroData->data.bVocation;// 职业
data << (BYTE)pHeroData->data.bCircle; //转数
data << pHero->GetProperty<unsigned int>(PROP_ACTOR_WEAPONAPPEARANCE); //武器外观
data << pHero->GetProperty<unsigned int>(PROP_ACTOR_SWINGAPPEARANCE); //翅膀外观
data << (unsigned int)0;
data << pHero->GetProperty<unsigned int>(PROP_ACTOR_SOCIALMASK);
}
}
CActor *pOwner =NULL;
if( nType == enPet || nType == enHero)
{
if(nType == enPet)
{
pOwner = ((CPet*)pEntity)->GetMaster();
}
else
{
pOwner = ((CHero*)pEntity)->GetMaster();
}
if(pOwner != m_pEntity)
{
data << (BYTE)0;
}
else
{
//((CAnimal*)pEntity)->GetBuffSystem()->WriteBuffData(data); //把宠物的buff数据写进去
((CAnimal*)pEntity)->GetBuffSystem()->AppendBuffData(data);
}
}
((CAnimal*)pEntity)->GetEffectSystem().AppendEffectData(data);
if ( nType == enPet || nType == enHero )
{
if(pOwner)
{
data << (Uint64) pOwner->GetHandle();
if( pOwner->HideOtherPlayerInfo() && pOwner != m_pEntity )
{
data << (BYTE)1;
}
else
{
data << (BYTE)0;
}
}
else
{
data << (Uint64)0;
data << (BYTE)0; //不隐藏名字
}
}
data <<(WORD)nMonsterId;
//没有属性也要发""或者0不允许没有值
data.writeString("");
data << (unsigned int)0;
pack.flush();
}
void CObserverSystem::EntityAppearNpc(const EntityHandle &handle, CEntity* pEntity)
{
if(!m_pEntity|| !pEntity)
{
return;
}
int nActorType = m_pEntity->GetHandle().GetType();
if (nActorType == enActor)
{
if (((CActor*)m_pEntity)->OnGetIsTestSimulator()
|| ((CActor*)m_pEntity)->OnGetIsSimulator())
{
return;
}
}
CActor *pSelf = (CActor *) m_pEntity;
//INT_PTR nType = handle.GetType();
CActorPacket pack;
CDataPacket &data =pSelf->AllocPacket(pack);
data <<(BYTE)enDefaultEntitySystemID <<(BYTE)sNPCAppear;
data << (Uint64) handle;
char sAllName[128];
const char *pMasterName = NULL;
if(pEntity->GetAttriFlag().DenyShowName)
{
sprintf_s(sAllName, sizeof(sAllName), " \\");
}
else
{
sprintf_s(sAllName,sizeof(sAllName),"%s\\%s",pEntity->GetShowName(), pMasterName ? pMasterName : pEntity->GetTitle());
}
data.writeString(sAllName);
data <<(WORD)pEntity->GetProperty<int>(PROP_ENTITY_ID); //id
data <<(WORD)pEntity->GetProperty<int>(PROP_ENTITY_POSX); //坐标x
data <<(WORD)pEntity->GetProperty<unsigned int>(PROP_ENTITY_POSY); //坐标y
data <<(unsigned)pEntity->GetProperty<unsigned int>(PROP_ENTITY_MODELID); //模型id
data << (BYTE)pEntity->GetProperty<unsigned int>(PROP_ENTITY_DIR); //朝向
//data << (byte)pSelf->GetQuestSystem()->GetQuestStateType((CNpc*)pEntity);
pack.flush();
}
void CObserverSystem::EntityAppearDefault(const EntityHandle &handle, CEntity* pEntity)
{
if(!m_pEntity|| !pEntity)
{
return;
}
int nActorType = m_pEntity->GetHandle().GetType();
if (nActorType == enActor)
{
if (((CActor*)m_pEntity)->OnGetIsTestSimulator()
|| ((CActor*)m_pEntity)->OnGetIsSimulator())
{
return;
}
}
CActor *pSelf = (CActor *) m_pEntity;
INT_PTR nType = handle.GetType();
CActorPacket pack;
CDataPacket &data =pSelf->AllocPacket(pack);
data <<(BYTE)enDefaultEntitySystemID <<(BYTE)sEntityAppear;
char sAllName[128];
const char *pMasterName = NULL;
data << (BYTE)nType;
data <<(Uint64) handle;
if(pEntity->GetAttriFlag().DenyShowName)
{
sprintf_s(sAllName, sizeof(sAllName), " \\");
}
else
{
sprintf_s(sAllName,sizeof(sAllName),"%s\\%s",pEntity->GetShowName(), pMasterName ? pMasterName : pEntity->GetTitle());
}
data.writeString(sAllName);
WORD nMonsterId = 0;
data <<(WORD)pEntity->GetProperty<int>(PROP_ENTITY_POSX); //坐标
data <<(WORD)pEntity->GetProperty<unsigned int>(PROP_ENTITY_POSY); //坐标
data <<(unsigned)pEntity->GetProperty<unsigned int>(PROP_ENTITY_MODELID); //模型id
data << (BYTE)pEntity->GetProperty<unsigned int>(PROP_ENTITY_DIR); //朝向
data <<(WORD)nMonsterId;
//没有属性也要发""或者0不允许没有值
data.writeString("");
data << (unsigned int)0;
pack.flush();
}
//出现了一个实体,如果是玩家要发消息到客户端
void CObserverSystem::EntityAppear(const EntityHandle &handle, CEntity* pEntity)
{
//如果是一个玩家,那么需要发送创建的消息
CActor *pSelf = (CActor *) m_pEntity;
if(m_pEntity ==NULL || pSelf ==NULL)return;
INT_PTR nType = handle.GetType();
switch(nType)
{
case enActor:
{
EntityAppearActor(handle,(CActor*)pEntity);
break;
}
case enDropItem:
{
EntityAppearDropItem(handle,pEntity);
break;
}
case enFire:
{
EntityAppearSpecialEntity(handle,pEntity);
break;
}
case enMonster:
case enGatherMonster:
{
EntityAppearMonster(handle,pEntity);
break;
}
case enPet:
{
EntityAppearPet(handle,pEntity);
break;
}
case enHero:
{
EntityAppearSlave(handle,pEntity);
break;
}
case enNpc:
{
EntityAppearNpc(handle,pEntity);
break;
}
default:
{
EntityAppearDefault(handle,pEntity);
break;
}
}
if (pEntity->PushActorAppear())
{
if (pEntity && NeedPushActor(pEntity->GetType()))
((CAnimal*)pEntity)->GetObserverSystem()->onActorAppear((CActor*)m_pEntity);
}
}
//实体消失
void CObserverSystem::EntityDisappear(const EntityHandle &handle)
{
CActor * pActor =(CActor *)m_pEntity;
if(pActor ==NULL) return;
//次元Boss归属玩家不从视野中移除
CEntity* pEntity = GetEntityFromHandle(handle);
if ( pEntity && pEntity->GetType() == enActor && ((CActor *)pEntity)->IsBeLongBossActor() && pEntity->GetFuBen() && pEntity->GetFuBen()->GetFbId() == 23 && pEntity->GetSceneID() == 317 && pEntity->GetProperty<unsigned int>(PROP_CREATURE_HP) > 0 )
{
return;
}
//次元Boss怪物不从视野中移除
if ( pEntity && pEntity->GetType() == enMonster && pEntity->GetProperty<unsigned int>(PROP_ENTITY_ID) == 386 && pEntity->GetFuBen()->GetFbId() == 23 && pEntity->GetSceneID() == 317 && pEntity->GetProperty<unsigned int>(PROP_CREATURE_HP) > 0 )
{
return;
}
CActorPacket pack;
CDataPacket &data = ((CActor *) m_pEntity)->AllocPacket(pack);
//其他的实体和掉落物品不同处理
if(handle.GetType() != enDropItem)
{
data << (BYTE)enDefaultEntitySystemID << (BYTE)sEntityDisappear << (Uint64)handle;
}
else
{
//拾取物品使用新的消息格式
data <<(BYTE)enLootSystemID << (BYTE)sDropItemDisAppear << (unsigned int)handle.GetIndex();
}
pack.flush();
// 玩家的视野里头出现其他非玩家实体
if (NeedPushActor(handle.GetType()) )
{
CEntity* pEntity = GetEntityFromHandle(handle);
if (pEntity )
{
((CAnimal*)pEntity)->GetObserverSystem()->onActorDisappear((CActor*)m_pEntity);
}
}
}
EntityHandle CObserverSystem::FindEntityByName(const char *pEntityName)
{
CEntityManager* em = GetGlobalLogicEngine()->GetEntityMgr();
for (INT_PTR i = 0; i < m_sEntityList.count(); i++)
{
EntityHandle handle = m_sEntityList[i].m_handle;
CEntity *pEntity = em->GetEntity(handle);
if (pEntity)
{
const char *pIterName = pEntity->GetEntityName();
if (strlen(pEntityName) == strlen(pIterName) && !strcmp(pEntityName, pEntity->GetEntityName()))
return handle;
}
}
return EntityHandle();
}
void CObserverSystem::ClearObserveList()
{
if(m_pEntity ==NULL) return;
CEntityManager* em = GetGlobalLogicEngine()->GetEntityMgr();
EntityHandle handle = m_pEntity->GetHandle();
if (enActor == handle.GetType())
{
for (INT_PTR i = 0; i < m_sEntityList.count(); i++)
{
if (m_sEntityList[i].m_handle != handle)
{
CEntity* pEntity = em->GetEntity(m_sEntityList[i].m_handle);
if (pEntity && NeedPushActor(pEntity->GetType()))
{
((CAnimal *)pEntity)->GetObserverSystem()->onActorDisappear((CActor *)m_pEntity);
}
}
}
}
m_sEntityList.clear();
}