Guest User

Untitled

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