Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/pickups/src/orxonox/objects/pickup/PickupCollection.cc @ 2961

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