Lastbattle | 游戏场景服务器SS解析
游戏场景服务器概况
指令对应的处理handle的文件:SSBattleMgr.cpp
创建战场
- 指令: eMsgToSSFromCS_CreateBattle
- GC服务器发往SS fromCS 收到中心服务器CS创建站场的指令,在函数
INT32 CSSBattleMgr::OnMsgFromCS_CreateBattle(const char* pData, int n32DataLength)
中创建站场成功后,加入到战场管理器中:
m_cAllBattleMap[pBattle->GetBattleID()] = pBattle;
发送创建结果给CS服务器
CSSWorkThreadMgr::GetInstance().PostMsgToCS(sMsg, sMsg.mgsid());
发送可以进入战场的消息给客户端
CSSWorkThreadMgr::GetInstance().PostMsgToGCLIULU((*iter)->GetUserNetInfo(), sMsgBattle, sMsgBattle.msgid());
英雄移动
- 指令:eMsgToGSToSSFromGC_AskMoveDir,eMsgToGSToSSFromGC_AskStopMove
- GSToSS: 客户端发往SS,fromGC
收到客户端发来的移动信息,
GCToSS::MoveDir
, 转化为服务器能识别的参数CVector3D
, 开始计算客户端移动的位置
CVector3D pcDir(pMoveDir->dir().x(), 0, pMoveDir->dir().z());
m_pMsgBattle->AskMoveDir(m_pMsgUser, pcDir);
开始按照方向移动:
bool CSSMoveMgr::AskStartMoveDir(ISSMoveObject* pMObject, ColVector dir)
{<!-- -->
...
//计算下一个100毫秒后的位置
pMObject->CalculateStepMoveTarget(now + 100);
//检查是否会直接撞墙
if(FALSE == TestNextStepMove(pMObject)){<!-- -->
if(FALSE == TryTurnDir(pMObject)){<!-- -->
pMObject->Stop(now,FALSE);
return FALSE;
}
}
pMObject->OnStartMove(pMObject->GetDir());
}
INT32 CSSGameUnit::BeginAction_Move(const CVector3D &crsDir, bool bIfNotifyGC){<!-- -->}
同步移动状态到客户端
pcCurBattle->SyncState(this);
...
SendMsgToAllWatcher(*sMsg, msgid, pcGO);
...
CSSWorkThreadMgr::GetInstance().PostMsgToGCLIULU(watcherArray[i]->GetUserNetInfo(), sMsg, n32MsgID);
INT32 CSSBattle::SyncState(CSSGameUnit *pcGO, bool spot){<!-- -->}
void CSSBattle::SendMsgToAllWatcher(google::protobuf::Message& sMsg, int n32MsgID, CSSGameUnit* pGU){<!-- -->}
英雄技能
- 指令:eMsgToGSToSSFromGC_AskBuyGoods- GSToSS:客户端发往SS,fromGC
SS服务器接收到请求释放技能的指令
eMsgToGSToSSFromGC_AskBuyGoods
, 转化数据为GCToSS::UseSkill
格式 :
boost::shared_ptr<GCToSS::UseSkill> pUseSkill = ParseProtoMsgWithNewMemory<GCToSS::UseSkill>(pData, n32DataLength);
INT32 nret = m_pMsgBattle->AskUseSkill(m_pMsgUser, pUseSkill->skillid());
请求释放技能:
INT32 CSSAI_Hero::AskUseSkill(UINT32 un32SkillID) {<!-- -->}
//检查是否是不能操作状态
//检查是否被沉默了
//检查是否在吸附中,如果是,不能使用技能
//获取并检查技能是否存在
//检查技能是否符合可用条件
//检查是否是正在运行的技能
开始使用技能
pSkill->Start();
```cpp
准备技能的配置
```cpp
void CSSSkill::MakeSkillEffect(TIME_MILSEC tUTCMilsec){
...
pcCurBattle->GetEffectMgr()->AddEffectsFromCfg((SSNextSkillEffectCfg*)cpsCfg->asSkillModelList, pcMasterGU.get(), pcTarGU.get(), cPos, pcMasterGU->GetCurDir(), this, tUTCMilsec);
}
从配置中添加技能
INT32 CSSEffectMgr::AddEffectsFromCfg(SSNextSkillEffectCfg* pEffectCfg, CSSGameUnit* pMaster, CSSGameUnit* pTarget, CVector3D cPos, CVector3D cDir
, CSSSkill* pSkill, TIME_MILSEC beginTime, CSSGameUnit* pStartSkillGU){<!-- -->
...
AddEffect(pEffect);
}
添加效果到管理器中
INT32 CSSEffectMgr::AddEffect(CSSSkillEffect* pEffect) {<!-- -->
...
//尝试使用效果的启动方法。如果启动成功,将其加入正在运行的技能列表中
if(eNormal == pEffect->Begin()){<!-- -->
//if (FALSE == pEffect->m_pCfg->bIsCanMove){<!-- -->
pEffect->AddSelfToUsingList();
//}
m_UpdateEffectMap[pEffect->m_un32UniqueID] = pEffect;
}
//如果效果启动失败,检查其是否会开始计算技能CD,然后结束技能。
else{<!-- -->
pEffect->CheckCooldown();
pEffect->End();
DestroyAFreeSkillEffect(pEffect);
return eEC_AddEffectFailed;
}
...
}
//正在运行的效果列表
m_UpdateEffectMap
对应的技能在如下图所示的文件中
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uoAAHV02-1609600677855)(https://s3.ax1x.com/2021/01/02/spS5KH.png)]
- SSSkillEffect_Buf.cpp: 附加的buff技能
- SSSkillEffect_Fly.cpp: 飞行技能
- …
装备买卖
- 买装备指令:eMsgToGSToSSFromGC_AskBuyGoods
- 卖商品指令:eMsgToGSToSSFromGC_AskSellGoods
- 释放装备技能:eMsgToGSToSSFromGC_AskUseGoods
- GSToSS: 客户端发往SS,fromGC
商品配置
目录:
- 商品组合:CSBattleMgr/CombineCfg.xml
- 商品描述:CSBattleMgr/ItemCfg.xml
商品配置描述: |attributeKeyList / attributeValList|描述 |—— |5 / 10|+10 物理攻击 |6 / 35|+35点魔法攻击 |7 / 20|+20 点物理防御 |8 / 25|+25点魔法防御 |9 / 60|+60点移动速度 |10 / 200|+200生命值 |11 / 200|+200生命值 |12 / 150|+150魔法值 |13 / 2000|+2点/秒生命回复
attributeKeyLi
: 占位attributeValList
: 值n32CPCost
: 金币
举例
<info un32GoodsID="30038">
<sNameID>spe_item_HP</sNameID>
<sNameCh>神果</sNameCh>
<un8TypeID>3</un8TypeID>
<attributeKeyList>6</attributeKeyList>
<attributeValList>65</attributeValList>
<attributePerList>0</attributePerList>
<un8UseTimes>0</un8UseTimes>
<bDestroyAfterUsed>0</bDestroyAfterUsed>
<un32SkillID>0</un32SkillID>
<un32PassSkillID>0</un32PassSkillID>
<bIsCanDeathToBuy>1</bIsCanDeathToBuy>
<bUsedAfterBuyed>0</bUsedAfterBuyed>
<sIcon>Dicon038</sIcon>
<un32CdTime>0</un32CdTime>
<bUniqueID>0</bUniqueID>
<un8OverlapTimes>1</un8OverlapTimes>
<un8CPCostType>1</un8CPCostType>
<n32CPCost>800</n32CPCost>
<n32CombineCPCost>200</n32CombineCPCost>
<un8FunctionType>0</un8FunctionType>
<un32UniqueTypeID>0</un32UniqueTypeID>
<sDescribe>+65点魔法攻击</sDescribe>
<un32UseSoundID>0</un32UseSoundID>
</info>
神果+65点魔法攻击, 售价是800金币。
整个服务器的心跳
心跳的作用:
- 检查掉线时间。如果玩家掉线超过30秒,则将其AI替换为机器人AI
- 技能心跳- 移动心跳- NPC和hero的心跳
void CSSBattle::DoPlayHeartBeat(TIME_MILSEC tUTCMilsec, TIME_TICK tTickSpan){<!-- -->
...
//移动心跳
m_pMoveMgr->OnHeartBeat(tUTCMilsec, tTickSpan);
for (GameObjectMap::iterator iterObj = m_cGameObjectMap.begin(); iterObj != m_cGameObjectMap.end(); ++iterObj){<!-- -->
//NPC和hero的心跳
iterObj->second->OnHeartBeat(tUTCMilsec, tTickSpan);
}
...
//技能心跳
m_pEffectMgr->OnHeartBeat(tUTCMilsec, tTickSpan);
m_pPassiveSkillMgr->OnHeartBeat(tUTCMilsec, tTickSpan);
m_pSightMgr->OnHeartBeat(tUTCMilsec, tTickSpan);
...
}
--完--
- 原文作者: 留白
- 原文链接: https://zfunnily.github.io/2021/01/lastbattle/
- 更新时间:2024-04-16 01:01:05
- 本文声明:转载请标记原文作者及链接