Advertisement
Guest User

PUG 1.2

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