· 6 years ago · Oct 20, 2019, 01:16 AM
1#pragma semicolon 1
2#include <sourcemod>
3#include <sdktools>
4#include <smlib>
5
6#pragma newdecls required
7
8#define PLUGIN_VERSION "1.0"
9
10#define PREFIX "\x04Snake \x01> \x03"
11
12#define FIELD_X 14
13#define FIELD_Y 11
14
15#define COORD_X 0
16#define COORD_Y 1
17
18#define CHAR_WORM "█"
19#define CHAR_FOOD "▒"
20#define CHAR_AWESOMEFOOD "▒"
21#define CHAR_SPACE "░"
22
23#define AWESOME_NOMNOM_LIFETIME 50
24#define WORM_MIN_LENGTH 3
25#define FOOD_SCORE 100
26
27enum WormDirection
28{
29 Direction_Right = 0,
30 Direction_Down,
31 Direction_Left,
32 Direction_Up
33}
34
35enum WormMode
36{
37 Mode_Snake1, // walls are solid
38 Mode_Snake2 // walls are walkable
39}
40
41WormDirection g_iWormCurrentDirection[MAXPLAYERS+1];
42WormDirection g_iWormNextDirection[MAXPLAYERS+1];
43WormMode g_iSnakeMode[MAXPLAYERS+1];
44
45int g_iWormPositions[MAXPLAYERS+1][FIELD_X*FIELD_Y][2];
46int g_iWormLength[MAXPLAYERS+1];
47int g_iNomNomPosition[MAXPLAYERS+1][2];
48int g_iAwesomeNomNomPosition[MAXPLAYERS+1][2];
49int g_iNextAwesomeNomNom[MAXPLAYERS+1] = 0;
50int g_iAwesomeNomNomLifetime[MAXPLAYERS+1] = 0;
51int g_iScore[MAXPLAYERS+1];
52int g_iHighScore[MAXPLAYERS+1][WormMode];
53Handle g_hGameThink[MAXPLAYERS+1] = {INVALID_HANDLE,...};
54
55Handle g_hDatabase;
56
57int g_iButtons[MAXPLAYERS+1];
58
59public Plugin myinfo =
60{
61 name = "Snake",
62 author = "Jannik \"Peace-Maker\" Hartung",
63 description = "Snake minigame",
64 version = PLUGIN_VERSION,
65 url = "http://www.wcfan.de/"
66}
67
68public void OnPluginStart()
69{
70 RegConsoleCmd("sm_snake", Cmd_StartSnake, "Start a snake minigame session.");
71
72 HookEvent("player_spawn", Event_OnPlayerSpawn);
73
74 SQL_TConnect(SQL_OnDatabaseConnected, (SQL_CheckConfig("snake")?"snake":"storage-local"));
75}
76
77public void OnClientAuthorized(int client, const char[] auth)
78{
79 if(g_hDatabase != INVALID_HANDLE)
80 SQL_TQueryF(g_hDatabase, SQL_GetClientHighscores, GetClientUserId(client), DBPrio_Normal, "SELECT score1, score2 FROM snake_players WHERE steamid = \"%s\";", auth);
81}
82
83public void OnClientDisconnect(int client)
84{
85 ClearTimer(g_hGameThink[client]);
86 ResetSnakeGame(client);
87 g_iButtons[client] = 0;
88 g_iHighScore[client][Mode_Snake1] = 0;
89 g_iHighScore[client][Mode_Snake2] = 0;
90}
91
92public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3], float angles[3], int &weapon)
93{
94 // move up
95 if( (buttons & IN_FORWARD) && !(g_iButtons[client] & IN_FORWARD) )
96 {
97 if(GetOppositeDirection(g_iWormCurrentDirection[client]) != Direction_Up)
98 g_iWormNextDirection[client] = Direction_Up;
99 }
100 else if( (buttons & IN_MOVERIGHT) && !(g_iButtons[client] & IN_MOVERIGHT) )
101 {
102 if(GetOppositeDirection(g_iWormCurrentDirection[client]) != Direction_Right)
103 g_iWormNextDirection[client] = Direction_Right;
104 }
105 else if( (buttons & IN_BACK) && !(g_iButtons[client] & IN_BACK) )
106 {
107 if(GetOppositeDirection(g_iWormCurrentDirection[client]) != Direction_Down)
108 g_iWormNextDirection[client] = Direction_Down;
109 }
110 else if( (buttons & IN_MOVELEFT) && !(g_iButtons[client] & IN_MOVELEFT) )
111 {
112 if(GetOppositeDirection(g_iWormCurrentDirection[client]) != Direction_Left)
113 g_iWormNextDirection[client] = Direction_Left;
114 }
115
116 g_iButtons[client] = buttons;
117}
118
119public Action Event_OnPlayerSpawn(Handle event, const char[] name, bool dontBroadcast)
120{
121 int client = GetClientOfUserId(GetEventInt(event, "userid"));
122 if(g_hGameThink[client] != INVALID_HANDLE)
123 {
124 // Disable any movement
125 SetEntProp(client, Prop_Send, "m_fFlags", FL_CLIENT|FL_ATCONTROLS);
126 }
127}
128
129public Action Cmd_StartSnake(int client, int args)
130{
131 if(!client)
132 {
133 ReplyToCommand(client, "Snake: This command is ingame only.");
134 return Plugin_Handled;
135 }
136
137 if(g_hGameThink[client] != INVALID_HANDLE)
138 {
139 ClearTimer(g_hGameThink[client]);
140 PrintToChat(client, "%sGame paused.", PREFIX);
141 SetEntProp(client, Prop_Send, "m_fFlags", FL_FAKECLIENT|FL_ONGROUND|FL_PARTIALGROUND);
142 }
143
144 Handle hMenu = CreateMenu(Menu_HandleMainMenu);
145 SetMenuTitle(hMenu, "Snake: Mainmenu");
146 SetMenuExitButton(hMenu, true);
147
148 AddMenuItem(hMenu, "resume", "Resume game", (g_iWormLength[client]>0?ITEMDRAW_DEFAULT:ITEMDRAW_DISABLED));
149 AddMenuItem(hMenu, "newgame", "Start Snake with solid walls");
150 AddMenuItem(hMenu, "newgame2", "Start Snake2 with non-blocking walls");
151
152 AddMenuItem(hMenu, "", "", ITEMDRAW_SPACER);
153 AddMenuItem(hMenu, "top10", "Show Snake top 10");
154 AddMenuItem(hMenu, "top10_2", "Show Snake2 top 10");
155
156 char sMenu[64];
157 Format(sMenu, sizeof(sMenu), "Your best Snake score: %d", g_iHighScore[client][Mode_Snake1]);
158 AddMenuItem(hMenu, "", sMenu, ITEMDRAW_DISABLED);
159 Format(sMenu, sizeof(sMenu), "Your best Snake2 score: %d", g_iHighScore[client][Mode_Snake2]);
160 AddMenuItem(hMenu, "", sMenu, ITEMDRAW_DISABLED);
161
162 DisplayMenu(hMenu, client, MENU_TIME_FOREVER);
163
164 return Plugin_Handled;
165}
166
167public int Menu_HandleMainMenu(Menu menu, MenuAction action, int param1, int param2)
168{
169 if(action == MenuAction_Select)
170 {
171 char info[32];
172 GetMenuItem(menu, param2, info, sizeof(info));
173
174 // Start a new game with solid walls
175 if(StrEqual(info, "newgame"))
176 {
177 SetupSnakeGame(param1);
178
179 g_iSnakeMode[param1] = Mode_Snake1;
180
181 g_hGameThink[param1] = CreateTimer(0.1, Timer_OnGameThink, GetClientUserId(param1), TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
182 TriggerTimer(g_hGameThink[param1]);
183
184 // Disable any movement
185 SetEntProp(param1, Prop_Send, "m_fFlags", FL_CLIENT|FL_ATCONTROLS);
186 }
187 else if(StrEqual(info, "newgame2"))
188 {
189 SetupSnakeGame(param1);
190
191 g_iSnakeMode[param1] = Mode_Snake2;
192
193 g_hGameThink[param1] = CreateTimer(0.1, Timer_OnGameThink, GetClientUserId(param1), TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
194 TriggerTimer(g_hGameThink[param1]);
195
196 // Disable any movement
197 SetEntProp(param1, Prop_Send, "m_fFlags", FL_CLIENT|FL_ATCONTROLS);
198 }
199 else if(StrEqual(info, "resume"))
200 {
201 g_hGameThink[param1] = CreateTimer(0.1, Timer_OnGameThink, GetClientUserId(param1), TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
202 TriggerTimer(g_hGameThink[param1]);
203
204 // Disable any movement
205 SetEntProp(param1, Prop_Send, "m_fFlags", FL_CLIENT|FL_ATCONTROLS);
206 }
207 else if(StrEqual(info, "top10"))
208 {
209 SQL_TQueryF(g_hDatabase, SQL_FetchTop10, GetClientUserId(param1), DBPrio_Normal, "SELECT name, score1 FROM snake_players WHERE score1 > 0 ORDER BY score1 DESC LIMIT 10;");
210 }
211 else if(StrEqual(info, "top10_2"))
212 {
213 SQL_TQueryF(g_hDatabase, SQL_FetchTop10, GetClientUserId(param1), DBPrio_Normal, "SELECT name, score2 FROM snake_players WHERE score2 > 0 ORDER BY score2 DESC LIMIT 10;");
214 }
215 }
216 else if(action == MenuAction_End)
217 {
218 CloseHandle(menu);
219 }
220}
221
222public Action Menu_HandleTop10(Menu menu, MenuAction action, int param1, int param2)
223{
224 if(action == MenuAction_Cancel && param2 == MenuCancel_ExitBack)
225 {
226 Cmd_StartSnake(param1, 0);
227 }
228 else if(action == MenuAction_End)
229 {
230 CloseHandle(menu);
231 }
232}
233
234public Action Panel_GameHandler(Menu menu, MenuAction action, int param1, int param2)
235{
236 if(action == MenuAction_Select)
237 {
238 if(param2 == 10)
239 {
240 ClearTimer(g_hGameThink[param1]);
241 PrintToChat(param1, "%sGame paused. Type !snake to resume.", PREFIX);
242 SetEntProp(param1, Prop_Send, "m_fFlags", FL_FAKECLIENT|FL_ONGROUND|FL_PARTIALGROUND);
243 }
244 else if(param2 == 1)
245 {
246 SetupSnakeGame(param1);
247
248 g_hGameThink[param1] = CreateTimer(0.1, Timer_OnGameThink, GetClientUserId(param1), TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
249 TriggerTimer(g_hGameThink[param1]);
250
251 // Disable any movement
252 SetEntProp(param1, Prop_Send, "m_fFlags", FL_CLIENT|FL_ATCONTROLS);
253 }
254 }
255}
256
257public Action Timer_OnGameThink(Handle timer, any userid)
258{
259 int client = GetClientOfUserId(userid);
260 if(!client)
261 return Plugin_Stop;
262
263 // Apply the new direction
264 g_iWormCurrentDirection[client] = g_iWormNextDirection[client];
265
266 // Time for a new awesome one?
267 g_iNextAwesomeNomNom[client]--;
268 if(g_iNextAwesomeNomNom[client] == 0)
269 {
270 PutNewNomNomOnField(client, true);
271 g_iAwesomeNomNomLifetime[client] = AWESOME_NOMNOM_LIFETIME;
272 }
273
274 // Too late. This totally awesome food is gone..
275 if(g_iAwesomeNomNomLifetime[client] >= 0)
276 g_iAwesomeNomNomLifetime[client]--;
277 if(g_iAwesomeNomNomLifetime[client] == 0)
278 {
279 g_iNextAwesomeNomNom[client] = Math_GetRandomInt(100, 300);
280 g_iAwesomeNomNomPosition[client][COORD_X] = -1;
281 g_iAwesomeNomNomPosition[client][COORD_Y] = -1;
282 }
283
284 // GAME OVER
285 if(!MoveSnake(client))
286 {
287 PrintToChat(client, "%sGAME OVER! Your score: %d. Don't eat bad food!", PREFIX, g_iScore[client]);
288 DrawSnakePanel(client, true);
289
290 if(g_iHighScore[client][g_iSnakeMode[client]] < g_iScore[client])
291 {
292 if(g_hDatabase != INVALID_HANDLE)
293 {
294 int iHighscore[WormMode];
295 iHighscore[Mode_Snake1] = g_iHighScore[client][Mode_Snake1];
296 iHighscore[Mode_Snake2] = g_iHighScore[client][Mode_Snake2];
297 g_iHighScore[client][g_iSnakeMode[client]] = g_iScore[client];
298
299 char sName[MAX_NAME_LENGTH], sEscapedName[MAX_NAME_LENGTH*2+1], sAuth[32];
300 GetClientName(client, sName, sizeof(sName));
301 GetClientAuthId(client, AuthId_Steam2, sAuth, 63);
302 SQL_EscapeString(g_hDatabase, sName, sEscapedName, sizeof(sEscapedName));
303
304 if(iHighscore[Mode_Snake1] > 0 || iHighscore[Mode_Snake2] > 0)
305 SQL_TQueryF(g_hDatabase, SQL_DoNothing, 0, DBPrio_Normal, "UPDATE snake_players SET name = \"%s\", score1 = %d, score2 = %d WHERE steamid = \"%s\";", sEscapedName, g_iHighScore[client][Mode_Snake1], g_iHighScore[client][Mode_Snake2], sAuth);
306 else
307 SQL_TQueryF(g_hDatabase, SQL_DoNothing, 0, DBPrio_Normal, "INSERT INTO snake_players (name, steamid, score1, score2) VALUES(\"%s\", \"%s\", %d, %d);", sEscapedName, sAuth, g_iHighScore[client][Mode_Snake1], g_iHighScore[client][Mode_Snake2]);
308 }
309
310 g_iHighScore[client][g_iSnakeMode[client]] = g_iScore[client];
311 PrintToChat(client, "%sNew personal high score!", PREFIX, g_iScore[client]);
312 }
313
314 ResetSnakeGame(client);
315 SetEntProp(client, Prop_Send, "m_fFlags", FL_FAKECLIENT|FL_ONGROUND|FL_PARTIALGROUND);
316 g_hGameThink[client] = INVALID_HANDLE;
317 return Plugin_Stop;
318 }
319
320 DrawSnakePanel(client, false);
321
322 return Plugin_Continue;
323}
324
325public void SQL_OnDatabaseConnected(Handle owner, Handle hndl, const char[] error, any data)
326{
327 if(hndl == INVALID_HANDLE || strlen(error) > 0)
328 {
329 LogError("Error connecting to database: %s", error);
330 return;
331 }
332
333 g_hDatabase = hndl;
334
335 char sDriver[16];
336 SQL_ReadDriver(hndl, sDriver, sizeof(sDriver));
337 if(StrEqual(sDriver, "sqlite", false))
338 {
339 SQL_TQuery(hndl, SQL_DoNothing, "CREATE TABLE IF NOT EXISTS snake_players (steamid VARCHAR(64) PRIMARY KEY, name VARCHAR(64) NOT NULL, score1 INTEGER DEFAULT '0', score2 INTEGER DEFAULT '0');");
340 }
341 else
342 {
343 SQL_TQuery(hndl, SQL_DoNothing, "SET NAMES 'utf8';");
344 }
345
346 char sAuth[32];
347 for(int i = 1; i <= MaxClients; i++)
348 {
349 if(IsClientInGame(i) && IsClientAuthorized(i))
350 {
351 GetClientAuthId(i, AuthId_Steam2, sAuth, 63);
352 OnClientAuthorized(i, sAuth);
353 }
354 }
355}
356
357public void SQL_GetClientHighscores(Handle owner, Handle hndl, const char[] error, any userid)
358{
359 if(hndl == INVALID_HANDLE || strlen(error) > 0)
360 {
361 LogError("SQL query error: %s", error);
362 return;
363 }
364
365 int client = GetClientOfUserId(userid);
366 if(!client)
367 return;
368
369 while(SQL_MoreRows(hndl))
370 {
371 if(!SQL_FetchRow(hndl))
372 continue;
373
374 g_iHighScore[client][Mode_Snake1] = SQL_FetchInt(hndl, 0);
375 g_iHighScore[client][Mode_Snake2] = SQL_FetchInt(hndl, 1);
376 }
377}
378
379public void SQL_FetchTop10(Handle owner, Handle hndl, const char[] error, any userid)
380{
381 if(hndl == INVALID_HANDLE || strlen(error) > 0)
382 {
383 LogError("SQL query error: %s", error);
384 return;
385 }
386
387 int client = GetClientOfUserId(userid);
388 if(!client)
389 return;
390
391 Handle hMenu = CreateMenu(Menu_HandleTop10);
392 SetMenuTitle(hMenu, "Snake: Top 10");
393 SetMenuExitBackButton(hMenu, true);
394
395 char sMenu[128];
396 int iPlace = 1;
397 while(SQL_MoreRows(hndl))
398 {
399 if(!SQL_FetchRow(hndl))
400 continue;
401
402 SQL_FetchString(hndl, 0, sMenu, sizeof(sMenu));
403 Format(sMenu, sizeof(sMenu), "%d. %s: %d", iPlace, sMenu, SQL_FetchInt(hndl, 1));
404 AddMenuItem(hMenu, "", sMenu, ITEMDRAW_DISABLED);
405 iPlace++;
406 }
407
408 for(int i = iPlace; i <= 10; i++)
409 {
410 Format(sMenu, sizeof(sMenu), "%d. ", i);
411 AddMenuItem(hMenu, "", sMenu, ITEMDRAW_DISABLED);
412 }
413
414 DisplayMenu(hMenu, client, MENU_TIME_FOREVER);
415}
416
417public SQL_DoNothing(Handle:owner, Handle:hndl, const String:error[], any:data)
418{
419 if(hndl == INVALID_HANDLE || strlen(error) > 0)
420 {
421 LogError("SQL query error: %s", error);
422 return;
423 }
424}
425
426DrawSnakePanel(client, bool:bGameOver)
427{
428 new Handle:hPanel = CreatePanel();
429
430 new String:sGameField[512];
431 new iCoords[2];
432 for(new y=FIELD_Y-1;y>=0;y--)
433 {
434 for(new x=0;x<FIELD_X;x++)
435 {
436 // Put the snake on the field
437 iCoords[COORD_X] = x;
438 iCoords[COORD_Y] = y;
439 if(IsWormThere(client, iCoords))
440 Format(sGameField, sizeof(sGameField), "%s%s", sGameField, CHAR_WORM);
441 else if(g_iNomNomPosition[client][COORD_X] == x && g_iNomNomPosition[client][COORD_Y] == y)
442 Format(sGameField, sizeof(sGameField), "%s%s", sGameField, CHAR_FOOD);
443 else if(g_iAwesomeNomNomPosition[client][COORD_X] == x && g_iAwesomeNomNomPosition[client][COORD_Y] == y)
444 Format(sGameField, sizeof(sGameField), "%s%s", sGameField, CHAR_AWESOMEFOOD);
445 else
446 Format(sGameField, sizeof(sGameField), "%s%s", sGameField, CHAR_SPACE);
447 }
448 DrawPanelText(hPanel, sGameField);
449 Format(sGameField, sizeof(sGameField), "");
450 }
451
452 Format(sGameField, sizeof(sGameField), "Score: %d", g_iScore[client]);
453 DrawPanelText(hPanel, sGameField);
454
455 if(bGameOver)
456 {
457 DrawPanelItem(hPanel, "Game over. Restart?");
458 }
459 else
460 SetPanelKeys(hPanel, (1<<9));
461 SendPanelToClient(hPanel, client, Panel_GameHandler, (bGameOver?10:1));
462 CloseHandle(hPanel);
463}
464
465SetupSnakeGame(client)
466{
467 ClearTimer(g_hGameThink[client]);
468 ResetSnakeGame(client);
469 g_iWormLength[client] = WORM_MIN_LENGTH;
470 for(new i=0;i<WORM_MIN_LENGTH;i++)
471 {
472 g_iWormPositions[client][i][COORD_X] = (FIELD_X/2)-i+1-WORM_MIN_LENGTH;
473 g_iWormPositions[client][i][COORD_Y] = FIELD_Y/2;
474 }
475
476 PutNewNomNomOnField(client);
477
478 g_iNextAwesomeNomNom[client] = Math_GetRandomInt(100, 200);
479}
480
481ResetSnakeGame(client)
482{
483 for(new i=0;i<FIELD_X*FIELD_Y;i++)
484 {
485 g_iWormPositions[client][i][COORD_X] = -1;
486 g_iWormPositions[client][i][COORD_Y] = -1;
487 }
488 g_iNomNomPosition[client][COORD_X] = -1;
489 g_iNomNomPosition[client][COORD_Y] = -1;
490 g_iAwesomeNomNomPosition[client][COORD_X] = -1;
491 g_iAwesomeNomNomPosition[client][COORD_Y] = -1;
492 g_iWormCurrentDirection[client] = Direction_Right;
493 g_iWormNextDirection[client] = Direction_Right;
494 g_iWormLength[client] = 0;
495 g_iScore[client] = 0;
496 g_iNextAwesomeNomNom[client] = 0;
497 g_iAwesomeNomNomLifetime[client] = -1;
498}
499
500PutNewNomNomOnField(client, bool:bAwesome=false)
501{
502 // The gamefield is full..
503 if(g_iWormLength[client] == FIELD_X*FIELD_Y)
504 return;
505
506 // Can't spawn that extra food, since it's only one square in choice and that's filled with the normal food....
507 if(bAwesome
508 && g_iWormLength[client] == FIELD_X*FIELD_Y-1)
509 return;
510
511 new iCoords[2];
512 for(;;)
513 {
514 // Hope it won't take too long to find a free field.. PSEUDO RANDOMNESS!!
515 iCoords[COORD_X] = Math_GetRandomInt(0, FIELD_X-1);
516 iCoords[COORD_Y] = Math_GetRandomInt(0, FIELD_Y-1);
517 if(((bAwesome && (g_iNomNomPosition[client][COORD_X] != iCoords[COORD_X] || g_iNomNomPosition[client][COORD_Y] != iCoords[COORD_Y]))
518 || (!bAwesome && (g_iAwesomeNomNomPosition[client][COORD_X] != iCoords[COORD_X] || g_iAwesomeNomNomPosition[client][COORD_Y] != iCoords[COORD_Y])))
519 && !IsWormThere(client, iCoords))
520 break;
521 }
522 if(bAwesome)
523 {
524 g_iAwesomeNomNomPosition[client][COORD_X] = iCoords[COORD_X];
525 g_iAwesomeNomNomPosition[client][COORD_Y] = iCoords[COORD_Y];
526 }
527 else
528 {
529 g_iNomNomPosition[client][COORD_X] = iCoords[COORD_X];
530 g_iNomNomPosition[client][COORD_Y] = iCoords[COORD_Y];
531 }
532}
533
534IsWormThere(client, const iCoords[2])
535{
536 for(new i=0;i<g_iWormLength[client];i++)
537 {
538 if(g_iWormPositions[client][i][COORD_X] == iCoords[COORD_X] && g_iWormPositions[client][i][COORD_Y] == iCoords[COORD_Y])
539 {
540 return true;
541 }
542 }
543 return false;
544}
545
546bool:MoveSnake(client)
547{
548 new iTempPositions[2];
549 iTempPositions[COORD_X] = g_iWormPositions[client][0][COORD_X];
550 iTempPositions[COORD_Y] = g_iWormPositions[client][0][COORD_Y];
551
552 switch(g_iWormCurrentDirection[client])
553 {
554 case Direction_Right:
555 {
556 // Hit the wall on the right!!!
557 if(g_iWormPositions[client][0][COORD_X] == FIELD_X-1)
558 {
559 if(g_iSnakeMode[client] == Mode_Snake1)
560 return false;
561 else
562 {
563 iTempPositions[COORD_X] = 0;
564 }
565 }
566 else
567 iTempPositions[COORD_X]++;
568
569 // Is the food there?
570 if(iTempPositions[COORD_X] == g_iNomNomPosition[client][COORD_X]
571 && iTempPositions[COORD_Y] == g_iNomNomPosition[client][COORD_Y])
572 {
573 // shift it all one up. Don't cut of the last one, since it's getting longer!
574 PushWormArrayOneUp(client, false);
575
576 g_iWormPositions[client][0][COORD_X] = iTempPositions[COORD_X];
577
578 g_iWormLength[client]++;
579 g_iScore[client] += FOOD_SCORE;
580
581 PutNewNomNomOnField(client);
582
583 return true;
584 }
585
586 // Is the awesome food there?
587 if(iTempPositions[COORD_X] == g_iAwesomeNomNomPosition[client][COORD_X]
588 && iTempPositions[COORD_Y] == g_iAwesomeNomNomPosition[client][COORD_Y])
589 {
590 PushWormArrayOneUp(client, false);
591 g_iWormPositions[client][0][COORD_X] = iTempPositions[COORD_X];
592
593 g_iWormLength[client] -= 3;
594 if(g_iWormLength[client] < WORM_MIN_LENGTH)
595 g_iWormLength[client] = WORM_MIN_LENGTH;
596
597 RemoveAllCoordsAfterLength(client);
598
599 g_iScore[client] += FOOD_SCORE;
600
601 g_iAwesomeNomNomPosition[client][COORD_X] = -1;
602 g_iAwesomeNomNomPosition[client][COORD_Y] = -1;
603 g_iAwesomeNomNomLifetime[client] = -1;
604 g_iNextAwesomeNomNom[client] = Math_GetRandomInt(100, 200);
605
606 return true;
607 }
608
609 // Eat yaself!!
610 if(IsWormThere(client, iTempPositions))
611 return false;
612
613 PushWormArrayOneUp(client, true);
614
615 g_iWormPositions[client][0][COORD_X] = iTempPositions[COORD_X];
616 return true;
617 }
618 case Direction_Down:
619 {
620 // Hit the wall at the bottom!!!
621 if(g_iWormPositions[client][0][COORD_Y] == 0)
622 {
623 if(g_iSnakeMode[client] == Mode_Snake1)
624 return false;
625 else
626 {
627 iTempPositions[COORD_Y] = FIELD_Y-1;
628 }
629 }
630 else
631 iTempPositions[COORD_Y]--;
632
633
634 // Is the food there?
635 if(iTempPositions[COORD_X] == g_iNomNomPosition[client][COORD_X]
636 && iTempPositions[COORD_Y] == g_iNomNomPosition[client][COORD_Y])
637 {
638 // shift it all one up. Don't cut of the last one, since it's getting longer!
639 PushWormArrayOneUp(client, false);
640
641 g_iWormPositions[client][0][COORD_Y] = iTempPositions[COORD_Y];
642
643 g_iWormLength[client]++;
644 g_iScore[client] += FOOD_SCORE;
645
646 PutNewNomNomOnField(client);
647
648 return true;
649 }
650
651 if(iTempPositions[COORD_X] == g_iAwesomeNomNomPosition[client][COORD_X]
652 && iTempPositions[COORD_Y] == g_iAwesomeNomNomPosition[client][COORD_Y])
653 {
654 PushWormArrayOneUp(client, false);
655 g_iWormPositions[client][0][COORD_Y] = iTempPositions[COORD_Y];
656
657 g_iWormLength[client] -= 3;
658 if(g_iWormLength[client] < WORM_MIN_LENGTH)
659 g_iWormLength[client] = WORM_MIN_LENGTH;
660
661 RemoveAllCoordsAfterLength(client);
662
663 g_iScore[client] += FOOD_SCORE;
664
665 g_iAwesomeNomNomPosition[client][COORD_X] = -1;
666 g_iAwesomeNomNomPosition[client][COORD_Y] = -1;
667 g_iAwesomeNomNomLifetime[client] = -1;
668 g_iNextAwesomeNomNom[client] = Math_GetRandomInt(100, 200);
669
670 return true;
671 }
672
673 // Eat yaself!!
674 if(IsWormThere(client, iTempPositions))
675 return false;
676
677 PushWormArrayOneUp(client, true);
678
679 g_iWormPositions[client][0][COORD_Y] = iTempPositions[COORD_Y];
680 return true;
681 }
682 case Direction_Left:
683 {
684 // Hit the wall on the left!!!
685 if(g_iWormPositions[client][0][COORD_X] == 0)
686 {
687 if(g_iSnakeMode[client] == Mode_Snake1)
688 return false;
689 else
690 {
691 iTempPositions[COORD_X] = FIELD_X-1;
692 }
693 }
694 else
695 iTempPositions[COORD_X]--;
696
697 // Is the food there?
698 if(iTempPositions[COORD_X] == g_iNomNomPosition[client][COORD_X]
699 && iTempPositions[COORD_Y] == g_iNomNomPosition[client][COORD_Y])
700 {
701 // shift it all one up. Don't cut of the last one, since it's getting longer!
702 PushWormArrayOneUp(client, false);
703
704 g_iWormPositions[client][0][COORD_X] = iTempPositions[COORD_X];
705
706 g_iWormLength[client]++;
707 g_iScore[client] += FOOD_SCORE;
708
709 PutNewNomNomOnField(client);
710
711 return true;
712 }
713
714 if(iTempPositions[COORD_X] == g_iAwesomeNomNomPosition[client][COORD_X]
715 && iTempPositions[COORD_Y] == g_iAwesomeNomNomPosition[client][COORD_Y])
716 {
717 PushWormArrayOneUp(client, false);
718 g_iWormPositions[client][0][COORD_X] = iTempPositions[COORD_X];
719
720 g_iWormLength[client] -= 3;
721 if(g_iWormLength[client] < WORM_MIN_LENGTH)
722 g_iWormLength[client] = WORM_MIN_LENGTH;
723
724 RemoveAllCoordsAfterLength(client);
725
726 g_iScore[client] += FOOD_SCORE;
727
728 g_iAwesomeNomNomPosition[client][COORD_X] = -1;
729 g_iAwesomeNomNomPosition[client][COORD_Y] = -1;
730 g_iAwesomeNomNomLifetime[client] = -1;
731 g_iNextAwesomeNomNom[client] = Math_GetRandomInt(100, 200);
732
733 return true;
734 }
735
736 // Eat yaself!!
737 if(IsWormThere(client, iTempPositions))
738 return false;
739
740 PushWormArrayOneUp(client, true);
741
742 g_iWormPositions[client][0][COORD_X] = iTempPositions[COORD_X];
743 return true;
744 }
745 case Direction_Up:
746 {
747 // Hit the wall at the top!!!
748 if(g_iWormPositions[client][0][COORD_Y] == FIELD_Y-1)
749 {
750 if(g_iSnakeMode[client] == Mode_Snake1)
751 return false;
752 else
753 {
754 iTempPositions[COORD_Y] = 0;
755 }
756 }
757 else
758 iTempPositions[COORD_Y]++;
759
760 // Is the food there?
761 if(iTempPositions[COORD_X] == g_iNomNomPosition[client][COORD_X]
762 && iTempPositions[COORD_Y] == g_iNomNomPosition[client][COORD_Y])
763 {
764 // shift it all one up. Don't cut of the last one, since it's getting longer!
765 PushWormArrayOneUp(client, false);
766
767 g_iWormPositions[client][0][COORD_Y] = iTempPositions[COORD_Y];
768
769 g_iWormLength[client]++;
770 g_iScore[client] += FOOD_SCORE;
771
772 PutNewNomNomOnField(client);
773
774 return true;
775 }
776
777 if(iTempPositions[COORD_X] == g_iAwesomeNomNomPosition[client][COORD_X]
778 && iTempPositions[COORD_Y] == g_iAwesomeNomNomPosition[client][COORD_Y])
779 {
780 PushWormArrayOneUp(client, false);
781 g_iWormPositions[client][0][COORD_Y] = iTempPositions[COORD_Y];
782
783 g_iWormLength[client] -= 3;
784 if(g_iWormLength[client] < WORM_MIN_LENGTH)
785 g_iWormLength[client] = WORM_MIN_LENGTH;
786
787 RemoveAllCoordsAfterLength(client);
788
789 g_iScore[client] += FOOD_SCORE;
790
791 g_iAwesomeNomNomPosition[client][COORD_X] = -1;
792 g_iAwesomeNomNomPosition[client][COORD_Y] = -1;
793 g_iAwesomeNomNomLifetime[client] = -1;
794 g_iNextAwesomeNomNom[client] = Math_GetRandomInt(100, 200);
795
796 return true;
797 }
798
799 // Eat yaself!!
800 if(IsWormThere(client, iTempPositions))
801 return false;
802
803 PushWormArrayOneUp(client, true);
804
805 g_iWormPositions[client][0][COORD_Y] = iTempPositions[COORD_Y];
806 return true;
807 }
808 }
809
810 return false;
811}
812
813PushWormArrayOneUp(client, bool:bRemoveLast)
814{
815 new iLimit = g_iWormLength[client];
816 if(bRemoveLast)
817 iLimit--;
818
819 for(new i=iLimit-1;i>=0;i--)
820 {
821 if(i < FIELD_X*FIELD_Y)
822 {
823 g_iWormPositions[client][i+1][COORD_X] = g_iWormPositions[client][i][COORD_X];
824 g_iWormPositions[client][i+1][COORD_Y] = g_iWormPositions[client][i][COORD_Y];
825 }
826 }
827
828 if(bRemoveLast)
829 {
830 g_iWormPositions[client][g_iWormLength[client]][COORD_X] = -1;
831 g_iWormPositions[client][g_iWormLength[client]][COORD_Y] = -1;
832 }
833}
834
835RemoveAllCoordsAfterLength(client)
836{
837 for(new i=g_iWormLength[client]-1;i<FIELD_X*FIELD_Y;i++)
838 {
839 g_iWormPositions[client][i][COORD_X] = -1;
840 g_iWormPositions[client][i][COORD_Y] = -1;
841 }
842}
843
844WormDirection:GetOppositeDirection(WormDirection:iDirection)
845{
846 switch(iDirection)
847 {
848 case Direction_Right:
849 return Direction_Left;
850 case Direction_Down:
851 return Direction_Up;
852 case Direction_Left:
853 return Direction_Right;
854 case Direction_Up:
855 return Direction_Down;
856 }
857
858 // COMPILER!!! GRRR
859 return WormDirection:1337;
860}
861
862stock ClearTimer(&Handle:timer, bool:autoClose=false)
863{
864 if(timer != INVALID_HANDLE)
865 KillTimer(timer, autoClose);
866 timer = INVALID_HANDLE;
867}