1 #include <assert.h>
2 #include <string>
3 #include <sstream>
4 #include <random>
5 #include <iostream>
6 
7 #include "Util.h"
8 #include "../SharedDefines.h"
9 #include "../GameApp/BaseGameLogic.h"
10 
11 #include "../Events/EventMgr.h"
12 #include "../Events/Events.h"
13 
14 #include "../GameApp/BaseGameApp.h"
15 
16 #include "../Resource/Loaders/WavLoader.h"
17 
18 //#include "../Level/Level.h"
19 
20 namespace Util
21 {
SplitStringIntoVector(std::string str,std::vector<std::string> & vec)22     void SplitStringIntoVector(std::string str, std::vector<std::string>& vec)
23     {
24         std::stringstream ss(str);
25         ss >> std::noskipws;
26         std::string field;
27         char ws_delim;
28         while (1)
29         {
30             if (ss >> field)
31             {
32                 vec.push_back(field);
33             }
34             else if (ss.eof())
35             {
36                 break;
37             }
38             else
39             {
40                 vec.push_back(std::string());
41             }
42             ss.clear();
43             ss >> ws_delim;
44         }
45 
46         if (vec.empty())
47         {
48             vec.push_back(str);
49         }
50 
51         if (str.back() == ' ')
52         {
53             vec.push_back(std::string(""));
54         }
55     }
56 
ConvertToThreeDigitsString(int32_t num)57     std::string ConvertToThreeDigitsString(int32_t num)
58     {
59         assert(num >= 0 && num < 1000);
60 
61         std::stringstream ss;
62         if (num >= 100)
63         {
64             ss << num;
65         }
66         else if (num >= 10)
67         {
68             ss << (int32_t)0 << num;
69         }
70         else
71         {
72             ss << (int32_t)0 << (int32_t)0 << num;
73         }
74 
75         return ss.str();
76     }
77 
WwdRectToSDLRect(WwdRect & rect)78     SDL_Rect WwdRectToSDLRect(WwdRect& rect)
79     {
80         SDL_Rect sdlRect;
81         sdlRect.x = rect.left;
82         sdlRect.y = rect.top;
83         sdlRect.w = rect.right - rect.left;
84         sdlRect.h = rect.bottom - rect.top;
85 
86         return sdlRect;
87     }
88 
PrintRect(SDL_Rect rect,std::string comment)89     void PrintRect(SDL_Rect rect, std::string comment)
90     {
91         std::cout << comment.c_str() << ": X = " << rect.x << ", Y = " << rect.y << ", Width = " << rect.w << ", Height = " << rect.h << std::endl;
92     }
93 
IsInBetween(int32_t num,int32_t leftLimit,int32_t rightLimit)94     inline bool IsInBetween(int32_t num, int32_t leftLimit, int32_t rightLimit)
95     {
96         return ((num > leftLimit) && (num < rightLimit));
97     }
98     using namespace std;
PrintWwdRect(WwdRect rect)99     void PrintWwdRect(WwdRect rect)
100     {
101         cout << "WWD RECT: " << "left = " << rect.left << ", top = " << rect.top << ", right = " << rect.right << ", bottom = " << rect.bottom << endl;
102     }
103 
ParseCollisionRectanglesFromTile(TileCollisionPrototype * tilePrototype,TileDescription * tileDesc)104     void ParseCollisionRectanglesFromTile(TileCollisionPrototype* tilePrototype, TileDescription* tileDesc)
105     {
106         SDL_Rect tileRect = { 0, 0, 64, 64 };//WwdRectToSDLRect(tileDesc->rect);
107         SDL_Rect fullRect = { 0, 0, tileDesc->width, tileDesc->height };
108         //PrintRect(tileRect, to_string(tileId));
109         // This is full clear tile
110         /*if (tileId == -1)
111         {
112         tilePrototype->collisionRectangles.push_back({ WAP_TILE_ATTRIBUTE_CLEAR, fullRect });
113         // myfile << "Tile -1" << endl;
114         return;
115         }*/
116 
117         if (tileDesc->type == WAP_TILE_TYPE_SINGLE)
118         {
119             //myfile << "Tile 0" << endl;
120             SDL_Rect r = { 0, 0, tileDesc->width, tileDesc->height };
121             tilePrototype->collisionRectangles.push_back({ CollisionType(tileDesc->insideAttrib), fullRect });
122             return;
123         }
124         else if (tileDesc->type == WAP_TILE_TYPE_DOUBLE)
125         {
126             //PrintWwdRect(tileDesc->rect);
127             // Everything inside tileDesc->rect is clear, outside of that eveything is
128             // CollisionType(tileDesc->outsideAttrib)
129             // Though I dont think I have to specify this
130 
131             // My paper case (1)
132             // xxxx
133             // oooo
134             // oooo
135             // This yields 2 rectangles
136             if ((tileDesc->rect.left == 0 && tileDesc->rect.top == 0) && // Starting in upper left corner
137                 (tileDesc->rect.right == tileDesc->width - 1)) // Ending on right side of the rect
138             {
139                 // Inside rect
140                 SDL_Rect rect1 = { tileRect.x, tileRect.y, tileDesc->width, tileDesc->rect.bottom };
141                 // Outside rect
142                 SDL_Rect rect2 = { tileRect.x, tileRect.y + tileDesc->rect.bottom + 1, tileDesc->width, tileDesc->height - tileDesc->rect.bottom };
143                 tilePrototype->collisionRectangles.push_back({ CollisionType(tileDesc->insideAttrib), rect1 });
144                 tilePrototype->collisionRectangles.push_back({ CollisionType(tileDesc->outsideAttrib), rect2 });
145                 //myfile << "Tile 1" << endl;
146             }
147             // My paper case (2)
148             // ooox
149             // ooox
150             // ooox
151             // This yields 2 rectangles
152             else if ((tileDesc->rect.left > 0 && tileDesc->rect.top == 0) && // Starting in between right and left corners with top being on the top side
153                 (tileDesc->rect.right == tileDesc->width - 1) && (tileDesc->rect.bottom == tileDesc->height - 1)) // Ends in bottom right corner of the tile
154             {
155                 // Inside rect
156                 SDL_Rect rect1 = { tileRect.x + tileDesc->rect.left, tileRect.y, tileDesc->width - tileDesc->rect.left, tileDesc->height };
157                 // Outside rect
158                 SDL_Rect rect2 = { tileRect.x, tileRect.y, tileDesc->rect.left, tileDesc->height };
159                 tilePrototype->collisionRectangles.push_back({ CollisionType(tileDesc->insideAttrib), rect1 });
160                 tilePrototype->collisionRectangles.push_back({ CollisionType(tileDesc->outsideAttrib), rect2 });
161                 /*myfile << "Inside Rect x-y:w-h = " << rect1.x << "-" << rect1.y << ":" << rect1.w << "-" << rect1.h << endl;
162                 myfile << "Outside Rect x-y:w-h = " << rect2.x << "-" << rect2.y << ":" << rect2.w << "-" << rect2.h << endl;
163                 myfile << "Tile 2" << endl;*/
164             }
165             // My paper case (3)
166             // This yields 2 rectangles
167             else if ((tileDesc->rect.left == 0) && (tileDesc->rect.top > 0) && // Starting on left side between top and bottom
168                 (tileDesc->rect.right == tileDesc->width - 1) && (tileDesc->rect.bottom == tileDesc->height - 1)) // ending in bottom right corner
169             {
170                 // Inside rect
171                 SDL_Rect rect1 = { tileRect.x, tileRect.y + tileDesc->rect.top, tileDesc->width, tileDesc->height - tileDesc->rect.top };
172                 // Outside rect
173                 SDL_Rect rect2 = { tileRect.x, tileRect.y, tileDesc->width, tileDesc->rect.top };
174                 tilePrototype->collisionRectangles.push_back({ CollisionType(tileDesc->insideAttrib), rect1 });
175                 tilePrototype->collisionRectangles.push_back({ CollisionType(tileDesc->outsideAttrib), rect2 });
176                 /*myfile << "Inside Rect x-y:w-h = " << rect1.x << "-" << rect1.y << ":" << rect1.w << "-" << rect1.h << endl;
177                 myfile << "Outside Rect x-y:w-h = " << rect2.x << "-" << rect2.y << ":" << rect2.w << "-" << rect2.h << endl;
178                 myfile << "Tile 3" << endl;*/
179             }
180             // My paper case (4)
181             // This yields 2 rectangles
182             else if ((tileDesc->rect.left == 0) && (tileDesc->rect.top == 0) && // Starting in upper left corner
183                 (tileDesc->rect.right > 0) && (tileDesc->rect.bottom == tileDesc->height - 1)) // Ending on the bottom line somewhere between left and right
184             {
185                 // Inside rect
186                 SDL_Rect rect1 = { tileRect.x, tileRect.y, tileDesc->rect.right, tileDesc->height };
187                 // Outside rect
188                 SDL_Rect rect2 = { tileRect.x + tileDesc->rect.right + 1, tileRect.y, tileDesc->width - tileDesc->rect.right, tileDesc->height };
189                 tilePrototype->collisionRectangles.push_back({ CollisionType(tileDesc->insideAttrib), rect1 });
190                 tilePrototype->collisionRectangles.push_back({ CollisionType(tileDesc->outsideAttrib), rect2 });
191                 /*myfile << "Inside Rect x-y:w-h = " << rect1.x << "-" << rect1.y << ":" << rect1.w << "-" << rect1.h << endl;
192                 myfile << "Outside Rect x-y:w-h = " << rect2.x << "-" << rect2.y << ":" << rect2.w << "-" << rect2.h << endl;
193                 myfile << "Tile 4" << endl;*/
194 
195                 /*cout << "left = " << tileDesc->rect.left << endl;
196 
197                 cout << "tileId = " << tilePrototype->id << endl;
198                 PrintRect(rect1, "4.1");
199                 PrintRect(rect2, "4.2");*/
200             }
201             // My paper case (5)
202             // This yields 3 rectangles
203             else if ((tileDesc->rect.left == 0) && (tileDesc->rect.top > 0) && // Starting on the left side somewhere between top and bottom
204                 (tileDesc->rect.right == tileDesc->width - 1) && (tileDesc->rect.bottom > 0)) // !!! Not 100% but it works because we have case (3) ending on right side somewhere between top and bottom
205             {
206                 SDL_Rect rect1 = { 0, 0, tileDesc->width, tileDesc->rect.top };
207                 SDL_Rect rect2 = { 0, 0, tileDesc->width, tileDesc->rect.bottom - tileDesc->rect.top };
208                 SDL_Rect rect3 = { 0, tileDesc->rect.bottom, tileDesc->width, tileDesc->height - tileDesc->rect.bottom };
209                 tilePrototype->collisionRectangles.push_back({ CollisionType(tileDesc->outsideAttrib), rect1 });
210                 tilePrototype->collisionRectangles.push_back({ CollisionType(tileDesc->insideAttrib), rect2 });
211                 tilePrototype->collisionRectangles.push_back({ CollisionType(tileDesc->outsideAttrib), rect3 });
212 
213                 //LOG("TileId: " + ToStr(tileDesc->tileId));
214 
215                 //myfile << "Tile 5" << endl;
216                 //assert(false && "Paring rects case: 5");
217             }
218             // My paper case (6)
219             // This yields 3 rectangles
220             else if ((tileDesc->rect.left > 0) && (tileDesc->rect.top == 0) && // Starting on top side somewhere between left and right
221                 (tileDesc->rect.right > 0) && (tileDesc->rect.bottom == tileDesc->height - 1)) // !!! similiar to (2)
222             {
223                 //myfile << "Tile 6" << endl;
224                 //cout << "tileId: " << tileDesc->tileId << endl;
225                 //cout << "left: " << tileDesc->rect.left << "right: " << tileDesc->rect.right << "bott: " << tileDesc->rect.bottom << "top: " << tileDesc->rect.top << endl;
226                 SDL_Rect rect1 = { 0, 0, tileDesc->rect.left, tileDesc->height };
227                 SDL_Rect rect2 = { tileDesc->rect.left, 0, tileDesc->rect.right - tileDesc->rect.left, tileDesc->height };
228                 SDL_Rect rect3 = { tileDesc->rect.right, 0, tileDesc->width - tileDesc->rect.right, tileDesc->height };
229                 tilePrototype->collisionRectangles.push_back({ CollisionType(tileDesc->outsideAttrib), rect1 });
230                 tilePrototype->collisionRectangles.push_back({ CollisionType(tileDesc->insideAttrib), rect2 });
231                 tilePrototype->collisionRectangles.push_back({ CollisionType(tileDesc->outsideAttrib), rect3 });
232                 //assert(false && "Paring rects case: 6");
233             }
234             // My paper case (7) --- PAPERFIED
235             // This yields 3 rectangles
236             else if ((tileDesc->rect.left == 0) && (tileDesc->rect.top == 0) && // Starting in top left corner
237                 (tileDesc->rect.right != tileDesc->width - 1) && (tileDesc->rect.bottom != tileDesc->height - 1)) // Ending somewhere inside the rect
238             {
239                 SDL_Rect rect1 = { tileRect.x, tileRect.y, tileDesc->rect.right, tileDesc->rect.bottom };
240                 SDL_Rect rect2 = { tileRect.x, tileRect.y + tileDesc->rect.bottom + 1, tileDesc->rect.right + 1, tileDesc->height - tileDesc->rect.bottom };
241                 SDL_Rect rect3 = { tileRect.x + tileDesc->rect.right + 1, tileRect.y, tileDesc->width - tileDesc->rect.right, tileDesc->height };
242                 tilePrototype->collisionRectangles.push_back({ CollisionType(tileDesc->insideAttrib), rect1 });
243                 tilePrototype->collisionRectangles.push_back({ CollisionType(tileDesc->outsideAttrib), rect2 });
244                 tilePrototype->collisionRectangles.push_back({ CollisionType(tileDesc->outsideAttrib), rect3 });
245                 /*myfile << "Inside Rect x-y:w-h = " << rect1.x << "-" << rect1.y << ":" << rect1.w << "-" << rect1.h << endl;
246                 myfile << "Outside Rect 1 x-y:w-h = " << rect2.x << "-" << rect2.y << ":" << rect2.w << "-" << rect2.h << endl;
247                 myfile << "Outside Rect 2 x-y:w-h = " << rect3.x << "-" << rect3.y << ":" << rect3.w << "-" << rect3.h << endl;
248                 myfile << "Tile 7" << endl;*/
249 
250                 /*cout << "tileId = " << tilePrototype->id << endl;
251                 PrintRect(rect1, "7.1");
252                 PrintRect(rect2, "7.2");
253                 PrintRect(rect3, "7.3");*/
254             }
255             // My paper case (8) --- PAPERFIED
256             // This yields 3 rectangles
257             else if ((tileDesc->rect.left > 0) && (tileDesc->rect.top == 0) && // Starting somewhere on the top between left and right
258                 (tileDesc->rect.right == tileDesc->width - 1) && (tileDesc->rect.bottom != tileDesc->height - 1)) // ending somewhere on the right side between top and bottom
259             {
260                 SDL_Rect rect1 = { tileRect.x + tileDesc->rect.left, tileRect.y, tileDesc->width - tileDesc->rect.left, tileDesc->rect.bottom };
261                 SDL_Rect rect2 = { tileRect.x, tileRect.y, tileDesc->rect.left - 1, tileDesc->height };
262                 SDL_Rect rect3 = { tileRect.x + tileDesc->rect.left, tileRect.y + tileDesc->rect.bottom + 1, tileDesc->width - tileDesc->rect.left, tileDesc->height - tileDesc->rect.bottom - 1 };
263                 tilePrototype->collisionRectangles.push_back({ CollisionType(tileDesc->insideAttrib), rect1 });
264                 tilePrototype->collisionRectangles.push_back({ CollisionType(tileDesc->outsideAttrib), rect2 });
265                 tilePrototype->collisionRectangles.push_back({ CollisionType(tileDesc->outsideAttrib), rect3 });
266                 /*myfile << "Inside Rect x-y:w-h = " << rect1.x << "-" << rect1.y << ":" << rect1.w << "-" << rect1.h << endl;
267                 myfile << "Outside Rect 1 x-y:w-h = " << rect2.x << "-" << rect2.y << ":" << rect2.w << "-" << rect2.h << endl;
268                 myfile << "Outside Rect 2 x-y:w-h = " << rect3.x << "-" << rect3.y << ":" << rect3.w << "-" << rect3.h << endl;
269                 myfile << "Tile 8" << endl;*/
270             }
271             // My paper case (9) --- PAPERFIED
272             // This yields 3 rectangles
273             else if ((tileDesc->rect.left > 0) && (tileDesc->rect.top > 0) &&
274                 (tileDesc->rect.right == tileDesc->width - 1) && (tileDesc->rect.bottom == tileDesc->height - 1))
275             {
276                 SDL_Rect rect1 = { tileRect.x + tileDesc->rect.left, tileRect.y + tileDesc->rect.top, tileDesc->width - tileDesc->rect.left, tileDesc->height - tileDesc->rect.top };
277                 SDL_Rect rect2 = { tileRect.x, tileRect.y, tileDesc->rect.left, tileDesc->height };
278                 SDL_Rect rect3 = { tileRect.x + tileDesc->rect.left, tileRect.y, tileDesc->width - tileDesc->rect.left, tileDesc->rect.top };
279                 tilePrototype->collisionRectangles.push_back({ CollisionType(tileDesc->insideAttrib), rect1 });
280                 tilePrototype->collisionRectangles.push_back({ CollisionType(tileDesc->outsideAttrib), rect2 });
281                 tilePrototype->collisionRectangles.push_back({ CollisionType(tileDesc->outsideAttrib), rect3 });
282                 /*myfile << "Inside Rect x-y:w-h = " << rect1.x << "-" << rect1.y << ":" << rect1.w << "-" << rect1.h << endl;
283                 myfile << "Outside Rect 1 x-y:w-h = " << rect2.x << "-" << rect2.y << ":" << rect2.w << "-" << rect2.h << endl;
284                 myfile << "Outside Rect 2 x-y:w-h = " << rect3.x << "-" << rect3.y << ":" << rect3.w << "-" << rect3.h << endl;
285                 myfile << "Tile 9" << endl;*/
286             }
287             // My paper case (10) --- PAPERFIED
288             // This yields 3 rectangles
289             else if ((tileDesc->rect.left == 0) && (tileDesc->rect.top > 0) && // Beginning somewhere on the left side between top and bottom
290                 (tileDesc->rect.right != tileDesc->width - 1) && (tileDesc->rect.bottom == tileDesc->height - 1))
291             {
292                 SDL_Rect rect1 = { tileRect.x, tileRect.y + tileDesc->rect.top, tileDesc->rect.right, tileDesc->height - tileDesc->rect.top };
293                 SDL_Rect rect2 = { tileRect.x, tileRect.y, tileDesc->rect.right, tileDesc->rect.top };
294                 SDL_Rect rect3 = { tileRect.x + tileDesc->rect.right, tileRect.y, tileDesc->width - tileDesc->rect.right, tileDesc->height };
295                 tilePrototype->collisionRectangles.push_back({ CollisionType(tileDesc->insideAttrib), rect1 });
296                 tilePrototype->collisionRectangles.push_back({ CollisionType(tileDesc->outsideAttrib), rect2 });
297                 tilePrototype->collisionRectangles.push_back({ CollisionType(tileDesc->outsideAttrib), rect3 });
298                 /*myfile << "Inside Rect x-y:w-h = " << rect1.x << "-" << rect1.y << ":" << rect1.w << "-" << rect1.h << endl;
299                 myfile << "Outside Rect 1 x-y:w-h = " << rect2.x << "-" << rect2.y << ":" << rect2.w << "-" << rect2.h << endl;
300                 myfile << "Outside Rect 2 x-y:w-h = " << rect3.x << "-" << rect3.y << ":" << rect3.w << "-" << rect3.h << endl;
301                 myfile << "Tile 10" << endl;*/
302             }
303             // This is where the rekt begins
304 
305             // My paper case (11)
306             // This yields 4 rectangles
307             else if (IsInBetween(tileDesc->rect.left, 0, tileDesc->width - 1) && (tileDesc->rect.top == 0) &&
308                 (IsInBetween(tileDesc->rect.right, 0, tileDesc->width - 1)) && (IsInBetween(tileDesc->rect.bottom, 0, tileDesc->height - 1)))
309             {
310                 SDL_Rect rect1 = { tileDesc->rect.left, tileDesc->rect.top, tileDesc->rect.right - tileDesc->rect.left, tileDesc->rect.bottom };
311                 tilePrototype->collisionRectangles.push_back({ CollisionType(tileDesc->insideAttrib), rect1 });
312 
313                 assert(tileDesc->insideAttrib != WAP_TILE_ATTRIBUTE_CLEAR && tileDesc->outsideAttrib == WAP_TILE_ATTRIBUTE_CLEAR);
314             }
315             // My paper case (12)
316             // This yields 4 rectangles
317             else if (IsInBetween(tileDesc->rect.left, 0, tileDesc->width - 1) && IsInBetween(tileDesc->rect.top, 0, tileDesc->height - 1) &&
318                 (tileDesc->rect.right == tileDesc->width - 1) && IsInBetween(tileDesc->rect.bottom, 0, tileDesc->height - 1))
319             {
320                 LOG_ERROR("Case 12: Tile " + ToStr(tileDesc->tileId) + " not implemented !");
321                 //myfile << "Tile 12" << endl;
322                 //assert(false && "Paring rects case: 12");
323             }
324             // My paper case (13) --- PAPERFIED
325             // This yields 4 rectangles
326             else if (IsInBetween(tileDesc->rect.left, 0, tileDesc->width - 1) && IsInBetween(tileDesc->rect.top, 0, tileDesc->height - 1) &&
327                 IsInBetween(tileDesc->rect.right, 0, tileDesc->width - 1) && (tileDesc->rect.bottom == tileDesc->height - 1))
328             {
329                 SDL_Rect rect1 = { tileRect.x + tileDesc->rect.left, tileRect.y + tileDesc->rect.top, tileDesc->rect.right - tileDesc->rect.left, tileDesc->height - tileDesc->rect.top };
330                 SDL_Rect rect2 = { tileRect.x, tileRect.y, tileDesc->rect.left, tileDesc->height };
331                 SDL_Rect rect3 = { tileRect.x + tileDesc->rect.left, tileRect.y, tileDesc->rect.right - tileDesc->rect.left, tileDesc->rect.top };
332                 SDL_Rect rect4 = { tileRect.x + tileDesc->rect.right, tileRect.y, tileDesc->width - tileDesc->rect.right, tileDesc->height };
333                 tilePrototype->collisionRectangles.push_back({ CollisionType(tileDesc->insideAttrib), rect1 });
334                 tilePrototype->collisionRectangles.push_back({ CollisionType(tileDesc->outsideAttrib), rect2 });
335                 tilePrototype->collisionRectangles.push_back({ CollisionType(tileDesc->outsideAttrib), rect3 });
336                 tilePrototype->collisionRectangles.push_back({ CollisionType(tileDesc->outsideAttrib), rect4 });
337                 /*myfile << "Inside Rect x-y:w-h = " << rect1.x << "-" << rect1.y << ":" << rect1.w << "-" << rect1.h << endl;
338                 myfile << "Outside Rect 1 x-y:w-h = " << rect2.x << "-" << rect2.y << ":" << rect2.w << "-" << rect2.h << endl;
339                 myfile << "Outside Rect 2 x-y:w-h = " << rect3.x << "-" << rect3.y << ":" << rect3.w << "-" << rect3.h << endl;
340                 myfile << "Outside Rect 3 x-y:w-h = " << rect4.x << "-" << rect4.y << ":" << rect4.w << "-" << rect4.h << endl;
341                 myfile << "Tile 13" << endl;*/
342             }
343             // My paper case (14)
344             // This yields 4 rectangles
345             else if ((tileDesc->rect.left == 0) && IsInBetween(tileDesc->rect.top, 0, tileDesc->height - 1) &&
346                 IsInBetween(tileDesc->rect.right, 0, tileDesc->width - 1) && (tileDesc->rect.bottom == tileDesc->height - 1))
347             {
348                 //myfile << "Tile 14" << endl;
349                 assert(false && "Paring rects case: 14");
350             }
351             // My paper case (15)
352             // This yields 5 rectangles
353             else if (IsInBetween(tileDesc->rect.left, 0, tileDesc->width - 1) && IsInBetween(tileDesc->rect.top, 0, tileDesc->height - 1) &&
354                 IsInBetween(tileDesc->rect.right, 0, tileDesc->width - 1) && (tileDesc->rect.bottom == tileDesc->height - 1))
355             {
356                 //myfile << "Tile 15" << endl;
357                 assert(false && "Paring rects case: 16");
358             }
359         }
360         else
361         {
362             assert(false);
363         }
364 
365         if (tilePrototype->collisionRectangles.empty())
366         {
367             LOG_ERROR("Collision rectangles are empty for tile: " + ToStr(tileDesc->tileId));
368             SDL_Rect rect;
369             rect.x = tileDesc->rect.left;
370             rect.y = tileDesc->rect.top;
371             rect.w = tileDesc->rect.right - tileDesc->rect.left;
372             rect.h = tileDesc->rect.bottom - tileDesc->rect.top;
373             PrintRect(rect, "Unknown Rect");
374             //assert(!tilePrototype->collisionRectangles.empty());
375         }
376 
377         /*for (auto a : tilePrototype->collisionRectangles)
378         {
379         PrintRect(a.collisionRect, to_string(tileId));
380         }*/
381     }
382 
GetRandomNumber(int fromRange,int toRange)383     int GetRandomNumber(int fromRange, int toRange)
384     {
385         static std::random_device rd;
386         std::mt19937 rng(rd());
387         std::uniform_int_distribution<int> uni(fromRange, toRange);
388 
389         return uni(rng);
390     }
391 
RollDice(int chanceToSucceed)392     bool RollDice(int chanceToSucceed)
393     {
394         return (GetRandomNumber(0, 100) < chanceToSucceed);
395     }
396 
PlayRandomSoundFromList(const std::vector<std::string> & sounds,int volume)397     std::string PlayRandomSoundFromList(const std::vector<std::string>& sounds, int volume)
398     {
399         if (!sounds.empty())
400         {
401             int soundIdx = Util::GetRandomNumber(0, sounds.size() - 1);
402 
403             SoundInfo soundInfo(sounds[soundIdx]);
404             soundInfo.soundVolume = volume;
405             IEventMgr::Get()->VTriggerEvent(IEventDataPtr(
406                 new EventData_Request_Play_Sound(soundInfo)));
407 
408             return soundInfo.soundToPlay;
409         }
410 
411         return "";
412     }
413 
PlaySimpleSound(const std::string & sound,int volume)414     void PlaySimpleSound(const std::string& sound, int volume)
415     {
416         SoundInfo soundInfo(sound);
417         soundInfo.soundVolume = volume;
418         IEventMgr::Get()->VTriggerEvent(IEventDataPtr(
419             new EventData_Request_Play_Sound(soundInfo)));
420     }
421 
GetSoundDurationMs(const std::string & soundPath)422     int GetSoundDurationMs(const std::string& soundPath)
423     {
424         shared_ptr<Mix_Chunk> pSound = WavResourceLoader::LoadAndReturnSound(soundPath.c_str());
425         assert(pSound != nullptr);
426         return GetSoundDurationMs(pSound.get());
427     }
428 
GetSoundDurationMs(Mix_Chunk * pSound)429     int GetSoundDurationMs(Mix_Chunk* pSound)
430     {
431         uint32 points = 0;
432         uint32 frames = 0;
433         int frequency = 0;
434         uint16 format = 0;
435         int channels = 0;
436 
437         if (Mix_QuerySpec(&frequency, &format, &channels) == 0)
438         {
439             return -1;
440         }
441 
442         points = (pSound->alen / ((format & 0xFF) / 8));
443         frames = points / channels;
444         return ((frames * 1000) / frequency);
445     }
446 
CreateSDLTextureRect(int width,int height,SDL_Color color,SDL_Renderer * pRenderer)447     SDL_Texture* CreateSDLTextureRect(int width, int height, SDL_Color color, SDL_Renderer* pRenderer)
448     {
449         SDL_Surface* pSurface = SDL_CreateRGBSurface(0, width, height, 32, 0, 0, 0, 0);
450         SDL_FillRect(pSurface, NULL, SDL_MapRGB(pSurface->format, color.r, color.g, color.b));
451         SDL_Texture* pTextureRect = SDL_CreateTextureFromSurface(pRenderer, pSurface);
452 
453         SDL_FreeSurface(pSurface);
454         return pTextureRect;
455     }
456 
CreateSDLTextureRect(int width,int height,SDL_Color color,SDL_Renderer * pRenderer,uint8_t alpha)457     SDL_Texture* CreateSDLTextureRect(int width, int height, SDL_Color color, SDL_Renderer* pRenderer, uint8_t alpha)
458     {
459         Uint32 rmask, gmask, bmask, amask;
460 
461 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
462         rmask = 0xff000000;
463         gmask = 0x00ff0000;
464         bmask = 0x0000ff00;
465         amask = 0x000000ff;
466 #else
467         rmask = 0x000000ff;
468         gmask = 0x0000ff00;
469         bmask = 0x00ff0000;
470         amask = 0xff000000;
471 #endif
472         SDL_Surface* pSurface = SDL_CreateRGBSurface(0, width, height, 32, rmask, gmask, bmask, amask);
473         SDL_FillRect(pSurface, NULL, SDL_MapRGBA(pSurface->format, color.r, color.g, color.b, alpha));
474         SDL_Texture* pTextureRect = SDL_CreateTextureFromSurface(pRenderer, pSurface);
475 
476         SDL_FreeSurface(pSurface);
477 
478         return pTextureRect;
479     }
480 
PlayRandomHitSound()481     void PlayRandomHitSound()
482     {
483         static std::vector<std::string> hitSounds =
484         { SOUND_GAME_HIT1, SOUND_GAME_HIT2, SOUND_GAME_HIT3, SOUND_GAME_HIT4 };
485 
486         PlayRandomSoundFromList(hitSounds);
487     }
488 
489     // From MINIZ
CalcCRC32(const char * pData,size_t dataLen)490     uint32 CalcCRC32(const char* pData, size_t dataLen)
491     {
492         static const uint32 s_crc32[16] = { 0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
493             0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c };
494         uint32 crcu32 = (uint32)0;
495         if (!pData) return 0;
496         crcu32 = ~crcu32; while (dataLen--) { uint8 b = *pData++; crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b & 0xF)]; crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b >> 4)]; }
497         return ~crcu32;
498     }
499 };
500