Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/ScriptableController_FS18/src/orxonox/controllers/SectionController.cc @ 11890

Last change on this file since 11890 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
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_ = nullptr;
43        this->myDivisionLeader_ = nullptr;
44        this->bFirstAction_ = true;
45
46    }
47   
48    SectionController::~SectionController()
49    {
50        for (WorldEntity* actionpoint : this->actionpoints_)
51        {
52            if (actionpoint)
53                actionpoint->destroy();
54        }
55        this->parsedActionpoints_.clear();
56        this->actionpoints_.clear();
57    }
58
59    void SectionController::action()
60    {
61        if (!this->getControllableEntity() || !this->isActive())
62            return;
63
64        //----If no leader, find one---- 
65        if (!myDivisionLeader_)
66        {
67            ActionpointController* newDivisionLeader = findNewDivisionLeader();
68
69            this->myDivisionLeader_ = newDivisionLeader;
70        }
71        //----If have leader----
72        else
73        {
74        }
75        if (!myDivisionLeader_)
76        {
77            ActionpointController::action();
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            }
85        }
86        else if (myDivisionLeader_)
87        {
88            if (this->myDivisionLeader_->bKeepFormation_ || !(this->myDivisionLeader_->getAction() == Action::FIGHT
89                || this->myDivisionLeader_->getAction() == Action::FIGHTALL
90                || this->myDivisionLeader_->getAction() == Action::ATTACK))
91            {
92                this->keepFormation();
93            }
94            else if (!this->myDivisionLeader_->bKeepFormation_)
95            {
96
97                if (!this->hasTarget())
98                {
99                    this->chooseTarget(); 
100                }
101
102            }
103        }
104
105    }
106
107   
108    //PRE: myDivisionLeader_ != 0 && myDivisionLeader_->action_ == Action::FIGHT
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----
113        Action action = this->myDivisionLeader_->getAction();
114
115        if (action == Action::FIGHT || action == Action::FIGHTALL || action == Action::ATTACK)
116        {
117            Pawn* target = nullptr;
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();
128                    Gametype* gt = this->getGametype();
129                    for (Pawn* pawn : ObjectList<Pawn>())
130                    {
131                        //----is enemy?----
132                        if ( CommonController::sameTeam (this->getControllableEntity(), static_cast<ControllableEntity*>(pawn), gt) )
133                            continue;           
134                        //----in range?----
135                        if ((pawn->getWorldPosition() - divisionTargetPosition).length() < 3000 &&
136                            pawn != this->myDivisionLeader_->getTarget())
137                        {
138                            foundTarget = true;
139                            target = pawn;
140                            break; 
141                        }
142                    }
143                    //----no target? then attack same target as division leader----
144                    if (!foundTarget)
145                    {
146                        target = orxonox_cast<Pawn*>(this->myDivisionLeader_->getTarget());
147                    }
148                }
149                //----if division leader doesn't have a wingman, support his fire----
150                else
151                {
152                    target = orxonox_cast<Pawn*>(this->myDivisionLeader_->getTarget());
153                }
154            }
155            //----If he fights but doesn't have a target, wait for him to get one----
156            else
157            {
158
159            }
160            this->setTarget (orxonox_cast<ControllableEntity*>(target));
161        }
162        else
163        {
164        } 
165    }
166    Vector3 SectionController::getFormationPosition ()
167    {
168        this->setFormationMode( this->myDivisionLeader_->getFormationMode() );
169        this->spread_ = this->myDivisionLeader_->getSpread();
170        switch (this->formationMode_){
171            case FormationMode::WALL:
172                return Vector3 (-2.0f*this->spread_, 0, 0);
173
174            case FormationMode::FINGER4: 
175                return Vector3 (-2.0f*this->spread_, 0, 1.0f*this->spread_);
176           
177            case FormationMode::DIAMOND: 
178                return Vector3 (-2.0f*this->spread_, 0, 1.0f*this->spread_);
179
180            default:
181                return Vector3::ZERO;
182        }
183    }
184
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    }
194
195    ActionpointController* SectionController::findNewDivisionLeader()
196    {
197
198        if (!this->getControllableEntity())
199            return nullptr;
200
201        ActionpointController* closestLeader = nullptr;
202        float minDistance =  std::numeric_limits<float>::infinity();
203        //go through all pawns
204        for (ActionpointController* controller : ObjectList<ActionpointController>())
205        {
206            //0ptr or not DivisionController?
207            if (!controller || !(controller->getIdentifier()->getName() == "DivisionController") || !(controller->getControllableEntity()))
208                continue;
209            //same team?
210            if ((this->getControllableEntity()->getTeam() != controller->getControllableEntity()->getTeam()))
211                continue;
212
213            //is equal to this?
214            if (orxonox_cast<ControllableEntity*>(controller) == this->getControllableEntity())
215                continue;
216
217            float distance = CommonController::distance (controller->getControllableEntity(), this->getControllableEntity());
218           
219            if (distance < minDistance && !(controller->hasFollower()))
220            {
221                closestLeader = controller;
222                minDistance = distance;
223            }
224         
225        }
226        if (closestLeader)
227        {
228            if (closestLeader->setFollower(this))
229                return closestLeader;
230        }
231        return nullptr;
232    }
233
234    bool SectionController::setWingman(ActionpointController* newWingman)
235    {
236
237        if (!this->myWingman_)
238        {
239            this->myWingman_ = newWingman;
240            newWingman->takeActionpoints (this->parsedActionpoints_, this->loopActionpoints_, this->bLoop_);
241            return true;
242        }
243        else
244        {
245            return false;
246        }
247    }
248   
249    bool SectionController::hasWingman()
250    {
251        if (this->myWingman_)
252            return true;
253        else
254            return false;
255    }
256}
Note: See TracBrowser for help on using the repository browser.