Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

ShipParts can "die" and detach the corresponding Entity while doing so. Issue: The Entity being detached while a hit on a collisionshape is being handled causes a runtime-error.

File size: 9.8 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 <BulletCollision/CollisionShapes/btCollisionShape.h>
43
44
45
46namespace orxonox
47{
48    RegisterClass(ModularSpaceShip);
49
50    ModularSpaceShip::ModularSpaceShip(Context* context) : SpaceShip(context)
51    {
52        RegisterObject(ModularSpaceShip);
53
54        this->registerVariables();
55
56    }
57
58    ModularSpaceShip::~ModularSpaceShip()
59    {
60        if (this->isInitialized())
61        {
62
63        }
64    }
65
66    void ModularSpaceShip::XMLPort(Element& xmlelement, XMLPort::Mode mode)
67    {
68        SUPER(ModularSpaceShip, XMLPort, xmlelement, mode);
69        XMLPortObject(ModularSpaceShip, ShipPart, "parts", addShipPart, getShipPart, xmlelement, mode);
70    }
71
72    void ModularSpaceShip::registerVariables()
73    {
74        return;
75    }
76
77    void ModularSpaceShip::updatePartAssignment()
78    {
79        // iterate through all attached objects
80        for (unsigned int i=0; i < 100; i++)
81        {
82            if (this->getAttachedObject(i) == NULL)
83                break;
84            // iterate through all attached parts
85            for(unsigned int j = 0; j < this->partList_.size(); j++)
86            {
87                // if the name of the part matches the name of the object, add the object to that parts entitylist (unless it was already done).
88                if((this->partList_[j]->getName() == this->getAttachedObject(i)->getName()) && !this->partList_[j]->hasEntity(orxonox_cast<StaticEntity*>(this->getAttachedObject(i))))
89                {
90                    // The Entity is added to the part's entityList_
91                    this->partList_[j]->addEntity(orxonox_cast<StaticEntity*>(this->getAttachedObject(i)));
92                    // An entry in the partMap_ is created, assigning the part to the entity.
93                    this->addPartEntityAssignment((StaticEntity*)(this->getAttachedObject(i)), this->partList_[j]);
94                    orxout() << "A matching part-entity-pair with name " << this->partList_[j]->getName() << " was found!" << endl;
95                    this->partList_[j]->printEntities(); // FIXME: (noep) remove debug
96                }
97            }
98        }
99
100        orxout() << "List of all assignments:" << endl;
101        for (std::map<StaticEntity*, ShipPart*>::const_iterator it = this->partMap_.begin(); it != this->partMap_.end(); ++it)
102                {
103                    orxout() << "Entity: " << it->first << "   Part: " << it->second << endl;
104                }
105    }
106
107    void ModularSpaceShip::attach(WorldEntity* object)
108    {
109        SpaceShip::attach(object);
110        this->updatePartAssignment();
111    }
112
113    void ModularSpaceShip::addPartEntityAssignment(StaticEntity* entity, ShipPart* part)
114    {
115        if (!entity || !part)
116            return;
117
118        if (this->partMap_.find(entity) != this->partMap_.end())
119                {
120                    orxout(internal_warning) << "Assigning an Entity to multiple parts is not yet supported." << endl;
121                    return;
122                }
123
124        this->partMap_[entity] = part;
125        orxout() << "New entity-part assignment created!" << endl;
126    }
127
128    /**
129    @brief
130        Get the ShipPart an attached entity belongs to.
131    @param entity
132        The entity to be searched.
133    @return
134        Returns a pointer to the ShipPart the entity belongs to.
135    */
136    ShipPart* ModularSpaceShip::getPartOfEntity(StaticEntity* entity) const
137    {
138        for (std::map<StaticEntity*, ShipPart*>::const_iterator it = this->partMap_.begin(); it != this->partMap_.end(); ++it)
139        {
140            if (it->first == entity)
141                return it->second;
142        }
143        return NULL;
144    }
145
146    //FIXME: (noep) finish
147    // void ModularSpaceShip::attach
148
149    void ModularSpaceShip::damage(float damage, float healthdamage, float shielddamage, Pawn* originator, const btCollisionShape* cs)
150    {
151        orxout() << "Mdamage(): Collision detected on " << this->getRadarName() << ", btCS*: " << cs << endl;
152        orxout() << "UserPtr of said collisionShape: " << cs->getUserPointer() << endl;
153
154
155            // Print all attached objects & parts
156        /*
157        orxout() << "  " << this->getName() << " has the following Objects attached:" << endl;
158
159        for (int i=0; i<50; i++)
160        {
161            if (this->getAttachedObject(i)==NULL)
162                break;
163            orxout() << " " << i << ": " << this->getAttachedObject(i) << " (" << this->getAttachedObject(i)->getName() << ")";
164            orxout() << endl;
165        }
166
167        orxout() << "  Attached ShipParts:" << endl;
168        for(unsigned int i=0; i < this->partList_.size(); i++)
169        {
170            orxout() << "  " << i << ": " << this->partList_[i] << " (" << this->partList_[i]->getName() << ")" << endl;
171        }*/
172
173
174        //int collisionShapeIndex = this->isMyCollisionShape(cs);
175        //orxout() << collisionShapeIndex << endl;
176
177        //orxout() << "ShipPart of Entity " << cs->getUserPointer() << ": " << this->getPartOfEntity((StaticEntity*)(cs->getUserPointer())) << endl;
178
179        orxout() << "CP_start" << endl;
180
181        if (this->getPartOfEntity((StaticEntity*)(cs->getUserPointer())) != NULL)
182            this->getPartOfEntity((StaticEntity*)(cs->getUserPointer()))->handleHit(damage, healthdamage, shielddamage, originator);
183        else
184            SpaceShip::damage(damage, healthdamage, shielddamage, originator, cs);
185
186        orxout() << "CP_end" << endl;
187
188        /*
189        // Applies multiplier given by the DamageBoost Pickup.
190        if (originator)
191            damage *= originator->getDamageMultiplier();
192
193        if (this->getGametype() && this->getGametype()->allowPawnDamage(this, originator))
194        {
195            if (shielddamage >= this->getShieldHealth())
196            {
197                this->setShieldHealth(0);
198                this->setHealth(this->health_ - (healthdamage + damage));
199            }
200            else
201            {
202                this->setShieldHealth(this->shieldHealth_ - shielddamage);
203
204                // remove remaining shieldAbsorpton-Part of damage from shield
205                shielddamage = damage * this->shieldAbsorption_;
206                shielddamage = std::min(this->getShieldHealth(),shielddamage);
207                this->setShieldHealth(this->shieldHealth_ - shielddamage);
208
209                // set remaining damage to health
210                this->setHealth(this->health_ - (damage - shielddamage) - healthdamage);
211            }
212
213            this->lastHitOriginator_ = originator;
214        }*/
215    }
216
217    /**
218    @brief
219        Add a ShipPart to the SpaceShip.
220    @param engine
221        A pointer to the ShipPart to be added.
222    */
223    void ModularSpaceShip::addShipPart(ShipPart* part)
224    {
225        OrxAssert(part != NULL, "The ShipPart cannot be NULL.");
226        this->partList_.push_back(part);
227        part->setParent(this);
228        //part->addToSpaceShip(this); //FIXME: (noep) add
229        this->updatePartAssignment();
230    }
231
232    /**
233    @brief
234        Get the i-th ShipPart of the SpaceShip.
235    @return
236        Returns a pointer to the i-the ShipPart. NULL if there is no ShipPart with that index.
237    */
238    ShipPart* ModularSpaceShip::getShipPart(unsigned int index)
239    {
240        if(this->partList_.size() >= index)
241            return NULL;
242        else
243            return this->partList_[index];
244    }
245
246    /**
247    @brief
248        Check whether the SpaceShip has a particular Engine.
249    @param engine
250        A pointer to the Engine to be checked.
251    */
252    bool ModularSpaceShip::hasShipPart(ShipPart* part) const
253    {
254        for(unsigned int i = 0; i < this->partList_.size(); i++)
255        {
256            if(this->partList_[i] == part)
257                return true;
258        }
259        return false;
260    }
261
262    void ModularSpaceShip::removeShipPart(ShipPart* part)
263    {
264        // Remove the part from the partList_
265        std::vector<ShipPart*>::iterator it = this->partList_.begin();
266        for(unsigned int i = 0; i < this->partList_.size(); i++)
267        {
268            if(this->partList_[i] == part)
269                this->partList_.erase(it);
270            it++;
271        }
272        // Remove the part-entity assignment and detach the Entity of this ShipPart
273        for (std::map<StaticEntity*, ShipPart*>::iterator itt = this->partMap_.begin(); itt != this->partMap_.end(); ++itt)
274        {
275            if (itt->second == part)
276            {
277                this->detach(itt->first);
278                this->partMap_.erase(itt);
279            }
280        }
281    }
282
283}
Note: See TracBrowser for help on using the repository browser.