Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

Some documenting done. Added files, that I had forgotten to add. Cleaned the old pickups out.

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