Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/orxonox/weaponsystem/WeaponMode.cc @ 8787

Last change on this file since 8787 was 8706, checked in by dafrick, 13 years ago

Merging presentation branch back into trunk.
There are many new features and also a lot of other changes and bugfixes, if you want to know, digg through the svn log.
Not everything is yet working as it should, but it should be fairly stable. If you habe any bug reports, just send me an email.

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