Beispiel #1
0
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 ;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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();
}
Beispiel #6
0
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;
}
Beispiel #7
0
void BipedManager::TransitionWalkIdleToIdle()
{
    mState = ANIM_IDLE;
    DoIdle();
}