map 玩家上线

map 玩家上线
else if(gs2ms_add_player == pkt.cmd)
{
    PlayerChannel* pPC = new PlayerChannel(this);
    //加到地图中,但是并未激活该玩家
    int nChannelId = pPC->OnPlayerEnter(pkt.data, pkt.len);//玩家信息的初始化工作
    m_vecPlayerChannel[nChannelId] = pPC;
    AddPlayer(nChannelId);//玩家加入地图,玩家进入地图位置,向客户端发送entermap包
}
在AddPlayer中向客户端发送了玩家位置包,现在好像DataLayer专门搞了个线程取所有线程的包和GS的包
接下来客户端就发送了玩家激活包,如果客户端不发送是不让玩家进入地图的

//激活包处理
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->GetAttrTgtPos()); 
//    SetMapColl(mpos.x, mpos.y, true);
//    GetAllPlayers()[pPC->GetAttrObjID_Id()] = pPC;
    m_MapCellMgr.AddPlayer(pPC->GetAttrObjID_Id(), pPC);//这个就是说了很久的地图单元格管理
    m_MapCellMgr.AddObj(cPlayerMapPos.x, cPlayerMapPos.y, pPC);

    //在新进入块中通知
    pos2d newBlockPos(pPC->GetAttrBlockX(), pPC->GetAttrBlockY());
    pPC->m_fnSendStatChange(pPC->GetAttrObjStat());//向客户端发送statchang包,就是有名的玩家状态包,表示其魔量,血量,可以说是玩家最基本的信息
#ifdef USE_BLOCK_MGR
    NotifyBlockX(pos2d(), newBlockPos, pPC, Map::eBlockChange_EnterMap);
    m_MapBlockMgr.Add(newBlockPos, pPC);
#else
    NotifyBlock(pos2d(0), newBlockPos, pPC, true);//以前好像是5*5block格子的通知,现在不清楚,就是说玩家上线5*5格子内的玩家可以看到他上线,发的是objinfo结构体
    m_MapCellMgr.m_vecRolesBlock[pPC->GetAttrBlockX()][pPC->GetAttrBlockY()].Add(pPC);//加入到blockmgr中,有名的block管理器
#endif
    //让玩家上线就能看到所有附近角色的动作。

    UpdateRegionInfo(pPC, cPlayerMapPos);//初始化服务器玩家区域信息,是在哪个区域中

    //判断罪恶值
    if(pPC->GetAttrSinValue() > 0)
    {
        m_spSinMgr->AddPlayer(pPC);//加入罪恶管理器中
    }
    //如果在皇宫内地图,重新设置皇宫内帮会类型
    if(eMAPTYPE_PALACE == m_MapType)
    {
        std::wstring GuildName = safe::mbstowcs(pPC->m_pActorInfoEx->GetGangName());
        m_spCityObj->SetPalaceGuild(GuildName, true);
    }
    //宠物(现在主要是切图时宠物携带)
    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->GetAttrObjID_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::StartGame(int mapChannelId)
{
    auto plchannel = m_vecPlayerChannel[mapChannelId];
    //上线通知好友
    m_pRelationOpt->ActorOnline(plchannel);
    int missionid = -1;
    auto& misison_map = plchannel->m_pActorInfoEx->Mission_map;

    //这步应该是根据玩家任务状态发送跟新客户端玩家任务面板任务信息,关于lua后面再看
    ActorInfoExTemp* pAcInfoT = plchannel->m_pActorInfoEx;
    for(auto i = 0; i < MAX_MISSION_RCV_NUM; i++)
    {
        int id = pAcInfoT->GetAcceptedMissionId(i);
        if(pAcInfoT->GetIsOnTrack(i))
             m_pMission->GetLuaMissionPtr()->SendSavedTaskPanelMsg(m_nMapId, mapChannelId, id);
        if(pAcInfoT->GetMissionState(id) == ShuiHu::eMissionState_In)
        {
            m_pMission->GetLuaMissionPtr()->SetMissionFlag(m_nMapId,mapChannelId,id);
            missionid = id;
        }
    }
    

    //m_pMission->GetLuaMissionPtr()->ChangeMapClearMission(m_nMapId,mapChannelId,missionid);
//     for(int i = 2;i < 4;i++)
//      GetLuaMisson()->GetMUIMissionName(m_nMapId,mapChannelId, i);
      GetLuaMisson()->GetMUIMissionName(m_nMapId,mapChannelId, -1);

}

//经过激活之后附近玩家就可以看到玩家的动作和其他的状态信息,服务器也响应处理好了玩家的相关信息,表示玩家正式的加入地图了

 

posted @ 2015-01-19 02:12  zzyoucan  阅读(185)  评论(0编辑  收藏  举报