Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/orxonox/worldentities/pawns/ModularSpaceShip.cc @ 11071

Last change on this file since 11071 was 11071, checked in by landauf, 8 years ago

merged branch cpp11_v3 back to trunk

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