Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 7496 was 7494, checked in by dafrick, 14 years ago

Some documenting and cleaning up/re-organization in pickups module.

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