Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/modularships/src/orxonox/worldentities/pawns/ModularSpaceShip.cc @ 10053

Last change on this file since 10053 was 10053, checked in by noep, 10 years ago

Fixed yet another segfault (which we hadn't seen yet).
Cleared emptyLevel, created two testlevels (testing with boxes)

File size: 12.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
40#include "items/ShipPart.h"
41#include "worldentities/StaticEntity.h"
42#include "collisionshapes/WorldEntityCollisionShape.h"
43#include <BulletCollision/CollisionShapes/btCollisionShape.h>
44#include <BulletCollision/CollisionShapes/btCompoundShape.h>
45
46
47
48namespace orxonox
49{
50    RegisterClass(ModularSpaceShip);
51
52    ModularSpaceShip::ModularSpaceShip(Context* context) : SpaceShip(context)
53    {
54        RegisterObject(ModularSpaceShip);
55
56        this->registerVariables();
57
58    }
59
60    ModularSpaceShip::~ModularSpaceShip()
61    {
62        if (this->isInitialized())
63        {
64
65        }
66    }
67
68    void ModularSpaceShip::XMLPort(Element& xmlelement, XMLPort::Mode mode)
69    {
70        SUPER(ModularSpaceShip, XMLPort, xmlelement, mode);
71        XMLPortObject(ModularSpaceShip, ShipPart, "parts", addShipPart, getShipPart, xmlelement, mode);
72    }
73
74    void ModularSpaceShip::registerVariables()
75    {
76        return;
77    }
78
79    void ModularSpaceShip::updatePartAssignment()
80    {
81        // iterate through all attached objects
82        for (unsigned int i=0; i < (unsigned int)(this->getNumAttachedObj()); i++)
83        {
84            if (this->getAttachedObject(i) == NULL)
85            {
86                break;
87            }
88            // iterate through all attached parts
89            for(unsigned int j = 0; j < this->partList_.size(); j++)
90            {
91                // if the name of the part matches the name of the object, add the object to that parts entitylist (unless it was already done).
92                if((this->partList_[j]->getName() == this->getAttachedObject(i)->getName()) && !this->partList_[j]->hasEntity(orxonox_cast<StaticEntity*>(this->getAttachedObject(i))))
93                {
94                    // The Entity is added to the part's entityList_
95                    this->partList_[j]->addEntity(orxonox_cast<StaticEntity*>(this->getAttachedObject(i)));
96                    // An entry in the partMap_ is created, assigning the part to the entity.
97                    this->addPartEntityAssignment((StaticEntity*)(this->getAttachedObject(i)), this->partList_[j]);
98                    orxout() << "A matching part-entity-pair with name " << this->partList_[j]->getName() << " was found!" << endl;
99                    this->partList_[j]->printEntities(); // FIXME: (noep) remove debug
100                }
101            }
102        }
103
104        orxout() << "List of all assignments:" << endl;
105        for (std::map<StaticEntity*, ShipPart*>::const_iterator it = this->partMap_.begin(); it != this->partMap_.end(); ++it)
106                {
107                    orxout() << "Entity: " << it->first << "   Part: " << it->second << endl;
108                }
109    }
110
111    void ModularSpaceShip::attach(WorldEntity* object)
112    {
113        SpaceShip::attach(object);
114        this->updatePartAssignment();
115    }
116
117    void ModularSpaceShip::addPartEntityAssignment(StaticEntity* entity, ShipPart* part)
118    {
119        if (!entity || !part)
120            return;
121
122        if (this->partMap_.find(entity) != this->partMap_.end())
123                {
124                    orxout(internal_warning) << "Assigning an Entity to multiple parts is not yet supported." << endl;
125                    return;
126                }
127
128        this->partMap_[entity] = part;
129
130        //This adds a list of SmartPointers for all StaticEntities which have a ShipPart, preventing them from getting deleted. Hopefully.
131        SmartPtr<StaticEntity> newSmartPtr = entity;
132        SmartPtr<StaticEntity>* one = &newSmartPtr;
133        this->entityPtrList_.push_back(one);
134
135        //this->createCSPtrList(this->getWorldEntityCollisionShape());
136
137        orxout() << "New entity-part assignment created!" << endl;
138    }
139
140    // This should add smartPointers to all (Orxonox)Collisionshapes of this SpaceShip, preventing them fromg etting deleted. Might not work due to weird acting getAttachedShape
141    void ModularSpaceShip::createCSPtrList(CompoundCollisionShape* cs) // FIXME: (noep) remove debug
142    {
143        for (int i=0; i < cs->getNumChildShapes(); i++)
144        {
145
146            if (!orxonox_cast<CompoundCollisionShape*>(cs->getAttachedShape(i)))
147            {
148                SmartPtr<CollisionShape> newSmartPtr = cs->getAttachedShape(i);
149                SmartPtr<CollisionShape>* one = &newSmartPtr;
150                this->csPtrList_.push_back(one);
151            }
152
153            if (orxonox_cast<CompoundCollisionShape*>(cs->getAttachedShape(i)))
154                createCSPtrList((CompoundCollisionShape*)(cs->getAttachedShape(i)));
155
156        }
157    }
158
159    /**
160    @brief
161        Get the ShipPart an attached entity belongs to.
162    @param entity
163        The entity to be searched.
164    @return
165        Returns a pointer to the ShipPart the entity belongs to.
166    */
167    ShipPart* ModularSpaceShip::getPartOfEntity(StaticEntity* entity) const
168    {
169        for (std::map<StaticEntity*, ShipPart*>::const_iterator it = this->partMap_.begin(); it != this->partMap_.end(); ++it)
170        {
171            if (it->first == entity)
172                return it->second;
173        }
174        return NULL;
175    }
176
177    //FIXME: (noep) finish
178    // void ModularSpaceShip::attach
179
180    void ModularSpaceShip::damage(float damage, float healthdamage, float shielddamage, Pawn* originator, const btCollisionShape* cs)
181    {
182        /*orxout() << "Mdamage(): Collision detected on " << this->getRadarName() << ", btCS*: " << cs << endl;
183        orxout() << "UserPtr of said collisionShape: " << cs->getUserPointer() << endl;
184
185
186            // Print all attached objects & parts
187        /*
188        orxout() << "  " << this->getName() << " has the following Objects attached:" << endl;
189
190        for (int i=0; i<50; i++)
191        {
192            if (this->getAttachedObject(i)==NULL)
193                break;
194            orxout() << " " << i << ": " << this->getAttachedObject(i) << " (" << this->getAttachedObject(i)->getName() << ")";
195            orxout() << endl;
196        }
197
198        orxout() << "  Attached ShipParts:" << endl;
199        for(unsigned int i=0; i < this->partList_.size(); i++)
200        {
201            orxout() << "  " << i << ": " << this->partList_[i] << " (" << this->partList_[i]->getName() << ")" << endl;
202        }*/
203
204
205        //int collisionShapeIndex = this->isMyCollisionShape(cs);
206        //orxout() << collisionShapeIndex << endl;
207
208        //orxout() << "ShipPart of Entity " << cs->getUserPointer() << ": " << this->getPartOfEntity((StaticEntity*)(cs->getUserPointer())) << endl;
209
210        if (this->getPartOfEntity((StaticEntity*)(cs->getUserPointer())) != NULL)
211            this->getPartOfEntity((StaticEntity*)(cs->getUserPointer()))->handleHit(damage, healthdamage, shielddamage, originator);
212        else
213            SpaceShip::damage(damage, healthdamage, shielddamage, originator, cs);
214
215        /*
216        // Applies multiplier given by the DamageBoost Pickup.
217        if (originator)
218            damage *= originator->getDamageMultiplier();
219
220        if (this->getGametype() && this->getGametype()->allowPawnDamage(this, originator))
221        {
222            if (shielddamage >= this->getShieldHealth())
223            {
224                this->setShieldHealth(0);
225                this->setHealth(this->health_ - (healthdamage + damage));
226            }
227            else
228            {
229                this->setShieldHealth(this->shieldHealth_ - shielddamage);
230
231                // remove remaining shieldAbsorpton-Part of damage from shield
232                shielddamage = damage * this->shieldAbsorption_;
233                shielddamage = std::min(this->getShieldHealth(),shielddamage);
234                this->setShieldHealth(this->shieldHealth_ - shielddamage);
235
236                // set remaining damage to health
237                this->setHealth(this->health_ - (damage - shielddamage) - healthdamage);
238            }
239
240            this->lastHitOriginator_ = originator;
241        }*/
242    }
243
244    /**
245    @brief
246        Add a ShipPart to the SpaceShip.
247    @param engine
248        A pointer to the ShipPart to be added.
249    */
250    void ModularSpaceShip::addShipPart(ShipPart* part)
251    {
252        OrxAssert(part != NULL, "The ShipPart cannot be NULL.");
253        this->partList_.push_back(part);
254        part->setParent(this);
255        this->updatePartAssignment();
256    }
257
258    /**
259    @brief
260        Get the i-th ShipPart of the SpaceShip.
261    @return
262        Returns a pointer to the i-the ShipPart. NULL if there is no ShipPart with that index.
263    */
264    ShipPart* ModularSpaceShip::getShipPart(unsigned int index)
265    {
266        if(this->partList_.size() <= index)
267            return NULL;
268        else
269            return this->partList_[index];
270    }
271
272    /**
273    @brief
274        Check whether the SpaceShip has a particular Engine.
275    @param engine
276        A pointer to the Engine to be checked.
277    */
278    bool ModularSpaceShip::hasShipPart(ShipPart* part) const
279    {
280        for(unsigned int i = 0; i < this->partList_.size(); i++)
281        {
282            if(this->partList_[i] == part)
283                return true;
284        }
285        return false;
286    }
287
288    void ModularSpaceShip::removeShipPart(ShipPart* part)
289    {
290        // Remove the part from the partList_
291        std::vector<ShipPart*>::iterator it = this->partList_.begin();
292        for(unsigned int i = 0; i < this->partList_.size(); i++)
293        {
294            if(this->partList_[i] == part)
295            {
296                this->partList_.erase(it);
297                break;
298            }
299            it++;
300        }
301        // Remove the part-entity assignment and detach the Entity of this ShipPart
302        for (std::map<StaticEntity*, ShipPart*>::iterator itt = this->partMap_.begin(); itt != this->partMap_.end(); )
303        {
304            if (itt->second == part)
305            {
306                this->detach(itt->first);
307                //itt->first->destroy();
308                //itt->first->setActive(false);
309                //itt->first->setVisible(false);
310                //itt->first->setCollisionResponse(false);
311                //itt->first->setCollisionType(None);
312                //itt->first->deactivatePhysics();
313                this->partMap_.erase(itt++);
314            } else {
315                ++itt;
316            }
317        }
318    }
319
320    /**
321    @brief
322        Detaches a child WorldEntity from this instance.
323    */
324    void ModularSpaceShip::detach(WorldEntity* object)
325    {
326        std::set<WorldEntity*>::iterator it = this->children_.find(object);
327        if (it == this->children_.end())
328        {
329            orxout(internal_warning) << "Cannot detach an object that is not a child." << endl;
330            return;
331        }
332
333        // collision shapes
334        orxout() << "MSS: detach()" << endl;
335
336        this->printBtChildShapes((btCompoundShape*)(this->getWorldEntityCollisionShape()->getCollisionShape()), 2, 0);
337        this->detachCollisionShape(object->collisionShape_);  // after succeeding, causes a crash in the collision handling
338        //this->printBtChildShapes((btCompoundShape*)(this->getWorldEntityCollisionShape()->getCollisionShape()), 2, 0);
339
340        // mass
341        if (object->getMass() > 0.0f)
342        {
343            this->childrenMass_ -= object->getMass();
344            recalculateMassProps();
345        }
346
347        this->detachNode(object->node_);
348        this->children_.erase(it);        // this causes a crash when unloading the level. Or not?
349
350        object->notifyDetached();
351        orxout() << "MSS: detach() completed." << endl;
352    }
353}
Note: See TracBrowser for help on using the repository browser.