Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/presentation2012merge/src/modules/pickup/items/ShrinkPickup.cc @ 9319

Last change on this file since 9319 was 9318, checked in by landauf, 12 years ago

removed PickupIdentifier for a number of reasons (I talked to Damian about it before)
a pickup now references the PickupRepresentation by name with the "representation" attribute

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