Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 6117 was 5781, checked in by rgrieder, 15 years ago

Reverted trunk again. We might want to find a way to delete these revisions again (x3n's changes are still available as diff in the commit mails).

  • 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 "core/CoreIncludes.h"
37#include "EquipmentItem.h"
38#include "PassiveItem.h"
39#include "UsableItem.h"
40
41namespace orxonox
42{
43    typedef std::pair<std::multimap<std::string, BaseItem*>::iterator, std::multimap<std::string, BaseItem*>::iterator> item_range;
44    typedef std::pair<std::multimap<ModifierType::Value, float>::iterator, std::multimap<ModifierType::Value, float>::iterator> modifier_range;
45
46    //! Constructor
47    PickupCollection::PickupCollection()
48    {
49        this->bBlockRemovals_ = false;
50        this->currentUsable_ = NULL;
51    }
52
53    /**
54        @brief
55            Add an item to the collection.
56
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        {
66            Identifier* ident = Class(UsableItem);
67            if(this->currentUsable_ == NULL && item->isA(ident))
68                this->currentUsable_ = orxonox_cast<UsableItem*>(item);
69
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    {
88        return (static_cast<int>(this->items_.count(item->getPickupIdentifier())) < item->getMaxCarryAmount());
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        }
105        this->currentUsable_ = NULL;
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        {
123            item_range bounds = this->items_.equal_range(item->getPickupIdentifier());
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    {
137        if(this->currentUsable_)
138            this->currentUsable_->used(this->owner_);
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
159        bool getNewUsable = false;
160        if (item == this->currentUsable_ || (this->currentUsable_ && removeAllOfType && this->currentUsable_->getPickupIdentifier() == item->getPickupIdentifier()))
161        {
162            getNewUsable = true;
163        }
164
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        {
175            item_range bounds = this->items_.equal_range(item->getPickupIdentifier());
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);
181                    break;
182                }
183            }
184        }
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;
194
195        }
196    }
197    /**
198        @brief Add an additive modifier.
199        @param type ModifierType to add.
200        @param value Value for the modifier.
201    */
202    void PickupCollection::addAdditiveModifier(ModifierType::Value type, float value)
203    {
204        this->additiveModifiers_.insert( std::pair<ModifierType::Value, float>(type, value) );
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    */
211    float PickupCollection::getAdditiveModifier(ModifierType::Value type)
212    {
213        float v = 0.0f;
214
215        modifier_range range = this->additiveModifiers_.equal_range(type);
216
217        for (std::multimap<ModifierType::Value, float>::iterator it = range.first; it != range.second && it != this->additiveModifiers_.end(); it++)
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    */
229    void PickupCollection::removeAdditiveModifier(ModifierType::Value type, float value)
230    {
231        modifier_range range = this->additiveModifiers_.equal_range(type);
232        for (std::multimap<ModifierType::Value, float>::iterator it = range.first; it != range.second && it != this->additiveModifiers_.end(); it++)
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    */
246    void PickupCollection::addMultiplicativeModifier(ModifierType::Value type, float value)
247    {
248        this->multiplicativeModifiers_.insert( std::pair<ModifierType::Value, float>(type, value) );
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    */
255    float PickupCollection::getMultiplicativeModifier(ModifierType::Value type)
256    {
257        float v = 1.0f;
258
259        modifier_range range = this->multiplicativeModifiers_.equal_range(type);
260        for (std::multimap<ModifierType::Value, float>::iterator it = range.first; it != range.second && it != this->multiplicativeModifiers_.end(); it++)
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    */
272    void PickupCollection::removeMultiplicativeModifier(ModifierType::Value type, float value)
273    {
274        modifier_range range = this->multiplicativeModifiers_.equal_range(type);
275        for (std::multimap<ModifierType::Value, float>::iterator it = range.first; it != range.second && it != this->multiplicativeModifiers_.end(); it++)
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    */
291    float PickupCollection::processModifiers(ModifierType::Value type, float inputValue, bool addBeforeMultiplication)
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    */
312    Vector3 PickupCollection::processModifiers(ModifierType::Value type, Vector3 inputValue, bool addBeforeMultiplication)
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    */
330    std::deque<EquipmentItem*> PickupCollection::getEquipmentItems()
331    {
332        std::deque<EquipmentItem*> ret;
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))
338                ret.push_back(orxonox_cast<EquipmentItem*>((*it).second));
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    */
347    std::deque<PassiveItem*> PickupCollection::getPassiveItems()
348    {
349        std::deque<PassiveItem*> ret;
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))
355                ret.push_back(orxonox_cast<PassiveItem*>((*it).second));
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    */
364    std::deque<UsableItem*> PickupCollection::getUsableItems()
365    {
366        std::deque<UsableItem*> ret;
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))
372                ret.push_back(orxonox_cast<UsableItem*>((*it).second));
373        }
374
375        return ret;
376    }
377}
Note: See TracBrowser for help on using the repository browser.