Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/HUD_HS16/src/orxonox/interfaces/Pickupable.cc @ 12150

Last change on this file since 12150 was 11510, checked in by patricwi, 7 years ago

looking for SEGFault

  • Property svn:eol-style set to native
File size: 10.6 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_ = nullptr;
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        orxout()<< "end of preDestroy" << endl;
83    }
84
85    /**
86    @brief
87        Is called internally within the pickup module to destroy pickups.
88    */
89    void Pickupable::destroy(void)
90    {
91        this->destroyPickup();
92    }
93
94    /**
95    @brief
96        Destroys a Pickupable.
97        If the Pickupable is already in the process of being destroyed a warning is displayed and this method is skipped.
98    */
99    void Pickupable::destroyPickup(void)
100    {
101        orxout()<< "beginning of actual destroy" << endl;
102        if(!this->isBeingDestroyed())
103            this->Destroyable::destroy();
104        else
105            orxout(internal_warning, context::pickups) << this->getIdentifier()->getName() << " may be unsafe. " << endl;
106        orxout()<<"end of actual destroy" << 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        orxout(verbose, context::pickups) << "Pickupable (&" << this << ") set to used " << used << "." << endl;
126
127        this->used_ = used;
128
129        // Notify all the PickupListeners of the change.
130        PickupListener::broadcastPickupChangedUsed(this, used);
131
132        this->changedUsed();
133
134
135        return true;
136    }
137
138    /**
139    @brief
140        Get whether the given PickupCarrier is a target of this Pickupable.
141    @param carrier
142        The PickupCarrier of which it has to be determinde whether it is a target of this Pickupable.
143    @return
144        Returns true if the given PickupCarrier is a target.
145    */
146    bool Pickupable::isTarget(const PickupCarrier* carrier) const
147    {
148        if(carrier == nullptr)
149            return false;
150
151        return this->isTarget(carrier->getIdentifier());
152    }
153
154    /**
155    @brief
156        Get whether the given Identififer is a target of this Pickupable.
157    @param identifier
158        The PickupCarrier of which it has to be determinde whether it is a target of this Pickupable.
159    @return
160        Returns true if the given PickupCarrier is a target.
161    */
162    bool Pickupable::isTarget(const Identifier* identifier) const
163    {
164        // Iterate through all targets of this Pickupable.
165        for(Identifier* target : this->targets_)
166        {
167            if(identifier->isA(target))
168                return true;
169        }
170
171        return false;
172    }
173
174    /**
175    @brief
176        Add a PickupCarrier as target of this Pickupable.
177    @param target
178        The PickupCarrier to be added.
179    @return
180        Returns true if the target was added, false if not.
181    */
182    bool Pickupable::addTarget(PickupCarrier* target)
183    {
184        return this->addTarget(target->getIdentifier());
185    }
186
187    /**
188    @brief
189        Add a class, representetd by the input Identifier, as target of this Pickupable.
190    @param target
191        The Identifier to be added.
192    @return
193        Returns true if the target was added, false if not.
194    */
195    bool Pickupable::addTarget(Identifier* target)
196    {
197        if(this->isTarget(target)) // If the input target is already present in the list of targets.
198            return false;
199
200        orxout(verbose, context::pickups) << "Target " << target->getName() << " added to Pickupable (" << this->getIdentifier()->getName() << ") (&" << this << ")." << endl;
201        this->targets_.push_back(target);
202        return true;
203    }
204
205    /**
206    @brief
207        Can be called to pick up a Pickupable.
208    @param carrier
209        A pointer to the PickupCarrier that picks up the Pickupable.
210    @return
211        Returns true if the Pickupable was picked up, false if not.
212    */
213    bool Pickupable::pickup(PickupCarrier* carrier)
214    {
215        if(carrier == nullptr || this->isPickedUp()) // If carrier is nullptr or the Pickupable is already picked up.
216            return false;
217
218        if(!this->setCarrier(carrier))
219        {
220            orxout(internal_warning, context::pickups) << "A Pickupable (&" << this << ") was trying to be added to a PickupCarrier, but was already present." << endl;
221            return false;
222        }
223
224        this->setPickedUp(true);
225        orxout(verbose, context::pickups) << "Pickupable (&" << this << ") got picked up by a PickupCarrier (&" << carrier << ")." << endl;
226        return true;
227    }
228
229    /**
230    @brief
231        Can be called to drop a Pickupable.
232    @param createSpawner
233        If true a spawner is to be created for the dropped Pickupable. True is default.
234    @return
235        Returns true if the Pickupable has been dropped, false if not.
236    */
237    bool Pickupable::drop(bool createSpawner)
238    {
239        if(!this->isPickedUp()) // If the Pickupable is not picked up.
240            return false;
241
242        assert(this->getCarrier()); // The Carrier cannot be nullptr at this point.
243        if(!this->getCarrier()->removePickup(this)) //TODO Shouldn't this be a little later?
244            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;
245
246        orxout(verbose, context::pickups) << "Pickupable (&" << this << ") got dropped up by a PickupCarrier (&" << this->getCarrier() << ")." << endl;
247        this->setUsed(false);
248        this->setPickedUp(false);
249
250        bool created = false;
251        if(createSpawner)
252            created = this->createSpawner();
253
254        this->setCarrier(nullptr);
255
256        if(!created && createSpawner) // If a PickupSpawner should have been created but wasn't.
257            this->destroy();
258
259        return true;
260    }
261
262    /**
263    @brief
264        Helper method to set the Pickupable to either picked up or not picked up.
265    @param pickedUp
266        The value this->pickedUp_ should be set to.
267    @return
268        Returns true if the pickedUp status was changed, false if not.
269    */
270    bool Pickupable::setPickedUp(bool pickedUp)
271    {
272        if(this->pickedUp_ == pickedUp) // If the picked up status has not changed.
273            return false;
274
275        orxout(verbose, context::pickups) << "Pickupable (&" << this << ") set to pickedUp " << pickedUp << "." << endl;
276
277        this->pickedUp_ = pickedUp;
278
279        // Notify all the PickupListeners of the change.
280        PickupListener::broadcastPickupChangedPickedUp(this, pickedUp);
281
282        if(!pickedUp) // if the Pickupable has been dropped it unregisters itself with its PickupCarrier.
283            this->getCarrier()->removePickup(this);
284        this->changedPickedUp();
285
286        return true;
287    }
288
289    /**
290    @brief
291        Sets the carrier of the Pickupable.
292    @param carrier
293        Sets the input PickupCarrier as the carrier of the pickup.
294    @param tell
295        If true (default) the pickup is added to the list of pickups in the PickupCarrier.
296    @return
297        Returns true if successful, false if not.
298    */
299    bool Pickupable::setCarrier(orxonox::PickupCarrier* carrier, bool tell)
300    {
301        if(this->carrier_ == carrier) // If the PickupCarrier doesn't change.
302            return false;
303
304        orxout(verbose, context::pickups) << "Pickupable (&" << this << ") changed Carrier (& " << carrier << ")." << endl;
305
306        if(carrier != nullptr && tell)
307        {
308            if(!carrier->addPickup(this))
309                return false;
310        }
311
312        this->carrier_ = carrier;
313        this->changedCarrier();
314        return true;
315    }
316
317    /**
318    @brief
319        Is called by the PickupCarrier when it is being destroyed.
320    */
321    void Pickupable::carrierDestroyed(void)
322    {
323        this->destroy();
324    }
325
326    /**
327    @brief
328        Method to transcribe a Pickupable as a Rewardable to the player.
329    @param player
330        A pointer to the PlayerInfo, do whatever you want with it.
331    @return
332        Return true if successful.
333    */
334    bool Pickupable::reward(PlayerInfo* player)
335    {
336        ControllableEntity* entity = player->getControllableEntity();
337        Pawn* pawn = static_cast<Pawn*>(entity);
338        PickupCarrier* carrier = static_cast<PickupCarrier*>(pawn);
339        return this->pickup(carrier);
340    }
341
342}
Note: See TracBrowser for help on using the repository browser.