Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 10104 was 9667, checked in by landauf, 11 years ago

merged core6 back to trunk

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