1 /*-------------------------------------------------------------------------------
2 
3 	BARONY
4 	File: consolecommand.cpp
5 	Desc: contains consoleCommand()
6 
7 	Copyright 2013-2016 (c) Turning Wheel LLC, all rights reserved.
8 	See LICENSE for details.
9 
10 -------------------------------------------------------------------------------*/
11 #include <sstream>
12 #include "../main.hpp"
13 #include "../files.hpp"
14 #include "../game.hpp"
15 #include "../stat.hpp"
16 #include "../items.hpp"
17 #include "../init.hpp"
18 #include "../book.hpp"
19 #include "../sound.hpp"
20 #include "../menu.hpp"
21 #include "../monster.hpp"
22 #include "../net.hpp"
23 #include "../paths.hpp"
24 #include "../player.hpp"
25 #include "interface.hpp"
26 #include "../scores.hpp"
27 #include "../magic/magic.hpp"
28 #include "../mod_tools.hpp"
29 #include "../collision.hpp"
30 
31 bool spamming = false;
32 bool showfirst = false;
33 bool logCheckObstacle = false;
34 int logCheckObstacleCount = 0;
35 bool logCheckMainLoopTimers = false;
36 bool autoLimbReload = false;
37 
38 /*-------------------------------------------------------------------------------
39 
40 	consoleCommand
41 
42 	Takes a string and executes it as a game command
43 
44 -------------------------------------------------------------------------------*/
45 
consoleCommand(char const * const command_str)46 void consoleCommand(char const * const command_str)
47 {
48 	node_t* node;
49 	Entity* entity;
50 	char name[64];
51 	int c;
52 	bool invalidcommand = false;
53 
54 	if ( !command_str )
55 	{
56 		return;
57 	}
58 
59 	if ( !strncmp(command_str, "/ping", 5) )
60 	{
61 		if ( multiplayer != CLIENT )
62 		{
63 			messagePlayer(clientnum, language[1117], 0);
64 		}
65 		else
66 		{
67 			strcpy((char*)net_packet->data, "PING");
68 			net_packet->data[4] = clientnum;
69 			net_packet->address.host = net_server.host;
70 			net_packet->address.port = net_server.port;
71 			net_packet->len = 5;
72 			sendPacketSafe(net_sock, -1, net_packet, 0);
73 			pingtime = SDL_GetTicks();
74 		}
75 	}
76 	else if ( !strncmp(command_str, "/usemodelcache", 14) )
77 	{
78 		useModelCache = true;
79 	}
80 	else if ( !strncmp(command_str, "/disablemodelcache", 14) )
81 	{
82 		useModelCache = false;
83 	}
84 	else if (!strncmp(command_str, "/fov", 4))
85 	{
86 		fov = atoi(&command_str[5]);
87 		fov = std::min(std::max<Uint32>(40, fov), 100u);
88 	}
89 	else if ( !strncmp(command_str, "/fps", 4) )
90 	{
91 		fpsLimit = atoi(&command_str[5]);
92 		fpsLimit = std::min(std::max<Uint32>(30, fpsLimit), 144u);
93 	}
94 	else if (!strncmp(command_str, "/svflags ", 9))
95 	{
96 		if ( multiplayer == CLIENT )
97 		{
98 			messagePlayer(clientnum, language[275]);
99 		}
100 		else
101 		{
102 			svFlags = atoi(&command_str[9]);
103 			messagePlayer(clientnum, language[276]);
104 
105 			if ( multiplayer == SERVER )
106 			{
107 				// update client flags
108 				strcpy((char*)net_packet->data, "SVFL");
109 				SDLNet_Write32(svFlags, &net_packet->data[4]);
110 				net_packet->len = 8;
111 
112 				for ( int c = 1; c < MAXPLAYERS; c++ )
113 				{
114 					if ( client_disconnected[c] )
115 					{
116 						continue;
117 					}
118 					net_packet->address.host = net_clients[c - 1].host;
119 					net_packet->address.port = net_clients[c - 1].port;
120 					sendPacketSafe(net_sock, -1, net_packet, c - 1);
121 					messagePlayer(c, language[276]);
122 				}
123 			}
124 		}
125 	}
126 	else if ( !strncmp(command_str, "/lastname ", 10) )
127 	{
128 		strcpy(name, command_str + 10);
129 		lastname = (string)name;
130 		lastname = lastname.substr(0, lastname.size() - 1);
131 	}
132 	else if ( !strncmp(command_str, "/lastcharacter ", 15) )
133 	{
134 		int loadedValues = 0;
135 		for ( c = 0; c < strlen(command_str); ++c )
136 		{
137 			if ( command_str[c] == ' ' )
138 			{
139 				switch ( loadedValues )
140 				{
141 					case 0:
142 						lastCreatedCharacterSex = atoi(&command_str[c + 1]);
143 						break;
144 					case 1:
145 						lastCreatedCharacterClass = atoi(&command_str[c + 1]);
146 						break;
147 					case 2:
148 						lastCreatedCharacterAppearance = atoi(&command_str[c + 1]);
149 						break;
150 					case 3:
151 						lastCreatedCharacterRace = atoi(&command_str[c + 1]);
152 						break;
153 					default:
154 						break;
155 				}
156 				++loadedValues;
157 			}
158 		}
159 	}
160 	else if ( !strncmp(command_str, "/spawnitem ", 11) )
161 	{
162 		if ( !(svFlags & SV_FLAG_CHEATS) )
163 		{
164 			messagePlayer(clientnum, language[277]);
165 			return;
166 		}
167 		strcpy(name, command_str + 11);
168 		for ( c = 0; c < NUMITEMS; c++ )
169 		{
170 			if ( strstr(items[c].name_identified, name) )
171 			{
172 				dropItem(newItem(static_cast<ItemType>(c), EXCELLENT, 0, 1, rand(), true, &stats[clientnum]->inventory), 0);
173 				break;
174 			}
175 		}
176 		if ( c == NUMITEMS )
177 		{
178 			messagePlayer(clientnum, language[278], name);
179 		}
180 	}
181 	else if ( !strncmp(command_str, "/spawncursed ", 13) )
182 	{
183 		if ( !(svFlags & SV_FLAG_CHEATS) )
184 		{
185 			messagePlayer(clientnum, language[277]);
186 			return;
187 		}
188 		strcpy(name, command_str + 13);
189 		for ( c = 0; c < NUMITEMS; c++ )
190 		{
191 			if ( strstr(items[c].name_identified, name) )
192 			{
193 				dropItem(newItem(static_cast<ItemType>(c), WORN, -2, 1, rand(), false, &stats[clientnum]->inventory), 0);
194 				break;
195 			}
196 		}
197 		if ( c == NUMITEMS )
198 		{
199 			messagePlayer(clientnum, language[278], name);
200 		}
201 	}
202 	else if ( !strncmp(command_str, "/spawnblessed ", 14) )
203 	{
204 		if ( !(svFlags & SV_FLAG_CHEATS) )
205 		{
206 			messagePlayer(clientnum, language[277]);
207 			return;
208 		}
209 		strcpy(name, command_str + 14);
210 		for ( c = 0; c < NUMITEMS; ++c )
211 		{
212 			if ( strstr(items[c].name_identified, name) )
213 			{
214 				dropItem(newItem(static_cast<ItemType>(c), WORN, 2, 1, rand(), false, &stats[clientnum]->inventory), 0);
215 				break;
216 			}
217 		}
218 		if ( c == NUMITEMS )
219 		{
220 			messagePlayer(clientnum, language[278], name);
221 		}
222 	}
223 	else if ( !strncmp(command_str, "/kick ", 6) )
224 	{
225 		strcpy(name, command_str + 6);
226 		if ( multiplayer == SERVER )
227 		{
228 			for ( c = 1; c < MAXPLAYERS; c++ )
229 			{
230 				if ( !client_disconnected[c] && !strncmp(name, stats[c]->name, 128) )
231 				{
232 					client_disconnected[c] = true;
233 					strcpy((char*)net_packet->data, "KICK");
234 					net_packet->address.host = net_clients[c - 1].host;
235 					net_packet->address.port = net_clients[c - 1].port;
236 					net_packet->len = 4;
237 					sendPacketSafe(net_sock, -1, net_packet, c - 1);
238 					int i;
239 					for ( i = 0; i < MAXPLAYERS; i++ )
240 					{
241 						messagePlayer(i, language[279], c, stats[c]->name);
242 					}
243 					break;
244 				}
245 			}
246 			if ( c == MAXPLAYERS )
247 			{
248 				messagePlayer(clientnum, language[280]);
249 			}
250 		}
251 		else if ( multiplayer == CLIENT )
252 		{
253 			messagePlayer(clientnum, language[281]);
254 		}
255 		else
256 		{
257 			messagePlayer(clientnum, language[282]);
258 		}
259 	}
260 	else if ( !strncmp(command_str, "/spawnbook ", 11) )
261 	{
262 		if ( !(svFlags & SV_FLAG_CHEATS) )
263 		{
264 			messagePlayer(clientnum, language[277]);
265 			return;
266 		}
267 
268 		strcpy(name, command_str + 11);
269 		dropItem(newItem(READABLE_BOOK, EXCELLENT, 0, 1, getBook(name), true, &stats[clientnum]->inventory), 0);
270 	}
271 	else if ( !strncmp(command_str, "/savemap ", 9) )
272 	{
273 		if ( command_str[9] != 0 )
274 		{
275 			saveMap(command_str + 9);
276 			messagePlayer(clientnum, language[283], command_str + 9);
277 		}
278 	}
279 	else if ( !strncmp(command_str, "/nextlevel", 10) )
280 	{
281 		if ( !(svFlags & SV_FLAG_CHEATS) )
282 		{
283 			messagePlayer(clientnum, language[277]);
284 			return;
285 		}
286 		if ( multiplayer == CLIENT )
287 		{
288 			messagePlayer(clientnum, language[284]);
289 		}
290 		else
291 		{
292 			messagePlayer(clientnum, language[285]);
293 			loadnextlevel = true;
294 		}
295 	}
296 	else if ( !strncmp(command_str, "/pos", 4) )
297 	{
298 		if ( !(svFlags & SV_FLAG_CHEATS) )
299 		{
300 			messagePlayer(clientnum, language[277]);
301 			return;
302 		}
303 		messagePlayer(clientnum, language[286], (int)cameras[0].x, (int)cameras[0].y, (int)cameras[0].z, cameras[0].ang, cameras[0].vang);
304 	}
305 	else if ( !strncmp(command_str, "/pathmap", 4) )
306 	{
307 		if (!(svFlags & SV_FLAG_CHEATS))
308 		{
309 			messagePlayer(clientnum, language[277]);
310 			return;
311 		}
312 		if (players[clientnum] && players[clientnum]->entity)
313 		{
314 			int x = std::min<int>(std::max<int>(0, floor(players[clientnum]->entity->x / 16)), map.width - 1);
315 			int y = std::min<int>(std::max<int>(0, floor(players[clientnum]->entity->y / 16)), map.height - 1);
316 			messagePlayer(clientnum, "pathMapGrounded value: %d", pathMapGrounded[y + x * map.height]);
317 			messagePlayer(clientnum, "pathMapFlying value: %d", pathMapFlying[y + x * map.height]);
318 		}
319 	}
320 	else if ( !strncmp(command_str, "/exit", 5) )
321 	{
322 		mainloop = 0;
323 	}
324 	else if ( !strncmp(command_str, "/showfps", 8) )
325 	{
326 		showfps = (showfps == false);
327 	}
328 	else if ( !strncmp(command_str, "/noclip", 7) )
329 	{
330 		if ( !(svFlags & SV_FLAG_CHEATS) )
331 		{
332 			messagePlayer(clientnum, language[277]);
333 			return;
334 		}
335 		if ( multiplayer != SINGLE )
336 		{
337 			messagePlayer(clientnum, language[287]);
338 		}
339 		else
340 		{
341 			noclip = (noclip == false);
342 			if ( noclip )
343 			{
344 				messagePlayer(clientnum, language[288]);
345 			}
346 			else
347 			{
348 				messagePlayer(clientnum, language[289]);
349 			}
350 		}
351 	}
352 	else if ( !strncmp(command_str, "/god", 4) )
353 	{
354 		if ( !(svFlags & SV_FLAG_CHEATS) )
355 		{
356 			messagePlayer(clientnum, language[277]);
357 			return;
358 		}
359 		if ( multiplayer != SINGLE )
360 		{
361 			messagePlayer(clientnum, language[290]);
362 		}
363 		else
364 		{
365 			godmode = (godmode == false);
366 			if ( godmode )
367 			{
368 				messagePlayer(clientnum, language[291]);
369 			}
370 			else
371 			{
372 				messagePlayer(clientnum, language[292]);
373 			}
374 		}
375 	}
376 	else if ( !strncmp(command_str, "/spam", 5) )
377 	{
378 		spamming = !(spamming);
379 	}
380 	else if ( !strncmp(command_str, "/logobstacle", 12) )
381 	{
382 		logCheckObstacle = !(logCheckObstacle);
383 	}
384 	else if ( !strncmp(command_str, "/showfirst", 10) )
385 	{
386 		showfirst = !(showfirst);
387 	}
388 	else if ( !strncmp(command_str, "/buddha", 7) )
389 	{
390 		if ( multiplayer != SINGLE )
391 		{
392 			messagePlayer(clientnum, language[293]);
393 		}
394 		else
395 		{
396 			buddhamode = (buddhamode == false);
397 			if ( buddhamode )
398 			{
399 				messagePlayer(clientnum, language[294]);
400 			}
401 			else
402 			{
403 				messagePlayer(clientnum, language[295]);
404 			}
405 		}
406 	}
407 	else if ( !strncmp(command_str, "/friendly", 9) )
408 	{
409 		if ( !(svFlags & SV_FLAG_CHEATS) )
410 		{
411 			messagePlayer(clientnum, language[277]);
412 			return;
413 		}
414 		if ( multiplayer == CLIENT )
415 		{
416 			messagePlayer(clientnum, language[284]);
417 			return;
418 		}
419 		everybodyfriendly = (everybodyfriendly == false);
420 		if ( everybodyfriendly )
421 		{
422 			messagePlayer(clientnum, language[296]);
423 		}
424 		else
425 		{
426 			messagePlayer(clientnum, language[297]);
427 		}
428 	}
429 	else if ( !strncmp(command_str, "/dowse", 6) )
430 	{
431 		if ( !(svFlags & SV_FLAG_CHEATS) )
432 		{
433 			messagePlayer(clientnum, language[277]);
434 			return;
435 		}
436 		for ( node = map.entities->first; node != NULL; node = node->next )
437 		{
438 			entity = (Entity*)node->element;
439 			if ( entity->behavior == &actLadder )
440 			{
441 				messagePlayer(clientnum, language[298], (int)(entity->x / 16), (int)(entity->y / 16));
442 			}
443 		}
444 	}
445 	else if (!strncmp(command_str, "/thirdperson", 12))
446 	{
447 		/*if (!(svFlags & SV_FLAG_CHEATS))
448 		{
449 			messagePlayer(clientnum, language[277]);
450 			return;
451 		}*/
452 		if (players[clientnum] != nullptr && players[clientnum]->entity != nullptr)
453 		{
454 			players[clientnum]->entity->skill[3] = (players[clientnum]->entity->skill[3] == 0);
455 			if (players[clientnum]->entity->skill[3] == 1)
456 			{
457 				messagePlayer(clientnum, "thirdperson ON");
458 			}
459 			else
460 			{
461 				messagePlayer(clientnum, "thirdperson OFF");
462 			}
463 		}
464 	}
465 	else if ( !strncmp(command_str, "/res ", 5) )
466 	{
467 		xres = atoi(&command_str[5]);
468 		for ( c = 0; c < strlen(command_str); c++ )
469 		{
470 			if ( command_str[c] == 'x' )
471 			{
472 				yres = atoi(&command_str[c + 1]);
473 				break;
474 			}
475 		}
476 	}
477 	else if ( !strncmp(command_str, "/rscale", 7) )
478 	{
479 		rscale = atoi(&command_str[8]);
480 	}
481 	else if ( !strncmp(command_str, "/smoothlighting", 15) )
482 	{
483 		smoothlighting = (smoothlighting == 0);
484 	}
485 	else if ( !strncmp(command_str, "/fullscreen", 11) )
486 	{
487 		fullscreen = (fullscreen == 0);
488 	}
489 	else if ( !strncmp(command_str, "/shaking", 8) )
490 	{
491 		shaking = (shaking == 0);
492 	}
493 	else if ( !strncmp(command_str, "/bobbing", 8) )
494 	{
495 		bobbing = (bobbing == 0);
496 	}
497 	else if ( !strncmp(command_str, "/sfxvolume", 10) )
498 	{
499 		sfxvolume = atoi(&command_str[11]);
500 	}
501 	else if ( !strncmp(command_str, "/musvolume", 10) )
502 	{
503 		musvolume = atoi(&command_str[11]);
504 	}
505 	else if ( !strncmp(command_str, "/bind", 5) )
506 	{
507 		if ( strstr(command_str, "IN_FORWARD") )
508 		{
509 			impulses[IN_FORWARD] = atoi(&command_str[6]);
510 			printlog("Bound IN_FORWARD: %d\n", atoi(&command_str[6]));
511 		}
512 		else if ( strstr(command_str, "IN_LEFT") )
513 		{
514 			impulses[IN_LEFT] = atoi(&command_str[6]);
515 			printlog("Bound IN_LEFT: %d\n", atoi(&command_str[6]));
516 		}
517 		else if ( strstr(command_str, "IN_BACK") )
518 		{
519 			impulses[IN_BACK] = atoi(&command_str[6]);
520 			printlog("Bound IN_BACK: %d\n", atoi(&command_str[6]));
521 		}
522 		else if ( strstr(command_str, "IN_RIGHT") )
523 		{
524 			impulses[IN_RIGHT] = atoi(&command_str[6]);
525 			printlog("Bound IN_RIGHT: %d\n", atoi(&command_str[6]));
526 		}
527 		else if ( strstr(command_str, "IN_TURNL") )
528 		{
529 			impulses[IN_TURNL] = atoi(&command_str[6]);
530 			printlog("Bound IN_TURNL: %d\n", atoi(&command_str[6]));
531 		}
532 		else if ( strstr(command_str, "IN_TURNR") )
533 		{
534 			impulses[IN_TURNR] = atoi(&command_str[6]);
535 			printlog("Bound IN_TURNR: %d\n", atoi(&command_str[6]));
536 		}
537 		else if ( strstr(command_str, "IN_UP") )
538 		{
539 			impulses[IN_UP] = atoi(&command_str[6]);
540 			printlog("Bound IN_UP: %d\n", atoi(&command_str[6]));
541 		}
542 		else if ( strstr(command_str, "IN_DOWN") )
543 		{
544 			impulses[IN_DOWN] = atoi(&command_str[6]);
545 			printlog("Bound IN_DOWN: %d\n", atoi(&command_str[6]));
546 		}
547 		else if ( strstr(command_str, "IN_CHAT") )
548 		{
549 			impulses[IN_CHAT] = atoi(&command_str[6]);
550 			printlog("Bound IN_CHAT: %d\n", atoi(&command_str[6]));
551 		}
552 		else if ( strstr(command_str, "IN_COMMAND") )
553 		{
554 			impulses[IN_COMMAND] = atoi(&command_str[6]);
555 			printlog("Bound IN_COMMAND: %d\n", atoi(&command_str[6]));
556 		}
557 		else if ( strstr(command_str, "IN_STATUS") )
558 		{
559 			impulses[IN_STATUS] = atoi(&command_str[6]);
560 			printlog("Bound IN_STATUS: %d\n", atoi(&command_str[6]));
561 		}
562 		else if (strstr(command_str, "IN_SPELL_LIST"))
563 		{
564 			impulses[IN_SPELL_LIST] = atoi(&command_str[6]);
565 			printlog( "Bound IN_SPELL_LIST: %d\n", atoi(&command_str[6]));
566 		}
567 		else if (strstr(command_str, "IN_CAST_SPELL"))
568 		{
569 			impulses[IN_CAST_SPELL] = atoi(&command_str[6]);
570 			printlog( "Bound IN_CAST_SPELL: %d\n", atoi(&command_str[6]));
571 		}
572 		else if (strstr(command_str, "IN_DEFEND"))
573 		{
574 			impulses[IN_DEFEND] = atoi(&command_str[6]);
575 			printlog( "Bound IN_DEFEND: %d\n", atoi(&command_str[6]));
576 		}
577 		else if (strstr(command_str, "IN_ATTACK"))
578 		{
579 			impulses[IN_ATTACK] = atoi(&command_str[6]);
580 			printlog( "Bound IN_ATTACK: %d\n", atoi(&command_str[6]));
581 		}
582 		else if (strstr(command_str, "IN_USE"))
583 		{
584 			impulses[IN_USE] = atoi(&command_str[6]);
585 			printlog( "Bound IN_USE: %d\n", atoi(&command_str[6]));
586 		}
587 		else if ( strstr(command_str, "IN_AUTOSORT") )
588 		{
589 			impulses[IN_AUTOSORT] = atoi(&command_str[6]);
590 			printlog("Bound IN_AUTOSORT: %d\n", atoi(&command_str[6]));
591 		}
592 		else if ( strstr(command_str, "IN_MINIMAPSCALE") )
593 		{
594 			impulses[IN_MINIMAPSCALE] = atoi(&command_str[6]);
595 			printlog("Bound IN_MINIMAPSCALE: %d\n", atoi(&command_str[6]));
596 		}
597 		else if ( strstr(command_str, "IN_TOGGLECHATLOG") )
598 		{
599 			impulses[IN_TOGGLECHATLOG] = atoi(&command_str[6]);
600 			printlog("Bound IN_TOGGLECHATLOG: %d\n", atoi(&command_str[6]));
601 		}
602 		else if ( strstr(command_str, "IN_FOLLOWERMENU_OPEN") )
603 		{
604 			impulses[IN_FOLLOWERMENU] = atoi(&command_str[6]);
605 			printlog("Bound IN_FOLLOWERMENU_OPEN: %d\n", impulses[IN_FOLLOWERMENU]);
606 		}
607 		else if ( strstr(command_str, "IN_FOLLOWERMENU_LASTCMD") )
608 		{
609 			impulses[IN_FOLLOWERMENU_LASTCMD] = atoi(&command_str[6]);
610 			printlog("Bound IN_FOLLOWERMENU_LASTCMD: %d\n", impulses[IN_FOLLOWERMENU_LASTCMD]);
611 		}
612 		else if ( strstr(command_str, "IN_FOLLOWERMENU_CYCLENEXT") )
613 		{
614 			impulses[IN_FOLLOWERMENU_CYCLENEXT] = atoi(&command_str[6]);
615 			printlog("Bound IN_FOLLOWERMENU_CYCLENEXT: %d\n", impulses[IN_FOLLOWERMENU_CYCLENEXT]);
616 		}
617 		else if ( strstr(command_str, "IN_HOTBAR_SCROLL_LEFT") )
618 		{
619 			impulses[IN_HOTBAR_SCROLL_LEFT] = atoi(&command_str[6]);
620 			printlog("Bound IN_HOTBAR_SCROLL_LEFT: %d\n", impulses[IN_HOTBAR_SCROLL_LEFT]);
621 		}
622 		else if ( strstr(command_str, "IN_HOTBAR_SCROLL_RIGHT") )
623 		{
624 			impulses[IN_HOTBAR_SCROLL_RIGHT] = atoi(&command_str[6]);
625 			printlog("Bound IN_HOTBAR_SCROLL_RIGHT: %d\n", impulses[IN_HOTBAR_SCROLL_RIGHT]);
626 		}
627 		else if ( strstr(command_str, "IN_HOTBAR_SCROLL_SELECT") )
628 		{
629 			impulses[IN_HOTBAR_SCROLL_SELECT] = atoi(&command_str[6]);
630 			printlog("Bound IN_HOTBAR_SCROLL_SELECT: %d\n", impulses[IN_HOTBAR_SCROLL_SELECT]);
631 		}
632 		else
633 		{
634 			messagePlayer(clientnum, "Invalid binding.");
635 		}
636 	}
637 	else if (!strncmp(command_str, "/joybind", 8))
638 	{
639 		if (strstr(command_str, "INJOY_STATUS"))
640 		{
641 			joyimpulses[INJOY_STATUS] = atoi(&command_str[9]);
642 			printlog("[GAMEPAD] Bound INJOY_STATUS: %d\n", atoi(&command_str[9]));
643 		}
644 		else if (strstr(command_str, "INJOY_SPELL_LIST"))
645 		{
646 			joyimpulses[INJOY_SPELL_LIST] = atoi(&command_str[9]);
647 			printlog("[GAMEPAD] Bound INJOY_SPELL_LIST: %d\n", atoi(&command_str[9]));
648 		}
649 		else if (strstr(command_str, "INJOY_GAME_CAST_SPELL"))
650 		{
651 			joyimpulses[INJOY_GAME_CAST_SPELL] = atoi(&command_str[9]);
652 			printlog("[GAMEPAD] Bound INJOY_GAME_CAST_SPELL: %d\n", atoi(&command_str[9]));
653 		}
654 		else if (strstr(command_str, "INJOY_GAME_DEFEND"))
655 		{
656 			joyimpulses[INJOY_GAME_DEFEND] = atoi(&command_str[9]);
657 			printlog("[GAMEPAD] Bound INJOY_GAME_DEFEND: %d\n", atoi(&command_str[9]));
658 		}
659 		else if (strstr(command_str, "INJOY_GAME_ATTACK"))
660 		{
661 			joyimpulses[INJOY_GAME_ATTACK] = atoi(&command_str[9]);
662 			printlog("[GAMEPAD] Bound INJOY_GAME_ATTACK: %d\n", atoi(&command_str[9]));
663 		}
664 		else if (strstr(command_str, "INJOY_GAME_USE"))
665 		{
666 			joyimpulses[INJOY_GAME_USE] = atoi(&command_str[9]);
667 			printlog("[GAMEPAD] Bound INJOY_GAME_USE: %d\n", atoi(&command_str[9]));
668 		}
669 		else if (strstr(command_str, "INJOY_MENU_USE"))
670 		{
671 			joyimpulses[INJOY_MENU_USE] = atoi(&command_str[9]);
672 			printlog("[GAMEPAD] Bound INJOY_MENU_USE: %d\n", atoi(&command_str[9]));
673 		}
674 		else if (strstr(command_str, "INJOY_PAUSE_MENU"))
675 		{
676 			joyimpulses[INJOY_PAUSE_MENU] = atoi(&command_str[9]);
677 			printlog("[GAMEPAD] Bound INJOY_PAUSE_MENU: %d\n", atoi(&command_str[9]));
678 		}
679 		else if (strstr(command_str, "INJOY_MENU_LEFT_CLICK"))
680 		{
681 			joyimpulses[INJOY_MENU_LEFT_CLICK] = atoi(&command_str[9]);
682 			printlog("[GAMEPAD] Bound INJOY_MENU_LEFT_CLICK: %d\n", atoi(&command_str[9]));
683 		}
684 		else if (strstr(command_str, "INJOY_DPAD_LEFT"))
685 		{
686 			joyimpulses[INJOY_DPAD_LEFT] = atoi(&command_str[9]);
687 			printlog("[GAMEPAD] Bound INJOY_DPAD_LEFT: %d\n", atoi(&command_str[9]));
688 		}
689 		else if (strstr(command_str, "INJOY_DPAD_RIGHT"))
690 		{
691 			joyimpulses[INJOY_DPAD_RIGHT] = atoi(&command_str[9]);
692 			printlog("[GAMEPAD] Bound INJOY_DPAD_RIGHT: %d\n", atoi(&command_str[9]));
693 		}
694 		else if (strstr(command_str, "INJOY_DPAD_UP"))
695 		{
696 			joyimpulses[INJOY_DPAD_UP] = atoi(&command_str[9]);
697 			printlog("[GAMEPAD] Bound INJOY_DPAD_UP: %d\n", atoi(&command_str[9]));
698 		}
699 		else if (strstr(command_str, "INJOY_DPAD_DOWN"))
700 		{
701 			joyimpulses[INJOY_DPAD_DOWN] = atoi(&command_str[9]);
702 			printlog("[GAMEPAD] Bound INJOY_DPAD_DOWN: %d\n", atoi(&command_str[9]));
703 		}
704 		else if (strstr(command_str, "INJOY_MENU_NEXT"))
705 		{
706 			joyimpulses[INJOY_MENU_NEXT] = atoi(&command_str[9]);
707 			printlog("[GAMEPAD] Bound INJOY_MENU_NEXT: %d\n", atoi(&command_str[9]));
708 		}
709 		else if (strstr(command_str, "INJOY_GAME_HOTBAR_NEXT"))
710 		{
711 			joyimpulses[INJOY_GAME_HOTBAR_NEXT] = atoi(&command_str[9]);
712 			printlog("[GAMEPAD] Bound INJOY_GAME_HOTBAR_NEXT: %d\n", atoi(&command_str[9]));
713 		}
714 		else if (strstr(command_str, "INJOY_GAME_HOTBAR_PREV"))
715 		{
716 			joyimpulses[INJOY_GAME_HOTBAR_PREV] = atoi(&command_str[9]);
717 			printlog("[GAMEPAD] Bound INJOY_GAME_HOTBAR_PREV: %d\n", atoi(&command_str[9]));
718 		}
719 		else if (strstr(command_str, "INJOY_GAME_HOTBAR_ACTIVATE"))
720 		{
721 			joyimpulses[INJOY_GAME_HOTBAR_ACTIVATE] = atoi(&command_str[9]);
722 			printlog("[GAMEPAD] Bound INJOY_GAME_HOTBAR_ACTIVATE: %d\n", atoi(&command_str[9]));
723 		}
724 		else if ( strstr(command_str, "INJOY_GAME_HOTBAR_ACTIVATE") )
725 		{
726 			joyimpulses[INJOY_GAME_HOTBAR_ACTIVATE] = atoi(&command_str[9]);
727 			printlog("[GAMEPAD] Bound INJOY_GAME_HOTBAR_ACTIVATE: %d\n", atoi(&command_str[9]));
728 		}
729 		else if ( strstr(command_str, "INJOY_GAME_GAME_MINIMAPSCALE") )
730 		{
731 			joyimpulses[INJOY_GAME_MINIMAPSCALE] = atoi(&command_str[9]);
732 			printlog("[GAMEPAD] Bound INJOY_GAME_GAME_MINIMAPSCALE: %d\n", atoi(&command_str[9]));
733 		}
734 		else if ( strstr(command_str, "INJOY_GAME_GAME_TOGGLECHATLOG") )
735 		{
736 			joyimpulses[INJOY_GAME_TOGGLECHATLOG] = atoi(&command_str[9]);
737 			printlog("[GAMEPAD] Bound INJOY_GAME_GAME_TOGGLECHATLOG: %d\n", atoi(&command_str[9]));
738 		}
739 		else if ( strstr(command_str, "INJOY_GAME_GAME_FOLLOWERMENU_OPEN") )
740 		{
741 			joyimpulses[INJOY_GAME_FOLLOWERMENU] = atoi(&command_str[9]);
742 			printlog("[GAMEPAD] Bound INJOY_GAME_GAME_FOLLOWERMENU_OPEN: %d\n", atoi(&command_str[9]));
743 		}
744 		else if ( strstr(command_str, "INJOY_GAME_GAME_FOLLOWERMENU_LASTCMD") )
745 		{
746 			joyimpulses[INJOY_GAME_FOLLOWERMENU_LASTCMD] = atoi(&command_str[9]);
747 			printlog("[GAMEPAD] Bound INJOY_GAME_GAME_FOLLOWERMENU_LASTCMD: %d\n", atoi(&command_str[9]));
748 		}
749 		else if ( strstr(command_str, "INJOY_GAME_GAME_FOLLOWERMENU_CYCLENEXT") )
750 		{
751 			joyimpulses[INJOY_GAME_FOLLOWERMENU_CYCLE] = atoi(&command_str[9]);
752 			printlog("[GAMEPAD] Bound INJOY_GAME_GAME_FOLLOWERMENU_CYCLENEXT: %d\n", atoi(&command_str[9]));
753 		}
754 		else if ( strstr(command_str, "INJOY_MENU_CHEST_GRAB_ALL"))
755 		{
756 			joyimpulses[INJOY_MENU_CHEST_GRAB_ALL] = atoi(&command_str[9]);
757 			printlog("[GAMEPAD] Bound INJOY_MENU_CHEST_GRAB_ALL: %d\n", atoi(&command_str[9]));
758 		}
759 		else if (strstr(command_str, "INJOY_MENU_HOTBAR_CLEAR"))
760 		{
761 			joyimpulses[INJOY_MENU_HOTBAR_CLEAR] = atoi(&command_str[9]);
762 			printlog("[GAMEPAD] Bound INJOY_MENU_HOTBAR_CLEAR: %d\n", atoi(&command_str[9]));
763 		}
764 		else if (strstr(command_str, "INJOY_MENU_REFRESH_LOBBY"))
765 		{
766 			joyimpulses[INJOY_MENU_REFRESH_LOBBY] = atoi(&command_str[9]);
767 			printlog("[GAMEPAD] Bound INJOY_MENU_REFRESH_LOBBY: %d\n", atoi(&command_str[9]));
768 		}
769 		else if (strstr(command_str, "INJOY_MENU_DONT_LOAD_SAVE"))
770 		{
771 			joyimpulses[INJOY_MENU_DONT_LOAD_SAVE] = atoi(&command_str[9]);
772 			printlog("[GAMEPAD] Bound INJOY_MENU_DONT_LOAD_SAVE: %d\n", atoi(&command_str[9]));
773 		}
774 		else if (strstr(command_str, "INJOY_MENU_RANDOM_CHAR"))
775 		{
776 			joyimpulses[INJOY_MENU_RANDOM_CHAR] = atoi(&command_str[9]);
777 			printlog("[GAMEPAD] Bound INJOY_MENU_RANDOM_CHAR: %d\n", atoi(&command_str[9]));
778 		}
779 		else if (strstr(command_str, "INJOY_MENU_CANCEL"))
780 		{
781 			joyimpulses[INJOY_MENU_CANCEL] = atoi(&command_str[9]);
782 			printlog("[GAMEPAD] Bound INJOY_MENU_CANCEL: %d\n", atoi(&command_str[9]));
783 		}
784 		else if (strstr(command_str, "INJOY_MENU_DROP_ITEM"))
785 		{
786 			joyimpulses[INJOY_MENU_DROP_ITEM] = atoi(&command_str[9]);
787 			printlog("[GAMEPAD] Bound INJOY_MENU_DROP_ITEM: %d\n", atoi(&command_str[9]));
788 		}
789 		else if (strstr(command_str, "INJOY_MENU_CYCLE_SHOP_LEFT"))
790 		{
791 			joyimpulses[INJOY_MENU_CYCLE_SHOP_LEFT] = atoi(&command_str[9]);
792 			printlog("[GAMEPAD] Bound INJOY_MENU_CYCLE_SHOP_LEFT: %d\n", atoi(&command_str[9]));
793 		}
794 		else if (strstr(command_str, "INJOY_MENU_CYCLE_SHOP_RIGHT"))
795 		{
796 			joyimpulses[INJOY_MENU_CYCLE_SHOP_RIGHT] = atoi(&command_str[9]);
797 			printlog("[GAMEPAD] Bound INJOY_MENU_CYCLE_SHOP_RIGHT: %d\n", atoi(&command_str[9]));
798 		}
799 		else if (strstr(command_str, "INJOY_MENU_BOOK_NEXT"))
800 		{
801 			joyimpulses[INJOY_MENU_BOOK_NEXT] = atoi(&command_str[9]);
802 			printlog("[GAMEPAD] Bound INJOY_MENU_BOOK_NEXT: %d\n", atoi(&command_str[9]));
803 		}
804 		else if (strstr(command_str, "INJOY_MENU_BOOK_PREV"))
805 		{
806 			joyimpulses[INJOY_MENU_BOOK_PREV] = atoi(&command_str[9]);
807 			printlog("[GAMEPAD] Bound INJOY_MENU_BOOK_PREV: %d\n", atoi(&command_str[9]));
808 		}
809 		else if (strstr(command_str, "INJOY_MENU_SETTINGS_NEXT"))
810 		{
811 			joyimpulses[INJOY_MENU_SETTINGS_NEXT] = atoi(&command_str[9]);
812 			printlog("[GAMEPAD] Bound INJOY_MENU_SETTINGS_NEXT: %d\n", atoi(&command_str[9]));
813 		}
814 		else if (strstr(command_str, "INJOY_MENU_SETTINGS_PREV"))
815 		{
816 			joyimpulses[INJOY_MENU_SETTINGS_PREV] = atoi(&command_str[9]);
817 			printlog("[GAMEPAD] Bound INJOY_MENU_SETTINGS_PREV: %d\n", atoi(&command_str[9]));
818 		}
819 		else if (strstr(command_str, "INJOY_MENU_INVENTORY_TAB"))
820 		{
821 			joyimpulses[INJOY_MENU_INVENTORY_TAB] = atoi(&command_str[9]);
822 			printlog("[GAMEPAD] Bound INJOY_MENU_INVENTORY_TAB: %d\n", atoi(&command_str[9]));
823 		}
824 		else if (strstr(command_str, "INJOY_MENU_MAGIC_TAB"))
825 		{
826 			joyimpulses[INJOY_MENU_MAGIC_TAB] = atoi(&command_str[9]);
827 			printlog("[GAMEPAD] Bound INJOY_MENU_MAGIC_TAB: %d\n", atoi(&command_str[9]));
828 		}
829 		else if ( strstr(command_str, "INJOY_MENU_RANDOM_NAME") )
830 		{
831 			joyimpulses[INJOY_MENU_RANDOM_NAME] = atoi(&command_str[9]);
832 			printlog("[GAMEPAD] Bound INJOY_MENU_RANDOM_NAME: %d\n", atoi(&command_str[9]));
833 		}
834 		else
835 		{
836 			messagePlayer(clientnum, "Invalid binding.");
837 		}
838 	}
839 	else if ( !strncmp(command_str, "/mousespeed", 11) )
840 	{
841 		mousespeed = atoi(&command_str[12]);
842 	}
843 	else if ( !strncmp(command_str, "/reversemouse", 13) )
844 	{
845 		reversemouse = (reversemouse == 0);
846 	}
847 	else if ( !strncmp(command_str, "/smoothmouse", 12) )
848 	{
849 		smoothmouse = (smoothmouse == false);
850 	}
851 	else if ( !strncmp(command_str, "/mana", 4) )
852 	{
853 		if ( !(svFlags & SV_FLAG_CHEATS) )
854 		{
855 			messagePlayer(clientnum, language[277]);
856 			return;
857 		}
858 
859 		if ( multiplayer == SINGLE )
860 		{
861 			stats[clientnum]->MP = stats[clientnum]->MAXMP;
862 		}
863 		else
864 		{
865 			messagePlayer(clientnum, language[299]);
866 		}
867 	}
868 	else if ( !strncmp(command_str, "/heal", 4) )
869 	{
870 		if ( !(svFlags & SV_FLAG_CHEATS) )
871 		{
872 			messagePlayer(clientnum, language[277]);
873 			return;
874 		}
875 
876 		if ( multiplayer == SINGLE )
877 		{
878 			stats[clientnum]->HP = stats[clientnum]->MAXHP;
879 		}
880 		else
881 		{
882 			messagePlayer(clientnum, language[299]);
883 		}
884 	}
885 	else if ( !strncmp(command_str, "/damage ", 8) )
886 	{
887 		if ( !(svFlags & SV_FLAG_CHEATS) )
888 		{
889 			messagePlayer(clientnum, language[277]);
890 			return;
891 		}
892 		if ( multiplayer != SINGLE )
893 		{
894 			messagePlayer(clientnum, language[299]);
895 			return;
896 		}
897 
898 		int amount = atoi(&command_str[8]);
899 
900 		players[clientnum]->entity->modHP(-amount);
901 
902 		messagePlayer(clientnum, "Damaging you by %d. New health: %d", amount, stats[clientnum]->HP);
903 	}
904 	else if (!strncmp(command_str, "/ip ", 4))
905 	{
906 		if ( command_str[4] != 0 )
907 		{
908 			strcpy(last_ip, command_str + 4);
909 			last_ip[strlen(last_ip) - 1] = 0;
910 		}
911 	}
912 	else if (!strncmp(command_str, "/port ", 6))
913 	{
914 		if (command_str[6] != 0)
915 		{
916 			strcpy(last_port, command_str + 6);
917 			last_port[strlen(last_port) - 1] = 0;
918 		}
919 	}
920 	else if (!strncmp(command_str, "/noblood", 8))
921 	{
922 		spawn_blood = (spawn_blood == false);
923 	}
924 	else if (!strncmp(command_str, "/nolightflicker", 15))
925 	{
926 		flickerLights = (flickerLights == false);
927 	}
928 	else if ( !strncmp(command_str, "/vsync", 6) )
929 	{
930 		verticalSync = (verticalSync == false);
931 	}
932 	else if ( !strncmp(command_str, "/hidestatusicons", 16) )
933 	{
934 		showStatusEffectIcons = (showStatusEffectIcons == false);
935 	}
936 	else if ( !strncmp(command_str, "/muteping", 9) )
937 	{
938 		minimapPingMute = (minimapPingMute == false);
939 	}
940 	else if (!strncmp(command_str, "/colorblind", 11))
941 	{
942 		colorblind = (colorblind == false);
943 	}
944 	else if (!strncmp(command_str, "/gamma", 6))
945 	{
946 		std::stringstream ss;
947 		ss << command_str + 7;
948 		ss >> vidgamma;
949 	}
950 	else if (!strncmp(command_str, "/capturemouse", 13))
951 	{
952 		capture_mouse = (capture_mouse == false);
953 	}
954 	else if (!strncmp(command_str, "/levelup", 8))
955 	{
956 		if ( !(svFlags & SV_FLAG_CHEATS) )
957 		{
958 			messagePlayer(clientnum, language[277]);
959 			return;
960 		}
961 
962 		if (multiplayer != CLIENT)
963 		{
964 			if (players[clientnum] && players[clientnum]->entity)
965 			{
966 				players[clientnum]->entity->getStats()->EXP += 100;
967 			}
968 		}
969 		else if ( multiplayer == CLIENT )
970 		{
971 			// request level up
972 			strcpy((char*)net_packet->data, "CLVL");
973 			net_packet->data[4] = clientnum;
974 			net_packet->address.host = net_server.host;
975 			net_packet->address.port = net_server.port;
976 			net_packet->len = 5;
977 			sendPacketSafe(net_sock, -1, net_packet, 0);
978 			//messagePlayer(clientnum, language[299]);
979 		}
980 	}
981 	else if ( !strncmp(command_str, "/maxout2", 8) )
982 	{
983 		if ( !(svFlags & SV_FLAG_CHEATS) )
984 		{
985 			messagePlayer(clientnum, language[277]);
986 			return;
987 		}
988 
989 		if ( multiplayer != CLIENT )
990 		{
991 			int c;
992 			Stat* myStats = stats[0];
993 			for ( c = 0; c < 24; c++ )
994 			{
995 				consoleCommand("/levelup");
996 			}
997 			for ( c = 0; c < NUM_HOTBAR_SLOTS; c++ )
998 			{
999 				hotbar[c].item = 0;
1000 			}
1001 			myStats->weapon = newItem(STEEL_SWORD, SERVICABLE, 0, 1, rand(), true, &myStats->inventory);
1002 			newItem(CROSSBOW, SERVICABLE, 0, 1, rand(), true, &myStats->inventory);
1003 			newItem(MAGICSTAFF_LIGHT, SERVICABLE, 0, 1, rand(), true, &myStats->inventory);
1004 			myStats->shield = newItem(STEEL_SHIELD, SERVICABLE, 0, 1, rand(), true, &myStats->inventory);
1005 			myStats->helmet = newItem(HAT_HOOD, SERVICABLE, 0, 1, 2, true, &myStats->inventory);
1006 			myStats->shoes = newItem(STEEL_BOOTS, SERVICABLE, 0, 1, rand(), true, &myStats->inventory);
1007 			myStats->breastplate = newItem(STEEL_BREASTPIECE, SERVICABLE, 0, 1, rand(), true, &myStats->inventory);
1008 			myStats->gloves = newItem(GAUNTLETS, SERVICABLE, 0, 1, rand(), true, &myStats->inventory);
1009 			myStats->cloak = newItem(CLOAK_BLACK, SERVICABLE, 0, 1, rand(), true, &myStats->inventory);
1010 		}
1011 		else
1012 		{
1013 			for ( int c = 0; c < 24; c++ )
1014 			{
1015 				consoleCommand("/levelup");
1016 			}
1017 			//messagePlayer(clientnum, language[299]);
1018 		}
1019 	}
1020 	else if ( !strncmp(command_str, "/jumplevel ", 11) )
1021 	{
1022 		if ( !(svFlags & SV_FLAG_CHEATS) )
1023 		{
1024 			messagePlayer(clientnum, language[277]);
1025 			return;
1026 		}
1027 		skipLevelsOnLoad = atoi((char*)(command_str + 11));
1028 		if ( skipLevelsOnLoad == -1 )
1029 		{
1030 			loadingSameLevelAsCurrent = true;
1031 		}
1032 		consoleCommand("/nextlevel");
1033 	}
1034 	else if ( !strncmp(command_str, "/maxout3", 8) )
1035 	{
1036 		if ( !(svFlags & SV_FLAG_CHEATS) )
1037 		{
1038 			messagePlayer(clientnum, language[277]);
1039 			return;
1040 		}
1041 
1042 		if ( multiplayer == SINGLE )
1043 		{
1044 			int c;
1045 			Stat* myStats = stats[0];
1046 			skipLevelsOnLoad = 31;
1047 			for ( c = 0; c < 24; c++ )
1048 			{
1049 				consoleCommand("/levelup");
1050 			}
1051 			for ( c = 0; c < NUM_HOTBAR_SLOTS; c++ )
1052 			{
1053 				hotbar[c].item = 0;
1054 			}
1055 			myStats->weapon = newItem(STEEL_SWORD, SERVICABLE, 0, 1, rand(), true, &myStats->inventory);
1056 			newItem(CROSSBOW, SERVICABLE, 0, 1, rand(), true, &myStats->inventory);
1057 			newItem(MAGICSTAFF_LIGHT, SERVICABLE, 0, 1, rand(), true, &myStats->inventory);
1058 			myStats->shield = newItem(STEEL_SHIELD, SERVICABLE, 0, 1, rand(), true, &myStats->inventory);
1059 			myStats->helmet = newItem(HAT_HOOD, SERVICABLE, 0, 1, 2, true, &myStats->inventory);
1060 			myStats->shoes = newItem(STEEL_BOOTS, SERVICABLE, 0, 1, rand(), true, &myStats->inventory);
1061 			myStats->breastplate = newItem(STEEL_BREASTPIECE, SERVICABLE, 0, 1, rand(), true, &myStats->inventory);
1062 			myStats->gloves = newItem(GAUNTLETS, SERVICABLE, 0, 1, rand(), true, &myStats->inventory);
1063 			myStats->cloak = newItem(CLOAK_BLACK, SERVICABLE, 0, 1, rand(), true, &myStats->inventory);
1064 			consoleCommand("/levelskill 9");
1065 			//consoleCommand("/nextlevel");
1066 			while ( myStats->PROFICIENCIES[PRO_APPRAISAL] < 50 )
1067 			{
1068 				consoleCommand("/levelskill 3");
1069 			}
1070 		}
1071 		else
1072 		{
1073 			messagePlayer(clientnum, language[299]);
1074 		}
1075 	}
1076 	else if ( !strncmp(command_str, "/maxout4", 8) )
1077 	{
1078 		if ( !(svFlags & SV_FLAG_CHEATS) )
1079 		{
1080 			messagePlayer(clientnum, language[277]);
1081 			return;
1082 		}
1083 
1084 		if ( multiplayer == SINGLE )
1085 		{
1086 			int c;
1087 			Stat* myStats = stats[0];
1088 			for ( c = 0; c < 35; c++ )
1089 			{
1090 				consoleCommand("/levelup");
1091 			}
1092 			for ( c = 0; c < NUM_HOTBAR_SLOTS; c++ )
1093 			{
1094 				hotbar[c].item = 0;
1095 			}
1096 			myStats->weapon = newItem(STEEL_SWORD, SERVICABLE, 0, 1, rand(), true, &myStats->inventory);
1097 			newItem(CROSSBOW, SERVICABLE, 0, 1, rand(), true, &myStats->inventory);
1098 			newItem(MAGICSTAFF_LIGHT, SERVICABLE, 0, 1, rand(), true, &myStats->inventory);
1099 			myStats->shield = newItem(STEEL_SHIELD, SERVICABLE, 0, 1, rand(), true, &myStats->inventory);
1100 			myStats->helmet = newItem(HAT_HOOD, SERVICABLE, 0, 1, 2, true, &myStats->inventory);
1101 			myStats->shoes = newItem(STEEL_BOOTS, SERVICABLE, 0, 1, rand(), true, &myStats->inventory);
1102 			myStats->breastplate = newItem(STEEL_BREASTPIECE, SERVICABLE, 0, 1, rand(), true, &myStats->inventory);
1103 			myStats->gloves = newItem(GAUNTLETS, SERVICABLE, 0, 1, rand(), true, &myStats->inventory);
1104 			myStats->cloak = newItem(CLOAK_BLACK, SERVICABLE, 0, 1, rand(), true, &myStats->inventory);
1105 			//consoleCommand("/nextlevel");
1106 			for ( c = 0; c < NUMPROFICIENCIES; c++ )
1107 			{
1108 				if ( c != PRO_STEALTH )
1109 				{
1110 					while ( stats[clientnum]->PROFICIENCIES[c] < 100 )
1111 					{
1112 						//++stats[clientnum]->PROFICIENCIES[c];
1113 						players[clientnum]->entity->increaseSkill(c);
1114 					}
1115 				}
1116 			}
1117 		}
1118 		else
1119 		{
1120 			messagePlayer(clientnum, language[299]);
1121 		}
1122 	}
1123 	else if (!strncmp(command_str, "/maxout", 7))
1124 	{
1125 		if ( !(svFlags & SV_FLAG_CHEATS) )
1126 		{
1127 			messagePlayer(clientnum, language[277]);
1128 			return;
1129 		}
1130 
1131 		if ( multiplayer == SINGLE )
1132 		{
1133 			int c;
1134 			for ( c = 0; c < 14; c++ )
1135 			{
1136 				consoleCommand("/levelup");
1137 			}
1138 			consoleCommand("/spawnitem steel breastpiece");
1139 			consoleCommand("/spawnitem steel boots");
1140 			consoleCommand("/spawnitem steel gauntlets");
1141 			consoleCommand("/spawnitem steel helm");
1142 			consoleCommand("/spawnitem cloak of magic");
1143 			consoleCommand("/spawnitem steel shield of magic");
1144 			consoleCommand("/spawnitem steel sword");
1145 			consoleCommand("/spawnitem crossbow");
1146 			consoleCommand("/spawnitem magicstaff of lightning");
1147 			for ( c = 0; c < NUMPROFICIENCIES; c++ )
1148 			{
1149 				//for ( int j = 0; j < 100; ++j )
1150 				while ( stats[clientnum]->PROFICIENCIES[c] < 100 )
1151 				{
1152 					//++stats[clientnum]->PROFICIENCIES[c];
1153 					players[clientnum]->entity->increaseSkill(c);
1154 				}
1155 			}
1156 		}
1157 		else
1158 		{
1159 			messagePlayer(clientnum, language[299]);
1160 		}
1161 	}
1162 	else if (!strncmp(command_str, "/hunger", 7))
1163 	{
1164 		if ( !(svFlags & SV_FLAG_CHEATS) )
1165 		{
1166 			messagePlayer(clientnum, language[277]);
1167 			return;
1168 		}
1169 
1170 		if ( multiplayer == SINGLE )
1171 		{
1172 			Stat* tempStats = players[clientnum]->entity->getStats();
1173 			if ( tempStats )
1174 			{
1175 				tempStats->HUNGER = std::max(0, tempStats->HUNGER - 100);
1176 			}
1177 		}
1178 		else
1179 		{
1180 			messagePlayer(clientnum, language[299]);
1181 		}
1182 	}
1183 	else if (!strncmp(command_str, "/poison", 7))
1184 	{
1185 		if ( !(svFlags & SV_FLAG_CHEATS) )
1186 		{
1187 			messagePlayer(clientnum, language[277]);
1188 			return;
1189 		}
1190 
1191 		if ( multiplayer == SINGLE )
1192 		{
1193 			Stat* tempStats = players[clientnum]->entity->getStats();
1194 			if ( tempStats )
1195 			{
1196 				tempStats->EFFECTS[EFF_POISONED] = true;
1197 				tempStats->EFFECTS_TIMERS[EFF_POISONED] = 600;
1198 			}
1199 		}
1200 		else
1201 		{
1202 			messagePlayer(clientnum, language[299]);
1203 		}
1204 	}
1205 	else if (!strncmp(command_str, "/testsound ", 11))
1206 	{
1207 		int num = 0;
1208 		//snprintf((char *)(command_str + 11), strlen(command_str)-11, "%d", num);
1209 		//printlog( "Number is %d. Original is: \"%s\"\n", num, (char *)(&command_str[11]));
1210 		num = atoi((char*)(command_str + 11));
1211 		playSound(num, 256);
1212 	}
1213 	else if (!strncmp(command_str, "/skipintro", 10))
1214 	{
1215 		skipintro = (skipintro == false);
1216 	}
1217 	else if (!strncmp(command_str, "/levelmagic", 11))
1218 	{
1219 		if ( !(svFlags & SV_FLAG_CHEATS) )
1220 		{
1221 			messagePlayer(clientnum, language[277]);
1222 			return;
1223 		}
1224 
1225 		if (multiplayer == SINGLE)
1226 		{
1227 			int i = 0;
1228 			for (; i < 10; ++i)
1229 			{
1230 				players[clientnum]->entity->increaseSkill(PRO_MAGIC);
1231 				players[clientnum]->entity->increaseSkill(PRO_SPELLCASTING);
1232 			}
1233 		}
1234 		else
1235 		{
1236 			messagePlayer(clientnum, language[299]);
1237 		}
1238 	}
1239 	else if (!strncmp(command_str, "/numentities", 12))
1240 	{
1241 		messagePlayer(clientnum, language[300], list_Size(map.entities));
1242 	}
1243 	else if ( !strncmp(command_str, "/nummonsters2", 13) )
1244 	{
1245 		messagePlayer(clientnum, language[2353], list_Size(map.creatures));
1246 	}
1247 	else if ( !strncmp(command_str, "/nummonsters", 12) )
1248 	{
1249 		messagePlayer(clientnum, language[2353], nummonsters);
1250 	}
1251 	else if ( !strncmp(command_str, "/verifycreaturelist", strlen("/verifycreaturelist")) )
1252 	{
1253 		//Make sure that the number of creatures in the creature list are the real count in the game world.
1254 		unsigned entcount = 0;
1255 
1256 		for ( node_t* node = map.entities->first; node; node = node->next )
1257 		{
1258 			if ( node->element )
1259 			{
1260 				Entity* ent = static_cast<Entity*>(node->element);
1261 				if ( ent->behavior == actMonster || ent->behavior == actPlayer )
1262 				{
1263 					++entcount;
1264 				}
1265 			}
1266 		}
1267 
1268 		messagePlayer(clientnum, "ent count = %d, creatures list size = %d", entcount, list_Size(map.creatures));
1269 
1270 		if ( entcount == list_Size(map.creatures) )
1271 		{
1272 			messagePlayer(clientnum, "Yes, list is verified correct.");
1273 		}
1274 		else
1275 		{
1276 			messagePlayer(clientnum, "Nope, much problemo!");
1277 		}
1278 	}
1279 	else if ( !strncmp(command_str, "/loadmodels ", 12) )
1280 	{
1281 		char name2[128];
1282 		char buf[16] = "";
1283 		int startIndex = 0;
1284 		int endIndex = nummodels;
1285 		int i = 0;
1286 		strcpy(name, command_str + 12);
1287 		for ( c = 0; name[c] != '\0'; c++ )
1288 		{
1289 			if ( name[c] == ' ' && startIndex == 0 )
1290 			{
1291 				startIndex = atoi(buf);
1292 				strcpy(buf, "");
1293 				i = 0;
1294 				continue;
1295 			}
1296 			buf[i] = name[c];
1297 			i++;
1298 		}
1299 
1300 		if ( startIndex != 0 )
1301 		{
1302 			endIndex = atoi(buf);
1303 			if ( endIndex > nummodels || endIndex < startIndex )
1304 			{
1305 				endIndex = nummodels;
1306 			}
1307 		}
1308 
1309 		std::string modelsDirectory = PHYSFS_getRealDir("models/models.txt");
1310 		modelsDirectory.append(PHYSFS_getDirSeparator()).append("models/models.txt");
1311 		FILE *fp = openDataFile(modelsDirectory.c_str(), "r");
1312 		for ( c = 0; !feof(fp); c++ )
1313 		{
1314 			fscanf(fp, "%s", name2);
1315 			while ( fgetc(fp) != '\n' ) if ( feof(fp) )
1316 			{
1317 				break;
1318 			}
1319 			if ( c >= startIndex && c < endIndex )
1320 			{
1321 				if ( models[c] != NULL )
1322 				{
1323 					if ( models[c]->data )
1324 					{
1325 						free(models[c]->data);
1326 					}
1327 					free(models[c]);
1328 					if ( polymodels[c].faces )
1329 					{
1330 						free(polymodels[c].faces);
1331 					}
1332 					if ( polymodels[c].vbo )
1333 					{
1334 						SDL_glDeleteBuffers(1, &polymodels[c].vbo);
1335 					}
1336 					if ( polymodels[c].colors )
1337 					{
1338 						SDL_glDeleteBuffers(1, &polymodels[c].colors);
1339 					}
1340 					if ( polymodels[c].va )
1341 					{
1342 						SDL_glDeleteVertexArrays(1, &polymodels[c].va);
1343 					}
1344 					if ( polymodels[c].colors_shifted )
1345 					{
1346 						SDL_glDeleteBuffers(1, &polymodels[c].colors_shifted);
1347 					}
1348 				}
1349 				models[c] = loadVoxel(name2);
1350 			}
1351 		}
1352 		fclose(fp);
1353 		//messagePlayer(clientnum, language[2354]);
1354 		messagePlayer(clientnum, language[2355], startIndex, endIndex);
1355 		generatePolyModels(startIndex, endIndex, true);
1356 	}
1357 	else if (!strncmp(command_str, "/killmonsters", 13))
1358 	{
1359 		if ( !(svFlags & SV_FLAG_CHEATS) )
1360 		{
1361 			messagePlayer(clientnum, language[277]);
1362 			return;
1363 		}
1364 		if ( multiplayer == CLIENT )
1365 		{
1366 			messagePlayer(clientnum, language[284]);
1367 		}
1368 		else
1369 		{
1370 			int c = 0;
1371 			node_t* node, *nextnode;
1372 			for ( node = map.entities->first; node != NULL; node = nextnode )
1373 			{
1374 				nextnode = node->next;
1375 				Entity* entity = (Entity*)node->element;
1376 				if ( entity->behavior == &actMonster )
1377 				{
1378 					entity->setHP(0);
1379 					c++;
1380 				}
1381 			}
1382 			messagePlayer(clientnum, language[301], c);
1383 		}
1384 	}
1385 	else if (!strncmp(command_str, "/die", 4))
1386 	{
1387 		if ( multiplayer == CLIENT )
1388 		{
1389 			// request sweet release.
1390 			strcpy((char*)net_packet->data, "IDIE");
1391 			net_packet->data[4] = clientnum;
1392 			net_packet->address.host = net_server.host;
1393 			net_packet->address.port = net_server.port;
1394 			net_packet->len = 5;
1395 			sendPacketSafe(net_sock, -1, net_packet, 0);
1396 		}
1397 		else
1398 		{
1399 			if ( players[clientnum] && players[clientnum]->entity )
1400 			{
1401 				players[clientnum]->entity->setHP(0);
1402 			}
1403 		}
1404 	}
1405 	else if (!strncmp(command_str, "/segfault", 9))
1406 	{
1407 		int* potato = NULL;
1408 		(*potato) = 322; //Crash the game!
1409 	}
1410 	else if ( !(strncmp(command_str, "/flames", 7)) )
1411 	{
1412 		if ( !(svFlags & SV_FLAG_CHEATS) )
1413 		{
1414 			messagePlayer(clientnum, language[277]);
1415 			return;
1416 		}
1417 
1418 		if ( multiplayer != SINGLE )
1419 		{
1420 			messagePlayer(clientnum, language[299]);
1421 			return;
1422 		}
1423 
1424 		// Attempt to set the Player on fire
1425 		players[clientnum]->entity->SetEntityOnFire();
1426 
1427 		for ( c = 0; c < 100; c++ )
1428 		{
1429 			entity = spawnFlame(players[clientnum]->entity, SPRITE_FLAME);
1430 			entity->sprite = 16;
1431 			double vel = rand() % 10;
1432 			entity->vel_x = vel * cos(entity->yaw) * cos(entity->pitch) * .1;
1433 			entity->vel_y = vel * sin(entity->yaw) * cos(entity->pitch) * .1;
1434 			entity->vel_z = vel * sin(entity->pitch) * .2;
1435 			entity->skill[0] = 5 + rand() % 10;
1436 		}
1437 	}
1438 	else if ( !(strncmp(command_str, "/cure", 5)) )
1439 	{
1440 		if ( !(svFlags & SV_FLAG_CHEATS) )
1441 		{
1442 			messagePlayer(clientnum, language[277]);
1443 			return;
1444 		}
1445 
1446 		if ( multiplayer != SINGLE )
1447 		{
1448 			messagePlayer(clientnum, language[299]);
1449 			return;
1450 		}
1451 
1452 		for ( c = 0; c < NUMEFFECTS; c++ )   //This does a whole lot more than just cure ailments.
1453 		{
1454 			if ( !(c == EFF_VAMPIRICAURA && players[clientnum]->entity->getStats()->EFFECTS_TIMERS[c] == -2)
1455 				&& c != EFF_WITHDRAWAL && c != EFF_SHAPESHIFT )
1456 			{
1457 				players[clientnum]->entity->getStats()->EFFECTS[c] = false;
1458 				players[clientnum]->entity->getStats()->EFFECTS_TIMERS[c] = 0;
1459 			}
1460 		}
1461 		if ( players[clientnum]->entity->getStats()->EFFECTS[EFF_WITHDRAWAL] )
1462 		{
1463 			players[clientnum]->entity->setEffect(EFF_WITHDRAWAL, false, EFFECT_WITHDRAWAL_BASE_TIME, true);
1464 		}
1465 	}
1466 	else if (!strncmp(command_str, "/summonall ", 11))
1467 	{
1468 		if (!(svFlags & SV_FLAG_CHEATS))
1469 		{
1470 			messagePlayer(clientnum, language[277]);
1471 			return;
1472 		}
1473 		if (multiplayer == CLIENT)
1474 		{
1475 			messagePlayer(clientnum, language[284]);
1476 		}
1477 		else if (players[clientnum] && players[clientnum]->entity)
1478 		{
1479 			strcpy(name, command_str + 11);
1480 			int i, creature;
1481 			bool found = false;
1482 
1483 			for (i = 1; i < NUMMONSTERS; ++i)   //Start at 1 because 0 is a nothing.
1484 			{
1485 				if ( i < KOBOLD ) //Search original monsters
1486 				{
1487 					if ( strstr(language[90 + i], name) )
1488 					{
1489 						creature = i;
1490 						found = true;
1491 						break;
1492 					}
1493 				}
1494 				else if ( i >= KOBOLD ) //Search additional monsters
1495 				{
1496 					if ( strstr(language[2000 + (i - KOBOLD)], name) )
1497 					{
1498 						creature = i;
1499 						found = true;
1500 						break;
1501 					}
1502 				}
1503 
1504 			}
1505 
1506 			if (found)
1507 			{
1508 				playSoundEntity(players[clientnum]->entity, 153, 64);
1509 
1510 				//Spawn monster
1511 				summonManyMonster(static_cast<Monster>(creature));
1512 			}
1513 			else
1514 			{
1515 				messagePlayer(clientnum, language[304], name);
1516 			}
1517 		}
1518 	}
1519 	else if (!strncmp(command_str, "/summon ", 8))
1520 	{
1521 		if (!(svFlags & SV_FLAG_CHEATS))
1522 		{
1523 			messagePlayer(clientnum, language[277]);
1524 			return;
1525 		}
1526 		if (multiplayer == CLIENT)
1527 		{
1528 			messagePlayer(clientnum, language[284]);
1529 		}
1530 		else if (players[clientnum] && players[clientnum]->entity)
1531 		{
1532 			strcpy(name, command_str + 8);
1533 			int i, creature;
1534 			bool found = false;
1535 
1536 			for (i = 1; i < NUMMONSTERS; ++i)   //Start at 1 because 0 is a nothing.
1537 			{
1538 				if ( i < KOBOLD ) //Search original monsters
1539 				{
1540 					if ( strstr(language[90 + i], name) )
1541 					{
1542 						creature = i;
1543 						found = true;
1544 						break;
1545 					}
1546 				}
1547 				else if ( i >= KOBOLD ) //Search additional monsters
1548 				{
1549 					if ( strstr(language[2000 + (i - KOBOLD)], name) )
1550 					{
1551 						creature = i;
1552 						found = true;
1553 						break;
1554 					}
1555 				}
1556 			}
1557 			if ( !found )
1558 			{
1559 				MonsterStatCustomManager::StatEntry* statEntry = monsterStatCustomManager.readFromFile(name);
1560 				if ( statEntry )
1561 				{
1562 					Entity* monster = summonMonster(static_cast<Monster>(statEntry->type), players[clientnum]->entity->x + 32 * cos(players[clientnum]->entity->yaw), players[clientnum]->entity->y + 32 * sin(players[clientnum]->entity->yaw));
1563 					if ( monster )
1564 					{
1565 						if ( static_cast<Monster>(statEntry->type) < KOBOLD )
1566 						{
1567 							messagePlayer(clientnum, language[302], language[90 + static_cast<Monster>(statEntry->type)]);
1568 						}
1569 						else if ( static_cast<Monster>(statEntry->type) >= KOBOLD )
1570 						{
1571 							messagePlayer(clientnum, language[302], language[2000 + (static_cast<Monster>(statEntry->type) - 21)]);
1572 						}
1573 						if ( monster->getStats() )
1574 						{
1575 							statEntry->setStatsAndEquipmentToMonster(monster->getStats());
1576 							while ( statEntry->numFollowers > 0 )
1577 							{
1578 								std::string followerName = statEntry->getFollowerVariant();
1579 								if ( followerName.compare("") && followerName.compare("none") )
1580 								{
1581 									MonsterStatCustomManager::StatEntry* followerEntry = monsterStatCustomManager.readFromFile(followerName.c_str());
1582 									if ( followerEntry )
1583 									{
1584 										Entity* summonedFollower = summonMonster(static_cast<Monster>(followerEntry->type), monster->x, monster->y);
1585 										if ( summonedFollower )
1586 										{
1587 											if ( summonedFollower->getStats() )
1588 											{
1589 												followerEntry->setStatsAndEquipmentToMonster(summonedFollower->getStats());
1590 												summonedFollower->getStats()->leader_uid = monster->getUID();
1591 											}
1592 										}
1593 										delete followerEntry;
1594 									}
1595 									else
1596 									{
1597 										Entity* summonedFollower = summonMonster(monster->getStats()->type, monster->x, monster->y);
1598 										if ( summonedFollower )
1599 										{
1600 											if ( summonedFollower->getStats() )
1601 											{
1602 												summonedFollower->getStats()->leader_uid = monster->getUID();
1603 											}
1604 										}
1605 									}
1606 								}
1607 								--statEntry->numFollowers;
1608 							}
1609 						}
1610 					}
1611 					delete statEntry;
1612 					return;
1613 				}
1614 			}
1615 
1616 			if (found)
1617 			{
1618 				playSoundEntity(players[clientnum]->entity, 153, 64);
1619 
1620 				//Spawn monster
1621 				Entity* monster = summonMonster(static_cast<Monster>(creature), players[clientnum]->entity->x + 32 * cos(players[clientnum]->entity->yaw), players[clientnum]->entity->y + 32 * sin(players[clientnum]->entity->yaw));
1622 				if (monster)
1623 				{
1624 					if ( i < KOBOLD )
1625 					{
1626 						messagePlayer(clientnum, language[302], language[90 + creature]);
1627 					}
1628 					else if ( i >= KOBOLD )
1629 					{
1630 						messagePlayer(clientnum, language[302], language[2000 + (creature-21)]);
1631 					}
1632 				}
1633 				else
1634 				{
1635 					if ( i < KOBOLD )
1636 					{
1637 						messagePlayer(clientnum, language[303], language[90 + creature]);
1638 					}
1639 					else if ( i >= KOBOLD )
1640 					{
1641 						messagePlayer(clientnum, language[303], language[2000 + (creature - KOBOLD)]);
1642 					}
1643 				}
1644 			}
1645 			else
1646 			{
1647 				messagePlayer(clientnum, language[304], name);
1648 			}
1649 		}
1650 	}
1651 	else if (!strncmp(command_str, "/summonchest", 12)) //MAGIC TEST FUNCTION WE NEEDED LONG AGO.
1652 	{
1653 		if (!(svFlags & SV_FLAG_CHEATS))
1654 		{
1655 			messagePlayer(clientnum, language[277]);
1656 			return;
1657 		}
1658 		if (multiplayer == CLIENT)
1659 		{
1660 			messagePlayer(clientnum, language[284]);
1661 		}
1662 		else if (players[clientnum] && players[clientnum]->entity)
1663 		{
1664 			playSoundEntity(players[clientnum]->entity, 153, 64);
1665 
1666 			//Spawn monster
1667 			Entity* chest = summonChest(players[clientnum]->entity->x + 32 * cos(players[clientnum]->entity->yaw), players[clientnum]->entity->y + 32 * sin(players[clientnum]->entity->yaw));
1668 		}
1669 	}
1670 	else if (!strncmp(command_str, "/broadcast", 10))
1671 	{
1672 		broadcast = (broadcast == false);
1673 	}
1674 	else if (!strncmp(command_str, "/nohud", 6))
1675 	{
1676 		nohud = (nohud == false);
1677 	}
1678 	else if (!strncmp(command_str, "/disablehotbarnewitems", 15))
1679 	{
1680 		auto_hotbar_new_items = (auto_hotbar_new_items == false);
1681 	}
1682 	else if ( !strncmp(command_str, "/hotbarenablecategory ", 22) )
1683 	{
1684 		int catIndex = atoi(&command_str[22]);
1685 		int value = atoi(&command_str[24]);
1686 		auto_hotbar_categories[catIndex] = value;
1687 		printlog("Hotbar auto add category %d, value %d.", catIndex, value);
1688 	}
1689 	else if ( !strncmp(command_str, "/autosortcategory ", 18) )
1690 	{
1691 		int catIndex = atoi(&command_str[18]);
1692 		int value = atoi(&command_str[20]);
1693 		autosort_inventory_categories[catIndex] = value;
1694 		printlog("Autosort inventory category %d, priority %d.", catIndex, value);
1695 	}
1696 	else if ( !strncmp(command_str, "/quickaddtohotbar", 17) )
1697 	{
1698 		hotbar_numkey_quick_add = !hotbar_numkey_quick_add;
1699 	}
1700 	else if ( !strncmp(command_str, "/locksidebar", 12) )
1701 	{
1702 		lock_right_sidebar = (lock_right_sidebar == false);
1703 		if ( lock_right_sidebar )
1704 		{
1705 			proficienciesPage = 1;
1706 		}
1707 	}
1708 	else if ( !strncmp(command_str, "/showgametimer", 14) )
1709 	{
1710 		show_game_timer_always = (show_game_timer_always == false);
1711 	}
1712 	else if (!strncmp(command_str, "/lang ", 6))
1713 	{
1714 		char *lang = strdup(command_str);
1715 		lang[8] = 0;
1716 		loadLanguage(lang + 6);
1717 		free(lang);
1718 	}
1719 	else if ( !strncmp(command_str, "/mapseed", 8) )
1720 	{
1721 		messagePlayer(clientnum, "%d", mapseed);
1722 	}
1723 	else if (!strncmp(command_str, "/reloadlang", 11))
1724 	{
1725 		reloadLanguage();
1726 	}
1727 	else if (!strncmp(command_str, "/disablemessages", 15))
1728 	{
1729 		disable_messages = true;
1730 	}
1731 	else if (!strncmp(command_str, "/right_click_protect", 19))
1732 	{
1733 		right_click_protect = (right_click_protect == false);
1734 	}
1735 	else if (!strncmp(command_str, "/autoappraisenewitems", 21))
1736 	{
1737 		auto_appraise_new_items = true;
1738 	}
1739 	else if (!strncmp(command_str, "/startfloor ", 12))
1740 	{
1741 		startfloor = atoi(&command_str[12]);
1742 		//Ensure its value is in range.
1743 		startfloor = std::max(startfloor, 0);
1744 		//startfloor = std::min(startfloor, numlevels);
1745 		printlog("Start floor is %d.", startfloor);
1746 	}
1747 	else if (!strncmp(command_str, "/splitscreen", 12))
1748 	{
1749 		splitscreen = !splitscreen;
1750 		client_disconnected[1] = false;
1751 		client_disconnected[2] = false;
1752 		client_disconnected[3] = false;
1753 	}
1754 	else if (!strncmp(command_str, "/gamepad_deadzone ", 18))
1755 	{
1756 		gamepad_deadzone = atoi(&command_str[18]);
1757 		//Ensure its value is in range.
1758 		gamepad_deadzone = std::max(gamepad_deadzone, 0);
1759 		printlog("Controller deadzone is %d.", gamepad_deadzone);
1760 	}
1761 	else if (!strncmp(command_str, "/gamepad_trigger_deadzone ", 26))
1762 	{
1763 		gamepad_trigger_deadzone = atoi(&command_str[26]);
1764 		//Ensure its value is in range.
1765 		gamepad_trigger_deadzone = std::max(gamepad_trigger_deadzone, 0);
1766 		printlog("Controller trigger deadzone is %d.", gamepad_trigger_deadzone);
1767 	}
1768 	else if (!strncmp(command_str, "/gamepad_leftx_sensitivity ", 27))
1769 	{
1770 		gamepad_leftx_sensitivity = atoi(&command_str[27]);
1771 		//Ensure its value is in range.
1772 		gamepad_leftx_sensitivity = std::max(gamepad_leftx_sensitivity, 1);
1773 		printlog("Controller leftx sensitivity is %d.", gamepad_leftx_sensitivity);
1774 	}
1775 	else if (!strncmp(command_str, "/gamepad_lefty_sensitivity ", 27))
1776 	{
1777 		gamepad_lefty_sensitivity = atoi(&command_str[27]);
1778 		//Ensure its value is in range.
1779 		gamepad_lefty_sensitivity = std::max(gamepad_lefty_sensitivity, 1);
1780 		printlog("Controller lefty sensitivity is %d.", gamepad_lefty_sensitivity);
1781 	}
1782 	else if (!strncmp(command_str, "/gamepad_rightx_sensitivity ", 28))
1783 	{
1784 		gamepad_rightx_sensitivity = atoi(&command_str[28]);
1785 		//Ensure its value is in range.
1786 		gamepad_rightx_sensitivity = std::max(gamepad_rightx_sensitivity, 1);
1787 		printlog("Controller rightx sensitivity is %d.", gamepad_rightx_sensitivity);
1788 	}
1789 	else if (!strncmp(command_str, "/gamepad_righty_sensitivity ", 28))
1790 	{
1791 		gamepad_righty_sensitivity = atoi(&command_str[28]);
1792 		//Ensure its value is in range.
1793 		gamepad_righty_sensitivity = std::max(gamepad_righty_sensitivity, 1);
1794 		printlog("Controller righty sensitivity is %d.", gamepad_righty_sensitivity);
1795 	}
1796 	else if (!strncmp(command_str, "/gamepad_menux_sensitivity ", 27))
1797 	{
1798 		gamepad_menux_sensitivity = atoi(&command_str[27]);
1799 		//Ensure its value is in range.
1800 		gamepad_menux_sensitivity = std::max(gamepad_menux_sensitivity, 1);
1801 		printlog("Controller menux sensitivity is %d.", gamepad_menux_sensitivity);
1802 	}
1803 	else if (!strncmp(command_str, "/gamepad_menuy_sensitivity ", 27))
1804 	{
1805 		gamepad_menuy_sensitivity = atoi(&command_str[27]);
1806 		//Ensure its value is in range.
1807 		gamepad_menuy_sensitivity = std::max(gamepad_menuy_sensitivity, 1);
1808 		printlog("Controller menuy sensitivity is %d.", gamepad_menuy_sensitivity);
1809 	}
1810 	else if (!strncmp(command_str, "/gamepad_leftx_invert", 21))
1811 	{
1812 		gamepad_leftx_invert = true;
1813 	}
1814 	else if (!strncmp(command_str, "/gamepad_lefty_invert", 21))
1815 	{
1816 		gamepad_lefty_invert = true;
1817 	}
1818 	else if (!strncmp(command_str, "/gamepad_rightx_invert", 22))
1819 	{
1820 		gamepad_rightx_invert = true;
1821 	}
1822 	else if (!strncmp(command_str, "/gamepad_righty_invert", 22))
1823 	{
1824 		gamepad_righty_invert = true;
1825 	}
1826 	else if (!strncmp(command_str, "/gamepad_menux_invert", 21))
1827 	{
1828 		gamepad_menux_invert = true;
1829 	}
1830 	else if (!strncmp(command_str, "/gamepad_menuy_invert", 21))
1831 	{
1832 		gamepad_menuy_invert = true;
1833 	}
1834 	else if ( !strncmp(command_str, "/numgold", 8) )
1835 	{
1836 		for ( unsigned i = 0; i < MAXPLAYERS; ++i )
1837 		{
1838 			if ( client_disconnected[i] )
1839 			{
1840 				continue;
1841 			}
1842 			messagePlayer(clientnum, "Player %d has %d gold.", i, stats[i]->GOLD);
1843 		}
1844 	}
1845 	else if ( !strncmp(command_str, "/gold ", 5) )
1846 	{
1847 		if ( !(svFlags & SV_FLAG_CHEATS) )
1848 		{
1849 			messagePlayer(clientnum, language[277]);
1850 			return;
1851 		}
1852 		if ( multiplayer != SINGLE )
1853 		{
1854 			messagePlayer(clientnum, language[299]);
1855 			return;
1856 		}
1857 
1858 		int amount = atoi(&command_str[5]);
1859 		stats[clientnum]->GOLD += amount;
1860 		stats[clientnum]->GOLD = std::max(stats[clientnum]->GOLD, 0);
1861 
1862 		messagePlayer(clientnum, "Giving %d gold pieces.", amount);
1863 	}
1864 	else if ( !strncmp(command_str, "/dropgold", 9) )
1865 	{
1866 		int amount = 100;
1867 		if ( !stats[clientnum] )
1868 		{
1869 			return;
1870 		}
1871 		else if ( stats[clientnum]->HP <= 0 )
1872 		{
1873 			return;
1874 		}
1875 		if ( stats[clientnum]->GOLD - amount < 0 )
1876 		{
1877 			amount = stats[clientnum]->GOLD;
1878 		}
1879 		if ( amount == 0 )
1880 		{
1881 			messagePlayer(clientnum, language[2593]);
1882 			return;
1883 		}
1884 		stats[clientnum]->GOLD -= amount;
1885 		stats[clientnum]->GOLD = std::max(stats[clientnum]->GOLD, 0);
1886 
1887 		if ( multiplayer == CLIENT )
1888 		{
1889 			//Tell the server we dropped some gold.
1890 			strcpy((char*)net_packet->data, "DGLD");
1891 			net_packet->data[4] = clientnum;
1892 			SDLNet_Write32(amount, &net_packet->data[5]);
1893 			net_packet->address.host = net_server.host;
1894 			net_packet->address.port = net_server.port;
1895 			net_packet->len = 9;
1896 			sendPacketSafe(net_sock, -1, net_packet, 0);
1897 		}
1898 		else
1899 		{
1900 			//Drop gold.
1901 			int x = std::min<int>(std::max(0, (int)(players[clientnum]->entity->x / 16)), map.width - 1);
1902 			int y = std::min<int>(std::max(0, (int)(players[clientnum]->entity->y / 16)), map.height - 1);
1903 			if ( map.tiles[y * MAPLAYERS + x * MAPLAYERS * map.height] )
1904 			{
1905 				entity = newEntity(130, 0, map.entities, nullptr); // 130 = goldbag model
1906 				entity->sizex = 4;
1907 				entity->sizey = 4;
1908 				entity->x = players[clientnum]->entity->x;
1909 				entity->y = players[clientnum]->entity->y;
1910 				entity->z = 6;
1911 				entity->yaw = (rand() % 360) * PI / 180.0;
1912 				entity->flags[PASSABLE] = true;
1913 				entity->flags[UPDATENEEDED] = true;
1914 				entity->behavior = &actGoldBag;
1915 				entity->goldAmount = amount; // amount
1916 			}
1917 			playSoundEntity(players[clientnum]->entity, 242 + rand() % 4, 64);
1918 		}
1919 
1920 		messagePlayer(clientnum, language[2594], amount);
1921 	}
1922 	else if (!strncmp(command_str, "/minotaurlevel", 14))
1923 	{
1924 		if ( !(svFlags & SV_FLAG_CHEATS) )
1925 		{
1926 			messagePlayer(clientnum, language[277]);
1927 			return;
1928 		}
1929 		if ( multiplayer != SINGLE )
1930 		{
1931 			messagePlayer(clientnum, language[299]);
1932 			return;
1933 		}
1934 
1935 		if ( !minotaurlevel )
1936 		{
1937 			minotaurlevel = 1;
1938 			createMinotaurTimer(players[0]->entity, &map);
1939 		}
1940 	}
1941 	else if ( !strncmp(command_str, "/minotaurnow", 12) )
1942 	{
1943 		if ( !(svFlags & SV_FLAG_CHEATS) )
1944 		{
1945 			messagePlayer(clientnum, language[277]);
1946 			return;
1947 		}
1948 		if ( multiplayer != SINGLE )
1949 		{
1950 			messagePlayer(clientnum, language[299]);
1951 			return;
1952 		}
1953 
1954 		if ( minotaurlevel )
1955 		{
1956 			node_t *tmpNode = NULL;
1957 			Entity *tmpEnt = NULL;
1958 			for ( tmpNode = map.entities->first; tmpNode != NULL; tmpNode = tmpNode->next )
1959 			{
1960 				tmpEnt = (Entity*)tmpNode->element;
1961 				if ( tmpEnt->sprite == 37 )
1962 				{
1963 					tmpEnt->skill[0] += TICKS_PER_SECOND * 210;
1964 					return;
1965 				}
1966 			}
1967 		}
1968 	}
1969 	else if ( !strncmp(command_str, "/levelskill ", 12) )
1970 	{
1971 		if ( !(svFlags & SV_FLAG_CHEATS) )
1972 		{
1973 			messagePlayer(clientnum, language[277]);
1974 			return;
1975 		}
1976 		if ( multiplayer != SINGLE )
1977 		{
1978 			messagePlayer(clientnum, language[299]);
1979 			return;
1980 		}
1981 
1982 		int skill = atoi(&command_str[12]);
1983 		if ( skill >= NUMPROFICIENCIES )
1984 		{
1985 			messagePlayer(clientnum, language[3239]); //Skill out of range.
1986 		}
1987 		else
1988 		{
1989 			for ( int i = 0; i < 10; ++i )
1990 			{
1991 				players[clientnum]->entity->increaseSkill(skill);
1992 			}
1993 		}
1994 	}
1995 	else if ( !strncmp(command_str, "/maplevel", 9) )
1996 	{
1997 		if ( !(svFlags & SV_FLAG_CHEATS) )
1998 		{
1999 			messagePlayer(clientnum, language[277]);
2000 			return;
2001 		}
2002 		if ( multiplayer != SINGLE )
2003 		{
2004 			messagePlayer(clientnum, language[299]);
2005 			return;
2006 		}
2007 
2008 		messagePlayer(clientnum, language[412]);
2009 		printlog("Made it this far...");
2010 
2011 		mapLevel(clientnum);
2012 	}
2013 	else if ( !strncmp(command_str, "/drunky", 7) )
2014 	{
2015 		if ( !(svFlags & SV_FLAG_CHEATS) )
2016 		{
2017 			messagePlayer(clientnum, language[277]);
2018 			return;
2019 		}
2020 		if ( multiplayer != SINGLE )
2021 		{
2022 			messagePlayer(clientnum, language[299]);
2023 			return;
2024 		}
2025 
2026 		if ( !players[clientnum]->entity->getStats()->EFFECTS[EFF_DRUNK] )
2027 		{
2028 			players[clientnum]->entity->getStats()->EFFECTS[EFF_DRUNK] = true;
2029 			players[clientnum]->entity->getStats()->EFFECTS_TIMERS[EFF_DRUNK] = -1;
2030 		}
2031 		else
2032 		{
2033 			players[clientnum]->entity->getStats()->EFFECTS[EFF_DRUNK] = false;
2034 			players[clientnum]->entity->getStats()->EFFECTS_TIMERS[EFF_DRUNK] = 0;
2035 		}
2036 	}
2037 	else if ( !strncmp(command_str, "/maxskill ", 10) )
2038 	{
2039 		if ( !(svFlags & SV_FLAG_CHEATS) )
2040 		{
2041 			messagePlayer(clientnum, language[277]);
2042 			return;
2043 		}
2044 		if ( multiplayer != SINGLE )
2045 		{
2046 			messagePlayer(clientnum, language[299]);
2047 			return;
2048 		}
2049 
2050 		int skill = atoi(&command_str[10]);
2051 		if ( skill >= NUMPROFICIENCIES )
2052 		{
2053 			messagePlayer(clientnum, "Invalid skill ID"); //Skill out of range.
2054 		}
2055 		else
2056 		{
2057 			for ( int i = players[clientnum]->entity->getStats()->PROFICIENCIES[skill]; i < 100; ++i )
2058 			{
2059 				players[clientnum]->entity->increaseSkill(skill);
2060 			}
2061 		}
2062 	}
2063 	else if ( !strncmp(command_str, "/reloadlimbs", 12) )
2064 	{
2065 		int x;
2066 		FILE* fp;
2067 		bool success = true;
2068 
2069 		if ( !autoLimbReload )
2070 		{
2071 			messagePlayer(clientnum, "Reloading limb offsets from limbs.txt files...");
2072 		}
2073 
2074 		for ( c = 1; c < NUMMONSTERS; c++ )
2075 		{
2076 			// initialize all offsets to zero
2077 			for ( x = 0; x < 20; x++ )
2078 			{
2079 				limbs[c][x][0] = 0;
2080 				limbs[c][x][1] = 0;
2081 				limbs[c][x][2] = 0;
2082 			}
2083 
2084 			// open file
2085 			char filename[256];
2086 			strcpy(filename, "models/creatures/");
2087 			strcat(filename, monstertypename[c]);
2088 			strcat(filename, "/limbs.txt");
2089 			if ( (fp = openDataFile(filename, "r")) == NULL )
2090 			{
2091 				continue;
2092 			}
2093 
2094 			// read file
2095 			int line;
2096 			for ( line = 1; feof(fp) == 0; line++ )
2097 			{
2098 				char data[256];
2099 				int limb = 20;
2100 				int dummy;
2101 
2102 				// read line from file
2103 				fgets(data, 256, fp);
2104 
2105 				// skip blank and comment lines
2106 				if ( data[0] == '\n' || data[0] == '\r' || data[0] == '#' )
2107 				{
2108 					continue;
2109 				}
2110 
2111 				// process line
2112 				if ( sscanf(data, "%d", &limb) != 1 || limb >= 20 || limb < 0 )
2113 				{
2114 					messagePlayer(clientnum, "warning: syntax error in '%s':%d\n invalid limb index!", filename, line);
2115 					printlog("warning: syntax error in '%s':%d\n invalid limb index!\n", filename, line);
2116 					success = false;
2117 					continue;
2118 				}
2119 				if ( sscanf(data, "%d %f %f %f\n", &dummy, &limbs[c][limb][0], &limbs[c][limb][1], &limbs[c][limb][2]) != 4 )
2120 				{
2121 					messagePlayer(clientnum, "warning: syntax error in '%s':%d\n invalid limb offsets!", filename, line);
2122 					printlog("warning: syntax error in '%s':%d\n invalid limb offsets!\n", filename, line);
2123 					success = false;
2124 					continue;
2125 				}
2126 			}
2127 
2128 			// close file
2129 			fclose(fp);
2130 		}
2131 		if ( success && !autoLimbReload )
2132 		{
2133 			messagePlayer(clientnum, "Successfully reloaded all limbs.txt!");
2134 		}
2135 	}
2136 	else if ( !strncmp(command_str, "/animspeed ", 10) )
2137 	{
2138 		if ( !(svFlags & SV_FLAG_CHEATS) )
2139 		{
2140 			messagePlayer(clientnum, language[277]);
2141 			return;
2142 		}
2143 		if ( multiplayer != SINGLE )
2144 		{
2145 			messagePlayer(clientnum, language[299]);
2146 			return;
2147 		}
2148 
2149 		int speed = atoi(&command_str[11]);
2150 		monsterGlobalAnimationMultiplier = speed;
2151 		messagePlayer(clientnum, "Changed animation speed multiplier to %f.", speed / 10.0);
2152 	}
2153 	else if ( !strncmp(command_str, "/atkspeed ", 9) )
2154 	{
2155 		if ( !(svFlags & SV_FLAG_CHEATS) )
2156 		{
2157 			messagePlayer(clientnum, language[277]);
2158 			return;
2159 		}
2160 		if ( multiplayer != SINGLE )
2161 		{
2162 			messagePlayer(clientnum, language[299]);
2163 			return;
2164 		}
2165 
2166 		int speed = atoi(&command_str[10]);
2167 		monsterGlobalAttackTimeMultiplier = speed;
2168 		messagePlayer(clientnum, "Changed attack speed multiplier to %d.", speed);
2169 	}
2170 	else if ( !strncmp(command_str, "/loadmod ", 9) )
2171 	{
2172 		std::string cmd = command_str;
2173 		std::size_t dirfind = cmd.find("dir:");
2174 		std::size_t namefind = cmd.find("name:");
2175 		std::string modname;
2176 		std::size_t fileidFind = cmd.find("fileid:");
2177 		if ( dirfind != std::string::npos && namefind != std::string::npos && fileidFind == std::string::npos )
2178 		{
2179 			std::string directory = cmd.substr(dirfind + 4, namefind - (dirfind + 5));
2180 			modname = cmd.substr(namefind + 5);
2181 			modname = modname.substr(0, modname.length() - 1);
2182 			printlog("[Mods]: Adding mod \"%s\" in path \"%s\"", directory.c_str(), modname.c_str());
2183 			gamemods_mountedFilepaths.push_back(std::make_pair(directory, modname));
2184 			gamemods_modelsListRequiresReload = true;
2185 			gamemods_soundListRequiresReload = true;
2186 		}
2187 		if ( dirfind != std::string::npos && namefind != std::string::npos && fileidFind != std::string::npos )
2188 		{
2189 #ifdef STEAMWORKS
2190 			std::string directory = cmd.substr(dirfind + 4, namefind - (dirfind + 5));
2191 			modname = cmd.substr(namefind + 5, fileidFind - (namefind + 6));
2192 			printlog("[Mods]: Adding mod \"%s\" in path \"%s\"", directory.c_str(), modname.c_str());
2193 			gamemods_mountedFilepaths.push_back(std::make_pair(directory, modname));
2194 			gamemods_modelsListRequiresReload = true;
2195 			gamemods_soundListRequiresReload = true;
2196 
2197 			uint64 id = atoi(cmd.substr(fileidFind + 7).c_str());
2198 			gamemods_workshopLoadedFileIDMap.push_back(std::make_pair(modname, id));
2199 			printlog("[Mods]: Steam Workshop mod file ID added for previous entry:%lld", id);
2200 #endif
2201 		}
2202 	}
2203 	else
2204 	{
2205 		invalidcommand = true;
2206 	}
2207 
2208 	if ( invalidcommand ) // starting new if else block to get around compiler >128 statement limit.
2209 	{
2210 		if ( !strncmp(command_str, "/muteaudiofocuslost", 19) )
2211 		{
2212 			mute_audio_on_focus_lost = (mute_audio_on_focus_lost == false);
2213 		}
2214 		else if ( !strncmp(command_str, "/muteplayermonstersounds", 24) )
2215 		{
2216 			mute_player_monster_sounds = (mute_player_monster_sounds == false);
2217 		}
2218 		else if ( !strncmp(command_str, "/minimaptransparencyfg", 22) )
2219 		{
2220 			minimapTransparencyForeground = atoi(&command_str[23]);
2221 			minimapTransparencyForeground = std::min(std::max<int>(0, minimapTransparencyForeground), 100);
2222 
2223 		}
2224 		else if ( !strncmp(command_str, "/minimaptransparencybg", 22) )
2225 		{
2226 			minimapTransparencyBackground = atoi(&command_str[23]);
2227 			minimapTransparencyBackground = std::min(std::max<int>(0, minimapTransparencyBackground), 100);
2228 
2229 		}
2230 		else if ( !strncmp(command_str, "/minimapscale", 13) )
2231 		{
2232 			minimapScale = atoi(&command_str[14]);
2233 			minimapScale = std::min(std::max<int>(2, minimapScale), 16);
2234 		}
2235 		else if ( !strncmp(command_str, "/minimapobjectzoom", 18) )
2236 		{
2237 			minimapObjectZoom = atoi(&command_str[19]);
2238 			minimapObjectZoom = std::min(std::max<int>(0, minimapObjectZoom), 4);
2239 		}
2240 		else if ( !strncmp(command_str, "/uiscale_inv", 12) )
2241 		{
2242 			std::stringstream ss;
2243 			ss << command_str + 13;
2244 			ss >> uiscale_inventory;
2245 		}
2246 		else if ( !strncmp(command_str, "/uiscale_hotbar", 15) )
2247 		{
2248 			std::stringstream ss;
2249 			ss << command_str + 16;
2250 			ss >> uiscale_hotbar;
2251 		}
2252 		else if ( !strncmp(command_str, "/uiscale_chatbox", 16) )
2253 		{
2254 			std::stringstream ss;
2255 			ss << command_str + 17;
2256 			ss >> uiscale_chatlog;
2257 		}
2258 		else if ( !strncmp(command_str, "/uiscale_playerbars", 19) )
2259 		{
2260 			std::stringstream ss;
2261 			ss << command_str + 20;
2262 			ss >> uiscale_playerbars;
2263 		}
2264 		else if ( !strncmp(command_str, "/uiscale_charsheet", 18) )
2265 		{
2266 			uiscale_charactersheet = !uiscale_charactersheet;
2267 		}
2268 		else if ( !strncmp(command_str, "/uiscale_skillsheet", 19) )
2269 		{
2270 			uiscale_skillspage = !uiscale_skillspage;
2271 		}
2272 		else if ( !strncmp(command_str, "/hidestatusbar", 14) )
2273 		{
2274 			hide_statusbar = !hide_statusbar;
2275 		}
2276 		else if ( !strncmp(command_str, "/hideplayertags", 15) )
2277 		{
2278 			hide_playertags = !hide_playertags;
2279 		}
2280 		else if ( !strncmp(command_str, "/showskillvalues", 16) )
2281 		{
2282 			show_skill_values = !show_skill_values;
2283 		}
2284 		else if ( !strncmp(command_str, "/disablenetworkmultithreading", 29) )
2285 		{
2286 			disableMultithreadedSteamNetworking = true;// !disableMultithreadedSteamNetworking;
2287 		}
2288 		else if ( !strncmp(command_str, "/autolimbreload", 15) )
2289 		{
2290 			autoLimbReload = !autoLimbReload;
2291 		}
2292 		else if ( !strncmp(command_str, "/togglesecretlevel", 18) )
2293 		{
2294 			if ( !(svFlags & SV_FLAG_CHEATS) )
2295 			{
2296 				messagePlayer(clientnum, language[277]);
2297 				return;
2298 			}
2299 			if ( multiplayer != SINGLE )
2300 			{
2301 				messagePlayer(clientnum, language[299]);
2302 				return;
2303 			}
2304 			secretlevel = (secretlevel == false);
2305 		}
2306 		else if ( !strncmp(command_str, "/seteffect ", 11) )
2307 		{
2308 			if ( !(svFlags & SV_FLAG_CHEATS) )
2309 			{
2310 				messagePlayer(clientnum, language[277]);
2311 				return;
2312 			}
2313 			if ( multiplayer != SINGLE )
2314 			{
2315 				messagePlayer(clientnum, language[299]);
2316 				return;
2317 			}
2318 
2319 			int effect = atoi(&command_str[11]);
2320 			if ( effect >= NUMEFFECTS || effect < 0 )
2321 			{
2322 				return;
2323 			}
2324 			else
2325 			{
2326 				players[clientnum]->entity->setEffect(effect, true, 500, true);
2327 			}
2328 		}
2329 		else if ( !strncmp(command_str, "/levelsummon", 12) )
2330 		{
2331 			if ( !(svFlags & SV_FLAG_CHEATS) )
2332 			{
2333 				messagePlayer(clientnum, language[277]);
2334 				return;
2335 			}
2336 			for ( node_t* node = map.creatures->first; node != nullptr; node = node->next )
2337 			{
2338 				Entity* entity = (Entity*)node->element;
2339 				if ( entity && entity->behavior == &actMonster && entity->monsterAllySummonRank != 0 )
2340 				{
2341 					Stat* entityStats = entity->getStats();
2342 					if ( entityStats )
2343 					{
2344 						entityStats->EXP += 100;
2345 					}
2346 				}
2347 			}
2348 			return;
2349 		}
2350 		else if ( !strncmp(command_str, "/brawlermode", 12) )
2351 		{
2352 			achievementBrawlerMode = !achievementBrawlerMode;
2353 			if ( achievementBrawlerMode && conductGameChallenges[CONDUCT_BRAWLER] )
2354 			{
2355 				messagePlayer(clientnum, language[2995]);
2356 			}
2357 			else if ( achievementBrawlerMode && !conductGameChallenges[CONDUCT_BRAWLER] )
2358 			{
2359 				messagePlayer(clientnum, language[2998]);
2360 			}
2361 			else if ( !achievementBrawlerMode )
2362 			{
2363 				messagePlayer(clientnum, language[2996]);
2364 			}
2365 		}
2366 		else if ( !strncmp(command_str, "/rangermode", 11) )
2367 		{
2368 			int player = -1;
2369 			if ( !strncmp(command_str, "/rangermode ", 12) )
2370 			{
2371 				player = std::min(std::max(0, atoi(&command_str[12])), MAXPLAYERS);
2372 			}
2373 			else
2374 			{
2375 				player = 0;
2376 			}
2377 
2378 			if ( multiplayer == CLIENT )
2379 			{
2380 				messagePlayer(clientnum, language[284]);
2381 				return;
2382 			}
2383 
2384 			achievementRangedMode[player] = !achievementRangedMode[player];
2385 			if ( multiplayer == SERVER )
2386 			{
2387 				if ( player != clientnum )
2388 				{
2389 					if ( achievementRangedMode[player] )
2390 					{
2391 						messagePlayer(clientnum, language[3926], player);
2392 					}
2393 					else
2394 					{
2395 						messagePlayer(clientnum, language[3925], player);
2396 					}
2397 				}
2398 			}
2399 			if ( achievementRangedMode[player] && !playerFailedRangedOnlyConduct[player] )
2400 			{
2401 				messagePlayer(player, language[3921]);
2402 			}
2403 			else if ( achievementRangedMode[player] && playerFailedRangedOnlyConduct[player] )
2404 			{
2405 				messagePlayer(player, language[3924]);
2406 			}
2407 			else if ( !achievementRangedMode[player] )
2408 			{
2409 				messagePlayer(player, language[3922]);
2410 			}
2411 		}
2412 		else if ( !strncmp(command_str, "/gimmepotions", 13) )
2413 		{
2414 			if ( !(svFlags & SV_FLAG_CHEATS) )
2415 			{
2416 				messagePlayer(clientnum, language[277]);
2417 				return;
2418 			}
2419 
2420 			if ( multiplayer != SINGLE )
2421 			{
2422 				messagePlayer(clientnum, language[299]);
2423 				return;
2424 			}
2425 
2426 			std::vector<int> potionChances =
2427 			{
2428 				1,	//POTION_WATER,
2429 				1,	//POTION_BOOZE,
2430 				1,	//POTION_JUICE,
2431 				1,	//POTION_SICKNESS,
2432 				1,	//POTION_CONFUSION,
2433 				1,	//POTION_EXTRAHEALING,
2434 				1,	//POTION_HEALING,
2435 				1,	//POTION_CUREAILMENT,
2436 				1,	//POTION_BLINDNESS,
2437 				1,	//POTION_RESTOREMAGIC,
2438 				1,	//POTION_INVISIBILITY,
2439 				1,	//POTION_LEVITATION,
2440 				1,	//POTION_SPEED,
2441 				1,	//POTION_ACID,
2442 				1,	//POTION_PARALYSIS,
2443 				1,	//POTION_POLYMORPH
2444 			};
2445 
2446 			std::discrete_distribution<> potionDistribution(potionChances.begin(), potionChances.end());
2447 			for ( int i = 0; i < 10; ++i )
2448 			{
2449 				auto generatedPotion = potionStandardAppearanceMap.at(potionDistribution(fountainSeed));
2450 				Item* potion = newItem(static_cast<ItemType>(generatedPotion.first), static_cast<Status>(SERVICABLE + rand() % 2),
2451 					0, 1, generatedPotion.second, true, nullptr);
2452 				itemPickup(clientnum, potion);
2453 				//free(potion);
2454 			}
2455 		}
2456 		else if ( !strncmp(command_str, "/hungoverstats", 14) )
2457 		{
2458 			if ( !(svFlags & SV_FLAG_CHEATS) )
2459 			{
2460 				messagePlayer(clientnum, language[277]);
2461 				return;
2462 			}
2463 
2464 			if ( multiplayer != SINGLE )
2465 			{
2466 				messagePlayer(clientnum, language[299]);
2467 				return;
2468 			}
2469 
2470 			messagePlayer(clientnum, "Hungover Active: %d, Time to go: %d, Drunk Active: %d, Drunk time: %d",
2471 				stats[clientnum]->EFFECTS[EFF_WITHDRAWAL], stats[clientnum]->EFFECTS_TIMERS[EFF_WITHDRAWAL],
2472 				stats[clientnum]->EFFECTS[EFF_DRUNK], stats[clientnum]->EFFECTS_TIMERS[EFF_DRUNK]);
2473 			return;
2474 		}
2475 		else if ( !strncmp(command_str, "/debugtimers", 12) )
2476 		{
2477 			logCheckMainLoopTimers = !logCheckMainLoopTimers;
2478 		}
2479 		else if ( !strncmp(command_str, "/entityfreeze", 13) )
2480 		{
2481 			if ( !(svFlags & SV_FLAG_CHEATS) )
2482 			{
2483 				messagePlayer(clientnum, language[277]);
2484 				return;
2485 			}
2486 			gameloopFreezeEntities = !gameloopFreezeEntities;
2487 		}
2488 		else if ( !strncmp(command_str, "/tickrate", 9) )
2489 		{
2490 			networkTickrate = atoi(&command_str[10]);
2491 			networkTickrate = std::max<Uint32>(1, networkTickrate);
2492 			messagePlayer(clientnum, "Set tickrate to %d, network processing allowed %3.0f percent of frame limit interval. Default value 2.",
2493 				networkTickrate, 100.f / networkTickrate);
2494 		}
2495 		else if ( !strncmp(command_str, "/disablenetcodefpslimit", 23) )
2496 		{
2497 			disableFPSLimitOnNetworkMessages = !disableFPSLimitOnNetworkMessages;
2498 		}
2499 		else if ( !strncmp(command_str, "/allspells", 10) )
2500 		{
2501 			if ( !(svFlags & SV_FLAG_CHEATS) )
2502 			{
2503 				messagePlayer(clientnum, language[277]);
2504 				return;
2505 			}
2506 
2507 			for ( auto it = allGameSpells.begin(); it != allGameSpells.end(); ++it )
2508 			{
2509 				spell_t* spell = *it;
2510 				bool learned = addSpell(spell->ID, clientnum, true);
2511 			}
2512 			return;
2513 		}
2514 		else if ( !strncmp(command_str, "/setmapseed ", 12) )
2515 		{
2516 			if ( !(svFlags & SV_FLAG_CHEATS) )
2517 			{
2518 				messagePlayer(clientnum, language[277]);
2519 				return;
2520 			}
2521 			if ( multiplayer == CLIENT )
2522 			{
2523 				messagePlayer(clientnum, language[284]);
2524 				return;
2525 			}
2526 
2527 			Uint32 newseed = atoi(&command_str[12]);
2528 			forceMapSeed = newseed;
2529 			messagePlayer(clientnum, "Set next map seed to: %d", forceMapSeed);
2530 			return;
2531 		}
2532 		else if ( !strncmp(command_str, "/greaseme", 9) )
2533 		{
2534 			if ( !(svFlags & SV_FLAG_CHEATS) )
2535 			{
2536 				messagePlayer(clientnum, language[277]);
2537 				return;
2538 			}
2539 			if ( multiplayer == CLIENT )
2540 			{
2541 				messagePlayer(clientnum, language[284]);
2542 				return;
2543 			}
2544 			if ( players[clientnum] && players[clientnum]->entity )
2545 			{
2546 				players[clientnum]->entity->setEffect(EFF_GREASY, true, TICKS_PER_SECOND * 20, false);
2547 			}
2548 		}
2549 		else if ( !strncmp(command_str, "/gimmearrows", 12) )
2550 		{
2551 			if ( !(svFlags & SV_FLAG_CHEATS) )
2552 			{
2553 				messagePlayer(clientnum, language[277]);
2554 				return;
2555 			}
2556 			for ( int i = QUIVER_SILVER; i <= QUIVER_HUNTING; ++i )
2557 			{
2558 				dropItem(newItem(static_cast<ItemType>(i), EXCELLENT, 0, 25 + rand() % 26, rand(), true, &stats[clientnum]->inventory), 0);
2559 			}
2560 		}
2561 		else if ( !strncmp(command_str, "/gimmescrap", 11) )
2562 		{
2563 			if ( !(svFlags & SV_FLAG_CHEATS) )
2564 			{
2565 				messagePlayer(clientnum, language[277]);
2566 				return;
2567 			}
2568 			dropItem(newItem(TOOL_METAL_SCRAP, EXCELLENT, 0, 100, rand(), true, &stats[clientnum]->inventory), 0);
2569 			dropItem(newItem(TOOL_MAGIC_SCRAP, EXCELLENT, 0, 100, rand(), true, &stats[clientnum]->inventory), 0);
2570 			dropItem(newItem(TOOL_TINKERING_KIT, EXCELLENT, 0, 1, rand(), true, &stats[clientnum]->inventory), 0);
2571 		}
2572 		else if ( !strncmp(command_str, "/gimmerobots", 12) )
2573 		{
2574 			if ( !(svFlags & SV_FLAG_CHEATS) )
2575 			{
2576 				messagePlayer(clientnum, language[277]);
2577 				return;
2578 			}
2579 			dropItem(newItem(TOOL_GYROBOT, EXCELLENT, 0, 10, rand(), true, &stats[clientnum]->inventory), 0);
2580 			dropItem(newItem(TOOL_DUMMYBOT, EXCELLENT, 0, 10, rand(), true, &stats[clientnum]->inventory), 0);
2581 			dropItem(newItem(TOOL_SENTRYBOT, EXCELLENT, 0, 10, rand(), true, &stats[clientnum]->inventory), 0);
2582 			dropItem(newItem(TOOL_SPELLBOT, EXCELLENT, 0, 10, rand(), true, &stats[clientnum]->inventory), 0);
2583 		}
2584 		else if ( !strncmp(command_str, "/toggletinkeringlimits", 22) )
2585 		{
2586 			if ( !(svFlags & SV_FLAG_CHEATS) )
2587 			{
2588 				messagePlayer(clientnum, language[277]);
2589 				return;
2590 			}
2591 			overrideTinkeringLimit = !overrideTinkeringLimit;
2592 			if ( overrideTinkeringLimit )
2593 			{
2594 				messagePlayer(clientnum, "Disabled tinkering bot limit");
2595 			}
2596 			else
2597 			{
2598 				messagePlayer(clientnum, "Re-enabled tinkering bot limit");
2599 			}
2600 		}
2601 		else if ( !strncmp(command_str, "/setdecoyrange ", 15) )
2602 		{
2603 			if ( !(svFlags & SV_FLAG_CHEATS) )
2604 			{
2605 				messagePlayer(clientnum, language[277]);
2606 				return;
2607 			}
2608 			if ( multiplayer == CLIENT )
2609 			{
2610 				messagePlayer(clientnum, language[284]);
2611 				return;
2612 			}
2613 			decoyBoxRange = atoi(&command_str[15]);
2614 			messagePlayer(clientnum, "Set decoy range to %d", decoyBoxRange);
2615 		}
2616 		else if ( !strncmp(command_str, "/gimmegoblinbooks", 17) )
2617 		{
2618 			if ( !(svFlags & SV_FLAG_CHEATS) )
2619 			{
2620 				messagePlayer(clientnum, language[277]);
2621 				return;
2622 			}
2623 			for ( int i = 0; i < NUM_SPELLS; ++i )
2624 			{
2625 				int spellbook = getSpellbookFromSpellID(i);
2626 				dropItem(newItem(static_cast<ItemType>(spellbook), DECREPIT, -1, 1, rand(), true, &stats[clientnum]->inventory), 0);
2627 			}
2628 		}
2629 		else if ( !strncmp(command_str, "/unsetdlc2achievements", 22) )
2630 		{
2631 			if ( !(svFlags & SV_FLAG_CHEATS) )
2632 			{
2633 				messagePlayer(clientnum, language[277]);
2634 				return;
2635 			}
2636 #ifdef STEAMWORKS
2637 			steamUnsetAchievement("BARONY_ACH_TAKING_WITH");
2638 			steamUnsetAchievement("BARONY_ACH_TELEFRAG");
2639 			steamUnsetAchievement("BARONY_ACH_FASCIST");
2640 			steamUnsetAchievement("BARONY_ACH_REAL_BOY");
2641 			steamUnsetAchievement("BARONY_ACH_OVERCLOCKED");
2642 			steamUnsetAchievement("BARONY_ACH_TRASH_COMPACTOR");
2643 			steamUnsetAchievement("BARONY_ACH_BOILERPLATE_BARON");
2644 			steamUnsetAchievement("BARONY_ACH_PIMPIN");
2645 			steamUnsetAchievement("BARONY_ACH_BAD_BEAUTIFUL");
2646 			steamUnsetAchievement("BARONY_ACH_SERIAL_THRILLA");
2647 			steamUnsetAchievement("BARONY_ACH_TRADITION");
2648 			steamUnsetAchievement("BARONY_ACH_BAD_BOY_BARON");
2649 			steamUnsetAchievement("BARONY_ACH_POP_QUIZ");
2650 			steamUnsetAchievement("BARONY_ACH_DYSLEXIA");
2651 			steamUnsetAchievement("BARONY_ACH_SAVAGE");
2652 			steamUnsetAchievement("BARONY_ACH_TRIBE_SUBSCRIBE");
2653 			steamUnsetAchievement("BARONY_ACH_BAYOU_BARON");
2654 			steamUnsetAchievement("BARONY_ACH_GASTRIC_BYPASS");
2655 			steamUnsetAchievement("BARONY_ACH_BOOKWORM");
2656 			steamUnsetAchievement("BARONY_ACH_FLUTTERSHY");
2657 			steamUnsetAchievement("BARONY_ACH_MONARCH");
2658 			steamUnsetAchievement("BARONY_ACH_BUGGAR_BARON");
2659 			steamUnsetAchievement("BARONY_ACH_TIME_TO_PLAN");
2660 			steamUnsetAchievement("BARONY_ACH_WONDERFUL_TOYS");
2661 			steamUnsetAchievement("BARONY_ACH_SUPER_SHREDDER");
2662 			steamUnsetAchievement("BARONY_ACH_UTILITY_BELT");
2663 			steamUnsetAchievement("BARONY_ACH_FIXER_UPPER");
2664 			steamUnsetAchievement("BARONY_ACH_TORCHERER");
2665 			steamUnsetAchievement("BARONY_ACH_LEVITANT_LACKEY");
2666 			steamUnsetAchievement("BARONY_ACH_GOODNIGHT_SWEET_PRINCE");
2667 			steamUnsetAchievement("BARONY_ACH_MANY_PEDI_PALP");
2668 			steamUnsetAchievement("BARONY_ACH_5000_SECOND_RULE");
2669 			steamUnsetAchievement("BARONY_ACH_FORUM_TROLL");
2670 			steamUnsetAchievement("BARONY_ACH_SOCIAL_BUTTERFLY");
2671 			steamUnsetAchievement("BARONY_ACH_ROLL_THE_BONES");
2672 			steamUnsetAchievement("BARONY_ACH_COWBOY_FROM_HELL");
2673 			steamUnsetAchievement("BARONY_ACH_IRONIC_PUNISHMENT");
2674 			steamUnsetAchievement("BARONY_ACH_SELF_FLAGELLATION");
2675 			steamUnsetAchievement("BARONY_ACH_OHAI_MARK");
2676 			steamUnsetAchievement("BARONY_ACH_CHOPPING_BLOCK");
2677 			steamUnsetAchievement("BARONY_ACH_ITS_A_LIVING");
2678 			steamUnsetAchievement("BARONY_ACH_ARSENAL");
2679 			steamUnsetAchievement("BARONY_ACH_IF_YOU_LOVE_SOMETHING");
2680 			steamUnsetAchievement("BARONY_ACH_GUDIPARIAN_BAZI");
2681 			steamUnsetAchievement("BARONY_ACH_STRUNG_OUT");
2682 			steamUnsetAchievement("BARONY_ACH_FELL_BEAST");
2683 			steamUnsetAchievement("BARONY_ACH_PLEASE_HOLD");
2684 			steamUnsetAchievement("BARONY_ACH_SWINGERS");
2685 			steamUnsetAchievement("BARONY_ACH_COLD_BLOODED");
2686 			steamUnsetAchievement("BARONY_ACH_SOULLESS");
2687 			steamUnsetAchievement("BARONY_ACH_TRIBAL");
2688 			steamUnsetAchievement("BARONY_ACH_MANAGEMENT_TEAM");
2689 			steamUnsetAchievement("BARONY_ACH_SOCIOPATHS");
2690 			steamUnsetAchievement("BARONY_ACH_FACES_OF_DEATH");
2691 			steamUnsetAchievement("BARONY_ACH_SURVIVALISTS");
2692 			steamUnsetAchievement("BARONY_ACH_I_WANT_IT_ALL");
2693 			steamUnsetAchievement("BARONY_ACH_RUST_IN_PEACE");
2694 			steamUnsetAchievement("BARONY_ACH_MACHINE_HEAD");
2695 			steamUnsetAchievement("BARONY_ACH_RAGE_AGAINST");
2696 			steamUnsetAchievement("BARONY_ACH_GUERILLA_RADIO");
2697 			steamUnsetAchievement("BARONY_ACH_BOMBTRACK");
2698 			steamUnsetAchievement("BARONY_ACH_CALM_LIKE_A_BOMB");
2699 			steamUnsetAchievement("BARONY_ACH_CAUGHT_IN_A_MOSH");
2700 			steamUnsetAchievement("BARONY_ACH_SPICY");
2701 			for ( int i = STEAM_STAT_TRASH_COMPACTOR; i < 43; ++i )
2702 			{
2703 				g_SteamStats[i].m_iValue = 0;
2704 				SteamUserStats()->SetStat(g_SteamStats[i].m_pchStatName, 0);
2705 			}
2706 			SteamUserStats()->StoreStats();
2707 #endif // STEAMWORKS
2708 		}
2709 		else if ( !strncmp(command_str, "/gimmebombs", 11) )
2710 		{
2711 			if ( !(svFlags & SV_FLAG_CHEATS) )
2712 			{
2713 				messagePlayer(clientnum, language[277]);
2714 				return;
2715 			}
2716 			dropItem(newItem(TOOL_BOMB, EXCELLENT, 0, 10, rand(), true, &stats[clientnum]->inventory), 0);
2717 			dropItem(newItem(TOOL_FREEZE_BOMB, EXCELLENT, 0, 10, rand(), true, &stats[clientnum]->inventory), 0);
2718 			dropItem(newItem(TOOL_TELEPORT_BOMB, EXCELLENT, 0, 10, rand(), true, &stats[clientnum]->inventory), 0);
2719 			dropItem(newItem(TOOL_SLEEP_BOMB, EXCELLENT, 0, 10, rand(), true, &stats[clientnum]->inventory), 0);
2720 		}
2721 		else if ( !strncmp(command_str, "/showhunger", 11) )
2722 		{
2723 			if ( !(svFlags & SV_FLAG_CHEATS) )
2724 			{
2725 				messagePlayer(clientnum, language[277]);
2726 				return;
2727 			}
2728 			messagePlayer(clientnum, "Hunger value: %d", stats[clientnum]->HUNGER);
2729 		}
2730 		else if ( !strncmp(command_str, "/disablemouserotationlimit", 26) )
2731 		{
2732 			disablemouserotationlimit = (disablemouserotationlimit == false);
2733 		}
2734 		else if ( !strncmp(command_str, "/usecamerasmoothing", 19) )
2735 		{
2736 			usecamerasmoothing = (usecamerasmoothing == false);
2737 		}
2738 		else if ( !strncmp(command_str, "/lightupdate ", 13) )
2739 		{
2740 			globalLightSmoothingRate = atoi(&command_str[13]);
2741 		}
2742 		else if ( !strncmp(command_str, "/dumpnetworkdata", 16) )
2743 		{
2744 			for ( auto element : DebugStats.networkPackets )
2745 			{
2746 				printlog("Packet: %s | %d", element.second.first.c_str(), element.second.second);
2747 			}
2748 		}
2749 		else if ( !strncmp(command_str, "/dumpentudata", 13) )
2750 		{
2751 			for ( auto element : DebugStats.entityUpdatePackets )
2752 			{
2753 				printlog("Sprite: %d | %d", element.first, element.second);
2754 			}
2755 		}
2756 		else if ( !strncmp(command_str, "/borderless", 11) )
2757 		{
2758 			borderless = (!borderless);
2759 		}
2760 		else if ( !strncmp(command_str, "/jsonexportmonster ", 19) )
2761 		{
2762 			strcpy(name, command_str + 19);
2763 			int creature = NOTHING;
2764 
2765 			for ( int i = 1; i < NUMMONSTERS; ++i )   //Start at 1 because 0 is a nothing.
2766 			{
2767 				if ( i < KOBOLD ) //Search original monsters
2768 				{
2769 					if ( strstr(language[90 + i], name) )
2770 					{
2771 						creature = i;
2772 						break;
2773 					}
2774 				}
2775 				else if ( i >= KOBOLD ) //Search additional monsters
2776 				{
2777 					if ( strstr(language[2000 + (i - KOBOLD)], name) )
2778 					{
2779 						creature = i;
2780 						break;
2781 					}
2782 				}
2783 
2784 			}
2785 
2786 			if ( creature != NOTHING )
2787 			{
2788 				Stat* monsterStats = new Stat(1000 + creature);
2789 				monsterStatCustomManager.writeAllFromStats(monsterStats);
2790 				delete monsterStats;
2791 			}
2792 		}
2793 		else if ( !strncmp(command_str, "/jsonexportfromcursor", 21) )
2794 		{
2795 			Entity* target = entityClicked(nullptr, true, clientnum);
2796 			if ( target )
2797 			{
2798 				Entity* parent = uidToEntity(target->skill[2]);
2799 				if ( target->behavior == &actMonster || (parent && parent->behavior == &actMonster) )
2800 				{
2801 					// see if we selected a limb
2802 					if ( parent )
2803 					{
2804 						target = parent;
2805 					}
2806 				}
2807 				monsterStatCustomManager.writeAllFromStats(target->getStats());
2808 			}
2809 		}
2810 		else if ( !strncmp(command_str, "/jsonexportgameplaymodifiers", 28) )
2811 		{
2812 			gameplayCustomManager.writeAllToDocument();
2813 		}
2814 		else if ( !strncmp(command_str, "/jsonexportmonstercurve", 23) )
2815 		{
2816 			monsterCurveCustomManager.writeSampleToDocument();
2817 		}
2818 		else if ( !strncmp(command_str, "/crossplay", 10) )
2819 		{
2820 #if (defined STEAMWORKS && defined USE_EOS)
2821 			EOS.CrossplayAccountManager.autologin = true;
2822 #endif // USE_EOS
2823 		}
2824 		else if ( !strncmp(command_str, "/sfxambientvolume", 17) )
2825 		{
2826 			sfxAmbientVolume = atoi(&command_str[18]);
2827 		}
2828 		else if ( !strncmp(command_str, "/sfxambientdynamic", 18) )
2829 		{
2830 			sfxUseDynamicAmbientVolume = !sfxUseDynamicAmbientVolume;
2831 			if ( sfxUseDynamicAmbientVolume )
2832 			{
2833 				messagePlayer(clientnum, "Dynamic ambient volume ON");
2834 			}
2835 			else
2836 			{
2837 				messagePlayer(clientnum, "Dynamic ambient volume OFF");
2838 			}
2839 		}
2840 		else if ( !strncmp(command_str, "/sfxenvironmentdynamic", 22) )
2841 		{
2842 			sfxUseDynamicEnvironmentVolume = !sfxUseDynamicEnvironmentVolume;
2843 			if ( sfxUseDynamicEnvironmentVolume )
2844 			{
2845 				messagePlayer(clientnum, "Dynamic environment volume ON");
2846 			}
2847 			else
2848 			{
2849 				messagePlayer(clientnum, "Dynamic environment volume OFF");
2850 			}
2851 		}
2852 		else if ( !strncmp(command_str, "/sfxenvironmentvolume", 21) )
2853 		{
2854 			sfxEnvironmentVolume = atoi(&command_str[22]);
2855 		}
2856 		else
2857 		{
2858 			messagePlayer(clientnum, language[305], command_str);
2859 		}
2860 	}
2861 }
2862