Advertisement
Guest User

PUG 1.1

a guest
Sep 12th, 2012
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 67.13 KB | None | 0 0
  1. #include <sourcemod>
  2. #include <cstrike>
  3. #include <sdktools>
  4. #include <sdktools_functions>
  5.  
  6. #if defined MAXPLAYERS
  7. #undef MAXPLAYERS
  8. #define MAXPLAYERS 64
  9. #endif
  10.  
  11. new Handle:hTVEnabled;
  12. new Handle:RestartTimers = INVALID_HANDLE;
  13. new Handle:hMaxPlayers;
  14. #define MAX_PLAYERS_DEFAULT "10"
  15. new OffsetAccount; // MONEY OFFSET
  16. new bool:bPubChatMuted[MAXPLAYERS+1]=false;
  17. new bool:bTeamChatMuted[MAXPLAYERS+1]=false;
  18. new bool:bMuted[MAXPLAYERS+1][MAXPLAYERS+1];
  19. new Float:fLastMessage[MAXPLAYERS+1];
  20. new bool:bAuthed[MAXPLAYERS+1];
  21. new Handle:hBotQuota = INVALID_HANDLE;
  22. new PlCount = 0;
  23.  
  24. // Current match stuff
  25. enum MatchState
  26. {
  27. MS_Pre_Setup = 0,
  28. MS_Setup,
  29. MS_Before_First_Half, // This is only used if the map changes.
  30. MS_Live_First_Half,
  31. MS_Before_Second_Half, // Always used.
  32. MS_Live_Second_Half,
  33. MS_Before_Overtime_First_Half,
  34. MS_Live_Overtime_First_Half,
  35. MS_Before_Overtime_Second_Half,
  36. MS_Live_Overtime_Second_Half,
  37. MS_Post_Match,
  38. };
  39.  
  40. new MatchState:gMatchState = MS_Pre_Setup;
  41. new TeamAScore; // Team A goes CT first.
  42. new TeamBScore; // Team B goes T first.
  43. // Keep in mind team A and B are always randomized / captains.
  44. // In the case of captains, it is still random which captains will be on which team, A or B.
  45. new CurrentRound = 0;
  46. new String:MatchMap[32] = ""; // Map name.
  47. enum RuleType
  48. {
  49. Rules_PUG = 0,
  50. Rules_CGS,
  51. };
  52. new RuleType:Ruleset = Rules_PUG;
  53. #define ROUNDS_HALF_PUG 15
  54. #define ROUNDS_HALF_CGS 11
  55. #define ROUNDS_OVERTIME_HALF_PUG 5
  56. #define ROUNDS_OVERTIME_HALF_CGS 1
  57. #define MAX_ROUNDS 50 // We won't exceed 50 rounds for now.
  58. new Handle:hMatchDamage[MAX_ROUNDS]; // Vector of all the damage.
  59. new Handle:hMatchKills[MAX_ROUNDS]; // Vector of all the kills.
  60. new bool:CaptainMode = false;
  61. new bool:BunnyHopMode = false;
  62. #define MAX_MAPS 50 // For now.
  63. new String:MapNames[MAX_MAPS][32]; // Loaded OnPluginStart()
  64. #define TEAM_A 0
  65. #define TEAM_B 1
  66. #define TEAM_COUNT 2
  67. #define TEAM_CAPTAIN 0
  68. new String:TeamPlayers[TEAM_COUNT][5][24]; // Steam ID's. Cached before map change.
  69. new bool:RoundCounterOn = false;
  70.  
  71. //Clients
  72. new bool:bReady[MAXPLAYERS+1];
  73. new String:clientUsername[MAXPLAYERS+1][24];
  74. new readyUpTime[MAXPLAYERS+1];
  75. new notReadyTime[MAXPLAYERS+1];
  76. new bool:FirstSpawn[MAXPLAYERS+1] = true;
  77. new bool:AutoDmg[MAXPLAYERS+1] = false;
  78. new bool:bDisconnecting[MAXPLAYERS+1] = true;
  79.  
  80. OnAllReady()
  81. {
  82. /*
  83. enum MatchState
  84. {
  85. MS_Pre_Setup = 0,
  86. MS_Setup_Up,
  87. MS_Before_First_Half, // This is only used if the map changes.
  88. MS_Live_First_Half,
  89. MS_Before_Second_Half, // Always used.
  90. MS_Live_Second_Half,
  91. MS_Before_Overtime_First_Half,
  92. MS_Live_Overtime_First_Half,
  93. MS_Before_Overtime_Second_Half,
  94. MS_Live_Overtime_Second_Half,
  95. MS_Post_Match,
  96. };
  97. */
  98. if(gMatchState == MS_Pre_Setup)
  99. {
  100. StartMatchSetup();
  101. }
  102. else if(gMatchState == MS_Before_First_Half)
  103. {
  104. StartFirstHalf();
  105. }
  106. else if(gMatchState == MS_Before_Second_Half)
  107. {
  108. StartSecondHalf();
  109. }
  110. else if(gMatchState == MS_Before_Overtime_First_Half)
  111. {
  112. StartOTFirstHalf();
  113. }
  114. else if(gMatchState == MS_Before_Overtime_Second_Half)
  115. {
  116. StartOTSecondHalf();
  117. }
  118. }
  119.  
  120. PartialNameClient(const String:matchText[])
  121. {
  122. new Client = 0;
  123. for(new x=1;x<=MAXPLAYERS;x++)
  124. {
  125. if(ValidClient(x) && !IsSourceTV(x))
  126. {
  127. new String:clName[32];
  128. GetClientName(x, clName, 32);
  129. if(StrContains(clName, matchText, false)>=0)
  130. {
  131. if(Client!=0)
  132. {
  133. return -1; // -1 == multiple
  134. }
  135. else
  136. {
  137. Client = x;
  138. }
  139. }
  140. }
  141. }
  142. return Client;
  143. }
  144.  
  145. CSLTeam(client)
  146. {
  147. if(!ValidClient(client) || IsSourceTV(client))
  148. {
  149. return -1;
  150. }
  151. new String:steamID[24];
  152. GetClientAuthString(client, steamID, 24);
  153. return CSLTeamOfSteam(steamID);
  154. }
  155.  
  156. CSLTeamOfSteam(const String:steamID[])
  157. {
  158. for(new x=0;x<5;x++)
  159. {
  160. if(StrEqual(steamID, TeamPlayers[TEAM_A][x]))
  161. {
  162. return TEAM_A;
  163. }
  164. }
  165. for(new x=0;x<5;x++)
  166. {
  167. if(StrEqual(steamID, TeamPlayers[TEAM_B][x]))
  168. {
  169. return TEAM_B;
  170. }
  171. }
  172. return -1;
  173. }
  174.  
  175. bool:AllowBots()
  176. {
  177. return false; // Temp.
  178. }
  179.  
  180. ClientDefaults(client)
  181. {
  182. fLastMessage[client] = 0.0;
  183. AutoDmg[client] = false;
  184. FirstSpawn[client] = true;
  185. if(ValidClient(client)) {
  186. GetClientName(client, clientUsername[client], 24);
  187. }
  188. bAuthed[client] = false;
  189. bReady[client] = false;
  190. readyUpTime[client] = 0;
  191. notReadyTime[client] = 0;
  192. bDisconnecting[client] = true;
  193. bPubChatMuted[client] = false;
  194. bTeamChatMuted[client] = false;
  195. for(new x=0;x<=MAXPLAYERS;x++)
  196. {
  197. bMuted[client][x] = false;
  198. }
  199. }
  200.  
  201. Kick(client, String:format[], any:...)
  202. {
  203. if(!ValidClient(client))
  204. {
  205. return;
  206. }
  207. new String:reason[256];
  208. VFormat(reason, sizeof(reason), format, 3);
  209. if(StrEqual(reason,""))
  210. {
  211. KickClient(client);
  212. }
  213. else
  214. {
  215. KickClient(client,"%s",reason);
  216. }
  217. PrintToServer("KICK (%d): %s",client,reason);
  218. }
  219.  
  220. bool:ReadyUpState()
  221. {
  222. if(gMatchState==MS_Pre_Setup || gMatchState==MS_Before_First_Half || gMatchState==MS_Before_Second_Half
  223. || gMatchState==MS_Before_Overtime_First_Half || gMatchState==MS_Before_Overtime_Second_Half)
  224. {
  225. return true;
  226. }
  227. return false;
  228. }
  229.  
  230. ChangeCvar(const String:cvarName[], const String:newValue[])
  231. {
  232. new Handle:hVar = FindConVar(cvarName);
  233. new oldFlags = GetConVarFlags(hVar);
  234. new newFlags = oldFlags;
  235. newFlags &= ~FCVAR_NOTIFY;
  236. SetConVarFlags(hVar, newFlags);
  237. SetConVarString(hVar, newValue);
  238. SetConVarFlags(hVar, oldFlags);
  239. }
  240.  
  241. EnterReadyUpState()
  242. {
  243. // Just a hack for freeze time.
  244. ChangeCvar("mp_freezetime", "3");
  245. ChangeCvar("mp_buytime", "999");
  246. ChangeCvar("mp_forcecamera", "0");
  247. for(new x=0;x<=MAXPLAYERS;x++)
  248. {
  249. notReadyTime[x] = GetTime();
  250. bReady[x] = false;
  251. }
  252. }
  253.  
  254. public Action:WarmUpSpawner(Handle:timer)
  255. {
  256. if(ReadyUpState())
  257. {
  258. if(GetClientCount() != 10)
  259. {
  260. PrintToChatAll("[PUG] %d/10 Players are connected.", GetClientCount());
  261. }
  262. else
  263. {
  264. PrintToChatAll("[PUG] All player have connected.");
  265. }
  266. PrintToChatAll("Players not ready:");
  267. new String:plName1[32];
  268. new String:plName2[32];
  269. new String:plName3[32];
  270. new String:plName4[32];
  271. new String:plName5[32];
  272. new String:plName6[32];
  273. new String:plName7[32];
  274. new String:plName8[32];
  275. new String:plName9[32];
  276. new String:plName10[32];
  277. for(new x=1;x<=MAXPLAYERS;x++)
  278. {
  279. if(!bReady[x])
  280. {
  281. new String:plName[32];
  282. if(x==1)
  283. {
  284. GetClientName(x, plName1, 32);
  285. }
  286. if(x==2)
  287. {
  288. GetClientName(x, plName2, 32);
  289. }
  290. if(x==3)
  291. {
  292. GetClientName(x, plName3, 32);
  293. }
  294. if(x==4)
  295. {
  296. GetClientName(x, plName4, 32);
  297. }
  298. if(x==5)
  299. {
  300. GetClientName(x, plName5, 32);
  301. }
  302. if(x==6)
  303. {
  304. GetClientName(x, plName6, 32);
  305. }
  306. if(x==7)
  307. {
  308. GetClientName(x, plName7, 32);
  309. }
  310. if(x==8)
  311. {
  312. GetClientName(x, plName8, 32);
  313. }
  314. if(x==9)
  315. {
  316. GetClientName(x, plName9, 32);
  317. }
  318. if(x==10)
  319. {
  320. GetClientName(x, plName10, 32);
  321. }
  322. PrintToChatAll("%s %s %s %s %s", plName1, plName2, plName3, plName4, plName5);
  323. }
  324. else
  325. {
  326. PrintToChatAll("(None)");
  327. }
  328. PrintToChatAll("%s %s %s %s %s", plName6, plName7, plName8, plName9, plName10);
  329. PrintToChatAll("Type /ready in chat when you are ready.");
  330. if(gMatchState!=MS_Pre_Setup)
  331. {
  332. return Plugin_Stop;
  333. }
  334. }
  335. DeleteBomb();
  336. for(new x=1;x<=MAXPLAYERS;x++)
  337. {
  338. if(ValidClient(x) && !IsSourceTV(x) && GetClientTeam(x)>=CS_TEAM_T && !IsPlayerAlive(x))
  339. {
  340. // Is it warm up?
  341. if(ReadyUpState())
  342. {
  343. CS_RespawnPlayer(x);
  344. }
  345. }
  346. }
  347. }
  348. }
  349.  
  350. new seconds=60;
  351. new minute=9;
  352.  
  353. public Action:OneSecCheck(Handle:timer)
  354. {
  355. seconds--;
  356. for(new x=1;x<=MAXPLAYERS;x++)
  357. {
  358. if(ValidClient(x) && !IsFakeClient(x))
  359. {
  360. if(ReadyUpState())
  361. {
  362. new Handle:hBuffer = StartMessageOne("KeyHintText", x);
  363. new String:tmptext[256];
  364. if(seconds==-1)
  365. {
  366. minute--;
  367. seconds=59;
  368. }
  369. if(minute==-1)
  370. {
  371. seconds=-2;
  372. }
  373. Format(tmptext, 256, "TIME: 0s");
  374. if(minute==9)
  375. {
  376. Format(tmptext, 256, "TIME: 9m %is", seconds);
  377. }
  378. if(minute==8)
  379. {
  380. Format(tmptext, 256, "TIME: 8m %is", seconds);
  381. }
  382. if(minute==7)
  383. {
  384. Format(tmptext, 256, "TIME: 7m %is", seconds);
  385. }
  386. if(minute==6)
  387. {
  388. Format(tmptext, 256, "TIME: 6m %is", seconds);
  389. }
  390. if(minute==5)
  391. {
  392. Format(tmptext, 256, "TIME: 5m %is", seconds);
  393. }
  394. if(minute==4)
  395. {
  396. Format(tmptext, 256, "TIME: 4m %is", seconds);
  397. }
  398. if(minute==3)
  399. {
  400. Format(tmptext, 256, "TIME: 3m %is", seconds);
  401. }
  402. if(minute==2)
  403. {
  404. Format(tmptext, 256, "TIME: 2m %is", seconds);
  405. }
  406. if(minute==1)
  407. {
  408. Format(tmptext, 256, "TIME: 1m %is", seconds);
  409. }
  410. if(seconds != -2 && minute == 0)
  411. {
  412. Format(tmptext, 256, "TIME: %is", seconds);
  413. }
  414. BfWriteByte(hBuffer, 1);
  415. BfWriteString(hBuffer, tmptext);
  416. EndMessage();
  417. }
  418. }
  419. }
  420. if(minute==-1)
  421. {
  422. OnAllReady();
  423. return Plugin_Stop;
  424. }
  425. else
  426. {
  427. return Plugin_Continue;
  428. }
  429. }
  430.  
  431. // This function checks if a STEAMID is valid.
  432. // AS VALVE UPDATES THEIR STANDARDS CHANGE THIS
  433. bool:BadSteamId(const String:steamID[])
  434. {
  435. if(!AllowBots() && StrEqual(steamID,"BOT"))
  436. return true;
  437.  
  438. return false; // It's good.
  439. }
  440.  
  441. bool:ValidClient(client,bool:check_alive=false)
  442. {
  443. if(client>0 && client<=MaxClients && IsClientConnected(client) && IsClientInGame(client))
  444. {
  445. if(check_alive && !IsPlayerAlive(client))
  446. {
  447. return false;
  448. }
  449. return true;
  450. }
  451. return false;
  452. }
  453.  
  454. public Action:MapDelayed(Handle:timer)
  455. {
  456. ChangeMatchState(MS_Before_First_Half);
  457. new String:curmap[32];
  458. GetCurrentMap(curmap, 32);
  459. if(!StrEqual(curmap, MatchMap))
  460. {
  461. ForceChangeLevel(MatchMap, "Setting up match");
  462. }
  463. }
  464.  
  465. TeamSize(teamCSL)
  466. {
  467. new i = 0;
  468. for(new x=0;x<5;x++)
  469. {
  470. if(!StrEqual(TeamPlayers[teamCSL][x],""))
  471. {
  472. i++;
  473. }
  474. }
  475. return i;
  476. }
  477.  
  478. TeamSizeActive(teamCSL)
  479. {
  480. new i = 0;
  481. for(new x=0;x<5;x++)
  482. {
  483. if(!StrEqual(TeamPlayers[teamCSL][x],""))
  484. {
  485. new cAtX = ClientOfSteamId(TeamPlayers[teamCSL][x]);
  486. if(ValidClient(cAtX))
  487. {
  488. i++;
  489. }
  490. }
  491. }
  492. return i;
  493. }
  494.  
  495. AddSteamToTeam(const String:steamID[], teamNum)
  496. {
  497. // If the team is full, look for a disconnect. They are going to be replaced and will probably be penelized.
  498. new TeamCount = TeamSize(teamNum);
  499. if(TeamCount<5)
  500. {
  501. for(new x=0;x<5;x++)
  502. {
  503. if(StrEqual(TeamPlayers[teamNum][x],""))
  504. {
  505. Format(TeamPlayers[teamNum][x], 24, "%s", steamID);
  506. return;
  507. }
  508. }
  509. }
  510. else
  511. {
  512. // Sorry, whoever left is bound to cry if they were trying to come back :(
  513. for(new x=0;x<5;x++)
  514. {
  515. new ClientAt = ClientOfSteamId(TeamPlayers[teamNum][x]);
  516. if(!ValidClient(ClientAt))
  517. {
  518. Format(TeamPlayers[teamNum][x], 24, "%s", steamID);
  519. return;
  520. }
  521. }
  522. }
  523. }
  524.  
  525. StartFirstHalf()
  526. {
  527. // Record.
  528. // Map.
  529. ServerCommand("tv_record %d_%s\n", GetTime(), MatchMap);
  530. if(!CaptainMode)
  531. {
  532. // Go through each person (random order), if they aren't on a team assign them to the team lacking players, or random.
  533. new bool:ClientIterated[MAXPLAYERS+1] = false;
  534. for(new i=1;i<=MAXPLAYERS;i++)
  535. {
  536. new RandClient = GetRandomInt(1,MAXPLAYERS);
  537. while(ClientIterated[RandClient])
  538. {
  539. RandClient = GetRandomInt(1,MAXPLAYERS);
  540. }
  541. ClientIterated[RandClient] = true;
  542. if(!ValidClient(RandClient) || IsSourceTV(RandClient))
  543. {
  544. continue;
  545. }
  546. new String:steamID[24];
  547. GetClientAuthString(RandClient, steamID, 24);
  548. if(CSLTeam(RandClient)!=-1)
  549. {
  550. continue; // Already on a team, on a group likely.
  551. }
  552. // Now put them on a team.
  553. new TeamACount = TeamSizeActive(TEAM_A);
  554. new TeamBCount = TeamSizeActive(TEAM_B);
  555. if(TeamACount < TeamBCount)
  556. {
  557. AddSteamToTeam(steamID, TEAM_A);
  558. }
  559. else if(TeamBCount < TeamACount)
  560. {
  561. AddSteamToTeam(steamID, TEAM_B);
  562. }
  563. else
  564. {
  565. new RandTeam = GetRandomInt(TEAM_A, TEAM_B);
  566. AddSteamToTeam(steamID, RandTeam);
  567. }
  568. }
  569. }
  570. /*
  571. else
  572. {
  573. Later
  574. }
  575. */
  576. // Clear scores just incase.
  577. TeamAScore = 0;
  578. TeamBScore = 0;
  579. // Team A goes T first
  580. for(new x=1;x<=MAXPLAYERS;x++)
  581. {
  582. if(ValidClient(x) && !IsSourceTV(x))
  583. {
  584. new Team = CSLTeam(x);
  585. if(Team==TEAM_A)
  586. {
  587. CS_SwitchTeam(x, CS_TEAM_T);
  588. }
  589. else if(Team==TEAM_B)
  590. {
  591. CS_SwitchTeam(x, CS_TEAM_CT);
  592. }
  593. else
  594. {
  595. Kick(x, "Sorry, you aren't supposed to be here");
  596. }
  597. }
  598. }
  599.  
  600. ChangeMatchState(MS_Live_First_Half);
  601.  
  602. PrintToChatAll("[PUG] Starting the first half...");
  603. EnforceMatchCvars();
  604. ServerCommand("mp_restartgame 1\n");
  605. RestartTimers = CreateTimer(2.0, RestartSecondTime);
  606. }
  607.  
  608. public Action:RestartSecondTime(Handle:timer)
  609. {
  610. ServerCommand("mp_restartgame 5\n");
  611. RestartTimers = CreateTimer(6.0, RestartThirdTime)
  612. }
  613.  
  614. public Action:RestartThirdTime(Handle:timer)
  615. {
  616. ServerCommand("mp_restartgame 5\n");
  617. PrintToChatAll("[PUG] Next round is live.");
  618. RestartTimers = CreateTimer(4.5, LiveMessageTimer);
  619. }
  620.  
  621. public Action:LiveMessageTimer(Handle:timer)
  622. {
  623. RestartTimers = INVALID_HANDLE;
  624. PrintCenterTextAll("MATCH IS LIVE!");
  625. RoundCounterOn = true;
  626. PrintToChatAll("[PUG] Match is live!");
  627. }
  628.  
  629. bool:TeamsSetup()
  630. {
  631. if(gMatchState>=MS_Live_First_Half && gMatchState<MS_Post_Match)
  632. {
  633. return true;
  634. }
  635. return false;
  636. }
  637.  
  638. EnforceMatchCvars(bool:ot = false)
  639. {
  640. ChangeCvar("mp_freezetime", "8");
  641. ChangeCvar("mp_forcecamera", "1");
  642. ChangeCvar("mp_buytime", "15");
  643. if(BunnyHopMode)
  644. {
  645. ChangeCvar("sv_enablebunnyhopping", "1");
  646. }
  647. else
  648. {
  649. ChangeCvar("sv_enablebunnyhopping", "0");
  650. }
  651. if(Ruleset==Rules_PUG)
  652. {
  653. ChangeCvar("mp_roundtime", "1.75");
  654. }
  655. else if(Ruleset==Rules_CGS)
  656. {
  657. ChangeCvar("mp_roundtime", "1.50");
  658. }
  659. if(ot)
  660. {
  661. if(Ruleset==Rules_PUG)
  662. {
  663. ChangeCvar("mp_startmoney", "8000");
  664. }
  665. else if(Ruleset==Rules_CGS)
  666. {
  667. ChangeCvar("mp_startmoney", "16000");
  668. }
  669. }
  670. else
  671. {
  672. if(Ruleset==Rules_PUG)
  673. {
  674. ChangeCvar("mp_startmoney", "800");
  675. }
  676. else if(Ruleset==Rules_CGS)
  677. {
  678. ChangeCvar("mp_startmoney", "8000");
  679. }
  680. }
  681. }
  682.  
  683. StartSecondHalf()
  684. {
  685. ChangeMatchState(MS_Live_Second_Half);
  686. EnforceMatchCvars();
  687. PrintToChatAll("[PUG] Starting the second half...");
  688. ServerCommand("mp_restartgame 1\n");
  689. RestartTimers = CreateTimer(2.0, RestartSecondTime);
  690. }
  691.  
  692. StartOTFirstHalf()
  693. {
  694. ChangeMatchState(MS_Live_Overtime_First_Half);
  695.  
  696. PrintToChatAll("[PUG] Starting the first half of overtime...");
  697. EnforceMatchCvars(true);
  698. ServerCommand("mp_restartgame 1\n");
  699. RestartTimers = CreateTimer(2.0, RestartSecondTime);
  700. }
  701.  
  702. StartOTSecondHalf()
  703. {
  704. ChangeMatchState(MS_Live_Overtime_Second_Half);
  705.  
  706. PrintToChatAll("[PUG] Starting the second half of overtime...");
  707. EnforceMatchCvars(true);
  708. ServerCommand("mp_restartgame 1\n");
  709. RestartTimers = CreateTimer(2.0, RestartSecondTime);
  710. }
  711.  
  712. // BUG: Votes dont continue if failed.
  713. TryStartMatch()
  714. {
  715. // Are we on the correct map?
  716. new String:curmap[32];
  717. GetCurrentMap(curmap, 32);
  718. if(!StrEqual(curmap, MatchMap))
  719. {
  720. PrintToChatAll("[PUG] Map is changing in 5 seconds, brace yourselves.");
  721. CreateTimer(5.0, MapDelayed);
  722. }
  723. else
  724. {
  725. StartFirstHalf();
  726. }
  727. }
  728.  
  729. RulesCSL()
  730. {
  731. PrintToChatAll("[PUG] Ruleset will be: PUG");
  732. Ruleset = Rules_PUG;
  733. TeamVote();
  734. }
  735.  
  736. SetMatchMap(const String:mapname[])
  737. {
  738. PrintToChatAll("[PUG] Map will be: %s", mapname);
  739. Format(MatchMap, 32, mapname);
  740. TryStartMatch();
  741. }
  742.  
  743. public Handle_MapVote(Handle:menu, MenuAction:action, param1, param2)
  744. {
  745. if (action == MenuAction_End)
  746. {
  747. CloseHandle(menu);
  748. } else if (action == MenuAction_VoteEnd) {
  749. new String:map[32];
  750. GetMenuItem(menu, param1, map, sizeof(map));
  751. if(StrEqual(map,"Random"))
  752. {
  753. SetMatchMap(MapNames[GetRandomInt(0, GetMapCount()-1)]);
  754. }
  755. else
  756. {
  757. SetMatchMap(map);
  758. }
  759. }
  760. else if(action==MenuAction_VoteCancel)
  761. {
  762. // Choose a random map.
  763. SetMatchMap(MapNames[GetRandomInt(0, GetMapCount()-1)]);
  764. }
  765. }
  766.  
  767. StartMapVote()
  768. {
  769. // Choose a rule set.
  770. if (IsVoteInProgress())
  771. {
  772. CancelVote();
  773. }
  774.  
  775. new Handle:menu = CreateMenu(Handle_MapVote);
  776. SetMenuTitle(menu, "Vote for the map");
  777. // Random order.
  778. new bool:bShowed[MAX_MAPS];
  779. for(new x=0;x<GetMapCount();x++)
  780. {
  781. new Rand = GetRandomInt(0, GetMapCount()-1);
  782. while(bShowed[Rand])
  783. {
  784. Rand = GetRandomInt(0, GetMapCount()-1);
  785. }
  786. bShowed[Rand] = true;
  787. AddMenuItem(menu, MapNames[Rand], MapNames[Rand]);
  788. }
  789. SetMenuExitButton(menu, false);
  790. VoteMenuToAll(menu, 15);
  791. }
  792.  
  793. BHopOn()
  794. {
  795. PrintToChatAll("[PUG] Bunnyhopping will be enabled.");
  796. BunnyHopMode = true;
  797. StartMapVote();
  798. }
  799.  
  800. BHopOff()
  801. {
  802. PrintToChatAll("[PUG] Bunnyhopping will be disabled.");
  803. BunnyHopMode = false;
  804. StartMapVote();
  805. }
  806.  
  807. public Handle_BHopVote(Handle:menu, MenuAction:action, param1, param2)
  808. {
  809. if (action == MenuAction_End)
  810. {
  811. CloseHandle(menu);
  812. } else if (action == MenuAction_VoteEnd) {
  813. // 0 = Off
  814. // 1 = On
  815. if(param1 == 0)
  816. {
  817. BHopOff();
  818. }
  819. else
  820. {
  821. BHopOn();
  822. }
  823. }
  824. else if(action==MenuAction_VoteCancel)
  825. {
  826. BHopOff();
  827. }
  828. }
  829.  
  830. BHopVote()
  831. {
  832. if(IsVoteInProgress())
  833. {
  834. CancelVote();
  835. }
  836.  
  837. new Handle:menu = CreateMenu(Handle_BHopVote);
  838. SetMenuTitle(menu, "Vote for bunny hopping");
  839. AddMenuItem(menu, "off", "Off");
  840. AddMenuItem(menu, "on", "On");
  841. SetMenuExitButton(menu, false);
  842. VoteMenuToAll(menu, 15);
  843. }
  844.  
  845. TeamsRandom()
  846. {
  847. CaptainMode = false;
  848. BHopVote();
  849. }
  850.  
  851. /*public Handle_TeamVote(Handle:menu, MenuAction:action, param1, param2)
  852. {
  853. if (action == MenuAction_End)
  854. {
  855. CloseHandle(menu);
  856. } else if (action == MenuAction_VoteEnd) {
  857. // 0 = Random
  858. // 1 = Captains
  859. if(param1 == 0)
  860. {
  861. TeamsRandom();
  862. }
  863. else
  864. {
  865. TeamsCaptains();
  866. }
  867. }
  868. }*/
  869.  
  870. TeamVote()
  871. {
  872. // For now random teams.
  873. TeamsRandom();
  874. /*// Choose a team set.
  875. if (IsVoteInProgress())
  876. {
  877. CancelVote();
  878. }
  879.  
  880. new Handle:menu = CreateMenu(Handle_TeamVote);
  881. SetMenuTitle(menu, "Vote for team sorting");
  882. AddMenuItem(menu, "rand", "Random");
  883. AddMenuItem(menu, "capt", "Captains");
  884. SetMenuExitButton(menu, false);
  885. VoteMenuToAll(menu, 15);*/
  886. }
  887.  
  888. RulesCGS()
  889. {
  890. PrintToChatAll("[PUG] Ruleset will be: CGS");
  891. Ruleset = Rules_CGS;
  892. TeamVote();
  893. }
  894.  
  895. public Handle_RulesVote(Handle:menu, MenuAction:action, param1, param2)
  896. {
  897. if (action == MenuAction_End)
  898. {
  899. CloseHandle(menu);
  900. } else if (action == MenuAction_VoteEnd) {
  901. // 0 = CSL
  902. // 1 = Pug
  903. if(param1 == 0)
  904. {
  905. RulesCSL();
  906. }
  907. else
  908. {
  909. RulesCGS();
  910. }
  911. }
  912. else if(action==MenuAction_VoteCancel)
  913. {
  914. RulesCSL();
  915. }
  916. }
  917.  
  918. StartRulesVote()
  919. {
  920. // Choose a rule set.
  921. if (IsVoteInProgress())
  922. {
  923. CancelVote();
  924. }
  925.  
  926. new Handle:menu = CreateMenu(Handle_RulesVote);
  927. SetMenuTitle(menu, "Vote for rule set");
  928. AddMenuItem(menu, "csl", "CSL (15 Round Halves, $800)");
  929. AddMenuItem(menu, "cgs", "CGS (9 Round Halves, $8000)");
  930. SetMenuExitButton(menu, false);
  931. VoteMenuToAll(menu, 15);
  932. }
  933.  
  934. ChangeMatchState(MatchState:newState)
  935. {
  936. gMatchState = newState;
  937.  
  938. if(ReadyUpState())
  939. {
  940. EnterReadyUpState();
  941. }
  942. }
  943.  
  944. StartMatchSetup()
  945. {
  946. // Vote for rule set.
  947. PrintToChatAll("[PUG] Starting match setup and votes.");
  948. ChangeMatchState(MS_Setup);
  949. StartRulesVote();
  950. }
  951.  
  952. public Action:SayTeamHook(client,args)
  953. {
  954. return SayHook(client, args, true);
  955. }
  956.  
  957. public Action:SayPubHook(client,args)
  958. {
  959. return SayHook(client, args, false);
  960. }
  961.  
  962. ReadyUp(client) {
  963. new String:plName[32];
  964. GetClientName(client, plName, 32);
  965. bReady[client] = true;
  966. readyUpTime[client] = GetTime();
  967. PrintToChatAll("[PUG] %s is now ready.", plName);
  968. // If this is the last ready up.
  969. new bool:bStillMore = false;
  970. new PlCount = 0;
  971. for(new a=1;a<=MAXPLAYERS;a++)
  972. {
  973. if(ValidClient(a) && !IsSourceTV(a))
  974. {
  975. PlCount++;
  976. if(!bReady[a])
  977. {
  978. bStillMore = true;
  979. }
  980. }
  981. }
  982. if(!bStillMore)
  983. {
  984. if(PlCount == GetConVarInt(hMaxPlayers))
  985. {
  986. OnAllReady();
  987. }
  988. }
  989. }
  990.  
  991. public Action:SayHook(client,args,bool:team)
  992. {
  993. if(!client)
  994. return Plugin_Continue; // Don't block the server ever.
  995.  
  996. decl String:ChatText[256];
  997. GetCmdArgString(ChatText,256);
  998. StripQuotes(ChatText);
  999. new String:Words[100][256];
  1000. new WordCount = ExplodeString(ChatText, " ", Words, 100, 256);
  1001. new bool:bHookMessage = false;
  1002. new bool:bCommand = true;
  1003.  
  1004. if(StrEqual(Words[0],"/ready", false))
  1005. {
  1006. if(!ReadyUpState())
  1007. {
  1008. PrintToChat(client, "[PUG] You don't need to ready up right now.");
  1009. bHookMessage = true;
  1010. }
  1011. else
  1012. {
  1013. if(bReady[client])
  1014. {
  1015. PrintToChat(client,"[PUG] You are already ready.");
  1016. bHookMessage = true;
  1017. }
  1018. else
  1019. {
  1020. ReadyUp(client);
  1021. }
  1022. }
  1023. }
  1024. else if(StrEqual(Words[0], "/mute", false))
  1025. {
  1026. bHookMessage = true;
  1027. new String:fullSecond[256];
  1028. Format(fullSecond, 256, "%s", Words[1]);
  1029. for(new x=2;x<WordCount;x++)
  1030. {
  1031. Format(fullSecond, 256, "%s %s", fullSecond, Words[x]);
  1032. }
  1033. if(StrEqual(fullSecond,""))
  1034. {
  1035. PrintToChat(client, "[PUG] Syntax: /mute <part of name>");
  1036. }
  1037. else
  1038. {
  1039. new cl = PartialNameClient(fullSecond);
  1040. if(cl==-1)
  1041. {
  1042. PrintToChat(client, "[PUG] Be more specific, multiple matches.");
  1043. }
  1044. else if(cl==0)
  1045. {
  1046. PrintToChat(client, "[PUG] No matches for \"%s\".", fullSecond);
  1047. }
  1048. else
  1049. {
  1050. if(client==cl)
  1051. {
  1052. PrintToChat(client, "[PUG] You can't mute yourself.");
  1053. }
  1054. else if(IsPlayerMuted(client, cl))
  1055. {
  1056. PrintToChat(client, "[PUG] Player already muted.");
  1057. }
  1058. else
  1059. {
  1060. PrintToChat(client, "[PUG] Player muted.");
  1061. bMuted[client][cl] = true;
  1062. }
  1063. }
  1064. }
  1065. }
  1066. else if(StrEqual(Words[0], "/unmute", false))
  1067. {
  1068. bHookMessage = true;
  1069. new String:fullSecond[256];
  1070. Format(fullSecond, 256, "%s", Words[1]);
  1071. for(new x=2;x<WordCount;x++)
  1072. {
  1073. Format(fullSecond, 256, "%s %s", fullSecond, Words[x]);
  1074. }
  1075. if(StrEqual(fullSecond,""))
  1076. {
  1077. PrintToChat(client, "[PUG] Syntax: /unmute <part of name>");
  1078. }
  1079. else
  1080. {
  1081. new cl = PartialNameClient(fullSecond);
  1082. if(cl==-1)
  1083. {
  1084. PrintToChat(client, "[PUG] Be more specific, multiple matches.");
  1085. }
  1086. else if(cl==0)
  1087. {
  1088. PrintToChat(client, "[PUG] No matches for \"%s\".", fullSecond);
  1089. }
  1090. else
  1091. {
  1092. if(client==cl)
  1093. {
  1094. PrintToChat(client, "[PUG] You can't mute yourself.");
  1095. }
  1096. else if(!IsPlayerMuted(client, cl))
  1097. {
  1098. PrintToChat(client, "[PUG] Player isn't muted.");
  1099. }
  1100. else
  1101. {
  1102. PrintToChat(client, "[PUG] Player unmuted.");
  1103. bMuted[client][cl] = false;
  1104. }
  1105. }
  1106. }
  1107. }
  1108. else if(StrEqual(Words[0], "/chat", false))
  1109. {
  1110. bHookMessage = true;
  1111. if(IsPubChatMuted(client))
  1112. {
  1113. bPubChatMuted[client] = false;
  1114. PrintToChat(client, "[PUG] Public chat unmuted");
  1115. }
  1116. else
  1117. {
  1118. bPubChatMuted[client] = true;
  1119. PrintToChat(client, "[PUG] Public chat muted.");
  1120. }
  1121. }
  1122. else if(StrEqual(Words[0], "/teamchat", false))
  1123. {
  1124. bHookMessage = true;
  1125. if(IsTeamChatMuted(client))
  1126. {
  1127. bTeamChatMuted[client] = false;
  1128. PrintToChat(client, "[PUG] Team chat unmuted.");
  1129. }
  1130. else
  1131. {
  1132. bTeamChatMuted[client] = true;
  1133. PrintToChat(client, "[PUG] Team chat muted.");
  1134. }
  1135. }
  1136. else if(StrEqual(Words[0], "/unready", false))
  1137. {
  1138. if(!bReady[client])
  1139. {
  1140. PrintToChat(client, "[PUG] You already are unready.");
  1141. bHookMessage = true;
  1142. }
  1143. else
  1144. {
  1145. new curTime = GetTime();
  1146. if(readyUpTime[client] + 3 > curTime)
  1147. {
  1148. PrintToChat(client, "[PUG] You must wait 3 seconds between ready commands.");
  1149. bHookMessage = true;
  1150. }
  1151. else
  1152. {
  1153. bReady[client] = false;
  1154. new String:plName[32];
  1155. GetClientName(client, plName, 32);
  1156. PrintToChatAll("[PUG] %s is no longer ready.", plName);
  1157. notReadyTime[client] = GetTime();
  1158. }
  1159. }
  1160. }
  1161. else if(StrEqual(Words[0], "/autodmg",false))
  1162. {
  1163. if(AutoDmg[client])
  1164. {
  1165. AutoDmg[client] = false;
  1166. PrintToChat(client, "[PUG] Auto /dmg has been toggled off.");
  1167. }
  1168. else
  1169. {
  1170. AutoDmg[client] = true;
  1171. PrintToChat(client, "[PUG] Auto /dmg has been toggled on.");
  1172. }
  1173. }
  1174. else if(StrEqual(Words[0], "/dmg", false))
  1175. {
  1176. if(!MatchLive())
  1177. {
  1178. PrintToChat(client, "[PUG] You can't use this now.");
  1179. bHookMessage = true;
  1180. }
  1181. else
  1182. {
  1183. if(IsPlayerAlive(client))
  1184. {
  1185. PrintToChat(client, "[PUG] You must be dead to use this.");
  1186. bHookMessage = true;
  1187. }
  1188. else
  1189. {
  1190. PrintDmgReport(client);
  1191. }
  1192. }
  1193. }
  1194. else if(StrEqual(Words[0], "/help", false))
  1195. {
  1196. PrintToChat(client, "[PUG] Commands: /ready, /help, /dmg, /autodmg");
  1197. bHookMessage = true;
  1198. }
  1199. else
  1200. {
  1201. bCommand = false;
  1202. }
  1203. new bool:bCanChat = (fLastMessage[client] + 0.5 <= GetEngineTime());
  1204. if(!bCommand && !bHookMessage && team && IsTeamChatMuted(client))
  1205. {
  1206. PrintToChat(client, "[PUG] You can't team chat until you re-enable it with /teamchat.");
  1207. return Plugin_Handled;
  1208. }
  1209. if(!bCommand && !bHookMessage && !team && IsPubChatMuted(client))
  1210. {
  1211. PrintToChat(client, "[PUG] You can't public chat until you re-enable it with /chat.");
  1212. return Plugin_Handled;
  1213. }
  1214. if(!bHookMessage && bCanChat)
  1215. {
  1216. fLastMessage[client] = GetEngineTime();
  1217. ChatMsg(client, team, ChatText);
  1218. }
  1219. return Plugin_Handled;
  1220. }
  1221.  
  1222. public Action:RespawnCheck(Handle:timer, any:userid)
  1223. {
  1224. new client = GetClientOfUserId(userid);
  1225. if(ReadyUpState() && ValidClient(client) && !IsSourceTV(client) && !IsPlayerAlive(client))
  1226. {
  1227. CS_RespawnPlayer(client);
  1228. }
  1229. }
  1230.  
  1231. LogKillLocalStats(const String:steamAttacker[], const String:steamVictim[], const String:weapon[], bool:headshot)
  1232. {
  1233. if(!MatchLive())
  1234. {
  1235. return;
  1236. }
  1237. if(CurrentRound<1)
  1238. {
  1239. return;
  1240. }
  1241. // Create a new array.
  1242. new Handle:newArray = CreateArray(24);
  1243. PushArrayString(newArray, steamAttacker);
  1244. PushArrayString(newArray, steamVictim);
  1245. PushArrayString(newArray, weapon);
  1246. PushArrayCell(newArray, headshot);
  1247. }
  1248.  
  1249. LogKill(attacker, victim, const String:weapon[], bool:headshot)
  1250. {
  1251. if(MatchLive())
  1252. {
  1253. new String:steamAttacker[24];
  1254. new String:steamVictim[24];
  1255. GetClientAuthString(attacker, steamAttacker, 24);
  1256. GetClientAuthString(victim, steamVictim, 24);
  1257. LogKillLocalStats(steamAttacker, steamVictim, weapon, headshot);
  1258. }
  1259. }
  1260.  
  1261. public Action:DeathCallback(Handle:event, const String:name[], bool:dontBroadcast)
  1262. {
  1263. new userid = GetEventInt(event, "userid");
  1264. CreateTimer(2.0, RespawnCheck, userid);
  1265. new client = GetClientOfUserId(userid);
  1266. new attacker_userid = GetEventInt(event, "attacker");
  1267. new attacker = GetClientOfUserId(attacker_userid);
  1268. new String:weapon[64];
  1269. GetEventString(event, "weapon", weapon, 64);
  1270. new bool:Headshot = (GetEventInt(event, "headshot")==0)?false:true;
  1271. if(ValidClient(client))
  1272. {
  1273. if(attacker==client || attacker==0)
  1274. {
  1275. LogKill(client, client, weapon, false);
  1276. }
  1277. else if(ValidClient(attacker))
  1278. {
  1279. LogKill(attacker, client, weapon, Headshot);
  1280. }
  1281. }
  1282.  
  1283. if(MatchLive() && AutoDmg[client])
  1284. {
  1285. PrintDmgReport(client);
  1286. }
  1287.  
  1288. return Plugin_Continue;
  1289. }
  1290.  
  1291. public Action:RoundStartCallback(Handle:event, const String:name[], bool:dontBroadcast)
  1292. {
  1293. if(RoundCounterOn == true)
  1294. {
  1295. CurrentRound++;
  1296. // Create an array here.
  1297. hMatchDamage[CurrentRound] = CreateArray();
  1298. hMatchKills[CurrentRound] = CreateArray();
  1299. // Who is winning?
  1300. if(TeamAScore>TeamBScore)
  1301. {
  1302. // Is team A ct or t?
  1303. if(CSTeamToCSL(CS_TEAM_CT) == TEAM_A)
  1304. {
  1305. // They are CT's.
  1306. PrintToChatAll("[PUG] Round %d. CT's winning %d - %d", CurrentRound, TeamAScore, TeamBScore);
  1307. }
  1308. else
  1309. {
  1310. PrintToChatAll("[PUG] Round %d. T's winning %d - %d", CurrentRound, TeamAScore, TeamBScore);
  1311. }
  1312. }
  1313. else if(TeamBScore>TeamAScore)
  1314. {
  1315. if(CSTeamToCSL(CS_TEAM_CT) == TEAM_B)
  1316. {
  1317. // They are CT's.
  1318. PrintToChatAll("[PUG] Round %d. CT's winning %d - %d", CurrentRound, TeamBScore, TeamAScore);
  1319. }
  1320. else
  1321. {
  1322. PrintToChatAll("[PUG] Round %d. T's winning %d - %d", CurrentRound, TeamBScore, TeamAScore);
  1323. }
  1324. }
  1325. else
  1326. {
  1327. PrintToChatAll("[PUG] Round %d. Tie game, %d - %d", CurrentRound, TeamAScore, TeamBScore);
  1328. }
  1329. }
  1330. return Plugin_Continue;
  1331. }
  1332.  
  1333. public Action:RoundEndCallback(Handle:event, const String:name[], bool:dontBroadcast)
  1334. {
  1335. //new reason = GetEventInt(event, "reason");
  1336. new winner = GetEventInt(event, "winner");
  1337. if(RoundCounterOn == true)
  1338. {
  1339. if(winner==CS_TEAM_T)
  1340. {
  1341. new CSLT = CSTeamToCSL(CS_TEAM_T);
  1342. if(CSLT == TEAM_A)
  1343. {
  1344. TeamAScore++;
  1345. }
  1346. else
  1347. {
  1348. TeamBScore++;
  1349. }
  1350. }
  1351. else if(winner==CS_TEAM_CT)
  1352. {
  1353. new CSLCT = CSTeamToCSL(CS_TEAM_CT);
  1354. if(CSLCT == TEAM_A)
  1355. {
  1356. TeamAScore++;
  1357. }
  1358. else
  1359. {
  1360. TeamBScore++;
  1361. }
  1362. }
  1363.  
  1364. // Is this CSL or CGS rules?
  1365. // Check score first, if there is a winner call WinLegit or whatever.
  1366. // Are we in overtime?
  1367. // Check for a winner, then check for transitioning stuff. If there is a winner, no need to go to Half, etc...
  1368. if(gMatchState >= MS_Before_Overtime_First_Half && gMatchState!=MS_Post_Match)
  1369. {
  1370. // If CSL, overtime start score is 15-15
  1371. // Otherwise, 9 - 9
  1372. if(Ruleset==Rules_PUG)
  1373. {
  1374. if(TeamAScore >= 21)
  1375. {
  1376. MatchWinOT(TEAM_A);
  1377. return Plugin_Continue;
  1378. }
  1379. else if(TeamBScore >= 21)
  1380. {
  1381. MatchWinOT(TEAM_B);
  1382. return Plugin_Continue;
  1383. }
  1384. else if(TeamAScore == 20 && TeamBScore == 20)
  1385. {
  1386. // Tie.
  1387. MatchTieOT();
  1388. return Plugin_Continue;
  1389. }
  1390. }
  1391. else if(Ruleset==Rules_CGS)
  1392. {
  1393. if(TeamAScore >= 13)
  1394. {
  1395. MatchWinOT(TEAM_A);
  1396. return Plugin_Continue;
  1397. }
  1398. else if(TeamBScore >= 13)
  1399. {
  1400. MatchWinOT(TEAM_B);
  1401. return Plugin_Continue;
  1402. }
  1403. else if(TeamAScore == 12 && TeamBScore == 12)
  1404. {
  1405. // Tie.
  1406. MatchTieOT();
  1407. return Plugin_Continue;
  1408. }
  1409. }
  1410. }
  1411. else
  1412. {
  1413. if(Ruleset==Rules_PUG)
  1414. {
  1415. // Check of score >=16.
  1416. if(TeamAScore>=16)
  1417. {
  1418. MatchWin(TEAM_A);
  1419. }
  1420. else if(TeamBScore>=16)
  1421. {
  1422. MatchWin(TEAM_B);
  1423. }
  1424. }
  1425. else if(Ruleset==Rules_CGS)
  1426. {
  1427. // Check of score >=10.
  1428. if(TeamAScore>=10)
  1429. {
  1430. MatchWin(TEAM_A);
  1431. }
  1432. else if(TeamBScore>=10)
  1433. {
  1434. MatchWin(TEAM_B);
  1435. }
  1436. }
  1437. }
  1438.  
  1439. // Now do our checks for transitions.
  1440. if(Ruleset==Rules_PUG)
  1441. {
  1442. if(CurrentRound==15)
  1443. {
  1444. // Go to second half.
  1445. TransSecondHalfWarmup();
  1446. return Plugin_Continue;
  1447. }
  1448. else if(CurrentRound==30)
  1449. {
  1450. // Previous checks allow for no use of ==15, ==15
  1451. TransOTFirstHalfWarmup();
  1452. return Plugin_Continue;
  1453. }
  1454. else if(CurrentRound==35)
  1455. {
  1456. TransOTSecondHalfWarmup();
  1457. return Plugin_Continue;
  1458. }
  1459. }
  1460. else if(Ruleset==Rules_CGS)
  1461. {
  1462. if(CurrentRound==9)
  1463. {
  1464. // Go to second half.
  1465. TransSecondHalfWarmup();
  1466. return Plugin_Continue;
  1467. }
  1468. else if(CurrentRound==18)
  1469. {
  1470. // Previous checks allow for no use of ==15, ==15
  1471. TransOTFirstHalfWarmup();
  1472. return Plugin_Continue;
  1473. }
  1474. else if(CurrentRound==21)
  1475. {
  1476. TransOTSecondHalfWarmup();
  1477. return Plugin_Continue;
  1478. }
  1479. }
  1480. }
  1481. return Plugin_Continue;
  1482. }
  1483.  
  1484. MoveAfterTrans()
  1485. {
  1486. for(new x=1;x<=MAXPLAYERS;x++)
  1487. {
  1488. if(ValidClient(x) && !IsSourceTV(x))
  1489. {
  1490. new cslTeam = CSLTeam(x);
  1491. if(cslTeam!=TEAM_A && cslTeam!=TEAM_B)
  1492. {
  1493. continue; // Should we kick him? Probably not. This shouldn't happen.
  1494. }
  1495. else
  1496. {
  1497. new csTeam = CSLToCSTeam(cslTeam);
  1498. new curTeam = GetClientTeam(x);
  1499. if(curTeam!=csTeam)
  1500. {
  1501. CS_SwitchTeam(x, csTeam);
  1502. }
  1503. }
  1504. }
  1505. }
  1506. }
  1507.  
  1508. TransSecondHalfWarmup()
  1509. {
  1510. // All stop the round counter.
  1511. RoundCounterOn = false;
  1512. // Change state.
  1513. ChangeMatchState(MS_Before_Second_Half);
  1514. // Move them.
  1515. MoveAfterTrans();
  1516. }
  1517.  
  1518. TransOTFirstHalfWarmup()
  1519. {
  1520. RoundCounterOn = false;
  1521. ChangeMatchState(MS_Before_Overtime_First_Half);
  1522. MoveAfterTrans();
  1523. }
  1524.  
  1525. TransOTSecondHalfWarmup()
  1526. {
  1527. RoundCounterOn = false;
  1528. ChangeMatchState(MS_Before_Overtime_Second_Half);
  1529. MoveAfterTrans();
  1530. }
  1531.  
  1532. public Action:ReduceToOneHundred(Handle:timer, any:userid)
  1533. {
  1534. new client = GetClientOfUserId(userid);
  1535. if(ValidClient(client) && ReadyUpState() && IsPlayerAlive(client))
  1536. {
  1537. if(GetClientHealth(client)>100)
  1538. {
  1539. SetEntityHealth(client, 100);
  1540. }
  1541. }
  1542. }
  1543.  
  1544. public Action:SpawnCallback(Handle:event, const String:name[], bool:dontBroadcast)
  1545. {
  1546. new userid = GetEventInt(event, "userid");
  1547. new client = GetClientOfUserId(userid);
  1548. if(!ValidClient(client) || IsSourceTV(client))
  1549. {
  1550. return Plugin_Continue;
  1551. }
  1552. if(ReadyUpState())
  1553. {
  1554. if(FirstSpawn[client])
  1555. {
  1556. FirstSpawn[client] = false;
  1557. PrintToChat(client, "[PUG] Welcome! Please /ready up and type /help if you need help.");
  1558. }
  1559. else if(!bReady[client])
  1560. {
  1561. PrintToChat(client, "[PUG] Type /ready in chat when you are ready.");
  1562. }
  1563. if(GetMoney(client)!=16000)
  1564. {
  1565. SetMoney(client, 16000);
  1566. }
  1567.  
  1568. if(!bReady[client] && IsFakeClient(client)) {
  1569. ReadyUp(client);
  1570. }
  1571.  
  1572. // Spawn protection.
  1573. SetEntityHealth(client, 500);
  1574. CreateTimer(2.0, ReduceToOneHundred, userid);
  1575. }
  1576. else
  1577. {
  1578. if(FirstSpawn[client])
  1579. {
  1580. PrintToChat(client, "[PUG] Welcome! Match is LIVE, type /help for help.");
  1581. FirstSpawn[client] = false;
  1582. }
  1583. }
  1584. return Plugin_Continue;
  1585. }
  1586.  
  1587. PrintDmgReport(client)
  1588. {
  1589. // Get current round.
  1590. new OurTeam = GetClientTeam(client);
  1591. for(new x=1;x<=MAXPLAYERS;x++)
  1592. {
  1593. if(ValidClient(x) && !IsSourceTV(x) && GetClientTeam(x)!=OurTeam)
  1594. {
  1595. new Handle:dmgRound = hMatchDamage[CurrentRound];
  1596. new dmgSize = GetArraySize(dmgRound);
  1597. new dmgTo = 0;
  1598. new dmgHits = 0;
  1599. new String:clName[24];
  1600. GetClientName(x, clName, 24);
  1601. for(new y=0;y<dmgSize;y++)
  1602. {
  1603. new String:Att[24];
  1604. new String:Vic[24];
  1605. new Handle:singleDmg = GetArrayCell(dmgRound, y);
  1606. GetArrayString(singleDmg, 0, Att, 24);
  1607. GetArrayString(singleDmg, 1, Vic, 24);
  1608. new dM = GetArrayCell(singleDmg, 2);
  1609. new IndAtt = ClientOfSteamId(Att);
  1610. new IndVic = ClientOfSteamId(Vic);
  1611. if(ValidClient(IndAtt) && ValidClient(IndVic) && IndAtt==client && IndVic==x)
  1612. {
  1613. dmgTo+=dM;
  1614. dmgHits++;
  1615. }
  1616. }
  1617. PrintToChat(client, "[PUG] %s - Damage Given: %d (%d hits)", clName, dmgTo, dmgHits);
  1618. }
  1619. }
  1620.  
  1621. }
  1622.  
  1623. LogDmg(Attacker, Victim, Dmg)
  1624. {
  1625. if(!MatchLive())
  1626. {
  1627. return;
  1628. }
  1629. if(CurrentRound<1)
  1630. {
  1631. return;
  1632. }
  1633. new String:AttackerSteam[24];
  1634. new String:VictimSteam[24];
  1635. GetClientAuthString(Attacker, AttackerSteam, 24);
  1636. GetClientAuthString(Victim, VictimSteam, 24);
  1637. // Create a new array.
  1638. new Handle:newArray = CreateArray(24);
  1639. PushArrayString(newArray, AttackerSteam);
  1640. PushArrayString(newArray, VictimSteam);
  1641. PushArrayCell(newArray, Dmg);
  1642. PushArrayCell(hMatchDamage[CurrentRound], newArray);
  1643. }
  1644.  
  1645. public Action:HurtCallback(Handle:event, const String:name[], bool:dontBroadcast)
  1646. {
  1647. // userid, attacker, dmg_health
  1648. new VictimUserid = GetEventInt(event, "userid");
  1649. new AttackerUserid = GetEventInt(event, "attacker");
  1650. new VictimIndex = GetClientOfUserId(VictimUserid);
  1651. new AttackerIndex = GetClientOfUserId(AttackerUserid);
  1652. new Dmg = GetEventInt(event, "dmg_health");
  1653. if(VictimIndex>0 && AttackerIndex>0 && ValidClient(VictimIndex) && ValidClient(AttackerIndex) && AttackerIndex!=VictimIndex)
  1654. {
  1655. LogDmg(AttackerIndex, VictimIndex, Dmg);
  1656. }
  1657. return Plugin_Continue;
  1658. }
  1659.  
  1660. SetMoney(client, money)
  1661. {
  1662. if(ValidClient(client) && !IsSourceTV(client))
  1663. {
  1664. SetEntData(client, OffsetAccount, money);
  1665. }
  1666. }
  1667.  
  1668. GetMoney(client)
  1669. {
  1670. if(ValidClient(client) && !IsSourceTV(client))
  1671. {
  1672. return GetEntData(client, OffsetAccount);
  1673. }
  1674. return 0;
  1675. }
  1676.  
  1677. #define CS_TEAM_T 2
  1678. #define CS_TEAM_CT 3
  1679. #define CS_TEAM_SPEC 1
  1680. #define CS_TEAM_AUTO 0
  1681.  
  1682. public Action:HookSpectate(client, const String:command[], argc)
  1683. {
  1684. PrintCenterText(client, "CSL: You can't join spectator.");
  1685. return Plugin_Handled;
  1686. }
  1687.  
  1688. OurAutojoin(client)
  1689. {
  1690. // Which team are we supposed to be on?
  1691. // Have the teams been setup yet?
  1692. if(TeamsSetup())
  1693. {
  1694. new MyTeam = CSLTeam(client);
  1695. if(MyTeam!=-1)
  1696. {
  1697. // Join the team we are on.
  1698. if(GetClientTeam(client)!=CSLToCSTeam(MyTeam))
  1699. {
  1700. CS_SwitchTeam(client, CSLToCSTeam(MyTeam));
  1701. }
  1702. }
  1703. else
  1704. {
  1705. // Find a team for us.
  1706. // What team has less active players?
  1707. new String:steamID[24];
  1708. GetClientAuthString(client, steamID, 24);
  1709. new APTeamA = TeamSizeActive(TEAM_A);
  1710. new APTeamB = TeamSizeActive(TEAM_B);
  1711. if(APTeamA<APTeamB)
  1712. {
  1713. // Team A
  1714. AddSteamToTeam(steamID, TEAM_A);
  1715. }
  1716. else if(APTeamB<APTeamA)
  1717. {
  1718. // Team B
  1719. AddSteamToTeam(steamID, TEAM_B);
  1720. }
  1721. else
  1722. {
  1723. // Random
  1724. new RandTeam = GetRandomInt(TEAM_A, TEAM_B);
  1725. AddSteamToTeam(steamID, RandTeam);
  1726. }
  1727. MyTeam = CSLTeam(client);
  1728. if(MyTeam!=-1)
  1729. {
  1730. // Join the team we are on.
  1731. if(GetClientTeam(client)!=CSLToCSTeam(MyTeam))
  1732. {
  1733. CS_SwitchTeam(client, CSLToCSTeam(MyTeam));
  1734. }
  1735. }
  1736. }
  1737. }
  1738. }
  1739.  
  1740. TryGoT(client)
  1741. {
  1742. if(TeamsSetup())
  1743. {
  1744. new MyTeam = CSLTeam(client);
  1745. if(MyTeam!=-1)
  1746. {
  1747. // Join the team we are on.
  1748. if(CSLToCSTeam(MyTeam)!=CS_TEAM_T)
  1749. {
  1750. PrintCenterText(client, "[PUG] You are on Team %s, they are currently Counter-Terrorist.", ((MyTeam==TEAM_A)?"A":"B"));
  1751. }
  1752. if(GetClientTeam(client)!=CSLToCSTeam(MyTeam))
  1753. {
  1754. CS_SwitchTeam(client, CSLToCSTeam(MyTeam));
  1755. }
  1756. }
  1757. else
  1758. {
  1759. // They clearly want to be a Terrorist, which team is T?
  1760. new TCSL = CSTeamToCSL(CS_TEAM_T);
  1761. new CTCSL = CSTeamToCSL(CS_TEAM_CT);
  1762. new ATCount = TeamSizeActive(TCSL);
  1763. new ACTCount = TeamSizeActive(CTCSL);
  1764. new String:steamID[24];
  1765. GetClientAuthString(client, steamID, 24);
  1766. if(ATCount <= ACTCount)
  1767. {
  1768. // Let them, and add them to the team.
  1769. AddSteamToTeam(steamID, TCSL);
  1770. if(GetClientTeam(client)!=CS_TEAM_T)
  1771. {
  1772. CS_SwitchTeam(client, CS_TEAM_T);
  1773. }
  1774. }
  1775. else
  1776. {
  1777. // They gotta go CT, add em and tell em the bad news :(
  1778. PrintCenterText(client, "CSL: Sorry, you have been forced to Team %s, the Counter-Terrorists.", ((CTCSL==TEAM_A)?"A":"B"));
  1779. AddSteamToTeam(steamID, CTCSL);
  1780. if(GetClientTeam(client)!=CS_TEAM_CT)
  1781. {
  1782. CS_SwitchTeam(client, CS_TEAM_CT);
  1783. }
  1784. }
  1785. }
  1786. }
  1787. }
  1788.  
  1789. CSLToCSTeam(cslTeam)
  1790. {
  1791. /*
  1792. MS_Before_First_Half, // This is only used if the map changes.
  1793. MS_Live_First_Half,
  1794. MS_Before_Second_Half, // Always used. Team A is CT B is T
  1795. MS_Live_Second_Half, // Team A is CT team B is T
  1796. MS_Before_Overtime_First_Half, // Team A is T, Team B is CT
  1797. MS_Live_Overtime_First_Half, // Team A is T, Team B is CT
  1798. MS_Before_Overtime_Second_Half, // Team A is CT, Team B is T
  1799. MS_Live_Overtime_Second_Half, // Team A is CT, Team B is T
  1800. */
  1801. // This might need an edit when captains come along?
  1802. if(gMatchState==MS_Live_First_Half)
  1803. {
  1804. if(cslTeam==TEAM_A)
  1805. {
  1806. return CS_TEAM_T;
  1807. }
  1808. else
  1809. {
  1810. return CS_TEAM_CT;
  1811. }
  1812. }
  1813. else if(gMatchState==MS_Before_Second_Half || gMatchState==MS_Live_Second_Half)
  1814. {
  1815. if(cslTeam==TEAM_A)
  1816. {
  1817. return CS_TEAM_CT;
  1818. }
  1819. else
  1820. {
  1821. return CS_TEAM_T;
  1822. }
  1823. }
  1824. else if(gMatchState==MS_Before_Overtime_First_Half || gMatchState==MS_Live_Overtime_First_Half)
  1825. {
  1826. if(cslTeam==TEAM_A)
  1827. {
  1828. return CS_TEAM_T;
  1829. }
  1830. else
  1831. {
  1832. return CS_TEAM_CT;
  1833. }
  1834. }
  1835. else if(gMatchState==MS_Before_Overtime_Second_Half || gMatchState==MS_Live_Overtime_Second_Half)
  1836. {
  1837. if(cslTeam==TEAM_A)
  1838. {
  1839. return CS_TEAM_CT;
  1840. }
  1841. else
  1842. {
  1843. return CS_TEAM_T;
  1844. }
  1845. }
  1846. else
  1847. {
  1848. return -1;
  1849. }
  1850. }
  1851.  
  1852. CSTeamToCSL(csTeam)
  1853. {
  1854. if(CSLToCSTeam(TEAM_A) == csTeam)
  1855. {
  1856. return TEAM_A;
  1857. }
  1858. else
  1859. {
  1860. return TEAM_B;
  1861. }
  1862. }
  1863.  
  1864. TryGoCT(client)
  1865. {
  1866. if(TeamsSetup())
  1867. {
  1868. new MyTeam = CSLTeam(client);
  1869. if(MyTeam!=-1)
  1870. {
  1871. // Join the team we are on.
  1872. if(CSLToCSTeam(MyTeam)!=CS_TEAM_CT)
  1873. {
  1874. PrintCenterText(client, "[PUG] You are on Team %s, they are currently Terrorist.", ((MyTeam==TEAM_A)?"A":"B"));
  1875. }
  1876. if(GetClientTeam(client)!=CSLToCSTeam(MyTeam))
  1877. {
  1878. CS_SwitchTeam(client, CSLToCSTeam(MyTeam));
  1879. }
  1880. }
  1881. else
  1882. {
  1883. // They clearly want to be a Counter-Terrorist, which team is CT?
  1884. new TCSL = CSTeamToCSL(CS_TEAM_T);
  1885. new CTCSL = CSTeamToCSL(CS_TEAM_CT);
  1886. new ATCount = TeamSizeActive(TCSL);
  1887. new ACTCount = TeamSizeActive(CTCSL);
  1888. new String:steamID[24];
  1889. GetClientAuthString(client, steamID, 24);
  1890. if(ACTCount <= ATCount)
  1891. {
  1892. // Let them, and add them to the team.
  1893. AddSteamToTeam(steamID, CTCSL);
  1894. if(GetClientTeam(client)!=CS_TEAM_CT)
  1895. {
  1896. CS_SwitchTeam(client, CS_TEAM_CT);
  1897. }
  1898. }
  1899. else
  1900. {
  1901. // They gotta go CT, add em and tell em the bad news :(
  1902. PrintCenterText(client, "CSL: Sorry, you have been forced to Team %s, the Terrorists.", ((TCSL==TEAM_A)?"A":"B"));
  1903. AddSteamToTeam(steamID, TCSL);
  1904. if(GetClientTeam(client)!=CS_TEAM_T)
  1905. {
  1906. CS_SwitchTeam(client, CS_TEAM_T);
  1907. }
  1908. }
  1909. }
  1910. }
  1911. }
  1912.  
  1913. public Action:HookJoinTeam(client, const String:command[], argc)
  1914. {
  1915. // Destined team
  1916. new String:firstParam[16];
  1917. GetCmdArg(1, firstParam, 16);
  1918. StripQuotes(firstParam);
  1919. new firstParamNumber = StringToInt(firstParam);
  1920. if(!ValidClient(client) || IsFakeClient(client) || IsSourceTV(client))
  1921. {
  1922. return Plugin_Continue;
  1923. }
  1924.  
  1925. if(firstParamNumber == CS_TEAM_SPEC)
  1926. {
  1927. // No.
  1928. PrintCenterText(client, "CSL: You can't join spectator.");
  1929. return Plugin_Handled;
  1930. }
  1931. else if(firstParamNumber == CS_TEAM_T)
  1932. {
  1933. if(TeamsSetup())
  1934. TryGoT(client);
  1935. else
  1936. return Plugin_Continue;
  1937. }
  1938. else if(firstParamNumber == CS_TEAM_CT)
  1939. {
  1940. if(TeamsSetup())
  1941. TryGoCT(client);
  1942. else
  1943. return Plugin_Continue;
  1944. }
  1945. else // Autojoin, our own version.
  1946. {
  1947. if(TeamsSetup())
  1948. OurAutojoin(client);
  1949. else
  1950. return Plugin_Continue;
  1951. }
  1952. return Plugin_Handled;
  1953. }
  1954.  
  1955. public Action:HookBuy(client, const String:command[], argc)
  1956. {
  1957. // Destined team
  1958. new String:firstParam[16];
  1959. GetCmdArg(1, firstParam, 16);
  1960. StripQuotes(firstParam);
  1961. if(ReadyUpState())
  1962. {
  1963. if(StrEqual(firstParam,"flashbang") || StrEqual(firstParam,"hegrenade") || StrEqual(firstParam,"smokegrenade"))
  1964. {
  1965. PrintCenterText(client, "CSL: No grenades during warm up.");
  1966. return Plugin_Handled;
  1967. }
  1968. }
  1969. return Plugin_Continue;
  1970. }
  1971.  
  1972. ClearMatch()
  1973. {
  1974. ServerCommand("tv_stoprecord\n"); // Leet, MIRITE?!
  1975. if(RestartTimers!=INVALID_HANDLE)
  1976. {
  1977. CloseHandle(RestartTimers);
  1978. }
  1979. RoundCounterOn = false;
  1980. ChangeMatchState(MS_Pre_Setup);
  1981. TeamAScore = 0;
  1982. TeamBScore = 0;
  1983. CurrentRound = 0;
  1984. Format(MatchMap, 32, "");
  1985. for(new x=0;x<MAX_ROUNDS;x++)
  1986. {
  1987. if(hMatchDamage[x]!=INVALID_HANDLE)
  1988. {
  1989. // How big is the array?
  1990. new s = GetArraySize(hMatchDamage[x]);
  1991. for(new y=0;y<s;y++)
  1992. {
  1993. new Handle:aAt = GetArrayCell(hMatchDamage[x], y);
  1994. CloseHandle(aAt);
  1995. }
  1996. CloseHandle(hMatchDamage[x]);
  1997. hMatchDamage[x] = INVALID_HANDLE;
  1998. }
  1999. if(hMatchKills[x]!=INVALID_HANDLE)
  2000. {
  2001. new s = GetArraySize(hMatchKills[x]);
  2002. for(new y=0;y<s;y++)
  2003. {
  2004. new Handle:aAt = GetArrayCell(hMatchKills[x], y);
  2005. CloseHandle(aAt);
  2006. }
  2007. CloseHandle(hMatchKills[x]);
  2008. hMatchKills[x] = INVALID_HANDLE;
  2009. }
  2010. }
  2011. Ruleset = Rules_PUG;
  2012. CaptainMode = false;
  2013. BunnyHopMode = false;
  2014. for(new x=0;x<TEAM_COUNT;x++)
  2015. {
  2016. Format(TeamPlayers[x][0], 24, "");
  2017. Format(TeamPlayers[x][1], 24, "");
  2018. Format(TeamPlayers[x][2], 24, "");
  2019. Format(TeamPlayers[x][3], 24, "");
  2020. Format(TeamPlayers[x][4], 24, "");
  2021. }
  2022. }
  2023.  
  2024. GetMapCount()
  2025. {
  2026. new mapCount = 0;
  2027. for(new x=0;x<MAX_MAPS;x++)
  2028. {
  2029. if(!StrEqual(MapNames[x],""))
  2030. {
  2031. mapCount++;
  2032. }
  2033. }
  2034. return mapCount;
  2035. }
  2036.  
  2037. AddToOurMaps(const String:mapName[])
  2038. {
  2039. for(new x=0;x<MAX_MAPS;x++)
  2040. {
  2041. if(StrEqual(MapNames[x],""))
  2042. {
  2043. Format(MapNames[x], 32, mapName);
  2044. break;
  2045. }
  2046. }
  2047. }
  2048.  
  2049. LoadMapsDir()
  2050. {
  2051. // Build path and look for .bsp files.
  2052. new String:mapsDir[1024];
  2053. BuildPath(Path_SM, mapsDir, 1024, "../../maps/");
  2054. new String:path[1024];
  2055. new Handle:dir = OpenDirectory(mapsDir);
  2056. new FileType:type;
  2057. while(ReadDirEntry(dir, path, sizeof(path), type))
  2058. {
  2059. if(type == FileType_File && StrContains(path, ".bsp") != -1)
  2060. {
  2061. // How many dots in the path?
  2062. new len = strlen(path);
  2063. new periods = 0;
  2064. for(new x=0;x<len;x++)
  2065. {
  2066. if(path[x]=='.')
  2067. {
  2068. periods++;
  2069. }
  2070. }
  2071. if(periods==1)
  2072. {
  2073. ReplaceString(path, 1024, ".bsp", "", false);
  2074. AddToOurMaps(path);
  2075. }
  2076. }
  2077. }
  2078. CloseHandle(dir);
  2079. }
  2080.  
  2081. GoPostgame(winning_team, bool:forfeit = false)
  2082. {
  2083. RoundCounterOn = false;
  2084. // Send stats?
  2085. ChangeMatchState(MS_Post_Match);
  2086.  
  2087. // TODO
  2088. new bool:tie=(winning_team==-1)?true:false;
  2089. if(tie)
  2090. {
  2091. forfeit = false; // Just incase?
  2092. }
  2093.  
  2094. // Show everyone their stats page.
  2095.  
  2096. ClearMatch();
  2097. }
  2098.  
  2099. MatchWinForfeit(winning_team)
  2100. {
  2101. PrintToChatAll("[PUG] %s wins due to forfeit", (winning_team==TEAM_A)?"Team A":"Team B");
  2102. GoPostgame(winning_team, true);
  2103. }
  2104.  
  2105. MatchWin(winning_team)
  2106. {
  2107. // Was the winning_team T or CT?
  2108. new WinningScore = (winning_team==TEAM_A)?TeamAScore:TeamBScore;
  2109. new LosingScore = (winning_team==TEAM_A)?TeamBScore:TeamAScore;
  2110. PrintToChatAll("[PUG] Match is over, %s wins the match %d - %d",(winning_team==TEAM_A)?"Team A":"Team B", WinningScore, LosingScore);
  2111.  
  2112. GoPostgame(winning_team);
  2113. }
  2114.  
  2115. MatchWinOT(winning_team)
  2116. {
  2117. // Was the winning_team T or CT?
  2118. new WinningScore = (winning_team==TEAM_A)?TeamAScore:TeamBScore;
  2119. new LosingScore = (winning_team==TEAM_A)?TeamBScore:TeamAScore;
  2120. PrintToChatAll("[PUG] Overtime is over, %s wins the match %d - %d",(winning_team==TEAM_A)?"Team A":"Team B", WinningScore, LosingScore);
  2121.  
  2122. GoPostgame(winning_team);
  2123. }
  2124.  
  2125. MatchTieOT()
  2126. {
  2127. PrintToChatAll("[PUG] Match ends in a tie, %d - %d", TeamAScore, TeamBScore);
  2128. GoPostgame(-1);
  2129. }
  2130.  
  2131. DeleteBomb()
  2132. {
  2133. for (new i = 1; i <= MaxClients; i++)
  2134. {
  2135. if (IsClientInGame(i) && IsPlayerAlive(i))
  2136. {
  2137. new iWeapon = GetPlayerWeaponSlot(i, 4);
  2138.  
  2139. if (iWeapon != -1 && IsValidEdict(iWeapon))
  2140. {
  2141. decl String:szClassName[64];
  2142. GetEdictClassname(iWeapon, szClassName, sizeof(szClassName));
  2143.  
  2144. if (StrEqual(szClassName, "weapon_c4"))
  2145. {
  2146. RemovePlayerItem(i, iWeapon);
  2147. RemoveEdict(iWeapon);
  2148. }
  2149. }
  2150. }
  2151. }
  2152.  
  2153. }
  2154.  
  2155. bool:IsPubChatMuted(client)
  2156. {
  2157. return bPubChatMuted[client];
  2158. }
  2159.  
  2160. bool:IsTeamChatMuted(client)
  2161. {
  2162. return bTeamChatMuted[client];
  2163. }
  2164.  
  2165. bool:IsPlayerMuted(client, player)
  2166. {
  2167. return bMuted[client][player];
  2168. }
  2169.  
  2170. TryTranslatePlace(const String:input[], String:output[], maxlen)
  2171. {
  2172. new bool:bOtherCheck = false;
  2173. if(StrEqual(input, "CTSpawn"))
  2174. {
  2175. Format(output, maxlen, "CT Spawn");
  2176. }
  2177. else if(StrEqual(input, "TSpawn"))
  2178. {
  2179. Format(output, maxlen, "T Spawn")
  2180. }
  2181. else
  2182. {
  2183. bOtherCheck = true;
  2184. }
  2185. if(!bOtherCheck)
  2186. {
  2187. return;
  2188. }
  2189. new len=strlen(input);
  2190. // Clear the output.
  2191. Format(output, maxlen, "");
  2192. new bool:bPrevHadSpace = true;
  2193. new bool:bPrevWasIndi = true;
  2194. for(new x=0;x<len;x++)
  2195. {
  2196. if(input[x]==' ')
  2197. {
  2198. bPrevWasIndi = false;
  2199. if(bPrevHadSpace)
  2200. {
  2201. bPrevHadSpace = false;
  2202. }
  2203. else
  2204. {
  2205. Format(output, maxlen, "%s ", output);
  2206. bPrevHadSpace = true;
  2207. }
  2208. }
  2209. else if( (input[x]>='A' && input[x]<='Z') || (input[x]>='1' && input[x]<='9'))
  2210. {
  2211. if(bPrevWasIndi)
  2212. {
  2213. Format(output, maxlen, "%s%c", output, input[x]);
  2214. bPrevHadSpace = false;
  2215. }
  2216. else
  2217. {
  2218. if(bPrevHadSpace)
  2219. {
  2220. Format(output, maxlen, "%s%c", output, input[x]);
  2221. bPrevHadSpace = false;
  2222. }
  2223. else
  2224. {
  2225. Format(output, maxlen, "%s %c", output, input[x]);
  2226. bPrevHadSpace = true;
  2227. }
  2228. }
  2229. bPrevWasIndi = true;
  2230. }
  2231. else
  2232. {
  2233. bPrevWasIndi = false;
  2234. if(bPrevHadSpace)
  2235. {
  2236. bPrevHadSpace = false;
  2237. }
  2238. Format(output, maxlen, "%s%c", output, input[x]);
  2239. }
  2240. }
  2241. }
  2242.  
  2243. ChatMsg(client, bool:team, const String:chatMsg[])
  2244. {
  2245. if(!ValidClient(client))
  2246. {
  2247. return;
  2248. }
  2249. new cTeam = GetClientTeam(client);
  2250. if(cTeam<CS_TEAM_T || cTeam>CS_TEAM_CT)
  2251. {
  2252. return;
  2253. }
  2254. new String:cTeamName[32];
  2255. if(cTeam == CS_TEAM_T)
  2256. {
  2257. Format(cTeamName, 32, "Terrorist");
  2258. }
  2259. else
  2260. {
  2261. Format(cTeamName, 32, "Counter-Terrorist");
  2262. }
  2263. new bool:bAlive = IsPlayerAlive(client);
  2264. new String:fullChat[250];
  2265. new String:sPlaceName[64];
  2266. new String:sNewPlaceName[64];
  2267. new String:plName[64];
  2268. GetClientName(client, plName, 64);
  2269. GetEntPropString(client, Prop_Data, "m_szLastPlaceName", sPlaceName, 64);
  2270. TryTranslatePlace(sPlaceName, sNewPlaceName, 64);
  2271. if(bAlive)
  2272. {
  2273. if(team)
  2274. {
  2275. if(StrEqual(sNewPlaceName, ""))
  2276. {
  2277. Format(fullChat, 250, "\x01(%s) \x03%s\x01 : %s", cTeamName, plName, chatMsg);
  2278. }
  2279. else
  2280. {
  2281. Format(fullChat, 250, "\x01(%s) \x03%s\x01 @ \x04%s\x01 : %s", cTeamName, plName, sNewPlaceName, chatMsg);
  2282. }
  2283. }
  2284. else
  2285. {
  2286. Format(fullChat, 250, "\x03%s\x01 : %s", plName, chatMsg);
  2287. }
  2288. }
  2289. else
  2290. {
  2291. if(team)
  2292. {
  2293. Format(fullChat, 250, "\x01*DEAD*(%s) \x03%s\x01 : %s", cTeamName, plName, chatMsg);
  2294. }
  2295. else
  2296. {
  2297. Format(fullChat, 250, "\x01*DEAD* \x03%s\x01 : %s", plName, chatMsg);
  2298. }
  2299. }
  2300.  
  2301. // Console friendly.
  2302. // But first clean it up a bit ;]
  2303. new String:fullChatClean[250];
  2304. Format(fullChatClean, 250, "%s", fullChat);
  2305. ReplaceString(fullChatClean, 250, "\x01", "");
  2306. ReplaceString(fullChatClean, 250, "\x02", "");
  2307. ReplaceString(fullChatClean, 250, "\x03", "");
  2308. ReplaceString(fullChatClean, 250, "\x04", "");
  2309. PrintToServer("%s", fullChatClean);
  2310.  
  2311. for(new x=1;x<=MAXPLAYERS;x++)
  2312. {
  2313. if(!ValidClient(x) || IsFakeClient(x))
  2314. {
  2315. continue;
  2316. }
  2317. new bool:bForMe = true;
  2318. if(team && GetClientTeam(x) != cTeam)
  2319. {
  2320. bForMe = false;
  2321. }
  2322. if(!bAlive)
  2323. {
  2324. if(IsPlayerAlive(x))
  2325. {
  2326. bForMe = false;
  2327. }
  2328. }
  2329. if(IsPlayerMuted(x, client))
  2330. {
  2331. bForMe = false;
  2332. }
  2333. if(team && IsTeamChatMuted(x))
  2334. {
  2335. bForMe = false;
  2336. }
  2337. if(!team && IsPubChatMuted(x))
  2338. {
  2339. bForMe = false;
  2340. }
  2341. if(bForMe)
  2342. {
  2343. new Handle:hBuffer = StartMessageOne("SayText2", x);
  2344. BfWriteByte(hBuffer, client);
  2345. BfWriteByte(hBuffer, true);
  2346. BfWriteString(hBuffer, fullChat);
  2347. EndMessage();
  2348. }
  2349. }
  2350. }
  2351.  
  2352. public OnPluginStart()
  2353. {
  2354. ServerCommand("exec server_pug.cfg\n");
  2355. OffsetAccount = FindSendPropOffs("CCSPlayer", "m_iAccount");
  2356. hMaxPlayers = CreateConVar("sv_maxplayers", MAX_PLAYERS_DEFAULT, "Match size.", FCVAR_PLUGIN|FCVAR_REPLICATED|FCVAR_SPONLY|FCVAR_NOTIFY);
  2357. CreateConVar("sm_pug_version", "0.1", "PUG Plugin Version",FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY|FCVAR_DONTRECORD);
  2358. hTVEnabled = FindConVar("tv_enable");
  2359. hBotQuota = FindConVar("bot_quota");
  2360. SetConVarInt(hBotQuota, 0);
  2361.  
  2362. //SetConVarInt(hTVEnabled, 1);
  2363. ClearMatch();
  2364. new Handle:hTagsCvar = FindConVar("sv_tags");
  2365. new oldFlags = GetConVarFlags(hTagsCvar);
  2366. new newFlags = oldFlags;
  2367. newFlags &= ~FCVAR_NOTIFY;
  2368. SetConVarFlags(hTagsCvar, newFlags);
  2369. //new Handle:hTVName = FindConVar("tv_name");
  2370. //SetConVarString(hTVName, "CSL SourceTV");
  2371. //new Handle:hTVTrans = FindConVar("tv_transmitall");
  2372. CreateTimer(4.0, WarmUpSpawner, _, TIMER_REPEAT);
  2373. //SetConVarInt(hTVTrans, 1);
  2374. LoadMapsDir();
  2375. HookEvent("player_spawn",SpawnCallback);
  2376. HookEvent("player_death",DeathCallback);
  2377. HookEvent("player_hurt",HurtCallback);
  2378. HookEvent("round_start",RoundStartCallback);
  2379. HookEvent("round_end",RoundEndCallback);
  2380. AddCommandListener(HookJoinTeam, "jointeam");
  2381. AddCommandListener(HookSpectate, "spectate");
  2382. AddCommandListener(HookBuy, "buy");
  2383. for(new x=0;x<MAXPLAYERS+1;x++) //[0-64]
  2384. {
  2385. ClientDefaults(x);
  2386. }
  2387. // Hooks
  2388. RegConsoleCmd("say",SayPubHook);
  2389. RegConsoleCmd("say_team",SayTeamHook);
  2390. CreateTimer(1.0, OneSecCheck, _, TIMER_REPEAT);
  2391. }
  2392.  
  2393. enum ConnAction
  2394. {
  2395. ConnAction_Connect_NonMember = 0,
  2396. ConnAction_Connect_Member,
  2397. ConnAction_Disconnect,
  2398. };
  2399.  
  2400. bool:MatchLive()
  2401. {
  2402. if(gMatchState == MS_Live_First_Half || gMatchState == MS_Live_Second_Half || gMatchState == MS_Live_Overtime_First_Half || gMatchState == MS_Live_Overtime_Second_Half)
  2403. {
  2404. return true;
  2405. }
  2406. return false;
  2407. }
  2408.  
  2409. public T_NoCallback(Handle:owner,Handle:hndl,const String:error[],any:data)
  2410. {
  2411. // pst... it's quiet... too quiet? maybe log errors?
  2412. }
  2413.  
  2414. public StatsCallback(Handle:owner,Handle:hndl,const String:error[],any:data)
  2415. {
  2416. new client=GetClientOfUserId(data);
  2417. if(!ValidClient(client))
  2418. {
  2419. return;
  2420. }
  2421. if(hndl!=INVALID_HANDLE)
  2422. {
  2423. SQL_Rewind(hndl);
  2424. if(!SQL_FetchRow(hndl))
  2425. {
  2426. PrintToChat(client, "[PUG] Sorry, username doesn't exist.");
  2427. }
  2428. else
  2429. {
  2430. new steamid;
  2431. SQL_FieldNameToNum(hndl, "steamid", steamid);
  2432. new String:steam[24];
  2433. SQL_FetchString(hndl, steamid, steam, 24);
  2434. new String:fullURL[192];
  2435. Format(fullURL, 192, "http://thecsleague.com/stats.php?steam=%s", steam);
  2436. ShowMOTDPanel(client, "Stats", fullURL, MOTDPANEL_TYPE_URL);
  2437. }
  2438. }
  2439. }
  2440.  
  2441. StartAuth(client)
  2442. {
  2443. if(!ValidClient(client) || IsSourceTV(client))
  2444. {
  2445. return;
  2446. }
  2447. if(!AllowBots() && IsFakeClient(client))
  2448. {
  2449. Kick(client,"No bots!"); // No bots stupid.
  2450. return;
  2451. }
  2452. notReadyTime[client] = GetTime();
  2453. // Make sure they are a customer.
  2454. decl String:steamID[24];
  2455. GetClientAuthString(client, steamID, 24);
  2456. if(BadSteamId(steamID))
  2457. {
  2458. Kick(client,"Your STEAMID isn't valid.");
  2459. return;
  2460. }
  2461.  
  2462. notReadyTime[client] = GetTime();
  2463. // Is the match already live? If it is put this person on a team etc...
  2464. // TODO: This will need to be changed once we have a captain mode.
  2465. if(TeamsSetup())
  2466. {
  2467. OurAutojoin(client);
  2468. }
  2469. }
  2470.  
  2471. bool:IsSourceTV(client)
  2472. {
  2473. if(!ValidClient(client))
  2474. return false;
  2475. decl String:plName[64];
  2476. GetClientName(client, plName, 64);
  2477. if(IsFakeClient(client) && ( StrEqual(plName,"SourceTV") || StrEqual(plName,"CSL SourceTV") ))
  2478. {
  2479. return true;
  2480. }
  2481. return false;
  2482. }
  2483.  
  2484. public OnClientPutInServer(client)
  2485. {
  2486. ClientDefaults(client);
  2487. if(IsSourceTV(client))
  2488. return; // Don't auth the SourceTV dude! :P
  2489. new cCount = GetClientCount();
  2490. if(GetConVarInt(hTVEnabled)==1)
  2491. cCount -= 1;
  2492. if(cCount>GetConVarInt(hMaxPlayers))
  2493. {
  2494. Kick(client, "Sorry, this match is full");
  2495. return;
  2496. }
  2497. StartAuth(client);
  2498. }
  2499.  
  2500. ClientOfSteamId(const String:steamID[])
  2501. {
  2502. for(new x=1;x<=MAXPLAYERS;x++)
  2503. {
  2504. if(ValidClient(x) && !IsSourceTV(x))
  2505. {
  2506. new String:mySteam[24];
  2507. GetClientAuthString(x, mySteam, 24);
  2508. if(StrEqual(steamID, mySteam))
  2509. {
  2510. return x;
  2511. }
  2512. }
  2513. }
  2514. return 0;
  2515. }
  2516.  
  2517. TeamOfSteamId(const String:steamID[])
  2518. {
  2519. // Return of -1 indicates none yet.
  2520. for(new x=0;x<TEAM_COUNT;x++)
  2521. {
  2522. for(new y=0;y<5;y++)
  2523. {
  2524. if(StrEqual(steamID, TeamPlayers[x][y]))
  2525. {
  2526. return x;
  2527. }
  2528. }
  2529. }
  2530. return -1;
  2531. }
  2532.  
  2533. public OnClientDisconnect(client)
  2534. {
  2535. bDisconnecting[client] = true;
  2536.  
  2537. new bool:specialCase = false;
  2538.  
  2539. if(IsFakeClient(client) && !IsSourceTV(client)) {
  2540. specialCase = true;
  2541. }
  2542.  
  2543. if(IsSourceTV(client))
  2544. return;
  2545.  
  2546. if(MatchLive())
  2547. {
  2548. new String:steamID[24];
  2549. GetClientAuthString(client, steamID, 24);
  2550. new TeamAB = TeamOfSteamId(steamID);
  2551. if(TeamAB==-1)
  2552. {
  2553. return; // They we're on a team yet.
  2554. }
  2555. // Is anyone else on their team still there? If not, the match has been forfeited.
  2556. new bool:AnyOnline = false;
  2557. for(new x=0;x<5;x++)
  2558. {
  2559. new cOfSteam = ClientOfSteamId(TeamPlayers[TeamAB][x]);
  2560. if(ValidClient(cOfSteam) && client!=cOfSteam)
  2561. {
  2562. AnyOnline = true;
  2563. }
  2564. }
  2565. if(!AnyOnline && !specialCase)
  2566. {
  2567. MatchWinForfeit( (TeamAB==TEAM_A) ? TEAM_B : TEAM_A );
  2568. }
  2569. }
  2570. /*else
  2571. {
  2572. // TODO: If we are picking teams?
  2573. }*/
  2574. }
  2575.  
  2576. public OnMapStart()
  2577. {
  2578. ServerCommand("mp_do_warmup_period 0");
  2579. ServerCommand("mp_maxrounds 0");
  2580. ServerCommand("bot_quota 0");
  2581. ServerCommand("bot_kick");
  2582. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement