Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

remove dropped pickups from their collection

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