Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/modularships/src/orxonox/items/ShipPart.cc @ 10068

Last change on this file since 10068 was 10068, checked in by smerkli, 10 years ago

Introduced a shippartmanager to hopefully fix the segfaults

File size: 8.6 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 *      Noe Pedrazzini
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#include "ShipPart.h"
30
31#include <algorithm>
32
33#include "core/CoreIncludes.h"
34#include "core/GameMode.h"
35#include "core/XMLPort.h"
36#include "network/NetworkFunction.h"
37#include "Item.h"
38#include "worldentities/pawns/Pawn.h"
39#include "worldentities/pawns/ModularSpaceShip.h"
40#include "gametypes/Gametype.h"
41#include "worldentities/StaticEntity.h"
42#include "items/PartDestructionEvent.h"
43#include "worldentities/BigExplosion.h"
44#include "chat/ChatManager.h"
45
46
47namespace orxonox
48{
49    RegisterClass(ShipPart);
50
51    ShipPart::ShipPart(Context* context)
52        : Item(context)
53    {
54        RegisterObject(ShipPart);
55        this->setAlive(true);
56        this->setEventExecution(true);
57    }
58
59    ShipPart::~ShipPart()
60    {
61
62    }
63
64    void ShipPart::XMLPort(Element& xmlelement, XMLPort::Mode mode)
65    {
66        SUPER(ShipPart, XMLPort, xmlelement, mode);
67
68        XMLPortParam(ShipPart, "health", setHealth, getHealth, xmlelement, mode).defaultValues(100);
69        XMLPortParam(ShipPart, "maxhealth", setMaxHealth, getMaxHealth, xmlelement, mode).defaultValues(200);
70        XMLPortParam(ShipPart, "initialhealth", setInitialHealth, getInitialHealth, xmlelement, mode).defaultValues(100);
71
72        XMLPortParam(ShipPart, "damageabsorption", setDamageAbsorption, getDamageAbsorption, xmlelement, mode).defaultValues(0.5);
73
74        XMLPortParamTemplate(ShipPart, "explosionposition", setExplosionPosition, getExplosionPosition, xmlelement, mode, Vector3);
75
76        XMLPortObject(ShipPart, PartDestructionEvent, "destructionevents", addDestructionEvent, getDestructionEvent, xmlelement, mode);
77    }
78
79    /**
80    @brief
81        Is called when the ShipPart dies.
82        Executes PartDestructionEvents.
83        Tells the ModularSpaceShip to remove this ShipPart.
84    */
85    void ShipPart::death()
86    {
87        //if (!(this->isAlive()))
88            //return;
89
90        this->explode();
91        this->setAlive(false);
92
93        if(eventExecution_)
94        {
95            // Execute all destruction events
96            for (unsigned int i = 0; i < this->eventList_.size(); i++)
97            {
98                this->getDestructionEvent(i)->execute();
99            }
100        }
101
102        // Remove this ShipPart from the parent.
103        this->parent_->removeShipPart(this);
104    }
105
106    void ShipPart::explode()
107    {
108        BigExplosion* chunk = new BigExplosion(this->getContext());
109        chunk->setPosition(this->parent_->getPosition() + this->parent_->getOrientation() * (this->explosionPosition_));
110        //chunk->setPosition(this->parent_->getPosition() + this->parent_->getOrientation() * Vector3(this->entityList_[0]->getLocalInertia()));
111        chunk->setVelocity(this->parent_->getVelocity());
112
113        // this->explosionSound_->setPosition(this->parent_->getPosition());
114        // this->explosionSound_->play();
115    }
116
117    /**
118    @brief
119        Add a StaticEntity to the ShipPart.
120    @param engine
121        A pointer to the StaticEntity to be added.
122    */
123    void ShipPart::addEntity(StaticEntity* entity)
124    {
125        OrxAssert(entity != NULL, "The Entity cannot be NULL.");
126        this->entityList_.push_back(entity);
127    }
128
129    /**
130    @brief
131        Get the i-th StaticEntity of the ShipPart.
132    @return
133        Returns a pointer to the i-the StaticEntity. NULL if there is no StaticEntity with that index.
134    */
135    StaticEntity* ShipPart::getEntity(unsigned int index)
136    {
137        if(this->entityList_.size() >= index)
138            return NULL;
139        else
140            return this->entityList_[index];
141    }
142
143    /**
144    @brief
145        Check whether the ShipPart has a particular Entity.
146    @param engine
147        A pointer to the Entity to be checked.
148    */
149    bool ShipPart::hasEntity(StaticEntity* entity) const
150    {
151        for(unsigned int i = 0; i < this->entityList_.size(); i++)
152        {
153            if(this->entityList_[i] == entity)
154                return true;
155        }
156        return false;
157    }
158
159    /**
160    @brief
161        Add a PartDestructionEvent to the ShipPart.
162    @param engine
163        A pointer to the PartDestructionEvent to be added.
164    */
165    void ShipPart::addDestructionEvent(PartDestructionEvent* event)
166    {
167        OrxAssert(event != NULL, "The PartDestructionEvent cannot be NULL.");
168        event->setParent(this);
169        this->eventList_.push_back(event);
170    }
171
172    /**
173    @brief
174        Get the i-th PartDestructionEvent of the ShipPart.
175    @return
176        Returns a pointer to the i-the PartDestructionEvent. NULL if there is no PartDestructionEvent with that index.
177    */
178    PartDestructionEvent* ShipPart::getDestructionEvent(unsigned int index)
179    {
180        if(this->eventList_.size() <= index)
181            return NULL;
182        else
183            return this->eventList_[index];
184    }
185
186    void ShipPart::setDamageAbsorption(float value)
187    {
188        this->damageAbsorption_ = value;
189    }
190
191    void ShipPart::setParent(ModularSpaceShip* ship)
192    {
193        this->parent_ = ship;
194    }
195
196    /**
197    @brief
198        Sets the health of the ShipPart.
199    */
200    void ShipPart::setHealth(float health)
201    {
202        this->health_ = health;
203    }
204
205    /**
206    @brief
207        Handles a received hit.
208    */
209    void ShipPart::handleHit(float damage, float healthdamage, float shielddamage, Pawn* originator)
210    {
211        if (parent_->getGametype() && parent_->getGametype()->allowPawnDamage(parent_, originator))
212        {
213            if (shielddamage >= parent_->getShieldHealth())
214            {
215                parent_->setShieldHealth(0);
216                this->setHealth(this->health_ - (healthdamage + damage) * this->damageAbsorption_);
217                parent_->setHealth(parent_->getHealth() - (healthdamage + damage) * (1 - this->damageAbsorption_));
218            }
219            else
220            {
221                parent_->setShieldHealth(parent_->getShieldHealth() - shielddamage);
222
223                // remove remaining shieldAbsorpton-Part of damage from shield
224                shielddamage = damage * parent_->getShieldAbsorption();
225                shielddamage = std::min(parent_->getShieldHealth(),shielddamage);
226                parent_->setShieldHealth(parent_->getShieldHealth() - shielddamage);
227
228                // set remaining damage to health
229                this->setHealth(this->health_ - ((damage - shielddamage) - healthdamage) * this->damageAbsorption_);
230                parent_->setHealth(parent_->getHealth() - ((damage - shielddamage) - healthdamage) * (1- this->damageAbsorption_));
231            }
232        }
233        if (this->health_ < 0)
234            this->alive_ = false;
235            //this->death();
236
237        // (Ugly) Chatoutput of health, until a GUI for modularspaceships-shipparts is implemented.
238        if (this->health_ < 0.2 * this->maxHealth_)
239        {
240            ChatManager::message("ShipPart " + this->getName() + " remaining health is 20%!");
241            return;
242        }
243        if (this->health_ < 0.4 * this->maxHealth_)
244        {
245            ChatManager::message("ShipPart " + this->getName() + " remaining health is 40%!");
246            return;
247        }
248        if (this->health_ < 0.6 * this->maxHealth_)
249        {
250            ChatManager::message("ShipPart " + this->getName() + " remaining health is 60%!");
251            return;
252        }
253        if (this->health_ < 0.8 * this->maxHealth_)
254        {
255            ChatManager::message("ShipPart " + this->getName() + " remaining health is 80%!");
256            return;
257        }
258    }
259
260
261    /**
262    @brief
263        Adds the ShipPart to the input SpaceShip.
264    @param ship
265        A pointer to the SpaceShip to which the ShipPart is added.
266    */
267    /*void ShipPart::addToSpaceShip(ModularSpaceShip* ship)
268    {
269        this->parent_ = ship;
270
271        if (ship)
272        {
273            this->parentID_ = ship->getObjectID();
274            if (!ship->hasShipPart(this))
275                ship->addShipPart(this);
276        }
277    }*/
278
279}
Note: See TracBrowser for help on using the repository browser.