Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/modules/objects/controllers/TurretController.cc @ 12366

Last change on this file since 12366 was 11071, checked in by landauf, 9 years ago

merged branch cpp11_v3 back to trunk

  • Property svn:eol-style set to native
File size: 6.2 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 *      Martin Mueller
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#include "TurretController.h"
30#include "worldentities/pawns/Pawn.h"
31#include "objects/Turret.h"
32#include "core/object/ObjectList.h"
33#include "core/CoreIncludes.h"
34
35 namespace orxonox
36 {
37    RegisterClass(TurretController);
38
39    /**
40        @brief
41        Sets default values for all variables.
42
43        @param context
44        The context
45    */
46    TurretController::TurretController(Context* context) : ArtificialController(context)
47    {
48        RegisterObject(TurretController);
49
50        this->once_ = false;
51
52    }
53
54    /**
55        @brief
56        Destructor. Nothing to see here.
57    */
58    TurretController::~TurretController()
59    {
60
61    }
62
63    /**
64        @brief
65        Searches a valid target for the turret to aim at.
66
67        Loops through all pawns and tests, if it is in range. Scores every pawn and chooses the best one (the one with the lowest score).
68        If the turret has a parent, try to aim at the same target the parent has, if there is one.
69
70        @see targetScore
71        The function that scores the pawns.
72    */
73    void TurretController::searchTarget()
74    {
75        Turret* turret = orxonox_cast<Turret*>(this->getControllableEntity());
76
77        //The controller might find a target before teams are set, so we need to check again here.
78        if(this->target_ && turret->isInRange(target_) != -1.f && !FormationController::sameTeam(turret, this->target_, this->getGametype()))
79        {
80            return;
81        }
82        else
83        {
84            this->forgetTarget();
85            turret->setTarget(nullptr);
86        }
87
88
89        ControllableEntity* parent = orxonox_cast<ControllableEntity*>(turret->getParent());
90        if(parent)
91        {
92            Pawn* parenttarget = orxonox_cast<Pawn*>(parent->getTarget());
93            if(parenttarget && turret->isInRange(parenttarget))
94            {
95                this->setTarget(parenttarget);
96                turret->setTarget(parenttarget);
97                return;
98            }
99        }
100
101        float minScore = FLT_MAX;
102        float tempScore;
103        Pawn* minScorePawn = nullptr;
104
105        for (Pawn* pawn : ObjectList<Pawn>())
106        {
107            if (!pawn || FormationController::sameTeam(turret, pawn, this->getGametype()))
108                continue;
109            tempScore = turret->isInRange(pawn);
110            if(tempScore != -1.f)
111            {
112                if(tempScore < minScore)
113                {
114                    minScore = tempScore;
115                    minScorePawn = pawn;
116                }
117            }
118        }
119        this->setTarget(minScorePawn);
120        turret->setTarget(minScorePawn);
121    }
122
123    /**
124        @brief
125        Tests, if the turret is looking at the target, with a specified tolerance
126
127        This uses the world position as opposed to the local position in the old version.
128
129        @param angle
130        The tolerance, in radians
131    */
132    bool TurretController::isLookingAtTargetNew(float angle) const
133    {
134        return (getAngle(this->getControllableEntity()->getWorldPosition(), this->getControllableEntity()->getWorldOrientation() * WorldEntity::FRONT, this->target_->getWorldPosition()) < angle);
135    }
136
137    /**
138        @brief
139        Scores a pawn as a target, based on distance and health.
140
141        The more health and distance a pawn has, the higher the score. This means lower equals better.
142
143        @param pawn
144        The pawn to score
145
146        @param distance
147        The distance. Can be squared or normed, doesn't matter as long as all are treated the same.
148    */   
149    float TurretController::targetScore(Pawn* pawn, float distance) const
150    {
151        return pawn->getHealth()/pawn->getMaxHealth() + distance;
152    }
153
154    /**
155        @brief
156        Does all the controlling of the turret.
157
158        If the turret has a parent, copies the team from there, if it's not already set.
159        Other actions are: Search a target. If a target has been found, aim and shoot at it.
160    */
161    void TurretController::tick(float dt)
162    {
163        if (!this->isActive() || !this->getControllableEntity())
164            return;
165
166
167        ControllableEntity* parent = orxonox_cast<ControllableEntity*> (this->getControllableEntity()->getParent());
168        if(this->getTeam() != -1 && !this->once_ && parent)
169        {
170            orxout(internal_warning) << "TurretController: Team already set, may result in undesired behaviour. Will get overridden by the parent's team." << endl;
171        }
172
173        if(!this->once_)
174            this->once_ = true;
175     
176        //Teams aren't set immediately, after creation, so we have to check every tick...
177        if(parent)
178        {
179            Controller* parentcontroller = parent->getController();
180            if(parentcontroller)
181            {
182                this->setTeam(parentcontroller->getTeam());
183            }
184            else
185            {
186                this->setTeam(parent->getTeam());
187            }
188            this->getControllableEntity()->setTeam(parent->getTeam());
189        }
190
191        this->searchTarget();
192        if(this->target_)
193        {
194            Turret* turret = orxonox_cast<Turret*> (this->getControllableEntity());
195            this->aimAtTarget();
196            turret->aimAtPosition(target_->getWorldPosition());
197            if(this->isLookingAtTargetNew(Degree(5).valueRadians()))
198            {
199
200                this->getControllableEntity()->fire(0);
201            }
202        }
203    }
204 }
Note: See TracBrowser for help on using the repository browser.