Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/OrxoBlox_FS19/src/modules/weapons/projectiles/BasicProjectile.cc @ 12378

Last change on this file since 12378 was 12378, checked in by pomselj, 5 years ago

Projectiles survive infinitely

  • Property svn:eol-style set to native
File size: 7.6 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 is destroying the projectile after collision
57        this->destroyAfterCollision_ = true;
58
59        // Default damage must be zero, otherwise it would be above zero if no settings are made in the weaponsettings xml file.
60        // same thing for all weaponmodes files
61        this->damage_ = 0.0f;
62        this->healthdamage_ = 0.0f;
63        this->shielddamage_ = 0.0f;
64    }
65
66    BasicProjectile::~BasicProjectile()
67    {
68    }
69
70    /**
71    @brief
72        The function called when a projectile hits another thing.
73        Calls the hit-function, starts the shield recharge countdown, displays visual hit effects defined in Pawn.
74        Needs to be called in the collidesAgainst() function by every Class directly inheriting from BasicProjectile.
75    @param otherObject
76        A pointer to the object the Projectile has collided against.
77    @param contactPoint
78        A btManifoldPoint indicating the point of contact/impact.
79    @param cs
80        The btCollisionShape of the other object
81    @return
82        Returns true if the collision resulted in a successful hit.
83    @see Pawn.h
84    */
85    bool BasicProjectile::processCollision(WorldEntity* otherObject, btManifoldPoint& contactPoint, const btCollisionShape* cs)
86    {
87        if (!this->bDestroy_ && GameMode::isMaster())
88        {
89            if (this->isObjectRelatedToShooter(otherObject) || otherObject->isA(Class(BasicProjectile))) // Prevents you from shooting yourself or other projectiles
90                return false;
91
92            if (getDestroyAfterCollision())
93            {
94                orxout() << "Destroy that stuff" << endl;
95                this->bDestroy_ = true; // If something is hit, the object is destroyed and can't hit something else.
96                                        // The projectile is destroyed by its tick()-function (in the following tick).
97                                        // TODO: Use destroyLater() for this
98            }
99
100            Pawn* victim = orxonox_cast<Pawn*>(otherObject); // If otherObject isn't a Pawn, then victim is nullptr
101
102            WorldEntity* entity = orxonox_cast<WorldEntity*>(this);
103            assert(entity); // The projectile must not be a WorldEntity.
104
105            // If visual effects after destruction cause problems, put this block below the effects code block
106            if (victim)
107            {
108                victim->hit(this->getShooter(), contactPoint, cs, this->getDamage(), this->getHealthDamage(), this->getShieldDamage());
109                victim->startShieldRechargeCountdown();
110            }
111
112            // Visual effects for being hit, depending on whether the shield is hit or not
113            if (this->getShooter()) // If the owner does not exist (anymore?), no effects are displayed.
114            {
115                // Damping and explosion effect is only played if the victim is no Pawn (see cast above)
116                // or if the victim is a Pawn, has no shield left, is still alive and any damage goes to the health
117                if (!victim || (victim && !victim->hasShield() && victim->getHealth() > 0.0f && (this->getDamage() > 0.0f || this->getHealthDamage() > 0.0f)))
118                {
119                    {
120                        ParticleSpawner* effect = new ParticleSpawner(this->getShooter()->getContext());
121                        effect->setPosition(entity->getPosition());
122                        effect->setOrientation(entity->getOrientation());
123                        effect->setDestroyAfterLife(true);
124                        effect->setSource("Orxonox/explosion3");
125                        effect->setLifetime(2.0f);
126                    }
127                    // Second effect with same condition
128                    {
129                        ParticleSpawner* effect = new ParticleSpawner(this->getShooter()->getContext());
130                        effect->setPosition(entity->getPosition());
131                        effect->setOrientation(entity->getOrientation());
132                        effect->setDestroyAfterLife(true);
133                        effect->setSource("Orxonox/smoke4");
134                        effect->setLifetime(3.0f);
135                    }
136                }
137
138                // victim->isAlive() is not false until the next tick, so getHealth() > 0 is used instead
139                if (victim && victim->hasShield() && (this->getDamage() > 0.0f || this->getShieldDamage() > 0.0f) && victim->getHealth() > 0.0f)
140                {
141                    ParticleSpawner* effect = new ParticleSpawner(this->getShooter()->getContext());
142                    effect->setDestroyAfterLife(true);
143                    effect->setSource("Orxonox/Shield");
144                    effect->setLifetime(0.5f);
145                    victim->attach(effect);
146                }
147            }
148            return true;
149        }
150        return false;
151    }
152
153    /**
154     * Returns true if otherObject is equal to the shooter or if one of otherObject's parents is equal to the shooter or if one of the shooter's parent is equal to otherObject.
155     */
156    bool BasicProjectile::isObjectRelatedToShooter(WorldEntity* otherObject)
157    {
158        for (WorldEntity* shooter = this->getShooter(); shooter != nullptr; shooter = shooter->getParent())
159            if (otherObject == shooter)
160                return true;
161        for (WorldEntity* object = otherObject; object != nullptr; object = object->getParent())
162            if (otherObject == this->getShooter())
163                return true;
164
165        return false;
166    }
167
168    /**
169    @brief
170        Check whether the projectile needs to be destroyed and destroys it if so.
171        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.
172    */
173    void BasicProjectile::destroyCheck(void)
174    {
175        if(GameMode::isMaster() && this->bDestroy_) {
176            orxout() << "Set true, smhow" << endl;
177            this->destroy();
178        }
179    }
180
181    /**
182    @brief
183        Destroys the object.
184    */
185    void BasicProjectile::destroyObject(void)
186    {
187        if(GameMode::isMaster()) {
188            orxout() << "Deleted myself" << endl;
189            this->destroy();
190        }
191    }
192}
Note: See TracBrowser for help on using the repository browser.