Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 10867 was 10622, checked in by landauf, 9 years ago

merged branch presentationFS15merge back to trunk

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