Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

Merged presentation2 branch into pickup2 branch.

File size: 8.4 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 *      ...
26 *
27 */
28
29/**
30    @file
31    @brief Implementation of PickupSpawner.
32*/
33
34#include "PickupSpawner.h"
35
36#include "BaseItem.h"
37
38#include "core/CoreIncludes.h"
39#include "core/GUIManager.h"     // HACK; see below
40#include "core/Template.h"
41#include "core/XMLPort.h"
42#include "worldentities/pawns/Pawn.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. Registers the PickupSpawner.
58    @param creator
59        Pointer to the object which created this item.
60    */
61    PickupSpawner::PickupSpawner(BaseObject* creator) : StaticEntity(creator)
62    {
63        this->initialize();
64    }
65
66    PickupSpawner::PickupSpawner(BaseObject* creator, BaseItem* item, float triggerDistance, float respawnTime, int maxSpawnedItems) : StaticEntity(creator)
67    {
68        this->initialize();
69 
70        //TODO: Does this actually work?
71        this->itemTemplateName_ = item->getIdentifier()->getName();
72        this->itemTemplate_ = Template::getTemplate(this->itemTemplateName_);
73
74        this->triggerDistance_ = triggerDistance;
75        this->respawnTime_ = respawnTime;
76        this->setMaxSpawnedItems(maxSpawnedItems);
77    }
78
79    void PickupSpawner::initialize(void)
80    {
81        RegisterObject(PickupSpawner);
82
83        this->itemTemplate_ = NULL;
84        this->triggerDistance_ = 20;
85        this->respawnTime_ = 0.0f;
86        this->tickSum_ = 0.0f;
87        this->maxSpawnedItems_ = INF;
88        this->spawnsRemaining_ = INF;
89    }
90
91    /**
92    @brief
93        Destructor.
94    */
95    PickupSpawner::~PickupSpawner()
96    {
97       
98    }
99
100    /**
101    @brief
102        Method for creating a PickupSpawner through XML.
103    @param xmlelement
104        XML element which contains the PickupSpawner.
105    @param mode
106        XMLPort mode.
107    */
108    void PickupSpawner::XMLPort(Element& xmlelement, XMLPort::Mode mode)
109    {
110        SUPER(PickupSpawner, XMLPort, xmlelement, mode);
111
112        XMLPortParam(PickupSpawner, "item", setItemTemplateName, getItemTemplateName, xmlelement, mode);
113        XMLPortParam(PickupSpawner, "triggerDistance", setTriggerDistance, getTriggerDistance, xmlelement, mode);
114        XMLPortParam(PickupSpawner, "respawnTime", setRespawnTime, getRespawnTime, xmlelement, mode);
115        XMLPortParam(PickupSpawner, "maxSpawnedItems", setMaxSpawnedItems, getMaxSpawnedItems, xmlelement, mode);
116
117        //TODO: Kill hack.
118        // HACKs
119        // Load the GUI image as soon as the PickupSpawner gets loaded
120        //  = less delays while running
121        BaseObject* newObject = this->itemTemplate_->getBaseclassIdentifier()->fabricate(this);
122        BaseItem* asItem = orxonox_cast<BaseItem*>(newObject);
123        if (asItem)
124        {
125            asItem->addTemplate(this->itemTemplate_);
126            PickupInventory::getImageForItem(asItem);
127            newObject->destroy();
128        }
129
130        //  & load the GUI itself too, along with some empty windows
131        //   = even less delays
132        GUIManager::showGUI("PickupInventory");
133        GUIManager::hideGUI("PickupInventory");
134        PickupInventory::getSingleton();
135    }
136
137    /**
138    @brief
139        Invoked when the activity has changed. Sets visibility of attached objects.
140    */
141    void PickupSpawner::changedActivity()
142    {
143        SUPER(PickupSpawner, changedActivity);
144
145        for (std::set<WorldEntity*>::const_iterator it = this->getAttachedObjects().begin(); it != this->getAttachedObjects().end(); it++)
146            (*it)->setVisible(this->isActive());
147    }
148
149    /**
150    @brief
151        Set the template name of the item to spawn, also loads the template.
152    @param name
153        Name of the new template.
154    */
155    void PickupSpawner::setItemTemplateName(const std::string& name)
156    {
157        this->itemTemplateName_ = name;
158        this->itemTemplate_ = Template::getTemplate(name);
159    }
160
161    void PickupSpawner::setMaxSpawnedItems(int items)
162    {
163        this->maxSpawnedItems_ = items;
164        this->spawnsRemaining_ = items;
165    }
166
167    /**
168    @brief
169        Tick, checks if any Pawn is close enough to trigger.
170    @param dt
171        Time since last tick.
172    */
173    //TODO: Replace this with a real DistanceTrigger.
174    void PickupSpawner::tick(float dt)
175    {
176        if (this->isActive())
177        {
178            //! Triggers as soon as a Pawn is in the specified distance.
179            for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it != ObjectList<Pawn>::end(); ++it)
180            {
181                Vector3 distance = it->getWorldPosition() - this->getWorldPosition();
182                if (distance.length() < this->triggerDistance_)
183                    this->trigger(*it);
184            }
185
186            //! Animation.
187            this->yaw(Radian(rotationSpeed_s*dt));
188            this->tickSum_ += bounceSpeed_s*dt;
189            this->translate(Vector3(0,bounceDistance_s*dt*sin(this->tickSum_),0));
190            if (this->tickSum_ > 2*Ogre::Math::PI)
191                this->tickSum_ -= 2*Ogre::Math::PI;
192        }
193    }
194
195    /**
196    @brief
197        Trigger the PickupSpawner.
198
199        Adds the pickup to the Pawn that triggered,
200        sets the timer to re-activate and deactives the PickupSpawner.
201
202    @param pawn
203        Pawn which triggered the PickupSpawner.
204    */
205    void PickupSpawner::trigger(Pawn* pawn)
206    {
207        if (this->isActive() && this->itemTemplate_ && this->itemTemplate_->getBaseclassIdentifier()) //!< Checks whether PickupItem is active, amongst other things.
208        {
209            BaseItem* item = this->getItem();
210            if (item != NULL) //!< If the conversion was successful.
211            {
212                item->setPickupIdentifier(this->itemTemplateName_); //TODO: Needed?
213                item->addTemplate(this->itemTemplate_); //TODO: Does what?
214
215                if(item->pickedUp(pawn))
216                {
217                    COUT(3) << this->itemTemplateName_ << " got picked up." << std::endl;
218
219
220                    if(this->spawnsRemaining_ != INF)
221                    {
222                        this->spawnsRemaining_--;
223                    }
224
225                    if (this->spawnsRemaining_ != 0 && this->respawnTime_ > 0.0f)
226                    {
227                        this->respawnTimer_.setTimer(this->respawnTime_, false, createExecutor(createFunctor(&PickupSpawner::respawnTimerCallback, this)));
228
229                        this->setActive(false);
230                        this->fireEvent();
231                    }
232                }
233                else
234                {
235                    item->destroy();
236                }
237            }
238        }
239
240        if(this->spawnsRemaining_ == 0)
241        {
242            COUT(3) << "PickupSpawner empty, selfdistruct initialized." << std::endl;
243            this->setActive(false);
244            this->destroy();
245        }
246    }
247
248    /**
249    @brief
250        Creates a BaseItem of the type specified by the PickupSpawner.
251    @return
252        The BaseItem created.
253    */   
254    BaseItem* PickupSpawner::getItem(void)
255    {
256        BaseObject* newItem = this->itemTemplate_->getBaseclassIdentifier()->fabricate(this); //!< Creates new object of specified item type.
257        return orxonox_cast<BaseItem*>(newItem);
258    }
259
260    /**
261    @brief
262        Invoked by the timer, re-activates the PickupSpawner.
263    */
264    void PickupSpawner::respawnTimerCallback()
265    {
266        COUT(3) << "PickupSpawner reactivated." << std::endl;
267
268        this->setActive(true);
269    }
270}
Note: See TracBrowser for help on using the repository browser.