加载好解析好脚本 生成AI脚本行为树 方便搜索 提高效率
BOOL AIScript::CreateCdtTree(VOID)
{
__ENTER_FUNCTION
m_pcdtTree = NULL;
if (m_poptorNodeList == NULL && m_pcdtNodeList == NULL)
{
return FALSE;
}
//生成新的条件树的根节点
ConditionTree* pRoot = NULL;
pRoot = new ConditionTree;
if(pRoot == NULL)
{
Assert(FALSE);
return FALSE;
}
//第一步,根据操作符list生成树框架
TreeNodeList* pList = m_poptorNodeList;
while(pList)
{
//new出一个新的树结点
ConditionTree* pNewTree = NULL;
pNewTree = new ConditionTree;
if (pNewTree == NULL)
{
Assert(FALSE);
return FALSE;
}
//进行插入操作-->是第一次插入
if(m_pcdtTree == NULL)
{
//根节点不进行赋值
m_pcdtTree = pRoot;
//将list表中的Node复制一份到pNewTree;
pNewTree->Node = pList->Node;
m_pcdtTree->pLeft = pNewTree;
pNewTree->pParent = pRoot;
}
else
{
//从根节点的左子节点寻找位置
ConditionTree* pCur = pRoot->pLeft;
ConditionTree* pParent = NULL;
while(pCur)
{
pParent = pCur;
if (pList->Node.pos > pCur->Node.pos)
{
pCur = pCur->pRight;
}
else
{
pCur = pCur->pLeft;
}
}
pNewTree->Node = pList->Node;
if (pNewTree->Node.pos>pParent->Node.pos)
{
pParent->pRight = pNewTree;
}
else
{
pParent->pLeft = pNewTree;
}
pNewTree->pParent = pParent;
}
pList = pList->pNext;
}
//第二步,根据条件表达式list生成完整的条件树
pList = m_pcdtNodeList;
while (pList)
{
//new出一个新的树结点
ConditionTree* pNewTree = NULL;
pNewTree = new ConditionTree;
if(pNewTree == NULL)
{
Assert(FALSE);
return FALSE;
}
//进行插入操作-->是第一次插入
//该情况只有当条件表达式为if(HP<10)这样的时候才能进入
if (m_pcdtTree==NULL)
{
//根节点不进行赋值
m_pcdtTree = pRoot;
//将list表中的Node复制一份到pNew;
pNewTree->Node = pList->Node;
m_pcdtTree->pLeft = pNewTree;
pNewTree->pParent = pRoot;
}
else
{
//从根节点的左子节点寻找位置
ConditionTree* pCur = pRoot->pLeft;
ConditionTree* pParent=NULL;
while (pCur)
{
pParent = pCur;
if (pList->Node.pos>pCur->Node.pos)
{
pCur = pCur->pRight;
}
else
{
pCur = pCur->pLeft;
}
}
pNewTree->Node = pList->Node;
if (pNewTree->Node.pos>pParent->Node.pos)
{
pParent->pRight = pNewTree;
}
else
{
pParent->pLeft = pNewTree;
}
pNewTree->pParent = pParent;
}
pList = pList->pNext;
}
return TRUE;
__LEAVE_FUNCTION
return FALSE;
}
//处理脚本AI逻辑
BOOL AIScript::ProcessScript(INT nState, AI_Character* pAI)
{
__ENTER_FUNCTION
if (!pAI)
{
Assert(NULL && "AIScript::ProcessScript...pAI=NULL...");
return FALSE;
}
Obj_Character* pChar = pAI->GetCharacter();
if (pChar && pChar->GetObjType() != Obj::OBJ_TYPE_MONSTER)
{
Assert(NULL && "pAI->GetCharacter() != OBJ_TYPE_MONSTEr...");
return FALSE;
}
((AI_Monster*)pAI)->ReSetNeedGoDist();
//将m_pcdtList中的条件节点依次取出
ConditionList* pCur = NULL;
pCur = m_vStateLists[nState];
while(pCur)
{
BOOL ret = FALSE;
//判断条件是否成功,执行条件语句
//取出m_pcdtList中的ConditionTree,解析树结构
ConditionTree* pTree = NULL;
pTree = pCur->pNode->pRootCondition;
//将AI_xxx中的times的数据复制给相应的Node的times
INT id = pCur->pNode->id;
if (id >= AISCRIPT_NUM)
{
Assert(NULL && "id > AISCRIPT_NUM...array overflow...");
return FALSE;
}
pCur->pNode->times = ((AI_Monster*)pAI)->m_aAIScriptTimes[id];
if(pCur->pNode->times > 0 || pCur->pNode->times == -1)
{
ret = ExcuteCdtScript(pTree, pAI);
}
else
{
pCur = pCur->pNext;
continue;
}
//如果条件成立,则执行行为语句
//取出m_pcdtList中的pToDo,解析toDo结构
if (TRUE == ret)
{
ExcuteToDoScript(pCur->pNode->pToDo, pAI);
pCur->pNode->SetDownFlag(1);//设置该操作执行过
if (pCur->pNode->times > 0)
{// 只是不想改变原来的结构和逻辑 故这样做:)...
pCur->pNode->times--;
if (pCur->pNode->times < 0)
pCur->pNode->times = 0;
((AI_Monster*)pAI)->m_aAIScriptTimes[id]--;
if (((AI_Monster*)pAI)->m_aAIScriptTimes[id] < 0)
((AI_Monster*)pAI)->m_aAIScriptTimes[id] = 0;
}
if (pCur->pNode->times == 0)
{
pCur->pNode->SetDownFlag(0);//设置该操作执行完
}
//if (pAI->GetCharacter()->GetObjType() == Obj::OBJ_TYPE_MONSTER)
//{
// ((AI_Monster*)pAI)->SetSkillID(m_SkillID);
//}
return TRUE;
}
else
{
if (SKILLSECTION == nState)
{
if (pAI->GetCharacter()->GetObjType() == Obj::OBJ_TYPE_MONSTER)
{
ObjID_t idSkill = ((AI_Monster*)pAI)->GetSkillID();
FLOAT fTmpDist = ((AI_Monster*)pAI)->GetNeedGoDist(idSkill);
FLOAT fNeedGoDist = ((AI_Monster*)pAI)->GetNeedGoDist();
if (fTmpDist > 0 && fNeedGoDist > fTmpDist)
{
((AI_Monster*)pAI)->SetNeedGoDist(fTmpDist);
((AI_Monster*)pAI)->SetSkillID(idSkill);
}
}
}
}
pCur = pCur->pNext;
}
if (NULL == pCur)
{/** 一个也没有执行成功 */
return FALSE;
}
return TRUE;
__LEAVE_FUNCTION
return TRUE;
}