进入副本流程
- 读publicTables,
- OnOpenCopySceneOK()发包
private void OnOpenCopySceneOK(){GameManager.PlayerDataPool.CurSelectTier = m_curSelTier;CG_OPEN_COPYSCENE_PAK pak = new CG_OPEN_COPYSCENE_PAK();pak.data.SceneID = (int)SCENE_DEFINE.SCENE_TDBK;pak.data.Grade = (int)COPYSCENE_GRADE.GRADE1;pak.data.Mode = (int)COPYSCENE_MODE.SOLO;pak.data.EnterTier = m_curSelTier;pak.SendPacket();}
传入副本名称、难度等级、挑战模式(单人、组队形式)、当前副本层数(如果有)
- 服务器Obj_Player_CopyScene.cpp收包
uint_t Obj_Player::HandlePacket(const ProtbufPacket::CG_OPEN_COPYSCENE &rPacket)
{int32_t nSceneID = rPacket.sceneID();int32_t nMode = rPacket.mode();int32_t nGrade = CopySceneGrade::Grade1;//---非法包检测---//特殊副本判断--if(nSceneClassID == SCENECLASS_ID::SCENECLASS_ID_TDBK){OpenTdbkCopyScene(csi,nEnter,nEnterTier);}
}
<br />4.打开副本逻辑(服务器)
void Obj_Player::OpenTdbkCopyScene(const CopySceneInfo& rInfo,int32_t nEnterType,int32_t nEnterTier)
{//客户端请求层级错误判断if(nEnterTier <= 0 || nEnterTier >= TDBK_SCENE_OVER){//--- }//Return情况://玩家跳过当前关卡、玩家已经全部通关、玩家重复挑战以前的关卡//确定请求挑战层SetTDBKEnterTier(nEnterTier);OpenCopyScene(rInfo);}
<br />打开副本
void Obj_Player::OpenCopyScene(const CopySceneInfo& rInfo,bool bAutoAgree)
{//单人模式//货币扣除流程成功SyncCopySceneData(rInfo.m_nSceneID);CreateCopyScene();return ;
}
服务器GameServer::Routine线程在心跳中检测
发现ROUTINEMSG_IMPL(PlayerEnterSceneMsg)
会走void CopyScene::HandleMsg(const PlayerEnterSceneMsg& Msg)
void CopyScene::HandleMsg(const PlayerEnterSceneMsg& Msg)
{if(Obj_Player->curPlayer != nullptr){CopySceneInfo Info = curPlayer->GetCopySceneInfo();if(info.CheckValid(GetLocalTime() == CopySceneErrorInfo::INFO_OK)){//单人模式数据添加//组队模式数据添加}//断线重连保存现场RefixLevelWhenAccident(Info,curPlayer->GetLevel.m_nLevel);//Open(Info,ptr);}
}
<br />打开副本
void CopyScene::Open(const CopySceneInfo& rInfo)
{//缓存是否首次掉落//副本共战信息//加载Lua脚本Script_OnCopySceneOpen();
}
调用Lua脚本
void CopyScene::Script_OnCopySceneOpen()
{__SOL_TRACEScriptParamList oParamList;LuaCall(m_data.GetScriptID(),"OnCopySceneOpen",oParamList);SOL_TRACE__
}
Lua脚本
OnCopySceneOpen是玩家刚进入副本时调用,在镇魔古洞中
--npc
x3323_g_JuBaoPenNpc_ObjId = -1;--副本难度
_,x3323_g_CopyGrade, _, x3323_g_CopyLevel = C_GetCopySceneInfo() ; --副本心跳
function x3323_OnCopySceneTick(elapse)if x3323_g_IsPlayerEnter == 0 thenreturn; -- 如果没人进入,则函数直接返回endif x3323_g_GameOver == 1 thenif x3323_g_EndTick > 0 thenx3323_CountDown(x3323_g_EndTick);x3323_g_EndTick = x3323_g_EndTick - 1;return;elseC_LeveCopySceneAllPlayer();x3323_g_Gameover = 2;end;return;end;x3323_g_CopyTime = x3323_g_CopyTime + elapse; --时间累加if x3323_g_CopyTime >= x3323_g_EndTime thenx3323_CountDown(x3323_g_EndTick)x3323_g_EndTick = x3323_g_EndTick -1;elsex3323_InActiveness();C_LeaveCopySceneAllPlayer();x3323_g_GameOver = 2;endreturn;
endif x3323_g_CurrentEnemyCount == 0 thenx3323_CreateNextEnemy();
end
end
可以看出对于游戏目前的状态,是否结束会进行不同的判断。 由于OnCopySceneTick是在服务器的Tick 过程中调用的,类似客户端的Update。
在其中进行游戏终止判定 和 生成敌人的操作(此副本中,定义一波敌人全部消灭后,生成下一波)