Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/orxonox/objects/pickup/PickupCollection.cc @ 3132

Last change on this file since 3132 was 3079, checked in by landauf, 16 years ago

Added forward declarations to OrxonoxPrereqs.h.

  • Property svn:eol-style set to native
File size: 12.8 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 *      Daniel 'Huty' Haggenmueller
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29/**
30    @file
31    @brief Implementation of PickupCollection.
32*/
33
34#include "PickupCollection.h"
35
36#include "BaseItem.h"
37#include "EquipmentItem.h"
38#include "PassiveItem.h"
39#include "UsableItem.h"
40
41#include "core/CoreIncludes.h"
42
43namespace orxonox
44{
45    typedef std::pair<std::multimap<std::string, BaseItem*>::iterator, std::multimap<std::string, BaseItem*>::iterator> item_range;
46    typedef std::pair<std::multimap<ModifierType::Enum, float>::iterator, std::multimap<ModifierType::Enum, float>::iterator> modifier_range;
47
48    //! Constructor
49    PickupCollection::PickupCollection()
50    {
51        this->bBlockRemovals_ = false;
52        this->currentUsable_ = NULL;
53    }
54
55    /**
56        @brief
57            Add an item to the collection.
58
59            Only adds the item if there's a free slot for it.
60
61        @param item Item to add to the collection.
62        @return Returns whether the item has been added to the collection.
63    */
64    bool PickupCollection::add(BaseItem* item)
65    {
66        if (this->checkSlot(item))
67        {
68            Identifier* ident = Class(UsableItem);
69            if(this->currentUsable_ == NULL && item->isA(ident))
70                this->currentUsable_ = dynamic_cast<UsableItem*>(item);
71
72            this->items_.insert( std::pair<std::string, BaseItem*> (item->getPickupIdentifier(), item) );
73            return true;
74        }
75        else
76            return false;
77    }
78    /**
79        @brief
80            Check if there's a free slot for an item.
81
82            Compares the amount of the item-type in the collection
83            against the maximal amount of the item that can be carried.
84
85        @param item Item to check for a slot.
86        @return Returns if there's a free slot for the item.
87    */
88    bool PickupCollection::checkSlot(BaseItem* item)
89    {
90        return ((int)this->items_.count(item->getPickupIdentifier()) < item->getMaxCarryAmount());
91    }
92    /**
93        @brief
94            Empty the collection.
95
96            Calls dropped() on all the items in the collection,
97            then clears the collection.
98    */
99    void PickupCollection::clear()
100    {
101        this->bBlockRemovals_ = true;
102        for (std::multimap<std::string, BaseItem*>::iterator it = this->items_.begin(); it != this->items_.end(); it++)
103        {
104            if((*it).second && (*it).second->getOwner())
105                (*it).second->dropped((*it).second->getOwner());
106        }
107        this->currentUsable_ = NULL;
108        this->items_.clear();
109        this->bBlockRemovals_ = false;
110    }
111    /**
112        @brief Check if an item/type of item is in the collection.
113        @param item Item to check.
114        @param anyOfType If it should look for any item of the item's type (default: false).
115        @return Whether the collection contains the item/type of item.
116    */
117    bool PickupCollection::contains(BaseItem* item, bool anyOfType)
118    {
119        if (anyOfType)
120        {
121            return (this->items_.count(item->getPickupIdentifier()) > 0);
122        }
123        else
124        {
125            item_range bounds = this->items_.equal_range(item->getPickupIdentifier());
126            for (std::multimap<std::string, BaseItem*>::iterator it = bounds.first; it != bounds.second && it != this->items_.end(); it++)
127            {
128                if ((*it).second == item)
129                {
130                    return true;
131                }
132            }
133            return false;
134        }
135    }
136    //! Uses the first usable item in the collection on the owner.
137    void PickupCollection::useItem()
138    {
139        if(this->currentUsable_)
140            this->currentUsable_->used(this->owner_);
141    }
142    /**
143        @brief Uses a usable item on the owner of the collection.
144        @param item Item to use.
145    */
146    void PickupCollection::useItem(UsableItem* item)
147    {
148        if (item && this->owner_)
149            item->used(this->owner_);
150    }
151    /**
152        @brief Remove an item/all of a type from the collection.
153        @param item Item to remove.
154        @param removeAllOfType Whether to remove all the items with the item's type (default: false).
155    */
156    void PickupCollection::remove(BaseItem* item, bool removeAllOfType)
157    {
158        if (!item || !this->contains(item, removeAllOfType) || this->bBlockRemovals_)
159            return;
160
161        bool getNewUsable = false;
162        if (item == this->currentUsable_ || (this->currentUsable_ && removeAllOfType && this->currentUsable_->getPickupIdentifier() == item->getPickupIdentifier()))
163        {
164            getNewUsable = true;
165        }
166
167        if (removeAllOfType)
168        {
169            std::multimap<std::string, BaseItem*>::iterator it;
170            while ((it = this->items_.find(item->getPickupIdentifier())) != this->items_.end())
171            {
172                this->items_.erase(it);
173            }
174        }
175        else
176        {
177            item_range bounds = this->items_.equal_range(item->getPickupIdentifier());
178            for (std::multimap<std::string, BaseItem*>::iterator it = bounds.first; it != bounds.second && it != this->items_.end(); it++)
179            {
180                if ((*it).second == item)
181                {
182                    this->items_.erase(it);
183                    break;
184                }
185            }
186        }
187
188        if (getNewUsable)
189        {
190            std::deque<UsableItem*> usables = this->getUsableItems();
191
192            if(usables.size() > 0)
193                this->currentUsable_ = usables.at(0);
194            else
195                this->currentUsable_ = NULL;
196
197        }
198    }
199    /**
200        @brief Add an additive modifier.
201        @param type ModifierType to add.
202        @param value Value for the modifier.
203    */
204    void PickupCollection::addAdditiveModifier(ModifierType::Enum type, float value)
205    {
206        this->additiveModifiers_.insert( std::pair<ModifierType::Enum, float>(type, value) );
207    }
208    /**
209        @brief Get the total amount of an additive modifier.
210        @param type Type for which to get the total.
211        @return Returns the sum of the additive modifiers of the type.
212    */
213    float PickupCollection::getAdditiveModifier(ModifierType::Enum type)
214    {
215        float v = 0.0f;
216
217        modifier_range range = this->additiveModifiers_.equal_range(type);
218
219        for (std::multimap<ModifierType::Enum, float>::iterator it = range.first; it != range.second && it != this->additiveModifiers_.end(); it++)
220        {
221            v += (*it).second;
222        }
223
224        return v;
225    }
226    /**
227        @brief Remove an additive modifier.
228        @param type Type of modifier.
229        @param value Value which is to be removed.
230    */
231    void PickupCollection::removeAdditiveModifier(ModifierType::Enum type, float value)
232    {
233        modifier_range range = this->additiveModifiers_.equal_range(type);
234        for (std::multimap<ModifierType::Enum, float>::iterator it = range.first; it != range.second && it != this->additiveModifiers_.end(); it++)
235        {
236            if ((*it).second == value)
237            {
238                this->additiveModifiers_.erase(it);
239                return;
240            }
241        }
242    }
243    /**
244        @brief Add a multiplicative modifier.
245        @param type ModifierType to add.
246        @param value Value for the modifier.
247    */
248    void PickupCollection::addMultiplicativeModifier(ModifierType::Enum type, float value)
249    {
250        this->multiplicativeModifiers_.insert( std::pair<ModifierType::Enum, float>(type, value) );
251    }
252    /**
253        @brief Get the total amount of a multiplicative modifier.
254        @param type Type for which to get the total.
255        @return Returns the product of the multiplicative modifiers of the type.
256    */
257    float PickupCollection::getMultiplicativeModifier(ModifierType::Enum type)
258    {
259        float v = 1.0f;
260
261        modifier_range range = this->multiplicativeModifiers_.equal_range(type);
262        for (std::multimap<ModifierType::Enum, float>::iterator it = range.first; it != range.second && it != this->multiplicativeModifiers_.end(); it++)
263        {
264            v *= (*it).second;
265        }
266
267        return v;
268    }
269    /**
270        @brief Remove a multiplicative modifier.
271        @param type Type of modifier.
272        @param value Value which is to be removed.
273    */
274    void PickupCollection::removeMultiplicativeModifier(ModifierType::Enum type, float value)
275    {
276        modifier_range range = this->multiplicativeModifiers_.equal_range(type);
277        for (std::multimap<ModifierType::Enum, float>::iterator it = range.first; it != range.second && it != this->multiplicativeModifiers_.end(); it++)
278        {
279            if ((*it).second == value)
280            {
281                this->multiplicativeModifiers_.erase(it);
282                return;
283            }
284        }
285    }
286    /**
287        @brief Applies modifiers to a float.
288        @param type Type of modifier tp apply.
289        @param inputValue Value which is to be processed.
290        @param addBeforeMultiplication Whether to apply the additive modifier before the multiplicative one (default: false).
291        @return Returns the value after being processed.
292    */
293    float PickupCollection::processModifiers(ModifierType::Enum type, float inputValue, bool addBeforeMultiplication)
294    {
295        float outputValue = inputValue;
296
297        if (addBeforeMultiplication)
298            outputValue += this->getAdditiveModifier(type);
299
300        outputValue *= this->getMultiplicativeModifier(type);
301
302        if (!addBeforeMultiplication)
303            outputValue += this->getAdditiveModifier(type);
304
305        return outputValue;
306    }
307    /**
308        @brief Applies modifiers to a Vector3.
309        @param type Type of modifier tp apply.
310        @param inputValue Value which is to be processed.
311        @param addBeforeMultiplication Whether to apply the additive modifier before the multiplicative one (default: false).
312        @return Returns the value after being processed.
313    */
314    Vector3 PickupCollection::processModifiers(ModifierType::Enum type, Vector3 inputValue, bool addBeforeMultiplication)
315    {
316        Vector3 outputValue = inputValue;
317
318        if (addBeforeMultiplication)
319            outputValue += Vector3(this->getAdditiveModifier(type));
320
321        outputValue *= this->getMultiplicativeModifier(type);
322
323        if (!addBeforeMultiplication)
324            outputValue += Vector3(this->getAdditiveModifier(type));
325
326        return outputValue;
327    }
328    /**
329        @brief Get a list of equipment-type items.
330        @return Returns a list of all the equipment-type items in the collection.
331    */
332    std::deque<EquipmentItem*> PickupCollection::getEquipmentItems()
333    {
334        std::deque<EquipmentItem*> ret;
335        Identifier* ident = Class(EquipmentItem);
336
337        for (std::multimap<std::string, BaseItem*>::iterator it = this->items_.begin(); it != this->items_.end(); it++)
338        {
339            if ((*it).second->isA(ident))
340                ret.push_back(dynamic_cast<EquipmentItem*>((*it).second));
341        }
342
343        return ret;
344    }
345    /**
346        @brief Get a list of passive items.
347        @return Returns a list of all the passive items in the collection.
348    */
349    std::deque<PassiveItem*> PickupCollection::getPassiveItems()
350    {
351        std::deque<PassiveItem*> ret;
352        Identifier* ident = Class(PassiveItem);
353
354        for (std::multimap<std::string, BaseItem*>::iterator it = this->items_.begin(); it != this->items_.end(); it++)
355        {
356            if ((*it).second->isA(ident))
357                ret.push_back(dynamic_cast<PassiveItem*>((*it).second));
358        }
359
360        return ret;
361    }
362    /**
363        @brief Get a list of usable items.
364        @return Returns a list of all the usable items in the collection.
365    */
366    std::deque<UsableItem*> PickupCollection::getUsableItems()
367    {
368        std::deque<UsableItem*> ret;
369        Identifier* ident = Class(UsableItem);
370
371        for (std::multimap<std::string, BaseItem*>::iterator it = this->items_.begin(); it != this->items_.end(); it++)
372        {
373            if ((*it).second->isA(ident))
374                ret.push_back(dynamic_cast<UsableItem*>((*it).second));
375        }
376
377        return ret;
378    }
379}
Note: See TracBrowser for help on using the repository browser.