进入副本流程
- 读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_TRACE
ScriptParamList 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 then
return; -- 如果没人进入,则函数直接返回
end
if x3323_g_GameOver == 1 then
if x3323_g_EndTick > 0 then
x3323_CountDown(x3323_g_EndTick);
x3323_g_EndTick = x3323_g_EndTick - 1;
return;
else
C_LeveCopySceneAllPlayer();
x3323_g_Gameover = 2;
end;
return;
end;
x3323_g_CopyTime = x3323_g_CopyTime + elapse; --时间累加
if x3323_g_CopyTime >= x3323_g_EndTime then
x3323_CountDown(x3323_g_EndTick)
x3323_g_EndTick = x3323_g_EndTick -1;
else
x3323_InActiveness();
C_LeaveCopySceneAllPlayer();
x3323_g_GameOver = 2;
end
return;
end
if x3323_g_CurrentEnemyCount == 0 then
x3323_CreateNextEnemy();
end
end
可以看出对于游戏目前的状态,是否结束会进行不同的判断。 由于OnCopySceneTick是在服务器的Tick 过程中调用的,类似客户端的Update。
在其中进行游戏终止判定 和 生成敌人的操作(此副本中,定义一波敌人全部消灭后,生成下一波)