Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

Cleaning up ShrinkPickup.

  • Property svn:eol-style set to native
File size: 12.1 KB
RevLine 
[8489]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:
[8713]23 *      Sandro Sgier
[8489]24 *   Co-authors:
25 *      ...
26 *
27 */
28
29
30/**
31    @file ShrinkPickup.cc
32    @brief Implementation of the HealthPickup class.
33*/
34
35
[8375]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
[8489]45#include "worldentities/CameraPosition.h"
[8381]46
[8375]47namespace orxonox
48{
49    CreateFactory(ShrinkPickup);
50
[8713]51    /**
[8534]52    @brief
53        Constructor: Initializes the Pickup.
54    */
[8489]55    ShrinkPickup::ShrinkPickup(BaseObject* creator) : Pickup(creator)
[8375]56    {
57        RegisterObject(ShrinkPickup);
58
59        this->initialize();
[8713]60    }
61
62    ShrinkPickup::~ShrinkPickup()
63    {
64
65    }
66
67    void ShrinkPickup::initialize(void)
68    {
69        this->addTarget(ClassIdentifier<Pawn>::getIdentifier());
70
[8556]71        this->shrinkFactor_ = 5.0f;
[8713]72        this->shrinkDuration_ = 5.0f;
[8556]73        this->duration_ = 5.0f;
[8713]74
[8556]75        this->isActive_ = false;
[8713]76        this->isShrinking_ = false;
[8556]77        this->isTerminating_ = false;
78
[8713]79        this->timeRemainig_ = 0.0f;
80        this->currentFactor_ = 1.0f;
[8375]81    }
82
[8534]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();
[8713]98        stream << this->getShrinkDuration();
[8534]99        std::string val3 = stream.str();
[8713]100        std::string type3 = "shrinkDuration";
[8534]101        this->pickupIdentifier_->addParameter(type3, val3);
102    }
103
104   /**
105    @brief
[8713]106        Method for creating a ShrinkPickup object through XML.
[8534]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);
[8713]114        XMLPortParam(ShrinkPickup, "shrinkDuration", setShrinkDuration, getShrinkDuration, xmlelement, mode);
[8534]115
116        this->initializeIdentifier();
117    }
118
119    /**
120    @brief
[8713]121        Prepares for shrinking.
[8534]122    */
[8713]123    void ShrinkPickup::changedUsed(void)
[8534]124    {
[8713]125        SUPER(ShrinkPickup, changedUsed);
[8534]126
[8713]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            }
[8534]135
[8713]136            this->currentFactor_ = 1.0f;
137            this->timeRemainig_ = this->shrinkDuration_;
[8534]138
[8713]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;
[8489]145    }
[8375]146
[8713]147    void ShrinkPickup::changedPickedUp(void)
[8489]148    {
[8713]149        SUPER(ShrinkPickup, changedPickedUp);
150       
151        if(!this->isPickedUp() && this->isActive_)
[8375]152        {
[8713]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;
[8486]159
[8713]160                float factor = 1.0f/this->currentFactor_;
[8489]161
[8713]162                pawn->setScale3D(pawn->getScale3D()*factor);
163                pawn->setMass(pawn->getMass()*factor);
[8489]164
[8713]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;
[8489]187
[8713]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            }
[8375]205        }
[8489]206    }
[8375]207
[8554]208    /**
[8534]209    @brief
210        Updates the scales of the ship.
211    @param dt
212        Time since last call.
213    */
[8489]214    void ShrinkPickup::tick(float dt)
215    {
[8713]216        if(this->isActive_)
[8489]217        {
[8713]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                }
[8433]226
[8713]227                this->timeRemainig_ -= dt;
[8433]228
[8713]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;
[8433]234
[8713]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.
[8489]259            {
[8713]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();
[8381]263
[8713]264                this->timeRemainig_ -= dt;
[8375]265
[8713]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;
[8489]271
[8713]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                }
[8489]283
[8713]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();
[8489]300            }
301        }
302    }
303
[8554]304    /**
[8534]305    @brief
306        Initializes the termination.
307    */
[8489]308    void ShrinkPickup::terminate(void)
309    {
[8713]310        this->setUsed(false);
[8489]311    }
312
[8375]313    Pawn* ShrinkPickup::carrierToPawnHelper(void)
314    {
315        PickupCarrier* carrier = this->getCarrier();
316        Pawn* pawn = dynamic_cast<Pawn*>(carrier);
317
318        return pawn;
319    }
320
[8554]321    /**
[8375]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);
[8534]333        ShrinkPickup* pickup = dynamic_cast<ShrinkPickup*>(item);
334        pickup->setShrinkFactor(this->getShrinkFactor());
335        pickup->setDuration(this->getDuration());
[8713]336        pickup->setShrinkDuration(this->getShrinkDuration());
[8534]337
338        pickup->initializeIdentifier();
[8375]339    }
340}
Note: See TracBrowser for help on using the repository browser.