Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 10955 was 10946, checked in by gania, 9 years ago

fix for sigsegv?

File size: 9.8 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            //spread copyOrientation called equally among the division
87
88        }
89        //----If have leader----
90        else
91        {
92        }
93        if (!myDivisionLeader_)
94        {
95            ActionpointController::action();
96            if (!this || !this->getControllableEntity())
97                return;
98            if (!(this->parsedActionpoints_.empty() && this->loopActionpoints_.empty()))
99            {
100                if (this->myWingman_)
101                {
102                    this->myWingman_->takeActionpoints(this->parsedActionpoints_, this->loopActionpoints_, this->bLoop_);
103                }   
104            }
105        }
106        else if (myDivisionLeader_)
107        {
108            if (this->myDivisionLeader_->bKeepFormation_ || !(this->myDivisionLeader_->getAction() == Action::FIGHT
109                || this->myDivisionLeader_->getAction() == Action::FIGHTALL
110                || this->myDivisionLeader_->getAction() == Action::ATTACK))
111            {
112                this->keepFormation();
113                //orxout (internal_error) << "Keeping formation" << endl;
114
115            }
116            else if (!this->myDivisionLeader_->bKeepFormation_)
117            {
118                if (!this || !this->getControllableEntity())
119                    return;
120
121                if (!this->hasTarget())
122                {
123                    this->chooseTarget(); 
124                }
125
126            }
127        }
128
129    }
130
131   
132    //PRE: myDivisionLeader_ != 0 && myDivisionLeader_->action_ == Action::FIGHT
133    //POST: this->target_ is set unless division leader doesn't have one
134    void SectionController::chooseTarget()
135    {
136        //----If division leader fights, cover him by fighting emenies close to his target----
137        Action::Value action = this->myDivisionLeader_->getAction();
138
139        if (action == Action::FIGHT || action == Action::FIGHTALL || action == Action::ATTACK)
140        {
141            Pawn* target;
142            //----if he has a target----
143            if (this->myDivisionLeader_->hasTarget())
144            {
145                //----try to find a new target if division leader has wingman (doing fine) and no good target already set----
146                if ( this->myDivisionLeader_->hasWingman() && 
147                    !( this->hasTarget() && this->getTarget() != this->myDivisionLeader_->getTarget() ) )
148                {
149                    bool foundTarget = false;
150                    //----new target should be close to division's target----
151                    Vector3 divisionTargetPosition = this->myDivisionLeader_->getTarget()->getWorldPosition();
152                    Gametype* gt = this->getGametype();
153                    for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
154                    {
155                        //----is enemy?----
156                        if ( CommonController::sameTeam (this->getControllableEntity(), static_cast<ControllableEntity*>(*itP), gt) )
157                            continue;           
158                        //----in range?----
159                        if (((*itP)->getWorldPosition() - divisionTargetPosition).length() < 3000 && 
160                            (*itP) != this->myDivisionLeader_->getTarget())
161                        {
162                            foundTarget = true;
163                            target =  (*itP);
164                            //orxout(internal_error) << "Found target" << endl;
165                            break; 
166                        }
167                    }
168                    //----no target? then attack same target as division leader----
169                    if (!foundTarget)
170                    {
171                        target = orxonox_cast<Pawn*>(this->myDivisionLeader_->getTarget());
172                    }
173                }
174                //----if division leader doesn't have a wingman, support his fire----
175                else
176                {
177                    target = orxonox_cast<Pawn*>(this->myDivisionLeader_->getTarget());
178                }
179            }
180            //----If he fights but doesn't have a target, wait for him to get one----
181            else
182            {
183
184            }
185            this->setTarget (orxonox_cast<ControllableEntity*>(target));
186        }
187        else
188        {
189        } 
190    }
191    Vector3 SectionController::getFormationPosition ()
192    {
193        this->setFormationMode( this->myDivisionLeader_->getFormationMode() );
194        this->spread_ = this->myDivisionLeader_->getSpread();
195        Vector3* targetRelativePosition;
196        switch (this->formationMode_){
197            case FormationMode::WALL:
198            {
199                targetRelativePosition = new Vector3 (-2*this->spread_, 0, 0);   
200                break;
201            }
202            case FormationMode::FINGER4: 
203            {
204                targetRelativePosition = new Vector3 (-2*this->spread_, 0, this->spread_);   
205                break;
206            }
207           
208            case FormationMode::DIAMOND: 
209            {
210                targetRelativePosition = new Vector3 (-2*this->spread_, 0, this->spread_);                   
211                break;
212            }
213        }
214        Vector3 result = *targetRelativePosition;
215        delete targetRelativePosition;
216        return result;
217    }
218
219    void SectionController::keepFormation()
220    {
221        this->bKeepFormation_ = true;
222        ControllableEntity* leaderEntity = this->myDivisionLeader_->getControllableEntity();
223        Vector3 targetRelativePosition = this->getFormationPosition();
224        if (!leaderEntity)
225            return;
226        FlyingController::keepFormation(leaderEntity, targetRelativePosition);
227    }
228
229    ActionpointController* SectionController::findNewDivisionLeader()
230    {
231
232        if (!this->getControllableEntity())
233            return 0;
234
235        ActionpointController* closestLeader = 0;
236        float minDistance =  std::numeric_limits<float>::infinity();
237        //go through all pawns
238        for (ObjectList<ActionpointController>::iterator it = ObjectList<ActionpointController>::begin(); it; ++it)
239        {
240            //0ptr or not DivisionController?
241            if (!(it) || !((it)->getIdentifier()->getName() == "DivisionController") || !(it->getControllableEntity()))
242                continue;
243            //same team?
244            if ((this->getControllableEntity()->getTeam() != (it)->getControllableEntity()->getTeam()))
245                continue;
246
247            //is equal to this?
248            if (orxonox_cast<ControllableEntity*>(*it) == this->getControllableEntity())
249                continue;
250
251            float distance = CommonController::distance (it->getControllableEntity(), this->getControllableEntity());
252           
253            if (distance < minDistance && !(it->hasFollower()))
254            {
255                closestLeader = *it;
256                minDistance = distance;
257            }
258         
259        }
260        if (closestLeader)
261        {
262            if (closestLeader->setFollower(this))
263                return closestLeader;
264        }
265        return 0;
266    }
267
268    bool SectionController::setWingman(ActionpointController* newWingman)
269    {
270
271        if (!this->myWingman_)
272        {
273            this->myWingman_ = newWingman;
274            newWingman->takeActionpoints (this->parsedActionpoints_, this->loopActionpoints_, this->bLoop_);
275            return true;
276        }
277        else
278        {
279            return false;
280        }
281    }
282   
283    bool SectionController::hasWingman()
284    {
285        if (this->myWingman_)
286            return true;
287        else
288            return false;
289    }
290}
Note: See TracBrowser for help on using the repository browser.