Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/modularships/src/modules/weapons/projectiles/BasicProjectile.cc @ 10001

Last change on this file since 10001 was 9995, checked in by noep, 11 years ago

Modified collision-detecting-process, such that collisions can be traced back to single child-CollisionShapes of Compound-CollisionShapes

  • Property svn:eol-style set to native
File size: 9.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 *      simonmie
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29/**
30    @file BasicProjectile.h
31    @brief Implementation of the BasicProjectile class.
32*/
33
34#include "BasicProjectile.h"
35
36#include "core/CoreIncludes.h"
37#include "core/GameMode.h"
38#include "core/command/Executor.h"
39
40#include "graphics/ParticleSpawner.h"
41
42namespace orxonox
43{
44    RegisterClassNoArgs(BasicProjectile);
45
46    /**
47    @brief
48        Constructor. Registers the object and initializes some default values.
49    */
50    BasicProjectile::BasicProjectile()
51    {
52        RegisterObject(BasicProjectile);// Register the BasicProjectile class to the core
53
54        this->bDestroy_ = false;
55
56        // Default damage must be zero, otherwise it would be above zero if no settings are made in the weaponsettings xml file.
57        // same thing for all weaponmodes files
58        this->damage_ = 0.0f;
59        this->healthdamage_ = 0.0f;
60        this->shielddamage_ = 0.0f;
61    }
62
63    BasicProjectile::~BasicProjectile()
64    {
65    }
66
67    /**
68    @brief
69        The function called when a projectile hits another thing.
70        Calls the hit-function, starts the reload countdown, displays visual hit effects defined in Pawn.
71        Needs to be called in the collidesAgainst() function by every Class directly inheriting from BasicProjectile.
72    @param otherObject
73        A pointer to the object the Projectile has collided against.
74    @param contactPoint
75        A btManifoldPoint indicating the point of contact/impact.
76    @return
77        Returns true if the collision resulted in a successful hit.
78    @see Pawn.h
79    */
80    bool BasicProjectile::processCollision(WorldEntity* otherObject, btManifoldPoint& contactPoint)
81    {
82        if (!this->bDestroy_ && GameMode::isMaster())
83        {
84            if (otherObject == this->getShooter()) // Prevents you from shooting yourself
85                return false;
86
87            this->bDestroy_ = true; // If something is hit, the object is destroyed and can't hit something else.
88                                    // The projectile is destroyed by its tick()-function (in the following tick).
89
90            Pawn* victim = orxonox_cast<Pawn*>(otherObject); // If otherObject isn't a Pawn, then victim is NULL
91
92            WorldEntity* entity = orxonox_cast<WorldEntity*>(this);
93            assert(entity); // The projectile must not be a WorldEntity.
94
95            // If visual effects after destruction cause problems, put this block below the effects code block
96            if (victim)
97            {
98                victim->hit(this->getShooter(), contactPoint, this->getDamage(), this->getHealthDamage(), this->getShieldDamage());
99                victim->startReloadCountdown();
100            }
101
102            // Visual effects for being hit, depending on whether the shield is hit or not
103            if (this->getShooter()) // If the owner does not exist (anymore?), no effects are displayed.
104            {
105                // Damping and explosion effect is only played if the victim is no Pawn (see cast above)
106                // or if the victim is a Pawn, has no shield left, is still alive and any damage goes to the health
107                if (!victim || (victim && !victim->hasShield() && victim->getHealth() > 0.0f && (this->getDamage() > 0.0f || this->getHealthDamage() > 0.0f)))
108                {
109                    {
110                        ParticleSpawner* effect = new ParticleSpawner(this->getShooter()->getContext());
111                        effect->setPosition(entity->getPosition());
112                        effect->setOrientation(entity->getOrientation());
113                        effect->setDestroyAfterLife(true);
114                        effect->setSource("Orxonox/explosion3");
115                        effect->setLifetime(2.0f);
116                    }
117                    // Second effect with same condition
118                    {
119                        ParticleSpawner* effect = new ParticleSpawner(this->getShooter()->getContext());
120                        effect->setPosition(entity->getPosition());
121                        effect->setOrientation(entity->getOrientation());
122                        effect->setDestroyAfterLife(true);
123                        effect->setSource("Orxonox/smoke4");
124                        effect->setLifetime(3.0f);
125                    }
126                }
127
128                // victim->isAlive() is not false until the next tick, so getHealth() > 0 is used instead
129                if (victim && victim->hasShield() && (this->getDamage() > 0.0f || this->getShieldDamage() > 0.0f) && victim->getHealth() > 0.0f)
130                {
131                    ParticleSpawner* effect = new ParticleSpawner(this->getShooter()->getContext());
132                    effect->setDestroyAfterLife(true);
133                    effect->setSource("Orxonox/Shield");
134                    effect->setLifetime(0.5f);
135                    victim->attach(effect);
136                }
137            }
138            return true;
139        }
140        return false;
141    }
142
143    bool BasicProjectile::customProcessCollision(WorldEntity* otherObject, btManifoldPoint& contactPoint, const btCollisionShape* cs)
144        {
145            if (!this->bDestroy_ && GameMode::isMaster())
146            {
147                if (otherObject == this->getShooter()) // Prevents you from shooting yourself
148                    return false;
149
150                this->bDestroy_ = true; // If something is hit, the object is destroyed and can't hit something else.
151                                        // The projectile is destroyed by its tick()-function (in the following tick).
152
153                Pawn* victim = orxonox_cast<Pawn*>(otherObject); // If otherObject isn't a Pawn, then victim is NULL
154
155                WorldEntity* entity = orxonox_cast<WorldEntity*>(this);
156                assert(entity); // The projectile must not be a WorldEntity.
157
158                // If visual effects after destruction cause problems, put this block below the effects code block
159                if (victim)
160                {
161                    victim->customHit(this->getShooter(), contactPoint, cs, this->getDamage(), this->getHealthDamage(), this->getShieldDamage());
162                    victim->startReloadCountdown();
163                }
164
165                // Visual effects for being hit, depending on whether the shield is hit or not
166                if (this->getShooter()) // If the owner does not exist (anymore?), no effects are displayed.
167                {
168                    // Damping and explosion effect is only played if the victim is no Pawn (see cast above)
169                    // or if the victim is a Pawn, has no shield left, is still alive and any damage goes to the health
170                    if (!victim || (victim && !victim->hasShield() && victim->getHealth() > 0.0f && (this->getDamage() > 0.0f || this->getHealthDamage() > 0.0f)))
171                    {
172                        {
173                            ParticleSpawner* effect = new ParticleSpawner(this->getShooter()->getContext());
174                            effect->setPosition(entity->getPosition());
175                            effect->setOrientation(entity->getOrientation());
176                            effect->setDestroyAfterLife(true);
177                            effect->setSource("Orxonox/explosion3");
178                            effect->setLifetime(2.0f);
179                        }
180                        // Second effect with same condition
181                        {
182                            ParticleSpawner* effect = new ParticleSpawner(this->getShooter()->getContext());
183                            effect->setPosition(entity->getPosition());
184                            effect->setOrientation(entity->getOrientation());
185                            effect->setDestroyAfterLife(true);
186                            effect->setSource("Orxonox/smoke4");
187                            effect->setLifetime(3.0f);
188                        }
189                    }
190
191                    // victim->isAlive() is not false until the next tick, so getHealth() > 0 is used instead
192                    if (victim && victim->hasShield() && (this->getDamage() > 0.0f || this->getShieldDamage() > 0.0f) && victim->getHealth() > 0.0f)
193                    {
194                        ParticleSpawner* effect = new ParticleSpawner(this->getShooter()->getContext());
195                        effect->setDestroyAfterLife(true);
196                        effect->setSource("Orxonox/Shield");
197                        effect->setLifetime(0.5f);
198                        victim->attach(effect);
199                    }
200                }
201                return true;
202            }
203            return false;
204        }
205
206    /**
207    @brief
208        Check whether the projectile needs to be destroyed and destroys it if so.
209        Needs to be called in the tick() by every Class directly inheriting from BasicProjectile, to make sure the projectile is destroyed after it has hit something.
210    */
211    void BasicProjectile::destroyCheck(void)
212    {
213        if(GameMode::isMaster() && this->bDestroy_)
214            this->destroy();
215    }
216
217    /**
218    @brief
219        Destroys the object.
220    */
221    void BasicProjectile::destroyObject(void)
222    {
223        if(GameMode::isMaster())
224            this->destroy();
225    }
226}
Note: See TracBrowser for help on using the repository browser.