Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/campaignHS15/src/orxonox/controllers/SectionController.cc @ 10851

Last change on this file since 10851 was 10851, checked in by gania, 10 years ago

works for the most part, still need to fix Section and Wingman

File size: 16.2 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 "SectionController.h"
30
31namespace orxonox
32{
33
34    RegisterClass(SectionController);
35
36    //Leaders share the fact that they have Wingmans
37    SectionController::SectionController(Context* context) : LeaderController(context)
38    {
39        RegisterObject(SectionController);
40        this->setFormationMode(FormationMode::FINGER4);
41
42        this->actionTimer_.setTimer(ACTION_INTERVAL, true, createExecutor(createFunctor(&SectionController::action, this)));
43        this->myWingman_ = 0;
44        this->myDivisionLeader_ = 0;
45        this->rank_ = Rank::SECTIONLEADER;
46        this->bFirstAction_ = true;
47        //orxout(internal_error) << this << "Was created" << endl;
48
49    }
50   
51    SectionController::~SectionController()
52    {
53       
54    }
55    void SectionController::XMLPort(Element& xmlelement, XMLPort::Mode mode)
56    {
57        SUPER(SectionController, XMLPort, xmlelement, mode);
58
59        //XMLPortParam(SectionController, "target_", setTarget, getTarget, xmlelement, mode).defaultValues(100.0f);
60    }
61
62    //----in tick, move (or look) and shoot----
63    void SectionController::tick(float dt)
64    {
65        if (!this->isActive())
66            return;
67     
68       
69        SUPER(SectionController, tick, dt);
70    }
71
72    void SectionController::action()
73    {
74
75        //----If no leader, find one---- 
76        if (!myDivisionLeader_)
77        {
78            LeaderController* newDivisionLeader = findNewDivisionLeader();
79            this->myDivisionLeader_ = newDivisionLeader;
80
81        }
82        //----If have leader----
83        else
84        {
85        }
86        if (!myDivisionLeader_)
87        {
88            if (this->startAttackingEnemiesThatAreClose())
89            {
90                Point p = { Action::FIGHT, "", Vector3::ZERO };
91               
92                if (this->myWingman_)
93                {
94                    this->myWingman_->parsedActionpoints_.push_back(p);
95                }
96            }
97            if (this->action_ == Action::NONE)
98            {
99                this->executeActionpoint();
100            }
101            if (this->action_ == Action::FIGHT || this->action_ == Action::FIGHTALL)
102            {
103                if (!this->hasTarget())
104                {
105                    //----find a target----
106                    ControllableEntity* newTarget = this->closestTarget();
107                    if (this->action_ == Action::FIGHT)
108                    {
109                        if (newTarget && 
110                                CommonController::distance (this->getControllableEntity(), newTarget) < this->attackRange_)
111                        {
112                            this->setAction (Action::FIGHT, newTarget);
113                        }
114                        else
115                        {
116                            this->nextActionpoint();
117                            if (this->myWingman_)
118                            {
119                                this->myWingman_->nextActionpoint();
120                            }
121               
122                            return;
123                        }
124                    }
125                    else if (this->action_ == Action::FIGHTALL)
126                    {
127                        if (newTarget && newTarget->getController())
128                        {
129                            this->setAction (Action::FIGHTALL, newTarget);
130                        }
131                        else
132                        {
133                            this->nextActionpoint();
134                            if (this->myWingman_)
135                            {
136                                this->myWingman_->nextActionpoint();
137                            }
138                            return;
139                        }
140                    }
141
142                }
143                else if (this->hasTarget())
144                {
145                    //----fly in formation if far enough----
146                    Vector3 diffVector = this->positionOfTarget_ - this->getControllableEntity()->getWorldPosition();         
147                       
148                    if (diffVector.length() > this->attackRange_)
149                    {
150                        if (this->action_ == Action::FIGHT)
151                        {
152                            this->nextActionpoint();
153                            if (this->myWingman_)
154                            {
155                                this->myWingman_->nextActionpoint();
156                            }
157                            return;
158                        }
159                        else
160                        {
161                            this->setTargetPositionOfWingman();
162                        }
163                    }
164                    else
165                    {
166                        //----wingmans shall support the fire of their leaders----
167                        if (this->myWingman_)
168                        {
169                            this->myWingman_->setAction (Action::FIGHT, this->target_);     
170                        }
171                       
172                    }
173                }
174            }
175            else if (this->action_ == Action::FLY)
176            {
177                if (this->squaredDistanceToTarget() <= this->squaredaccuracy_)
178                {
179                    this->nextActionpoint();
180                    if (this->myWingman_)
181                    {
182                        this->myWingman_->nextActionpoint();
183                    }
184                    return;
185                }
186                this->setTargetPositionOfWingman();
187            }
188            else if (this->action_ == Action::PROTECT)
189            {
190                if (!this->getProtect())
191                {
192                    this->nextActionpoint();
193                    if (this->myWingman_)
194                    {
195                        this->myWingman_->nextActionpoint();
196                    }
197                    return;
198                }
199
200                Vector3* targetRelativePosition;
201                   
202                targetRelativePosition = new Vector3 (0, 300, 300); 
203     
204                Vector3 targetAbsolutePosition = ((this->getProtect()->getWorldPosition()) + 
205                    (this->getProtect()->getWorldOrientation()* (*targetRelativePosition)));
206                this->setTargetPosition(targetAbsolutePosition);
207               
208                this->setTargetPositionOfWingman();
209
210            }
211            else if (this->action_ == Action::ATTACK)
212            {   
213                if (!this->hasTarget())
214                {
215                    this->nextActionpoint();
216                    if (this->myWingman_)
217                    {
218                        this->myWingman_->nextActionpoint();
219                    }
220                    return;
221                }
222                //----fly in formation if far enough----
223                Vector3 diffVector = this->positionOfTarget_ - this->getControllableEntity()->getWorldPosition();         
224                if (diffVector.length() > this->attackRange_)
225                {
226                    this->setTargetPositionOfWingman();
227                }
228                else
229                {
230                    //----wingmans shall support the fire of their leaders----
231                    if (this->myWingman_)
232                    {
233                        this->myWingman_->setAction (Action::FIGHT, this->target_);     
234                    }
235     
236                }         
237            }
238            if (this->hasTarget())
239            {
240                //----choose where to go----
241                this->maneuver();
242                //----fire if you can----
243                this->bShooting_ = this->canFire();               
244            }
245        }
246        //----If have leader----
247        else
248        {
249            //----action was set to fight----
250            if (this->action_ == Action::FIGHT)
251            {
252                if (!this->hasTarget())
253                {
254                    this->chooseTarget();
255                }
256                else
257                {
258                    //----fly in formation if far enough----
259                    Vector3 diffVector = this->positionOfTarget_ - this->getControllableEntity()->getWorldPosition();         
260                    if (diffVector.length() > this->attackRange_)
261                    {
262                        this->setTargetPositionOfWingman();
263                    }   
264                    else
265                    {
266                        //----wingmans shall support the fire of their leaders----
267                        if (this->myWingman_)
268                        {
269                            this->myWingman_->setAction (Action::FIGHT, this->target_);                   
270                        }
271                    }
272                }
273                if (this->hasTarget())
274                {
275                    //----choose where to go----
276                    this->maneuver();
277                    //----fire if you can----
278                    this->bShooting_ = this->canFire();               
279                }
280            }
281
282            //----action was set to fly----
283            else if (this->action_ == Action::FLY)
284            {
285                this->setTargetPositionOfWingman();
286                Pawn* newTarget = this->closestTarget();
287                if ( newTarget &&  this->distance (this->getControllableEntity(), 
288                                                    static_cast<ControllableEntity*>(newTarget)) <= this->attackRange_ )
289                {
290                    this->setAction (Action::FIGHT, static_cast<ControllableEntity*>(newTarget));
291                }
292            }       
293        }
294        if (this->bFirstAction_ && this->myDivisionLeader_)
295        {
296            this->parsedActionpoints_ = this->myDivisionLeader_->parsedActionpoints_;
297            this->bFirstAction_ = false;
298        }
299    }
300    //PRE: myDivisionLeader_ != 0 && myDivisionLeader_->action_ == Action::FIGHT
301    //POST: this->target_ is set unless division leader doesn't have one
302    void SectionController::chooseTarget()
303    {
304        //----If division leader fights, cover him by fighting emenies close to his target----
305        if (this->myDivisionLeader_->getAction() == Action::FIGHT)
306        {
307            //----if he has a target----
308            if (this->myDivisionLeader_->hasTarget())
309            {
310                //----try to find a new target if division leader has wingman (doing fine) and no good target already set----
311                if ( this->myDivisionLeader_->hasWingman() && 
312                    !( this->hasTarget() && this->getTarget() != this->myDivisionLeader_->getTarget() ) )
313                {
314
315                    bool foundTarget = false;
316                    //----new target should be close to division's target----
317                    Vector3 divisionTargetPosition = this->myDivisionLeader_->getTarget()->getWorldPosition();
318                    Gametype* gt = this->getGametype();
319                    for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
320                    {
321                        //----is enemy?----
322                        if ( CommonController::sameTeam (this->getControllableEntity(), static_cast<ControllableEntity*>(*itP), gt) )
323                            continue;           
324                        //----in range?----
325                        if (((*itP)->getWorldPosition() - divisionTargetPosition).length() < 3000 && 
326                            (*itP) != this->myDivisionLeader_->getTarget())
327                        {
328                            foundTarget = true;
329                            this->setAction(Action::FIGHT, (*itP));
330                            //orxout(internal_error) << "Found target" << endl;
331                            break; 
332                        }
333                    }
334                    //----no target? then attack same target as division leader----
335                    if (!foundTarget)
336                    {
337                        this->setAction(Action::FIGHT, this->myDivisionLeader_->getTarget());
338                    }
339                }
340                //----if division leader doesn't have a wingman, support his fire----
341                else
342                {
343                    this->setAction(Action::FIGHT, this->myDivisionLeader_->getTarget());
344                }
345            }
346            //----If he fights but doesn't have a target, wait for him to get one----
347            else
348            {
349
350            }
351        } 
352    }
353
354    //----stay in formation----
355    //gani-TODO: sum targetAbso... and this->predicted position
356    void SectionController::setTargetPositionOfWingman()
357    {
358        if (!this->myWingman_)
359            return;
360        Vector3* targetRelativePositionOfWingman;
361        switch (this->formationMode_){
362            case FormationMode::WALL:
363            {
364                targetRelativePositionOfWingman = new Vector3 (-400, 0, 0); 
365                break;
366            }
367            case FormationMode::FINGER4: 
368            {
369                targetRelativePositionOfWingman = new Vector3 (-400, 0, 200); 
370                break;
371            }
372            case FormationMode::DIAMOND: 
373            {
374                targetRelativePositionOfWingman = new Vector3 (400, -200, 0);                 
375                break;
376            }
377        }
378        Quaternion orient = this->getControllableEntity()->getWorldOrientation();
379       
380        Vector3 targetAbsolutePositionOfWingman = ((this->getControllableEntity()->getWorldPosition()) + 
381        (this->getControllableEntity()->getWorldOrientation()* (*targetRelativePositionOfWingman)));
382       
383        myWingman_->setAction (Action::FLY, targetAbsolutePositionOfWingman, orient);
384       
385    }
386
387    LeaderController* SectionController::findNewDivisionLeader()
388    {
389
390        if (!this->getControllableEntity())
391            return 0;
392
393        LeaderController* closestLeader = 0;
394        float minDistance =  std::numeric_limits<float>::infinity();
395        //go through all pawns
396        for (ObjectList<LeaderController>::iterator it = ObjectList<LeaderController>::begin(); it; ++it)
397        {
398            //0ptr or not DivisionController?
399            if (!(it) || !((it)->getRank() == Rank::DIVISIONLEADER) || !(it->getControllableEntity()))
400                continue;
401            //same team?
402            if ((this->getControllableEntity()->getTeam() != (it)->getControllableEntity()->getTeam()))
403                continue;
404
405            //is equal to this?
406            if (orxonox_cast<ControllableEntity*>(*it) == this->getControllableEntity())
407                continue;
408
409            float distance = CommonController::distance (it->getControllableEntity(), this->getControllableEntity());
410           
411            if (distance < minDistance && !(it->hasFollower()))
412            {
413                closestLeader = *it;
414                minDistance = distance;
415            }
416         
417        }
418        if (closestLeader)
419        {
420            if (closestLeader->setFollower(this))
421                return closestLeader;
422        }
423        return 0;
424    }
425    bool SectionController::setWingman(CommonController* cwingman)
426    {
427        WeakPtr<WingmanController> wingman = orxonox_cast<WingmanController*>(cwingman);
428
429        if (!this->myWingman_)
430        {
431            this->myWingman_ = wingman;
432            return true;
433        }
434        else
435        {
436            return false;
437        }
438    }
439   
440    bool SectionController::hasWingman()
441    {
442        if (this->myWingman_)
443            return true;
444        else
445            return false;
446    }
447}
Note: See TracBrowser for help on using the repository browser.