Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

Some documenting and cleaning up/re-organization in pickups module.

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