[1378] | 1 | #include "dxstdafx.h"
|
---|
| 2 | #include ".\aiplayer.h"
|
---|
| 3 | #include "GameScene.h"
|
---|
| 4 | #include "Terrain.h"
|
---|
| 5 | #include "Goodie.h"
|
---|
| 6 |
|
---|
| 7 | AIPlayer::AIPlayer(void) : Player() {
|
---|
| 8 | /*speedCounter = 0;
|
---|
| 9 | steeringCounter = 3;
|
---|
| 10 | speedMod = 3;
|
---|
| 11 | steeringMod = 7;
|
---|
| 12 | needNewRand = true;*/
|
---|
| 13 |
|
---|
| 14 |
|
---|
| 15 | this->drTimer = 0;
|
---|
| 16 | this->lastNewPositionTime = 0;
|
---|
| 17 |
|
---|
| 18 | this->myState = LEAVE_ISLAND;
|
---|
| 19 | this->activeOpponent = NULL;
|
---|
| 20 | this->activeGoodie = NULL;
|
---|
| 21 |
|
---|
| 22 | this->frTimer = 0;
|
---|
| 23 | this->lastFire = 0;
|
---|
| 24 | srand((UINT)time(NULL));
|
---|
| 25 | this->nodeType|=GameScene::NODE_AIPLAYER;
|
---|
| 26 | }
|
---|
| 27 |
|
---|
| 28 | AIPlayer::~AIPlayer(void) {
|
---|
| 29 | }
|
---|
| 30 |
|
---|
| 31 | //TODO OPPONENT AND GOODIE SHOULD BE SMART POINTER!!!!!
|
---|
| 32 | void AIPlayer::update(float dt) {
|
---|
| 33 | /*if(dt==0) {
|
---|
| 34 | return;
|
---|
| 35 | }*/
|
---|
| 36 |
|
---|
| 37 | /* #define CHECK_ROTATING 0
|
---|
| 38 | #define LEAVE_ISLAND 1
|
---|
| 39 | #define DRIVE_AROUND 2
|
---|
| 40 | #define ESCAPE 3
|
---|
| 41 | #define NEAR_GOODIE 4
|
---|
| 42 | #define NEAR_OPPONENT 5 */
|
---|
| 43 |
|
---|
| 44 | Player::update(dt);
|
---|
| 45 |
|
---|
| 46 | frTimer+=dt;
|
---|
| 47 |
|
---|
| 48 | float ch = ((GameScene *) this->myScene)->getWidth()/2;
|
---|
| 49 | Vector center(ch, 0, ch);
|
---|
| 50 | Vector driveToPos;
|
---|
| 51 | //Vector weaponPos(0, 25, 0);
|
---|
| 52 | Vector weaponPos(0, 1.25, 0);
|
---|
| 53 | Vector colPoint;
|
---|
| 54 | Vector opPos;
|
---|
| 55 |
|
---|
| 56 | //Vectors for Obstacle
|
---|
| 57 | Vector tempHeading;
|
---|
| 58 | Vector tempObstacle;
|
---|
| 59 | Vector upV;
|
---|
| 60 | Vector xV;
|
---|
| 61 |
|
---|
| 62 | this->selectWeapon();
|
---|
| 63 |
|
---|
| 64 | switch(this->myState) {
|
---|
| 65 | case CHECK_ROTATING:
|
---|
| 66 | //Check if vehicle is rotating
|
---|
| 67 | break;
|
---|
| 68 | case LEAVE_ISLAND:
|
---|
| 69 | //Turn and drive back to center of island
|
---|
| 70 | this->driveTo(dt, center, 0.2f);
|
---|
| 71 | //this->myScene->manager->printToConsole("LEAVE_ISLAND");
|
---|
| 72 | break;
|
---|
| 73 | case NEAR_OBSTACLE:
|
---|
| 74 | tempHeading = this->heading;
|
---|
| 75 | tempHeading.y = 0;
|
---|
| 76 | tempHeading.normalize();
|
---|
| 77 | tempObstacle = this->obstaclePos - this->getAbsolutePosition();
|
---|
| 78 | tempObstacle.y = 0;
|
---|
| 79 | tempObstacle.normalize();
|
---|
| 80 | upV = tempHeading.crossProd(tempObstacle);
|
---|
| 81 | upV.normalize();
|
---|
| 82 | xV = upV.crossProd(tempHeading);
|
---|
| 83 | driveToPos = tempHeading*5 + xV*10;
|
---|
| 84 | this->driveTo(dt, driveToPos, 1);
|
---|
| 85 | break;
|
---|
| 86 | case NEAR_OPPONENT:
|
---|
| 87 | //this->myScene->manager->printToConsole("NEAR_OPPONENT");
|
---|
| 88 | //Select Zone
|
---|
| 89 | switch(this->myZone) {
|
---|
| 90 | case COLL_ZONE:
|
---|
| 91 | //Avoid collistion
|
---|
| 92 | if(this->activeOpponent!=NULL) {
|
---|
| 93 | //driveToPos = this->myPosition + (this->myPosition - this->activeOpponent->getPosition())*2*COLL_DIST;
|
---|
| 94 | driveToPos = this->getAbsolutePosition() + (this->getAbsolutePosition() - this->activeOpponent->getAbsolutePosition())*2*COLL_DIST;
|
---|
| 95 | this->driveTo(dt, driveToPos, 1);
|
---|
| 96 | }
|
---|
| 97 | break;
|
---|
| 98 | case ATTACK_ZONE:
|
---|
| 99 | //Try to stay behind activeOpponent and attack him
|
---|
| 100 | if(this->activeOpponent!=NULL) {
|
---|
| 101 | driveToPos = this->activeOpponent->getPosition() + (this->activeOpponent->heading)*2*COLL_DIST;
|
---|
| 102 | this->driveTo(dt, driveToPos, 0.2f);
|
---|
| 103 |
|
---|
| 104 | //If theres no intersection, fire at opponent
|
---|
| 105 | /*opPos = this->activeOpponent->getPosition();
|
---|
| 106 | colPoint = ((GameScene *) this->myScene)->terrain->collision(this->pos+weaponPos, opPos);
|
---|
| 107 | if(colPoint.x == opPos.x && colPoint.y == opPos.y && colPoint.z == opPos.z && lastFire+0.8<frTimer) {
|
---|
| 108 | lastFire = frTimer;
|
---|
| 109 | this->fire();
|
---|
| 110 | }*/
|
---|
| 111 | //TODO verbessern
|
---|
| 112 |
|
---|
| 113 | //this->activeWeapon->fire();
|
---|
| 114 | if(lastFire+1.8<frTimer && ((GameScene*)this->myScene)->aiPlayerFireEnable) {
|
---|
| 115 | lastFire = frTimer;
|
---|
| 116 | this->activeWeapon->fire();
|
---|
| 117 | }
|
---|
| 118 | }
|
---|
| 119 | break;
|
---|
| 120 | case FIRE_ZONE:
|
---|
| 121 | //Try to attack him if possible!
|
---|
| 122 | this->driveAround(dt, center, ch);
|
---|
| 123 | if(this->activeOpponent!=NULL) {
|
---|
| 124 | /*opPos = this->activeOpponent->getPosition();
|
---|
| 125 | colPoint = this->sMgr->getTerrain()->collision(this->pos+weaponPos, opPos);
|
---|
| 126 | if(colPoint.x == opPos.x && colPoint.y == opPos.y && colPoint.z == opPos.z && lastFire+0.8<frTimer) {
|
---|
| 127 | lastFire = frTimer;
|
---|
| 128 | this->fire();
|
---|
| 129 | }*/
|
---|
| 130 | //TODO verbessern
|
---|
| 131 |
|
---|
| 132 | //this->activeWeapon->fire();
|
---|
| 133 | if(lastFire+1.8<frTimer && ((GameScene*)this->myScene)->aiPlayerFireEnable) {
|
---|
| 134 | lastFire = frTimer;
|
---|
| 135 | this->activeWeapon->fire();
|
---|
| 136 | }
|
---|
| 137 | }
|
---|
| 138 | break;
|
---|
| 139 | }
|
---|
| 140 | break;
|
---|
| 141 | case NEAR_GOODIE:
|
---|
| 142 | //this->myScene->manager->printToConsole("NEAR_GOODIE");
|
---|
| 143 | if(this->activeGoodie!=NULL) {
|
---|
| 144 | opPos = this->activeGoodie->getPosition();
|
---|
| 145 | this->driveTo(dt, opPos, 0.1f);
|
---|
| 146 | }
|
---|
| 147 | break;
|
---|
| 148 | case DRIVE_AROUND:
|
---|
| 149 | //this->myScene->manager->printToConsole("DRIVE_AROUND");
|
---|
| 150 | this->driveAround(dt, center, ch);
|
---|
| 151 | break;
|
---|
| 152 | }
|
---|
| 153 |
|
---|
| 154 | //Calculate next State
|
---|
| 155 |
|
---|
| 156 | /*char temp[100];
|
---|
| 157 | sprintf(temp, "myState = %i", this->myState);
|
---|
| 158 | this->myScene->manager->printToConsole(temp);*/
|
---|
| 159 |
|
---|
| 160 | if(false) {
|
---|
| 161 | //Solve rotating problem
|
---|
| 162 | this->myState = CHECK_ROTATING;
|
---|
| 163 | } else if(isLeaving(center, ch)) { //LEAVE_ISLAND
|
---|
| 164 | this->myState = LEAVE_ISLAND;
|
---|
| 165 | } else if(isObstacleNear()) { //NEAR OBSTACLE
|
---|
| 166 | this->myState = NEAR_OBSTACLE;
|
---|
| 167 | //this->myScene->manager->printToConsole("NEAR OBSTACLE!");
|
---|
| 168 | } else if(isNear()) { //NEAR OPPONENT
|
---|
| 169 | this->myState = NEAR_OPPONENT;
|
---|
| 170 | } else if(isGoodieNear()) { //NEAR GOODIE
|
---|
| 171 | this->myState = NEAR_GOODIE;
|
---|
| 172 | } else { //DRIVE AROUND
|
---|
| 173 | this->myState = DRIVE_AROUND;
|
---|
| 174 | }
|
---|
| 175 |
|
---|
| 176 | //Player::update(dt);
|
---|
| 177 |
|
---|
| 178 | Vector fireAt;
|
---|
| 179 | if(this->activeOpponent!=NULL) {
|
---|
| 180 | this->activeOpponent->getAbsoluteVector(fireAt, fireAt);
|
---|
| 181 | fireAt.y++;
|
---|
| 182 | this->activeWeapon->setFireAt(fireAt);
|
---|
| 183 | } else if(this->activeGoodie!=NULL) {
|
---|
| 184 | this->activeGoodie->getAbsoluteVector(fireAt, fireAt);
|
---|
| 185 | this->activeWeapon->setFireAt(fireAt);
|
---|
| 186 | } else {
|
---|
| 187 | D3DXMATRIX mYaw;
|
---|
| 188 | Vector fireAt(0,0,1000);
|
---|
| 189 | //mYaw.setRotateY(this->rot.y*M_PI/180);
|
---|
| 190 | D3DXMatrixRotationY(&mYaw, this->myRotation.y);
|
---|
| 191 | fireAt.applyD3DXVector(D3DXVec4Transform(&fireAt, &fireAt, &mYaw));//.transform(fireAt);
|
---|
| 192 | fireAt = fireAt + this->myPosition;
|
---|
| 193 | this->getActiveWeapon()->setFireAt(fireAt);
|
---|
| 194 | }
|
---|
| 195 |
|
---|
| 196 | /*char temp[100];
|
---|
| 197 | Vector tp;
|
---|
| 198 | this->myScene->manager->printToConsole("---------------");
|
---|
| 199 | for(int i=0;i<4;i++) {
|
---|
| 200 | tp = this->wheel[i]->getPosition();
|
---|
| 201 | sprintf(temp, "x=%f, y=%f z=%f", tp.x, tp.y, tp.z);
|
---|
| 202 | this->myScene->manager->printToConsole(temp);
|
---|
| 203 | }*/
|
---|
| 204 | }
|
---|
| 205 |
|
---|
| 206 |
|
---|
| 207 | bool AIPlayer::isLeaving(Vector center, float ch) {
|
---|
| 208 | return ((center-this->getAbsolutePosition()).length()>0.9*ch);
|
---|
| 209 | }
|
---|
| 210 |
|
---|
| 211 | bool AIPlayer::isObstacleNear() {
|
---|
| 212 | NxVec3 direction = this->heading.getNxVector();
|
---|
| 213 | //direction.y = 0;
|
---|
| 214 | NxRay ray(this->getAbsolutePosition().getNxVector(), direction);
|
---|
| 215 | NxRaycastHit hit;
|
---|
| 216 |
|
---|
| 217 |
|
---|
| 218 | // Get the closest shape
|
---|
| 219 | NxU32 mask = 1<<UserContactReport::COLGROUP_OBSTACLE;
|
---|
| 220 |
|
---|
| 221 | NxShape* closestShape = this->myScene->pScene->raycastClosestShape(ray, NX_ALL_SHAPES, hit, mask, 20);//0xffffff);
|
---|
| 222 | if (closestShape)
|
---|
| 223 | {
|
---|
| 224 | this->obstaclePos = Vector(closestShape->getGlobalPosition());
|
---|
| 225 | return true;
|
---|
| 226 | } else {
|
---|
| 227 | return false;
|
---|
| 228 | }
|
---|
| 229 | }
|
---|
| 230 |
|
---|
| 231 | bool AIPlayer::isNear() {
|
---|
| 232 | bool isnear = false;
|
---|
| 233 | int zone = DRIVE_ZONE;
|
---|
| 234 | Vector opPos;
|
---|
| 235 | Vector neDir;
|
---|
| 236 | Vector neHead;
|
---|
| 237 | float distance;
|
---|
| 238 | float minDistance=10000000;
|
---|
| 239 |
|
---|
| 240 | //std::vector<Player *> *playerList = this->sMgr->getPlayerList();
|
---|
| 241 | std::list<SPTR<Node> > *playerList = ((GameScene *)this->myScene)->getPlayerList();
|
---|
| 242 | std::list<SPTR<Node> >::iterator it;
|
---|
| 243 | Player *tempActiveOpponent = NULL;
|
---|
| 244 | Player *opponent;
|
---|
| 245 | //for(unsigned int i=0;i<playerList->size();i++) {
|
---|
| 246 | for(it=playerList->begin();it!=playerList->end();it++) {
|
---|
| 247 | //opponent = playerList->at(i);
|
---|
| 248 | opponent = ((Player *) (*it).get());
|
---|
| 249 | if(opponent->getTeam()==this->getTeam()) {
|
---|
| 250 | continue;
|
---|
| 251 | }
|
---|
| 252 | if(opponent!=this) {
|
---|
| 253 | opPos = opponent->getAbsolutePosition();
|
---|
| 254 | neDir = opPos - this->getAbsolutePosition();
|
---|
| 255 | distance = neDir.length();
|
---|
| 256 | neDir.normalize();
|
---|
| 257 |
|
---|
| 258 | neHead = this->heading;
|
---|
| 259 | neHead.normalize();
|
---|
| 260 | if((neHead.dotProd(neDir))>0) {
|
---|
| 261 | isnear = true;
|
---|
| 262 | if(distance<COLL_DIST) {
|
---|
| 263 | this->myZone = COLL_ZONE;
|
---|
| 264 | return true;
|
---|
| 265 | }
|
---|
| 266 |
|
---|
| 267 | if(distance<minDistance) {
|
---|
| 268 | minDistance = distance;
|
---|
| 269 | tempActiveOpponent = opponent;
|
---|
| 270 |
|
---|
| 271 | if(distance<ATTACK_DIST) {
|
---|
| 272 | this->myZone = ATTACK_ZONE;
|
---|
| 273 | } else {
|
---|
| 274 | this->myZone = FIRE_ZONE;
|
---|
| 275 | }
|
---|
| 276 | }
|
---|
| 277 | }
|
---|
| 278 | }
|
---|
| 279 | }
|
---|
| 280 | this->activeOpponent = tempActiveOpponent;
|
---|
| 281 | return isnear;
|
---|
| 282 | }
|
---|
| 283 |
|
---|
| 284 | bool AIPlayer::isGoodieNear() {
|
---|
| 285 | bool isnear = false;
|
---|
| 286 | Vector goPos;
|
---|
| 287 | Vector goDir;
|
---|
| 288 | Vector goHead;
|
---|
| 289 | float distance;
|
---|
| 290 | float minDistance=10000000;
|
---|
| 291 |
|
---|
| 292 | //std::vector<Goodie *> *goodieList = this->sMgr->getGoodieList();
|
---|
| 293 | std::list<SPTR<Node> > *goodieList = ((GameScene *)this->myScene)->getGoodieList();
|
---|
| 294 | std::list<SPTR<Node> >::iterator it;
|
---|
| 295 | Goodie *tempActiveGoodie = NULL;
|
---|
| 296 | Goodie *goodie;
|
---|
| 297 | for(unsigned int i=0;i<goodieList->size();i++) {
|
---|
| 298 | //goodie = goodieList->at(i);
|
---|
| 299 | goodie = ((Goodie *) (*it).get());
|
---|
| 300 |
|
---|
| 301 | goPos = goodie->getPosition();
|
---|
| 302 | goDir = goPos - this->myPosition;
|
---|
| 303 | distance = goDir.length();
|
---|
| 304 | goDir.normalize();
|
---|
| 305 |
|
---|
| 306 | goHead = this->heading;
|
---|
| 307 | goHead.normalize();
|
---|
| 308 | if((goHead.dotProd(goDir))>0) {
|
---|
| 309 | isnear = true;
|
---|
| 310 |
|
---|
| 311 | if(distance<minDistance) {
|
---|
| 312 | minDistance = distance;
|
---|
| 313 | tempActiveGoodie = goodie;
|
---|
| 314 | }
|
---|
| 315 | }
|
---|
| 316 |
|
---|
| 317 | }
|
---|
| 318 | this->activeGoodie = tempActiveGoodie;
|
---|
| 319 | return isnear;
|
---|
| 320 | }
|
---|
| 321 |
|
---|
| 322 | void AIPlayer::driveAround(float dt, Vector center, float ch) {
|
---|
| 323 | this->drTimer+=dt;
|
---|
| 324 | if(lastNewPositionTime+3<this->drTimer) {
|
---|
| 325 | float x = (float)(((float) rand())/(RAND_MAX+1)-0.5)*2*ch;
|
---|
| 326 | float y = (float)(((float) rand())/(RAND_MAX+1)-0.5)*2*ch;
|
---|
| 327 | float z = 0;//(float)(((float) rand())/(RAND_MAX+1)-0.5)*2*ch;
|
---|
| 328 |
|
---|
| 329 | this->driveToPosition.setXYZ(x, y, z);
|
---|
| 330 | this->driveToPosition = this->driveToPosition + center;
|
---|
| 331 | this->lastNewPositionTime = this->drTimer;
|
---|
| 332 | }
|
---|
| 333 | this->driveTo(dt, this->driveToPosition, 0.2f);
|
---|
| 334 | }
|
---|
| 335 |
|
---|
| 336 | void AIPlayer::driveTo(float dt, Vector position, float speed) {
|
---|
| 337 |
|
---|
| 338 | Vector drDirection;
|
---|
| 339 | drDirection = position - this->getAbsolutePosition();
|
---|
| 340 | drDirection.y = 0;
|
---|
| 341 | drDirection.normalize();
|
---|
| 342 |
|
---|
| 343 | Vector drHeading;
|
---|
| 344 | drHeading = this->heading;
|
---|
| 345 | drHeading = drHeading*(-1);
|
---|
| 346 | drHeading.y = 0;
|
---|
| 347 | drHeading.normalize();
|
---|
| 348 |
|
---|
| 349 | Vector drUp(0, 1, 0);
|
---|
| 350 |
|
---|
| 351 | //Berechnen ob nach links oder rechts gefahren werden soll
|
---|
| 352 | Vector drNormDir;
|
---|
| 353 | drNormDir = drUp.crossProd(drDirection);
|
---|
| 354 |
|
---|
| 355 | float leftright = drNormDir.dotProd(drHeading);
|
---|
| 356 | bool driveLeft = (leftright>0) ? false : true;
|
---|
| 357 |
|
---|
| 358 | //Set steering
|
---|
| 359 | if(leftright!=0) {
|
---|
| 360 | if(driveLeft)
|
---|
| 361 | this->toLeft();
|
---|
| 362 | else
|
---|
| 363 | this->toRight();
|
---|
| 364 | }
|
---|
| 365 |
|
---|
| 366 | //Set speed
|
---|
| 367 | //this->accelerate(this->engineTorque<this->maxEngineTorque*speed);
|
---|
| 368 | if(this->engineForce<this->maxEngineForce*speed*0.5) {
|
---|
| 369 | this->accelerate();
|
---|
| 370 | }
|
---|
| 371 | }
|
---|
| 372 |
|
---|
| 373 | void AIPlayer::selectWeapon()
|
---|
| 374 | {
|
---|
| 375 | if(this->activeWeapon->getAmo()==0) {
|
---|
| 376 | for(int i=0;i<10;i++) {
|
---|
| 377 | if(this->weaponList[i] && this->weaponList[i]->getAmo()>0) {
|
---|
| 378 | this->setActiveWeapon(i);
|
---|
| 379 | return;
|
---|
| 380 | }
|
---|
| 381 | }
|
---|
| 382 | }
|
---|
| 383 | } |
---|