Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/campaignHS15/src/orxonox/controllers/DivisionController.cc @ 10849

Last change on this file since 10849 was 10849, checked in by gania, 8 years ago

major change: introduced Actionpoints, look AITest.oxw. Only FLY works for now

File size: 12.6 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Fabian 'x3n' Landau
24 *   Co-authors:
25 *      Dominik Solenicki
26 *
27 */
28
29#include "DivisionController.h"
30#include "infos/PlayerInfo.h"
31
32namespace orxonox
33{
34
35    RegisterClass(DivisionController);
36
37    //Leaders share the fact that they have Wingmans
38    DivisionController::DivisionController(Context* context) : LeaderController(context)
39    {
40        RegisterObject(DivisionController);
41       
42        this->setFormationMode(FormationMode::DIAMOND);
43        this->target_ = 0;
44        this->myFollower_ = 0;
45        this->myWingman_ = 0;
46        this->actionTimer_.setTimer(ACTION_INTERVAL, true, createExecutor(createFunctor(&DivisionController::action, this)));
47        this->rank_ = Rank::DIVISIONLEADER;
48
49
50    }
51
52    DivisionController::~DivisionController()
53    {
54    } 
55
56    void DivisionController::XMLPort(Element& xmlelement, XMLPort::Mode mode)
57    {
58        SUPER(DivisionController, XMLPort, xmlelement, mode);
59
60        //XMLPortParam(DivisionController, "target_", setTarget, getTarget, xmlelement, mode).defaultValues(100.0f);
61    }
62
63   
64    void DivisionController::tick(float dt)
65    {   
66
67        if (!this->isActive())
68            return;
69       
70       
71        SUPER(DivisionController, tick, dt);
72
73    }
74    void DivisionController::action()
75    {
76
77       
78  /*      if (this->target_)
79        {
80            if (CommonController::distance (this->getControllableEntity(), newTarget) <
81                CommonController::distance (this->getControllableEntity(), target_))
82            {
83                Actionpoint* ap = new Actionpoint(this->getContext());
84                ap->setPosition (0, 0, 0);
85                ap->setActionXML ("FIGHT");
86                //ap->setEnemyXML(CommonController::getName(newTarget));
87                this->addActionpoint (ap);
88            }
89
90        }*/
91        //----Whatever ship is doing, if there are targets close to it and its own target is far away, fight them----
92        //analog to attack move
93        if (this->action_ != Action::FIGHT && this->action_ != Action::FIGHTALL)
94        {
95            if ( (this->target_ && CommonController::distance (this->getControllableEntity(), this->target_) > this->attackRange_) 
96                || !this->target_ )
97            {
98                Pawn* newTarget = this->closestTarget();
99                if ( newTarget && 
100                    CommonController::distance (this->getControllableEntity(), static_cast<ControllableEntity*>(newTarget))
101                        <= this->attackRange_ )
102                {
103                    // this->backupAction();
104                    // this->setAction (Action::FIGHT, newTarget);
105                    Point p = { Action::FIGHT, CommonController::getName(newTarget), Vector3::ZERO };
106                    this->parsedActionpoints_.push_back(p);
107                    this->executeActionpoint();
108                }
109            }
110        }
111
112        //action is NONE whenever ships finishes current action,
113        //if it was fighting before because enemies were close, resume what it was doing
114        //otherwise try to execute next action
115        if (this->action_ == Action::NONE)
116        {
117            this->executeActionpoint();
118        }
119
120
121        //this->action_ is what I am actually executing, this->target_ is what I am
122        //actually attacking, etc.
123
124        //after action is finished, .pop_back() is to be called.
125        if (this->action_ == Action::FIGHT || this->action_ == Action::FIGHTALL)
126        {
127            if (!this->hasTarget())
128            {
129                //----find a target----
130                ControllableEntity* newTarget = this->closestTarget();
131                if (this->action_ == Action::FIGHT)
132                {
133                    if (newTarget && CommonController::distance (this->getControllableEntity(), newTarget) < this->attackRange_)
134                    {
135                        this->setAction (Action::FIGHT, newTarget);
136                    }
137                    else
138                    {
139                        this->nextActionpoint();
140                        return;
141                    }
142                }
143                else if (this->action_ == Action::FIGHTALL)
144                {
145                    if (newTarget && newTarget->getController())
146                    {
147                        this->setAction (Action::FIGHTALL, newTarget);
148                    }
149                    else
150                    {
151                        this->nextActionpoint();
152                        return;
153                    }
154                }
155
156            }
157            else if (this->hasTarget())
158            {
159                //----fly in formation if far enough----
160                Vector3 diffVector = this->positionOfTarget_ - this->getControllableEntity()->getWorldPosition();         
161               
162                   
163                if (diffVector.length() > this->attackRange_)
164                {
165                    if (this->action_ == Action::FIGHT)
166                    {
167                        this->nextActionpoint();
168                        return;
169                    }
170                    else
171                    {
172                        this->setTargetPositionOfWingman();
173                        this->setTargetPositionOfFollower();                   
174                    }
175
176                }
177                else
178                {
179                    //----wingmans shall support the fire of their leaders----
180                    if (this->myWingman_)
181                    {
182                        this->myWingman_->setAction (this->action_, this->target_);     
183                    }
184                    if (this->myFollower_)
185                    {
186                        this->myFollower_->setAction (this->action_);                                   
187                    }
188
189                }
190               
191            }
192            if (this->hasTarget())
193            {
194                //----choose where to go----
195                this->maneuver();
196                //----fire if you can----
197                this->bShooting_ = this->canFire();               
198            }
199
200        }
201        else if (this->action_ == Action::FLY)
202        {
203
204            if (this->squaredDistanceToTarget() <= this->squaredaccuracy_)
205            {
206                orxout(internal_error) << "arrived";
207                this->nextActionpoint();
208                return;
209            }
210            this->setTargetPositionOfWingman();
211            this->setTargetPositionOfFollower();
212        }
213        else if (this->action_ == Action::PROTECT)
214        {
215            if (!this->getProtect())
216            {
217                this->nextActionpoint();
218                return;
219            }
220           /* if (this->myWingman_)
221                this->myWingman_->setAction (Action::PROTECT, this->getProtect());
222            if (this->myFollower_)
223                this->myFollower_->setAction (Action::PROTECT, this->getProtect());
224            */
225            Vector3* targetRelativePosition;
226               
227            targetRelativePosition = new Vector3 (0, 0, 500); 
228 
229            Vector3 targetAbsolutePosition = ((this->getProtect()->getWorldPosition()) + 
230                (this->getProtect()->getWorldOrientation()* (*targetRelativePosition)));
231            this->setTargetPosition(targetAbsolutePosition);
232           
233            this->setTargetPositionOfWingman();
234            this->setTargetPositionOfFollower();
235
236        }
237        else if (this->action_ == Action::ATTACK)
238        {   
239            if (!this->hasTarget())
240            {
241                this->nextActionpoint();
242                return;
243            }
244            //----fly in formation if far enough----
245            Vector3 diffVector = this->positionOfTarget_ - this->getControllableEntity()->getWorldPosition();         
246            if (diffVector.length() > this->attackRange_)
247            {
248                this->setTargetPositionOfWingman();
249                this->setTargetPositionOfFollower();                   
250            }
251            else
252            {
253                //----wingmans shall support the fire of their leaders----
254                if (this->myWingman_)
255                {
256                    this->myWingman_->setAction (this->action_, this->target_);     
257                }
258                if (this->myFollower_)
259                {
260                    this->myFollower_->setAction (this->action_);                                   
261                }
262
263            }
264           
265            //----choose where to go----
266            this->maneuver();
267            //----fire if you can----
268            this->bShooting_ = this->canFire();               
269        }
270
271    }
272
273   
274
275    void DivisionController::setTargetPositionOfWingman()
276    {
277        if (!this->myWingman_)
278            return;
279        Vector3* targetRelativePositionOfWingman;
280        switch (this->formationMode_){
281            case FormationMode::WALL:
282            {
283                targetRelativePositionOfWingman = new Vector3 (400, 0, 0); 
284                break;
285            }
286            case FormationMode::FINGER4: 
287            {
288                targetRelativePositionOfWingman = new Vector3 (400, 0, 200); 
289                break;
290            }
291         
292            case FormationMode::DIAMOND: 
293            {
294                targetRelativePositionOfWingman = new Vector3 (400, 0, 200);                 
295                break;
296            }
297        }
298        Quaternion orient = this->getControllableEntity()->getWorldOrientation();
299       
300        Vector3 targetAbsolutePositionOfWingman = ((this->getControllableEntity()->getWorldPosition()) + 
301        (this->getControllableEntity()->getWorldOrientation()* (*targetRelativePositionOfWingman)));
302       
303        myWingman_->setAction( Action::FLY, targetAbsolutePositionOfWingman, orient);
304       
305    }
306    void DivisionController::setTargetPositionOfFollower()
307    {
308        if (!this->myFollower_)
309            return;
310        this->myFollower_->setFormationMode(this->formationMode_);
311
312        Vector3* targetRelativePositionOfFollower;
313        switch (this->formationMode_){
314            case FormationMode::WALL:
315            {
316                targetRelativePositionOfFollower = new Vector3 (-400, 0, 0);   
317                break;
318            }
319            case FormationMode::FINGER4: 
320            {
321                targetRelativePositionOfFollower = new Vector3 (-400, 0, 200);   
322                break;
323            }
324           
325            case FormationMode::DIAMOND: 
326            {
327                targetRelativePositionOfFollower = new Vector3 (-400, 0, 200);                   
328                break;
329            }
330        }
331        Quaternion orient = this->getControllableEntity()->getWorldOrientation();
332       
333        Vector3 targetAbsolutePositionOfFollower = ((this->getControllableEntity()->getWorldPosition()) + 
334        (this->getControllableEntity()->getWorldOrientation()* (*targetRelativePositionOfFollower)));
335       
336        myFollower_->setAction ( Action::FLY, targetAbsolutePositionOfFollower, orient );       
337    }
338
339
340    bool DivisionController::setWingman(CommonController* cwingman)
341    {
342
343        WeakPtr<WingmanController> wingman = orxonox_cast<WingmanController*>(cwingman);
344        if (!this->myWingman_)
345        {
346            this->myWingman_ = wingman;
347            return true;
348        }
349        else
350        {
351            return false;
352        }
353   
354    }
355    bool DivisionController::setFollower(LeaderController* myFollower)
356    {
357         if (!this->myFollower_)
358        {
359            this->myFollower_ = myFollower;
360            return true;
361        }
362        else
363        {
364            return false;
365        }
366    }
367    bool DivisionController::hasWingman()
368    {
369        if (this->myWingman_)
370            return true;
371        else
372            return false;
373    }
374    bool DivisionController::hasFollower()
375    {
376        if (this->myFollower_)
377            return true;
378        else
379            return false;
380    }
381
382
383   
384   
385
386}
Note: See TracBrowser for help on using the repository browser.