#include "StdAfx.h" #include "ObserverSystem.h" //内存池 EntityVector* CObserverSystem::s_seqVisibleList = NULL; CVector* 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 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 tmpEntityList; // 周围实体列表(采取数组的方式存储) std::map tmpMapList; std::map 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(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(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(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 &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(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 <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 <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 <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 <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(PROP_ENTITY_POSX); WORD nPosY = (WORD)pOtherActor->GetProperty(PROP_ENTITY_POSY); int nSex = pOtherActor->GetProperty(PROP_ACTOR_SEX); INT_PTR nType = handle.GetType(); CActorPacket pack; CDataPacket &data = pSelf->AllocPacket(pack); CActorProperty * pProperty = (CActorProperty *) pOtherActor->GetPropertyPtr(); //玩家的属性集 data <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 <GetProperty(PROP_ENTITY_MODELID); //模型id data << (unsigned)pOtherActor->GetProperty(PROP_CREATURE_HP); //当前的血 data << (unsigned)pOtherActor->GetProperty(PROP_CREATURE_MP); //当前的蓝 data << (unsigned)pOtherActor->GetProperty(PROP_CREATURE_MAXHP); //最大的血 data << (unsigned)pOtherActor->GetProperty(PROP_CREATURE_MAXMP); //最大的蓝 data << (WORD) pOtherActor->GetProperty(PROP_CREATURE_MOVEONESLOTTIME); //移动速度 data << (BYTE) nSex; //性别 data << (BYTE) pOtherActor->GetProperty(PROP_ACTOR_VOCATION); //职业 data << (WORD) pOtherActor->GetProperty(PROP_CREATURE_LEVEL); //等级 data << (unsigned int)pOtherActor->GetProperty(PROP_ACTOR_CIRCLE); //转数 int nWeapon = pOtherActor->GetProperty(PROP_ACTOR_WEAPONAPPEARANCE); //武器外观 int nSwing = pOtherActor->GetProperty(PROP_ACTOR_SWINGAPPEARANCE); //翅膀外观 if (pOtherActor->IsSceneChangeModel()) { nSwing = 0; } data << (int)nWeapon; //武器外观 data << (int)nSwing; //翅膀外观 data << (int)pOtherActor->GetProperty(PROP_ACTOR_SOCIALMASK); //玩家社会关系 data << (WORD)pOtherActor->GetProperty(PROP_ENTITY_ICON); //头像ID data << (WORD)pOtherActor->GetProperty(PROP_CREATURE_ATTACK_SPEED);//攻击速度 data << (BYTE)pOtherActor->GetProperty(PROP_ENTITY_DIR); //下发朝向 data << (unsigned int)pOtherActor->GetProperty(PROP_CREATURE_STATE); //状态 data << (unsigned int)0; data << (int)pOtherActor->GetProperty(PROP_ACTOR_TEAM_ID); //队伍的ID data << (BYTE) pOtherActor->GetProperty(PROP_ACTOR_ZY); //阵营类型 data << (unsigned int)pOtherActor->GetProperty(PROP_ACTOR_CURNEWTITLE);//头衔 data << (unsigned int)(GetNameColorLookedByOther(pOtherActor->GetHandle(), m_pEntity->GetHandle()));//名字颜色 data << (unsigned int)pOtherActor->GetProperty(PROP_ACTOR_SUPPER_PLAY_LVL);//超玩俱乐部等级 data << (unsigned int)pOtherActor->GetProperty(PROP_ACTOR_SOLDIERSOULAPPEARANCE); //兵魂外观 data << (WORD)pOtherActor->GetProperty(PROP_ACTOR_WEAPON_ID); //正在装备的武器id data << (unsigned int)pOtherActor->GetProperty(PROP_ACTOR_GUILD_ID); //行会ID data << (unsigned int)pOtherActor->GetProperty(PROP_ACTOR_MONSTER_MODELID); //怪物模型id data << (unsigned int)pOtherActor->GetProperty(PROP_ACTOR_MERITORIOUSPOINT); //累计功勋 data << (unsigned int)pOtherActor->GetProperty(PROP_ACTOR_NEXT_SKILL_FLAG); //战士下一次技能flag data << (unsigned int)pOtherActor->GetProperty(PROP_ACTOR_EVIL_PK_STATUS); //恶意PK状态 data << (unsigned int)pOtherActor->GetProperty(PROP_ACTOR_PK_VALUE); //PK值 pOtherActor->GetBuffSystem()->AppendBuffData(data); //玩家的Buff数据 data << (unsigned int)pOtherActor->GetProperty(PROP_ENTITY_ID); //玩家id data << (unsigned int)pOtherActor->GetProperty(PROP_ACTOR_AREA_ATTR); //区域属性存储位 data << (unsigned int)pOtherActor->GetProperty(PROP_ACTOR_AREA_ATTR_0); data << (unsigned int)pOtherActor->GetProperty(PROP_ACTOR_NORMAL_ATK_ACC); data << (unsigned int)pOtherActor->GetProperty(PROP_ACTOR_FRENZY); data << (unsigned int)pOtherActor->GetProperty(PROP_ACTOR_OFFICE); ////宠物系统非 ai宠物 data << (int)pOtherActor->GetProperty(PROP_ACTOR_LOOT_PET_ID); data << (int)pOtherActor->GetProperty(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 <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(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(PROP_ENTITY_POSX); //坐标x data <<(WORD)pOtherItem->GetProperty(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(PROP_ENTITY_POSX); //坐标x data <<(WORD)pOtherItem->GetProperty(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 <GetProperty(PROP_ENTITY_MODELID); //模型的ID data <<(WORD)pSpecialEntity->GetProperty(PROP_ENTITY_POSX); //坐标x data <<(WORD)pSpecialEntity->GetProperty(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(PROP_ENTITY_POSX); //坐标x data <<(WORD)pEntity->GetProperty(PROP_ENTITY_POSY); //坐标y data <<(unsigned)pEntity->GetProperty(PROP_ENTITY_MODELID);//模型id data << (BYTE)pEntity->GetProperty(PROP_ENTITY_DIR); //方向 data << (WORD) pEntity->GetProperty(PROP_CREATURE_LEVEL); //等级 data << (unsigned)pEntity->GetProperty(PROP_CREATURE_HP); //当前hp data << (unsigned)pEntity->GetProperty(PROP_CREATURE_MP); //当前mp data << (unsigned)pEntity->GetProperty(PROP_CREATURE_MAXHP); //最大的血 data << (unsigned)pEntity->GetProperty(PROP_CREATURE_MAXMP); //最大的蓝 data << (WORD) pEntity->GetProperty(PROP_CREATURE_MOVEONESLOTTIME); //移动速度 data << (WORD) pEntity->GetProperty(PROP_CREATURE_ATTACK_SPEED); //攻击速度 data << (unsigned int) pEntity->GetProperty(PROP_CREATURE_STATE); //状态 data << (unsigned int) GetMonsterNameColorByOther(pEntity->GetHandle(), m_pEntity->GetHandle()); //名字颜色 data << (WORD)pEntity->GetProperty(PROP_ENTITY_ID); //怪物id data << (unsigned int)pEntity->GetProperty(PROP_MONSTER_LIVE_TIMEOUT); //怪物生命到期时间 ((CAnimal*)pEntity)->GetBuffSystem()->AppendBuffData(data); data << (BYTE)((CMonster *)pEntity)->GetMonsterType(); unsigned int nBelongActorId = pEntity->GetProperty(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(PROP_ENTITY_POSX); //坐标x data <<(WORD)pEntity->GetProperty(PROP_ENTITY_POSY); //坐标y data <<(unsigned)pEntity->GetProperty(PROP_ENTITY_MODELID); //模型id data << (BYTE)pEntity->GetProperty(PROP_ENTITY_DIR); //朝向 data << (BYTE) pEntity->GetProperty(PROP_CREATURE_LEVEL); //等级 data << (unsigned)pEntity->GetProperty(PROP_CREATURE_HP); //当前Hp data << (unsigned)pEntity->GetProperty(PROP_CREATURE_MP); //当前Mp data << (unsigned)pEntity->GetProperty(PROP_CREATURE_MAXHP); //最大的血 data << (unsigned)pEntity->GetProperty(PROP_CREATURE_MAXMP); //最大的蓝 data << (WORD) pEntity->GetProperty(PROP_CREATURE_MOVEONESLOTTIME); //移动速度 data << (WORD) pEntity->GetProperty(PROP_CREATURE_ATTACK_SPEED); //攻击速度 data << (unsigned int) pEntity->GetProperty(PROP_CREATURE_STATE); //状态 data << (unsigned int) ((CPet*)pEntity)->GetColor(); //颜色 if(pOwner) { data << (Uint64) pOwner->GetHandle(); //主人句柄 } else { data << (Uint64)0; } data <<(WORD)pEntity->GetProperty(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(PROP_ENTITY_POSX); //坐标 data <<(WORD)pEntity->GetProperty(PROP_ENTITY_POSY); //坐标 data <<(unsigned)pEntity->GetProperty(PROP_ENTITY_MODELID); //模型id data << (BYTE)pEntity->GetProperty(PROP_ENTITY_DIR); //朝向 nMonsterId = pEntity->GetProperty(PROP_ENTITY_ID); data << (BYTE) pEntity->GetProperty(PROP_CREATURE_LEVEL); data << (unsigned)pEntity->GetProperty(PROP_CREATURE_HP); data << (unsigned)pEntity->GetProperty(PROP_CREATURE_MP); data << (unsigned)pEntity->GetProperty(PROP_CREATURE_MAXHP); //最大的血 data << (unsigned)pEntity->GetProperty(PROP_CREATURE_MAXMP); //最大的蓝 data << (WORD) pEntity->GetProperty(PROP_CREATURE_MOVEONESLOTTIME); //移动速度 data << (WORD) pEntity->GetProperty(PROP_CREATURE_ATTACK_SPEED); //攻击速度 data << (unsigned int) pEntity->GetProperty(PROP_CREATURE_STATE); //状态 data << (unsigned int) pEntity->GetProperty(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(PROP_ACTOR_WEAPONAPPEARANCE); //武器外观 data << pHero->GetProperty(PROP_ACTOR_SWINGAPPEARANCE); //翅膀外观 data << (unsigned int)0; data << pHero->GetProperty(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(PROP_ENTITY_ID); //id data <<(WORD)pEntity->GetProperty(PROP_ENTITY_POSX); //坐标x data <<(WORD)pEntity->GetProperty(PROP_ENTITY_POSY); //坐标y data <<(unsigned)pEntity->GetProperty(PROP_ENTITY_MODELID); //模型id data << (BYTE)pEntity->GetProperty(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(PROP_ENTITY_POSX); //坐标 data <<(WORD)pEntity->GetProperty(PROP_ENTITY_POSY); //坐标 data <<(unsigned)pEntity->GetProperty(PROP_ENTITY_MODELID); //模型id data << (BYTE)pEntity->GetProperty(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(PROP_CREATURE_HP) > 0 ) { return; } //次元Boss怪物不从视野中移除 if ( pEntity && pEntity->GetType() == enMonster && pEntity->GetProperty(PROP_ENTITY_ID) == 386 && pEntity->GetFuBen()->GetFbId() == 23 && pEntity->GetSceneID() == 317 && pEntity->GetProperty(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(); }