Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/orxonox/interfaces/Pickupable.cc @ 9143

Last change on this file since 9143 was 8866, checked in by dafrick, 13 years ago

Moved clone base method into Pickupable to avoid ambiguity.

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