Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 12412 was 12028, checked in by merholzl, 6 years ago

added scriptable controller

  • 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 "chat/ChatManager.h"
44#include "Level.h"
45#include "scriptablecontroller/scriptable_controller.h"
46
47
48namespace orxonox
49{
50    RegisterClass(ShipPart);
51
52    ShipPart::ShipPart(Context* context)
53        : Item(context), parent_(nullptr)
54    {
55        RegisterObject(ShipPart);
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        this->explode();
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        this->destroyLater();
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 entity
121        A pointer to the StaticEntity to be added.
122    */
123    void ShipPart::addEntity(StaticEntity* entity)
124    {
125        OrxAssert(entity != nullptr, "The Entity cannot be nullptr.");
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. nullptr 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 nullptr;
139        else
140            return this->entityList_[index];
141    }
142
143    /**
144    @brief
145        Check whether the ShipPart has a particular Entity.
146    @param search
147        A pointer to the Entity to be checked.
148    */
149    bool ShipPart::hasEntity(StaticEntity* search) const
150    {
151        for(StaticEntity* entity : this->entityList_)
152        {
153            if(entity == search)
154                return true;
155        }
156        return false;
157    }
158
159    /**
160    @brief
161        Add a PartDestructionEvent to the ShipPart.
162    @param event
163        A pointer to the PartDestructionEvent to be added.
164    */
165    void ShipPart::addDestructionEvent(PartDestructionEvent* event)
166    {
167        OrxAssert(event != nullptr, "The PartDestructionEvent cannot be nullptr.");
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. nullptr 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 nullptr;
182        else
183            return this->eventList_[index];
184    }
185
186    void ShipPart::setParent(ModularSpaceShip* ship)
187    {
188        this->parent_ = ship;
189    }
190
191    /**
192    @brief
193        Handles a received hit.
194    */
195    void ShipPart::handleHit(float damage, float healthdamage, float shielddamage, Pawn* originator)
196    {
197        if (parent_->getGametype() && parent_->getGametype()->allowPawnDamage(parent_, originator))
198        {
199            if (shielddamage >= parent_->getShieldHealth())
200            {
201                parent_->setShieldHealth(0);
202                this->setHealth(this->health_ - (healthdamage + damage) * this->damageAbsorption_);
203                parent_->setHealth(parent_->getHealth() - (healthdamage + damage) * (1 - this->damageAbsorption_));
204            }
205            else
206            {
207                parent_->setShieldHealth(parent_->getShieldHealth() - shielddamage);
208
209                // remove remaining shieldAbsorpton-Part of damage from shield
210                shielddamage = damage * parent_->getShieldAbsorption();
211                shielddamage = std::min(parent_->getShieldHealth(),shielddamage);
212                parent_->setShieldHealth(parent_->getShieldHealth() - shielddamage);
213
214                // set remaining damage to health
215                this->setHealth(this->health_ - ((damage - shielddamage) - healthdamage) * this->damageAbsorption_);
216                parent_->setHealth(parent_->getHealth() - ((damage - shielddamage) - healthdamage) * (1- this->damageAbsorption_));
217            }
218        }
219
220        // This is a bit hacky, but it takes away damage control from the pawn, so it has to handle
221        // that as well.
222        this->getLevel()->getScriptableController()->pawnHit(parent_, originator, parent_->getHealth(), parent_->getShieldHealth());
223
224        if (this->health_ < 0)
225            this->death();
226
227        // (Ugly) Chatoutput of health, until a GUI for modularspaceships-shipparts is implemented.
228        if ((this->health_ < 0.2 * this->maxHealth_) && (this->healthMem_ == 40))
229        {
230            this->healthMem_ = 20;
231            ChatManager::message("ShipPart " + this->getName() + " remaining health is 20%!");
232            return;
233        }
234        if ((this->health_ < 0.4 * this->maxHealth_) && (this->healthMem_ == 60))
235        {
236            this->healthMem_ = 40;
237            ChatManager::message("ShipPart " + this->getName() + " remaining health is 40%!");
238            return;
239        }
240        if ((this->health_ < 0.6 * this->maxHealth_) && (this->healthMem_ == 80))
241        {
242            this->healthMem_ = 60;
243            ChatManager::message("ShipPart " + this->getName() + " remaining health is 60%!");
244            return;
245        }
246        if ((this->health_ < 0.8 * this->maxHealth_) && (this->healthMem_ == 100))
247        {
248            this->healthMem_ = 80;
249            ChatManager::message("ShipPart " + this->getName() + " remaining health is 80%!");
250            return;
251        }
252    }
253
254
255    /**
256    @brief
257        Adds the ShipPart to the input SpaceShip.
258    @param ship
259        A pointer to the SpaceShip to which the ShipPart is added.
260    */
261    /*void ShipPart::addToSpaceShip(ModularSpaceShip* ship)
262    {
263        this->parent_ = ship;
264
265        if (ship)
266        {
267            this->parentID_ = ship->getObjectID();
268            if (!ship->hasShipPart(this))
269                ship->addShipPart(this);
270        }
271    }*/
272
273}
Note: See TracBrowser for help on using the repository browser.