Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/sound6/src/modules/pickup/PickupCollection.cc @ 8784

Last change on this file since 8784 was 7547, checked in by dafrick, 14 years ago

Documenting and cleanup.

  • Property svn:eol-style set to native
File size: 11.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)
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::vector<CollectiblePickup*>::iterator it = this->pickups_.begin(); it != this->pickups_.end(); it++)
76        {
77            (*it)->removeFromCollection();
78            (*it)->destroy();
79        }
80        this->pickups_.clear();
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        this->initializeIdentifier();
94    }
95
96    /**
97    @brief
98        Initializes the PickupIdentifier for this pickup.
99    */
100    void PickupCollection::initializeIdentifier(void)
101    {
102        for(std::vector<CollectiblePickup*>::iterator it = this->pickups_.begin(); it != this->pickups_.end(); it++)
103        {
104            this->pickupCollectionIdentifier_->addPickup((*it)->getPickupIdentifier());
105        }
106    }
107
108    /**
109    @brief
110        Is called when the pickup has transited from used to unused or the other way around.
111        Any Class overwriting this method must call its SUPER function by adding SUPER(Classname, changedUsed); to their changdeUsed method.
112    */
113    void PickupCollection::changedUsed(void)
114    {
115        SUPER(PickupCollection, changedUsed);
116
117        this->processingUsed_ = true;
118        // Change used for all Pickupables this PickupCollection consists of.
119        for(std::vector<CollectiblePickup*>::iterator it = this->pickups_.begin(); it != this->pickups_.end(); it++)
120            (*it)->setUsed(this->isUsed());
121
122        this->processingUsed_ = false;
123
124        this->changedUsedAction();
125    }
126
127    /**
128    @brief
129        Helper method.
130        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.
131    */
132    void PickupCollection::changedUsedAction(void)
133    {
134        if(this->processingUsed_)
135            return;
136
137        // If all the pickups are not in use but the PickupCollection is.
138        if(this->usedCounter_ == 0 && this->isUsed())
139            this->setUsed(false);
140
141        // If all the enabled pickups are in use but the PickupCollection is not.
142        if(this->usedCounter_ != 0 && this->usedCounter_ == this->pickups_.size()-this->disabledCounter_ && !this->isUsed())
143            this->setUsed(true);
144    }
145
146    /**
147    @brief
148        Is called when the pickup has changed its PickupCarrier.
149        Any Class overwriting this method must call its SUPER function by adding SUPER(Classname, changedCarrier); to their changedCarrier method.
150    */
151    void PickupCollection::changedCarrier(void)
152    {
153        SUPER(PickupCollection, changedCarrier);
154
155        // Change the PickupCarrier for all Pickupables this PickupCollection consists of.
156        for(std::vector<CollectiblePickup*>::iterator it = this->pickups_.begin(); it != this->pickups_.end(); it++)
157        {
158            if(this->getCarrier() == NULL)
159                (*it)->setCarrier(NULL);
160            else
161                (*it)->setCarrier(this->getCarrier()->getTarget(*it));
162        }
163    }
164
165    /**
166    @brief
167        Is called when the pickup has transited from picked up to dropped or the other way around.
168        Any Class overwriting this method must call its SUPER function by adding SUPER(Classname, changedPickedUp); to their changedPickedUp method.
169    */
170    void PickupCollection::changedPickedUp()
171    {
172        SUPER(PickupCollection, changedPickedUp);
173
174        this->processingPickedUp_ = true;
175        // Change the pickedUp status for all Pickupables this PickupCollection consists of.
176        for(std::vector<CollectiblePickup*>::iterator it = this->pickups_.begin(); it != this->pickups_.end(); it++)
177            (*it)->setPickedUp(this->isPickedUp());
178
179        this->processingPickedUp_ = false;
180
181        this->changedPickedUpAction();
182    }
183
184    /**
185    @brief
186        Helper method.
187        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.
188    */
189    void PickupCollection::changedPickedUpAction(void)
190    {
191        if(this->processingPickedUp_)
192            return;
193
194        // If at least all the enabled pickups of this PickupCollection are no longer picked up.
195        if(this->pickedUpCounter_ <= this->disabledCounter_ && this->isPickedUp())
196            this->Pickupable::destroy();
197
198        // If the PickupCollection is no longer picked up.
199        if(!this->isPickedUp())
200            this->pickedUpCounter_ = 0;
201    }
202
203    /**
204    @brief
205        Creates a duplicate of the input Pickupable.
206        This method needs to be implemented by any Class inheriting from Pickupable.
207    @param item
208        A reference to a pointer to the OrxonoxClass that is to be duplicated.
209    */
210    void PickupCollection::clone(OrxonoxClass*& item)
211    {
212        if(item == NULL)
213            item = new PickupCollection(this);
214
215        SUPER(PickupCollection, clone, item);
216
217        PickupCollection* pickup = dynamic_cast<PickupCollection*>(item);
218        // Clone all Pickupables this PickupCollection consist of.
219        for(std::vector<CollectiblePickup*>::iterator it = this->pickups_.begin(); it != this->pickups_.end(); it++)
220        {
221            Pickupable* newPickup = (*it)->clone();
222            CollectiblePickup* collectible = static_cast<CollectiblePickup*>(newPickup);
223            pickup->addPickupable(collectible);
224        }
225
226        pickup->initializeIdentifier();
227    }
228
229    /**
230    @brief
231        Get whether a given class, represented by the input Identifier, is a target of this PickupCollection.
232    @param carrier
233        A pointer to the PickupCarrier we want to know of, whether it is a target of this PickupCollection.
234    @return
235        Returns true if the PickupCarrier identified by the input PickupIdentififer it is a target of this PickupCollection, false if not.
236    */
237    bool PickupCollection::isTarget(const PickupCarrier* carrier) const
238    {
239        for(std::vector<CollectiblePickup*>::const_iterator it = this->pickups_.begin(); it != this->pickups_.end(); it++)
240        {
241            if(!carrier->isTarget(*it))
242                return false;
243        }
244
245        return true;
246    }
247
248    /**
249    @brief
250        Get the PickupIdentifier of this PickupCollection.
251        This is in fact the PickupCollectionIdentifier.
252    @return
253        Returns a pointer to the PickupIdentifier of this PickupCollection.
254    */
255    const PickupIdentifier* PickupCollection::getPickupIdentifier(void) const
256    {
257        return this->pickupCollectionIdentifier_;
258    }
259
260    /**
261    @brief
262        Add the input Pickupable to list of Pickupables combined by this PickupCollection.
263    @param pickup
264        The Pickupable to be added.
265    @return
266        Returns true if successful,
267    */
268    bool PickupCollection::addPickupable(CollectiblePickup* pickup)
269    {
270        if(pickup == NULL)
271            return false;
272
273        pickup->addToCollection(this);
274        this->pickups_.push_back(pickup);
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        return this->pickups_[index];
289    }
290
291    /**
292    @brief
293        Informs the PickupCollection, that one of its pickups has changed its used status to the input value.
294        This is used internally by the CollectiblePickup class.
295    @param changed
296        The value the used status has changed to.
297    */
298    void PickupCollection::pickupChangedUsed(bool changed)
299    {
300        if(changed)
301            this->usedCounter_++;
302        else
303            this->usedCounter_--;
304
305        this->changedUsedAction();
306    }
307
308    /**
309    @brief
310        Informs the PickupCollection, that one of its pickups has changed its picked up status to the input value.
311        This is used internally by the CollectiblePickup class.
312    @param changed
313        The value the picked up status has changed to.
314    */
315    void PickupCollection::pickupChangedPickedUp(bool changed)
316    {
317        if(changed)
318            this->pickedUpCounter_++;
319        else
320            this->pickedUpCounter_--;
321
322        this->changedPickedUpAction();
323    }
324
325    /**
326    @brief
327        Informs the PickupCollection, that one of its pickups has been disabled.
328        This is used internally by the CollectiblePickup class.
329    */
330    void PickupCollection::pickupDisabled(void)
331    {
332        this->disabledCounter_++;
333    }
334
335    /**
336    @brief
337        Facilitates the creation of a PickupSpawner upon dropping of the Pickupable.
338        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.:
339        DroppedPickup(BaseObject* creator, Pickupable* pickup, const Vector3& position);
340    @return
341        Returns true if a spawner was created, false if not.
342    */
343    bool PickupCollection::createSpawner(void)
344    {
345        new DroppedPickup(this, this, this->getCarrier());
346        return true;
347    }
348
349}
Note: See TracBrowser for help on using the repository browser.