Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core7/src/orxonox/items/ShipPart.cc @ 10414

Last change on this file since 10414 was 10414, checked in by landauf, 9 years ago

destroy all remaining ship parts if ModularSpaceShip is destroyed.
separate ship part death effects from object deletion. ShipPart.death() creates effects, ShipPartManager destroys the instance.

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