Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/orxonox/items/ShipPart.cc @ 10901

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

merged branch core7 back to trunk

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