Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/cpp11_v2/src/orxonox/weaponsystem/Weapon.cc @ 10916

Last change on this file since 10916 was 10916, checked in by landauf, 10 years ago

use actual types instead of 'auto'. only exception is for complicated template types, e.g. when iterating over a map

  • Property svn:eol-style set to native
File size: 4.6 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 "Weapon.h"
31
32#include "core/CoreIncludes.h"
33#include "core/XMLPort.h"
34
35#include "WeaponMode.h"
36#include "WeaponPack.h"
37#include "WeaponSystem.h"
38
39namespace orxonox
40{
41    RegisterClass(Weapon);
42
43    Weapon::Weapon(Context* context) : StaticEntity(context)
44    {
45        RegisterObject(Weapon);
46
47        this->weaponPack_ = nullptr;
48        this->weaponSlot_ = nullptr;
49        this->bReloading_ = false;
50        this->reloadingWeaponmode_ = WeaponSystem::WEAPON_MODE_UNASSIGNED;
51
52        this->reloadTimer_.setTimer(0.0f, false, createExecutor(createFunctor(&Weapon::reloaded, this)));
53        this->reloadTimer_.stopTimer();
54    }
55
56    Weapon::~Weapon()
57    {
58        if (this->isInitialized())
59        {
60            if (this->weaponPack_)
61                this->weaponPack_->removeWeapon(this);
62
63            for (auto& mapEntry : this->weaponmodes_)
64                mapEntry.second->destroy();
65        }
66    }
67
68    void Weapon::XMLPort(Element& xmlelement, XMLPort::Mode mode)
69    {
70        SUPER(Weapon, XMLPort, xmlelement, mode);
71
72        XMLPortObject(Weapon, WeaponMode, "", addWeaponmode, getWeaponmode, xmlelement, mode);
73    }
74
75    void Weapon::addWeaponmode(WeaponMode* weaponmode)
76    {
77        if (!weaponmode)
78            return;
79
80        this->weaponmodes_.insert(std::pair<unsigned int, WeaponMode*>(weaponmode->getMode(), weaponmode));
81        weaponmode->setWeapon(this);
82    }
83
84    WeaponMode* Weapon::getWeaponmode(unsigned int index) const
85    {
86        unsigned int i = 0;
87        for (const auto& mapEntry : this->weaponmodes_)
88        {
89            if (i == index)
90                return mapEntry.second;
91
92            ++i;
93        }
94        return nullptr;
95    }
96
97    /**
98    @brief
99        Fire this Weapon with the the WeaponMode defined by @param mode
100    */
101    void Weapon::fire(unsigned int mode)
102    {
103        // To avoid firing with more than one mode at the same time, we lock the weapon (reloading) for
104        // all modes except the one which is currently reloading.
105        //
106        // Example:
107        // WeaponMode A -> mode 0
108        // WeaponMode B -> mode 0
109        // WeaponMode C -> mode 1
110        //
111        // -> A and B can fire at the same time, but C has to wait until both (A and B) have reloaded
112        // -> If C fires, A and B have to wait until C has reloaded
113        //
114        // Note: The reloading of each WeaponMode is internally handled by each A, B and C.
115        //       The reloading of the weapon is only performed to avoid firing with different modes at the same time.
116        if (this->bReloading_ && this->reloadingWeaponmode_ != mode)
117            return;
118
119        std::multimap<unsigned int, WeaponMode*>::iterator start = this->weaponmodes_.lower_bound(mode);
120        std::multimap<unsigned int, WeaponMode*>::iterator end   = this->weaponmodes_.upper_bound(mode);
121
122        for (std::multimap<unsigned int, WeaponMode*>::iterator it = start; it != end; ++it)
123        {
124            float reloading_time = 0;
125            if (it->second->fire(&reloading_time))
126            {
127                this->bReloading_ = true;
128                this->reloadingWeaponmode_ = mode;
129
130                this->reloadTimer_.setInterval(reloading_time);
131                this->reloadTimer_.startTimer();
132            }
133        }
134    }
135
136    void Weapon::reload()
137    {
138        for (auto& mapEntry : this->weaponmodes_)
139            mapEntry.second->reload();
140    }
141
142    void Weapon::reloaded()
143    {
144        this->bReloading_ = false;
145        this->reloadingWeaponmode_ = WeaponSystem::WEAPON_MODE_UNASSIGNED;
146    }
147
148    void Weapon::notifyWeaponModes()
149    {
150        for (auto& mapEntry : this->weaponmodes_)
151            mapEntry.second->setWeapon(this);
152    }
153}
Note: See TracBrowser for help on using the repository browser.