Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/presentationHS14/src/modules/objects/controllers/TurretController.cc @ 10181

Last change on this file since 10181 was 10147, checked in by maxima, 9 years ago
File size: 6.0 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 "Turret.h"
32
33 namespace orxonox
34 {
35        RegisterClass(TurretController);
36
37    /**
38        @brief
39        Sets default values for all variables.
40
41        @param context
42        The context
43    */
44        TurretController::TurretController(Context* context) : ArtificialController(context)
45        {
46                RegisterObject(TurretController);
47
48                this->once_ = false;
49
50        }
51
52    /**
53        @brief
54        Destructor. Nothing to see here.
55    */
56        TurretController::~TurretController()
57        {
58
59        }
60
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    */
71        void TurretController::searchTarget()
72        {
73        Turret* turret = orxonox_cast<Turret*>(this->getControllableEntity());
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()))
77        {
78                return;
79        }
80        else
81        {
82                this->forgetTarget();
83                turret->setTarget(0);
84        }
85
86
87        ControllableEntity* parent = orxonox_cast<ControllableEntity*>(turret->getParent());
88        if(parent)
89        {
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                }
97        }
98
99        float minScore = FLT_MAX;
100        float tempScore;
101        Pawn* minScorePawn = 0;
102
103                for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it != ObjectList<Pawn>::end(); ++it)     
104        {
105                Pawn* entity = orxonox_cast<Pawn*>(*it);
106            if (!entity || FormationController::sameTeam(this->getControllableEntity(), entity, this->getGametype()))
107                continue;
108            tempScore = turret->isInRange(entity);
109            if(tempScore != -1.f)
110            {
111                if(tempScore < minScore)
112                {
113                        minScore = tempScore;
114                        minScorePawn = entity;
115                }
116            }
117        }
118        this->setTarget(minScorePawn);
119        turret->setTarget(minScorePawn);
120        }
121
122    /**
123        @brief
124        Tests, if the turret is looking at the target, with a specified tolerance
125
126                This uses the world position as opposed to the local position in the old version.
127
128                @param angle
129                The tolerance, in radians
130    */
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
136    /**
137        @brief
138        Scores a pawn as a target, based on distance and health.
139
140        The more health and distance a pawn has, the higher the score. This means lower equals better.
141
142                @param pawn
143                The pawn to score
144
145                @param distance
146                The distance. Can be squared or normed, doesn't matter as long as all are treated the same.
147    */   
148        float TurretController::targetScore(Pawn* pawn, float distance) const
149        {
150                return pawn->getHealth()/pawn->getMaxHealth() + distance;
151        }
152
153    /**
154        @brief
155        Does all the controlling of the turret.
156
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.
159    */
160        void TurretController::tick(float dt)
161        {
162            if (!this->isActive() || !this->getControllableEntity())
163                return;
164
165
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;
170        }
171
172        if(!this->once_)
173                this->once_ = true;
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
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                        {
198                                this->getControllableEntity()->fire(0);
199                        }
200                }
201        }
202 }
Note: See TracBrowser for help on using the repository browser.