Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 3008 was 3001, checked in by danielh, 16 years ago
  • Added helper method to HumanController to get it's ControllableEntity as a Pawn
  • Removed tooltip, added default (empty) values for text and image from BaseItem
  • Fixed tolua in BaseItem.h
  • Added object to PickupCollection for the current UsableItem
  • Moved most inventory logic from Lua to PickupInventory (still slow)

TODO

  • Re-use of CEGUI item windows, destroying and creating them on each update is slow, very slow
  • Property svn:eol-style set to native
File size: 12.7 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        if (item == this->currentUsable_ || (this->currentUsable_ && removeAllOfType && this->currentUsable_->getPickupIdentifier() == item->getPickupIdentifier()))
161        {
162            std::deque<UsableItem*> usables = this->getUsableItems();
163
164            if(usables.size() > 0)
165                this->currentUsable_ = usables.at(0);
166            else
167                this->currentUsable_ = NULL;
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            std::multimap<std::string, BaseItem*>::_Pairii 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                    return;
186                }
187            }
188        }
189    }
190    /**
191        @brief Add an additive modifier.
192        @param type ModifierType to add.
193        @param value Value for the modifier.
194    */
195    void PickupCollection::addAdditiveModifier(ModifierType::Enum type, float value)
196    {
197        this->additiveModifiers_.insert( std::pair<ModifierType::Enum, float>(type, value) );
198    }
199    /**
200        @brief Get the total amount of an additive modifier.
201        @param type Type for which to get the total.
202        @return Returns the sum of the additive modifiers of the type.
203    */
204    float PickupCollection::getAdditiveModifier(ModifierType::Enum type)
205    {
206        float v = 0.0f;
207
208        std::multimap<ModifierType::Enum, float>::_Pairii range = this->additiveModifiers_.equal_range(type);
209
210        for (std::multimap<ModifierType::Enum, float>::iterator it = range.first; it != range.second && it != this->additiveModifiers_.end(); it++)
211        {
212            v += (*it).second;
213        }
214
215        return v;
216    }
217    /**
218        @brief Remove an additive modifier.
219        @param type Type of modifier.
220        @param value Value which is to be removed.
221    */
222    void PickupCollection::removeAdditiveModifier(ModifierType::Enum type, float value)
223    {
224        std::multimap<ModifierType::Enum, float>::_Pairii range = this->additiveModifiers_.equal_range(type);
225        for (std::multimap<ModifierType::Enum, float>::iterator it = range.first; it != range.second && it != this->additiveModifiers_.end(); it++)
226        {
227            if ((*it).second == value)
228            {
229                this->additiveModifiers_.erase(it);
230                return;
231            }
232        }
233    }
234    /**
235        @brief Add a multiplicative modifier.
236        @param type ModifierType to add.
237        @param value Value for the modifier.
238    */
239    void PickupCollection::addMultiplicativeModifier(ModifierType::Enum type, float value)
240    {
241        this->multiplicativeModifiers_.insert( std::pair<ModifierType::Enum, float>(type, value) );
242    }
243    /**
244        @brief Get the total amount of a multiplicative modifier.
245        @param type Type for which to get the total.
246        @return Returns the product of the multiplicative modifiers of the type.
247    */
248    float PickupCollection::getMultiplicativeModifier(ModifierType::Enum type)
249    {
250        float v = 1.0f;
251
252        std::multimap<ModifierType::Enum, float>::_Pairii range = this->multiplicativeModifiers_.equal_range(type);
253        for (std::multimap<ModifierType::Enum, float>::iterator it = range.first; it != range.second && it != this->multiplicativeModifiers_.end(); it++)
254        {
255            v *= (*it).second;
256        }
257
258        return v;
259    }
260    /**
261        @brief Remove a multiplicative modifier.
262        @param type Type of modifier.
263        @param value Value which is to be removed.
264    */
265    void PickupCollection::removeMultiplicativeModifier(ModifierType::Enum type, float value)
266    {
267        std::multimap<ModifierType::Enum, float>::_Pairii range = this->multiplicativeModifiers_.equal_range(type);
268        for (std::multimap<ModifierType::Enum, float>::iterator it = range.first; it != range.second && it != this->multiplicativeModifiers_.end(); it++)
269        {
270            if ((*it).second == value)
271            {
272                this->multiplicativeModifiers_.erase(it);
273                return;
274            }
275        }
276    }
277    /**
278        @brief Applies modifiers to a float.
279        @param type Type of modifier tp apply.
280        @param inputValue Value which is to be processed.
281        @param addBeforeMultiplication Whether to apply the additive modifier before the multiplicative one (default: false).
282        @return Returns the value after being processed.
283    */
284    float PickupCollection::processModifiers(ModifierType::Enum type, float inputValue, bool addBeforeMultiplication)
285    {
286        float outputValue = inputValue;
287
288        if (addBeforeMultiplication)
289            outputValue += this->getAdditiveModifier(type);
290
291        outputValue *= this->getMultiplicativeModifier(type);
292
293        if (!addBeforeMultiplication)
294            outputValue += this->getAdditiveModifier(type);
295
296        return outputValue;
297    }
298    /**
299        @brief Applies modifiers to a Vector3.
300        @param type Type of modifier tp apply.
301        @param inputValue Value which is to be processed.
302        @param addBeforeMultiplication Whether to apply the additive modifier before the multiplicative one (default: false).
303        @return Returns the value after being processed.
304    */
305    Vector3 PickupCollection::processModifiers(ModifierType::Enum type, Vector3 inputValue, bool addBeforeMultiplication)
306    {
307        Vector3 outputValue = inputValue;
308
309        if (addBeforeMultiplication)
310            outputValue += Vector3(this->getAdditiveModifier(type));
311
312        outputValue *= this->getMultiplicativeModifier(type);
313
314        if (!addBeforeMultiplication)
315            outputValue += Vector3(this->getAdditiveModifier(type));
316
317        return outputValue;
318    }
319    /**
320        @brief Get a list of equipment-type items.
321        @return Returns a list of all the equipment-type items in the collection.
322    */
323    std::deque<EquipmentItem*> PickupCollection::getEquipmentItems()
324    {
325        std::deque<EquipmentItem*> ret;
326        Identifier* ident = Class(EquipmentItem);
327
328        for (std::multimap<std::string, BaseItem*>::iterator it = this->items_.begin(); it != this->items_.end(); it++)
329        {
330            if ((*it).second->isA(ident))
331                ret.push_back(dynamic_cast<EquipmentItem*>((*it).second));
332        }
333
334        return ret;
335    }
336    /**
337        @brief Get a list of passive items.
338        @return Returns a list of all the passive items in the collection.
339    */
340    std::deque<PassiveItem*> PickupCollection::getPassiveItems()
341    {
342        std::deque<PassiveItem*> ret;
343        Identifier* ident = Class(PassiveItem);
344
345        for (std::multimap<std::string, BaseItem*>::iterator it = this->items_.begin(); it != this->items_.end(); it++)
346        {
347            if ((*it).second->isA(ident))
348                ret.push_back(dynamic_cast<PassiveItem*>((*it).second));
349        }
350
351        return ret;
352    }
353    /**
354        @brief Get a list of usable items.
355        @return Returns a list of all the usable items in the collection.
356    */
357    std::deque<UsableItem*> PickupCollection::getUsableItems()
358    {
359        std::deque<UsableItem*> ret;
360        Identifier* ident = Class(UsableItem);
361
362        for (std::multimap<std::string, BaseItem*>::iterator it = this->items_.begin(); it != this->items_.end(); it++)
363        {
364            if ((*it).second->isA(ident))
365                ret.push_back(dynamic_cast<UsableItem*>((*it).second));
366        }
367
368        return ret;
369    }
370}
Note: See TracBrowser for help on using the repository browser.