Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/pickups2/src/orxonox/objects/pickup/PickupCollection.cc @ 3016

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