Advertisement
Guest User

PUG 1.3

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