void KDoodad::ChangeState(DOODAD_STATE eState) { BOOL bRetCode = FALSE; switch(eState) { case dsIdle: DoIdle(); break; case dsBeHit: DoBeHit(); break; case dsAfterHit: DoAfterHit(); break; case dsRemove: // bRetCode = g_SO3World.RemoveDoodad(this); // KGLOG_CHECK_ERROR(bRetCode); //#ifdef _CLIENT // bRetCode = g_SO3World.DelDoodad(this); // KGLOG_CHECK_ERROR(bRetCode); //#endif //_CLIENT break; default: KGLOG_PROCESS_ERROR(FALSE); } return ; Exit0: return ; }
void KAIBase::OnReturn(void) { int nRetCode = cmsInvalid; BOOL bRetCode = FALSE; bRetCode = CheckReturn(); KG_PROCESS_SUCCESS(bRetCode); nRetCode = m_pSelf->m_eMoveState; if (nRetCode == cmsOnStand) { int nDir = g_GetDirection(m_pSelf->m_nX, m_pSelf->m_nY, m_nReturnX, m_nReturnY); m_pSelf->Turn(nDir, true, true); // 跑回ReturnPoint //KGLogPrintf(KGLOG_DEBUG, "[AI] Return Run to (%d, %d)\n", m_nReturnX, m_nReturnY); m_pSelf->RunTo(m_nReturnX, m_nReturnY); } return; Exit1: //返回原点了,停一秒 if (m_pNpcTeam) DoWait(); else DoIdle(GAME_FPS); return; }
void KAIBase::OnIdle(void) { BOOL bRetCode = FALSE; bRetCode = CheckAttacked(); KG_PROCESS_SUCCESS(bRetCode); bRetCode = CheckTargetInAlertRange(); KG_PROCESS_SUCCESS(bRetCode); bRetCode = CheckTargetInAttackRange(); KG_PROCESS_SUCCESS(bRetCode); KGLOG_PROCESS_ERROR(m_pSelf); if (g_pSO3World->m_nGameLoop >= m_IdleData.nIdleFrameCount) { //根据之前的状态恢复工作 switch(m_eAIMainState) { case aisInvalid: KGLOG_CHECK_ERROR(!"Invalid main state!"); break; case aisIdle: //当Npc站立的时候,调整Npc的方向 if (m_pSelf->m_eMoveState == cmsOnStand && m_pSelf->m_nFaceDirection != m_nOriginDirection) { bRetCode = m_pSelf->Turn(m_nOriginDirection, true, true); KGLOG_PROCESS_ERROR(bRetCode); } break; case aisWander: DoWander(); break; case aisPatrol: DoPatrol(); break; case aisFollow: DoFollow(); break; default: KGLOG_CHECK_ERROR(FALSE); DoIdle(); break; } return; } Exit1: return; Exit0: return; }
void KAIBase::OnAlert(void) { KCharacter* pTarget = NULL; BOOL bRetCode = FALSE; bRetCode = m_pSelf->m_SelectTarget.GetTarget(&pTarget); KG_PROCESS_ERROR(bRetCode && pTarget); if (pTarget) { //目标超出范围 int nDistance2 = g_GetDistance2(m_pSelf->m_nX, m_pSelf->m_nY, pTarget->m_nX, pTarget->m_nY); //按等级修正距离 int nCheckDistance2 = (int)(m_pAIParam->nAlertRange * m_pAIParam->nAlertRange); KG_PROCESS_ERROR(nDistance2 <= nCheckDistance2); //朝向目标 int nDirection = g_GetDirection(m_pSelf->m_nX, m_pSelf->m_nY, pTarget->m_nX, pTarget->m_nY); if (m_pSelf->m_nFaceDirection != nDirection) { m_pSelf->Turn(nDirection, true, true); } //目标未丢失, 看是否超时 if (g_pSO3World->m_nGameLoop > m_AlertData.nAlartFrame) { //超时,进行攻击 m_pSelf->m_ThreatList.ModifyThreat(pTarget, 0); TurnToFight(); return; } } bRetCode = CheckTargetInAttackRange(); KG_PROCESS_SUCCESS(bRetCode); return; Exit0: bRetCode = CheckTargetInAttackRange(); KG_PROCESS_SUCCESS(bRetCode); //什么都没有了,出警戒状态,开始发呆 ClearTarget(); DoIdle(1); return; Exit1: return; }
void BipedManager::Initialize(int idleWalkCount, int walkCount, int walkRunCount) { mState = ANIM_IDLE; mCount = 0; mCountMax[ANIM_IDLE] = 0; mCountMax[ANIM_IDLE_WALK] = idleWalkCount; mCountMax[ANIM_WALK] = mCountMax[ANIM_IDLE_WALK] + walkCount; mCountMax[ANIM_WALK_RUN] = mCountMax[ANIM_WALK] + walkRunCount; mCountMax[ANIM_RUN] = mCountMax[ANIM_WALK_RUN]; mWeight = 0.0f; mDeltaWeight0 = 1.0f / static_cast<float>(idleWalkCount); mDeltaWeight1 = 1.0f / static_cast<float>(walkRunCount); DoIdle(); }
void KAIBase::OnPathResult(BOOL bSucceed) { BOOL bRetCode = FALSE; int nMoveState = 0; KG_PROCESS_ERROR(m_pSelf); nMoveState = m_pSelf->getMoveState(); KG_PROCESS_ERROR(nMoveState != cmsOnDeath); //KGLogPrintf(KGLOG_DEBUG, "[AI] path event : %d , frame : %d\n", bSucceed, g_pSO3World->m_nGameLoop); switch (m_eAIState) { case aisIdle: break; case aisWander: if (bSucceed) { // 闲逛一段距离,发一下呆 DoIdle(m_pAIParam->nWanderInterval); } else { // 强制往回走。 Wander(true); } break; case aisPatrol: if (bSucceed) { // 如果成功了,则发一会儿呆再说 if (m_pNpcTeam && m_pNpcTeam->m_pLeader != m_pSelf) { //在Npc队伍中且不是Leader OnPartol(); } else { int nPatrolID = ((KNpc*)m_pSelf)->m_AIData.m_nPatrolPathID; KG_PROCESS_ERROR(nPatrolID); KPatrolPath* pPatrolPath = g_pSO3World->m_Settings.m_PatrolPathList.GetPatrolPath(m_pSelf->m_pScene->m_dwMapID, nPatrolID); int nRestFrame = 0; int nFaceTo = -1; if(pPatrolPath) { KPatrolNode rPatrolNode; int nIndex = 0; int nMemberCount = 0; if (m_pNpcTeam) { nMemberCount = m_pNpcTeam->GetMemberCount(); for (nIndex = 0; nIndex < nMemberCount; nIndex++) { KNpc* pMember = m_pNpcTeam->GetMember(nIndex); if (pMember && pMember->m_pScene) { pMember->m_AIController.SetPatrolPath(nPatrolID, m_nNextPartolIndex + 1); } } } else { m_nNextPartolIndex++; } bRetCode = pPatrolPath->GetPoint(m_nNextPartolIndex - 1, rPatrolNode); if (bRetCode) { nRestFrame = rPatrolNode.nRestFrame; nFaceTo = rPatrolNode.nFaceTo; //触发Npc寻路到达的脚本 if (rPatrolNode.szScriptName[0] != '\0') { bRetCode= g_pSO3World->m_ScriptCenter.IsScriptExist(rPatrolNode.szScriptName); if (bRetCode && g_pSO3World->m_ScriptCenter.IsFuncExist(rPatrolNode.szScriptName, SCRIPT_ON_PATROL)) { int nTopIndex = 0; g_pSO3World->m_ScriptCenter.SafeCallBegin(&nTopIndex); g_pSO3World->m_ScriptCenter.PushValueToStack((KNpc*)m_pSelf); g_pSO3World->m_ScriptCenter.PushValueToStack(m_nNextPartolIndex); //Lua的索引从1开始编号,所以不-1 g_pSO3World->m_ScriptCenter.CallFunction(rPatrolNode.szScriptName, SCRIPT_ON_PATROL, 0); g_pSO3World->m_ScriptCenter.SafeCallEnd(nTopIndex); } } } KG_PROCESS_ERROR(m_pSelf->m_pScene && m_pSelf->m_pCell && m_pSelf->m_eMoveState != cmsOnDeath); //Npc可能在脚本中被删除,所以调用脚本之后要判断下 if (m_nNextPartolIndex >= pPatrolPath->GetPointCount()) m_nNextPartolIndex = 0; } if (nFaceTo >= 0 && nRestFrame > 0) { m_pSelf->Turn(nFaceTo, true, true); } DoIdle(nRestFrame); } } else { /* // 如果寻路失败了,则换个方向再来 int nDirection = m_pSelf->m_nFaceDirection + 40; if (nDirection >= DIRECTION_COUNT) nDirection -= DIRECTION_COUNT; KGLOG_PROCESS_ERROR(nDirection >= 0 && nDirection < DIRECTION_COUNT); m_pSelf->Turn(nDirection); DoPatrol(); */ } break; case aisAlert: break; case aisFollow: if (bSucceed) { OnFollow(); } break; case aisPursuit: if (bSucceed) { OnPursuit(); } else { //For Debug //KGLogPrintf(KGLOG_DEBUG, "[AI] 追击中寻路失败\n"); } break; case aisEscape: if (bSucceed) { // 到了目标点,等一下,接着逃 m_EscapeData.nEscapeIdleFrame = g_pSO3World->m_nGameLoop + m_pAIParam->nEscapeInterval; m_pSelf->Stop(); OnEscape(); } break; case aisReturn: if (!bSucceed) { //返回时寻路失败,传送 bRetCode = IS_PLAYER(m_pSelf->m_dwID); KG_ASSERT_EXIT(!bRetCode); KG_ASSERT_EXIT(m_pSelf->m_pScene); m_pSelf->MoveTo(m_nReturnX, m_nReturnY, m_nReturnZ); m_ReturnData.nReturnFrame = -1; m_pSelf->Stop(); m_pSelf->m_ThreatList.ClearAllThreat(); } else { m_ReturnData.nReturnFrame = -1; } break; case aisWait: break; default: KGLOG_PROCESS_ERROR(FALSE); break; } Exit0: return; }
void BipedManager::TransitionWalkIdleToIdle() { mState = ANIM_IDLE; DoIdle(); }