Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/cpp11_v3/src/orxonox/controllers/SectionController.cc @ 11054

Last change on this file since 11054 was 11054, checked in by landauf, 8 years ago

merged branch cpp11_v2 into cpp11_v3

  • Property svn:eol-style set to native
File size: 9.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 *      Gani Aliguzhinov
24 *   Co-authors:
25 *      ...
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) : ActionpointController(context)
38    {
39        RegisterObject(SectionController);
40        this->setFormationMode(FormationMode::FINGER4);
41
42        this->myWingman_ = 0;
43        this->myDivisionLeader_ = 0;
44        this->bFirstAction_ = true;
45
46    }
47   
48    SectionController::~SectionController()
49    {
50       for (size_t i = 0; i < this->actionpoints_.size(); ++i)
51        {
52            if(this->actionpoints_[i])
53                this->actionpoints_[i]->destroy();
54        }
55        this->parsedActionpoints_.clear();
56        this->actionpoints_.clear();
57    }
58    void SectionController::XMLPort(Element& xmlelement, XMLPort::Mode mode)
59    {
60        SUPER(SectionController, XMLPort, xmlelement, mode);
61    }
62
63    //----in tick, move (or look) and shoot----
64    void SectionController::tick(float dt)
65    {
66        if (!this->isActive())
67            return;
68   
69        SUPER(SectionController, tick, dt);
70       
71    }
72
73    void SectionController::action()
74    {
75        if (!this || !this->getControllableEntity() || !this->isActive())
76            return;
77
78        //----If no leader, find one---- 
79        if (!myDivisionLeader_)
80        {
81            ActionpointController* newDivisionLeader = findNewDivisionLeader();
82            if (!this || !this->getControllableEntity())
83                return;
84
85            this->myDivisionLeader_ = newDivisionLeader;
86        }
87        //----If have leader----
88        else
89        {
90        }
91        if (!myDivisionLeader_)
92        {
93            ActionpointController::action();
94            if (!this || !this->getControllableEntity())
95                return;
96            if (!(this->parsedActionpoints_.empty() && this->loopActionpoints_.empty()))
97            {
98                if (this->myWingman_)
99                {
100                    this->myWingman_->takeActionpoints(this->parsedActionpoints_, this->loopActionpoints_, this->bLoop_);
101                }   
102            }
103        }
104        else if (myDivisionLeader_)
105        {
106            if (this->myDivisionLeader_->bKeepFormation_ || !(this->myDivisionLeader_->getAction() == Action::FIGHT
107                || this->myDivisionLeader_->getAction() == Action::FIGHTALL
108                || this->myDivisionLeader_->getAction() == Action::ATTACK))
109            {
110                this->keepFormation();
111            }
112            else if (!this->myDivisionLeader_->bKeepFormation_)
113            {
114                if (!this || !this->getControllableEntity())
115                    return;
116
117                if (!this->hasTarget())
118                {
119                    this->chooseTarget(); 
120                }
121
122            }
123        }
124
125    }
126
127   
128    //PRE: myDivisionLeader_ != 0 && myDivisionLeader_->action_ == Action::FIGHT
129    //POST: this->target_ is set unless division leader doesn't have one
130    void SectionController::chooseTarget()
131    {
132        //----If division leader fights, cover him by fighting emenies close to his target----
133        Action::Value action = this->myDivisionLeader_->getAction();
134
135        if (action == Action::FIGHT || action == Action::FIGHTALL || action == Action::ATTACK)
136        {
137            Pawn* target;
138            //----if he has a target----
139            if (this->myDivisionLeader_->hasTarget())
140            {
141                //----try to find a new target if division leader has wingman (doing fine) and no good target already set----
142                if ( this->myDivisionLeader_->hasWingman() && 
143                    !( this->hasTarget() && this->getTarget() != this->myDivisionLeader_->getTarget() ) )
144                {
145                    bool foundTarget = false;
146                    //----new target should be close to division's target----
147                    Vector3 divisionTargetPosition = this->myDivisionLeader_->getTarget()->getWorldPosition();
148                    Gametype* gt = this->getGametype();
149                    for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>().begin(); itP; ++itP)
150                    {
151                        //----is enemy?----
152                        if ( CommonController::sameTeam (this->getControllableEntity(), static_cast<ControllableEntity*>(*itP), gt) )
153                            continue;           
154                        //----in range?----
155                        if (((*itP)->getWorldPosition() - divisionTargetPosition).length() < 3000 && 
156                            (*itP) != this->myDivisionLeader_->getTarget())
157                        {
158                            foundTarget = true;
159                            target =  (*itP);
160                            break; 
161                        }
162                    }
163                    //----no target? then attack same target as division leader----
164                    if (!foundTarget)
165                    {
166                        target = orxonox_cast<Pawn*>(this->myDivisionLeader_->getTarget());
167                    }
168                }
169                //----if division leader doesn't have a wingman, support his fire----
170                else
171                {
172                    target = orxonox_cast<Pawn*>(this->myDivisionLeader_->getTarget());
173                }
174            }
175            //----If he fights but doesn't have a target, wait for him to get one----
176            else
177            {
178
179            }
180            this->setTarget (orxonox_cast<ControllableEntity*>(target));
181        }
182        else
183        {
184        } 
185    }
186    Vector3 SectionController::getFormationPosition ()
187    {
188        this->setFormationMode( this->myDivisionLeader_->getFormationMode() );
189        this->spread_ = this->myDivisionLeader_->getSpread();
190        Vector3* targetRelativePosition;
191        switch (this->formationMode_){
192            case FormationMode::WALL:
193            {
194                targetRelativePosition = new Vector3 (-2.0f*this->spread_, 0, 0);   
195                break;
196            }
197            case FormationMode::FINGER4: 
198            {
199                targetRelativePosition = new Vector3 (-2.0f*this->spread_, 0, 1.0f*this->spread_);   
200                break;
201            }
202           
203            case FormationMode::DIAMOND: 
204            {
205                targetRelativePosition = new Vector3 (-2.0f*this->spread_, 0, 1.0f*this->spread_);
206                break;
207            }
208        }
209        Vector3 result = *targetRelativePosition;
210        delete targetRelativePosition;
211        return result;
212    }
213
214    void SectionController::keepFormation()
215    {
216        this->bKeepFormation_ = true;
217        ControllableEntity* leaderEntity = this->myDivisionLeader_->getControllableEntity();
218        Vector3 targetRelativePosition = this->getFormationPosition();
219        if (!leaderEntity)
220            return;
221        FlyingController::keepFormation(leaderEntity, targetRelativePosition);
222    }
223
224    ActionpointController* SectionController::findNewDivisionLeader()
225    {
226
227        if (!this->getControllableEntity())
228            return 0;
229
230        ActionpointController* closestLeader = 0;
231        float minDistance =  std::numeric_limits<float>::infinity();
232        //go through all pawns
233        for (ObjectList<ActionpointController>::iterator it = ObjectList<ActionpointController>().begin(); it; ++it)
234        {
235            //0ptr or not DivisionController?
236            if (!(it) || !((it)->getIdentifier()->getName() == "DivisionController") || !(it->getControllableEntity()))
237                continue;
238            //same team?
239            if ((this->getControllableEntity()->getTeam() != (it)->getControllableEntity()->getTeam()))
240                continue;
241
242            //is equal to this?
243            if (orxonox_cast<ControllableEntity*>(*it) == this->getControllableEntity())
244                continue;
245
246            float distance = CommonController::distance (it->getControllableEntity(), this->getControllableEntity());
247           
248            if (distance < minDistance && !(it->hasFollower()))
249            {
250                closestLeader = *it;
251                minDistance = distance;
252            }
253         
254        }
255        if (closestLeader)
256        {
257            if (closestLeader->setFollower(this))
258                return closestLeader;
259        }
260        return 0;
261    }
262
263    bool SectionController::setWingman(ActionpointController* newWingman)
264    {
265
266        if (!this->myWingman_)
267        {
268            this->myWingman_ = newWingman;
269            newWingman->takeActionpoints (this->parsedActionpoints_, this->loopActionpoints_, this->bLoop_);
270            return true;
271        }
272        else
273        {
274            return false;
275        }
276    }
277   
278    bool SectionController::hasWingman()
279    {
280        if (this->myWingman_)
281            return true;
282        else
283            return false;
284    }
285}
Note: See TracBrowser for help on using the repository browser.