Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/pickup2/src/modules/pickup/PickupSpawner.cc @ 6551

Last change on this file since 6551 was 6405, checked in by dafrick, 15 years ago

Commit changes in pickup before merge.

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