Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/pickup3/src/modules/pickup/PickupSpawner.cc @ 6421

Last change on this file since 6421 was 6421, checked in by dafrick, 14 years ago

Some Documenting and bug fixes.

  • Property svn:eol-style set to native
File size: 10.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 *      Daniel 'Huty' Haggenmueller
24 *   Co-authors:
25 *      Damian 'Mozork' Frick
26 *
27 */
28
29/**
30    @file
31    @brief Implementation of PickupSpawner.
32*/
33
34#include "PickupSpawner.h"
35
36#include "core/CoreIncludes.h"
37//#include "core/GUIManager.h"     // HACK; see below
38#include "core/Template.h"
39#include "core/XMLPort.h"
40#include "worldentities/pawns/Pawn.h"
41//#include "PickupInventory.h"    // HACK; Only for hack, remove later
42
43
44namespace orxonox
45{
46
47//     const float PickupSpawner::bounceSpeed_s = 6.0f;
48//     const float PickupSpawner::rotationSpeed_s = 1.0f;
49//     const float PickupSpawner::bounceDistance_s = 4.0f;
50
51    CreateFactory(PickupSpawner);
52
53    /**
54    @brief
55        Constructor. Creates a blank PickupSpawner.
56    @param creator
57        Pointer to the object which created this item.
58    */
59    PickupSpawner::PickupSpawner(BaseObject* creator) : StaticEntity(creator)
60    {
61        this->initialize();
62    }
63
64    /**
65    @brief
66        Constructor, Creates a fully functional PickupSpawner.
67    @param creator
68        The creator of this PickupSpawner.
69    @param pickup
70        The Pickupable to be spawned by this PickupSpawner.
71    @param triggerDistance
72        The distance at which the PickupSpawner will trigger.
73    @param respawnTime
74        The minimum time between two spawns.
75    @param maySpawnedItems
76        The maximum number of items spawned by this PickupSpawner.
77    */
78    PickupSpawner::PickupSpawner(BaseObject* creator, Pickupable* pickup, float triggerDistance, float respawnTime, int maxSpawnedItems) : StaticEntity(creator)
79    {
80        this->initialize();
81 
82        this->pickup_ = pickup;
83
84        this->triggerDistance_ = triggerDistance;
85        this->respawnTime_ = respawnTime;
86        this->setMaxSpawnedItems(maxSpawnedItems);
87    }
88
89    /**
90    @brief
91        Registers the object and sets some default values.
92    */
93    void PickupSpawner::initialize(void)
94    {
95        RegisterObject(PickupSpawner);
96
97        this->pickup_ = NULL;
98       
99        this->triggerDistance_ = 20;
100        this->respawnTime_ = 0;
101        this->tickSum_ = 0;
102        this->maxSpawnedItems_ = INF;
103        this->spawnsRemaining_ = INF;
104    }
105
106    /**
107    @brief
108        Destructor.
109    */
110    PickupSpawner::~PickupSpawner()
111    {
112        if(this->pickup_ != NULL)
113            delete this->pickup_;
114    }
115
116    /**
117    @brief
118        Method for creating a PickupSpawner through XML.
119    @param xmlelement
120        XML element which contains the PickupSpawner.
121    @param mode
122        XMLPort mode.
123    */
124    void PickupSpawner::XMLPort(Element& xmlelement, XMLPort::Mode mode)
125    {
126        SUPER(PickupSpawner, XMLPort, xmlelement, mode);
127
128        XMLPortObject(PickupSpawner, Pickupable, "pickup", setPickupable, getPickupable, xmlelement, mode);
129       
130        XMLPortParam(PickupSpawner, "triggerDistance", setTriggerDistance, getTriggerDistance, xmlelement, mode);
131        XMLPortParam(PickupSpawner, "respawnTime", setRespawnTime, getRespawnTime, xmlelement, mode);
132        XMLPortParam(PickupSpawner, "maxSpawnedItems", setMaxSpawnedItems, getMaxSpawnedItems, xmlelement, mode);
133
134        //TODO: Kill hack.
135        // HACKs
136        // Load the GUI image as soon as the PickupSpawner gets loaded
137        //  = less delays while running
138//         BaseObject* newObject = this->itemTemplate_->getBaseclassIdentifier()->fabricate(this);
139//         BaseItem* asItem = orxonox_cast<BaseItem*>(newObject);
140//         if (asItem)
141//         {
142//             asItem->addTemplate(this->itemTemplate_);
143//             PickupInventory::getImageForItem(asItem);
144//             newObject->destroy();
145//         }
146
147        //  & load the GUI itself too, along with some empty windows
148        //   = even less delays
149//         GUIManager::getInstance().showGUI("PickupInventory");
150//         GUIManager::getInstance().executeCode("hideGUI(\"PickupInventory\")");
151//         PickupInventory::getSingleton();
152    }
153   
154    /**
155    @brief
156        Sets a Pickupable for the PickupSpawner to spawn.
157    @param pickup
158        The Pickupable to be set.
159    */
160    void PickupSpawner::setPickupable(Pickupable* pickup)
161    {
162        if(this->pickup_ != NULL)
163        {
164            COUT(1) << "addPickupable called, with this->pickup_ already set." << std::endl;
165            return;
166        }
167        if(pickup == NULL)
168        {
169            COUT(1) << "Argument of addPickupable is NULL." << std::endl;
170            return;
171        }
172       
173        this->pickup_ = pickup;
174    }
175   
176    /**
177    @brief
178        Get the Pickupable that is spawned by this PickupSpawner.
179    @return
180        Returns the Pickupable that is spawned by this PickupSpawner.
181    */
182    const Pickupable* PickupSpawner::getPickupable(void)
183    {
184        return this->pickup_;
185    }
186
187    /**
188    @brief
189        Invoked when the activity has changed. Sets visibility of attached objects.
190    */
191//     void PickupSpawner::changedActivity()
192//     {
193//         SUPER(PickupSpawner, changedActivity);
194//
195//         for (std::set<WorldEntity*>::const_iterator it = this->getAttachedObjects().begin(); it != this->getAttachedObjects().end(); it++)
196//             (*it)->setVisible(this->isActive());
197//     }
198
199    /**
200    @brief
201        Sets the maximum number of spawned items.
202    @param items
203        The maximum number of spawned items to be set.
204    */
205    void PickupSpawner::setMaxSpawnedItems(int items)
206    {
207        this->maxSpawnedItems_ = items;
208        this->spawnsRemaining_ = items;
209    }
210
211    /**
212    @brief
213        Tick, checks if any Pawn is close enough to trigger.
214    @param dt
215        Time since last tick.
216    */
217    //TODO: Replace this with a real DistanceTrigger?
218    void PickupSpawner::tick(float dt)
219    {
220        //! If the PickupSpawner is active.
221        if (this->isActive())
222        {
223            //! Iterate trough all Pawns.
224            for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it != ObjectList<Pawn>::end(); ++it)
225            {
226                Vector3 distance = it->getWorldPosition() - this->getWorldPosition();
227                //! If a Pawn, that fits the target-range of the item spawned by this Pickup, is in trigger-distance.
228                if (distance.length() < this->triggerDistance_ && this->pickup_->isTarget(*it))
229                {
230                    this->trigger(*it);
231                }
232            }
233
234            //! Animation.
235//             this->yaw(Radian(rotationSpeed_s*dt));
236//             this->tickSum_ += bounceSpeed_s*dt;
237//             this->translate(Vector3(0,bounceDistance_s*dt*sin(this->tickSum_),0));
238//             if (this->tickSum_ > 2*Ogre::Math::PI)
239//                 this->tickSum_ -= 2*Ogre::Math::PI;
240        }
241    }
242
243    /**
244    @brief
245        Trigger the PickupSpawner.
246
247        Adds the pickup to the Pawn that triggered,
248        sets the timer to re-activate and deactives the PickupSpawner.
249
250    @param pawn
251        Pawn which triggered the PickupSpawner.
252    */
253    void PickupSpawner::trigger(Pawn* pawn)
254    {
255        //TODO: If private, isActive doesn't need to be tested anymore.
256        if (this->isActive()) //!< Checks whether PickupItem is active.
257        {
258            Pickupable* pickup = this->getPickup();
259            if (pickup != NULL) //!< If everything went ok, and pickup is not NULL.
260            {
261                PickupCarrier* carrier = dynamic_cast<PickupCarrier*>(pawn);
262                if(carrier == NULL)
263                {
264                    COUT(1) << "This is bad. Pawn isn't PickupCarrier." << std::endl;
265                    return;
266                }
267               
268                if(pickup->pickup(carrier))
269                {
270                    COUT(3) << "Pickup got picked up." << std::endl;
271
272                    this->decrementSpawnsRemaining();
273                }
274                else
275                {
276                    pickup->destroy();
277                }
278            }
279        }
280    }
281   
282    /**
283    @brief
284        Decrements the number of remaining spawns.
285        Sets the PickupSpawner to inactive for the duration of the respawnTime.
286        Destroys the PickupSpawner if the number of remaining spawns has reached zero.
287       
288    */
289    void PickupSpawner::decrementSpawnsRemaining(void)
290    {
291        if(this->spawnsRemaining_ != INF)
292        {
293            this->spawnsRemaining_--;
294        }
295        if(this->spawnsRemaining_ != 0 && this->respawnTime_ > 0)
296        {
297            //TODO: Nicer? Does this even work?
298            this->respawnTimer_.setTimer(this->respawnTime_, false, createExecutor(createFunctor(&PickupSpawner::respawnTimerCallback, this)));
299
300            this->setActive(false);
301            this->fireEvent();
302        }
303        else
304        {
305            COUT(3) << "PickupSpawner empty, selfdistruct initialized." << std::endl;
306            this->setActive(false);
307            this->destroy(); //TODO: Implement destroy().
308        }
309    }
310
311    /**
312    @brief
313        Creates a new Pickupable.
314    @return
315        The Pickupable created.
316    */   
317    Pickupable* PickupSpawner::getPickup(void)
318    {
319        if(this->spawnsRemaining_ == 0)
320        {
321            COUT(1) << "Massive Error: PickupSpawner still alive until having spawned last item." << std::endl;
322            return NULL;
323        }
324       
325        Pickupable* pickup = this->pickup_->clone();
326        return pickup;
327    }
328
329    /**
330    @brief
331        Invoked by the timer, re-activates the PickupSpawner.
332    */
333    void PickupSpawner::respawnTimerCallback()
334    {
335        COUT(3) << "PickupSpawner reactivated." << std::endl;
336
337        this->setActive(true);
338    }
339}
Note: See TracBrowser for help on using the repository browser.