Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/presentation3/src/orxonox/interfaces/Pickupable.cc @ 7186

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

Significant structural changes to the pickup module. Lots of bugs found and fixed.
Introduced a new class CollectiblePickup (which is now the only kind a PickupCollection can consist of) to solve some issues cleanly.
MetaPickup received additional functionality. It can now also be set to either destroy all the pickups of a PickupCarrier or destroy the PickupCarrier itself. (This was done mainly for testing purposes)
I've done some extensive testing on the pickups, so they should really work now.

  • Property svn:eol-style set to native
File size: 11.2 KB
RevLine 
[6474]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 Pickupable.cc
[6474]31    @brief Implementation of the Pickupable class.
32*/
33
34#include "Pickupable.h"
35
[6996]36#include "core/LuaState.h"
37#include "core/GUIManager.h"
[6474]38#include "core/Identifier.h"
39#include "core/CoreIncludes.h"
[6996]40#include "util/Convert.h"
41#include "infos/PlayerInfo.h"
[6475]42#include "pickup/PickupIdentifier.h"
[6996]43#include "worldentities/pawns/Pawn.h"
[6474]44#include "PickupCarrier.h"
45
46namespace orxonox
47{
[7127]48
[6474]49    /**
50    @brief
51        Constructor. Registers the objects and initializes its member variables.
52    */
[6725]53    Pickupable::Pickupable() : pickupIdentifier_(NULL), used_(false), pickedUp_(false)
[7127]54    {
[6478]55        RegisterRootObject(Pickupable);
[7127]56
[6474]57        this->carrier_ = NULL;
[7127]58
[6480]59        this->pickupIdentifier_ = new PickupIdentifier(this);
[7162]60        this->beingDestroyed_ = false;
61        this->enabled_ = true;
[6474]62    }
[7127]63
[6474]64    /**
65    @brief
[7127]66        Destructor.
[6474]67    */
68    Pickupable::~Pickupable()
69    {
[7162]70        COUT(4) << "Pickupable (" << this->getIdentifier()->getName() << ") (&" << this << ") destroyed." << std::endl;
71        if(this->pickupIdentifier_ != NULL)
72            this->pickupIdentifier_->destroy();
73    }
[7127]74
[7162]75    /**
76    @brief
77        A method that is called by OrxonoxClass::destroy() before the object is actually destroyed.
78    */
79    void Pickupable::preDestroy(void)
80    {
81        this->beingDestroyed_ = true;
82
[7150]83        if(this->isPickedUp())
[7162]84            this->drop(false); // Drops the pickup without creating a PickupSpawner.
85    }
[7127]86
[7162]87    /**
88    @brief
89        Is called internally within the pickup module to destroy pickups.
90    */
91    void Pickupable::destroy(void)
92    {
93        this->destroyPickup();
[6474]94    }
[7127]95
[6474]96    /**
97    @brief
[7162]98        Destroys a Pickupable.
99        If the Pickupable is already in the process of being destroyed a warning is displayed and this method is skipped.
100    */
101    void Pickupable::destroyPickup(void)
102    {
103        if(!this->beingDestroyed_)
104            this->OrxonoxClass::destroy();
105        else
106            COUT(2) << this->getIdentifier()->getName() << " may be unsafe. " << std::endl;
107    }
108
109    /**
110    @brief
[6474]111        Sets the Pickupable to used or unused, depending on the input.
112    @param used
113        If used is true the Pickupable is set to used, it is set to unused, otherwise.
114    @return
115        Returns true if the used state was changed, false if not.
116    */
117    bool Pickupable::setUsed(bool used)
118    {
[7162]119        if(this->used_ == used || !this->isPickedUp()) // If either the used status of the Pickupable doesn't change or it isn't picked up.
[6474]120            return false;
[7127]121
[7162]122        if((!this->isUsable() && used) || (!this->isUnusable() && !used)) // If either the Pickupable is requested to be used but it is not usable or the Pickupable is requested to be unused, while it is not unusable.
123            return false;
124
[6474]125        COUT(4) << "Pickupable (&" << this << ") set to used " << used << "." << std::endl;
[7127]126
[6474]127        this->used_ = used;
128        this->changedUsed();
[6996]129
130        GUIManager::getInstance().getLuaState()->doString("PickupInventory.update()");
[6474]131        return true;
132    }
[7127]133
[6474]134    /**
135    @brief
[6538]136        Get whether the given PickupCarrier is a target of this Pickupable.
[6474]137    @param carrier
[6538]138        The PickupCarrier of which it has to be determinde whether it is a target of this Pickupable.
[6474]139    @return
140        Returns true if the given PickupCarrier is a target.
141    */
[6901]142    bool Pickupable::isTarget(PickupCarrier* carrier) const
[6474]143    {
[6731]144        if(carrier == NULL)
145            return false;
[7162]146
[6490]147        return this->isTarget(carrier->getIdentifier());
148    }
[7127]149
[6490]150    /**
151    @brief
[6731]152        Get whether the given Identififer is a target of this Pickupable.
153    @param identifier
154        The PickupCarrier of which it has to be determinde whether it is a target of this Pickupable.
[6490]155    @return
[6731]156        Returns true if the given PickupCarrier is a target.
[6490]157    */
[6731]158    bool Pickupable::isTarget(const Identifier* identifier) const
[6490]159    {
[6474]160        //! Iterate through all targets of this Pickupable.
161        for(std::list<Identifier*>::const_iterator it = this->targets_.begin(); it != this->targets_.end(); it++)
162        {
[6731]163            if(identifier->isA(*it))
[6474]164                return true;
165        }
[7162]166
[6474]167        return false;
168    }
[7127]169
[6474]170    /**
171    @brief
[6538]172        Add a PickupCarrier as target of this Pickupable.
[6474]173    @param target
174        The PickupCarrier to be added.
175    @return
176        Returns true if the target was added, false if not.
177    */
178    bool Pickupable::addTarget(PickupCarrier* target)
179    {
[6490]180        return this->addTarget(target->getIdentifier());
181    }
[7127]182
[6490]183    /**
184    @brief
[6538]185        Add a class, representetd by the input Identifier, as target of this Pickupable.
[6490]186    @param target
187        The Identifier to be added.
188    @return
189        Returns true if the target was added, false if not.
190    */
191    bool Pickupable::addTarget(Identifier* target)
192    {
[6474]193        if(this->isTarget(target)) //!< If the input target is already present in the list of targets.
194            return false;
[7127]195
[6490]196        COUT(4) << "Target " << target->getName() << " added to Pickupable (&" << this << ")." << std::endl;
197        this->targets_.push_back(target);
[6474]198        return true;
199    }
[7127]200
[6474]201    /**
[7127]202    @brief
[7150]203        Can be called to pick up a Pickupable.
[6474]204    @param carrier
[7150]205        A pointer to the PickupCarrier that picks up the Pickupable.
[6474]206    @return
[7150]207        Returns true if the Pickupable was picked up, false if not.
[6474]208    */
[7150]209    bool Pickupable::pickup(PickupCarrier* carrier)
[6474]210    {
[7150]211        if(carrier == NULL || this->isPickedUp()) //!< If carrier is NULL or the Pickupable is already picked up.
[6474]212            return false;
[7127]213
[7162]214        if(!this->setCarrier(carrier))
[7150]215        {
216            COUT(3) << "A Pickupable (&" << this << ") was trying to be added to a PickupCarrier, but was already present." << std::endl;
217            return false;
218        }
[7162]219       
220        this->setPickedUp(true);
[6474]221        COUT(4) << "Pickupable (&" << this << ") got picked up by a PickupCarrier (&" << carrier << ")." << std::endl;
222        return true;
223    }
[7127]224
[6474]225    /**
[6521]226    @brief
[7150]227        Can be called to drop a Pickupable.
228    @param createSpawner
[7162]229        If true a spawner is to be created for the dropped Pickupable. True is default.
[7150]230    @return
231        Returns true if the Pickupable has been dropped, false if not.
232    */
233    bool Pickupable::drop(bool createSpawner)
234    {
[7162]235        if(!this->isPickedUp()) // If the Pickupable is not picked up.
[7150]236            return false;
237
[7162]238        assert(this->getCarrier()); // The Carrier cannot be NULL at this point.
[7150]239        if(!this->getCarrier()->removePickup(this)) //TODO Shouldn't this be a little later?
[7162]240            COUT(2) << "Pickupable (&" << this << ", " << this->getIdentifier()->getName() << ") is being dropped, but it was not present in the PickupCarriers list of pickups." << std::endl;
241
[7150]242        COUT(4) << "Pickupable (&" << this << ") got dropped up by a PickupCarrier (&" << this->getCarrier() << ")." << std::endl;
243        this->setUsed(false);
244        this->setPickedUp(false);
245
246        bool created = false;
247        if(createSpawner)
248            created = this->createSpawner();
249
250        this->setCarrier(NULL);
251
[7162]252        if(!created && createSpawner) // If a PickupSpawner should have been created but wasn't.
[7150]253            this->destroy();
254
255        return true;
256    }
257
258    /**
259    @brief
[6521]260        Helper method to set the Pickupable to either picked up or not picked up.
261    @param pickedUp
262        The value this->pickedUp_ should be set to.
263    @return
264        Returns true if the pickedUp status was changed, false if not.
265    */
266    bool Pickupable::setPickedUp(bool pickedUp)
267    {
[7162]268        if(this->pickedUp_ == pickedUp) // If the picked up status has not changed.
[6521]269            return false;
[7127]270
[6521]271        COUT(4) << "Pickupable (&" << this << ") set to pickedUp " << pickedUp << "." << std::endl;
[7127]272
[6521]273        this->pickedUp_ = pickedUp;
[7162]274        if(!pickedUp) // if the Pickupable has been dropped it unregisters itself with its PickupCarrier.
275            this->getCarrier()->removePickup(this);
[6521]276        this->changedPickedUp();
[6996]277        GUIManager::getInstance().getLuaState()->doString("PickupInventory.update()");
[6521]278        return true;
279    }
[7127]280
[6521]281    /**
282    @brief
[6538]283        Sets the carrier of the Pickupable.
[6521]284    @param carrier
285        Sets the input PickupCarrier as the carrier of the pickup.
[7162]286    @param tell
287        If true (default) the pickup is added to the list of pickups in the PickupCarrier.
288    @return
289        Returns true if successful, false if not.
[6521]290    */
[7162]291    bool Pickupable::setCarrier(orxonox::PickupCarrier* carrier, bool tell)
[6521]292    {
[7162]293        if(this->carrier_ == carrier) // If the PickupCarrier doesn't change.
[6521]294            return false;
[7127]295
[6521]296        COUT(4) << "Pickupable (&" << this << ") changed Carrier (& " << carrier << ")." << std::endl;
[7127]297
[7162]298        if(carrier != NULL && tell)
299        {
300            if(!carrier->addPickup(this))
301                return false;
302        }
303       
[6521]304        this->carrier_ = carrier;
305        this->changedCarrier();
306        return true;
307    }
[7127]308
[6521]309    /**
[7127]310    @brief
[7162]311        Is called by the PickupCarrier when it is being destroyed.
312    */
313    void Pickupable::carrierDestroyed(void)
314    {
315        this->destroy();
316    }
317
318    /**
319    @brief
[6474]320        Creates a duplicate of the Pickupable.
321    @return
322        Returns the clone of this pickup as a pointer to a Pickupable.
323    */
324    Pickupable* Pickupable::clone(void)
325    {
[6497]326        OrxonoxClass* item = NULL;
327        this->clone(item);
[7127]328
[6497]329        Pickupable* pickup = dynamic_cast<Pickupable*>(item);
[7127]330
[6474]331        COUT(4) << "Pickupable (&" << this << ") cloned. Clone is new Pickupable (&" << pickup << ")." << std::endl;
332        return pickup;
333    }
[7127]334
[6474]335    /**
336    @brief
337        Creates a duplicate of the input OrxonoxClass.
338        This method needs to be implemented by any Class inheriting from Pickupable.
339    @param item
[6538]340        A reference to a pointer to the OrxonoxClass that is to be duplicated.
[6474]341    */
[6497]342    void Pickupable::clone(OrxonoxClass*& item)
[6474]343    {
344        SUPER(Pickupable, clone, item);
345    }
[6996]346
347    /**
348    @brief
349        Method to transcribe a Pickupable as a Rewardable to the player.
350    @param player
351        A pointer to the PlayerInfo, do whatever you want with it.
352    @return
353        Return true if successful.
354    */
355    bool Pickupable::reward(PlayerInfo* player)
356    {
357        ControllableEntity* entity = player->getControllableEntity();
358        Pawn* pawn = static_cast<Pawn*>(entity);
359        PickupCarrier* carrier = static_cast<PickupCarrier*>(pawn);
[7150]360        return this->pickup(carrier);
[6996]361    }
[7127]362
[6474]363}
Note: See TracBrowser for help on using the repository browser.