Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/spaceboundaries/src/orxonox/worldentities/SpaceBoundaries.cc @ 8244

Last change on this file since 8244 was 8244, checked in by kmaurus, 13 years ago

Pawns that want to leave the area are reflected, one billboard is added that represents the boundary

File size: 8.4 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 *      Maurus Kaufmann
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#include "SpaceBoundaries.h"
30
31#include "worldentities/MobileEntity.h"
32#include "worldentities/ControllableEntity.h"
33#include "core/ObjectListIterator.h"
34#include "core/XMLPort.h"
35#include "worldentities/pawns/Pawn.h"
36#include "infos/PlayerInfo.h"
37#include "interfaces/RadarViewable.h"
38#include "graphics/Billboard.h"
39
40
41//#include <OgreTextAreaOverlayElement.h>
42#include <OgreOverlayManager.h>
43//#include <overlays/OverlayText.h>
44
45namespace orxonox
46{
47    CreateFactory(SpaceBoundaries);
48
49    SpaceBoundaries::SpaceBoundaries(BaseObject* creator) : StaticEntity(creator)
50    {
51        /* Standardwerte, die zum Tragen kommen,
52         * falls im XML-File keine Werte spezifiziert wurden. */
53        this->setMaxDistance(3000);
54        this->setWarnDistance(2000);
55        this->setShowDistance(2500);
56        this->setHealthDecrease(1);
57       
58        RegisterObject(SpaceBoundaries);
59       
60        // Show Boundaries on the radar.
61        this->centerRadar_ = new RadarViewable(this, this);
62        this->centerRadar_->setRadarObjectShape(RadarViewable::Dot);
63        this->centerRadar_->setRadarVisibility(false);
64       
65//         m_pColoredTextAreaOverlayElementFactory = new ColoredTextAreaOverlayElementFactory();
66    }
67    SpaceBoundaries::~SpaceBoundaries()
68    {
69        delete this->centerRadar_;
70       
71        if(this->boundary_ != NULL)
72        {
73            delete this->boundary_;
74        }
75       
76//        delete pColoredTextAreaOverlayElementFactory;
77    }
78   
79    void SpaceBoundaries::setMaxDistance(float r)
80    {
81        this->maxDistance_ = r;
82    }
83    float SpaceBoundaries::getMaxDistance()
84    {
85        return this->maxDistance_;
86    }
87   
88    void SpaceBoundaries::setWarnDistance(float r)
89    {
90        this->warnDistance_ = r;
91    }
92    float SpaceBoundaries::getWarnDistance()
93    {
94        return this->warnDistance_;
95    }
96   
97    void SpaceBoundaries::setShowDistance(float r)
98    {
99        this->showDistance_ = r;
100    }
101    float SpaceBoundaries::getShowDistance()
102    {
103        return this->showDistance_;
104    }
105   
106    void SpaceBoundaries::setHealthDecrease(float amount)
107    {
108        this->healthDecrease_ = amount/1000;
109    }
110    float SpaceBoundaries::getHealthDecrease()
111    {
112        return this->healthDecrease_;
113    }
114
115    void SpaceBoundaries::XMLPort(Element& xmlelement, XMLPort::Mode mode)
116    {
117        SUPER(SpaceBoundaries, XMLPort, xmlelement, mode);
118
119        XMLPortParam(SpaceBoundaries, "maxDistance", setMaxDistance, getMaxDistance, xmlelement, mode);
120        XMLPortParam(SpaceBoundaries, "warnDistance", setWarnDistance, getWarnDistance, xmlelement, mode);
121        XMLPortParam(SpaceBoundaries, "healthDecrease", setHealthDecrease, getHealthDecrease, xmlelement, mode);
122    }
123   
124    void SpaceBoundaries::tick(float dt)
125    {
126        for(ObjectListIterator<MobileEntity> item = ObjectList<MobileEntity>::begin(); item != ObjectList<MobileEntity>::end(); ++item)
127        {
128            MobileEntity* myMobileEntity = *item;
129            Pawn* currentPawn = dynamic_cast<Pawn*>(myMobileEntity);
130            if(currentPawn != NULL)
131            {
132                float distance = this->computeDistance(currentPawn);
133                bool humanItem = this->isHumanPlayer(currentPawn);
134                COUT(0) << "Distanz:" << distance << std::endl; //!< message for debugging
135                if(distance > this->warnDistance_ && distance < this->maxDistance_) // Zeige Warnung an!
136                {
137                    COUT(0) << "You are leaving the area" << std::endl; //!< message for debugging
138                    if(humanItem)
139                    {
140                        COUT(0) << "humanItem ist true" << std::endl;
141                        this->displayWarning("Attention! You are leaving the area!");
142                    } else {
143                       
144                    }
145                }
146                if( (this->maxDistance_ - distance) < this->showDistance_)
147                {
148                    // Zeige Grenze an!
149                    this->displayBoundaries(currentPawn);
150                }
151                if(distance > this->maxDistance_)
152                {
153                    if(humanItem)
154                    {
155                        COUT(0) << "Health should be decreasing!" << std::endl;
156                        this->displayWarning("You are out of the area now!");
157                        currentPawn->removeHealth( (distance - maxDistance_) * this->healthDecrease_);
158                    } else {
159                       
160                    }
161                   
162                    this->bounceBack(currentPawn);
163                }
164            }
165        }
166    }
167   
168    float SpaceBoundaries::computeDistance(WorldEntity *item)
169    {
170        Vector3 itemPosition = item->getPosition();
171        return (itemPosition.distance(this->getPosition()));
172    }
173   
174    void SpaceBoundaries::displayWarning(const std::string warnText)
175    {   /*
176        Ogre::TextAreaOverlayElement *pTextArea;
177        Ogre::OverlayManager manager = Ogre::OverlayManager();
178        Ogre::OverlayElement temp = manager.createOverlayElement("TextArea", "MyTextArea");
179        //pTextArea = (Ogre::TextAreaOverlayElement *)
180       // pTextArea->setCaption("Some plain text");
181   
182        Ogre::TextAreaOverlayElement warning(warnText);
183        warning.initialise();
184        //warning.setPosition(0.2, 0.2);
185       
186
187        COUT(0) << "Breite des Warntextes: " << warning.getWidth() << std::endl;
188        COUT(0) << "Hoehe des Warntextes: " << warning.getHeight() << std::endl;
189       
190        warning.show();*/
191        // Register the overlay element
192/*         OverlayManager::getSingleton().addOverlayElementFactory(pColoredTextAreaOverlayElementFactory);
193         
194        Ogre::TextAreaOverlayElement *pTextArea =
195                (Ogre::TextAreaOverlayElement*)Ogre::OverlayManager.createOverlayElement("TextArea", "MyTextArea");
196        pTextArea->setCaption("Some plain text");
197*/
198       
199    }
200   
201    void SpaceBoundaries::displayBoundaries(Pawn *item)
202    {
203       
204        Vector3 direction = item->getPosition() - this->getPosition();
205        direction.normalise();
206       
207        Vector3 boundaryPosition = this->getPosition() + direction * this->maxDistance_;
208       
209        if(this->boundary_ == NULL)
210        {
211            this->boundary_ = new Billboard(this);
212            this->boundary_->setMaterial("Examples/Flare");
213            this->boundary_->setVisible(true);
214        }
215       
216        this->boundary_->setPosition(boundaryPosition);
217    }
218   
219    void SpaceBoundaries::bounceBack(Pawn *item)
220    {
221        Vector3 normal = item->getPosition() - this->getPosition();
222        if( item->getVelocity().dotProduct(normal) > 0 ) // greife nur ein, falls
223        {
224            normal.normalise();
225            Vector3 velocity = item->getVelocity();
226            velocity = velocity.reflect(normal);
227            Vector3 acceleration = item->getAcceleration();
228            acceleration = acceleration.reflect(normal);
229            /*
230            Vector3 rotationAxis = velocity.crossProduct(normal);
231            Ogre::Radian angle = velocity.angleBetween(normal);
232            item->setOrientation(Ogre::Quaternion::Quaternion(angle, rotationAxis));
233            */
234            item->setAcceleration(acceleration);
235            item->setVelocity(velocity);
236        }
237    }
238   
239    bool SpaceBoundaries::isHumanPlayer(Pawn *item)
240    {
241        if(item != NULL)
242        {
243            if(item->getPlayer())
244            {
245                return item->getPlayer()->isHumanPlayer();
246            }
247        }
248        return false;
249    }
250   
251}
Note: See TracBrowser for help on using the repository browser.