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(); }
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(); } }
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(); }
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; }
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; }
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(); }
/* * 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); }
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(); }
// --------------- 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(); }
//------------------------------------------------------------------------------------------------ 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; }
//------------------------------------------------------------------------------------------------ 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(); }
//------------------------------------------------------------------------------------------------ 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); }
void KAIBase::DoWait() { SetAIState(aisWait); OnWait(); }
void KAIBase::DoKeepAway() { //KGLogPrintf(KGLOG_DEBUG, "[AI State] {%s} Turn to KeepAway\n", m_pSelf->m_szName); SetAIState(aisKeepAway); OnKeepAway(); }
void KAIBase::DoFollow() { //KGLogPrintf(KGLOG_DEBUG, "[AI State] {%s} Turn to Follow\n", m_pSelf->m_szName); SetAIState(aisFollow); OnFollow(); }
/* * remove the shield, and change the state to disabled * * @author Cameron MacIntosh */ void CTower::TakeEMP() { m_fShieldStrength = 0.0f; SetAIState(TOWERAI_STATE_DISABLED); }
void KAIBase::DoWander() { //KGLogPrintf(KGLOG_DEBUG, "[AI State] {%s} Turn to Wander\n", m_pSelf->m_szName); SetAIState(aisWander); OnWander(); }