Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/orxonox/objects/weaponsystem/WeaponSystem.cc @ 3053

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

merged weapons branch back to trunk

  • Property svn:eol-style set to native
File size: 9.4 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 "OrxonoxStableHeaders.h"
30#include "WeaponSystem.h"
31
32#include "core/CoreIncludes.h"
33#include "objects/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    CreateFactory(WeaponSystem);
49
50    WeaponSystem::WeaponSystem(BaseObject* creator) : BaseObject(creator)
51    {
52        RegisterObject(WeaponSystem);
53
54        this->pawn_ = 0;
55    }
56
57    WeaponSystem::~WeaponSystem()
58    {
59        if (this->isInitialized())
60        {
61            if (this->pawn_)
62                this->pawn_->setWeaponSystem(0);
63
64            while (!this->weaponSets_.empty())
65                delete (this->weaponSets_.begin()->second);
66
67            while (!this->weaponPacks_.empty())
68                delete (*this->weaponPacks_.begin());
69
70            while (!this->weaponSlots_.empty())
71                delete (*this->weaponSlots_.begin());
72
73            while (!this->munitions_.empty())
74                { delete (this->munitions_.begin()->second); 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 (std::vector<WeaponSlot*>::const_iterator it = this->weaponSlots_.begin(); it != this->weaponSlots_.end(); ++it)
109        {
110            ++i;
111            if (i > index)
112                return (*it);
113        }
114        return 0;
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 (std::map<unsigned int, WeaponSet*>::const_iterator it = this->weaponSets_.begin(); it != this->weaponSets_.end(); ++it)
156        {
157            ++i;
158            if (i > index)
159                return it->second;
160        }
161        return 0;
162    }
163
164    bool WeaponSystem::canAddWeaponPack(WeaponPack * wPack)
165    {
166        if (!wPack)
167            return false;
168
169        unsigned int freeSlots = 0;
170        for (std::vector<WeaponSlot*>::iterator it = this->weaponSlots_.begin(); it != this->weaponSlots_.end(); ++it)
171        {
172            if (!(*it)->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 (std::vector<WeaponSlot*>::iterator it = this->weaponSlots_.begin(); it != this->weaponSlots_.end(); ++it)
187        {
188            if (!(*it)->isOccupied() && i < wPack->getNumWeapons())
189            {
190                Weapon* weapon = wPack->getWeapon(i);
191                (*it)->attachWeapon(weapon);
192                this->getPawn()->attach(weapon);
193                ++i;
194            }
195        }
196
197        // Assign the desired weaponmode to the firemodes
198        for (std::map<unsigned int, WeaponSet *>::iterator it = this->weaponSets_.begin(); it != this->weaponSets_.end(); ++it)
199        {
200            unsigned int weaponmode = wPack->getDesiredWeaponmode(it->first);
201            if (weaponmode != WeaponSystem::WEAPON_MODE_UNASSIGNED)
202                it->second->setWeaponmodeLink(wPack, weaponmode);
203        }
204
205        this->weaponPacks_.insert(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 = 0;
216        while (weapon = wPack->getWeapon(i++))
217            weapon->getWeaponSlot()->removeWeapon();
218
219        // Remove all added links from the WeaponSets
220        for (std::map<unsigned int, WeaponSet *>::iterator it = this->weaponSets_.begin(); it != this->weaponSets_.end(); ++it)
221            it->second->removeWeaponmodeLink(wPack);
222
223        // Remove the WeaponPack from the WeaponSystem
224        this->weaponPacks_.erase(wPack);
225    }
226
227    WeaponPack * WeaponSystem::getWeaponPack(unsigned int index) const
228    {
229        unsigned int i = 0;
230        for (std::set<WeaponPack*>::const_iterator it = this->weaponPacks_.begin(); it != this->weaponPacks_.end(); ++it)
231        {
232            ++i;
233            if (i > index)
234                return (*it);
235        }
236        return 0;
237    }
238
239    bool WeaponSystem::swapWeaponSlots(WeaponSlot * wSlot1, WeaponSlot * wSlot2)
240    {
241        if (!wSlot1 || !wSlot2)
242            return false;
243
244        Weapon* weapon1 = wSlot1->getWeapon();
245        Weapon* weapon2 = wSlot2->getWeapon();
246
247        wSlot1->attachWeapon(weapon2);
248        wSlot2->attachWeapon(weapon1);
249
250        return true;
251        // In the future, certain weapons might not fit to some slots. Swapping would then be
252        // impossible and the returnvalue would be false.
253    }
254
255    void WeaponSystem::changeWeaponmode(WeaponPack * wPack, WeaponSet * wSet, unsigned int weaponmode)
256    {
257        if (!wPack || !wSet)
258            return;
259
260        // Check if the WeaponPack belongs to this WeaponSystem
261        std::set<WeaponPack *>::iterator it1 = this->weaponPacks_.find(wPack);
262        if (it1 == this->weaponPacks_.end())
263            return;
264
265        // Check if the WeaponSet belongs to this WeaponSystem
266        bool foundWeaponSet = false;
267        for (std::map<unsigned int, WeaponSet *>::iterator it2 = this->weaponSets_.begin(); it2 != this->weaponSets_.end(); ++it2)
268        {
269            if (it2->second == wSet)
270            {
271                foundWeaponSet = true;
272                break;
273            }
274        }
275        if (!foundWeaponSet)
276            return;
277
278        // Finally set the link between firemode and weaponmode
279        wSet->setWeaponmodeLink(wPack, weaponmode);
280    }
281
282    void WeaponSystem::fire(unsigned int firemode)
283    {
284        std::map<unsigned int, WeaponSet *>::iterator it = this->weaponSets_.find(firemode);
285        if (it != this->weaponSets_.end() && it->second)
286            it->second->fire();
287    }
288
289    void WeaponSystem::reload()
290    {
291        for (std::map<unsigned int, WeaponSet *>::iterator it = this->weaponSets_.begin(); it != this->weaponSets_.end(); ++it)
292            it->second->reload();
293    }
294
295    Munition * WeaponSystem::getMunition(SubclassIdentifier<Munition> * identifier)
296    {
297        if (!identifier || !identifier->getIdentifier())
298            return 0;
299
300        std::map<Identifier *, Munition *>::iterator it = this->munitions_.find(identifier->getIdentifier());
301        if (it != this->munitions_.end())
302        {
303            return it->second;
304        }
305        else if (identifier->getIdentifier()->isA(Class(Munition)))
306        {
307            Munition* munition = identifier->fabricate(this);
308            this->munitions_[identifier->getIdentifier()] = munition;
309            return munition;
310        }
311        else
312        {
313            return 0;
314        }
315    }
316}
Note: See TracBrowser for help on using the repository browser.