Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

Lots of things done in pickups module. Compiles, but it seems, that I've also introduced an error preventing steering of the spaceship.

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