Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 11011 was 10968, checked in by gania, 9 years ago

a little clean up

File size: 9.6 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;
86        }
[10826]87        //----If have leader----
[10780]88        else
[10805]89        {
[10826]90        }
[10851]91        if (!myDivisionLeader_)
[10805]92        {
[10864]93            ActionpointController::action();
[10861]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            }
[10854]103        }
104        else if (myDivisionLeader_)
105        {
[10883]106            if (this->myDivisionLeader_->bKeepFormation_ || !(this->myDivisionLeader_->getAction() == Action::FIGHT
107                || this->myDivisionLeader_->getAction() == Action::FIGHTALL
108                || this->myDivisionLeader_->getAction() == Action::ATTACK))
[10805]109            {
[10886]110                this->keepFormation();
[10879]111            }
[10886]112            else if (!this->myDivisionLeader_->bKeepFormation_)
[10879]113            {
[10925]114                if (!this || !this->getControllableEntity())
115                    return;
116
[10886]117                if (!this->hasTarget())
[10883]118                {
[10913]119                    this->chooseTarget(); 
[10851]120                }
[10935]121
[10832]122            }
[10854]123        }
[10915]124
[10854]125    }
[10851]126
[10856]127   
[10832]128    //PRE: myDivisionLeader_ != 0 && myDivisionLeader_->action_ == Action::FIGHT
[10826]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----
[10854]133        Action::Value action = this->myDivisionLeader_->getAction();
[10923]134
[10854]135        if (action == Action::FIGHT || action == Action::FIGHTALL || action == Action::ATTACK)
[10826]136        {
[10923]137            Pawn* target;
[10826]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();
[10838]148                    Gametype* gt = this->getGametype();
[10826]149                    for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
150                    {
151                        //----is enemy?----
[10838]152                        if ( CommonController::sameTeam (this->getControllableEntity(), static_cast<ControllableEntity*>(*itP), gt) )
[10826]153                            continue;           
154                        //----in range?----
155                        if (((*itP)->getWorldPosition() - divisionTargetPosition).length() < 3000 && 
156                            (*itP) != this->myDivisionLeader_->getTarget())
157                        {
158                            foundTarget = true;
[10854]159                            target =  (*itP);
[10826]160                            break; 
161                        }
162                    }
163                    //----no target? then attack same target as division leader----
164                    if (!foundTarget)
165                    {
[10854]166                        target = orxonox_cast<Pawn*>(this->myDivisionLeader_->getTarget());
[10826]167                    }
168                }
169                //----if division leader doesn't have a wingman, support his fire----
170                else
171                {
[10854]172                    target = orxonox_cast<Pawn*>(this->myDivisionLeader_->getTarget());
[10826]173                }
174            }
175            //----If he fights but doesn't have a target, wait for him to get one----
176            else
177            {
178
179            }
[10858]180            this->setTarget (orxonox_cast<ControllableEntity*>(target));
[10854]181        }
182        else
183        {
[10826]184        } 
185    }
[10854]186    Vector3 SectionController::getFormationPosition ()
187    {
188        this->setFormationMode( this->myDivisionLeader_->getFormationMode() );
[10883]189        this->spread_ = this->myDivisionLeader_->getSpread();
[10854]190        Vector3* targetRelativePosition;
191        switch (this->formationMode_){
192            case FormationMode::WALL:
193            {
[10873]194                targetRelativePosition = new Vector3 (-2*this->spread_, 0, 0);   
[10854]195                break;
196            }
197            case FormationMode::FINGER4: 
198            {
[10873]199                targetRelativePosition = new Vector3 (-2*this->spread_, 0, this->spread_);   
[10854]200                break;
201            }
202           
203            case FormationMode::DIAMOND: 
204            {
[10873]205                targetRelativePosition = new Vector3 (-2*this->spread_, 0, this->spread_);                   
[10854]206                break;
207            }
208        }
[10880]209        Vector3 result = *targetRelativePosition;
210        delete targetRelativePosition;
211        return result;
[10854]212    }
[10826]213
[10886]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    }
[10826]223
[10885]224    ActionpointController* SectionController::findNewDivisionLeader()
[10719]225    {
226
227        if (!this->getControllableEntity())
[10722]228            return 0;
[10719]229
[10885]230        ActionpointController* closestLeader = 0;
[10722]231        float minDistance =  std::numeric_limits<float>::infinity();
[10719]232        //go through all pawns
[10885]233        for (ObjectList<ActionpointController>::iterator it = ObjectList<ActionpointController>::begin(); it; ++it)
[10719]234        {
[10722]235            //0ptr or not DivisionController?
[10869]236            if (!(it) || !((it)->getIdentifier()->getName() == "DivisionController") || !(it->getControllableEntity()))
[10722]237                continue;
[10719]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
[10826]246            float distance = CommonController::distance (it->getControllableEntity(), this->getControllableEntity());
[10722]247           
248            if (distance < minDistance && !(it->hasFollower()))
249            {
250                closestLeader = *it;
251                minDistance = distance;
252            }
[10729]253         
[10719]254        }
[10722]255        if (closestLeader)
256        {
257            if (closestLeader->setFollower(this))
258                return closestLeader;
259        }
260        return 0;
[10719]261    }
[10915]262
[10885]263    bool SectionController::setWingman(ActionpointController* newWingman)
[10731]264    {
[10719]265
[10731]266        if (!this->myWingman_)
[10719]267        {
[10877]268            this->myWingman_ = newWingman;
[10885]269            newWingman->takeActionpoints (this->parsedActionpoints_, this->loopActionpoints_, this->bLoop_);
[10731]270            return true;
[10719]271        }
[10731]272        else
273        {
274            return false;
275        }
[10729]276    }
277   
[10731]278    bool SectionController::hasWingman()
[10725]279    {
[10731]280        if (this->myWingman_)
281            return true;
282        else
283            return false;
[10719]284    }
285}
Note: See TracBrowser for help on using the repository browser.