Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 9292 was 9292, checked in by dafrick, 12 years ago

Looked through recten changes in pickup module, should be fine!

  • 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            delete this->pickupCollectionIdentifier_;
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
187        // If the PickupCollection is no longer picked up.
188        if(!this->isPickedUp())
189            this->pickedUpCounter_ = 0;
190    }
191
192    /**
193    @brief
194        Creates a duplicate of the input Pickupable.
195        This method needs to be implemented by any Class inheriting from Pickupable.
196    @param item
197        A reference to a pointer to the OrxonoxClass that is to be duplicated.
198    */
199    void PickupCollection::clone(OrxonoxClass*& item)
200    {
201        if(item == NULL)
202            item = new PickupCollection(this);
203
204        SUPER(PickupCollection, clone, item);
205
206        PickupCollection* pickup = orxonox_cast<PickupCollection*>(item);
207        // Clone all Pickupables this PickupCollection consist of.
208        for(std::list<CollectiblePickup*>::iterator it = this->pickups_.begin(); it != this->pickups_.end(); ++it)
209        {
210            Pickupable* newPickup = (*it)->clone();
211            CollectiblePickup* collectible = static_cast<CollectiblePickup*>(newPickup);
212            pickup->addPickupable(collectible);
213        }
214    }
215
216    /**
217    @brief
218        Get whether a given class, represented by the input Identifier, is a target of this PickupCollection.
219    @param carrier
220        A pointer to the PickupCarrier we want to know of, whether it is a target of this PickupCollection.
221    @return
222        Returns true if the PickupCarrier identified by the input PickupIdentififer it is a target of this PickupCollection, false if not.
223    */
224    bool PickupCollection::isTarget(const PickupCarrier* carrier) const
225    {
226        for(std::list<CollectiblePickup*>::const_iterator it = this->pickups_.begin(); it != this->pickups_.end(); ++it)
227        {
228            if(!carrier->isTarget(*it))
229                return false;
230        }
231
232        return true;
233    }
234
235    /**
236    @brief
237        Get the PickupIdentifier of this PickupCollection.
238        This is in fact the PickupCollectionIdentifier.
239    @return
240        Returns a pointer to the PickupIdentifier of this PickupCollection.
241    */
242    const PickupIdentifier* PickupCollection::getPickupIdentifier(void) const
243    {
244        return this->pickupCollectionIdentifier_;
245    }
246
247    /**
248    @brief
249        Add the input Pickupable to list of Pickupables combined by this PickupCollection.
250    @param pickup
251        The Pickupable to be added.
252    @return
253        Returns true if successful,
254    */
255    bool PickupCollection::addPickupable(CollectiblePickup* pickup)
256    {
257        if(pickup == NULL)
258            return false;
259
260        this->pickups_.push_back(pickup);
261        pickup->wasAddedToCollection(this);
262        return true;
263    }
264
265    /**
266    @brief
267        Get the Pickupable at the given index.
268    @param index
269        The index the Pickupable is fetched from.
270    @return
271        Returns a pointer to the Pickupable at the index given by index.
272    */
273    const Pickupable* PickupCollection::getPickupable(unsigned int index) const
274    {
275        if(this->pickups_.size() >= index)
276            return NULL;
277
278        std::list<CollectiblePickup*>::iterator it = this->pickups_.begin();
279        std::advance(it, index);
280        return *it;
281    }
282
283    /**
284    @brief
285        Removes the Pickup from the Collection.
286    @param pickup
287        The Pickup to be removed.
288    @return
289        Returns true if the pickup was in the collection.
290    */
291    bool PickupCollection::removePickupable(CollectiblePickup* pickup)
292    {
293        for(std::list<CollectiblePickup*>::iterator it = this->pickups_.begin(); it != this->pickups_.end(); ++it)
294        {
295            if (*it == pickup)
296            {
297                this->pickups_.erase(it);
298                pickup->wasRemovedFromCollection();
299                return true;
300            }
301        }
302        return false;
303    }
304
305    /**
306    @brief
307        Informs the PickupCollection, that one of its pickups has changed its used status to the input value.
308        This is used internally by the CollectiblePickup class.
309    @param changed
310        The value the used status has changed to.
311    */
312    void PickupCollection::pickupChangedUsed(bool changed)
313    {
314        if(changed)
315            this->usedCounter_++;
316        else
317            this->usedCounter_--;
318
319        this->changedUsedAction();
320    }
321
322    /**
323    @brief
324        Informs the PickupCollection, that one of its pickups has changed its picked up status to the input value.
325        This is used internally by the CollectiblePickup class.
326    @param changed
327        The value the picked up status has changed to.
328    */
329    void PickupCollection::pickupChangedPickedUp(bool changed)
330    {
331        if(changed)
332            this->pickedUpCounter_++;
333        else
334            this->pickedUpCounter_--;
335
336        this->changedPickedUpAction();
337    }
338
339    /**
340    @brief
341        Informs the PickupCollection, that one of its pickups has been disabled.
342        This is used internally by the CollectiblePickup class.
343    */
344    void PickupCollection::pickupDisabled(void)
345    {
346        this->disabledCounter_++;
347    }
348
349    /**
350    @brief
351        Facilitates the creation of a PickupSpawner upon dropping of the Pickupable.
352        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.:
353        DroppedPickup(BaseObject* creator, Pickupable* pickup, const Vector3& position);
354    @return
355        Returns true if a spawner was created, false if not.
356    */
357    bool PickupCollection::createSpawner(void)
358    {
359        new DroppedPickup(this, this, this->getCarrier());
360        return true;
361    }
362
363}
Note: See TracBrowser for help on using the repository browser.