Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 10822 was 10818, checked in by muemart, 10 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
RevLine 
[10008]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
[10031]29#include "TurretController.h"
30#include "worldentities/pawns/Pawn.h"
[10218]31#include "objects/Turret.h"
[10818]32#include "core/object/ObjectList.h"
33#include "core/CoreIncludes.h"
[10008]34
35 namespace orxonox
36 {
[10215]37    RegisterClass(TurretController);
[10008]38
[10060]39    /**
40        @brief
41        Sets default values for all variables.
42
43        @param context
44        The context
45    */
[10215]46    TurretController::TurretController(Context* context) : ArtificialController(context)
47    {
48        RegisterObject(TurretController);
[10044]49
[10215]50        this->once_ = false;
[10044]51
[10215]52    }
[10008]53
[10060]54    /**
55        @brief
56        Destructor. Nothing to see here.
57    */
[10215]58    TurretController::~TurretController()
59    {
[10008]60
[10215]61    }
[10008]62
[10060]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    */
[10215]73    void TurretController::searchTarget()
74    {
[10031]75        Turret* turret = orxonox_cast<Turret*>(this->getControllableEntity());
[10060]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()))
[10031]79        {
[10215]80            return;
[10031]81        }
82        else
83        {
[10215]84            this->forgetTarget();
[10768]85            turret->setTarget(nullptr);
[10031]86        }
87
88
89        ControllableEntity* parent = orxonox_cast<ControllableEntity*>(turret->getParent());
90        if(parent)
91        {
[10215]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            }
[10031]99        }
100
[10062]101        float minScore = FLT_MAX;
[10060]102        float tempScore;
[10768]103        Pawn* minScorePawn = nullptr;
[10060]104
[10215]105        for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it != ObjectList<Pawn>::end(); ++it)
[10031]106        {
[10215]107            Pawn* entity = orxonox_cast<Pawn*>(*it);
[10622]108            if (!entity || FormationController::sameTeam(turret, entity, this->getGametype()))
[10215]109                continue;
[10060]110            tempScore = turret->isInRange(entity);
111            if(tempScore != -1.f)
[10031]112            {
[10215]113                if(tempScore < minScore)
114                {
115                    minScore = tempScore;
116                    minScorePawn = entity;
117                }
[10031]118            }
[10215]119        }
[10062]120        this->setTarget(minScorePawn);
121        turret->setTarget(minScorePawn);
[10215]122    }
[10031]123
[10060]124    /**
125        @brief
126        Tests, if the turret is looking at the target, with a specified tolerance
127
[10215]128        This uses the world position as opposed to the local position in the old version.
[10060]129
[10215]130        @param angle
131        The tolerance, in radians
[10060]132    */
[10042]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
[10060]138    /**
139        @brief
140        Scores a pawn as a target, based on distance and health.
141
[10062]142        The more health and distance a pawn has, the higher the score. This means lower equals better.
[10060]143
[10215]144        @param pawn
145        The pawn to score
[10060]146
[10215]147        @param distance
148        The distance. Can be squared or normed, doesn't matter as long as all are treated the same.
[10060]149    */   
[10215]150    float TurretController::targetScore(Pawn* pawn, float distance) const
151    {
152        return pawn->getHealth()/pawn->getMaxHealth() + distance;
153    }
[10060]154
155    /**
[10215]156        @brief
157        Does all the controlling of the turret.
[10060]158
[10215]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.
[10060]161    */
[10215]162    void TurretController::tick(float dt)
163    {
164        if (!this->isActive() || !this->getControllableEntity())
165            return;
[10039]166
167
[10060]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;
[10044]172        }
[10039]173
[10060]174        if(!this->once_)
[10215]175            this->once_ = true;
[10060]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
[10215]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            {
[10622]200
[10215]201                this->getControllableEntity()->fire(0);
202            }
203        }
204    }
205 }
Note: See TracBrowser for help on using the repository browser.