Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/presentation2012merge/src/modules/pickup/PickupCollection.cc @ 9294

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

removed 2 lines from ~PickupCollection() again because they don't solve the real issue
use destroy() for PickupCollectionIdentifier because it's an OrxonoxClass
calling this→destroy() should be the last thing you do in a function
details in PickupIdentifier

  • 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 *      Damian 'Mozork' Frick
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29/**
30    @file PickupCollection.cc
31    @brief Implementation of PickupCollection.
32*/
33
34#include "core/CoreIncludes.h"
35#include "core/XMLPort.h"
36
37#include "interfaces/PickupCarrier.h"
38
39#include "CollectiblePickup.h"
40#include "DroppedPickup.h"
41#include "PickupCollectionIdentifier.h"
42
43#include "PickupCollection.h"
44
45namespace orxonox
46{
47
48    CreateFactory(PickupCollection);
49
50    /**
51    @brief
52        Default Constructor.
53    @param creator
54        The creator of the object.
55    */
56    PickupCollection::PickupCollection(BaseObject* creator) : BaseObject(creator), pickupCollectionIdentifier_(NULL)
57    {
58        RegisterObject(PickupCollection);
59
60        this->pickupCollectionIdentifier_ = new PickupCollectionIdentifier(this);
61        this->usedCounter_ = 0;
62        this->pickedUpCounter_ = 0;
63        this->disabledCounter_ = 0;
64        this->processingUsed_ = false;
65        this->processingPickedUp_ = false;
66    }
67
68    /**
69    @brief
70        Destructor. Iterates through all Pickupables this PickupCollection consists of and destroys them if they haven't been already.
71    */
72    PickupCollection::~PickupCollection()
73    {
74        // Destroy all Pickupables constructing this PickupCollection.
75        for(std::list<CollectiblePickup*>::iterator it = this->pickups_.begin(); it != this->pickups_.end(); ++it)
76        {
77            (*it)->wasRemovedFromCollection();
78            (*it)->destroyPickup();
79        }
80        this->pickups_.clear();
81
82        if(this->pickupCollectionIdentifier_ != NULL)
83            this->pickupCollectionIdentifier_->destroy();
84    }
85
86    /**
87    @brief
88        Creates an instance of this Class through XML.
89    */
90    void PickupCollection::XMLPort(Element& xmlelement, XMLPort::Mode mode)
91    {
92        SUPER(PickupCollection, XMLPort, xmlelement, mode);
93
94        XMLPortObject(PickupCollection, CollectiblePickup, "pickupables", addPickupable, getPickupable, xmlelement, mode);
95    }
96
97    /**
98    @brief
99        Is called when the pickup has transited from used to unused or the other way around.
100        Any Class overwriting this method must call its SUPER function by adding SUPER(Classname, changedUsed); to their changdeUsed method.
101    */
102    void PickupCollection::changedUsed(void)
103    {
104        SUPER(PickupCollection, changedUsed);
105
106        this->processingUsed_ = true;
107        // Change used for all Pickupables this PickupCollection consists of.
108        for(std::list<CollectiblePickup*>::iterator it = this->pickups_.begin(); it != this->pickups_.end(); ++it)
109            (*it)->setUsed(this->isUsed());
110
111        this->processingUsed_ = false;
112
113        this->changedUsedAction();
114    }
115
116    /**
117    @brief
118        Helper method.
119        Checks whether due to changes in the used status of the pickups of this PickupCollection the used status of this PickupCollection has to change as well.
120    */
121    void PickupCollection::changedUsedAction(void)
122    {
123        if(this->processingUsed_)
124            return;
125
126        // If all the pickups are not in use but the PickupCollection is.
127        if(this->usedCounter_ == 0 && this->isUsed())
128            this->setUsed(false);
129
130        // If all the enabled pickups are in use but the PickupCollection is not.
131        if(this->usedCounter_ != 0 && this->usedCounter_ == this->pickups_.size()-this->disabledCounter_ && !this->isUsed())
132            this->setUsed(true);
133    }
134
135    /**
136    @brief
137        Is called when the pickup has changed its PickupCarrier.
138        Any Class overwriting this method must call its SUPER function by adding SUPER(Classname, changedCarrier); to their changedCarrier method.
139    */
140    void PickupCollection::changedCarrier(void)
141    {
142        SUPER(PickupCollection, changedCarrier);
143
144        // Change the PickupCarrier for all Pickupables this PickupCollection consists of.
145        for(std::list<CollectiblePickup*>::iterator it = this->pickups_.begin(); it != this->pickups_.end(); ++it)
146        {
147            if(this->getCarrier() == NULL)
148                (*it)->setCarrier(NULL);
149            else
150                (*it)->setCarrier(this->getCarrier()->getTarget(*it));
151        }
152    }
153
154    /**
155    @brief
156        Is called when the pickup has transited from picked up to dropped or the other way around.
157        Any Class overwriting this method must call its SUPER function by adding SUPER(Classname, changedPickedUp); to their changedPickedUp method.
158    */
159    void PickupCollection::changedPickedUp()
160    {
161        SUPER(PickupCollection, changedPickedUp);
162
163        this->processingPickedUp_ = true;
164        // Change the pickedUp status for all Pickupables this PickupCollection consists of.
165        for(std::list<CollectiblePickup*>::iterator it = this->pickups_.begin(); it != this->pickups_.end(); )
166            (*(it++))->setPickedUp(this->isPickedUp());
167
168        this->processingPickedUp_ = false;
169
170        this->changedPickedUpAction();
171    }
172
173    /**
174    @brief
175        Helper method.
176        Checks whether due to changes in the picked up status of the pickups of this PickupCollection the picked up status of this PickupCollection has to change as well.
177    */
178    void PickupCollection::changedPickedUpAction(void)
179    {
180        if(this->processingPickedUp_)
181            return;
182
183        // If at least all the enabled pickups of this PickupCollection are no longer picked up.
184        if(this->pickedUpCounter_ <= this->disabledCounter_ && this->isPickedUp())
185            this->Pickupable::destroy();
186        else if(!this->isPickedUp()) // If the PickupCollection is no longer picked up.
187            this->pickedUpCounter_ = 0;
188    }
189
190    /**
191    @brief
192        Creates a duplicate of the input Pickupable.
193        This method needs to be implemented by any Class inheriting from Pickupable.
194    @param item
195        A reference to a pointer to the OrxonoxClass that is to be duplicated.
196    */
197    void PickupCollection::clone(OrxonoxClass*& item)
198    {
199        if(item == NULL)
200            item = new PickupCollection(this);
201
202        SUPER(PickupCollection, clone, item);
203
204        PickupCollection* pickup = orxonox_cast<PickupCollection*>(item);
205        // Clone all Pickupables this PickupCollection consist of.
206        for(std::list<CollectiblePickup*>::iterator it = this->pickups_.begin(); it != this->pickups_.end(); ++it)
207        {
208            Pickupable* newPickup = (*it)->clone();
209            CollectiblePickup* collectible = static_cast<CollectiblePickup*>(newPickup);
210            pickup->addPickupable(collectible);
211        }
212    }
213
214    /**
215    @brief
216        Get whether a given class, represented by the input Identifier, is a target of this PickupCollection.
217    @param carrier
218        A pointer to the PickupCarrier we want to know of, whether it is a target of this PickupCollection.
219    @return
220        Returns true if the PickupCarrier identified by the input PickupIdentififer it is a target of this PickupCollection, false if not.
221    */
222    bool PickupCollection::isTarget(const PickupCarrier* carrier) const
223    {
224        for(std::list<CollectiblePickup*>::const_iterator it = this->pickups_.begin(); it != this->pickups_.end(); ++it)
225        {
226            if(!carrier->isTarget(*it))
227                return false;
228        }
229
230        return true;
231    }
232
233    /**
234    @brief
235        Get the PickupIdentifier of this PickupCollection.
236        This is in fact the PickupCollectionIdentifier.
237    @return
238        Returns a pointer to the PickupIdentifier of this PickupCollection.
239    */
240    const PickupIdentifier* PickupCollection::getPickupIdentifier(void) const
241    {
242        return this->pickupCollectionIdentifier_;
243    }
244
245    /**
246    @brief
247        Add the input Pickupable to list of Pickupables combined by this PickupCollection.
248    @param pickup
249        The Pickupable to be added.
250    @return
251        Returns true if successful,
252    */
253    bool PickupCollection::addPickupable(CollectiblePickup* pickup)
254    {
255        if(pickup == NULL)
256            return false;
257
258        this->pickups_.push_back(pickup);
259        pickup->wasAddedToCollection(this);
260        return true;
261    }
262
263    /**
264    @brief
265        Get the Pickupable at the given index.
266    @param index
267        The index the Pickupable is fetched from.
268    @return
269        Returns a pointer to the Pickupable at the index given by index.
270    */
271    const Pickupable* PickupCollection::getPickupable(unsigned int index) const
272    {
273        if(this->pickups_.size() >= index)
274            return NULL;
275
276        std::list<CollectiblePickup*>::const_iterator it = this->pickups_.begin();
277        std::advance(it, index);
278        return *it;
279    }
280
281    /**
282    @brief
283        Removes the Pickup from the Collection.
284    @param pickup
285        The Pickup to be removed.
286    @return
287        Returns true if the pickup was in the collection.
288    */
289    bool PickupCollection::removePickupable(CollectiblePickup* pickup)
290    {
291        for(std::list<CollectiblePickup*>::iterator it = this->pickups_.begin(); it != this->pickups_.end(); ++it)
292        {
293            if (*it == pickup)
294            {
295                this->pickups_.erase(it);
296                pickup->wasRemovedFromCollection();
297                return true;
298            }
299        }
300        return false;
301    }
302
303    /**
304    @brief
305        Informs the PickupCollection, that one of its pickups has changed its used status to the input value.
306        This is used internally by the CollectiblePickup class.
307    @param changed
308        The value the used status has changed to.
309    */
310    void PickupCollection::pickupChangedUsed(bool changed)
311    {
312        if(changed)
313            this->usedCounter_++;
314        else
315            this->usedCounter_--;
316
317        this->changedUsedAction();
318    }
319
320    /**
321    @brief
322        Informs the PickupCollection, that one of its pickups has changed its picked up status to the input value.
323        This is used internally by the CollectiblePickup class.
324    @param changed
325        The value the picked up status has changed to.
326    */
327    void PickupCollection::pickupChangedPickedUp(bool changed)
328    {
329        if(changed)
330            this->pickedUpCounter_++;
331        else
332            this->pickedUpCounter_--;
333
334        this->changedPickedUpAction();
335    }
336
337    /**
338    @brief
339        Informs the PickupCollection, that one of its pickups has been disabled.
340        This is used internally by the CollectiblePickup class.
341    */
342    void PickupCollection::pickupDisabled(void)
343    {
344        this->disabledCounter_++;
345    }
346
347    /**
348    @brief
349        Facilitates the creation of a PickupSpawner upon dropping of the Pickupable.
350        This method must be implemented by any class directly inheriting from Pickupable. It is most easily done by just creating a new DroppedPickup, e.g.:
351        DroppedPickup(BaseObject* creator, Pickupable* pickup, const Vector3& position);
352    @return
353        Returns true if a spawner was created, false if not.
354    */
355    bool PickupCollection::createSpawner(void)
356    {
357        new DroppedPickup(this, this, this->getCarrier());
358        return true;
359    }
360
361}
Note: See TracBrowser for help on using the repository browser.