Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/presentation2/src/orxonox/weaponsystem/WeaponMode.cc @ 6252

Last change on this file since 6252 was 6245, checked in by youngk, 15 years ago

Implemented Firing sounds in Weapons HsW01, LightningGun and RocketFire. Engine and Explosion sounds for the Rocket are not yet implemented.
From now on, when creating a new sound for a weapon, just insert "this→setDefaultSound(PATH_TO_FILE)" into the constructor of the weapon.

Sound Files for HsW01 and LightningGun will be available in a couple of minutes

  • 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 *      Martin Polak
24 *      Fabian 'x3n' Landau
25 *   Co-authors:
26 *      ...
27 *
28 */
29
30#include "WeaponMode.h"
31
32#include "core/CoreIncludes.h"
33#include "core/XMLPort.h"
34#include "controllers/Controller.h"
35#include "worldentities/pawns/Pawn.h"
36
37#include "Munition.h"
38#include "Weapon.h"
39#include "WeaponPack.h"
40#include "WeaponSystem.h"
41
42#include "sound/WorldSound.h"
43
44namespace orxonox
45{
46    WeaponMode::WeaponMode(BaseObject* creator) : BaseObject(creator)
47    {
48        RegisterObject(WeaponMode);
49
50        this->weapon_ = 0;
51        this->mode_ = WeaponSystem::WEAPON_MODE_UNASSIGNED;
52
53        this->munition_ = 0;
54        this->initialMunition_ = 0;
55        this->initialMagazines_ = 0;
56        this->munitionPerShot_ = 1;
57
58        this->reloadTime_ = 0.25;
59        this->bReloading_ = false;
60        this->bAutoReload_ = true;
61        this->bParallelReload_ = true;
62
63        this->reloadTimer_.setTimer(0.0f, false, createExecutor(createFunctor(&WeaponMode::reloaded, this)));
64        this->reloadTimer_.stopTimer();
65
66        this->damage_ = 0;
67       
68        this->muzzleOffset_ = Vector3::ZERO;
69        this->muzzlePosition_ = Vector3::ZERO;
70        this->muzzleOrientation_ = Quaternion::IDENTITY;
71
72        this->defSndWpnFire_ = new WorldSound(this);
73        this->defSndWpnFire_->setLooping(false);
74    }
75
76    WeaponMode::~WeaponMode()
77    {
78        if(this->isInitialized())
79        {
80            delete this->defSndWpnFire_;
81        }
82    }
83
84    void WeaponMode::XMLPort(Element& xmlelement, XMLPort::Mode mode)
85    {
86        SUPER(WeaponMode, XMLPort, xmlelement, mode);
87
88        XMLPortParam(WeaponMode, "mode",             setMode,             getMode,             xmlelement, mode);
89
90        XMLPortParam(WeaponMode, "munitiontype",     setMunitionName,     getMunitionName,     xmlelement, mode);
91        XMLPortParam(WeaponMode, "initialmunition",  setInitialMunition,  getInitialMunition,  xmlelement, mode);
92        XMLPortParam(WeaponMode, "initialmagazines", setInitialMagazines, getInitialMagazines, xmlelement, mode);
93        XMLPortParam(WeaponMode, "munitionpershot",  setMunitionPerShot,  getMunitionPerShot,  xmlelement, mode);
94
95        XMLPortParam(WeaponMode, "reloadtime",       setReloadTime,       getReloadTime,       xmlelement, mode);
96        XMLPortParam(WeaponMode, "autoreload",       setAutoReload,       getAutoReload,       xmlelement, mode).description("If true, the weapon reloads the magazine automatically");
97        XMLPortParam(WeaponMode, "parallelreload",   setParallelReload,   getParallelReload,   xmlelement, mode).description("If true, the weapon reloads in parallel to the magazine reloading");
98
99        XMLPortParam(WeaponMode, "damage",           setDamage,           getDamage,           xmlelement, mode);
100        XMLPortParam(WeaponMode, "muzzleoffset",     setMuzzleOffset,     getMuzzleOffset,     xmlelement, mode);
101    }
102
103    bool WeaponMode::fire(float* reloadTime)
104    {
105        (*reloadTime) = this->reloadTime_;
106
107        if (!this->bReloading_ && this->munition_ && this->munition_->takeMunition(this->munitionPerShot_, this))
108        {
109            float reloadtime = this->reloadTime_;
110
111            if (this->bAutoReload_ && this->munition_->needReload(this))
112            {
113                if (this->munition_->reload(this))
114                {
115                    if (!this->bParallelReload_)
116                        reloadtime += this->munition_->getReloadTime();
117                }
118            }
119
120            this->bReloading_ = true;
121            this->reloadTimer_.setInterval(reloadtime);
122            this->reloadTimer_.startTimer();
123
124            assert( this->getWeapon() && this->getWeapon()->getWeaponPack() && this->getWeapon()->getWeaponPack()->getWeaponSystem() && this->getWeapon()->getWeaponPack()->getWeaponSystem()->getPawn() );
125            this->getWeapon()->getWeaponPack()->getWeaponSystem()->getPawn()->attach(this->defSndWpnFire_);
126            if(!(this->defSndWpnFire_->isPlaying()))
127            {
128                this->defSndWpnFire_->play();
129            }
130           
131            this->fire();
132
133            return true;
134        }
135        else
136        {
137            return false;
138        }
139    }
140
141    bool WeaponMode::reload()
142    {
143        if (this->munition_ && this->munition_->reload(this))
144        {
145            if (!this->bParallelReload_)
146            {
147                this->bReloading_ = true;
148                this->reloadTimer_.setInterval(this->reloadTime_ + this->munition_->getReloadTime());
149                this->reloadTimer_.startTimer();
150            }
151
152            return true;
153        }
154
155        return false;
156    }
157
158    void WeaponMode::setMunitionType(Identifier* identifier)
159    {
160        this->munitionname_ = identifier->getName();
161        this->munitiontype_ = identifier;
162        this->updateMunition();
163    }
164
165    void WeaponMode::setMunitionName(const std::string& munitionname)
166    {
167        this->munitionname_ = munitionname;
168        Identifier* identifier = ClassByString(this->munitionname_);
169        if (identifier)
170            this->munitiontype_ = identifier;
171        else
172            COUT(2) << "Warning: No munition class defined in WeaponMode " << this->getName() << std::endl;
173        this->updateMunition();
174    }
175
176    void WeaponMode::updateMunition()
177    {
178        if (this->munitiontype_ && this->weapon_ && this->weapon_->getWeaponPack() && this->weapon_->getWeaponPack()->getWeaponSystem())
179        {
180            this->munition_ = this->weapon_->getWeaponPack()->getWeaponSystem()->getMunition(&this->munitiontype_);
181
182            if (this->munition_)
183            {
184                // Add the initial magazines
185                this->munition_->addMagazines(this->initialMagazines_);
186
187                // Maybe we have to reload (if this munition is used the first time or if there weren't any magazines available before)
188                if (this->munition_->needReload(this))
189                    this->munition_->reload(this, false);
190
191                // Add the initial munition
192                if (this->initialMunition_ > 0 && this->munition_->getNumMunitionInCurrentMagazine(this) == this->munition_->getMaxMunitionPerMagazine())
193                {
194                    // The current magazine is still full, so let's just add another magazine to
195                    // the stack and reduce the current magazine to the given amount of munition
196
197                    unsigned int initialmunition = this->initialMunition_;
198                    if (initialmunition > this->munition_->getMaxMunitionPerMagazine())
199                        initialmunition = this->munition_->getMaxMunitionPerMagazine();
200
201                    this->munition_->takeMunition(this->munition_->getMaxMunitionPerMagazine() - initialmunition, this);
202                    this->munition_->addMagazines(1);
203                }
204                else
205                {
206                    // The current magazine isn't full, add the munition directly
207
208                    this->munition_->addMunition(this->initialMunition_);
209                }
210            }
211        }
212        else
213            this->munition_ = 0;
214    }
215
216    void WeaponMode::reloaded()
217    {
218        if(this->defSndWpnFire_->isPlaying())
219        {
220            this->defSndWpnFire_->stop();
221        }
222        this->bReloading_ = false;
223    }
224
225    void WeaponMode::computeMuzzleParameters(const Vector3& target)
226    {
227        if (this->weapon_)
228        {
229            this->muzzlePosition_ = this->weapon_->getWorldPosition() + this->weapon_->getWorldOrientation() * this->muzzleOffset_;
230
231            Vector3 muzzleDirection;
232            muzzleDirection = target - this->muzzlePosition_;
233//             COUT(0) << "muzzleDirection " << muzzleDirection << endl;
234            this->muzzleOrientation_ = (this->weapon_->getWorldOrientation() * WorldEntity::FRONT).getRotationTo(muzzleDirection) * this->weapon_->getWorldOrientation();
235        }
236        else
237        {
238            this->muzzlePosition_ = this->muzzleOffset_;
239            this->muzzleOrientation_ = Quaternion::IDENTITY;
240        }
241    }
242
243    Vector3 WeaponMode::getMuzzleDirection() const
244    {
245        if (this->weapon_)
246            return (this->getMuzzleOrientation() * WorldEntity::FRONT);
247        else
248            return WorldEntity::FRONT;
249    }
250
251    void WeaponMode::setDefaultSound(const std::string& soundPath)
252    {
253        this->defSndWpnFire_->setSource(soundPath);
254    }
255
256    const std::string& WeaponMode::getDefaultSound()
257    {
258        return this->defSndWpnFire_->getSource();
259    }
260}
Note: See TracBrowser for help on using the repository browser.