Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 10071 was 10071, checked in by noep, 6 years ago

Removed all segfaults (or at least those we found…)

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)
53    {
54        RegisterObject(ShipPart);
55        this->setAlive(true);
56        this->setEventExecution(true);
57        this->healthMem_ = 100;
58    }
59
60    ShipPart::~ShipPart()
61    {
62
63    }
64
65    void ShipPart::XMLPort(Element& xmlelement, XMLPort::Mode mode)
66    {
67        SUPER(ShipPart, XMLPort, xmlelement, mode);
68
69        XMLPortParam(ShipPart, "health", setHealth, getHealth, xmlelement, mode).defaultValues(100);
70        XMLPortParam(ShipPart, "maxhealth", setMaxHealth, getMaxHealth, xmlelement, mode).defaultValues(200);
71        XMLPortParam(ShipPart, "initialhealth", setInitialHealth, getInitialHealth, xmlelement, mode).defaultValues(100);
72
73        XMLPortParam(ShipPart, "damageabsorption", setDamageAbsorption, getDamageAbsorption, xmlelement, mode).defaultValues(0.5);
74
75        XMLPortParamTemplate(ShipPart, "explosionposition", setExplosionPosition, getExplosionPosition, xmlelement, mode, Vector3);
76
77        XMLPortObject(ShipPart, PartDestructionEvent, "destructionevents", addDestructionEvent, getDestructionEvent, xmlelement, mode);
78    }
79
80    /**
81    @brief
82        Is called when the ShipPart dies.
83        Executes PartDestructionEvents.
84        Tells the ModularSpaceShip to remove this ShipPart.
85    */
86    void ShipPart::death()
87    {
88        //if (!(this->isAlive()))
89            //return;
90
91        this->explode();
92        this->setAlive(false);
93
94        if(eventExecution_)
95        {
96            // Execute all destruction events
97            for (unsigned int i = 0; i < this->eventList_.size(); i++)
98            {
99                this->getDestructionEvent(i)->execute();
100            }
101        }
102
103        // Remove this ShipPart from the parent.
104        this->parent_->removeShipPart(this);
105        delete this;
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->alive_ = false;
243            //this->death();
244
245        // (Ugly) Chatoutput of health, until a GUI for modularspaceships-shipparts is implemented.
246        if ((this->health_ < 0.2 * this->maxHealth_) && (this->healthMem_ == 40))
247        {
248            this->healthMem_ = 20;
249            ChatManager::message("ShipPart " + this->getName() + " remaining health is 20%!");
250            return;
251        }
252        if ((this->health_ < 0.4 * this->maxHealth_) && (this->healthMem_ == 60))
253        {
254            this->healthMem_ = 40;
255            ChatManager::message("ShipPart " + this->getName() + " remaining health is 40%!");
256            return;
257        }
258        if ((this->health_ < 0.6 * this->maxHealth_) && (this->healthMem_ == 80))
259        {
260            this->healthMem_ = 60;
261            ChatManager::message("ShipPart " + this->getName() + " remaining health is 60%!");
262            return;
263        }
264        if ((this->health_ < 0.8 * this->maxHealth_) && (this->healthMem_ == 100))
265        {
266            this->healthMem_ = 80;
267            ChatManager::message("ShipPart " + this->getName() + " remaining health is 80%!");
268            return;
269        }
270    }
271
272
273    /**
274    @brief
275        Adds the ShipPart to the input SpaceShip.
276    @param ship
277        A pointer to the SpaceShip to which the ShipPart is added.
278    */
279    /*void ShipPart::addToSpaceShip(ModularSpaceShip* ship)
280    {
281        this->parent_ = ship;
282
283        if (ship)
284        {
285            this->parentID_ = ship->getObjectID();
286            if (!ship->hasShipPart(this))
287                ship->addShipPart(this);
288        }
289    }*/
290
291}
Note: See TracBrowser for help on using the repository browser.