Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

merged branch presentation2012merge back to trunk

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