天龙八部AI战斗系统分析

加载好解析好脚本  生成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;

}




你可能感兴趣的:(天龙八部AI战斗系统分析)