Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/cpp11_v2/src/modules/objects/controllers/TurretController.cc @ 10818

Last change on this file since 10818 was 10818, checked in by muemart, 9 years ago
  • Fixed some suspicious virtual function signatures
  • Fixed some clang warnings (and errors in the last commit, forgot to mention that)
  • Fix compilation without pch
  • Hack "override" keyword support into Tolua++
  • Property svn:eol-style set to native
File size: 6.3 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 (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it != ObjectList<Pawn>::end(); ++it)
106        {
107            Pawn* entity = orxonox_cast<Pawn*>(*it);
108            if (!entity || FormationController::sameTeam(turret, entity, this->getGametype()))
109                continue;
110            tempScore = turret->isInRange(entity);
111            if(tempScore != -1.f)
112            {
113                if(tempScore < minScore)
114                {
115                    minScore = tempScore;
116                    minScorePawn = entity;
117                }
118            }
119        }
120        this->setTarget(minScorePawn);
121        turret->setTarget(minScorePawn);
122    }
123
124    /**
125        @brief
126        Tests, if the turret is looking at the target, with a specified tolerance
127
128        This uses the world position as opposed to the local position in the old version.
129
130        @param angle
131        The tolerance, in radians
132    */
133    bool TurretController::isLookingAtTargetNew(float angle) const
134    {
135        return (getAngle(this->getControllableEntity()->getWorldPosition(), this->getControllableEntity()->getWorldOrientation() * WorldEntity::FRONT, this->target_->getWorldPosition()) < angle);
136    }
137
138    /**
139        @brief
140        Scores a pawn as a target, based on distance and health.
141
142        The more health and distance a pawn has, the higher the score. This means lower equals better.
143
144        @param pawn
145        The pawn to score
146
147        @param distance
148        The distance. Can be squared or normed, doesn't matter as long as all are treated the same.
149    */   
150    float TurretController::targetScore(Pawn* pawn, float distance) const
151    {
152        return pawn->getHealth()/pawn->getMaxHealth() + distance;
153    }
154
155    /**
156        @brief
157        Does all the controlling of the turret.
158
159        If the turret has a parent, copies the team from there, if it's not already set.
160        Other actions are: Search a target. If a target has been found, aim and shoot at it.
161    */
162    void TurretController::tick(float dt)
163    {
164        if (!this->isActive() || !this->getControllableEntity())
165            return;
166
167
168        ControllableEntity* parent = orxonox_cast<ControllableEntity*> (this->getControllableEntity()->getParent());
169        if(this->getTeam() != -1 && !this->once_ && parent)
170        {
171            orxout(internal_warning) << "TurretController: Team already set, may result in undesired behaviour. Will get overridden by the parent's team." << endl;
172        }
173
174        if(!this->once_)
175            this->once_ = true;
176     
177        //Teams aren't set immediately, after creation, so we have to check every tick...
178        if(parent)
179        {
180            Controller* parentcontroller = parent->getController();
181            if(parentcontroller)
182            {
183                this->setTeam(parentcontroller->getTeam());
184            }
185            else
186            {
187                this->setTeam(parent->getTeam());
188            }
189            this->getControllableEntity()->setTeam(parent->getTeam());
190        }
191
192        this->searchTarget();
193        if(this->target_)
194        {
195            Turret* turret = orxonox_cast<Turret*> (this->getControllableEntity());
196            this->aimAtTarget();
197            turret->aimAtPosition(target_->getWorldPosition());
198            if(this->isLookingAtTargetNew(Degree(5).valueRadians()))
199            {
200
201                this->getControllableEntity()->fire(0);
202            }
203        }
204    }
205 }
Note: See TracBrowser for help on using the repository browser.