Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 6112 was 6112, checked in by scheusso, 14 years ago

first attempts to have synchronised fire direction and target
however client cannot select targets yet (probably because of classtreemask hack)

  • 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            Pawn* pawn = this->getWeapon()->getWeaponPack()->getWeaponSystem()->getPawn();
205            Vector3 muzzleDirection;
206            if ( pawn->getTarget() )
207            {
208                muzzleDirection = pawn->getTarget()->getWorldPosition() - this->muzzlePosition_;
209            }
210            else
211                muzzleDirection = pawn->getAimPosition() - this->muzzlePosition_;
212//             COUT(0) << "muzzleDirection " << muzzleDirection << endl;
213            this->muzzleOrientation_ = (this->weapon_->getWorldOrientation() * WorldEntity::FRONT).getRotationTo(muzzleDirection) * this->weapon_->getWorldOrientation();
214        }
215        else
216        {
217            this->muzzlePosition_ = this->muzzleOffset_;
218            this->muzzleOrientation_ = Quaternion::IDENTITY;
219        }
220    }
221
222    Vector3 WeaponMode::getMuzzleDirection() const
223    {
224        if (this->weapon_)
225            return (this->getMuzzleOrientation() * WorldEntity::FRONT);
226        else
227            return WorldEntity::FRONT;
228    }
229}
Note: See TracBrowser for help on using the repository browser.