Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

merged pickups2 branch back to trunk. not yet tested.

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