Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/orxonox/controllers/SectionController.cc @ 11933

Last change on this file since 11933 was 11083, checked in by muemart, 9 years ago

Fix some clang-tidy warnings.
Also, Serialise.h was doing some C-style casts that ended up being const casts. I moved those const casts as close to the source as possible and changed the loadAndIncrease functions to not do that.

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