Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 9318 was 9318, checked in by landauf, 13 years ago

removed PickupIdentifier for a number of reasons (I talked to Damian about it before)
a pickup now references the PickupRepresentation by name with the "representation" attribute

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