Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/modules/pickup/items/ShrinkPickup.cc @ 8884

Last change on this file since 8884 was 8713, checked in by dafrick, 14 years ago

Cleaning up ShrinkPickup.

  • Property svn:eol-style set to native
File size: 12.1 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 *      Sandro Sgier
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29
30/**
31    @file ShrinkPickup.cc
32    @brief Implementation of the HealthPickup class.
33*/
34
35
36#include "ShrinkPickup.h"
37
38#include <sstream>
39#include "core/CoreIncludes.h"
40#include "core/XMLPort.h"
41
42#include "pickup/PickupIdentifier.h"
43#include "worldentities/pawns/Pawn.h"
44
45#include "worldentities/CameraPosition.h"
46
47namespace orxonox
48{
49    CreateFactory(ShrinkPickup);
50
51    /**
52    @brief
53        Constructor: Initializes the Pickup.
54    */
55    ShrinkPickup::ShrinkPickup(BaseObject* creator) : Pickup(creator)
56    {
57        RegisterObject(ShrinkPickup);
58
59        this->initialize();
60    }
61
62    ShrinkPickup::~ShrinkPickup()
63    {
64
65    }
66
67    void ShrinkPickup::initialize(void)
68    {
69        this->addTarget(ClassIdentifier<Pawn>::getIdentifier());
70
71        this->shrinkFactor_ = 5.0f;
72        this->shrinkDuration_ = 5.0f;
73        this->duration_ = 5.0f;
74
75        this->isActive_ = false;
76        this->isShrinking_ = false;
77        this->isTerminating_ = false;
78
79        this->timeRemainig_ = 0.0f;
80        this->currentFactor_ = 1.0f;
81    }
82
83    void ShrinkPickup::initializeIdentifier(void)
84    {
85        std::stringstream stream;
86        stream << this->getShrinkFactor();
87        std::string type1 = "shrinkFactor";
88        std::string val1 = stream.str();
89        this->pickupIdentifier_->addParameter(type1, val1);
90
91        stream.clear();
92        stream << this->getDuration();
93        std::string val2 = stream.str();
94        std::string type2 = "duration";
95        this->pickupIdentifier_->addParameter(type2, val2);
96
97        stream.clear();
98        stream << this->getShrinkDuration();
99        std::string val3 = stream.str();
100        std::string type3 = "shrinkDuration";
101        this->pickupIdentifier_->addParameter(type3, val3);
102    }
103
104   /**
105    @brief
106        Method for creating a ShrinkPickup object through XML.
107    */
108    void ShrinkPickup::XMLPort(Element& xmlelement, orxonox::XMLPort::Mode mode)
109    {
110        SUPER(ShrinkPickup, XMLPort, xmlelement, mode);
111
112        XMLPortParam(ShrinkPickup, "shrinkFactor", setShrinkFactor, getShrinkFactor, xmlelement, mode);
113        XMLPortParam(ShrinkPickup, "duration", setDuration, getDuration, xmlelement, mode);
114        XMLPortParam(ShrinkPickup, "shrinkDuration", setShrinkDuration, getShrinkDuration, xmlelement, mode);
115
116        this->initializeIdentifier();
117    }
118
119    /**
120    @brief
121        Prepares for shrinking.
122    */
123    void ShrinkPickup::changedUsed(void)
124    {
125        SUPER(ShrinkPickup, changedUsed);
126
127        if(this->isUsed())
128        {
129            Pawn* pawn = this->carrierToPawnHelper();
130            if(pawn == NULL) // If the PickupCarrier is no Pawn, then this pickup is useless and therefore is destroyed.
131            {
132                this->Pickupable::destroy();
133                return;
134            }
135
136            this->currentFactor_ = 1.0f;
137            this->timeRemainig_ = this->shrinkDuration_;
138
139            this->isActive_ = true; // Start shrinking now.
140            this->isShrinking_ = true;
141            this->durationTimer_.setTimer(this->duration_, false, createExecutor(createFunctor(&ShrinkPickup::terminate, this))); //Set timer for termination.
142        }
143        if(!this->isUsed() && this->isActive_)
144             this->isTerminating_ = true;
145    }
146
147    void ShrinkPickup::changedPickedUp(void)
148    {
149        SUPER(ShrinkPickup, changedPickedUp);
150       
151        if(!this->isPickedUp() && this->isActive_)
152        {
153            if(this->isShrinking_ || this->isTerminating_)
154            {
155                //TODO: Deploy particle effect.
156                Pawn* pawn = this->carrierToPawnHelper();
157                if(pawn == NULL) // If the PickupCarrier is no Pawn, then this pickup is useless and therefore is destroyed.
158                    return;
159
160                float factor = 1.0f/this->currentFactor_;
161
162                pawn->setScale3D(pawn->getScale3D()*factor);
163                pawn->setMass(pawn->getMass()*factor);
164
165                // Iterate over all camera positions and inversely move the camera to create a shrinking sensation.
166                const std::list< SmartPtr<CameraPosition> >& cameraPositions = pawn->getCameraPositions();
167                int size = cameraPositions.size();
168                for(int index = 0; index < size; index++)
169                {
170                    CameraPosition* cameraPos = pawn->getCameraPosition(index);
171                    if(cameraPos == NULL)
172                        continue;
173                    cameraPos->setPosition(cameraPos->getPosition()/factor);
174                }
175                this->currentFactor_ = 1.0f;
176                this->timeRemainig_ = this->shrinkDuration_;
177                this->isActive_ = false;
178                this->isShrinking_ = false;
179                this->isTerminating_ = false;
180            }
181            else
182            {
183                //TODO: Deploy particle effect.
184                Pawn* pawn = this->carrierToPawnHelper();
185                if(pawn == NULL) // If the PickupCarrier is no Pawn, then this pickup is useless and therefore is destroyed.
186                    return;
187
188                pawn->setScale3D(pawn->getScale3D()*this->shrinkFactor_);
189                pawn->setMass(pawn->getMass()*this->shrinkFactor_);
190
191                // Iterate over all camera positions and inversely move the camera to create a shrinking sensation.
192                const std::list< SmartPtr<CameraPosition> >& cameraPositions = pawn->getCameraPositions();
193                int size = cameraPositions.size();
194                for(int index = 0; index < size; index++)
195                {
196                    CameraPosition* cameraPos = pawn->getCameraPosition(index);
197                    if(cameraPos == NULL)
198                        continue;
199                    cameraPos->setPosition(cameraPos->getPosition()/this->shrinkFactor_);
200                }
201                this->currentFactor_ = 1.0f;
202                this->timeRemainig_ = this->shrinkDuration_;
203                this->isActive_ = false;
204            }
205        }
206    }
207
208    /**
209    @brief
210        Updates the scales of the ship.
211    @param dt
212        Time since last call.
213    */
214    void ShrinkPickup::tick(float dt)
215    {
216        if(this->isActive_)
217        {
218            if(this->isShrinking_)    // If the ship has not reached the target scale, continue shrinking
219            {
220                Pawn* pawn = this->carrierToPawnHelper();
221                if(pawn == NULL) // If the PickupCarrier is no Pawn, then this pickup is useless and therefore is destroyed.
222                {
223                    this->Pickupable::destroy();
224                    return;
225                }
226
227                this->timeRemainig_ -= dt;
228
229                // Calculate the scaling factor by which the initial size would have to be scaled to have the current scale.
230                float currentFactor = std::max(1 - (1-std::max(this->timeRemainig_, 0.0f)/this->shrinkDuration_)*(1-1/this->shrinkFactor_), 1/this->shrinkFactor_);
231                // Calculate the factor by which the previous size has to be scaled to be the current scale.
232                float factor = currentFactor/this->currentFactor_;
233                this->currentFactor_ = currentFactor;
234
235                // Stop shrinking if the desired size is reached.
236                if(this->timeRemainig_ <= 0.0f)
237                {
238                    this->timeRemainig_ = this->shrinkDuration_; // Reset the time remaining for when we start to grow the ship again.
239                    this->currentFactor_ = 1/this->shrinkFactor_;
240                    this->isShrinking_ = false;
241                }
242
243                pawn->setScale3D(pawn->getScale3D()*factor);
244                pawn->setMass(pawn->getMass()*factor);
245
246                // Iterate over all camera positions and inversely move the camera to create a shrinking sensation.
247                const std::list< SmartPtr<CameraPosition> >& cameraPositions = pawn->getCameraPositions();
248                int size = cameraPositions.size();
249                for(int index = 0; index < size; index++)
250                {
251                    CameraPosition* cameraPos = pawn->getCameraPosition(index);
252                    if(cameraPos == NULL)
253                        continue;
254                    cameraPos->setPosition(cameraPos->getPosition()/factor);
255                }
256
257            }
258            else if(this->isTerminating_)    // Grow until the ship reaches its default scale.
259            {
260                Pawn* pawn = this->carrierToPawnHelper();
261                if(pawn == NULL) // If the PickupCarrier is no Pawn, then this pickup is useless and therefore is destroyed.
262                    this->Pickupable::destroy();
263
264                this->timeRemainig_ -= dt;
265
266                // Calculate the scaling factor by which the initial size would have to be scaled to have the current scale.
267                float currentFactor = std::min(1/this->shrinkFactor_ + (1-std::max(this->timeRemainig_, 0.0f)/this->shrinkDuration_)*(1-1/this->shrinkFactor_), 1.0f);
268                // Calculate the factor by which the previous size has to be scaled to be the current scale.
269                float factor = currentFactor/this->currentFactor_;
270                this->currentFactor_ = currentFactor;
271
272                bool destroy = false;
273               
274                // Stop shrinking if the desired size is reached.
275                if(this->timeRemainig_ <= 0.0f)
276                {
277                    this->timeRemainig_ = shrinkDuration_; // Reset the time remaining for when we start to grow the ship again.
278                    this->currentFactor_ = 1.0f;
279                    this->isTerminating_ = false;
280                    this->isActive_ = false;
281                    destroy = true;
282                }
283
284                pawn->setScale3D(pawn->getScale3D()*factor);
285                pawn->setMass(pawn->getMass()*factor);
286
287                // Iterate over all camera positions and inversely move the camera to create a shrinking sensation.
288                const std::list< SmartPtr<CameraPosition> >& cameraPositions = pawn->getCameraPositions();
289                int size = cameraPositions.size();
290                for(int index = 0; index < size; index++)
291                {
292                    CameraPosition* cameraPos = pawn->getCameraPosition(index);
293                    if(cameraPos == NULL)
294                        continue;
295                    cameraPos->setPosition(cameraPos->getPosition()/factor);
296                }
297
298                if(destroy)
299                    this->Pickupable::destroy();
300            }
301        }
302    }
303
304    /**
305    @brief
306        Initializes the termination.
307    */
308    void ShrinkPickup::terminate(void)
309    {
310        this->setUsed(false);
311    }
312
313    Pawn* ShrinkPickup::carrierToPawnHelper(void)
314    {
315        PickupCarrier* carrier = this->getCarrier();
316        Pawn* pawn = dynamic_cast<Pawn*>(carrier);
317
318        return pawn;
319    }
320
321    /**
322    @brief
323        Creates a duplicate of the input OrxonoxClass.
324    @param item
325        A pointer to the Orxonox class.
326    */
327    void ShrinkPickup::clone(OrxonoxClass*& item)
328    {
329        if(item == NULL)
330            item = new ShrinkPickup(this);
331
332        SUPER(ShrinkPickup, clone, item);
333        ShrinkPickup* pickup = dynamic_cast<ShrinkPickup*>(item);
334        pickup->setShrinkFactor(this->getShrinkFactor());
335        pickup->setDuration(this->getDuration());
336        pickup->setShrinkDuration(this->getShrinkDuration());
337
338        pickup->initializeIdentifier();
339    }
340}
Note: See TracBrowser for help on using the repository browser.