Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

simplified code a little by using MultiType instead of explicit conversion

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