Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/steering/src/orxonox/weaponsystem/WeaponMode.cc @ 6182

Last change on this file since 6182 was 6058, checked in by rgrieder, 15 years ago

Found the firing direction bug: "Fixed goes first" we were told a few weeks ago in a lecture about spatial coordinates.
Here the problem was a quaternion multiplication.

  • Property svn:eol-style set to native
File size: 8.1 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
42namespace orxonox
43{
44    WeaponMode::WeaponMode(BaseObject* creator) : BaseObject(creator)
45    {
46        RegisterObject(WeaponMode);
47
48        this->weapon_ = 0;
49        this->mode_ = WeaponSystem::WEAPON_MODE_UNASSIGNED;
50
51        this->munition_ = 0;
52        this->initialMunition_ = 0;
53        this->initialMagazines_ = 0;
54        this->munitionPerShot_ = 1;
55
56        this->reloadTime_ = 0.25;
57        this->bReloading_ = false;
58        this->bAutoReload_ = true;
59        this->bParallelReload_ = true;
60
61        this->reloadTimer_.setTimer(0.0f, false, createExecutor(createFunctor(&WeaponMode::reloaded, this)));
62        this->reloadTimer_.stopTimer();
63
64        this->damage_ = 0;
65        this->muzzleOffset_ = Vector3::ZERO;
66    }
67
68    WeaponMode::~WeaponMode()
69    {
70    }
71
72    void WeaponMode::XMLPort(Element& xmlelement, XMLPort::Mode mode)
73    {
74        SUPER(WeaponMode, XMLPort, xmlelement, mode);
75
76        XMLPortParam(WeaponMode, "mode",             setMode,             getMode,             xmlelement, mode);
77
78        XMLPortParam(WeaponMode, "munitiontype",     setMunitionName,     getMunitionName,     xmlelement, mode);
79        XMLPortParam(WeaponMode, "initialmunition",  setInitialMunition,  getInitialMunition,  xmlelement, mode);
80        XMLPortParam(WeaponMode, "initialmagazines", setInitialMagazines, getInitialMagazines, xmlelement, mode);
81        XMLPortParam(WeaponMode, "munitionpershot",  setMunitionPerShot,  getMunitionPerShot,  xmlelement, mode);
82
83        XMLPortParam(WeaponMode, "reloadtime",       setReloadTime,       getReloadTime,       xmlelement, mode);
84        XMLPortParam(WeaponMode, "autoreload",       setAutoReload,       getAutoReload,       xmlelement, mode).description("If true, the weapon reloads the magazine automatically");
85        XMLPortParam(WeaponMode, "parallelreload",   setParallelReload,   getParallelReload,   xmlelement, mode).description("If true, the weapon reloads in parallel to the magazine reloading");
86
87        XMLPortParam(WeaponMode, "damage",           setDamage,           getDamage,           xmlelement, mode);
88        XMLPortParam(WeaponMode, "muzzleoffset",     setMuzzleOffset,     getMuzzleOffset,     xmlelement, mode);
89    }
90
91    bool WeaponMode::fire(float* reloadTime)
92    {
93        (*reloadTime) = this->reloadTime_;
94
95        if (!this->bReloading_ && this->munition_ && this->munition_->takeMunition(this->munitionPerShot_, this))
96        {
97            float reloadtime = this->reloadTime_;
98
99            if (this->bAutoReload_ && this->munition_->needReload(this))
100            {
101                if (this->munition_->reload(this))
102                {
103                    if (!this->bParallelReload_)
104                        reloadtime += this->munition_->getReloadTime();
105                }
106            }
107
108            this->bReloading_ = true;
109            this->reloadTimer_.setInterval(reloadtime);
110            this->reloadTimer_.startTimer();
111
112            this->fire();
113
114            return true;
115        }
116        else
117        {
118            return false;
119        }
120    }
121
122    bool WeaponMode::reload()
123    {
124        if (this->munition_ && this->munition_->reload(this))
125        {
126            if (!this->bParallelReload_)
127            {
128                this->bReloading_ = true;
129                this->reloadTimer_.setInterval(this->reloadTime_ + this->munition_->getReloadTime());
130                this->reloadTimer_.startTimer();
131            }
132
133            return true;
134        }
135
136        return false;
137    }
138
139    void WeaponMode::setMunitionType(Identifier* identifier)
140    {
141        this->munitionname_ = identifier->getName();
142        this->munitiontype_ = identifier;
143        this->updateMunition();
144    }
145
146    void WeaponMode::setMunitionName(const std::string& munitionname)
147    {
148        this->munitionname_ = munitionname;
149        this->munitiontype_ = ClassByString(this->munitionname_);
150        this->updateMunition();
151    }
152
153    void WeaponMode::updateMunition()
154    {
155        if (this->munitiontype_ && this->weapon_ && this->weapon_->getWeaponPack() && this->weapon_->getWeaponPack()->getWeaponSystem())
156        {
157            this->munition_ = this->weapon_->getWeaponPack()->getWeaponSystem()->getMunition(&this->munitiontype_);
158
159            if (this->munition_)
160            {
161                // Add the initial magazines
162                this->munition_->addMagazines(this->initialMagazines_);
163
164                // Maybe we have to reload (if this munition is used the first time or if there weren't any magazines available before)
165                if (this->munition_->needReload(this))
166                    this->munition_->reload(this, false);
167
168                // Add the initial munition
169                if (this->initialMunition_ > 0 && this->munition_->getNumMunitionInCurrentMagazine(this) == this->munition_->getMaxMunitionPerMagazine())
170                {
171                    // The current magazine is still full, so let's just add another magazine to
172                    // the stack and reduce the current magazine to the given amount of munition
173
174                    unsigned int initialmunition = this->initialMunition_;
175                    if (initialmunition > this->munition_->getMaxMunitionPerMagazine())
176                        initialmunition = this->munition_->getMaxMunitionPerMagazine();
177
178                    this->munition_->takeMunition(this->munition_->getMaxMunitionPerMagazine() - initialmunition, this);
179                    this->munition_->addMagazines(1);
180                }
181                else
182                {
183                    // The current magazine isn't full, add the munition directly
184
185                    this->munition_->addMunition(this->initialMunition_);
186                }
187            }
188        }
189        else
190            this->munition_ = 0;
191    }
192
193    void WeaponMode::reloaded()
194    {
195        this->bReloading_ = false;
196    }
197
198    void WeaponMode::computeMuzzleParameters()
199    {
200        if (this->weapon_)
201        {
202            this->muzzlePosition_ = this->weapon_->getWorldPosition() + this->weapon_->getWorldOrientation() * this->muzzleOffset_;
203
204            Controller* controller = this->getWeapon()->getWeaponPack()->getWeaponSystem()->getPawn()->getController();
205            if (controller->canFindTarget())
206            {
207                Vector3 muzzleDirection(controller->getTarget() - this->muzzlePosition_);
208                this->muzzleOrientation_ = (this->weapon_->getWorldOrientation() * WorldEntity::FRONT).getRotationTo(muzzleDirection) * this->weapon_->getWorldOrientation();
209            }
210            else
211                this->muzzleOrientation_ = this->weapon_->getWorldOrientation();
212        }
213        else
214        {
215            this->muzzlePosition_ = this->muzzleOffset_;
216            this->muzzleOrientation_ = Quaternion::IDENTITY;
217        }
218    }
219
220    Vector3 WeaponMode::getMuzzleDirection() const
221    {
222        if (this->weapon_)
223            return (this->getMuzzleOrientation() * WorldEntity::FRONT);
224        else
225            return WorldEntity::FRONT;
226    }
227}
Note: See TracBrowser for help on using the repository browser.