Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

fixed library dependencies

File size: 11.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:
23 *      Fabian 'x3n' Landau
24 *   Co-authors:
25 *      Dominik Solenicki
26 *
27 */
28
29#include "SectionController.h"
[10866]30//TODO: formation vectors are wrong, fix it.
31// split classes.
32// weaponsystem.
33//-> Math ?
34 
[10719]35namespace orxonox
36{
37
38    RegisterClass(SectionController);
39
[10826]40    //Leaders share the fact that they have Wingmans
[10719]41    SectionController::SectionController(Context* context) : LeaderController(context)
42    {
43        RegisterObject(SectionController);
[10759]44        this->setFormationMode(FormationMode::FINGER4);
[10725]45
[10719]46        this->actionTimer_.setTimer(ACTION_INTERVAL, true, createExecutor(createFunctor(&SectionController::action, this)));
[10725]47        this->myWingman_ = 0;
48        this->myDivisionLeader_ = 0;
[10851]49        this->bFirstAction_ = true;
[10826]50        //orxout(internal_error) << this << "Was created" << endl;
[10719]51
52    }
53   
54    SectionController::~SectionController()
55    {
[10859]56        // if (this->myWingman_)
57        // {
58        //     this->myWingman_->takeActionpoints(this->parsedActionpoints_, this->loopActionpoints_, this->bLoop_);
59        // }
[10854]60       for (size_t i = 0; i < this->actionpoints_.size(); ++i)
61        {
62            if(this->actionpoints_[i])
63                this->actionpoints_[i]->destroy();
64        }
65        this->parsedActionpoints_.clear();
66        this->actionpoints_.clear();
[10725]67    }
[10826]68    void SectionController::XMLPort(Element& xmlelement, XMLPort::Mode mode)
69    {
70        SUPER(SectionController, XMLPort, xmlelement, mode);
[10731]71
[10826]72        //XMLPortParam(SectionController, "target_", setTarget, getTarget, xmlelement, mode).defaultValues(100.0f);
73    }
74
75    //----in tick, move (or look) and shoot----
[10731]76    void SectionController::tick(float dt)
77    {
[10843]78        if (!this->isActive())
[10731]79            return;
[10875]80
81    //this doesn't fight in formation flight, thus we can afford executing following code in tick: when nobody fights, tick is anyway stable.
82        if (this->myDivisionLeader_ && this->myDivisionLeader_->getAction() != Action::FIGHT && this->myDivisionLeader_->getAction() !=
83            Action::FIGHTALL && this->myDivisionLeader_->getAction() != Action::ATTACK)
84        {
85            ControllableEntity* myEntity = this->getControllableEntity();
86            Vector3 myPosition = myEntity->getWorldPosition();
87            if (!this->myDivisionLeader_)
88            {
89                return;
90            }
91            ControllableEntity* leaderEntity = this->myDivisionLeader_->getControllableEntity();
92            Quaternion orient = leaderEntity->getWorldOrientation();
93            Vector3 leaderPosition = leaderEntity->getWorldPosition();
94
95            Vector3 targetRelativePosition = getFormationPosition();
96            if (!this->myDivisionLeader_)
97            {
98                return;
99            }
100            Vector3 targetAbsolutePosition = 
101                (leaderPosition + (orient*WorldEntity::FRONT) * (leaderEntity->getVelocity().length()/5)
102                 + (orient* (targetRelativePosition)));
103       
104            this->setAction (Action::FLY, targetAbsolutePosition, orient);
105            if ((targetAbsolutePosition - myPosition).length() > this->tolerance_ * 1.5f)
106            {
107                this->boostControl();
108            }
109            else
110            {
111               this->getControllableEntity()->boost(false);
112            }
113        }   
[10731]114        SUPER(SectionController, tick, dt);
115    }
116
117    void SectionController::action()
118    {
[10859]119        if (!this || !this->getControllableEntity())
120            return;
[10851]121
[10826]122        //----If no leader, find one---- 
[10731]123        if (!myDivisionLeader_)
124        {
125            LeaderController* newDivisionLeader = findNewDivisionLeader();
126            this->myDivisionLeader_ = newDivisionLeader;
[10826]127
[10731]128        }
[10826]129        //----If have leader----
[10780]130        else
[10805]131        {
[10826]132        }
[10851]133        if (!myDivisionLeader_)
[10805]134        {
[10861]135           
[10864]136            ActionpointController::action();
[10861]137            if (!this || !this->getControllableEntity())
138                return;
139            if (!(this->parsedActionpoints_.empty() && this->loopActionpoints_.empty()))
140            {
141                if (this->myWingman_)
142                {
143                    this->myWingman_->takeActionpoints(this->parsedActionpoints_, this->loopActionpoints_, this->bLoop_);
144                }   
145            }
[10854]146        }
147        else if (myDivisionLeader_)
148        {
149            switch (myDivisionLeader_->getAction())
[10805]150            {
[10858]151                case Action::FIGHT:
152                {
153                    if (!this->hasTarget())
154                    {
155                        this->chooseTarget();
156                    }
157                    break;
158                }
159                case Action::FIGHTALL:
160                {
161                    if (!this->hasTarget())
162                    {
163                        this->chooseTarget();
164                    }
165                    break;
166                }
167                case Action::ATTACK:
168                {
169                    if (!this->hasTarget())
170                    {
171                        this->chooseTarget();
172                    }
173                    break;
174                }
[10854]175                default:
[10805]176                {
[10875]177                    //formation flight is executed in tick
[10851]178                }
[10832]179            }
[10858]180            if (this->hasTarget())
181            {
182                //----choose where to go----
183                this->maneuver();
184                //----fire if you can----
185                this->bShooting_ = this->canFire();               
186            }
[10854]187        }
[10851]188     
[10854]189    }
[10851]190
[10856]191   
[10832]192    //PRE: myDivisionLeader_ != 0 && myDivisionLeader_->action_ == Action::FIGHT
[10826]193    //POST: this->target_ is set unless division leader doesn't have one
194    void SectionController::chooseTarget()
195    {
196        //----If division leader fights, cover him by fighting emenies close to his target----
[10854]197        Action::Value action = this->myDivisionLeader_->getAction();
198       
199        Pawn* target;
200        if (action == Action::FIGHT || action == Action::FIGHTALL || action == Action::ATTACK)
[10826]201        {
202            //----if he has a target----
203            if (this->myDivisionLeader_->hasTarget())
204            {
205                //----try to find a new target if division leader has wingman (doing fine) and no good target already set----
206                if ( this->myDivisionLeader_->hasWingman() && 
207                    !( this->hasTarget() && this->getTarget() != this->myDivisionLeader_->getTarget() ) )
208                {
209
210                    bool foundTarget = false;
211                    //----new target should be close to division's target----
212                    Vector3 divisionTargetPosition = this->myDivisionLeader_->getTarget()->getWorldPosition();
[10838]213                    Gametype* gt = this->getGametype();
[10826]214                    for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
215                    {
216                        //----is enemy?----
[10838]217                        if ( CommonController::sameTeam (this->getControllableEntity(), static_cast<ControllableEntity*>(*itP), gt) )
[10826]218                            continue;           
219                        //----in range?----
220                        if (((*itP)->getWorldPosition() - divisionTargetPosition).length() < 3000 && 
221                            (*itP) != this->myDivisionLeader_->getTarget())
222                        {
223                            foundTarget = true;
[10854]224                            target =  (*itP);
[10826]225                            //orxout(internal_error) << "Found target" << endl;
226                            break; 
227                        }
228                    }
229                    //----no target? then attack same target as division leader----
230                    if (!foundTarget)
231                    {
[10854]232                        target = orxonox_cast<Pawn*>(this->myDivisionLeader_->getTarget());
[10826]233                    }
234                }
235                //----if division leader doesn't have a wingman, support his fire----
236                else
237                {
[10854]238                    target = orxonox_cast<Pawn*>(this->myDivisionLeader_->getTarget());
[10826]239                }
240            }
241            //----If he fights but doesn't have a target, wait for him to get one----
242            else
243            {
244
245            }
[10858]246            this->setTarget (orxonox_cast<ControllableEntity*>(target));
[10854]247        }
248        else
249        {
[10826]250        } 
251    }
[10854]252    Vector3 SectionController::getFormationPosition ()
253    {
254        this->setFormationMode( this->myDivisionLeader_->getFormationMode() );
255        Vector3* targetRelativePosition;
256        switch (this->formationMode_){
257            case FormationMode::WALL:
258            {
[10873]259                targetRelativePosition = new Vector3 (-2*this->spread_, 0, 0);   
[10854]260                break;
261            }
262            case FormationMode::FINGER4: 
263            {
[10873]264                targetRelativePosition = new Vector3 (-2*this->spread_, 0, this->spread_);   
[10854]265                break;
266            }
267           
268            case FormationMode::DIAMOND: 
269            {
[10873]270                targetRelativePosition = new Vector3 (-2*this->spread_, 0, this->spread_);                   
[10854]271                break;
272            }
273        }
274        return *targetRelativePosition;
275    }
[10826]276
[10856]277   
[10826]278
[10722]279    LeaderController* SectionController::findNewDivisionLeader()
[10719]280    {
281
282        if (!this->getControllableEntity())
[10722]283            return 0;
[10719]284
[10722]285        LeaderController* closestLeader = 0;
286        float minDistance =  std::numeric_limits<float>::infinity();
[10719]287        //go through all pawns
288        for (ObjectList<LeaderController>::iterator it = ObjectList<LeaderController>::begin(); it; ++it)
289        {
[10722]290            //0ptr or not DivisionController?
[10869]291            if (!(it) || !((it)->getIdentifier()->getName() == "DivisionController") || !(it->getControllableEntity()))
[10722]292                continue;
[10719]293            //same team?
294            if ((this->getControllableEntity()->getTeam() != (it)->getControllableEntity()->getTeam()))
295                continue;
296
297            //is equal to this?
298            if (orxonox_cast<ControllableEntity*>(*it) == this->getControllableEntity())
299                continue;
300
[10826]301            float distance = CommonController::distance (it->getControllableEntity(), this->getControllableEntity());
[10722]302           
303            if (distance < minDistance && !(it->hasFollower()))
304            {
305                closestLeader = *it;
306                minDistance = distance;
307            }
[10729]308         
[10719]309        }
[10722]310        if (closestLeader)
311        {
312            if (closestLeader->setFollower(this))
313                return closestLeader;
314        }
315        return 0;
[10719]316    }
[10869]317    bool SectionController::setWingman(CommonController* cwingman)
[10731]318    {
319        WeakPtr<WingmanController> wingman = orxonox_cast<WingmanController*>(cwingman);
[10719]320
[10731]321        if (!this->myWingman_)
[10719]322        {
[10731]323            this->myWingman_ = wingman;
324            return true;
[10719]325        }
[10731]326        else
327        {
328            return false;
329        }
[10729]330    }
331   
[10731]332    bool SectionController::hasWingman()
[10725]333    {
[10731]334        if (this->myWingman_)
335            return true;
336        else
337            return false;
[10719]338    }
339}
Note: See TracBrowser for help on using the repository browser.