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, 10 years ago

fix for sigsegv?

File size: 9.8 KB
RevLine 
[10719]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:
[10885]23 *      Gani Aliguzhinov
[10719]24 *   Co-authors:
[10885]25 *      ...
[10719]26 *
27 */
28
29#include "SectionController.h"
[10935]30
[10719]31namespace orxonox
32{
33
34    RegisterClass(SectionController);
35
[10826]36    //Leaders share the fact that they have Wingmans
[10886]37    SectionController::SectionController(Context* context) : ActionpointController(context)
[10719]38    {
39        RegisterObject(SectionController);
[10759]40        this->setFormationMode(FormationMode::FINGER4);
[10725]41
42        this->myWingman_ = 0;
43        this->myDivisionLeader_ = 0;
[10851]44        this->bFirstAction_ = true;
[10719]45
46    }
47   
48    SectionController::~SectionController()
49    {
[10854]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();
[10725]57    }
[10826]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----
[10731]64    void SectionController::tick(float dt)
65    {
[10843]66        if (!this->isActive())
[10731]67            return;
[10886]68   
[10731]69        SUPER(SectionController, tick, dt);
[10935]70       
[10731]71    }
72
73    void SectionController::action()
74    {
[10946]75        if (!this || !this->getControllableEntity() || !this->isActive())
[10859]76            return;
[10851]77
[10826]78        //----If no leader, find one---- 
[10731]79        if (!myDivisionLeader_)
80        {
[10885]81            ActionpointController* newDivisionLeader = findNewDivisionLeader();
[10925]82            if (!this || !this->getControllableEntity())
83                return;
84
[10731]85            this->myDivisionLeader_ = newDivisionLeader;
[10881]86            //spread copyOrientation called equally among the division
[10923]87
[10731]88        }
[10826]89        //----If have leader----
[10780]90        else
[10805]91        {
[10826]92        }
[10851]93        if (!myDivisionLeader_)
[10805]94        {
[10864]95            ActionpointController::action();
[10861]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            }
[10854]105        }
106        else if (myDivisionLeader_)
107        {
[10883]108            if (this->myDivisionLeader_->bKeepFormation_ || !(this->myDivisionLeader_->getAction() == Action::FIGHT
109                || this->myDivisionLeader_->getAction() == Action::FIGHTALL
110                || this->myDivisionLeader_->getAction() == Action::ATTACK))
[10805]111            {
[10886]112                this->keepFormation();
[10912]113                //orxout (internal_error) << "Keeping formation" << endl;
114
[10879]115            }
[10886]116            else if (!this->myDivisionLeader_->bKeepFormation_)
[10879]117            {
[10925]118                if (!this || !this->getControllableEntity())
119                    return;
120
[10886]121                if (!this->hasTarget())
[10883]122                {
[10913]123                    this->chooseTarget(); 
[10851]124                }
[10935]125
[10832]126            }
[10854]127        }
[10915]128
[10854]129    }
[10851]130
[10856]131   
[10832]132    //PRE: myDivisionLeader_ != 0 && myDivisionLeader_->action_ == Action::FIGHT
[10826]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----
[10854]137        Action::Value action = this->myDivisionLeader_->getAction();
[10923]138
[10854]139        if (action == Action::FIGHT || action == Action::FIGHTALL || action == Action::ATTACK)
[10826]140        {
[10923]141            Pawn* target;
[10826]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();
[10838]152                    Gametype* gt = this->getGametype();
[10826]153                    for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
154                    {
155                        //----is enemy?----
[10838]156                        if ( CommonController::sameTeam (this->getControllableEntity(), static_cast<ControllableEntity*>(*itP), gt) )
[10826]157                            continue;           
158                        //----in range?----
159                        if (((*itP)->getWorldPosition() - divisionTargetPosition).length() < 3000 && 
160                            (*itP) != this->myDivisionLeader_->getTarget())
161                        {
162                            foundTarget = true;
[10854]163                            target =  (*itP);
[10826]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                    {
[10854]171                        target = orxonox_cast<Pawn*>(this->myDivisionLeader_->getTarget());
[10826]172                    }
173                }
174                //----if division leader doesn't have a wingman, support his fire----
175                else
176                {
[10854]177                    target = orxonox_cast<Pawn*>(this->myDivisionLeader_->getTarget());
[10826]178                }
179            }
180            //----If he fights but doesn't have a target, wait for him to get one----
181            else
182            {
183
184            }
[10858]185            this->setTarget (orxonox_cast<ControllableEntity*>(target));
[10854]186        }
187        else
188        {
[10826]189        } 
190    }
[10854]191    Vector3 SectionController::getFormationPosition ()
192    {
193        this->setFormationMode( this->myDivisionLeader_->getFormationMode() );
[10883]194        this->spread_ = this->myDivisionLeader_->getSpread();
[10854]195        Vector3* targetRelativePosition;
196        switch (this->formationMode_){
197            case FormationMode::WALL:
198            {
[10873]199                targetRelativePosition = new Vector3 (-2*this->spread_, 0, 0);   
[10854]200                break;
201            }
202            case FormationMode::FINGER4: 
203            {
[10873]204                targetRelativePosition = new Vector3 (-2*this->spread_, 0, this->spread_);   
[10854]205                break;
206            }
207           
208            case FormationMode::DIAMOND: 
209            {
[10873]210                targetRelativePosition = new Vector3 (-2*this->spread_, 0, this->spread_);                   
[10854]211                break;
212            }
213        }
[10880]214        Vector3 result = *targetRelativePosition;
215        delete targetRelativePosition;
216        return result;
[10854]217    }
[10826]218
[10886]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    }
[10826]228
[10885]229    ActionpointController* SectionController::findNewDivisionLeader()
[10719]230    {
231
232        if (!this->getControllableEntity())
[10722]233            return 0;
[10719]234
[10885]235        ActionpointController* closestLeader = 0;
[10722]236        float minDistance =  std::numeric_limits<float>::infinity();
[10719]237        //go through all pawns
[10885]238        for (ObjectList<ActionpointController>::iterator it = ObjectList<ActionpointController>::begin(); it; ++it)
[10719]239        {
[10722]240            //0ptr or not DivisionController?
[10869]241            if (!(it) || !((it)->getIdentifier()->getName() == "DivisionController") || !(it->getControllableEntity()))
[10722]242                continue;
[10719]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
[10826]251            float distance = CommonController::distance (it->getControllableEntity(), this->getControllableEntity());
[10722]252           
253            if (distance < minDistance && !(it->hasFollower()))
254            {
255                closestLeader = *it;
256                minDistance = distance;
257            }
[10729]258         
[10719]259        }
[10722]260        if (closestLeader)
261        {
262            if (closestLeader->setFollower(this))
263                return closestLeader;
264        }
265        return 0;
[10719]266    }
[10915]267
[10885]268    bool SectionController::setWingman(ActionpointController* newWingman)
[10731]269    {
[10719]270
[10731]271        if (!this->myWingman_)
[10719]272        {
[10877]273            this->myWingman_ = newWingman;
[10885]274            newWingman->takeActionpoints (this->parsedActionpoints_, this->loopActionpoints_, this->bLoop_);
[10731]275            return true;
[10719]276        }
[10731]277        else
278        {
279            return false;
280        }
[10729]281    }
282   
[10731]283    bool SectionController::hasWingman()
[10725]284    {
[10731]285        if (this->myWingman_)
286            return true;
287        else
288            return false;
[10719]289    }
290}
Note: See TracBrowser for help on using the repository browser.