Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/mergeFS18/src/orxonox/items/ShipPart.cc @ 12222

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

added scriptable controller

  • Property svn:eol-style set to native
File size: 8.9 KB
RevLine 
[10019]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"
[10023]39#include "worldentities/pawns/ModularSpaceShip.h"
[10019]40#include "gametypes/Gametype.h"
41#include "worldentities/StaticEntity.h"
[10052]42#include "items/PartDestructionEvent.h"
[10067]43#include "chat/ChatManager.h"
[12028]44#include "Level.h"
45#include "scriptablecontroller/scriptable_controller.h"
[10019]46
47
48namespace orxonox
49{
50    RegisterClass(ShipPart);
51
52    ShipPart::ShipPart(Context* context)
[11071]53        : Item(context), parent_(nullptr)
[10019]54    {
55        RegisterObject(ShipPart);
[10624]56        this->eventExecution_ = true;
[10071]57        this->healthMem_ = 100;
[10019]58    }
59
60    ShipPart::~ShipPart()
61    {
[10624]62        if (this->parent_)
63        {
64            // Remove this ShipPart from the parent.
65            this->parent_->removeShipPart(this);
66        }
[10019]67    }
68
[10023]69    void ShipPart::XMLPort(Element& xmlelement, XMLPort::Mode mode)
70    {
71        SUPER(ShipPart, XMLPort, xmlelement, mode);
[10019]72
[10023]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
[10067]79        XMLPortParamTemplate(ShipPart, "explosionposition", setExplosionPosition, getExplosionPosition, xmlelement, mode, Vector3);
80
[10052]81        XMLPortObject(ShipPart, PartDestructionEvent, "destructionevents", addDestructionEvent, getDestructionEvent, xmlelement, mode);
[10023]82    }
83
[10055]84    /**
85    @brief
86        Is called when the ShipPart dies.
87        Executes PartDestructionEvents.
88        Tells the ModularSpaceShip to remove this ShipPart.
89    */
[10023]90    void ShipPart::death()
91    {
[10067]92        this->explode();
[10053]93
[10058]94        if(eventExecution_)
[10053]95        {
[10058]96            // Execute all destruction events
97            for (unsigned int i = 0; i < this->eventList_.size(); i++)
98            {
99                this->getDestructionEvent(i)->execute();
100            }
[10053]101        }
102
[10624]103        this->destroyLater();
[10023]104    }
105
[10067]106    void ShipPart::explode()
107    {
[11052]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());
[10067]112
113        // this->explosionSound_->setPosition(this->parent_->getPosition());
114        // this->explosionSound_->play();
115    }
116
[10019]117    /**
118    @brief
119        Add a StaticEntity to the ShipPart.
[11099]120    @param entity
[10019]121        A pointer to the StaticEntity to be added.
122    */
123    void ShipPart::addEntity(StaticEntity* entity)
124    {
[11071]125        OrxAssert(entity != nullptr, "The Entity cannot be nullptr.");
[10019]126        this->entityList_.push_back(entity);
127    }
128
129    /**
130    @brief
131        Get the i-th StaticEntity of the ShipPart.
132    @return
[11071]133        Returns a pointer to the i-the StaticEntity. nullptr if there is no StaticEntity with that index.
[10019]134    */
135    StaticEntity* ShipPart::getEntity(unsigned int index)
136    {
137        if(this->entityList_.size() >= index)
[11071]138            return nullptr;
[10019]139        else
140            return this->entityList_[index];
141    }
142
143    /**
144    @brief
145        Check whether the ShipPart has a particular Entity.
[11071]146    @param search
[10019]147        A pointer to the Entity to be checked.
148    */
[11071]149    bool ShipPart::hasEntity(StaticEntity* search) const
[10019]150    {
[11071]151        for(StaticEntity* entity : this->entityList_)
[10019]152        {
[11071]153            if(entity == search)
[10019]154                return true;
155        }
156        return false;
157    }
158
[10052]159    /**
160    @brief
161        Add a PartDestructionEvent to the ShipPart.
[11099]162    @param event
[10052]163        A pointer to the PartDestructionEvent to be added.
164    */
[10053]165    void ShipPart::addDestructionEvent(PartDestructionEvent* event)
[10052]166    {
[11071]167        OrxAssert(event != nullptr, "The PartDestructionEvent cannot be nullptr.");
[10053]168        event->setParent(this);
169        this->eventList_.push_back(event);
[10052]170    }
171
172    /**
173    @brief
174        Get the i-th PartDestructionEvent of the ShipPart.
175    @return
[11071]176        Returns a pointer to the i-the PartDestructionEvent. nullptr if there is no PartDestructionEvent with that index.
[10052]177    */
178    PartDestructionEvent* ShipPart::getDestructionEvent(unsigned int index)
179    {
[10053]180        if(this->eventList_.size() <= index)
[11071]181            return nullptr;
[10052]182        else
183            return this->eventList_[index];
184    }
185
[10023]186    void ShipPart::setParent(ModularSpaceShip* ship)
187    {
188        this->parent_ = ship;
189    }
190
[10019]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        }
[12028]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
[10023]224        if (this->health_ < 0)
[10624]225            this->death();
[10067]226
227        // (Ugly) Chatoutput of health, until a GUI for modularspaceships-shipparts is implemented.
[10071]228        if ((this->health_ < 0.2 * this->maxHealth_) && (this->healthMem_ == 40))
[10067]229        {
[10071]230            this->healthMem_ = 20;
[10067]231            ChatManager::message("ShipPart " + this->getName() + " remaining health is 20%!");
232            return;
233        }
[10071]234        if ((this->health_ < 0.4 * this->maxHealth_) && (this->healthMem_ == 60))
[10067]235        {
[10071]236            this->healthMem_ = 40;
[10067]237            ChatManager::message("ShipPart " + this->getName() + " remaining health is 40%!");
238            return;
239        }
[10071]240        if ((this->health_ < 0.6 * this->maxHealth_) && (this->healthMem_ == 80))
[10067]241        {
[10071]242            this->healthMem_ = 60;
[10067]243            ChatManager::message("ShipPart " + this->getName() + " remaining health is 60%!");
244            return;
245        }
[10071]246        if ((this->health_ < 0.8 * this->maxHealth_) && (this->healthMem_ == 100))
[10067]247        {
[10071]248            this->healthMem_ = 80;
[10067]249            ChatManager::message("ShipPart " + this->getName() + " remaining health is 80%!");
250            return;
251        }
[10019]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.