예제 #1
0
파일: KAIBase.cpp 프로젝트: 1suming/pap2
void KAIBase::DoReturn()
{
	//KGLogPrintf(KGLOG_DEBUG, "[AI State] {%s} Turn to Return\n", m_pSelf->m_szName);
	SetAIInterval(1.0);
	m_ReturnData.nReturnFrame = g_pSO3World->m_nGameLoop + AI_RETURN_OVERTIME_FRAME;
	m_pSelf->Stop();
	
#ifdef _SERVER
	//清除仇恨
	m_pSelf->m_ThreatList.ClearAllThreat();

	//清除DEBUF
	//m_pSelf->m_BuffList.DeathClean();

	//设置无敌
	m_pSelf->m_bSystemShield = true;
#endif
	SetAIState(aisReturn);

#ifdef _SERVER
	TurnToIdle();
#endif //_SERVER

	OnReturn();
}
예제 #2
0
파일: KAIBase.cpp 프로젝트: 1suming/pap2
void KAIBase::DoPatrol()
{
	//KGLogPrintf(KGLOG_DEBUG, "[AI State] {%s} Turn to Patrol\n", m_pSelf->m_szName);
	if (IS_NPC(m_pSelf->m_dwID))
	{
		SetAIState(aisPatrol);
		OnPartol();
	}
}
예제 #3
0
파일: KAIBase.cpp 프로젝트: 1suming/pap2
void KAIBase::DoAlert()
{
	//KGLogPrintf(KGLOG_DEBUG, "[AI State] {%s} Turn to Alert\n", m_pSelf->m_szName);
	m_AlertData.nAlartFrame = g_pSO3World->m_nGameLoop + m_pAIParam->nAlertOverTime;

	SetAIInterval(0.5);
	SetAIState(aisAlert);
	OnAlert();
}
예제 #4
0
파일: KAIBase.cpp 프로젝트: 1suming/pap2
BOOL KAIBase::Init(KCharacter* pSelf)
{
	BOOL bRetCode = FALSE;

	m_nNextActiveFrame = 0;
	m_eAIType = aitInvalid;
	m_nOriginX = 0;
	m_nOriginY = 0;
	m_nOriginZ = 0;
	m_pAIParam = NULL;
	m_nAIInterval = g_pSO3World->m_Settings.m_ConstList.nAIInterval * 2;
	m_nNextIdleActionFrame = 0;
    m_nNextAStarFrame = 0;
    m_eAIMainState = aisInvalid;

    SetAIState(aisIdle);

	m_pSelf = pSelf;
	KGLOG_PROCESS_ERROR(m_pSelf);

#if defined(_SERVER)
	m_pPatrolPath = NULL;
	m_pNpcTeam = NULL;
#endif //_SERVER

	memset(&m_Params, 0, sizeof(m_Params));
	memset(m_nAIEventTimer, 0, sizeof(m_nAIEventTimer));

	//如果是NPC的话,加载参数模板
	if (IS_NPC(m_pSelf->m_dwID))
	{
		KNpc* pNpc = (KNpc*)(m_pSelf);
	
		KNpcTemplate* pNpcTemplate = pNpc->m_pTemplate;
		if (pNpcTemplate == NULL)
		{
			pNpcTemplate = g_pSO3World->m_Settings.m_NpcTemplateList.GetTemplate(pNpc->m_dwTemplateID);
		}
		KGLOG_PROCESS_ERROR(pNpcTemplate);

		m_pAIParam = g_pSO3World->m_Settings.m_AIParamTemplateList.GetTemplate(pNpcTemplate->nAIParamTemplateID);
		KGLOG_PROCESS_ERROR(m_pAIParam);
	}
	else
	{
		m_pAIParam = g_pSO3World->m_Settings.m_AIParamTemplateList.GetTemplate(g_pSO3World->m_Settings.m_ConstList.nPlayerAITemplateID);
		KGLOG_PROCESS_ERROR(m_pAIParam);
	}

	LoadParamFromTemplate();


	bRetCode = TRUE;
Exit0:
	return bRetCode;
}
예제 #5
0
파일: KAIBase.cpp 프로젝트: 1suming/pap2
void KAIBase::OnWait(void)
{
	BOOL bRetCode = FALSE;

	KGLOG_PROCESS_ERROR(m_pSelf);

	bRetCode = CheckAttacked();
	KG_PROCESS_SUCCESS(bRetCode);

	bRetCode = CheckTargetInAlertRange();
	KG_PROCESS_SUCCESS(bRetCode);

	bRetCode = CheckTargetInAttackRange();
	KG_PROCESS_SUCCESS(bRetCode);

	// 检测小队状态,个体Npc一般没有必要进入wait
	if (m_pNpcTeam && m_pNpcTeam->m_pLeader == m_pSelf)
	{
		bRetCode = m_pNpcTeam->CheckNpcWorkDone();
		if (bRetCode)
		{	
			int nIndex = 0;
			int nMemberCount = m_pNpcTeam->GetMemberCount();

			SetAIState(m_eAIMainState);

			//所有小队成员的工作已经完成,根据之前的状态恢复工作
			for (nIndex = 0; nIndex < nMemberCount; nIndex++)
			{	
				KNpc* pNpc = m_pNpcTeam->GetMember(nIndex);
				if (pNpc && pNpc != m_pSelf)
				{
					KAI_STATE eAiMainState = pNpc->m_AIController.GetMainState();
					SetAIState(eAiMainState);
				}
			}
		}
	}
Exit1:
	return;
Exit0:
	return;
}
예제 #6
0
파일: KAIBase.cpp 프로젝트: 1suming/pap2
void KAIBase::DoEscape()
{
	//KGLogPrintf(KGLOG_DEBUG, "[AI State] {%s} Turn to Escape\n", m_pSelf->m_szName);
	//逃跑的函数会检测状态,所以要先停下来再逃跑
	m_EscapeData.nEscapeIdleFrame = 0;

	m_pSelf->Stop();
	SetAIState(aisEscape);
	OnEscape();
}
예제 #7
0
/*
* Damages the shield, and forces an AIState transition to disabled
*   if the shield is no longer positive
* 
* @author				Cameron MacIntosh
* @param _fDamage		The amount to damage the shield by
* @return float32		The shield's modified strength
*/
float32
CTower::TakeDamage(float32 _fDamage)
{
	m_fShieldStrength -= _fDamage;
	if(m_fShieldStrength<=0)
	{
		m_fShieldStrength = 0;
		SetAIState(TOWERAI_STATE_DISABLED);
	}
	return (m_fShieldStrength);
}
예제 #8
0
파일: KAIBase.cpp 프로젝트: 1suming/pap2
void KAIBase::DoPursuit()
{
	//KGLogPrintf(KGLOG_DEBUG, "[AI State] {%s} Turn to Pursuit\n", m_pSelf->m_szName);
	//记录进战斗时间
	m_PursuitData.nTurnToFightFrame = g_pSO3World->m_nGameLoop;
	m_PursuitData.nCallHealFrame = 0;
	m_PursuitData.dwCallByNpcID = 0;
	m_PursuitData.dwKeepDisDivisor = 1;

	SetAIInterval(0.5);
	SetAIState(aisPursuit);
	OnPursuit();
}
예제 #9
0
파일: KAIBase.cpp 프로젝트: 1suming/pap2
// --------------- AI状态切换函数 ---------------------------------------
void KAIBase::DoIdle(int nIdleFrame)
{
	//KGLogPrintf(KGLOG_DEBUG, "[AI State] {%s} Turn to Idle\n", m_pSelf->m_szName);
	SetAIInterval(1.0);
	m_pSelf->Stop();
	if (m_eAIState == aisIdle)
	{
		int nTmpFrameCount = g_pSO3World->m_nGameLoop + nIdleFrame;
		m_IdleData.nIdleFrameCount = (m_IdleData.nIdleFrameCount > nTmpFrameCount) ? m_IdleData.nIdleFrameCount : nTmpFrameCount;
	}
	else
	{
		m_IdleData.nIdleFrameCount	= g_pSO3World->m_nGameLoop + nIdleFrame;
	}
	SetAIState(aisIdle);
	OnIdle();
}
예제 #10
0
//------------------------------------------------------------------------------------------------
AI::AI(JQuad* quads[], JQuad* deadquad, std::vector<Bullet*>* bullets, std::vector<GunObject*>* guns, std::vector<Node*> nodes, int team, char* name, int movementstyle) : Person(quads, deadquad, bullets, guns, team, name, movementstyle)
{
	mPathTime = 0.0f;
	mMoveTime = 0.0f;
	mFireTime = 0.0f;
	mNewAngle = 0;
	mNodes = nodes;
	SetAIState(AI_SEARCHING);
	mTarget = NULL;
	//mTargetNode = NULL;
	mFaceTargetX = 0.0f;
	mFaceTargetY = 0.0f;
	mMoveTargetX = 0.0f;
	mMoveTargetY = 0.0f;
	mAIStateTime = 0.0f;
	mCanSeeEnemy = false;
	mStuckTimer = 0.0f;
	mBuyGun = NULL;
}
예제 #11
0
//------------------------------------------------------------------------------------------------
void AI::Reset()
{
	std::vector<Person*> mValidTargets;
	for (unsigned int i=0; i<mPeople->size(); i++) {
		if ((*mPeople)[i]->mTeam == mTeam || (*mPeople)[i]->mTeam == NONE) continue;
		mValidTargets.push_back((*mPeople)[i]);
	}

	mTarget = mValidTargets[rand()%mValidTargets.size()];

	mTargetNode = NULL;
	mNode = NULL;
	mPath.clear();
	SetAIState(AI_SEARCHING);
	mCanSeeEnemy = false;
	
	mStuckTimer = 0.0f;

	if (mBuyGun == NULL) {
		mBuyGun = &(*mGameGuns)[7+rand()%18];
	}

	Person::Reset();
}
예제 #12
0
//------------------------------------------------------------------------------------------------
void AI::Update(float dt)
{
	//return;
	if (mState == DEAD) {
		Person::Update(dt);
		return;
	}

	//if (mGunIndex != KNIFE) Switch(KNIFE);
	float dx = mOldX-mX;
	float dy = mOldY-mY;
	if (fabs(dx) >= EPSILON || fabs(dy) >= EPSILON) {
		if (dx*dx + dy*dy < 0.0016f) {
			mStuckTimer += dt;
			if (mStuckTimer > 3000.0f) {
				mPath.clear();
				mTargetNode = mNode;
			}
		}
		else {
			mStuckTimer = 0.0f;
		}
	}
	else {
		mStuckTimer += dt;
		if (mStuckTimer > 3000.0f) {
			mPath.clear();
			mTargetNode = mNode;
		}
	}

	if (mIsFlashed) {
		SetAIState(AI_FLASHED);
	}

	mAIStateTime += dt;

	switch (mAIState) {
		case AI_IDLE: {

			mMoveTargetX = mX;
			mMoveTargetY = mY;

			if (mAIStateTime > 100.0f) {
				mTarget = GetClosestPerson();

				if (mTarget != NULL) {
					float dx = mTarget->mX-mX;
					float dy = mTarget->mY-mY;
					float distance = dx*dx + dy*dy;

					if (distance < 50000) {
						mPath.clear();
						SetAIState(AI_ATTACKING);
						break;
					}
				}

				SetAIState(AI_SEARCHING);

				mAIStateTime = 0.0f;
			}
			break;
		}
		case AI_RANDOM: {
			if (mTargetNode == NULL) break;

			float dx = mTargetNode->mX-mX;
			float dy = mTargetNode->mY-mY;
			float distance = dx*dx + dy*dy;
			if (distance < 1000) {
				Node* mTempNode;
				for (int i=0;i<50;i++) {
					mTempNode = mTargetNode->mConnections[rand()%mTargetNode->mConnections.size()];
					if (mTargetNode->mConnections.size() == 1) break;
					if (mTempNode != mNode) break;
				}
				mNode = mTargetNode;
				mTargetNode = mTempNode;
			}

			if (mAIStateTime > 100.0f) {
				mTarget = GetClosestPerson();

				if (mTarget != NULL) {
					float dx = mTarget->mX-mX;
					float dy = mTarget->mY-mY;
					float distance = dx*dx + dy*dy;

					if (distance < 50000) {
						mPath.clear();
						SetAIState(AI_ATTACKING);
						break;
					}
				}
				SetAIState(AI_SEARCHING);

				mAIStateTime = 0.0f;
			}

			mMoveTargetX = mTargetNode->mX;
			mMoveTargetY = mTargetNode->mY;

			mFaceTargetX = mTargetNode->mX;
			mFaceTargetY = mTargetNode->mY;

			break;
		}
		case AI_SEARCHING: {

			if (mTarget == NULL) {
				mTarget = GetClosestPerson();
				if (mTarget == NULL) {
					SetAIState(AI_RANDOM);
					break;
				}
			}
			if (mTargetNode == NULL) {
				float dx = mTarget->mX-mX;
				float dy = mTarget->mY-mY;
				float distance = dx*dx + dy*dy;

				if (mNode == NULL) {
					mNode = mAStar->GetClosestNode(this);
				}
				if (mNode == NULL) {
					SetAIState(AI_IDLE);
					break;
				}

				Node* endnode = mTarget->mTargetNode; //mAStar->GetClosestNode(mTarget);
				if (endnode == NULL) {
					endnode = mAStar->GetClosestNode(mTarget);
				}
				if (endnode == NULL) break;

				mPath = mAStar->GetPath(mNode,endnode,(int)sqrtf(distance)*15);
				mTargetNode = mPath.back();
				mPath.pop_back();
			}

			if (mAIStateTime > 100.0f) {
				if (mTargetNode != NULL) {
					float dx = mTargetNode->mX-mX;
					float dy = mTargetNode->mY-mY;
					float distance = dx*dx + dy*dy;
					if (distance < 1000) {
						mNode = mTargetNode;
						if (mPath.size() > 0) {
							mTargetNode = mPath.back();
							mPath.pop_back();
						}
						else {
							float dx = mTarget->mX-mX;
							float dy = mTarget->mY-mY;
							float distance = dx*dx + dy*dy;

							Node* endnode = mTarget->mTargetNode; //mAStar->GetClosestNode(mTarget);
							if (endnode == NULL) {
								endnode = mAStar->GetClosestNode(mTarget);
							}
							if (endnode == NULL) break;

							mPath = mAStar->GetPath(mNode,endnode,(int)sqrtf(distance)*15);
							mTargetNode = mPath.back();
							mPath.pop_back();
						}
					}

					mFaceTargetX = mTargetNode->mX;
					mFaceTargetY = mTargetNode->mY;
				}

				mTarget = GetClosestPerson();

				if (mTarget != NULL) {
					float dx = mTarget->mX-mX;
					float dy = mTarget->mY-mY;
					float distance = dx*dx + dy*dy;

					if (distance < 50000) {
						mPath.clear();
						SetAIState(AI_ATTACKING);
						break;
					}
				}

				mAIStateTime = 0.0f;
			}

			mMoveTargetX = mTargetNode->mX;
			mMoveTargetY = mTargetNode->mY;

			break;
		}
		case AI_ATTACKING: {
			if (mTarget == NULL) {
				SetAIState(AI_SEARCHING);
				break;
			}
			if (mTargetNode != NULL) {
				float dx = mTargetNode->mX-mX;
				float dy = mTargetNode->mY-mY;
				float distance = dx*dx + dy*dy;
				if (distance < 500) {
					mNode = mTargetNode;
					if (mPath.size() > 0) {
						mTargetNode = mPath.back();
						mPath.pop_back();
					}
					else {
						Node* endnode = mTarget->mTargetNode; //mAStar->GetClosestNode(mTarget);
						if (endnode == NULL) {
							endnode = mAStar->GetClosestNode(mTarget);
						}
						if (endnode == NULL) break;

						mPath = mAStar->GetPath(mNode,endnode);
						mTargetNode = mPath.back();
						mPath.pop_back();
					}
				}
				mMoveTargetX = mTargetNode->mX;
				mMoveTargetY = mTargetNode->mY;
			}

			mFaceTargetX = mTarget->mX;
			mFaceTargetY = mTarget->mY;

			float dx = mTarget->mX-mX;
			float dy = mTarget->mY-mY;
			float distance = dx*dx + dy*dy;

			if (mCanSeeEnemy) {
				mFaceTargetX = mTarget->mX+mTarget->mSpeed*cosf(mTarget->mAngle)*(sqrtf(distance)/0.25f);
				mFaceTargetY = mTarget->mY+mTarget->mSpeed*sinf(mTarget->mAngle)*(sqrtf(distance)/0.25f);
			}
			if (distance > 50000) {
				SetAIState(AI_SEARCHING);
				break;
			}
			if (mTarget->mState == DEAD) {
				SetAIState(AI_SEARCHING);
				mTarget = NULL;
				break;
			}
			if (mAIStateTime > 100.0f) {
				if (GetClosestPerson() != mTarget) {
					mTarget = GetClosestPerson();
				}

				//Vector2D A(mX,mY);
				//Vector2D B(mTarget->mX,mTarget->mY);

				//Line line1(A,B);
				mCanSeeEnemy = true;
				mCanSeeEnemy = mGrid->LineOfSight(mX,mY,mTarget->mX,mTarget->mY);

				/*for (unsigned int i=0;i<mCollisionPoints->size()-1;i++) {
					if ((*mCollisionPoints)[i].bullets == false) continue;
					if ((*mCollisionPoints)[i].x == -1 || (*mCollisionPoints)[i+1].x == -1) continue;
					Vector2D C((*mCollisionPoints)[i].x,(*mCollisionPoints)[i].y);
					Vector2D D((*mCollisionPoints)[i+1].x,(*mCollisionPoints)[i+1].y);
					if (C == D) continue;
					Line line2(C,D);

					Vector2D d;
					if (LineLineIntersect(line1,line2,d)) {
						mCanSeeEnemy = false;
						break;
					}
				}*/
				mAIStateTime = 0.0f;
			}

			break;
		}
		case AI_FLASHED: {
			if (!mIsFlashed) {
				mTarget = NULL;
				mTargetNode = NULL;
				mNode = NULL;
				SetAIState(AI_SEARCHING);
			}
			if (mAIStateTime > 1000.0f+rand()%1000-500) {
				float angle = 2*M_PI*(rand()%100)/100.0f;
				mMoveTargetX = mX+cosf(angle)*1000;
				mMoveTargetY = mY+sinf(angle)*1000;

				angle = 2*M_PI*(rand()%100)/100.0f;
				mFaceTargetX = mX+cosf(angle);
				mFaceTargetY = mY+sinf(angle);
				mAIStateTime = 0.0f;
			}


			break;
		}
	}

	if (fabs(mFaceTargetX-mX) >= EPSILON || fabs(mFaceTargetY-mY) >= EPSILON) {
		float e = atan2f(mFaceTargetY-mY,mFaceTargetX-mX);//+((double)rand()/((double)RAND_MAX*2))-0.25;
		float diffangle = e-mFacingAngle;
		if (diffangle < -M_PI) {
			diffangle += M_PI*2;
		}
		else if (diffangle > M_PI) {
			diffangle -= M_PI*2;
		}
		RotateFacing(diffangle*(0.003f*dt));
	}


	if (fabs(mMoveTargetX-mX) >= EPSILON || fabs(mMoveTargetY-mY) >= EPSILON) {
		float e = atan2f(mMoveTargetY-mY,mMoveTargetX-mX);//+((double)rand()/((double)RAND_MAX*2))-0.25;
		float diffangle = e-mAngle;
		if (diffangle < -M_PI) {
			diffangle += M_PI*2;
		}
		else if (diffangle > M_PI) {
			diffangle -= M_PI*2;
		}

		mAngle += diffangle*(0.005f*dt);
		//SetAngle(GetAngle()+(((float)rand()/RAND_MAX)-0.5f)/50*dt);
		//SetRotation(GetRotation()+(((float)rand()/RAND_MAX)-0.5f)/50*dt);
		Move(.08f,mAngle+M_PI_2);
		//SetSpeed((float)rand()/RAND_MAX/10);
	}

	if (mAIState == AI_ATTACKING && mCanSeeEnemy) {
		mFireTime += dt;
		if (mFireTime >= 500+rand()%500-250) {
			if (mState != ATTACKING) {
				Fire();
			}
			if (mFireTime >= 1000+rand()%1000-500) {
				mFireTime = 0.0f;
			}
		}
	}
	else {
		StopFire();
	}

	if (mState != RELOADING) {
		if (mGuns[mGunIndex]->mClipAmmo == 0) {
			if (!Reload()) {
				Drop(mGunIndex);
			}
		}
	}

	if (mIsInBuyZone && mBuyGun != NULL && mMoney >= mBuyGun->mCost) {
		if (mBuyGun->mType == PRIMARY) {
			mMoney -= mBuyGun->mCost;
			Drop(PRIMARY);
			GunObject *gun = new GunObject(mBuyGun,mBuyGun->mClip,0);
			PickUp(gun);
			//mPlayer->mGuns[PRIMARY] = gun;
			//mPlayer->mGunIndex = PRIMARY;
			gSfxManager->PlaySample(gPickUpSound, mX, mY);
			mBuyGun = NULL;
		}
	}

	Person::Update(dt);
}
예제 #13
0
파일: KAIBase.cpp 프로젝트: 1suming/pap2
void KAIBase::DoWait()
{
	SetAIState(aisWait);
	OnWait();
}
예제 #14
0
파일: KAIBase.cpp 프로젝트: 1suming/pap2
void KAIBase::DoKeepAway()
{
	//KGLogPrintf(KGLOG_DEBUG, "[AI State] {%s} Turn to KeepAway\n", m_pSelf->m_szName);
	SetAIState(aisKeepAway);
	OnKeepAway();
}
예제 #15
0
파일: KAIBase.cpp 프로젝트: 1suming/pap2
void KAIBase::DoFollow()
{
	//KGLogPrintf(KGLOG_DEBUG, "[AI State] {%s} Turn to Follow\n", m_pSelf->m_szName);
	SetAIState(aisFollow);
	OnFollow();
}
예제 #16
0
/*
* remove the shield, and change the state to disabled
* 
* @author			Cameron MacIntosh
*/
void
CTower::TakeEMP()
{
	m_fShieldStrength = 0.0f;
	SetAIState(TOWERAI_STATE_DISABLED);
}
예제 #17
0
파일: KAIBase.cpp 프로젝트: 1suming/pap2
void KAIBase::DoWander()
{
	//KGLogPrintf(KGLOG_DEBUG, "[AI State] {%s} Turn to Wander\n", m_pSelf->m_szName);
	SetAIState(aisWander);
	OnWander();
}