Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 10885 was 10885, checked in by gania, 8 years ago

added other weapons

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