Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 5397 was 3325, checked in by rgrieder, 15 years ago

Merged orxonox_cast related revisions from core4 back to trunk.

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