Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/cpp11_v2/src/orxonox/weaponsystem/WeaponSystem.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: 9.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 *   Co-authors:
25 *      ...
26 *
27 */
28
29#include "WeaponSystem.h"
30
31#include "core/CoreIncludes.h"
32#include "core/class/SubclassIdentifier.h"
33#include "worldentities/pawns/Pawn.h"
34
35#include "WeaponSlot.h"
36#include "WeaponPack.h"
37#include "WeaponSet.h"
38#include "Weapon.h"
39#include "Munition.h"
40
41/* WeaponSystem
42 *
43 *  www.orxonox.net/wiki/WeaponSystem
44 */
45
46namespace orxonox
47{
48    RegisterClass(WeaponSystem);
49
50    WeaponSystem::WeaponSystem(Context* context) : BaseObject(context)
51    {
52        RegisterObject(WeaponSystem);
53
54        this->pawn_ = nullptr;
55    }
56
57    WeaponSystem::~WeaponSystem()
58    {
59        if (this->isInitialized())
60        {
61            if (this->pawn_)
62                this->pawn_->setWeaponSystem(nullptr);
63
64            while (!this->weaponSets_.empty())
65                this->weaponSets_.begin()->second->destroy();
66
67            while (!this->weaponPacks_.empty())
68                (*this->weaponPacks_.begin())->destroy();
69
70            while (!this->weaponSlots_.empty())
71                (*this->weaponSlots_.begin())->destroy();
72
73            while (!this->munitions_.empty())
74                { this->munitions_.begin()->second->destroy(); this->munitions_.erase(this->munitions_.begin()); }
75        }
76    }
77
78    void WeaponSystem::addWeaponSlot(WeaponSlot * wSlot)
79    {
80        if (!wSlot)
81            return;
82
83        this->weaponSlots_.push_back(wSlot);
84        wSlot->setWeaponSystem(this);
85    }
86
87    void WeaponSystem::removeWeaponSlot(WeaponSlot * wSlot)
88    {
89        if (!wSlot)
90            return;
91
92        if (wSlot->getWeapon())
93            this->removeWeaponPack(wSlot->getWeapon()->getWeaponPack());
94
95        for (std::vector<WeaponSlot*>::iterator it = this->weaponSlots_.begin(); it != this->weaponSlots_.end(); ++it)
96        {
97            if ((*it) == wSlot)
98            {
99                this->weaponSlots_.erase(it);
100                break;
101            }
102        }
103    }
104
105    WeaponSlot * WeaponSystem::getWeaponSlot(unsigned int index) const
106    {
107        unsigned int i = 0;
108        for (WeaponSlot* weaponSlot : this->weaponSlots_)
109        {
110            ++i;
111            if (i > index)
112                return weaponSlot;
113        }
114        return nullptr;
115    }
116
117    bool WeaponSystem::addWeaponSet(WeaponSet * wSet)
118    {
119        if (wSet)
120            return this->addWeaponSet(wSet, wSet->getDesiredFiremode());
121        else
122            return false;
123    }
124
125    bool WeaponSystem::addWeaponSet(WeaponSet * wSet, unsigned int firemode)
126    {
127        if (!wSet || firemode >= WeaponSystem::MAX_FIRE_MODES)
128            return false;
129
130        std::map<unsigned int, WeaponSet*>::const_iterator it = this->weaponSets_.find(firemode);
131        if (it == this->weaponSets_.end())
132        {
133            this->weaponSets_[firemode] = wSet;
134            wSet->setWeaponSystem(this);
135            return true;
136        }
137
138        return false;
139    }
140
141    void WeaponSystem::removeWeaponSet(WeaponSet * wSet)
142    {
143        for (std::map<unsigned int, WeaponSet*>::iterator it = this->weaponSets_.begin(); it != this->weaponSets_.end(); )
144        {
145            if (it->second == wSet)
146                this->weaponSets_.erase(it++);
147            else
148                ++it;
149        }
150    }
151
152    WeaponSet * WeaponSystem::getWeaponSet(unsigned int index) const
153    {
154        unsigned int i = 0;
155        for (const auto& mapEntry : this->weaponSets_)
156        {
157            ++i;
158            if (i > index)
159                return mapEntry.second;
160        }
161        return nullptr;
162    }
163
164    bool WeaponSystem::canAddWeaponPack(WeaponPack * wPack)
165    {
166        if (!wPack)
167            return false;
168
169        unsigned int freeSlots = 0;
170        for (WeaponSlot* weaponSlot : this->weaponSlots_)
171        {
172            if (!weaponSlot->isOccupied())
173                ++freeSlots;
174        }
175
176        return (freeSlots >= wPack->getNumWeapons());
177    }
178
179    bool WeaponSystem::addWeaponPack(WeaponPack * wPack)
180    {
181        if (!this->canAddWeaponPack(wPack))
182            return false;
183
184        // Attach all weapons to the first free slots (and to the Pawn)
185        unsigned int i = 0;
186        for (WeaponSlot* weaponSlot : this->weaponSlots_)
187        {
188            if (!weaponSlot->isOccupied() && i < wPack->getNumWeapons())
189            {
190                Weapon* weapon = wPack->getWeapon(i);
191                weaponSlot->attachWeapon(weapon);
192                this->getPawn()->attach(weapon);
193                ++i;
194            }
195        }
196
197        // Assign the desired weaponmode to the firemodes
198        for (auto& mapEntry : this->weaponSets_)
199        {
200            unsigned int weaponmode = wPack->getDesiredWeaponmode(mapEntry.first);
201            if (weaponmode != WeaponSystem::WEAPON_MODE_UNASSIGNED)
202                mapEntry.second->setWeaponmodeLink(wPack, weaponmode);
203        }
204
205        this->weaponPacks_.push_back(wPack);
206        wPack->setWeaponSystem(this);
207
208        return true;
209    }
210
211    void WeaponSystem::removeWeaponPack(WeaponPack * wPack)
212    {
213        // Remove all weapons from their WeaponSlot
214        unsigned int i = 0;
215        Weapon* weapon = nullptr;
216        while ((weapon = wPack->getWeapon(i++)))
217            if (weapon->getWeaponSlot())
218                weapon->getWeaponSlot()->removeWeapon();
219
220        // Remove all added links from the WeaponSets
221        for (auto& mapEntry : this->weaponSets_)
222            mapEntry.second->removeWeaponmodeLink(wPack);
223
224        // Remove the WeaponPack from the WeaponSystem
225        std::vector<WeaponPack*>::iterator it2 = std::find(this->weaponPacks_.begin(),this->weaponPacks_.end(), wPack);
226        assert(it2 !=this->weaponPacks_.end());
227        this->weaponPacks_.erase(it2);
228    }
229
230    WeaponPack * WeaponSystem::getWeaponPack(unsigned int index) const
231    {
232        unsigned int i = 0;
233        for (WeaponPack* weaponPack : this->weaponPacks_)
234        {
235            ++i;
236            if (i > index)
237                return weaponPack;
238        }
239        return nullptr;
240    }
241
242    bool WeaponSystem::swapWeaponSlots(WeaponSlot * wSlot1, WeaponSlot * wSlot2)
243    {
244        if (!wSlot1 || !wSlot2)
245            return false;
246
247        Weapon* weapon1 = wSlot1->getWeapon();
248        Weapon* weapon2 = wSlot2->getWeapon();
249
250        wSlot1->attachWeapon(weapon2);
251        wSlot2->attachWeapon(weapon1);
252
253        return true;
254        // In the future, certain weapons might not fit to some slots. Swapping would then be
255        // impossible and the returnvalue would be false.
256    }
257
258    void WeaponSystem::changeWeaponmode(WeaponPack * wPack, WeaponSet * wSet, unsigned int weaponmode)
259    {
260        if (!wPack || !wSet)
261            return;
262
263        // Check if the WeaponPack belongs to this WeaponSystem
264        std::vector<WeaponPack *>::iterator it1 = std::find( this->weaponPacks_.begin(), this->weaponPacks_.end(), wPack );
265        if (it1 == this->weaponPacks_.end())
266            return;
267
268        // Check if the WeaponSet belongs to this WeaponSystem
269        bool foundWeaponSet = false;
270        for (auto& mapEntry : this->weaponSets_)
271        {
272            if (mapEntry.second == wSet)
273            {
274                foundWeaponSet = true;
275                break;
276            }
277        }
278        if (!foundWeaponSet)
279            return;
280
281        // Finally set the link between firemode and weaponmode
282        wSet->setWeaponmodeLink(wPack, weaponmode);
283    }
284
285    /**
286    @brief
287        Fires the @ref Orxonox::WeaponSet with the specified firemode.
288    */
289    void WeaponSystem::fire(unsigned int firemode)
290    {
291        std::map<unsigned int, WeaponSet *>::iterator it = this->weaponSets_.find(firemode);
292        if (it != this->weaponSets_.end() && it->second)
293            it->second->fire();
294    }
295
296    void WeaponSystem::reload()
297    {
298        for (auto& mapEntry : this->weaponSets_)
299            mapEntry.second->reload();
300    }
301
302    Munition * WeaponSystem::getMunition(SubclassIdentifier<Munition> * identifier)
303    {
304        if (!identifier || !identifier->getIdentifier())
305            return nullptr;
306
307        std::map<Identifier *, Munition *>::iterator it = this->munitions_.find(identifier->getIdentifier());
308        if (it != this->munitions_.end())
309        {
310            return it->second;
311        }
312        else if (identifier->getIdentifier()->isA(Class(Munition)))
313        {
314            Munition* munition = identifier->fabricate(this->getContext());
315            this->munitions_[identifier->getIdentifier()] = munition;
316            return munition;
317        }
318        else
319        {
320            return nullptr;
321        }
322    }
323}
Note: See TracBrowser for help on using the repository browser.