Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/weapons/src/orxonox/objects/weaponSystem/WeaponMode.cc @ 2918

Last change on this file since 2918 was 2918, checked in by landauf, 15 years ago

Added many new features in the Munition class:

  • there are now 3 modes: a) every weapon has it's own magazine b) all weapons use the same magazin c) no magazines, just a big munition pool
  • the Munition class handles the reloading of the magazine

Split the Weapon class into Weapon and WeaponMode. WeaponMode creates the fire of the Weapon. A weapon can own several WeaponModes (for example primary and secondary fire). But it's also possible to have a weapon with several muzzles which all fire at the same time (there's a WeaponMode for each muzzle).

Renamed LaserGun to LaserFire and Fusion to FusionFire. They inherit now from WeaponMode.

Changed the code in the Weapon class to use the new Munition functionality.

Added ReplenishingMunition, a subclass of Munition that replenishes itself (used for LaserGunMunition).

Added a reload command to reload magazines.

  • Property svn:eol-style set to native
File size: 12.5 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 "OrxonoxStableHeaders.h"
31#include "WeaponMode.h"
32
33#include "core/CoreIncludes.h"
34#include "core/XMLPort.h"
35
36#include "Munition.h"
37#include "Weapon.h"
38#include "WeaponPack.h"
39#include "WeaponSystem.h"
40
41namespace orxonox
42{
43    WeaponMode::WeaponMode(BaseObject* creator) : BaseObject(creator)
44    {
45        RegisterObject(WeaponMode);
46
47        this->weapon_ = 0;
48        this->mode_ = WeaponSystem::WEAPON_MODE_UNASSIGNED;
49
50        this->munition_ = 0;
51        this->initialMunition_ = 0;
52        this->initialMagazines_ = 0;
53        this->munitionPerShot_ = 1;
54
55        this->reloadTime_ = 0.25;
56        this->bReloading_ = false;
57        this->bAutoReload_ = true;
58        this->bParallelReload_ = true;
59
60        this->reloadTimer_.setTimer(0.0f, false, this, createExecutor(createFunctor(&WeaponMode::reloaded)));
61        this->reloadTimer_.stopTimer();
62
63        this->damage_ = 0;
64        this->muzzleOffset_ = Vector3::ZERO;
65
66COUT(0) << "+WeaponMode" << std::endl;
67    }
68
69    WeaponMode::~WeaponMode()
70    {
71COUT(0) << "~WeaponMode" << std::endl;
72    }
73
74    void WeaponMode::XMLPort(Element& xmlelement, XMLPort::Mode mode)
75    {
76        SUPER(WeaponMode, XMLPort, xmlelement, mode);
77
78        XMLPortParam(WeaponMode, "mode",             setMode,             getMode,             xmlelement, mode);
79
80        XMLPortParam(WeaponMode, "munitiontype",     setMunitionName,     getMunitionName,     xmlelement, mode);
81        XMLPortParam(WeaponMode, "initialmunition",  setInitialMunition,  getInitialMunition,  xmlelement, mode);
82        XMLPortParam(WeaponMode, "initialmagazines", setInitialMagazines, getInitialMagazines, xmlelement, mode);
83        XMLPortParam(WeaponMode, "munitionpershot",  setMunitionPerShot,  getMunitionPerShot,  xmlelement, mode);
84
85        XMLPortParam(WeaponMode, "reloadtime",       setReloadTime,       getReloadTime,       xmlelement, mode);
86        XMLPortParam(WeaponMode, "autoreload",       setAutoReload,       getAutoReload,       xmlelement, mode).description("If true, the weapon reloads the magazine automatically");
87        XMLPortParam(WeaponMode, "parallelreload",   setParallelReload,   getParallelReload,   xmlelement, mode).description("If true, the weapon reloads in parallel to the magazine reloading");
88
89        XMLPortParam(WeaponMode, "damage",           setDamage,           getDamage,           xmlelement, mode);
90        XMLPortParam(WeaponMode, "muzzleoffset",     setMuzzleOffset,     getMuzzleOffset,     xmlelement, mode);
91    }
92
93    bool WeaponMode::fire(float* reloadTime)
94    {
95        (*reloadTime) = this->reloadTime_;
96
97        if (!this->bReloading_ && this->munition_ && this->munition_->takeMunition(this->munitionPerShot_, this))
98        {
99            float reloadtime = this->reloadTime_;
100
101            if (this->bAutoReload_ && this->munition_->needReload(this))
102            {
103                if (this->munition_->reload(this))
104                {
105                    if (!this->bParallelReload_)
106                        reloadtime += this->munition_->getReloadTime();
107                }
108            }
109
110            this->bReloading_ = true;
111            this->reloadTimer_.setInterval(reloadtime);
112            this->reloadTimer_.startTimer();
113
114            this->fire();
115
116            return true;
117        }
118        else
119        {
120            return false;
121        }
122    }
123
124    bool WeaponMode::reload()
125    {
126        if (this->munition_ && this->munition_->reload(this))
127        {
128            if (!this->bParallelReload_)
129            {
130                this->bReloading_ = true;
131                this->reloadTimer_.setInterval(this->reloadTime_ + this->munition_->getReloadTime());
132                this->reloadTimer_.startTimer();
133            }
134
135            return true;
136        }
137
138        return false;
139    }
140
141    void WeaponMode::setMunitionType(Identifier* identifier)
142    {
143        this->munitionname_ = identifier->getName();
144        this->munitiontype_ = identifier;
145        this->updateMunition();
146    }
147
148    void WeaponMode::setMunitionName(const std::string& munitionname)
149    {
150        this->munitionname_ = munitionname;
151        this->munitiontype_ = ClassByString(this->munitionname_);
152        this->updateMunition();
153    }
154
155    void WeaponMode::updateMunition()
156    {
157        if (this->munitiontype_ && this->weapon_ && this->weapon_->getWeaponPack() && this->weapon_->getWeaponPack()->getWeaponSystem())
158        {
159            this->munition_ = this->weapon_->getWeaponPack()->getWeaponSystem()->getMunition(&this->munitiontype_);
160
161            if (this->munition_)
162            {
163                // Add the initial magazines
164                this->munition_->addMagazines(this->initialMagazines_);
165
166                // Maybe we have to reload (if this munition is used the first time or if there weren't any magazines available before)
167                if (this->munition_->needReload(this))
168                    this->munition_->reload(this, false);
169
170                // Add the initial munition
171                if (this->initialMunition_ > 0 && this->munition_->getNumMunitionInCurrentMagazine(this) == this->munition_->getMaxMunitionPerMagazine())
172                {
173                    // The current magazine is still full, so let's just add another magazine to
174                    // the stack and reduce the current magazine to the given amount of munition
175
176                    unsigned int initialmunition = this->initialMunition_;
177                    if (initialmunition > this->munition_->getMaxMunitionPerMagazine())
178                        initialmunition = this->munition_->getMaxMunitionPerMagazine();
179
180                    this->munition_->takeMunition(this->munition_->getMaxMunitionPerMagazine() - initialmunition, this);
181                    this->munition_->addMagazines(1);
182                }
183                else
184                {
185                    // The current magazine isn't full, add the munition directly
186
187                    this->munition_->addMunition(this->initialMunition_);
188                }
189            }
190        }
191        else
192            this->munition_ = 0;
193    }
194
195    void WeaponMode::reloaded()
196    {
197        this->bReloading_ = false;
198    }
199
200    Vector3 WeaponMode::getMuzzlePosition() const
201    {
202        if (this->weapon_)
203            return (this->weapon_->getWorldPosition() + this->muzzleOffset_);
204        else
205            return this->muzzleOffset_;
206    }
207
208    const Quaternion& WeaponMode::getMuzzleOrientation() const
209    {
210        if (this->weapon_)
211            return this->weapon_->getWorldOrientation();
212        else
213            return Quaternion::IDENTITY;
214    }
215
216    Vector3 WeaponMode::getMuzzleDirection() const
217    {
218        if (this->weapon_)
219            return (this->weapon_->getWorldOrientation() * WorldEntity::FRONT);
220        else
221            return WorldEntity::FRONT;
222    }
223
224/*
225    WeaponMode::WeaponMode(BaseObject* creator) : StaticEntity(creator)
226    {
227        RegisterObject(WeaponMode);
228
229        this->bulletReadyToShoot_ = true;
230        this->magazineReadyToShoot_ = true;
231        this->weaponSystem_ = 0;
232        this->weaponPack_ = 0;
233        this->weaponSlot_ = 0;
234        this->bulletLoadingTime_ = 0;
235        this->magazineLoadingTime_ = 0;
236        this->bReloading_ = false;
237        this->bulletAmount_= 0;
238        this->magazineAmount_ = 0;
239        this->munition_ = 0;
240        this->unlimitedMunition_ = false;
241        this->setObjectMode(0x0);
242COUT(0) << "+WeaponMode" << std::endl;
243    }
244
245    WeaponMode::~WeaponMode()
246    {
247COUT(0) << "~WeaponMode" << std::endl;
248        if (this->isInitialized() && this->weaponPack_)
249            this->weaponPack_->removeWeapon(this);
250    }
251
252    void WeaponMode::XMLPort(Element& xmlelement, XMLPort::Mode mode)
253    {
254        SUPER(WeaponMode, XMLPort, xmlelement, mode);
255
256        XMLPortParam(WeaponMode, "munitionType", setMunitionType, getMunitionType, xmlelement, mode);
257        XMLPortParam(WeaponMode, "bulletLoadingTime", setBulletLoadingTime, getBulletLoadingTime, xmlelement, mode);
258        XMLPortParam(WeaponMode, "magazineLoadingTime", setMagazineLoadingTime, getMagazineLoadingTime, xmlelement, mode);
259        XMLPortParam(WeaponMode, "bullets", setBulletAmount, getBulletAmount, xmlelement, mode);
260        XMLPortParam(WeaponMode, "magazines", setMagazineAmount, getMagazineAmount, xmlelement, mode);
261        XMLPortParam(WeaponMode, "unlimitedMunition", setUnlimitedMunition, getUnlimitedMunition, xmlelement, mode);
262    }
263
264    void WeaponMode::setWeapon()
265    {
266        this->munition_->fillBullets();
267        this->munition_->fillMagazines();
268    }
269
270    void WeaponMode::setMunition()
271    {
272        this->munition_->setMaxBullets(this->bulletAmount_);
273        this->munition_->setMaxMagazines(this->magazineAmount_);
274    }
275
276    void WeaponMode::fire()
277    {
278        if ( this->bulletReadyToShoot_ && this->magazineReadyToShoot_ && !this->bReloading_)
279        {
280            this->bulletReadyToShoot_ = false;
281            if ( this->unlimitedMunition_== true )
282            {
283                //shoot
284                this->reloadBullet();
285                this->createProjectile();
286            }
287            else
288            {
289                if ( this->munition_->bullets() > 0)
290                {
291                    //shoot and reload
292                    this->takeBullets();
293                    this->reloadBullet();
294                    this->createProjectile();
295                }
296                //if there are no bullets, but magazines
297                else if ( this->munition_->magazines() > 0 && this->munition_->bullets() == 0 )
298                {
299                    //reload magazine
300                    this->takeMagazines();
301                    this->reloadMagazine();
302                }
303                else
304                {
305                    //no magazines
306                }
307            }
308        }
309        else
310        {
311            //weapon not reloaded
312        }
313    }
314
315
316    //weapon reloading
317    void WeaponMode::bulletTimer(float bulletLoadingTime)
318    {
319        this->bReloading_ = true;
320        this->bulletReloadTimer_.setTimer( bulletLoadingTime , false , this , createExecutor(createFunctor(&WeaponMode::bulletReloaded)));
321    }
322    void WeaponMode::magazineTimer(float magazineLoadingTime)
323    {
324        this->bReloading_ = true;
325        this->magazineReloadTimer_.setTimer( magazineLoadingTime , false , this , createExecutor(createFunctor(&WeaponMode::magazineReloaded)));
326    }
327
328    void WeaponMode::bulletReloaded()
329    {
330        this->bReloading_ = false;
331        this->bulletReadyToShoot_ = true;
332    }
333
334    void WeaponMode::magazineReloaded()
335    {
336        this->bReloading_ = false;
337        this->munition_->fillBullets();
338    }
339
340
341
342    void WeaponMode::attachNeededMunition(const std::string& munitionName)
343    {
344        //  if munition type already exists attach it, else create a new one of this type and attach it to the weapon and to the WeaponSystem
345        if (this->weaponSystem_)
346        {
347            //getMunitionType returns 0 if there is no such munitionType
348            Munition* munition = this->weaponSystem_->getMunitionType(munitionName);
349            if ( munition )
350            {
351                this->munition_ = munition;
352                this->setMunition();
353            }
354            else
355            {
356                //create new munition with identifier because there is no such munitionType
357                this->munitionIdentifier_ = ClassByString(munitionName);
358                this->munition_ = this->munitionIdentifier_.fabricate(this);
359                this->weaponSystem_->setNewMunition(munitionName, this->munition_);
360                this->setMunition();
361            }
362        }
363    }
364
365
366    Munition * WeaponMode::getAttachedMunition(const std::string& munitionType)
367    {
368        this->munition_ = this->weaponSystem_->getMunitionType(munitionType);
369        return this->munition_;
370    }
371*/
372}
Note: See TracBrowser for help on using the repository browser.