Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/CampaignMap_HS17/src/modules/overlays/hud/StoryModeHUD.cc @ 11535

Last change on this file since 11535 was 11527, checked in by boltn, 7 years ago

Files fuer den story mode hud ge-added (noch nicht fertig)

File size: 13.5 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 *      Felix Schulthess
24 *   Co-authors:
25 *      Reto Grieder
26 *      Oliver Scheuss
27 *      Matthias Spalinger
28 *
29 */
30
31#include "HUDNavigation.h"
32
33#include <OgreCamera.h>
34#include <OgreFontManager.h>
35#include <OgreOverlayManager.h>
36#include <OgreTextAreaOverlayElement.h>
37#include <OgrePanelOverlayElement.h>
38
39#include <typeinfo>
40
41#include "util/Math.h"
42#include "util/Convert.h"
43#include "core/command/ConsoleCommandIncludes.h"
44#include "core/CoreIncludes.h"
45#include "core/XMLPort.h"
46#include "CameraManager.h"
47#include "Scene.h"
48#include "Radar.h"
49#include "graphics/Camera.h"
50#include "controllers/HumanController.h"
51#include "worldentities/pawns/Pawn.h"
52#include "worldentities/WorldEntity.h"
53#include "core/config/ConfigValueIncludes.h"
54#include "tools/TextureGenerator.h"
55
56
57namespace orxonox
58{
59
60    SetConsoleCommand("HUDNavigation","selectClosest", &HUDNavigation::selectClosestTarget).addShortcut().keybindMode(KeybindMode::OnPress);
61    SetConsoleCommand("HUDNavigation","selectNext", &HUDNavigation::selectNextTarget).addShortcut().keybindMode(KeybindMode::OnPress);
62
63    static bool compareDistance(std::pair<RadarViewable*, unsigned int> a,
64            std::pair<RadarViewable*, unsigned int> b)
65    {
66        return a.second < b.second;
67    }
68    RegisterClass ( HUDNavigation );
69
70    HUDNavigation* HUDNavigation::localHUD_s = nullptr;
71
72    HUDNavigation::HUDNavigation(Context* context) :
73        OrxonoxOverlay(context)
74    {
75        RegisterObject(HUDNavigation);
76        this->setConfigValues();
77
78        // Set default values
79        this->setFont("Monofur");
80        this->setTextSize(0.5f);
81
82        this->setDetectionLimit(10000.0f);
83        this->currentMunitionSpeed_ = 750.0f;
84
85        this->closestTarget_ = true;
86        this->nextTarget_ = false;
87        HUDNavigation::localHUD_s = this;
88    }
89
90    HUDNavigation::~HUDNavigation()
91    {
92        if (this->isInitialized())
93        {
94            for (std::map<RadarViewable*, ObjectInfo>::iterator it = this->activeObjectList_.begin(); it != this->activeObjectList_.end();)
95            removeObject((it++)->first);
96        }
97        this->sortedObjectList_.clear();
98    }
99
100     void HUDNavigation::setConfigValues()
101    {
102        SetConfigValue(markerLimit_, 100);
103        SetConfigValue(showDistance_, false);
104    }
105
106
107        void HUDNavigation::XMLPort(Element& xmlelement, XMLPort::Mode mode)
108    {
109        SUPER(HUDNavigation, XMLPort, xmlelement, mode);
110
111        XMLPortParam(HUDNavigation, "font", setFont, getFont, xmlelement, mode);
112        XMLPortParam(HUDNavigation, "textSize", setTextSize, getTextSize, xmlelement, mode);
113    }
114    void HUDNavigation::setFont(const std::string& font)
115    {
116        const Ogre::ResourcePtr& fontPtr = Ogre::FontManager::getSingleton().getByName(font);
117        if (fontPtr.isNull())
118        {
119            orxout(internal_warning) << "HUDNavigation: Font '" << font << "' not found" << endl;
120            return;
121        }
122        this->fontName_ = font;
123        for (const auto& mapEntry : this->activeObjectList_)
124        {
125            if (mapEntry.second.text_ != nullptr)
126                mapEntry.second.text_->setFontName(this->fontName_);
127        }
128    }
129
130    const std::string& HUDNavigation::getFont() const
131    {
132        return this->fontName_;
133    }
134
135    void HUDNavigation::setTextSize(float size)
136    {
137        if (size <= 0.0f)
138        {
139            orxout(internal_warning) << "HUDNavigation: Negative font size not allowed" << endl;
140            return;
141        }
142        this->textSize_ = size;
143        for (const auto& mapEntry : this->activeObjectList_)
144        {
145            if (mapEntry.second.text_)
146                mapEntry.second.text_->setCharHeight(size);
147        }
148    }
149
150    float HUDNavigation::getTextSize() const
151    {
152        return this->textSize_;
153    }
154
155    void HUDNavigation::tick(float dt)
156    {
157        SUPER(HUDNavigation, tick, dt);
158
159        Camera* cam = CameraManager::getInstance().getActiveCamera();
160        if (cam == nullptr)
161        return;
162        const Matrix4& camTransform = cam->getOgreCamera()->getProjectionMatrix() * cam->getOgreCamera()->getViewMatrix();
163
164        for (std::pair<RadarViewable*, unsigned int>& pair : this->sortedObjectList_)
165        pair.second = (int)((pair.first->getRVWorldPosition() - HumanController::getLocalControllerSingleton()->getControllableEntity()->getWorldPosition()).length() + 0.5f);
166
167        this->sortedObjectList_.sort(compareDistance);
168
169        unsigned int markerCount = 0;
170        bool closeEnough = false; // only display objects that are close enough to be relevant for the player
171
172        // if the selected object doesn't exist any more or is now out of range select the closest object
173        std::map<RadarViewable*, ObjectInfo>::iterator selectedActiveObject = this->activeObjectList_.find(this->selectedTarget_);
174        if(selectedActiveObject == this->activeObjectList_.end())
175        {
176            this->closestTarget_ = true;
177        }
178        else if(this->detectionLimit_ < (this->selectedTarget_->getRVWorldPosition() - HumanController::getLocalControllerSingleton()->getControllableEntity()->getWorldPosition()).length() + 0.5f)
179        {
180            this->closestTarget_ = true;
181            selectedActiveObject->second.selected_ = false;
182        }
183
184        bool nextHasToBeSelected = false;
185
186        for (std::list<std::pair<RadarViewable*, unsigned int>>::iterator listIt = this->sortedObjectList_.begin(); listIt != this->sortedObjectList_.end(); ++markerCount, ++listIt)
187        {
188
189            std::map<RadarViewable*, ObjectInfo>::iterator it = this->activeObjectList_.find(listIt->first);
190            closeEnough = listIt->second < this->detectionLimit_;
191            // display radarviewables on HUD if the marker limit and max-distance is not exceeded
192            if (markerCount < this->markerLimit_ && (closeEnough || this->detectionLimit_ < 0))
193            {
194                float textLength = 0.0f;
195
196                {
197                    //display name next to cursor
198                    it->second.text_->setCaption(it->first->getRadarName());
199                    textLength = it->first->getRadarName().size() * it->second.text_->getCharHeight() * 0.3f;
200                }
201
202
203
204
205
206
207                // Transform to screen coordinates
208                Vector3 pos = camTransform * it->first->getRVWorldPosition();
209                {
210                    // Object is in view
211
212                    // Change material only if outOfView changed
213                    if (it->second.wasOutOfView_)
214                    {
215                        //it->second.panel_->setMaterialName("Orxonox/NavTDC");
216                        it->second.panel_->setMaterialName(TextureGenerator::getMaterialName("tdc.png", it->first->getRadarObjectColour()));
217                        it->second.panel_->setDimensions(this->navMarkerSize_ * this->getActualSize().x, this->navMarkerSize_ * this->getActualSize().y);
218                        it->second.target_->setDimensions(this->aimMarkerSize_ * this->getActualSize().x, this->aimMarkerSize_ * this->getActualSize().y);
219                        it->second.wasOutOfView_ = false;
220                    }
221
222                    // Position marker
223                    it->second.panel_->setUV(0.0f, 0.0f, 1.0f, 1.0f);
224                    it->second.panel_->setLeft((pos.x + 1.0f - it->second.panel_->getWidth()) * 0.5f);
225                    it->second.panel_->setTop((-pos.y + 1.0f - it->second.panel_->getHeight()) * 0.5f);
226
227                    // Position text
228                    it->second.text_->setLeft((pos.x + 1.0f + it->second.panel_->getWidth()) * 0.5f);
229                    it->second.text_->setTop((-pos.y + 1.0f + it->second.panel_->getHeight()) * 0.5f);
230
231                    // Make sure the overlays are shown
232                    it->second.panel_->show();
233                    it->second.text_->show();
234
235                    // Target marker
236                    const Pawn* pawn = dynamic_cast<const Pawn*>(it->first->getWorldEntity());
237                    /* Pawn* humanPawn = HumanController::getLocalControllerEntityAsPawn();*/
238                    if(!it->second.selected_
239                            || it->first->getRVVelocity().squaredLength() == 0
240                            || pawn == nullptr
241                            /* TODO : improve getTeam in such a way that it works
242                             * || humanPawn == nullptr
243                             * || pawn->getTeam() == humanPawn->getTeam()*/)
244                    {
245                        // don't show marker for not selected enemies nor if the selected doesn't move
246                        it->second.target_->hide();
247                    }
248                    else // object is selected and moves
249                    {
250                        // get the aim position
251                        const Vector3& targetPos = this->toAimPosition(it->first);
252                        // Transform to screen coordinates
253                        Vector3 screenPos = camTransform * targetPos;
254                        // Check if the target marker is in view too
255                        if(screenPos.z > 1 || screenPos.x < -1.0 || screenPos.x > 1.0
256                                || screenPos.y < -1.0 || screenPos.y > 1.0)
257                        {
258                            it->second.target_->hide();
259                        }
260                        else
261                        {
262                            it->second.target_->setLeft((screenPos.x + 1.0f - it->second.target_->getWidth()) * 0.5f);
263                            it->second.target_->setTop((-screenPos.y + 1.0f - it->second.target_->getHeight()) * 0.5f);
264                            it->second.target_->show();
265                        }
266                    }
267
268                }
269            }
270        }
271
272        this->closestTarget_ = false;
273        this->nextTarget_ = false;
274    }
275
276    void HUDNavigation::addObject(RadarViewable* object)
277    {
278        if (showObject(object) == false)
279        return;
280
281        if (this->activeObjectList_.size() >= this->markerLimit_)
282        if (object == nullptr)
283        return;
284
285        // Object hasn't been added yet (we know that)
286        assert(this->activeObjectList_.find(object) == this->activeObjectList_.end());
287
288        // Scales used for dimensions and text size
289        float xScale = this->getActualSize().x;
290        float yScale = this->getActualSize().y;
291
292        // Create everything needed to display the object on the radar and add it to the map
293
294   
295        //panel->setMaterialName("Orxonox/NavTDC");
296        panel->setMaterialName(TextureGenerator::getMaterialName("tdc.png", object->getRadarObjectColour()));
297        panel->setDimensions(this->navMarkerSize_ * xScale, this->navMarkerSize_ * yScale);
298        //panel->setColour(object->getRadarObjectColour());
299
300        // Create text
301        Ogre::TextAreaOverlayElement* text = static_cast<Ogre::TextAreaOverlayElement*>( Ogre::OverlayManager::getSingleton()
302                .createOverlayElement("TextArea", "HUDNavigation_navText_" + getUniqueNumberString()));
303        text->setFontName(this->fontName_);
304        text->setCharHeight(this->textSize_ * yScale);
305        text->setColour(object->getRadarObjectColour());
306
307        text->hide();
308
309        ObjectInfo tempStruct =
310        {   health, healthLevel, panel, target, text, false, false, false};
311        this->activeObjectList_[object] = tempStruct;
312       
313        this->background_->addChild(text);
314
315        this->sortedObjectList_.push_front(std::make_pair(object, (unsigned int)0));
316    }
317
318    void HUDNavigation::removeObject(RadarViewable* viewable)
319    {
320        std::map<RadarViewable*, ObjectInfo>::iterator it = this->activeObjectList_.find(viewable);
321
322        if (this->activeObjectList_.find(viewable) != this->activeObjectList_.end())
323        {
324            // Detach overlays
325            this->background_->removeChild(it->second.text_->getName());
326            Ogre::OverlayManager::getSingleton().destroyOverlayElement(it->second.text_);
327            // Remove from the list
328            this->activeObjectList_.erase(viewable);
329        }
330
331        for (std::list<std::pair<RadarViewable*, unsigned int>>::iterator listIt = this->sortedObjectList_.begin(); listIt != this->sortedObjectList_.end(); ++listIt)
332        {
333            if ((listIt->first) == viewable)
334            {
335                this->sortedObjectList_.erase(listIt);
336                break;
337            }
338        }
339    }
340
341    void HUDNavigation::objectChanged(RadarViewable* viewable)
342    {
343        // TODO: niceification neccessary ;)
344        removeObject(viewable);
345        addObject(viewable);
346    }
347
348    bool HUDNavigation::showObject(RadarViewable* rv)
349    {
350        if (rv == orxonox_cast<RadarViewable*>(this->getOwner()))
351        return false;
352        assert(rv->getWorldEntity());
353        if (rv->getWorldEntity()->isVisible() == false || rv->getRadarVisibility() == false)
354        return false;
355        return true;
356    }
Note: See TracBrowser for help on using the repository browser.