/** * Processes the state * changes the tower's state to attack if enemy is close * * @author Cameron MacIntosh * @param _fDeltaTick Time between frames */ void CTowerIdle::Process(float32 _fDeltaTick) { // check through all tanks that are on the same face as this player. for (uint32 ui = 0; ui < 8; ++ui) { CTank* pTank = CPlayerManager::GetPlayerManagerInstance().GetPlayer(ui)->GetTank(); if ((pTank->GetFacePosition() == m_pTower->GetFacePosition()) && (pTank->GetTeam() != m_pTower->GetTeam()) ) { m_pTower->SetAIState(TOWERAI_STATE_ATTACK); } } //if an enemy moves close, switch to Attack m_pTower->SetAIState(TOWERAI_STATE_ATTACK); }
/* * Initialises the class instance * * @author Cameron MacIntosh * @param _pOwner the owning AIPlayer * @param _pMove an address of an instance of the Move substate * @param _pFlee an address of an instance of the Flee substate * @param Attack an address of an instance of the Attack substate * @return if it succeded. Don't use the instance if it returns false. */ bool CAIStateProtectPlayer::Initialise(CAIPlayer* _pOwner, CAISubstateMove* _pMove, CAISubstateFlee* _pFlee, CAISubstateAttack* _pAttack) { if(_pOwner!=0) { m_pOwner = _pOwner; m_pTank = m_pOwner->GetTank(); m_pMove = _pMove; m_pFlee = _pFlee; m_pAttack = _pAttack; InitGeneral(); for(uint32 i=0; i<8; ++i) { CTank* pTank = CPlayerManager::GetPlayerManagerInstance().GetPlayer(i)->GetTank(); if((m_eEnemyTeam!=pTank->GetTeam())&&(pTank!=m_pTank)) { if(pTank->HasFlag()) { //carrier has flag m_pFlagCarrier = pTank; D3DXVECTOR2 vec2 = pTank->GetPosition2D(); m_TTargetLastPos2.x = static_cast<int32>(vec2.x); m_TTargetLastPos2.y = static_cast<int32>(vec2.y); m_pMove->SetTarget(m_TTargetLastPos2.x, m_TTargetLastPos2.y, pTank->GetFacePosition()); } } } if(m_pFlagCarrier==0) { m_pOwner->RequestState(AI_STATE_IDLE); return(false); } return(true); } return(false); }
//overall code by rigardt, turret rotation by Cameron void CAISubstate::FireAtEnemy() { //#ifndef _AI_NOSHOOT // should probably be placed in substate.cpp, or substateAttack.cpp // as this is supposed to only be a container for the current state(s),\ // and not make decisions itself. D3DXVECTOR3 vec3Distance; D3DXVECTOR3 vec3ShootDir; D3DXVECTOR3 vec3ShootRight; CTank* pTankTarget = 0; bool m_bWillShoot = false; // check through all tanks that are on the same face as this player. for (uint32 ui = 0; ui < 8; ++ui) { // get pointer to a tank. CTank* pTank = CPlayerManager::GetPlayerManagerInstance().GetPlayer(ui)->GetTank(); // make sure that the tank is not equal to this one. if (m_pTank != CPlayerManager::GetPlayerManagerInstance().GetPlayer(ui)->GetTank() ) { if (pTank->GetAlive() && pTank->GetPowerUp() != POWERUP_INVISIBILITY && pTank->GetTeam() != m_pTank->GetTeam() && pTank->GetFacePosition() == m_pTank->GetFacePosition() && !m_pTank->HasFlag()) { // the tank found a target and will shoot at it at this point. m_bWillShoot = true; vec3ShootDir = pTank->GetPosition() - m_pTank->GetPosition(); if (D3DXVec3Length(&vec3Distance) > D3DXVec3Length(&vec3ShootDir) ) { // sets the shoot directions and the target tank. vec3Distance = vec3ShootDir; pTankTarget = pTank; } } } } // transforms the right coords. D3DXMATRIX mat; D3DXMatrixRotationAxis(&mat, &g_atUpRightDirectionVecs[m_pTank->GetFacePosition()].vec3Up, D3DXToRadian(90) ); D3DXVec3TransformCoord(&vec3ShootRight, &vec3Distance, &mat); //vec3Distance += (vec3ShootRight*((RandomFloat()-0.5f)*0.5f)); std::vector<CWall*> rvecWalls; if (!m_pTank->HasFlag()) { // checks if the target exsists. if (pTankTarget) { std::vector<CWall*> rvecWallsOnFace; // declare some base variables. float32 fXTarget = pTankTarget->GetPosition2D().x; float32 fYTarget = pTankTarget->GetPosition2D().y; float32 fXPosition = m_pTank->GetPosition2D().x; float32 fYPosition = m_pTank->GetPosition2D().y; float32 fXMin = 0.0f; float32 fXMax = 0.0f; float32 fYMin = 0.0f; float32 fYMax = 0.0f; // set the x min and max if (fXTarget < fXPosition) { fXMin = fXTarget - 0.5f; fXMax = fXPosition + 0.5f; } else { fXMax = fXTarget + 0.5f; fXMin = fXPosition - 0.5f; } // set the y min and max if (fYTarget < fYPosition) { fYMin = fYTarget - 0.5f; fYMax = fYPosition + 0.5f; } else { fYMax = fYTarget + 0.5f; fYMin = fYPosition - 0.5f; } // local variable is destroyed after these braces { std::vector<CWall*> rvecWalls = CPathfinder::GetInstance().GetCube()->GetWalls(); for (uint32 ui = 0; ui < rvecWalls.size(); ++ui) { // checks the wall is on the same face as the tank. if (rvecWalls[ui]->GetFacePosition() == m_pTank->GetFacePosition() ) { // adds the wall in the vector of walls to be referenced. rvecWallsOnFace.push_back(rvecWalls[ui]); } } } // checks through all the walls that are on the same face as the tank. for (uint32 ui = 0; ui < rvecWallsOnFace.size(); ++ui) { // This is the check to see if the walls are inside the square made by the two tanks. if (rvecWallsOnFace[ui]->GetX() >= fXMin && rvecWallsOnFace[ui]->GetX() <= fXMax && rvecWallsOnFace[ui]->GetY() >= fYMin && rvecWallsOnFace[ui]->GetY() <= fYMax) { // adds the wall into the a new vector of walls. rvecWalls.push_back(rvecWallsOnFace[ui]); } } } // checks if the vector is empty. if (!rvecWalls.empty() ) { //for (uint32 ui = 0; ui < rvecWalls.size(); ++ui) //{ // // checks if the shoot direction ray intersects with any of the wall // // that are in the vector. // if (TRUE == D3DXBoxBoundProbe(&rvecWalls[ui]->GetBoundingBox().m_vec3Min, // &rvecWalls[ui]->GetBoundingBox().m_vec3Max, // &m_pTank->GetPosition(), &vec3ShootDir) ) // { // if even one wall intersects the tank will not shoot. m_bWillShoot = false; //break; //} //} } // actually shoot now if (m_bWillShoot == true) { D3DXVec3Normalize(&vec3ShootDir, &vec3Distance); D3DXVec3Normalize(&vec3ShootRight, &vec3ShootRight); //m_pTank->SetShootRightAndDir(vec3ShootDir, vec3ShootRight); //rotates the turret - Cameron D3DXVECTOR2 vec2; EFacePosition eFace = m_pTank->GetFacePosition(); vec2.x = D3DXVec3Dot(&vec3ShootDir, &g_atUpRightDirectionVecs[eFace].vec3Right); vec2.y = D3DXVec3Dot(&vec3ShootDir, &g_atUpRightDirectionVecs[eFace].vec3Direction); m_pTank->RotateTurret(vec2.x, vec2.y, 0.5f); // int32 iRandomChanceValue = static_cast<int32>(RandomFloat() * 300); if (m_pTank->GetEMPCount() == 0) { m_pTank->ShootPlasma(); } else if (iRandomChanceValue >= 1) { m_pTank->ShootPlasma(); } else if (D3DXVec3LengthSq(&vec3Distance) <= 18.0f) { m_pTank->ShootEMP(); } else { m_pTank->ShootPlasma(); } } } //#endif //_AI_NOSHOOT }