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
RevLine 
[6405]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/**
[6538]30    @file PickupCollection.cc
[6405]31    @brief Implementation of PickupCollection.
32*/
33
34#include "core/CoreIncludes.h"
35#include "core/XMLPort.h"
[7494]36
[6405]37#include "interfaces/PickupCarrier.h"
[7494]38
[7163]39#include "CollectiblePickup.h"
[6475]40#include "DroppedPickup.h"
41
[6538]42#include "PickupCollection.h"
43
[6405]44namespace orxonox
45{
[7163]46
[6519]47    CreateFactory(PickupCollection);
48
[6405]49    /**
50    @brief
51        Default Constructor.
[7494]52    @param creator
53        The creator of the object.
[6405]54    */
[9318]55    PickupCollection::PickupCollection(BaseObject* creator) : BaseObject(creator)
[6405]56    {
57        RegisterObject(PickupCollection);
[7163]58
59        this->processingUsed_ = false;
60        this->processingPickedUp_ = false;
[6405]61    }
[7163]62
[6405]63    /**
64    @brief
[6538]65        Destructor. Iterates through all Pickupables this PickupCollection consists of and destroys them if they haven't been already.
[6405]66    */
[9290]67    PickupCollection::~PickupCollection()
[6405]68    {
[7163]69        // Destroy all Pickupables constructing this PickupCollection.
[9290]70        for(std::list<CollectiblePickup*>::iterator it = this->pickups_.begin(); it != this->pickups_.end(); ++it)
[6405]71        {
[9290]72            (*it)->wasRemovedFromCollection();
[9296]73            (*it)->destroy();
[6405]74        }
[7163]75        this->pickups_.clear();
[6405]76    }
[7163]77
[6405]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);
[7163]85
[9318]86        XMLPortParam(PickupCollection, "representation", setRepresentationName, getRepresentationName, xmlelement, mode);
[7163]87        XMLPortObject(PickupCollection, CollectiblePickup, "pickupables", addPickupable, getPickupable, xmlelement, mode);
[6405]88    }
[7163]89
[6538]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.
[6475]94    */
[6405]95    void PickupCollection::changedUsed(void)
96    {
97        SUPER(PickupCollection, changedUsed);
[7163]98
99        this->processingUsed_ = true;
100        // Change used for all Pickupables this PickupCollection consists of.
[9290]101        for(std::list<CollectiblePickup*>::iterator it = this->pickups_.begin(); it != this->pickups_.end(); ++it)
[7163]102            (*it)->setUsed(this->isUsed());
[7533]103
[7163]104        this->processingUsed_ = false;
105
106        this->changedUsedAction();
[6405]107    }
[7163]108
[6538]109    /**
110    @brief
[7163]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
[9295]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
[7163]129        // If all the pickups are not in use but the PickupCollection is.
[9295]130        if(numPickupsInUse == 0 && this->isUsed())
[7163]131            this->setUsed(false);
132
133        // If all the enabled pickups are in use but the PickupCollection is not.
[9295]134        if(numPickupsInUse > 0 && numPickupsInUse == numPickupsEnabled && !this->isUsed())
[7163]135            this->setUsed(true);
136    }
137
138    /**
139    @brief
[6538]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    */
[6521]143    void PickupCollection::changedCarrier(void)
[6405]144    {
[6466]145        SUPER(PickupCollection, changedCarrier);
[7163]146
147        // Change the PickupCarrier for all Pickupables this PickupCollection consists of.
[9290]148        for(std::list<CollectiblePickup*>::iterator it = this->pickups_.begin(); it != this->pickups_.end(); ++it)
[6405]149        {
[7163]150            if(this->getCarrier() == NULL)
151                (*it)->setCarrier(NULL);
152            else
153                (*it)->setCarrier(this->getCarrier()->getTarget(*it));
[6405]154        }
155    }
[7163]156
[6538]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    */
[6521]162    void PickupCollection::changedPickedUp()
163    {
164        SUPER(PickupCollection, changedPickedUp);
[7163]165
166        this->processingPickedUp_ = true;
167        // Change the pickedUp status for all Pickupables this PickupCollection consists of.
[9290]168        for(std::list<CollectiblePickup*>::iterator it = this->pickups_.begin(); it != this->pickups_.end(); )
169            (*(it++))->setPickedUp(this->isPickedUp());
[7533]170
[7163]171        this->processingPickedUp_ = false;
172
173        this->changedPickedUpAction();
[6521]174    }
[7163]175
[6538]176    /**
177    @brief
[7163]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
[9279]186        // If at least all the enabled pickups of this PickupCollection are no longer picked up.
[9295]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())
[7163]197            this->Pickupable::destroy();
198    }
199
200    /**
201    @brief
[7494]202        Creates a duplicate of the input Pickupable.
[6538]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    */
[6497]207    void PickupCollection::clone(OrxonoxClass*& item)
[6405]208    {
[6466]209        if(item == NULL)
210            item = new PickupCollection(this);
[7163]211
[6466]212        SUPER(PickupCollection, clone, item);
[7163]213
[9279]214        PickupCollection* pickup = orxonox_cast<PickupCollection*>(item);
[9318]215        pickup->setRepresentationName(this->getRepresentationName());
[7163]216        // Clone all Pickupables this PickupCollection consist of.
[9290]217        for(std::list<CollectiblePickup*>::iterator it = this->pickups_.begin(); it != this->pickups_.end(); ++it)
[6405]218        {
[7163]219            Pickupable* newPickup = (*it)->clone();
220            CollectiblePickup* collectible = static_cast<CollectiblePickup*>(newPickup);
221            pickup->addPickupable(collectible);
[6405]222        }
223    }
[7163]224
[6538]225    /**
226    @brief
227        Get whether a given class, represented by the input Identifier, is a target of this PickupCollection.
[7401]228    @param carrier
229        A pointer to the PickupCarrier we want to know of, whether it is a target of this PickupCollection.
[6538]230    @return
231        Returns true if the PickupCarrier identified by the input PickupIdentififer it is a target of this PickupCollection, false if not.
232    */
[7547]233    bool PickupCollection::isTarget(const PickupCarrier* carrier) const
[6519]234    {
[9290]235        for(std::list<CollectiblePickup*>::const_iterator it = this->pickups_.begin(); it != this->pickups_.end(); ++it)
[6519]236        {
[7163]237            if(!carrier->isTarget(*it))
[6519]238                return false;
239        }
[7163]240
[6519]241        return true;
242    }
[7163]243
[6538]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    */
[7163]252    bool PickupCollection::addPickupable(CollectiblePickup* pickup)
[6538]253    {
254        if(pickup == NULL)
255            return false;
[7163]256
257        this->pickups_.push_back(pickup);
[9290]258        pickup->wasAddedToCollection(this);
[9295]259        this->pickupsChanged();
[6538]260        return true;
261    }
[7163]262
[6538]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    */
[7547]271    const Pickupable* PickupCollection::getPickupable(unsigned int index) const
[6538]272    {
[9292]273        if(this->pickups_.size() >= index)
274            return NULL;
275
[9293]276        std::list<CollectiblePickup*>::const_iterator it = this->pickups_.begin();
[9292]277        std::advance(it, index);
278        return *it;
[6538]279    }
[7163]280
[6538]281    /**
282    @brief
[9290]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();
[9295]297                this->pickupsChanged();
[9290]298                return true;
299            }
300        }
301        return false;
302    }
303
304    /**
305    @brief
[7163]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
[9279]309        The value the used status has changed to.
[7163]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
[9295]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
[6538]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    */
[6540]355    bool PickupCollection::createSpawner(void)
[6538]356    {
[6540]357        new DroppedPickup(this, this, this->getCarrier());
[6538]358        return true;
359    }
[7163]360
361}
Note: See TracBrowser for help on using the repository browser.