#include "dxstdafx.h" #include ".\aiplayer.h" #include "GameScene.h" #include "Terrain.h" #include "Goodie.h" AIPlayer::AIPlayer(void) : Player() { /*speedCounter = 0; steeringCounter = 3; speedMod = 3; steeringMod = 7; needNewRand = true;*/ this->drTimer = 0; this->lastNewPositionTime = 0; this->myState = LEAVE_ISLAND; this->activeOpponent = NULL; this->activeGoodie = NULL; this->frTimer = 0; this->lastFire = 0; srand((UINT)time(NULL)); this->nodeType|=GameScene::NODE_AIPLAYER; } AIPlayer::~AIPlayer(void) { } //TODO OPPONENT AND GOODIE SHOULD BE SMART POINTER!!!!! void AIPlayer::update(float dt) { /*if(dt==0) { return; }*/ /* #define CHECK_ROTATING 0 #define LEAVE_ISLAND 1 #define DRIVE_AROUND 2 #define ESCAPE 3 #define NEAR_GOODIE 4 #define NEAR_OPPONENT 5 */ Player::update(dt); frTimer+=dt; float ch = ((GameScene *) this->myScene)->getWidth()/2; Vector center(ch, 0, ch); Vector driveToPos; //Vector weaponPos(0, 25, 0); Vector weaponPos(0, 1.25, 0); Vector colPoint; Vector opPos; //Vectors for Obstacle Vector tempHeading; Vector tempObstacle; Vector upV; Vector xV; this->selectWeapon(); switch(this->myState) { case CHECK_ROTATING: //Check if vehicle is rotating break; case LEAVE_ISLAND: //Turn and drive back to center of island this->driveTo(dt, center, 0.2f); //this->myScene->manager->printToConsole("LEAVE_ISLAND"); break; case NEAR_OBSTACLE: tempHeading = this->heading; tempHeading.y = 0; tempHeading.normalize(); tempObstacle = this->obstaclePos - this->getAbsolutePosition(); tempObstacle.y = 0; tempObstacle.normalize(); upV = tempHeading.crossProd(tempObstacle); upV.normalize(); xV = upV.crossProd(tempHeading); driveToPos = tempHeading*5 + xV*10; this->driveTo(dt, driveToPos, 1); break; case NEAR_OPPONENT: //this->myScene->manager->printToConsole("NEAR_OPPONENT"); //Select Zone switch(this->myZone) { case COLL_ZONE: //Avoid collistion if(this->activeOpponent!=NULL) { //driveToPos = this->myPosition + (this->myPosition - this->activeOpponent->getPosition())*2*COLL_DIST; driveToPos = this->getAbsolutePosition() + (this->getAbsolutePosition() - this->activeOpponent->getAbsolutePosition())*2*COLL_DIST; this->driveTo(dt, driveToPos, 1); } break; case ATTACK_ZONE: //Try to stay behind activeOpponent and attack him if(this->activeOpponent!=NULL) { driveToPos = this->activeOpponent->getPosition() + (this->activeOpponent->heading)*2*COLL_DIST; this->driveTo(dt, driveToPos, 0.2f); //If theres no intersection, fire at opponent /*opPos = this->activeOpponent->getPosition(); colPoint = ((GameScene *) this->myScene)->terrain->collision(this->pos+weaponPos, opPos); if(colPoint.x == opPos.x && colPoint.y == opPos.y && colPoint.z == opPos.z && lastFire+0.8fire(); }*/ //TODO verbessern //this->activeWeapon->fire(); if(lastFire+1.8myScene)->aiPlayerFireEnable) { lastFire = frTimer; this->activeWeapon->fire(); } } break; case FIRE_ZONE: //Try to attack him if possible! this->driveAround(dt, center, ch); if(this->activeOpponent!=NULL) { /*opPos = this->activeOpponent->getPosition(); colPoint = this->sMgr->getTerrain()->collision(this->pos+weaponPos, opPos); if(colPoint.x == opPos.x && colPoint.y == opPos.y && colPoint.z == opPos.z && lastFire+0.8fire(); }*/ //TODO verbessern //this->activeWeapon->fire(); if(lastFire+1.8myScene)->aiPlayerFireEnable) { lastFire = frTimer; this->activeWeapon->fire(); } } break; } break; case NEAR_GOODIE: //this->myScene->manager->printToConsole("NEAR_GOODIE"); if(this->activeGoodie!=NULL) { opPos = this->activeGoodie->getPosition(); this->driveTo(dt, opPos, 0.1f); } break; case DRIVE_AROUND: //this->myScene->manager->printToConsole("DRIVE_AROUND"); this->driveAround(dt, center, ch); break; } //Calculate next State /*char temp[100]; sprintf(temp, "myState = %i", this->myState); this->myScene->manager->printToConsole(temp);*/ if(false) { //Solve rotating problem this->myState = CHECK_ROTATING; } else if(isLeaving(center, ch)) { //LEAVE_ISLAND this->myState = LEAVE_ISLAND; } else if(isObstacleNear()) { //NEAR OBSTACLE this->myState = NEAR_OBSTACLE; //this->myScene->manager->printToConsole("NEAR OBSTACLE!"); } else if(isNear()) { //NEAR OPPONENT this->myState = NEAR_OPPONENT; } else if(isGoodieNear()) { //NEAR GOODIE this->myState = NEAR_GOODIE; } else { //DRIVE AROUND this->myState = DRIVE_AROUND; } //Player::update(dt); Vector fireAt; if(this->activeOpponent!=NULL) { this->activeOpponent->getAbsoluteVector(fireAt, fireAt); fireAt.y++; this->activeWeapon->setFireAt(fireAt); } else if(this->activeGoodie!=NULL) { this->activeGoodie->getAbsoluteVector(fireAt, fireAt); this->activeWeapon->setFireAt(fireAt); } else { D3DXMATRIX mYaw; Vector fireAt(0,0,1000); //mYaw.setRotateY(this->rot.y*M_PI/180); D3DXMatrixRotationY(&mYaw, this->myRotation.y); fireAt.applyD3DXVector(D3DXVec4Transform(&fireAt, &fireAt, &mYaw));//.transform(fireAt); fireAt = fireAt + this->myPosition; this->getActiveWeapon()->setFireAt(fireAt); } /*char temp[100]; Vector tp; this->myScene->manager->printToConsole("---------------"); for(int i=0;i<4;i++) { tp = this->wheel[i]->getPosition(); sprintf(temp, "x=%f, y=%f z=%f", tp.x, tp.y, tp.z); this->myScene->manager->printToConsole(temp); }*/ } bool AIPlayer::isLeaving(Vector center, float ch) { return ((center-this->getAbsolutePosition()).length()>0.9*ch); } bool AIPlayer::isObstacleNear() { NxVec3 direction = this->heading.getNxVector(); //direction.y = 0; NxRay ray(this->getAbsolutePosition().getNxVector(), direction); NxRaycastHit hit; // Get the closest shape NxU32 mask = 1<myScene->pScene->raycastClosestShape(ray, NX_ALL_SHAPES, hit, mask, 20);//0xffffff); if (closestShape) { this->obstaclePos = Vector(closestShape->getGlobalPosition()); return true; } else { return false; } } bool AIPlayer::isNear() { bool isnear = false; int zone = DRIVE_ZONE; Vector opPos; Vector neDir; Vector neHead; float distance; float minDistance=10000000; //std::vector *playerList = this->sMgr->getPlayerList(); std::list > *playerList = ((GameScene *)this->myScene)->getPlayerList(); std::list >::iterator it; Player *tempActiveOpponent = NULL; Player *opponent; //for(unsigned int i=0;isize();i++) { for(it=playerList->begin();it!=playerList->end();it++) { //opponent = playerList->at(i); opponent = ((Player *) (*it).get()); if(opponent->getTeam()==this->getTeam()) { continue; } if(opponent!=this) { opPos = opponent->getAbsolutePosition(); neDir = opPos - this->getAbsolutePosition(); distance = neDir.length(); neDir.normalize(); neHead = this->heading; neHead.normalize(); if((neHead.dotProd(neDir))>0) { isnear = true; if(distancemyZone = COLL_ZONE; return true; } if(distancemyZone = ATTACK_ZONE; } else { this->myZone = FIRE_ZONE; } } } } } this->activeOpponent = tempActiveOpponent; return isnear; } bool AIPlayer::isGoodieNear() { bool isnear = false; Vector goPos; Vector goDir; Vector goHead; float distance; float minDistance=10000000; //std::vector *goodieList = this->sMgr->getGoodieList(); std::list > *goodieList = ((GameScene *)this->myScene)->getGoodieList(); std::list >::iterator it; Goodie *tempActiveGoodie = NULL; Goodie *goodie; for(unsigned int i=0;isize();i++) { //goodie = goodieList->at(i); goodie = ((Goodie *) (*it).get()); goPos = goodie->getPosition(); goDir = goPos - this->myPosition; distance = goDir.length(); goDir.normalize(); goHead = this->heading; goHead.normalize(); if((goHead.dotProd(goDir))>0) { isnear = true; if(distanceactiveGoodie = tempActiveGoodie; return isnear; } void AIPlayer::driveAround(float dt, Vector center, float ch) { this->drTimer+=dt; if(lastNewPositionTime+3drTimer) { float x = (float)(((float) rand())/(RAND_MAX+1)-0.5)*2*ch; float y = (float)(((float) rand())/(RAND_MAX+1)-0.5)*2*ch; float z = 0;//(float)(((float) rand())/(RAND_MAX+1)-0.5)*2*ch; this->driveToPosition.setXYZ(x, y, z); this->driveToPosition = this->driveToPosition + center; this->lastNewPositionTime = this->drTimer; } this->driveTo(dt, this->driveToPosition, 0.2f); } void AIPlayer::driveTo(float dt, Vector position, float speed) { Vector drDirection; drDirection = position - this->getAbsolutePosition(); drDirection.y = 0; drDirection.normalize(); Vector drHeading; drHeading = this->heading; drHeading = drHeading*(-1); drHeading.y = 0; drHeading.normalize(); Vector drUp(0, 1, 0); //Berechnen ob nach links oder rechts gefahren werden soll Vector drNormDir; drNormDir = drUp.crossProd(drDirection); float leftright = drNormDir.dotProd(drHeading); bool driveLeft = (leftright>0) ? false : true; //Set steering if(leftright!=0) { if(driveLeft) this->toLeft(); else this->toRight(); } //Set speed //this->accelerate(this->engineTorquemaxEngineTorque*speed); if(this->engineForcemaxEngineForce*speed*0.5) { this->accelerate(); } } void AIPlayer::selectWeapon() { if(this->activeWeapon->getAmo()==0) { for(int i=0;i<10;i++) { if(this->weaponList[i] && this->weaponList[i]->getAmo()>0) { this->setActiveWeapon(i); return; } } } }