Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/presentationFS14/src/orxonox/items/PartDestructionEvent.cc @ 10214

Last change on this file since 10214 was 10214, checked in by landauf, 10 years ago

fixed segfault. after removing the engine from the ship, we need to destroy it. otherwise the engine remains in the object lists and will be destroyed at the end of the game - but at this point the ship may not exist anymore, leading to a crash.

File size: 12.2 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 "PartDestructionEvent.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 "items/Engine.h"
41#include "gametypes/Gametype.h"
42#include "chat/ChatManager.h"
43
44
45namespace orxonox
46{
47    RegisterClass(PartDestructionEvent);
48
49    PartDestructionEvent::PartDestructionEvent(Context* context)
50        : Item(context)
51    {
52        RegisterObject(PartDestructionEvent);
53        this->setValid(true);
54    }
55
56    PartDestructionEvent::~PartDestructionEvent()
57    {
58
59    }
60
61    void PartDestructionEvent::XMLPort(Element& xmlelement, XMLPort::Mode mode)
62    {
63        SUPER(PartDestructionEvent, XMLPort, xmlelement, mode);
64
65        XMLPortParam(PartDestructionEvent, "targetType", setTargetType, getTargetType, xmlelement, mode).defaultValues("NULL");
66        XMLPortParam(PartDestructionEvent, "targetName", setTargetName, getTargetName, xmlelement, mode).defaultValues("NULL");
67        XMLPortParam(PartDestructionEvent, "operation", setOperation, getOperation, xmlelement, mode).defaultValues("NULL");
68        XMLPortParam(PartDestructionEvent, "targetParam", setTargetParam, getTargetParam, xmlelement, mode).defaultValues("NULL");
69        XMLPortParam(PartDestructionEvent, "value", setEventValue, getEventValue, xmlelement, mode).defaultValues(0);
70        XMLPortParam(PartDestructionEvent, "message", setMessage, getMessage, xmlelement, mode).defaultValues("NULL");
71
72        /*
73        XMLPortParam(PartDestructionEvent, "health", setHealth, getHealth, xmlelement, mode).defaultValues(100);
74        XMLPortParam(PartDestructionEvent, "maxhealth", setMaxHealth, getMaxHealth, xmlelement, mode).defaultValues(200);
75        XMLPortParam(PartDestructionEvent, "initialhealth", setInitialHealth, getInitialHealth, xmlelement, mode).defaultValues(100);
76        */
77    }
78
79    /**
80    @brief
81        Executes this event.
82    */
83    void PartDestructionEvent::execute()
84    {
85        // Do not execute if this event is invalid
86        if(!isValid())
87        {
88            orxout(internal_warning) << "Attempted to execute an invalid PartDestructionEvent!" << endl;
89            return;
90        }
91
92        // Output the destruction-message to the chat
93        if(this->message_ != "NULL")
94            ChatManager::message(this->message_);
95
96        // Modify parameters as configured for all cases
97        if (this->targetType_ == "ship")
98        {
99            switch (this->targetParam_) {
100            case shieldhealth:
101                this->parent_->getParent()->setShieldHealth(operate(this->parent_->getParent()->getShieldHealth()));
102                break;
103            case boostpower:
104                this->parent_->getParent()->setInitialBoostPower(operate(this->parent_->getParent()->getInitialBoostPower()));
105                break;
106            case boostpowerrate:
107                this->parent_->getParent()->setBoostPowerRate(operate(this->parent_->getParent()->getBoostPowerRate()));
108                break;
109            case rotationthrust:
110                this->parent_->getParent()->setRotationThrust(operate(this->parent_->getParent()->getRotationThrust()));
111                break;
112            default:
113                break;
114            }
115            this->setValid(false);
116            return;
117        }
118
119        if (this->targetType_ == "engine")
120        {
121            switch (this->targetParam_) {
122            case null:
123                this->parent_->getParent()->getEngineByName(targetName_)->destroy();
124                break;
125            case boostfactor:
126                this->parent_->getParent()->getEngineByName(targetName_)->setBoostFactor(operate(this->parent_->getParent()->getEngineByName(targetName_)->getBoostFactor()));
127                break;
128            case speedfront:
129                this->parent_->getParent()->getEngineByName(targetName_)->setMaxSpeedFront(operate(this->parent_->getParent()->getEngineByName(targetName_)->getMaxSpeedFront()));
130                break;
131            case accelerationfront:
132                this->parent_->getParent()->getEngineByName(targetName_)->setAccelerationFront(operate(this->parent_->getParent()->getEngineByName(targetName_)->getAccelerationFront()));
133                break;
134            default:
135                break;
136            }
137            this->setValid(false);
138            return;
139        }
140
141        if (this->targetType_ == "part")
142        {
143            switch (this->targetParam_) {
144            case null:
145                if (!this->parent_->getParent()->getShipPartByName(targetName_))
146                    return;
147                this->parent_->getParent()->getShipPartByName(targetName_)->setEventExecution(false);
148                this->parent_->getParent()->killShipPart(targetName_);
149                break;
150            default:
151                break;
152            }
153            this->setValid(false);
154            return;
155        }
156    }
157
158    void PartDestructionEvent::setParent(ShipPart* part)
159    {
160        this->parent_ = part;
161    }
162
163    /**
164    @brief
165        Set type of the target
166    @param param
167        The desired target-type as string. Valid target-types: ship engine weapon
168    */
169    void PartDestructionEvent::setTargetType(std::string type)
170    {
171        if ((type == "ship") || (type == "engine") || (type == "weapon") || (type == "part"))
172        {
173            this->targetType_ = type;
174            return;
175        }
176
177        // Error, if invalid target-type was entered.
178        orxout(internal_warning) << "\"" << type << "\" is not a valid target-type for a PartDestructionEvent. Valid types are: ship engine weapon part" << endl;
179        this->setValid(false);
180        return;
181    }
182
183    void PartDestructionEvent::setTargetName(std::string name)
184    {
185        // Error, if the target-type is "weapon" or "engine", but the name of said target was not defined.
186        if (((this->targetType_ == "weapon") || (this->targetType_ == "engine")) && (name == "NULL"))
187        {
188            orxout(internal_warning) << "The target-name of a PartDestructionEvent with target-type \"" << this->targetType_ << "\" needs to be defined!" << endl;
189            return;
190        }
191
192        this->targetName_ = name;
193    }
194
195    /**
196    @brief
197        Set the operation to be applied.
198    @param param
199        The desired parameter as string. Valid parameters: c.f. @ref orxnox::PartDestructionEvent::TargetParam
200    */
201    void PartDestructionEvent::setTargetParam(std::string param)
202    {
203        // A target-type needs to be defined in order to choose a parameter.
204        if (this->targetType_ == "NULL")
205        {
206            orxout(internal_warning) << "No valid target-type defined. Cannot set target-param for this PartDestructionEvent." << endl;
207            this->setValid(false);
208            return;
209        }
210
211        // engine: NULL boostfactor speedfront accelerationfront
212        if (this->targetType_ == "engine")
213        {
214            if (param == "NULL")
215            {
216                this->targetParam_ = null;
217                return;
218            }
219            if (param == "boostfactor")
220            {
221                this->targetParam_ = boostfactor;
222                return;
223            }
224            if (param == "speedfront")
225            {
226                this->targetParam_ = speedfront;
227                return;
228            }
229            if (param == "accelerationfront")
230            {
231                this->targetParam_ = accelerationfront;
232                return;
233            }
234
235            orxout(internal_warning) << "\"" << param << "\" is not a valid target-param for a PartDestructionEvent with target-type \"engine\". Valid types are: boostfactor speedfront accelerationfront" << endl;
236            return;
237        }
238
239        // weapon:
240
241        // ship: shieldhealth (maxshieldhealth shieldabsorption shieldrechargerate) boostpower boostpowerrate rotationthrust
242        if (this->targetType_ == "ship")
243        {
244            if (param == "shieldhealth")
245            {
246                this->targetParam_ = shieldhealth;
247                return;
248            }
249            if (param == "boostpower")
250            {
251                this->targetParam_ = boostpower;
252                return;
253            }
254            if (param == "boostpowerrate")
255            {
256                this->targetParam_ = boostpowerrate;
257                return;
258            }
259            if (param == "rotationthrust")
260            {
261                this->targetParam_ = rotationthrust;
262                return;
263            }
264
265            orxout(internal_warning) << "\"" << param << "\" is not a valid target-param for a PartDestructionEvent with target-type \"ship\". Valid types are: shieldhealth maxshieldhealth shieldabsorption shieldrechargerate boostpower boostpowerrate rotationthrust" << endl;
266            return;
267        }
268
269        if (this->targetType_ == "part")
270        {
271            if (param == "NULL")
272            {
273                this->targetParam_ = null;
274                return;
275            }
276
277            orxout(internal_warning) << "\"" << param << "\" is not a valid target-param for a PartDestructionEvent with target-type \"part\". Valid types are: NULL (set operation to \"destroy\")" << endl;
278            return;
279        }
280
281        orxout(internal_warning) << "No valid target-param defined. The chosen param is either invalid or not available for this target-type." << endl;
282        this->setValid(false);
283    }
284
285    /**
286    @brief
287        Set the operation to be applied.
288    @param operation
289        The desired operator as string. Valid operators: * + - destroy
290    */
291    void PartDestructionEvent::setOperation(std::string operation)
292    {
293        // * + - destroy
294        if ((operation == "*") || (operation == "+") || (operation == "-") || (operation == "set") || (operation == "destroy"))
295        {
296            this->operation_ = operation;
297            return;
298        }
299        this->operation_ = "NULL";
300        orxout(internal_warning) << "\"" << operation << "\" is not a valid operation for a PartDestructionEvent. Valid operations are: * + - set destroy" << endl;
301    }
302
303    /**
304    @brief
305        Set the message to be shown upon execution of the vent.
306    @param msg
307        The desired message as string.
308    */
309    void PartDestructionEvent::setMessage(std::string msg)
310    {
311        this->message_ = msg;
312    }
313
314
315    /**
316    @brief
317        Apply the configured operation and value to an input.
318    @param input
319        The value which should be modified
320    @return
321        Returns the product / sum / difference of input and configured value,
322        the configured value if the operation is "set",
323        or 0 if the operation is "destroy"
324    */
325    float PartDestructionEvent::operate(float input)
326    {
327        if (this->operation_ == "*")
328            return input * this->value_;
329        if (this->operation_ == "+")
330            return input + this->value_;
331        if (this->operation_ == "-")
332            return input - this->value_;
333        if (this->operation_ == "set")
334            return this->value_;
335        if (this->operation_ == "destroy")
336        {
337            return 0;
338        }
339        return 0;
340    }
341
342    /**
343    @brief
344        Sets the value applied with the chosen operation.
345    @param value
346        The value as float.
347    */
348    void PartDestructionEvent::setEventValue(float value)
349    {
350        this->value_ = value;
351    }
352}
Note: See TracBrowser for help on using the repository browser.