Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core7/src/orxonox/interfaces/Pickupable.cc @ 10422

Last change on this file since 10422 was 10362, checked in by landauf, 10 years ago

use static identifier initializer to store the inheritance definition of abstract classes. this prevents that identifiers are used (via Class(Name)) before they are properly initialized.

  • 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<OrxonoxInterface>().inheritsFrom<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.