Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 10415 was 10414, checked in by landauf, 10 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.