source: GTP/trunk/App/Games/Jungle_Rumble/src/AIPlayer.cpp @ 1378

Revision 1378, 10.4 KB checked in by giegl, 18 years ago (diff)

GTPD - Jungle Rumble - integrate into GTP SVN structure

Line 
1#include "dxstdafx.h"
2#include ".\aiplayer.h"
3#include "GameScene.h"
4#include "Terrain.h"
5#include "Goodie.h"
6
7AIPlayer::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
28AIPlayer::~AIPlayer(void) {
29}
30
31//TODO OPPONENT AND GOODIE SHOULD BE SMART POINTER!!!!!
32void 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
207bool AIPlayer::isLeaving(Vector center, float ch) {
208        return ((center-this->getAbsolutePosition()).length()>0.9*ch);
209}
210
211bool 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
231bool 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
284bool 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
322void 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
336void 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
373void 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}
Note: See TracBrowser for help on using the repository browser.