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
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 "worldentities/pawns/Pawn.h"
43
44#include "worldentities/CameraPosition.h"
45
46namespace orxonox
47{
48    CreateFactory(ShrinkPickup);
49
50    /**
51    @brief
52        Constructor: Initializes the Pickup.
53    */
54    ShrinkPickup::ShrinkPickup(BaseObject* creator) : Pickup(creator)
55    {
56        RegisterObject(ShrinkPickup);
57
58        this->initialize();
59    }
60
61    ShrinkPickup::~ShrinkPickup()
62    {
63
64    }
65
66    void ShrinkPickup::initialize(void)
67    {
68        this->addTarget(ClassIdentifier<Pawn>::getIdentifier());
69
70        this->shrinkFactor_ = 5.0f;
71        this->shrinkDuration_ = 5.0f;
72        this->duration_ = 5.0f;
73
74        this->isActive_ = false;
75        this->isShrinking_ = false;
76        this->isTerminating_ = false;
77
78        this->timeRemainig_ = 0.0f;
79        this->currentFactor_ = 1.0f;
80    }
81
82   /**
83    @brief
84        Method for creating a ShrinkPickup object through XML.
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);
92        XMLPortParam(ShrinkPickup, "shrinkDuration", setShrinkDuration, getShrinkDuration, xmlelement, mode);
93    }
94
95    /**
96    @brief
97        Prepares for shrinking.
98    */
99    void ShrinkPickup::changedUsed(void)
100    {
101        SUPER(ShrinkPickup, changedUsed);
102
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            }
111
112            this->currentFactor_ = 1.0f;
113            this->timeRemainig_ = this->shrinkDuration_;
114
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;
121    }
122
123    void ShrinkPickup::changedPickedUp(void)
124    {
125        SUPER(ShrinkPickup, changedPickedUp);
126
127        if(!this->isPickedUp() && this->isActive_)
128        {
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;
135
136                float factor = 1.0f/this->currentFactor_;
137
138                pawn->setScale3D(pawn->getScale3D()*factor);
139                pawn->setMass(pawn->getMass()*factor);
140
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;
163
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            }
181        }
182    }
183
184    /**
185    @brief
186        Updates the scales of the ship.
187    @param dt
188        Time since last call.
189    */
190    void ShrinkPickup::tick(float dt)
191    {
192        if(this->isActive_)
193        {
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                }
202
203                this->timeRemainig_ -= dt;
204
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;
210
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.
235            {
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();
239
240                this->timeRemainig_ -= dt;
241
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;
247
248                bool destroy = false;
249
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                }
259
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();
276            }
277        }
278    }
279
280    /**
281    @brief
282        Initializes the termination.
283    */
284    void ShrinkPickup::terminate(void)
285    {
286        this->setUsed(false);
287    }
288
289    Pawn* ShrinkPickup::carrierToPawnHelper(void)
290    {
291        PickupCarrier* carrier = this->getCarrier();
292        Pawn* pawn = orxonox_cast<Pawn*>(carrier);
293
294        return pawn;
295    }
296
297    /**
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);
309        ShrinkPickup* pickup = orxonox_cast<ShrinkPickup*>(item);
310        pickup->setShrinkFactor(this->getShrinkFactor());
311        pickup->setDuration(this->getDuration());
312        pickup->setShrinkDuration(this->getShrinkDuration());
313    }
314}
Note: See TracBrowser for help on using the repository browser.