Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/modules/weapons/projectiles/MineProjectile.cc @ 11997

Last change on this file since 11997 was 11071, checked in by landauf, 9 years ago

merged branch cpp11_v3 back to trunk

  • Property svn:eol-style set to native
File size: 9.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 *      Jannis Holzer
24 *      Fabien Vultier
25 *   Co-authors:
26 *      ...
27 *
28 */
29
30/**
31    @file MineProjectile.h
32    @brief Implementation of the MineProjectile class.
33*/
34
35#include "MineProjectile.h"
36
37#include "core/CoreIncludes.h"
38#include "graphics/Model.h"
39#include "core/command/Executor.h"
40#include "graphics/ParticleSpawner.h"
41#include "worldentities/pawns/Pawn.h"
42#include "core/EventIncludes.h"
43#include "sound/WorldSound.h"
44
45namespace orxonox
46{
47    RegisterClass(MineProjectile);
48
49    const float MineProjectile::collisionShapeRadius_ = 15.0f;
50    const float MineProjectile::damageRadius_ = 200.0f;
51    const float MineProjectile::triggerRadius_ = 100.0f;
52
53    MineProjectile::MineProjectile(Context* context) : MovableEntity(context), BasicProjectile()
54    {
55        RegisterObject(MineProjectile);
56
57        this->bAllowExplosion_ = false;
58        this->maxTimeUntilExplosion_ = 10.0f;
59        this->timeUntilActivation_ = 1.0f;
60
61        //Create movable entities
62        rings1_ = new MovableEntity(this->getContext());
63        this->attach(rings1_);
64        rings1_->setPosition(Vector3(0.0,0.0,0.0));
65        rings1_->setAngularVelocity(Vector3(0.0,5.0,0.0));
66
67        rings2_ = new MovableEntity(this->getContext());
68        this->attach(rings2_);
69        rings2_->setPosition(Vector3(0.0,0.0,0.0));
70        rings2_->setAngularVelocity(Vector3(0.0,0.0,5.0));
71
72        core_ = new MovableEntity(this->getContext());
73        this->attach(core_);
74        core_->setPosition(Vector3(0.0,0.0,0.0));
75        core_->setAngularVelocity(Vector3(2.5,2.5,0.0));
76
77        //Create Models
78        //Core
79        modelCore_ = new Model(this->getContext());
80        modelCore_->setMeshSource("Mine_Core.mesh");
81        modelCore_->setScale(15.0);
82        core_->attach(modelCore_);
83        modelCore_->setPosition(Vector3(0,0,0));
84
85        //Ring 1
86        modelRing1_ = new Model(this->getContext());
87        modelRing1_->setMeshSource("Mine_Ring.mesh");
88        modelRing1_->setScale(15.0);
89        rings1_->attach(modelRing1_);
90        modelRing1_->setPosition(Vector3(0,0,0));
91        modelRing1_->yaw(Degree(0));
92        //Ring 2
93        modelRing2_ = new Model(this->getContext());
94        modelRing2_->setMeshSource("Mine_Ring.mesh");
95        modelRing2_->setScale(15.0);
96        rings1_->attach(modelRing2_);
97        modelRing2_->setPosition(Vector3(0,0,0));
98        modelRing2_->yaw(Degree(180));
99        //Ring 3
100        modelRing3_ = new Model(this->getContext());
101        modelRing3_->setMeshSource("Mine_Ring.mesh");
102        modelRing3_->setScale(15.0);
103        rings2_->attach(modelRing3_);
104        modelRing3_->setPosition(Vector3(0,0,0));
105        modelRing3_->yaw(Degree(90));
106        //Ring 4
107        modelRing4_ = new Model(this->getContext());
108        modelRing4_->setMeshSource("Mine_Ring.mesh");
109        modelRing4_->setScale(15.0);
110        rings2_->attach(modelRing4_);
111        modelRing4_->setPosition(Vector3(0,0,0));
112        modelRing4_->yaw(Degree(270));
113
114        emitter_ = nullptr;
115
116        if (GameMode::isMaster())
117        {
118            this->setMass(10.0f);
119            this->setLinearDamping(0.5f);
120            this->setAngularDamping(0.1f);
121            this->enableCollisionCallback();
122            this->setCollisionResponse(true);
123            this->setCollisionType(CollisionType::Dynamic);
124
125            // Create a sphere collision shape and attach it to the projectile.
126            collisionShape_ = new SphereCollisionShape(this->getContext());
127            collisionShape_->setRadius(collisionShapeRadius_);
128            this->attachCollisionShape(collisionShape_);
129            collisionShape_->setPosition(Vector3(0,0,0));
130
131            // Create a distance trigger and attach it to the projectile.
132            distanceTrigger_ = new DistanceTrigger(this->getContext());
133            this->attach(distanceTrigger_);
134            distanceTrigger_->setPosition(Vector3(0,0,0));
135            distanceTrigger_->setDistance(triggerRadius_);
136            distanceTrigger_->addTarget("Pawn");
137            distanceTrigger_->setStayActive(false);
138
139            this->addEventSource(distanceTrigger_, "explode");
140        }
141    }
142
143    MineProjectile::~MineProjectile()
144    {
145        if (this->isInitialized())
146        {
147            modelCore_->destroy();
148            modelRing1_->destroy();
149            modelRing2_->destroy();
150            modelRing3_->destroy();
151            modelRing4_->destroy();
152
153            if (distanceTrigger_)
154            {
155                distanceTrigger_->destroy();
156            }
157            if (emitter_)
158            {
159                emitter_->destroy();
160            }
161        }
162    }
163
164    /**
165    @brief
166        XMLPort for MineProjectile.
167    */
168    void MineProjectile::XMLEventPort(Element& xmlelement, XMLPort::Mode mode)
169    {
170        SUPER(MineProjectile, XMLEventPort, xmlelement, mode);
171        XMLPortEventState(MineProjectile, BaseObject, "explode", explode, xmlelement, mode);
172    }
173
174    /**
175    @brief
176        Max Time; after this time runs out,the Mine explodes.
177    */
178    void MineProjectile::setMaxTimeUntilExplosion(float maxTimeUntilExplosion)
179    {
180        if (maxTimeUntilExplosion >= 0)
181        {
182            this->maxTimeUntilExplosion_ = maxTimeUntilExplosion;
183            if (GameMode::isMaster())
184            {
185                this->explodeTimer_.setTimer(this->maxTimeUntilExplosion_, false, createExecutor(createFunctor(&MineProjectile::explode, this)));
186            }
187        }
188        else
189        {
190            this->maxTimeUntilExplosion_ = 0;
191        }
192    }
193
194    /**
195    @brief
196        The mine can only explode when the activation time has run out.
197    */
198    void MineProjectile::setTimeUntilActivation(float timeUntilActivation)
199    {
200        timeUntilActivation_ = timeUntilActivation;
201
202        if (GameMode::isMaster())
203        {
204            this->activationTimer_.setTimer(this->timeUntilActivation_, false, createExecutor(createFunctor(&MineProjectile::allowExplosion, this)));
205        }
206    }
207
208    /**
209    @brief
210        Mine explodes, deals damage to pawn within range and destroys itself.
211    */
212    void MineProjectile::explode()
213    {
214        if (bAllowExplosion_)
215        {
216            if (GameMode::isMaster())
217            {
218                // Damage all pawns within the damage radius
219                for (Pawn* pawn : ObjectList<Pawn>())
220                {
221                    Vector3 distanceVector = pawn->getWorldPosition()-this->getWorldPosition();
222                    if(distanceVector.length()< damageRadius_)
223                    {
224                        pawn->hit(this->getShooter(), pawn->getWorldPosition(), nullptr, this->getDamage(), this->getHealthDamage(), this->getShieldDamage());
225                    }
226                }
227            }
228
229            this->destructionEffect();
230            this->destroyLater();
231        }
232    }
233
234    /**
235    @brief
236        Mine is ready to explode.
237    */
238    void MineProjectile::allowExplosion()
239    {
240        // Allow explosion
241        bAllowExplosion_ = true;
242        // Add particle effect
243        emitter_ = new ParticleEmitter(this->getContext());
244        this->attach(emitter_);
245        emitter_->setOrientation(this->getOrientation());
246        emitter_->setSource("Orxonox/mineparticle"); 
247    }
248
249    void MineProjectile::destructionEffect()
250    {
251        ParticleSpawner *effect1, *effect2, *effect3;
252       
253        effect1 = new ParticleSpawner(this->getContext());
254        effect2 = new ParticleSpawner(this->getContext());
255        effect3 = new ParticleSpawner(this->getContext());
256
257        effect1->setPosition(this->getPosition());
258        effect1->setOrientation(this->getOrientation());
259        effect1->setDestroyAfterLife(true);
260        effect1->setSource("Orxonox/MineExpl");
261        effect1->setLifetime(2.5f);
262
263        effect2->setPosition(this->getPosition());
264        effect2->setOrientation(this->getOrientation());
265        effect2->setDestroyAfterLife(true);
266        effect2->setSource("Orxonox/MineExpl1");
267        effect2->setLifetime(2.5f);
268
269        effect3->setPosition(this->getPosition());
270        effect3->setOrientation(this->getOrientation());
271        effect3->setDestroyAfterLife(true);
272        effect3->setSource("Orxonox/MineExpl2");
273        effect3->setLifetime(2.5f);
274
275        // Explosion sound effect.
276        WeakPtr<WorldSound> explosionSound_ = new WorldSound(getContext());
277        explosionSound_->setSource("sounds/minesound.ogg");
278        explosionSound_->setVolume(1.0);
279        explosionSound_->play();
280    }
281}
Note: See TracBrowser for help on using the repository browser.