1 //
2 //  SuperTuxKart - a fun racing game with go-kart
3 //  Copyright (C) 2006-2015 Joerg Henrichs
4 //
5 //  This program is free software; you can redistribute it and/or
6 //  modify it under the terms of the GNU General Public License
7 //  as published by the Free Software Foundation; either version 3
8 //  of the License, or (at your option) any later version.
9 //
10 //  This program is distributed in the hope that it will be useful,
11 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //  GNU General Public License for more details.
14 //
15 //  You should have received a copy of the GNU General Public License
16 //  along with this program; if not, write to the Free Software
17 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18 
19 #ifndef HEADER_ITEMMANAGER_HPP
20 #define HEADER_ITEMMANAGER_HPP
21 
22 #include "LinearMath/btTransform.h"
23 
24 #include "items/item.hpp"
25 #include "utils/aligned_array.hpp"
26 #include "utils/no_copy.hpp"
27 #include "utils/vec3.hpp"
28 
29 #include <SColor.h>
30 
31 #include <assert.h>
32 #include <algorithm>
33 
34 #include <map>
35 #include <memory>
36 #include <random>
37 #include <string>
38 #include <vector>
39 
40 class Kart;
41 class STKPeer;
42 
43 /**
44   * \ingroup items
45   */
46 class ItemManager : public NoCopy
47 {
48     // Some static data and functions to initialise it:
49 private:
50     /** Stores the glow color for all items. */
51     static std::vector<video::SColorf> m_glow_color;
52 
53     /** Disable item collection (for debugging purposes). */
54     static bool m_disable_item_collection;
55 
56     static std::mt19937 m_random_engine;
57 
58     static uint32_t m_random_seed;
59 public:
60     static void loadDefaultItemMeshes();
61     static void removeTextures();
updateRandomSeed(uint32_t seed_number)62     static void updateRandomSeed(uint32_t seed_number)
63     {
64         m_random_engine.seed(seed_number);
65         m_random_seed = seed_number;
66     }   // updateRandomSeed
67     // ------------------------------------------------------------------------
getRandomSeed()68     static uint32_t getRandomSeed()
69     {
70         return m_random_seed;
71     }   // getRandomSeed
72 
73     // ------------------------------------------------------------------------
74 
75     /** Disable item collection, useful to test client mispreditions or
76      *  client/server disagreements. */
disableItemCollection()77     static void disableItemCollection()
78     {
79         m_disable_item_collection = true;
80     }   // disableItemCollection
81 
82     // ------------------------------------------------------------------------
83     /** Returns the mesh for a certain item. */
getItemModel(ItemState::ItemType type)84     static scene::IMesh* getItemModel(ItemState::ItemType type)
85                                       { return m_item_mesh[type]; }
86     // ------------------------------------------------------------------------
87     /** Returns the low resolution mesh for a certain item. */
getItemLowResolutionModel(ItemState::ItemType type)88     static scene::IMesh* getItemLowResolutionModel(ItemState::ItemType type)
89                                       { return m_item_lowres_mesh[type]; }
90     // ------------------------------------------------------------------------
91     /** Returns the glow color for an item. */
getGlowColor(ItemState::ItemType type)92     static video::SColorf& getGlowColor(ItemState::ItemType type)
93                                       { return m_glow_color[type]; }
94 
95     // ========================================================================
96 protected:
97     /** The vector of all items of the current track. */
98     typedef std::vector<ItemState*> AllItemTypes;
99     AllItemTypes m_all_items;
100 
101     /** What item this item is switched to. */
102     std::vector<ItemState::ItemType> m_switch_to;
103 
104 private:
105     /** Stores which items are on which quad. m_items_in_quads[#quads]
106      *  contains all items that are not on a quad. Note that this
107      *  field is undefined if no Graph exist, e.g. arena without navmesh. */
108     std::vector< AllItemTypes > *m_items_in_quads;
109 
110     /** Stores all item models. */
111     static std::vector<scene::IMesh *> m_item_mesh;
112 
113     /** Stores all low-resolution item models. */
114     static std::vector<scene::IMesh *> m_item_lowres_mesh;
115 
116 protected:
117     /** Remaining time that items should remain switched. If the
118      *  value is <0, it indicates that the items are not switched atm. */
119     int m_switch_ticks;
120 
121     void deleteItem(ItemState *item);
122     void switchItemsInternal(std::vector < ItemState*> &all_items);
123     void setSwitchItems(const std::vector<int> &switch_items);
124     void insertItemInQuad(Item *item);
125     void deleteItemInQuad(ItemState *item);
126 public:
127              ItemManager();
128     virtual ~ItemManager();
129 
130     virtual Item*  placeItem       (ItemState::ItemType type, const Vec3& xyz,
131                                     const Vec3 &normal);
132     virtual Item*  dropNewItem     (ItemState::ItemType type,
133                                     const AbstractKart* parent,
134                                     const Vec3 *server_xyz = NULL,
135                                     const Vec3 *normal = NULL);
136     void           update          (int ticks);
137     void           updateGraphics  (float dt);
138     void           checkItemHit    (AbstractKart* kart);
139     void           reset           ();
140     virtual void   collectedItem   (ItemState *item, AbstractKart *kart);
141     virtual void   switchItems     ();
142     bool           randomItemsForArena(const AlignedArray<btTransform>& pos);
143 
144     // ------------------------------------------------------------------------
145     /** Returns true if the items are switched atm. */
areItemsSwitched()146     bool           areItemsSwitched() { return (m_switch_ticks > 0); }
147     // ------------------------------------------------------------------------
148     /** Only used in the NetworkItemManager. */
setItemConfirmationTime(std::weak_ptr<STKPeer> peer,int ticks)149     virtual void setItemConfirmationTime(std::weak_ptr<STKPeer> peer,
150                                          int ticks)
151     {
152         assert(false);
153     }
154     // ------------------------------------------------------------------------
155     /** Returns the number of items. */
getNumberOfItems() const156     unsigned int   getNumberOfItems() const
157     {
158         return (unsigned int) m_all_items.size();
159     }
160     // ------------------------------------------------------------------------
161     /** Returns a pointer to the n-th item. */
getItem(unsigned int n) const162     const ItemState* getItem(unsigned int n) const
163     {
164         return dynamic_cast<Item*>(m_all_items[n]);
165     };
166     // ------------------------------------------------------------------------
167     /** Returns a pointer to the n-th item. */
getItem(unsigned int n)168     ItemState* getItem(unsigned int n)
169     {
170         return dynamic_cast<Item*>(m_all_items[n]);
171     }
172     // ------------------------------------------------------------------------
itemExists(const ItemState * is) const173     bool itemExists(const ItemState* is) const
174     {
175         if (!is)
176             return false;
177         auto it = std::find(m_all_items.begin(), m_all_items.end(), is);
178         return it != m_all_items.end();
179     }
180     // ------------------------------------------------------------------------
181     /** Returns a reference to the array of all items on the specified quad.
182      */
getItemsInQuads(unsigned int n) const183     const AllItemTypes& getItemsInQuads(unsigned int n) const
184     {
185         assert(m_items_in_quads);
186         assert(n<(*m_items_in_quads).size());
187         return (*m_items_in_quads)[n];
188     }   // getItemsInQuads
189     // ------------------------------------------------------------------------
190     /** Returns the first item (NULL if none) on the specified quad
191      */
getFirstItemInQuad(unsigned int n) const192     Item* getFirstItemInQuad(unsigned int n) const
193     {
194         assert(m_items_in_quads);
195         assert(n < m_items_in_quads->size());
196         return ((*m_items_in_quads)[n]).empty()
197               ? NULL
198              : dynamic_cast<Item*>((*m_items_in_quads)[n].front());
199     }   // getFirstItemInQuad
200     // ------------------------------------------------------------------------
201     unsigned int insertItem(Item *item);
202 };   // ItemManager
203 
204 #endif
205