Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/tutorial5/src/orxonox/worldentities/pawns/ModularSpaceShip.cc @ 10282

Last change on this file since 10282 was 10270, checked in by landauf, 10 years ago

fixed crash: cs can be null (e.g. when using the 'suicide' command)

  • Property svn:eol-style set to native
File size: 9.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 *      Fabian 'x3n' Landau
24 *   Co-authors:
25 *      Noe Pedrazzini
26 *
27 */
28
29#include "ModularSpaceShip.h"
30
31#include <BulletDynamics/Dynamics/btRigidBody.h>
32
33#include "core/CoreIncludes.h"
34#include "core/config/ConfigValueIncludes.h"
35#include "core/Template.h"
36#include "core/XMLPort.h"
37#include "util/Math.h"
38#include "gametypes/Gametype.h"
39#include "core/command/ConsoleCommand.h"
40
41#include "items/ShipPart.h"
42#include "items/Engine.h"
43#include "worldentities/StaticEntity.h"
44#include <BulletCollision/CollisionShapes/btCollisionShape.h>
45#include <BulletCollision/CollisionShapes/btCompoundShape.h>
46
47
48
49namespace orxonox
50{
51    SetConsoleCommand("ModularSpaceShip", "killshippart", &ModularSpaceShip::killShipPartStatic);
52
53    RegisterClass(ModularSpaceShip);
54
55    std::map<StaticEntity*, ShipPart*>* ModularSpaceShip::partMap_s = 0;
56
57    ModularSpaceShip::ModularSpaceShip(Context* context) : SpaceShip(context)
58    {
59        RegisterObject(ModularSpaceShip);
60
61        this->registerVariables();
62
63        ModularSpaceShip::partMap_s = &(this->partMap_);
64
65    }
66
67    ModularSpaceShip::~ModularSpaceShip()
68    {
69        if (this->isInitialized())
70        {
71
72        }
73    }
74
75    void ModularSpaceShip::XMLPort(Element& xmlelement, XMLPort::Mode mode)
76    {
77        SUPER(ModularSpaceShip, XMLPort, xmlelement, mode);
78        XMLPortObject(ModularSpaceShip, ShipPart, "parts", addShipPart, getShipPart, xmlelement, mode);
79    }
80
81    void ModularSpaceShip::registerVariables()
82    {
83        return;
84    }
85
86    /**
87    @brief
88        Searches for ShipParts matching to StaticEntities.
89    */
90    void ModularSpaceShip::updatePartAssignment()
91    {
92        // iterate through all attached objects
93        for (unsigned int i=0; i < this->getAttachedObjects().size(); i++)
94        {
95            if (this->getAttachedObject(i) == NULL)
96            {
97                break;
98            }
99            // iterate through all attached parts
100            for(unsigned int j = 0; j < this->partList_.size(); j++)
101            {
102                // if the name of the part matches the name of the object, add the object to that parts entitylist (unless it was already done).
103                if((this->partList_[j]->getName() == this->getAttachedObject(i)->getName()) && !this->partList_[j]->hasEntity(orxonox_cast<StaticEntity*>(this->getAttachedObject(i))))
104                {
105                    // The Entity is added to the part's entityList_
106                    this->partList_[j]->addEntity(orxonox_cast<StaticEntity*>(this->getAttachedObject(i)));
107                    // An entry in the partMap_ is created, assigning the part to the entity.
108                    this->addPartEntityAssignment((StaticEntity*)(this->getAttachedObject(i)), this->partList_[j]);
109                }
110            }
111        }
112    }
113
114    /**
115    @brief
116        Creates a new assignment for the given StaticEntity and ShipPart in the partMap_
117    @param entity
118        A pointer to the StaticEntity
119    @param part
120        A pointer to the ShipPart.
121    */
122    void ModularSpaceShip::addPartEntityAssignment(StaticEntity* entity, ShipPart* part)
123    {
124        if (!entity || !part)
125            return;
126
127        if (this->partMap_.find(entity) != this->partMap_.end())
128                {
129                    orxout(internal_warning) << "Assigning an Entity to multiple parts is not yet supported." << endl;
130                    return;
131                }
132
133        this->partMap_[entity] = part;
134    }
135
136
137    /**
138    @brief
139        Get the ShipPart an attached entity belongs to.
140    @param entity
141        The entity to be searched.
142    @return
143        Returns a pointer to the ShipPart the entity belongs to.
144    */
145    ShipPart* ModularSpaceShip::getPartOfEntity(StaticEntity* entity) const
146    {
147        for (std::map<StaticEntity*, ShipPart*>::const_iterator it = this->partMap_.begin(); it != this->partMap_.end(); ++it)
148        {
149            if (it->first == entity)
150                return it->second;
151        }
152        return NULL;
153    }
154
155    /**
156    @brief
157        If the damage occurred on an attached StaticEntity, the damage is given to the corresponding ShipPart to handle.
158    */
159    void ModularSpaceShip::damage(float damage, float healthdamage, float shielddamage, Pawn* originator, const btCollisionShape* cs)
160    {
161        if (cs != NULL && this->getPartOfEntity((StaticEntity*)(cs->getUserPointer())) != NULL)
162            this->getPartOfEntity((StaticEntity*)(cs->getUserPointer()))->handleHit(damage, healthdamage, shielddamage, originator);
163        else
164            SpaceShip::damage(damage, healthdamage, shielddamage, originator, cs);
165    }
166
167    /**
168    @brief
169        STATIC: Needed for consolecommand. Kills the ShipPart with the given name. Used from the console-command "ModularSpaceShip killshippart [string]".
170    @param name
171        The name of the part to be killed.
172    */
173    void ModularSpaceShip::killShipPartStatic(std::string name)
174    {
175        for (std::map<StaticEntity*, ShipPart*>::const_iterator it = ModularSpaceShip::partMap_s->begin(); it != ModularSpaceShip::partMap_s->end(); ++it)
176        {
177            if (it->second->getName() == name)
178            {
179                it->second->setAlive(false);
180                return;
181            }
182        }
183        orxout(internal_warning) << "Could not apply damage to ShipPart \"" << name << "\". Part not found." << endl;
184    }
185
186    /**
187    @brief
188        Kills the ShipPart with the given name. Used from the console-command "ModularSpaceShip killshippart [string]".
189    @param name
190        The name of the part to be killed.
191    */
192    void ModularSpaceShip::killShipPart(std::string name)
193    {
194        for (std::map<StaticEntity*, ShipPart*>::const_iterator it = ModularSpaceShip::partMap_.begin(); it != ModularSpaceShip::partMap_.end(); ++it)
195        {
196            if (it->second->getName() == name)
197            {
198                it->second->setAlive(false);
199                return;
200            }
201        }
202        orxout(internal_warning) << "Could not apply damage to ShipPart \"" << name << "\". Part not found." << endl;
203    }
204
205    /**
206    @brief
207        Add a ShipPart to the SpaceShip.
208    @param engine
209        A pointer to the ShipPart to be added.
210    */
211    void ModularSpaceShip::addShipPart(ShipPart* part)
212    {
213        OrxAssert(part != NULL, "The ShipPart cannot be NULL.");
214        this->partList_.push_back(part);
215        part->setParent(this);
216        this->updatePartAssignment();
217    }
218
219    /**
220    @brief
221        Get the i-th ShipPart of the SpaceShip.
222    @return
223        Returns a pointer to the i-the ShipPart. NULL if there is no ShipPart with that index.
224    */
225    ShipPart* ModularSpaceShip::getShipPart(unsigned int index)
226    {
227        if(this->partList_.size() <= index)
228            return NULL;
229        else
230            return this->partList_[index];
231    }
232
233    /**
234    @brief
235        Looks for an attached ShipPart with a certain name.
236    @param name
237        The name of the ShipPart to be returned.
238    @return
239        Pointer to the ShipPart with the given name, or NULL if not found.
240    */
241    ShipPart* ModularSpaceShip::getShipPartByName(std::string name)
242    {
243        for(std::vector<ShipPart*>::iterator it = this->partList_.begin(); it != this->partList_.end(); ++it)
244        {
245            if(orxonox_cast<ShipPart*>(*it)->getName() == name)
246            {
247                return orxonox_cast<ShipPart*>(*it);
248            }
249        }
250        orxout(internal_warning) << "Couldn't find ShipPart with name \"" << name << "\"." << endl;
251        return NULL;
252    }
253
254    /**
255    @brief
256        Check whether the SpaceShip has a particular Engine.
257    @param engine
258        A pointer to the Engine to be checked.
259    */
260    bool ModularSpaceShip::hasShipPart(ShipPart* part) const
261    {
262        for(unsigned int i = 0; i < this->partList_.size(); i++)
263        {
264            if(this->partList_[i] == part)
265                return true;
266        }
267        return false;
268    }
269
270
271    /**
272    @brief
273        Removes a ShipPart from the SpaceShip, destroying the corresponding StaticEntity
274    @param part
275        The ShipPart to be removed.
276    */
277    void ModularSpaceShip::removeShipPart(ShipPart* part)
278    {
279        // Remove the part from the partList_
280        std::vector<ShipPart*>::iterator it = this->partList_.begin();
281        for(unsigned int i = 0; i < this->partList_.size(); i++)
282        {
283            if(this->partList_[i] == part)
284            {
285                this->partList_.erase(it);
286                break;
287            }
288            it++;
289        }
290        // Remove the part-entity assignment and detach the Entity of this ShipPart
291        for (std::map<StaticEntity*, ShipPart*>::iterator itt = this->partMap_.begin(); itt != this->partMap_.end(); )
292        {
293            if (itt->second == part)
294            {
295                this->detach(itt->first);
296                itt->first->destroy();
297                //itt->first->setActive(false);
298                //itt->first->setVisible(false);
299                //itt->first->setCollisionResponse(false);
300                //itt->first->setCollisionType(None);
301                //itt->first->deactivatePhysics();
302                this->partMap_.erase(itt++);
303            } else {
304                ++itt;
305            }
306        }
307    }
308}
Note: See TracBrowser for help on using the repository browser.