• 玩家上线


    1.在GS这边发送(本地玩家信息)
     LocPlayerInfo info;
     InitLocalPlayer(rActorEx, info);
     SendCmd(s2c_local_player_info, &info, sizeof(info));
    这个LocPlayerInfo好像内容比较多
    struct LocPlayerInfo
    {
     int id;
     wchar_t name[64];
     unsigned int nBodyID;
     int mapID;
     pos2d pos;
     ObjStat stat;
     SkillStat skillstats[100];    // 身上技能,最大个数
     int     nskill;     // 当前技能个数
     AttInfo     m_AttInfo;     // 属性值
    };
    2.进入map,初始化一些信息之后,发送
    plchannel->m_fnSendLocalPlayerEnter(m_nMapId, plchannel->tgtPos);
    这个位置是纠正后的位置,有可能玩家位置不正确,mapid和位置都已这个为准
    3.客户端发送激活玩家的包
    服务器在收到激活包之后
    //这些都是相当重要的
    void Map::ActivatePlayer(int mapChannelId) //激活玩家
    {
     PlayerChannel* pPC = m_vecPlayerChannel[mapChannelId];
     if (pPC->m_bBeActived)
      return;
     pPC->m_bBeActived = true;
     auto& pActorInfoEx = pPC->m_pActorInfoEx;
    
     if (!pActorInfoEx->m_bGaming) 
     {//第一次进游戏
      pActorInfoEx->m_bGaming = true;
      StartGame(mapChannelId);//真心没看懂啥意思
     }     
     pos2d& cPlayerMapPos = m_spBase->GetMapPos(pPC->tgtPos); 
    //    SetMapColl(mpos.x, mpos.y, true);
     GetAllPlayers()[pPC->objId.id] = pPC;//完全不知道干啥
     m_MapCellMgr.AddObj(cPlayerMapPos.x, cPlayerMapPos.y, pPC);//完全不知道干啥
    
     //在新进入块中通知
     pos2d newBlockPos = {pPC->m_nBlockX, pPC->m_nBlockY};
     pPC->m_fnSendStatChange(pPC->stat);//此处为什么发送状态包
     NotifyBlock(pos2d(), newBlockPos, pPC, true);
    
     //让玩家上线就能看到所有附近角色的动作。
     m_MapCellMgr.m_vecRolesBlock[pPC->m_nBlockX][pPC->m_nBlockY].Add(pPC);
    
     UpdateRegionInfo(pPC, cPlayerMapPos);//不知干啥的
    
     //判断罪恶值
     if(pPC->m_pActorInfoEx->GetSinValue() > 0)
     {
      m_spSinMgr->AddPlayer(pPC);
     }
    
     //宠物(现在主要是切图时宠物携带)
     if(pPC->m_pActorInfoEx->IsCarryTempPet())
     {
      const ShuiHu::PetInfo* pTempPetInfo = pPC->m_pActorInfoEx->GetTempPetInfoPtr();
      if (pTempPetInfo->m_nCurHP <= 0)
      {
       ShuiHu::GetLogger()->Warning("玩家(ID=%d)进入新地图(%d),带了个血量为<=0的宠物(ID=%d)!",
        pPC->objId.id, m_nMapId, pTempPetInfo->m_nID);
       return;
      }
      pos2d cPetMapPos = {0};
      if (!Round(1, cPlayerMapPos, cPetMapPos))
      {
       pPC->m_pActorInfoEx->SetNoneTempPet();
       return; 
      }
    
      // 召唤正式宠物
      m_pSkill->CallPetByPos(pPC, *pTempPetInfo, cPetMapPos);
     }
    }
    
    
    void Map::NotifyBlock(pos2d OlDBlockPos, pos2d NewBlockPos, PlayerInfo* pPlayer, bool bOnlyNewBlock)
    {
        std::vector<pos2d> vecLeaveBlock;
        std::vector<pos2d> vecEnterBlock;
        if (bOnlyNewBlock)//玩家进入地图
        {
            getXxX(5, NewBlockPos.x, NewBlockPos.y, vecEnterBlock);//获取玩家所在格子为中心的5*5的格子
        }
        else//玩家移动
        {
            GetLeaveAndEnterBlocks(OlDBlockPos, NewBlockPos, vecLeaveBlock, vecEnterBlock);//针对移动,获取新进入的和离开的格子用于通知,对于没有离开和进入的格子待会再说
        }
        std::vector<ObjecInfo> vecLeaveObj;
        for (auto it : vecLeaveBlock)
        {
            NotifyItem(it, pPlayer, false);//物品通知
            NotifyOrnamental(it, pPlayer, false); //装饰物通知
            for (auto it2 : *m_MapCellMgr.m_vecRolesBlock[it.x][it.y].GetAllobj())
            {
                int id = it2.first.id;
                vecLeaveObj.push_back(*it2.second);
                if(it2.first.type == ObjID_Player)
                {
                    pPlayer->m_mapNearbyPlayers.erase(id);
                    //让对方玩家也能看到自己离开
                    auto pDestPlayer = (PlayerInfo*)it2.second;
                    pDestPlayer->m_mapNearbyPlayers.erase(pPlayer->objId.id);
                    if(!pPlayer->m_bHide)//如果是隐身无需此通知
                    {
                        std::vector<ObjecInfo> vecLeaveDestView;
                        vecLeaveDestView.push_back(*pPlayer);
                        pDestPlayer->m_fnSendObjLeave(vecLeaveDestView);
                    }
                }
                else
                {//非玩家不需要表现,不用发送消息。
                    auto pDestNpc = (I_NPC*)it2.second;
                    pDestNpc->m_mapNearbyPlayers.erase(pPlayer->objId.id);
                    pPlayer->m_mapNearbyMonsters.erase(id);
                }
            }
        }    
        if(vecLeaveObj.size())
            pPlayer->m_fnSendObjLeave(vecLeaveObj);
    
        std::vector<ObjecInfo> vecNewEnterObj;
        for (auto it : vecEnterBlock)
        {
            NotifyItem(it, pPlayer, true);  //掉落物品通知
            NotifyOrnamental(it, pPlayer, true); //装饰物通知
            for (auto it2 : *m_MapCellMgr.m_vecRolesBlock[it.x][it.y].GetAllobj())
            {
                ObjecInfoEx* obj_ex = (ObjecInfoEx*)it2.second;
                int id = it2.first.id;
                vecNewEnterObj.push_back(*it2.second);
                if(it2.first.type == ObjID_Player)
                {
                    auto pDestPlayer = (PlayerInfo*)it2.second;
                    pPlayer->m_mapNearbyPlayers[id] = pDestPlayer;
                    //让对方玩家也能看到自己进入(针对:对方不移出当前Block格时也能看对方进入)
                    pDestPlayer->m_mapNearbyPlayers[pPlayer->objId.id] = pPlayer;
                    if(!pPlayer->m_bHide)
                    {
                        std::vector<ObjecInfo> vecEnterDestViewObj;
                        vecEnterDestViewObj.push_back(*pPlayer);
                        pDestPlayer->m_fnSendObjEnter(vecEnterDestViewObj);
                    }
                }
                else
                {//非玩家不需要表现,不用发送消息。
                    auto pDestNpc = (I_NPC*)it2.second;
                    pDestNpc->m_mapNearbyPlayers[pPlayer->objId.id] = pPlayer;
                    pPlayer->m_mapNearbyMonsters[id] = pDestNpc;
                }
            }
        }
        if (vecNewEnterObj.size() > 1000)
        {
            Plug::PlugMessageBox("vecNewEnterObj出错");
        }
        if(vecNewEnterObj.size())
            pPlayer->m_fnSendObjEnter(vecNewEnterObj);
    }
  • 相关阅读:
    import()函数
    node-sass安装报错
    npm 安装扩展模块时,因缓存报错的问题汇总
    测试
    export default 和 export 区别
    正则
    物联网
    第十二次课堂总结
    第十二次作业
    作业10
  • 原文地址:https://www.cnblogs.com/zzyoucan/p/4162026.html
Copyright © 2020-2023  润新知