Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

should work, didn't compile

File size: 10.9 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 *      Fabian 'x3n' Landau
24 *   Co-authors:
25 *      Dominik Solenicki
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) : LeaderController(context)
38    {
39        RegisterObject(SectionController);
40        this->setFormationMode(FormationMode::FINGER4);
41
42        this->actionTimer_.setTimer(ACTION_INTERVAL, true, createExecutor(createFunctor(&SectionController::action, this)));
43        this->myWingman_ = 0;
44        this->myDivisionLeader_ = 0;
45        this->rank_ = Rank::SECTIONLEADER;
46        this->bFirstAction_ = true;
47        //orxout(internal_error) << this << "Was created" << endl;
48
49    }
50   
51    SectionController::~SectionController()
52    {
53        if (this->myWingman_)
54        {
55            this->myWingman_->takeActionpoints(this->parsedActionpoints_, this->loopActionpoints_, this->bLoop_);
56        }
57       for (size_t i = 0; i < this->actionpoints_.size(); ++i)
58        {
59            if(this->actionpoints_[i])
60                this->actionpoints_[i]->destroy();
61        }
62        this->parsedActionpoints_.clear();
63        this->actionpoints_.clear();
64    }
65    void SectionController::XMLPort(Element& xmlelement, XMLPort::Mode mode)
66    {
67        SUPER(SectionController, XMLPort, xmlelement, mode);
68
69        //XMLPortParam(SectionController, "target_", setTarget, getTarget, xmlelement, mode).defaultValues(100.0f);
70    }
71
72    //----in tick, move (or look) and shoot----
73    void SectionController::tick(float dt)
74    {
75        if (!this->isActive())
76            return;
77     
78       
79        SUPER(SectionController, tick, dt);
80    }
81
82    void SectionController::action()
83    {
84
85        //----If no leader, find one---- 
86        if (!myDivisionLeader_)
87        {
88            LeaderController* newDivisionLeader = findNewDivisionLeader();
89            this->myDivisionLeader_ = newDivisionLeader;
90
91        }
92        //----If have leader----
93        else
94        {
95        }
96        if (!myDivisionLeader_)
97        {
98            CommonController::action();
99        }
100        else if (myDivisionLeader_)
101        {
102            switch (myDivisionLeader_->getAction())
103            {
104                case Action::FIGHT:
105                {
106                    if (!this->hasTarget())
107                    {
108                        this->chooseTarget();
109                    }
110                    break;
111                }
112                case Action::FIGHTALL:
113                {
114                    if (!this->hasTarget())
115                    {
116                        this->chooseTarget();
117                    }
118                    break;
119                }
120                case Action::ATTACK:
121                {
122                    if (!this->hasTarget())
123                    {
124                        this->chooseTarget();
125                    }
126                    break;
127                }
128                default:
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               
149                    this->setAction (Action::FLY, targetAbsolutePosition, orient);
150                    if ((targetAbsolutePosition - myPosition).length() > this->tolerance_ * 1.5f)
151                    {
152                        this->boostControl();
153                    }
154                    else
155                    {
156                       this->getControllableEntity()->boost(false);
157                    }
158                }
159            }
160            if (this->hasTarget())
161            {
162                //----choose where to go----
163                this->maneuver();
164                //----fire if you can----
165                this->bShooting_ = this->canFire();               
166            }
167        }
168     
169    }
170
171   
172    //PRE: myDivisionLeader_ != 0 && myDivisionLeader_->action_ == Action::FIGHT
173    //POST: this->target_ is set unless division leader doesn't have one
174    void SectionController::chooseTarget()
175    {
176        //----If division leader fights, cover him by fighting emenies close to his target----
177        Action::Value action = this->myDivisionLeader_->getAction();
178       
179        Pawn* target;
180        if (action == Action::FIGHT || action == Action::FIGHTALL || action == Action::ATTACK)
181        {
182            //----if he has a target----
183            if (this->myDivisionLeader_->hasTarget())
184            {
185                //----try to find a new target if division leader has wingman (doing fine) and no good target already set----
186                if ( this->myDivisionLeader_->hasWingman() && 
187                    !( this->hasTarget() && this->getTarget() != this->myDivisionLeader_->getTarget() ) )
188                {
189
190                    bool foundTarget = false;
191                    //----new target should be close to division's target----
192                    Vector3 divisionTargetPosition = this->myDivisionLeader_->getTarget()->getWorldPosition();
193                    Gametype* gt = this->getGametype();
194                    for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
195                    {
196                        //----is enemy?----
197                        if ( CommonController::sameTeam (this->getControllableEntity(), static_cast<ControllableEntity*>(*itP), gt) )
198                            continue;           
199                        //----in range?----
200                        if (((*itP)->getWorldPosition() - divisionTargetPosition).length() < 3000 && 
201                            (*itP) != this->myDivisionLeader_->getTarget())
202                        {
203                            foundTarget = true;
204                            target =  (*itP);
205                            //orxout(internal_error) << "Found target" << endl;
206                            break; 
207                        }
208                    }
209                    //----no target? then attack same target as division leader----
210                    if (!foundTarget)
211                    {
212                        target = orxonox_cast<Pawn*>(this->myDivisionLeader_->getTarget());
213                    }
214                }
215                //----if division leader doesn't have a wingman, support his fire----
216                else
217                {
218                    target = orxonox_cast<Pawn*>(this->myDivisionLeader_->getTarget());
219                }
220            }
221            //----If he fights but doesn't have a target, wait for him to get one----
222            else
223            {
224
225            }
226            this->setTarget (orxonox_cast<ControllableEntity*>(target));
227        }
228        else
229        {
230        } 
231    }
232    Vector3 SectionController::getFormationPosition ()
233    {
234        this->setFormationMode( this->myDivisionLeader_->getFormationMode() );
235        Vector3* targetRelativePosition;
236        switch (this->formationMode_){
237            case FormationMode::WALL:
238            {
239                targetRelativePosition = new Vector3 (-400, 0, 0);   
240                break;
241            }
242            case FormationMode::FINGER4: 
243            {
244                targetRelativePosition = new Vector3 (-400, 0, 200);   
245                break;
246            }
247           
248            case FormationMode::DIAMOND: 
249            {
250                targetRelativePosition = new Vector3 (-400, 0, 200);                   
251                break;
252            }
253        }
254        return *targetRelativePosition;
255    }
256
257   
258
259    LeaderController* SectionController::findNewDivisionLeader()
260    {
261
262        if (!this->getControllableEntity())
263            return 0;
264
265        LeaderController* closestLeader = 0;
266        float minDistance =  std::numeric_limits<float>::infinity();
267        //go through all pawns
268        for (ObjectList<LeaderController>::iterator it = ObjectList<LeaderController>::begin(); it; ++it)
269        {
270            //0ptr or not DivisionController?
271            if (!(it) || !((it)->getRank() == Rank::DIVISIONLEADER) || !(it->getControllableEntity()))
272                continue;
273            //same team?
274            if ((this->getControllableEntity()->getTeam() != (it)->getControllableEntity()->getTeam()))
275                continue;
276
277            //is equal to this?
278            if (orxonox_cast<ControllableEntity*>(*it) == this->getControllableEntity())
279                continue;
280
281            float distance = CommonController::distance (it->getControllableEntity(), this->getControllableEntity());
282           
283            if (distance < minDistance && !(it->hasFollower()))
284            {
285                closestLeader = *it;
286                minDistance = distance;
287            }
288         
289        }
290        if (closestLeader)
291        {
292            if (closestLeader->setFollower(this))
293                return closestLeader;
294        }
295        return 0;
296    }
297    bool SectionController::setWingman(CommonController* cwingman)
298    {
299        WeakPtr<WingmanController> wingman = orxonox_cast<WingmanController*>(cwingman);
300
301        if (!this->myWingman_)
302        {
303            this->myWingman_ = wingman;
304            return true;
305        }
306        else
307        {
308            return false;
309        }
310    }
311   
312    bool SectionController::hasWingman()
313    {
314        if (this->myWingman_)
315            return true;
316        else
317            return false;
318    }
319}
Note: See TracBrowser for help on using the repository browser.