Files
mir_server/server/LogicServer/config/SkillProvider.cpp
aixianling 5c9f1dae4a init
2025-01-09 17:45:40 +08:00

453 lines
14 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "StdAfx.h"
#include "SkillConfig.h"
#include "SkillProvider.h"
#include "../base/Container.hpp"
using namespace wylib::stream;
CSkillProvider::CSkillProvider()
:Inherited(), Inherited2(), m_DataAllocator(_T("SkillDataAlloc"))
{
}
CSkillProvider::~CSkillProvider()
{
}
bool CSkillProvider::LoadSkills(LPCTSTR sFilePath)
{
bool Result = false;
CMemoryStream ms;
CCustomLuaPreProcessor pp;
LPCTSTR sText;
try
{
//从文件加载配置脚本
if ( ms.loadFromFile(sFilePath) <= 0 )
showErrorFormat(_T("unable to load from %s"), sFilePath);
//对配置脚本进行预处理
GetLogicServer()->GetVSPDefine().RegisteToPreprocessor(pp);
sText = pp.parse((LPCTSTR)ms.getMemory(), sFilePath);
//设置脚本内容
if ( !setScript(sText) )
showError(_T("syntax error on skill config"));
//读取标准物品配置数据
Result = ReadAllSkills();
}
catch (RefString &s)
{
OutputMsg(rmError, _T("load skill config error: %s"), s.rawStr());
FILE* fp = fopen("scripterror.txt", "wb");
if (fp)
{
fputs(sText, fp);
fclose(fp);
}
}
catch (...)
{
OutputMsg(rmError, _T("unexpected error on load skill config"));
}
//销毁脚本虚拟机
setScript(NULL);
return Result;
}
bool CSkillProvider::ReadAllSkills()
{
int nDef_1 = 1;
int nDef_0 = 0;
int nDef_999 = 999;
bool bDef_false = false;
bool bDef_true = true;
//技能总表
if (openGlobalTable("SkillConf"))
{
//获取配置中的技能数量
INT_PTR nCount = lua_objlen(m_pLua, -1);
//如果物品数量为0则输出未配置任何物品的错误
if ( nCount <= 0 )
{
showError(_T("no skill data on Skill config"));
return false;
}
++nCount;
//预留数据空间
reserve(nCount);
trunc(nCount);
OneSkillData *pSkills = this->Inherited::operator OneSkillData* ();
//循环读取技能配置数据
if (enumTableFirst())
{
//INT_PTR nIdx = 0;
do
{
INT_PTR nSkillId = getFieldInt("id");
if (nSkillId >= nCount)
{
showErrorFormat(_T("skill id 过大 nSkillId:%d, nCount:%d"), nSkillId, nCount);
endTableEnum();
break;
}
OneSkillData * pSkill = &pSkills[nSkillId];
//if (nSkillId != ++nIdx)
//{
// showErrorFormat(_T("skill id 不按顺序递增 nSkillId:%d, nIdx:%d"), nSkillId, nIdx);
// endTableEnum();
// break;
//}
//构造
new(pSkill) OneSkillData();
pSkill->nSkillID = nSkillId; //技能的ID
getFieldStringBuffer("name",pSkill->sSkillName,sizeof(pSkill->sSkillName)); //读取技能名字
pSkill->bVocation = (BYTE)getFieldInt("vocation",&nDef_0); //职业
pSkill->nSkillType =(BYTE) getFieldInt("skillType"); //技能的类型
pSkill->bSkillClass = (BYTE) getFieldInt("skillClass",&nDef_1); //技能的分类
pSkill->bSingleEmptyEffect = getFieldBoolean("singleEffect",&bDef_false); //单体远程空地展示特效
pSkill->nCommonCdTime = getFieldInt("commonCd"); //使用的时候触发的公共的cd时间
pSkill->bSpecialBuffCond = (BYTE)getFieldInt("specialBuffCond",&nDef_0); //特殊buff条件
pSkill->bBeedCalPassiveProperty = getFieldBoolean("needCalPassiveProperty",&bDef_true); //是否需要计算被动属性
pSkill->bPriority = (BYTE)getFieldInt("priority",&nDef_0); //优先级
pSkill->btClientDir = (BYTE)getFieldInt("direction",&nDef_0); //使用客户端方向
pSkill->wAttrId = (WORD)getFieldInt("attrid",&nDef_0); //属性id
pSkill->bIsSwitch = (BYTE) (getFieldBoolean("isSwitch",&bDef_false) ?1:0); //是否手动开关
pSkill->bIsAutoLearn = getFieldBoolean("isAutoLearn",&bDef_false);
pSkill->nAutoLearnSkillLvl = getFieldInt("autoLearnSkillLvl",&nDef_999);
pSkill->boIsDelete = getFieldBoolean("isDelete",&bDef_false);
switch (pSkill->bVocation)
{
case enVocNone:
m_None.push_back(pSkill);
break;
case enVocWarrior:
m_Warrior.push_back(pSkill);
break;
case enVocMagician:
m_Magician.push_back(pSkill);
break;
case enVocWizard:
m_Wizard.push_back(pSkill);
break;
}
}
while (enumTableNext());
}
closeTable();//end SkillConfig
} else return false;
// 作用范围表
static DataList<SKILLONERANGE> s_SkillRanges;
if (openGlobalTable("SkillRangesConf"))
{
const INT_PTR nActRangeCount = lua_objlen(m_pLua, -1) + 1;
s_SkillRanges.count = 0;
if ( nActRangeCount > 1 )
{
s_SkillRanges.count = nActRangeCount;
s_SkillRanges.pData = (PSKILLONERANGE)m_DataAllocator.allocObjects(nActRangeCount * sizeof(SKILLONERANGE));
if ( enumTableFirst() )
{
//INT_PTR nIdx = 0;
SKILLONERANGE *pBase = (PSKILLONERANGE)s_SkillRanges.pData;
do
{
INT_PTR nRangeId = getFieldInt("id");
//if (nRangeId != ++nIdx)
//{
// showErrorFormat(_T("nRangeId Error id非递增nRangeId:%d, nIdx:%d"), nRangeId, nIdx);
// return false;
//}
SKILLONERANGE * pRange = pBase + nRangeId;
{
pRange->nStartX = (int)getFieldInt("xStart",&nDef_0);
pRange->nEndX = (int)getFieldInt("xEnd",&nDef_0);
pRange->nStartY = (int)getFieldInt("yStart",&nDef_0);
pRange->nEndY = (int)getFieldInt("yEnd",&nDef_0);
pRange->rangeType = (int)getFieldInt("rangeType",&nDef_0);
pRange->rangeCenter = (int)getFieldInt("rangeCenter",&nDef_0);
pRange->nForceHitTargetDis = (int)getFieldInt("forceHitTargetDis",&nDef_0);
pRange->nDelay = getFieldInt("delay",&nDef_0);
//目标筛选条件
if ( feildTableExists("conds") && openFieldTable("conds") )
{
const INT_PTR nCount = lua_objlen(m_pLua, -1);
pRange->targetConditions.count = 0;
if ( nCount > 0 )
{
pRange->targetConditions.count = nCount;
pRange->targetConditions.pData =(PTARGETSELCONDITION)m_DataAllocator.allocObjects(nCount * sizeof(TARGETSELCONDITION));
if ( enumTableFirst() )
{
INT_PTR nIdx = 0;
PTARGETSELCONDITION pBase =(PTARGETSELCONDITION)pRange->targetConditions.pData;
do
{
TARGETSELCONDITION * pCondiition = pBase + nIdx;
pCondiition->nKey =(int)getFieldInt("cond");
int nValue = getFieldInt("param",&nDef_0);
if(nValue)
{
pCondiition->value.wLo = (WORD)getFieldInt("value",&nDef_0);
pCondiition->value.wHi = (WORD)nValue;
}
else
{
pCondiition->value.nValue = getFieldInt("value",&nDef_0);
}
nIdx++;
}
while (enumTableNext());
}
}
closeTable();
}
//读取技能结果
if ( feildTableExists("results") && openFieldTable("results") )
{
const INT_PTR nCount = lua_objlen(m_pLua, -1);
pRange->skillResults.count = 0;
if ( nCount > 0 )
{
pRange->skillResults.count = nCount;
pRange->skillResults.pData =(SKILLRESULT *) m_DataAllocator.allocObjects(sizeof(SKILLRESULT) *nCount);
if ( enumTableFirst() )
{
INT_PTR nIdx = 0;
SKILLRESULT *pBase = pRange->skillResults.pData;
do
{
SKILLRESULT * pResult = pBase + nIdx;
//读取1个等级的数据
int nDef = 0;
pResult->nId = getFieldInt("id",&nDef);
pResult->nValue = getFieldInt("value",&nDef);
pResult->nDelay = getFieldInt("delay",&nDef);
pResult->nResultType = getFieldInt("resultType",&nDef);
pResult->nParam1 = getFieldInt("param1",&nDef);
pResult->nParam2 = getFieldInt("param2",&nDef);
pResult->nParam3 = getFieldInt("param3",&nDef);
pResult->nParam4 = getFieldInt("param4",&nDef);
pResult->nParam5 = getFieldInt("param5",&nDef);
pResult->nParam6 = getFieldInt("param6",&nDef);
pResult->ignoreTargetDis=(BYTE)getFieldInt("ignoreTargetDis",&nDef); //是否忽视和目标的距离
pResult->bBuffType = (BYTE)getFieldInt("buffType",&nDef);
nIdx++;
}
while (enumTableNext());
}
}
closeTable();
}
}
}
while (enumTableNext());
}
}
closeTable();//end ActionRanges
} else return false;
//技能等级总表
if (openGlobalTable("SkillsLevelConf"))
{
OneSkillData *pSkills = this->Inherited::operator OneSkillData* ();
INT_PTR nSkillCount = this->Inherited::count();
for (size_t nSkillId = 1; nSkillId < nSkillCount; nSkillId++)
{
//对应技能
OneSkillData * pSkill = &pSkills[nSkillId];
if (pSkill->nSkillID != nSkillId)
{
showErrorFormat(_T("unexpected skill id %d, %d expected"), pSkill->nSkillID, nSkillId);
return false;
}
//打开对应技能的等级表
if(getFieldIndexTable(nSkillId))
{
// 分配该技能的等级空间
const INT_PTR nLevelCount = (INT_PTR)lua_objlen(m_pLua, -1) + 1;
pSkill->levels.count = nLevelCount;
SKILLONELEVEL *pBaseLevel = pSkill->levels.pData =(PSKILLONELEVEL)m_DataAllocator.allocObjects(nLevelCount * sizeof(SKILLONELEVEL));
// 遍历各个等级
if (enumTableFirst())
{
//INT_PTR nLevelIdx = 0;
do
{
INT_PTR nSkillId = getFieldInt("id");
if (pSkill->nSkillID != nSkillId)
{
showErrorFormat(_T("nSkillId Error id:%d, nSkillId:%d"), pSkill->nSkillID, nSkillId);
return false;
}
INT_PTR nLevel = getFieldInt("level");
//if (nLevel != ++nLevelIdx)
//{
// showErrorFormat(_T("nSkillLevel Error nLevel:%d, nLevelIdx:%d"), nLevel, nLevelIdx);
// return false;
//}
SKILLONELEVEL * pLevel = pBaseLevel + nLevel;
// 技能等级基本信息
{
pLevel->nLevel = nLevel; //技能等级
pLevel->nSingTime = getFieldInt("delayTime", &nDef_0); //延迟时间
pLevel->nCooldownTimes = getFieldInt("cooldownTime", &nDef_0); //冷却时间
pLevel->nAttrIdx = getFieldInt("attrIdx", &nDef_1); //技能增加的属性索引不是results
pLevel->isSceneEffect = getFieldInt("isSceneEffect", &nDef_0) ? true:false; //是否为场景特效
pLevel->nHitId = getFieldInt("hitId", &nDef_0); //技能特效
pLevel->nMaxPet = getFieldInt("maxpet", &nDef_0); //诱惑最大抓取宠物数
}
bool bDef = true;
// 施法条件
if ( feildTableExists("spellConds") && openFieldTable("spellConds") )
{
const INT_PTR nSpellCondsCount = (INT_PTR)lua_objlen(m_pLua, -1);
if ( nSpellCondsCount <= 0 )
{
pLevel->spellConditions.count =0;
}
else
{
pLevel->spellConditions.count = nSpellCondsCount;
pLevel->spellConditions.pData =(PSKILLTRAINSPELLCONDITION)m_DataAllocator.allocObjects(nSpellCondsCount *sizeof(SKILLTRAINSPELLCONDITION));
if ( enumTableFirst() )
{
INT_PTR nSpellCondsIdx = 0;
SKILLTRAINSPELLCONDITION *pBase = pLevel->spellConditions.pData;
do
{
bool boFalse = false;
SKILLTRAINSPELLCONDITION * pCondition = pBase + nSpellCondsIdx;
pCondition->nConditionID = (BYTE)getFieldInt("cond"); //条件类型
pCondition->nValue = getFieldInt64("value"); //值
pCondition->bConsumed =(BYTE)( getFieldBoolean("consume",&boFalse) ? 1 :0 ); //是否消耗
pCondition->nCount = getFieldInt("count",&nDef_0);
nSpellCondsIdx++;
}
while (enumTableNext());
}
}
closeTable();
}//end spellConds
// 升级条件
if ( feildTableExists("upgradeConds") && openFieldTable("upgradeConds") )
{
const INT_PTR nUpgradeCondsCount = lua_objlen(m_pLua, -1);
if ( nUpgradeCondsCount <= 0 )
{
pLevel->trainConditions.count =0;
}
else
{
pLevel->trainConditions.count = nUpgradeCondsCount;
pLevel->trainConditions.pData = (PSKILLTRAINSPELLCONDITION)m_DataAllocator.allocObjects(nUpgradeCondsCount *sizeof(SKILLTRAINSPELLCONDITION));
if ( enumTableFirst() )
{
INT_PTR nUpgradeCondsIdx = 0;
SKILLTRAINSPELLCONDITION *pBase =(PSKILLTRAINSPELLCONDITION)pLevel->trainConditions.pData;
do
{
SKILLTRAINSPELLCONDITION * pCondition = pBase + nUpgradeCondsIdx;
pCondition->nConditionID = (BYTE)getFieldInt("cond"); //条件类型
pCondition->nValue = getFieldInt64("value"); //值
pCondition->bConsumed =(BYTE)( getFieldBoolean("consume") ? 1 :0 ); //是否消耗
pCondition->nCount = getFieldInt("count",&nDef_1);
nUpgradeCondsIdx++;
}
while (enumTableNext());
}
}
closeTable();
}//end upgradeConds
// 技能效果范围
if ( feildTableExists("actRange") && openFieldTable("actRange") )
{
const INT_PTR nActRangeCount = lua_objlen(m_pLua, -1);
pLevel->pranges.count = 0;
if ( nActRangeCount > 0 )
{
pLevel->pranges.count = nActRangeCount;
PSKILLONERANGE *pBase = pLevel->pranges.pData = (PSKILLONERANGE*)m_DataAllocator.allocObjects(nActRangeCount * sizeof(PSKILLONERANGE));
if ( enumTableFirst() )
{
INT_PTR nIdx = 0;
do
{
int id = getFieldInt(NULL);
PSKILLONERANGE * pRange = pBase + nIdx;
if(id >= s_SkillRanges.count)
{
showErrorFormat(_T("RangeId Error nIdx:%d, id:%d"), nIdx, id);
return false;
}
*pRange = (PSKILLONERANGE)(s_SkillRanges.pData) + id;
nIdx++;
}
while (enumTableNext());
}
}
closeTable();
}//end actRange
}
while (enumTableNext());
}
closeTable();//end SkillsLevelConfig[nSkillId]
}
else
{
OutputMsg(rmError, "open SkillsLevelConfig[%d] failed", nSkillId);
return false;
}
}
closeTable();//end SkillsLevelConfig
} else return false;
OutputMsg(rmTip,_T("Load skill Finished"));
return true;
}
void CSkillProvider::showError(LPCTSTR sError)
{
m_sLastErrDesc = sError;
RefString s = _T("[Config Error]");
s += sError;
throw s;
}