Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

Adjusting some debug output with the added bonus of no more Segfaults when picking up a pickup.

  • Property svn:eol-style set to native
File size: 11.3 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 Pickupable.cc
31    @brief Implementation of the Pickupable class.
32*/
33
34#include "Pickupable.h"
35
36#include "core/Identifier.h"
37#include "core/CoreIncludes.h"
38#include "util/Convert.h"
39
40#include "infos/PlayerInfo.h"
41#include "pickup/PickupIdentifier.h"
42#include "worldentities/pawns/Pawn.h"
43
44#include "PickupCarrier.h"
45#include "PickupListener.h"
46
47namespace orxonox
48{
49
50    /**
51    @brief
52        Constructor. Registers the objects and initializes its member variables.
53    */
54    Pickupable::Pickupable() : pickupIdentifier_(NULL), used_(false), pickedUp_(false)
55    {
56        RegisterRootObject(Pickupable);
57
58        this->carrier_ = NULL;
59
60        this->pickupIdentifier_ = new PickupIdentifier(this);
61        this->beingDestroyed_ = false;
62        this->enabled_ = true;
63    }
64
65    /**
66    @brief
67        Destructor.
68    */
69    Pickupable::~Pickupable()
70    {
71        if(this->pickupIdentifier_ != NULL)
72        {
73            COUT(4) << "Pickupable (" << this->getIdentifier()->getName() << ") (&" << this << ") destroyed." << std::endl;
74            this->pickupIdentifier_->destroy();
75        }
76    }
77
78    /**
79    @brief
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
109            COUT(2) << this->getIdentifier()->getName() << " may be unsafe. " << std::endl;
110    }
111
112    /**
113    @brief
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    {
122        if(this->used_ == used || !this->isPickedUp()) // If either the used status of the Pickupable doesn't change or it isn't picked up.
123            return false;
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
128        COUT(4) << "Pickupable (&" << this << ") set to used " << used << "." << std::endl;
129
130        this->used_ = used;
131
132        // Notify all the PickupListeners of the change.
133        PickupListener::broadcastPickupChangedUsed(this, used);
134
135        this->changedUsed();
136
137
138        return true;
139    }
140
141    /**
142    @brief
143        Get whether the given PickupCarrier is a target of this Pickupable.
144    @param carrier
145        The PickupCarrier of which it has to be determinde whether it is a target of this Pickupable.
146    @return
147        Returns true if the given PickupCarrier is a target.
148    */
149    bool Pickupable::isTarget(const PickupCarrier* carrier) const
150    {
151        if(carrier == NULL)
152            return false;
153
154        return this->isTarget(carrier->getIdentifier());
155    }
156
157    /**
158    @brief
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.
162    @return
163        Returns true if the given PickupCarrier is a target.
164    */
165    bool Pickupable::isTarget(const Identifier* identifier) const
166    {
167        // Iterate through all targets of this Pickupable.
168        for(std::list<Identifier*>::const_iterator it = this->targets_.begin(); it != this->targets_.end(); it++)
169        {
170            if(identifier->isA(*it))
171                return true;
172        }
173
174        return false;
175    }
176
177    /**
178    @brief
179        Add a PickupCarrier as target of this Pickupable.
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    {
187        return this->addTarget(target->getIdentifier());
188    }
189
190    /**
191    @brief
192        Add a class, representetd by the input Identifier, as target of this Pickupable.
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    {
200        if(this->isTarget(target)) // If the input target is already present in the list of targets.
201            return false;
202
203        COUT(4) << "Target " << target->getName() << " added to Pickupable (" << this->getIdentifier()->getName() << ") (&" << this << ")." << std::endl;
204        this->targets_.push_back(target);
205        return true;
206    }
207
208    /**
209    @brief
210        Can be called to pick up a Pickupable.
211    @param carrier
212        A pointer to the PickupCarrier that picks up the Pickupable.
213    @return
214        Returns true if the Pickupable was picked up, false if not.
215    */
216    bool Pickupable::pickup(PickupCarrier* carrier)
217    {
218        if(carrier == NULL || this->isPickedUp()) // If carrier is NULL or the Pickupable is already picked up.
219            return false;
220
221        if(!this->setCarrier(carrier))
222        {
223            COUT(3) << "A Pickupable (&" << this << ") was trying to be added to a PickupCarrier, but was already present." << std::endl;
224            return false;
225        }
226
227        this->setPickedUp(true);
228        COUT(4) << "Pickupable (&" << this << ") got picked up by a PickupCarrier (&" << carrier << ")." << std::endl;
229        return true;
230    }
231
232    /**
233    @brief
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?
247            COUT(2) << "Pickupable (&" << this << ", " << this->getIdentifier()->getName() << ") is being dropped, but it was not present in the PickupCarriers list of pickups." << std::endl;
248
249        COUT(4) << "Pickupable (&" << this << ") got dropped up by a PickupCarrier (&" << this->getCarrier() << ")." << std::endl;
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
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    {
275        if(this->pickedUp_ == pickedUp) // If the picked up status has not changed.
276            return false;
277
278        COUT(4) << "Pickupable (&" << this << ") set to pickedUp " << pickedUp << "." << std::endl;
279
280        this->pickedUp_ = pickedUp;
281
282        // Notify all the PickupListeners of the change.
283        PickupListener::broadcastPickupChangedPickedUp(this, pickedUp);
284
285        if(!pickedUp) // if the Pickupable has been dropped it unregisters itself with its PickupCarrier.
286            this->getCarrier()->removePickup(this);
287        this->changedPickedUp();
288
289        return true;
290    }
291
292    /**
293    @brief
294        Sets the carrier of the Pickupable.
295    @param carrier
296        Sets the input PickupCarrier as the carrier of the pickup.
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.
301    */
302    bool Pickupable::setCarrier(orxonox::PickupCarrier* carrier, bool tell)
303    {
304        if(this->carrier_ == carrier) // If the PickupCarrier doesn't change.
305            return false;
306
307        COUT(4) << "Pickupable (&" << this << ") changed Carrier (& " << carrier << ")." << std::endl;
308
309        if(carrier != NULL && tell)
310        {
311            if(!carrier->addPickup(this))
312                return false;
313        }
314
315        this->carrier_ = carrier;
316        this->changedCarrier();
317        return true;
318    }
319
320    /**
321    @brief
322        Is called by the PickupCarrier when it is being destroyed.
323    */
324    void Pickupable::carrierDestroyed(void)
325    {
326        this->destroy();
327    }
328
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    {
337        OrxonoxClass* item = NULL;
338        this->clone(item);
339
340        Pickupable* pickup = dynamic_cast<Pickupable*>(item);
341
342        COUT(4) << "Pickupable (" << this->getIdentifier()->getName() << ") (&" << this << ") cloned. Clone is new Pickupable (&" << pickup << ")." << std::endl;
343        return pickup;
344    }
345
346    /**
347    @brief
348        Creates a duplicate of the input OrxonoxClass.
349        This method needs to be implemented by any Class inheriting from Pickupable.
350    @param item
351        A reference to a pointer to the OrxonoxClass that is to be duplicated.
352    */
353    void Pickupable::clone(OrxonoxClass*& item)
354    {
355        SUPER(Pickupable, clone, item);
356    }
357
358    /**
359    @brief
360        Method to transcribe a Pickupable as a Rewardable to the player.
361    @param player
362        A pointer to the PlayerInfo, do whatever you want with it.
363    @return
364        Return true if successful.
365    */
366    bool Pickupable::reward(PlayerInfo* player)
367    {
368        ControllableEntity* entity = player->getControllableEntity();
369        Pawn* pawn = static_cast<Pawn*>(entity);
370        PickupCarrier* carrier = static_cast<PickupCarrier*>(pawn);
371        return this->pickup(carrier);
372    }
373
374}
Note: See TracBrowser for help on using the repository browser.