Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 7162 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
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/LuaState.h"
37#include "core/GUIManager.h"
38#include "core/Identifier.h"
39#include "core/CoreIncludes.h"
40#include "util/Convert.h"
41#include "infos/PlayerInfo.h"
42#include "pickup/PickupIdentifier.h"
43#include "worldentities/pawns/Pawn.h"
44#include "PickupCarrier.h"
45
46namespace orxonox
47{
48
49    /**
50    @brief
51        Constructor. Registers the objects and initializes its member variables.
52    */
53    Pickupable::Pickupable() : pickupIdentifier_(NULL), used_(false), pickedUp_(false)
54    {
55        RegisterRootObject(Pickupable);
56
57        this->carrier_ = NULL;
58
59        this->pickupIdentifier_ = new PickupIdentifier(this);
60        this->beingDestroyed_ = false;
61        this->enabled_ = true;
62    }
63
64    /**
65    @brief
66        Destructor.
67    */
68    Pickupable::~Pickupable()
69    {
70        COUT(4) << "Pickupable (" << this->getIdentifier()->getName() << ") (&" << this << ") destroyed." << std::endl;
71        if(this->pickupIdentifier_ != NULL)
72            this->pickupIdentifier_->destroy();
73    }
74
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
83        if(this->isPickedUp())
84            this->drop(false); // Drops the pickup without creating a PickupSpawner.
85    }
86
87    /**
88    @brief
89        Is called internally within the pickup module to destroy pickups.
90    */
91    void Pickupable::destroy(void)
92    {
93        this->destroyPickup();
94    }
95
96    /**
97    @brief
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
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    {
119        if(this->used_ == used || !this->isPickedUp()) // If either the used status of the Pickupable doesn't change or it isn't picked up.
120            return false;
121
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
125        COUT(4) << "Pickupable (&" << this << ") set to used " << used << "." << std::endl;
126
127        this->used_ = used;
128        this->changedUsed();
129
130        GUIManager::getInstance().getLuaState()->doString("PickupInventory.update()");
131        return true;
132    }
133
134    /**
135    @brief
136        Get whether the given PickupCarrier is a target of this Pickupable.
137    @param carrier
138        The PickupCarrier of which it has to be determinde whether it is a target of this Pickupable.
139    @return
140        Returns true if the given PickupCarrier is a target.
141    */
142    bool Pickupable::isTarget(PickupCarrier* carrier) const
143    {
144        if(carrier == NULL)
145            return false;
146
147        return this->isTarget(carrier->getIdentifier());
148    }
149
150    /**
151    @brief
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.
155    @return
156        Returns true if the given PickupCarrier is a target.
157    */
158    bool Pickupable::isTarget(const Identifier* identifier) const
159    {
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        {
163            if(identifier->isA(*it))
164                return true;
165        }
166
167        return false;
168    }
169
170    /**
171    @brief
172        Add a PickupCarrier as target of this Pickupable.
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    {
180        return this->addTarget(target->getIdentifier());
181    }
182
183    /**
184    @brief
185        Add a class, representetd by the input Identifier, as target of this Pickupable.
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    {
193        if(this->isTarget(target)) //!< If the input target is already present in the list of targets.
194            return false;
195
196        COUT(4) << "Target " << target->getName() << " added to Pickupable (&" << this << ")." << std::endl;
197        this->targets_.push_back(target);
198        return true;
199    }
200
201    /**
202    @brief
203        Can be called to pick up a Pickupable.
204    @param carrier
205        A pointer to the PickupCarrier that picks up the Pickupable.
206    @return
207        Returns true if the Pickupable was picked up, false if not.
208    */
209    bool Pickupable::pickup(PickupCarrier* carrier)
210    {
211        if(carrier == NULL || this->isPickedUp()) //!< If carrier is NULL or the Pickupable is already picked up.
212            return false;
213
214        if(!this->setCarrier(carrier))
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        }
219       
220        this->setPickedUp(true);
221        COUT(4) << "Pickupable (&" << this << ") got picked up by a PickupCarrier (&" << carrier << ")." << std::endl;
222        return true;
223    }
224
225    /**
226    @brief
227        Can be called to drop a Pickupable.
228    @param createSpawner
229        If true a spawner is to be created for the dropped Pickupable. True is default.
230    @return
231        Returns true if the Pickupable has been dropped, false if not.
232    */
233    bool Pickupable::drop(bool createSpawner)
234    {
235        if(!this->isPickedUp()) // If the Pickupable is not picked up.
236            return false;
237
238        assert(this->getCarrier()); // The Carrier cannot be NULL at this point.
239        if(!this->getCarrier()->removePickup(this)) //TODO Shouldn't this be a little later?
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
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
252        if(!created && createSpawner) // If a PickupSpawner should have been created but wasn't.
253            this->destroy();
254
255        return true;
256    }
257
258    /**
259    @brief
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    {
268        if(this->pickedUp_ == pickedUp) // If the picked up status has not changed.
269            return false;
270
271        COUT(4) << "Pickupable (&" << this << ") set to pickedUp " << pickedUp << "." << std::endl;
272
273        this->pickedUp_ = pickedUp;
274        if(!pickedUp) // if the Pickupable has been dropped it unregisters itself with its PickupCarrier.
275            this->getCarrier()->removePickup(this);
276        this->changedPickedUp();
277        GUIManager::getInstance().getLuaState()->doString("PickupInventory.update()");
278        return true;
279    }
280
281    /**
282    @brief
283        Sets the carrier of the Pickupable.
284    @param carrier
285        Sets the input PickupCarrier as the carrier of the pickup.
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.
290    */
291    bool Pickupable::setCarrier(orxonox::PickupCarrier* carrier, bool tell)
292    {
293        if(this->carrier_ == carrier) // If the PickupCarrier doesn't change.
294            return false;
295
296        COUT(4) << "Pickupable (&" << this << ") changed Carrier (& " << carrier << ")." << std::endl;
297
298        if(carrier != NULL && tell)
299        {
300            if(!carrier->addPickup(this))
301                return false;
302        }
303       
304        this->carrier_ = carrier;
305        this->changedCarrier();
306        return true;
307    }
308
309    /**
310    @brief
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
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    {
326        OrxonoxClass* item = NULL;
327        this->clone(item);
328
329        Pickupable* pickup = dynamic_cast<Pickupable*>(item);
330
331        COUT(4) << "Pickupable (&" << this << ") cloned. Clone is new Pickupable (&" << pickup << ")." << std::endl;
332        return pickup;
333    }
334
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
340        A reference to a pointer to the OrxonoxClass that is to be duplicated.
341    */
342    void Pickupable::clone(OrxonoxClass*& item)
343    {
344        SUPER(Pickupable, clone, item);
345    }
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);
360        return this->pickup(carrier);
361    }
362
363}
Note: See TracBrowser for help on using the repository browser.