Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/modules/pickup/PickupCollection.cc @ 7339

Last change on this file since 7339 was 7163, checked in by dafrick, 14 years ago

Merged presentation3 branch into trunk.

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