· 8 years ago · Apr 03, 2018, 08:44 AM
1#include <sourcemod>
2#include <cstrike>
3#include <sdktools>
4#include <clientprefs>
5#include <smlib>
6
7#pragma newdecls required
8#pragma semicolon 1
9
10public Plugin myinfo =
11{
12 name = "Rushes",
13 author = "Ofir, Reduxed by Techno",
14 description = "Rushes",
15 version = "1.3",
16 url = "https://forums.alliedmods.net/member.php?u=190571"
17};
18
19//Enums and Contstants
20#define PREFIX " \x05[RUSHES]\x04 "
21#define CRATEMODEL "models/props/props_crates/wooden_crate_64x64_dirt.mdl"
22#define CRATEHEIGHT 74
23#define CRATEWIDTH 74
24#define MAXWALLS 64
25#define SITEA 0
26#define SITEB 1
27#define GRENADESSETTCOUNT 4
28#define GRENADESSETCTCOUNT 3
29enum Wall
30{
31 Id,
32 Float:Point1[3],
33 Float:Point2[3],
34 Site,
35 StartEnt,
36 EndEnt
37}
38
39enum WallEditor
40{
41 Step,
42 Float:Point1[3],
43 Float:Point2[3]
44}
45
46char gs_TGrenadeSets[][] = {
47 "weapon_flashbang",
48 "weapon_flashbang",
49 "weapon_smokegrenade",
50 "weapon_smokegrenade"
51};
52bool gb_TGrenadeSetsFlags[4];
53
54char gs_CTGrenadeSets[][] = {
55 "weapon_flashbang",
56 "weapon_hegrenade",
57 "weapon_hegrenade"
58};
59bool gb_CTGrenadeSetsFlags[3];
60
61//Cvars Handlers
62ConVar gh_PistolRoundsCount;
63ConVar gh_CzChancePercent;
64ConVar gh_BRush;
65
66//Cvars Vars
67int gi_PistolRoundsCount;
68int gi_CzChancePercent;
69bool gb_BRush;
70
71//Players Arrays
72bool gb_PreferenceLoaded[MAXPLAYERS+1] = {false, ...};
73int gi_PistolPrefence[MAXPLAYERS+1] = {0, ...};
74int gi_WantAwp[MAXPLAYERS+1] = {0, ...};
75bool gb_WantSilencer[MAXPLAYERS+1] = {false, ...};
76int gi_DamageCount[MAXPLAYERS+1];
77int gi_NextRoundTeam[MAXPLAYERS+1] = {-1, ...};
78
79//Vars
80int g_Walls[MAXWALLS][Wall];
81int gi_WallsCounter = 0;
82char gs_CurrentMap[64];
83int g_WallEditors[MAXPLAYERS+1][WallEditor];
84int gi_MoneyOffset;
85int gi_HelmetOffset;
86bool gb_EditMode = false;
87bool gb_WaitForPlayers = false;
88bool gb_WarmUp = false;
89bool gb_balancedTeams = false;
90bool gb_newClientsJoined = false;
91int gi_PlayerQueue[MAXPLAYERS+1];
92int gi_QueueCounter;
93int g_precacheLaser;
94int gi_WinRow;
95float gf_MapLoadTime;
96float gf_StartRoundTime;
97Handle gh_MapLoadTimer;
98int gi_WallsToShow = 2;
99bool gb_OnlyPistols = false;
100
101//Sql
102Handle gh_Sql;
103int gi_ReconncetCounter = 0;
104
105//Cookies
106Handle gh_SilencedM4 = INVALID_HANDLE;
107Handle gh_WantAwp = INVALID_HANDLE;
108Handle gh_PistolPrefence = INVALID_HANDLE;
109
110public void OnPluginStart()
111{
112 //Convars
113 gh_PistolRoundsCount = CreateConVar("rushes_pistols", "5", "How much Pistols Rounds should be. 0 to disable", _, true, 0.0);
114 gh_CzChancePercent = CreateConVar("rushes_czchance", "33", "How much percent to give a awper a cz by his choice. 0 to disable", _, true, 0.0, true, 100.0);
115 gh_BRush = CreateConVar("rushes_brush", "0", "Only B-Rush (like the original mod)", _, true, 0.0, true, 1.0);
116
117 gi_PistolRoundsCount = GetConVarInt(gh_PistolRoundsCount);
118 gi_CzChancePercent = GetConVarInt(gh_CzChancePercent);
119 gb_BRush = GetConVarBool(gh_BRush);
120
121 HookConVarChange(gh_PistolRoundsCount, Action_OnSettingsChange);
122 HookConVarChange(gh_CzChancePercent, Action_OnSettingsChange);
123 HookConVarChange(gh_BRush, Action_OnSettingsChange);
124
125 AutoExecConfig(true, "rushes");
126 //Coockies
127 gh_WantAwp = RegClientCookie("rushes_awp", "RUSHES allow player play with awp", CookieAccess_Protected);
128 gh_SilencedM4 = RegClientCookie("rushes_m4", "RUSHES play with m4a1s or m4a4", CookieAccess_Protected);
129 gh_PistolPrefence = RegClientCookie("rushes_pistol", "RUSHES pistol prefernce", CookieAccess_Protected);
130 //Admin Commands
131 RegAdminCmd("sm_add", Command_AddWall, ADMFLAG_RCON);
132 RegAdminCmd("sm_del", Command_DeleteWall, ADMFLAG_RCON);
133 RegAdminCmd("sm_delete", Command_DeleteWall, ADMFLAG_RCON);
134 RegAdminCmd("sm_show", Command_Show, ADMFLAG_RCON);
135 RegAdminCmd("sm_edit", Command_Edit, ADMFLAG_RCON);
136
137 RegAdminCmd("sm_start", Command_Start, ADMFLAG_KICK);
138 RegAdminCmd("sm_pistols", Command_OnlyPistols, ADMFLAG_KICK);
139
140 HookEvent("player_hurt", Event_OnPlayerDamged);
141 //Client Commands
142 RegConsoleCmd("sm_guns", Command_Guns);
143 RegConsoleCmd("sm_awp", Command_Guns);
144 RegConsoleCmd("sm_m4", Command_Guns);
145 RegConsoleCmd("sm_m4a1", Command_Guns);
146 RegConsoleCmd("sm_m4a4", Command_Guns);
147 //Events
148 HookEvent("round_prestart", Event_OnRoundPreStart);
149 HookEvent("round_poststart", Event_OnRoundPostStart);
150 HookEvent("round_end", Event_OnRoundEnd);
151 HookEvent("player_connect_full", Event_OnFullConnect);
152 HookEvent("player_team", Event_OnPlayerChangeTeam, EventHookMode_Pre);
153 AddCommandListener(Command_Say, "say");
154 AddCommandListener(Command_Say, "say_team");
155 //Listeners
156 AddCommandListener(Hook_ChangeTeam, "jointeam");
157 AddCommandListener(Hook_ChangeTeam, "teammenu");
158 //Offsets
159 gi_MoneyOffset = FindSendPropInfo("CCSPlayer", "m_iAccount");
160 gi_HelmetOffset = FindSendPropInfo("CCSPlayer", "m_bHasHelmet");
161 ConnectSQL();
162}
163
164public Action Command_Start(int client, int args)
165{
166 gf_MapLoadTime -= 50;
167 TriggerTimer(gh_MapLoadTimer, false);
168 return Plugin_Handled;
169}
170
171public Action Command_OnlyPistols(int client, int args)
172{
173 gb_OnlyPistols = !gb_OnlyPistols;
174 PrintToChatAll("%sOnly Pistol iss now \x02%s", PREFIX, gb_OnlyPistols ? "Enabled":"Disabled");
175 return Plugin_Handled;
176}
177
178public Action Command_Show(int client, int args)
179{
180 if(args > 0)
181 {
182 char sArg[64];
183 GetCmdArg(1, sArg, sizeof(sArg));
184 gi_WallsToShow = StringToInt(sArg);
185 }
186 else
187 {
188 ReplyToCommand(client, "[SM] Usage: sm_show <0=A,1=B,2=BOTH>");
189 }
190 return Plugin_Handled;
191}
192
193public void Action_OnSettingsChange(ConVar convar, const char[] oldValue, const char[] newValue)
194{
195 if (convar == gh_PistolRoundsCount)
196 {
197 gi_PistolRoundsCount = StringToInt(newValue);
198 }
199 else if(convar == gh_CzChancePercent)
200 {
201 gi_CzChancePercent = StringToInt(newValue);
202 }
203 else if(convar == gh_BRush)
204 {
205 gb_BRush = view_as<bool>(StringToInt(newValue));
206 }
207}
208
209public void OnMapStart()
210{
211 PrecacheModel(CRATEMODEL);
212 g_precacheLaser = PrecacheModel("materials/sprites/laserbeam.vmt");
213 //Map String to LowerCase
214 GetCurrentMap(gs_CurrentMap, sizeof(gs_CurrentMap));
215 int len = strlen(gs_CurrentMap);
216 for (int i=0;i < len;i++)
217 {
218 gs_CurrentMap[i] = CharToLower(gs_CurrentMap[i]);
219 }
220 gb_EditMode = false;
221 gb_WarmUp = true;
222 LoadWalls();
223 SetConfig(true);
224 ServerCommand("mp_warmuptime 5");
225 ServerCommand("mp_warmup_end");
226 gi_QueueCounter = 0;
227 for (int i = 1; i < MaxClients; i++)
228 {
229 if(IsClientInGame(i))
230 {
231 LoadClientCoockies(i);
232 if(GetClientTeam(i) == 1)
233 {
234 AddPlayerToQueue(i);
235 }
236 }
237 }
238 gb_WarmUp = true;
239 PrintToChatAll("%sRushes will start in 30 seconds", PREFIX);
240 gh_MapLoadTimer = CreateTimer(30.0, Timer_MapLoadDelay, _);
241 gf_MapLoadTime = GetEngineTime();
242 CreateTimer(0.1, Timer_PrintHintWarmup, _, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE);
243}
244
245void LoadClientCoockies(int client)
246{
247 if(IsFakeClient(client))
248 return;
249 char buffer[16];
250 bool openGunsMenu = false;
251
252 GetClientCookie(client, gh_WantAwp, buffer, sizeof(buffer));
253 if(!StrEqual(buffer, ""))
254 gi_WantAwp[client] = StringToInt(buffer);
255 else
256 openGunsMenu = true;
257
258 GetClientCookie(client, gh_SilencedM4, buffer, sizeof(buffer));
259 if(!StrEqual(buffer, ""))
260 gb_WantSilencer[client] = view_as<bool>(StringToInt(buffer));
261 else
262 openGunsMenu = true;
263
264 GetClientCookie(client, gh_PistolPrefence, buffer, sizeof(buffer));
265 if(!StrEqual(buffer, ""))
266 gi_PistolPrefence[client] = view_as<bool>(StringToInt(buffer));
267 else
268 openGunsMenu = true;
269
270 gb_PreferenceLoaded[client] = !openGunsMenu;
271}
272
273public void OnClientCookiesCached(int client)
274{
275 LoadClientCoockies(client);
276}
277
278public Action Event_OnRoundPreStart(Event event, const char[] name, bool dontBroadcast)
279{
280 if(!gb_EditMode)
281 {
282 if(!gb_balancedTeams)
283 {
284 SetQueueClients();
285 gb_balancedTeams = true;
286 }
287 else
288 {
289 gb_balancedTeams = false;
290 }
291 if(!gb_newClientsJoined)
292 {
293 for (int i = 1; i <= MaxClients; i++)
294 {
295 if(IsClientInGame(i) && gi_NextRoundTeam[i] == -1)
296 {
297 gi_NextRoundTeam[i] = GetClientTeam(i);
298 }
299 }
300 BalanceTeams();
301 }
302 gb_newClientsJoined = false;
303 for (int i = 1; i <= MaxClients; i++)
304 {
305 if(IsClientInGame(i) && !IsClientSourceTV(i) && gi_NextRoundTeam[i] != -1)
306 {
307 CS_SwitchTeam(i, gi_NextRoundTeam[i]);
308 CS_UpdateClientModel(i);
309 }
310 }
311 for (int i = 0; i < MAXPLAYERS; i++)
312 {
313 gi_NextRoundTeam[i] = -1;
314 }
315 }
316}
317
318public Action Event_OnRoundPostStart(Event event, const char[] name, bool dontBroadcast)
319{
320 if(!gb_EditMode && !gb_WaitForPlayers && !gb_WarmUp)
321 {
322 int site = SITEB;
323 if(!gb_BRush)
324 {
325 site = GetRandomInt(0, 1);
326 PrintToChatAll("%sRush to Site:\x02%s", PREFIX, site == SITEA ? "A":"B");
327 gf_StartRoundTime = GetEngineTime();
328 CreateTimer(0.1, Timer_PrintHintSite, site, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE);
329 }
330
331 for (int i = 0; i < MAXPLAYERS; i++)
332 {
333 gi_DamageCount[i] = 0;
334 }
335
336 for (int i = 0; i < GRENADESSETTCOUNT; i++)
337 {
338 gb_TGrenadeSetsFlags[i] = false;
339 }
340
341 for (int i = 0; i < GRENADESSETCTCOUNT; i++)
342 {
343 gb_CTGrenadeSetsFlags[i] = false;
344 }
345
346 //Random awper for each team
347 int awpCt = GetRandomAwpPlayer(3);
348 int awpT = GetRandomAwpPlayer(2);
349 //Get Bomber
350 int Bomber = GetRandomPlayerFromTeam(2);
351
352 int randomGrenadeSet = -1;
353
354 bool pistols = CS_GetTeamScore(3) + CS_GetTeamScore(2) < gi_PistolRoundsCount;
355 if(gb_OnlyPistols)
356 pistols = true;
357 for (int i = 1; i <= MaxClients; i++)
358 {
359 if(IsClientInGame(i) && !IsClientSourceTV(i) && GetClientTeam(i) != 1)
360 {
361 //Set Money to 0$
362 SetEntData(i, gi_MoneyOffset, 0);
363 SetEntProp(i, Prop_Data, "m_ArmorValue", 100);
364 Client_RemoveAllWeapons(i);
365 GivePlayerItem(i, "weapon_knife");
366 if(!pistols)
367 {
368 SetEntData(i, gi_HelmetOffset, 1);
369 randomGrenadeSet = GetRandomGrenadeSet(GetClientTeam(i));
370 if(randomGrenadeSet != -1)
371 {
372 if(GetClientTeam(i) == 3)
373 {
374 gb_CTGrenadeSetsFlags[randomGrenadeSet] = true;
375 GivePlayerItem(i, gs_CTGrenadeSets[randomGrenadeSet]);
376 }
377 else if(GetClientTeam(i) == 2)
378 {
379 gb_TGrenadeSetsFlags[randomGrenadeSet] = true;
380 GivePlayerItem(i, gs_TGrenadeSets[randomGrenadeSet]);
381 }
382 }
383 }
384 if(i == Bomber)
385 {
386 GivePlayerItem(i, "weapon_c4");
387 }
388 if(GetClientTeam(i) == 3)
389 {
390 GivePlayerItem(i, "item_defuser");
391 }
392 if((awpCt == i || awpT == i) && !pistols)
393 {
394 GivePlayerItem(i, "weapon_awp");
395 if(gi_PistolPrefence[i] == 0)
396 {
397 if(GetClientTeam(i) == 3)
398 GivePlayerItem(i, "weapon_hkp2000");
399 else
400 GivePlayerItem(i, "weapon_glock");
401 }
402 else if(gi_PistolPrefence[i] == 1)
403 {
404 if(GetRandomInt(1, 100) <= gi_CzChancePercent)
405 {
406 GivePlayerItem(i, "weapon_cz75a");
407 }
408 else
409 GivePlayerItem(i, "weapon_p250");
410 }
411 else if(gi_PistolPrefence[i] == 2)
412 GivePlayerItem(i, "weapon_p250");
413 }
414 else
415 {
416 if(GetClientTeam(i) == 3)
417 {
418 if(!pistols)
419 {
420 if(!gb_WantSilencer[i])
421 GivePlayerItem(i, "weapon_m4a1");
422 else
423 GivePlayerItem(i, "weapon_m4a1_silencer");
424 }
425 GivePlayerItem(i, "weapon_hkp2000");
426 }
427 else
428 {
429 if(!pistols)
430 {
431 GivePlayerItem(i, "weapon_ak47");
432 }
433 GivePlayerItem(i, "weapon_glock");
434 }
435 }
436 }
437 }
438 //Create walls for current site
439 for (int i = 0; i < gi_WallsCounter; i++)
440 {
441 if(g_Walls[i][Site] == site)
442 {
443 CreateCrateWall(i);
444 }
445 }
446 }
447 else if (gb_EditMode)
448 {
449 int color[4];
450 for (int i = 0; i < gi_WallsCounter; i++)
451 {
452 if(g_Walls[i][Site] == SITEA && (gi_WallsToShow == 2 || gi_WallsToShow == SITEA))
453 {
454 color[0] = 255;
455 color[1] = 0;
456 color[2] = 0;
457 color[3] = 255;
458 CreateCrateWall(i, color);
459 }
460 else if(g_Walls[i][Site] == SITEB && (gi_WallsToShow == 2 || gi_WallsToShow == SITEB))
461 {
462 color[0] = 0;
463 color[1] = 0;
464 color[2] = 255;
465 color[3] = 255;
466 CreateCrateWall(i, color);
467 }
468 }
469 }
470}
471
472public Action Event_OnRoundEnd(Event event, const char[] name, bool dontBroadcast)
473{
474 if(!gb_EditMode)
475 {
476 gb_balancedTeams = true;
477 if(GetEventInt(event, "winner") == 2)
478 {
479 gi_WinRow = 0;
480 //Move top Killers to CT
481 int FragList[MAXPLAYERS + 1];
482 int IndexList[MAXPLAYERS + 1];
483 int count = 0;
484 int ctCount = GetCtBalanceCount();
485 for (int i = 1; i <= MaxClients; i++)
486 {
487 if(IsClientInGame(i))
488 {
489 if(GetClientTeam(i) == 2)
490 {
491 FragList[count] = gi_DamageCount[i];
492 IndexList[count] = i;
493 count++;
494 }
495 else if (GetClientTeam(i) == 3)
496 {
497 gi_NextRoundTeam[i] = 2;
498 }
499 }
500 }
501 int temp;
502 int temp2;
503 for (int i = 0; i < count; i++)
504 {
505 for (int j = i+1; j < count; j++)
506 {
507 if(FragList[i] < FragList[j])
508 {
509 temp = FragList[i];
510 temp2 = IndexList[i];
511 FragList[i] = FragList[j];
512 IndexList[i] = IndexList[j];
513 FragList[j] = temp;
514 IndexList[j] = temp2;
515 }
516 }
517 }
518 for (int i = 0; i < ctCount; i++)
519 {
520 gi_NextRoundTeam[IndexList[i]] = 3;
521 }
522 }
523 else if (GetEventInt(event, "winner") == 3)
524 {
525 for (int i = 1; i < MaxClients; i++)
526 {
527 if(IsClientInGame(i) && gi_NextRoundTeam[i] == -1)
528 {
529 gi_NextRoundTeam[i] = GetClientTeam(i);
530 }
531 }
532 gi_WinRow++;
533 if(gi_WinRow > 3)
534 {
535 PrintToChatAll("%sThe ct's has %d win row", PREFIX, gi_WinRow);
536 }
537 }
538 }
539 SetQueueClients();
540}
541
542void BalanceTeams()
543{
544 //Balance Team if not Balanced
545 int ctCount = GetCtBalanceCount();
546 if(ctCount < GetNextTeamCount(3, true))
547 {
548 int DamageList[MAXPLAYERS + 1];
549 int IndexList[MAXPLAYERS + 1];
550 int count = 0;
551 for (int i = 1; i <= MaxClients; i++)
552 {
553 if(IsClientInGame(i) && GetClientTeam(i) == 3)
554 {
555 DamageList[count] = GetClientFrags(i);
556 IndexList[count] = i;
557 count++;
558 }
559 }
560 int temp;
561 int temp2;
562 for (int i = 0; i < count; i++)
563 {
564 for (int j = i+1; j < count; j++)
565 {
566 if(DamageList[i] < DamageList[j])
567 {
568 temp = DamageList[i];
569 temp2 = IndexList[i];
570 DamageList[i] = DamageList[j];
571 IndexList[i] = IndexList[j];
572 DamageList[j] = temp;
573 IndexList[j] = temp2;
574 }
575 }
576 }
577 for (int i = 0; i < GetNextTeamCount(3, true) - ctCount; i++)
578 {
579 gi_NextRoundTeam[IndexList[i]] = 2;
580 }
581 }
582 else if(ctCount > GetNextTeamCount(3, true))
583 {
584 int DamageList[MAXPLAYERS + 1];
585 int IndexList[MAXPLAYERS + 1];
586 int count = 0;
587 for (int i = 1; i <= MaxClients; i++)
588 {
589 if(IsClientInGame(i) && GetClientTeam(i) == 2)
590 {
591 DamageList[count] = GetClientFrags(i);
592 IndexList[count] = i;
593 count++;
594 }
595 }
596 int temp;
597 int temp2;
598 for (int i = 0; i < count; i++)
599 {
600 for (int j = i+1; j < count; j++)
601 {
602 if(DamageList[i] > DamageList[j])
603 {
604 temp = DamageList[i];
605 temp2 = IndexList[i];
606 DamageList[i] = DamageList[j];
607 IndexList[i] = IndexList[j];
608 DamageList[j] = temp;
609 IndexList[j] = temp2;
610 }
611 }
612 }
613 for (int i = 0; i < ctCount - GetNextTeamCount(3, true); i++)
614 {
615 gi_NextRoundTeam[IndexList[i]] = 3;
616 }
617 }
618}
619
620void ScrambleTeams()
621{
622 PrintToChatAll("%sScrambling Teams", PREFIX);
623 int ctCount = RoundToFloor(GetClientCountFix(false) / 2.0);
624 if(ctCount > 3)
625 ctCount = 3;
626 int randomPlayer = -1;
627 for (int i = 0; i < ctCount; i++)
628 {
629 randomPlayer = GetRandomPlayer();
630 if(randomPlayer != -1)
631 gi_NextRoundTeam[randomPlayer] = 3;
632 }
633 int tCount = 0;
634 for (int i = 1; i < MaxClients && tCount < 5; i++)
635 {
636 if(IsClientInGame(i) && gi_NextRoundTeam[i] != 3)
637 {
638 gi_NextRoundTeam[i] = 2;
639 tCount++;
640 }
641 }
642 gb_balancedTeams = true;
643}
644
645void SetQueueClients()
646{
647 for (int i = 1; i <= MaxClients; i++)
648 {
649 if(IsClientInGame(i) && gi_NextRoundTeam[i] == -1)
650 {
651 gi_NextRoundTeam[i] = GetClientTeam(i);
652 }
653 }
654 int terror = GetNextTeamCount(2);
655 int ct = GetNextTeamCount(3);
656 if(terror == 0 && ct == 0)
657 {
658 terror = GetTeamClientCount(2);
659 ct = GetTeamClientCount(3);
660 }
661 int counter = gi_QueueCounter;
662 int[] queue = new int[counter];
663 for (int i = 0; i < counter; i++)
664 {
665 queue[i] = gi_PlayerQueue[i];
666 }
667 for (int i = 0; i < counter; i++)
668 {
669 if(IsClientInGame(queue[i]))
670 {
671 if(terror > ct && ct < 3)
672 {
673 ChangeClientTeam(queue[i], 3);
674 ct++;
675 DeletePlayerFromQueue(i);
676 gb_newClientsJoined = true;
677 }
678 else if(terror < 5)
679 {
680 ChangeClientTeam(queue[i], 2);
681 terror++;
682 DeletePlayerFromQueue(i);
683 gb_newClientsJoined = true;
684 }
685 }
686 }
687}
688
689stock int GetRandomPlayer()
690{
691 int iClients[MAXPLAYERS + 1];
692 int numClients;
693
694 for (int i = 1; i < MaxClients; i++)
695 {
696 if(IsClientInGame(i) && !IsClientSourceTV(i) && gi_NextRoundTeam[i] == -1 && GetClientTeam(i) != 1)
697 {
698 iClients[numClients] = i;
699 numClients++;
700 }
701 }
702
703 if (numClients)
704 {
705 return iClients[GetRandomInt(0, numClients-1)];
706 }
707 return -1;
708}
709
710stock int GetRandomAwpPlayer(int team)
711{
712 int iClients[MAXPLAYERS + 1];
713 int numClients;
714
715 for (int i = 1; i < MaxClients; i++)
716 {
717 if(IsClientInGame(i) && !IsClientSourceTV(i) && gi_WantAwp[i] > 0 && GetClientTeam(i) == team)
718 {
719 iClients[numClients] = i;
720 numClients++;
721 }
722 }
723
724 if(numClients)
725 {
726 int awp = iClients[GetRandomInt(0, numClients-1)];
727 if(gi_WantAwp[awp] == 2 && GetRandomInt(0, 1) == 1)
728 {
729 numClients = 0;
730 for (int i = 1; i < MaxClients; i++)
731 {
732 if(IsClientInGame(i) && !IsClientSourceTV(i) && gi_WantAwp[i] == 1 && GetClientTeam(i) == team)
733 {
734 iClients[numClients] = i;
735 numClients++;
736 }
737 }
738 if(numClients)
739 {
740 return iClients[GetRandomInt(0, numClients-1)];
741 }
742 return -1;
743 }
744 return awp;
745 }
746 return -1;
747}
748
749stock int GetRandomPlayerFromTeam(int team)
750{
751 int iClients[MAXPLAYERS + 1];
752 int numClients = 0;
753
754 for (int i = 1; i < MaxClients; i++)
755 {
756 if(IsClientInGame(i) && !IsClientSourceTV(i) && GetClientTeam(i) == team)
757 {
758 iClients[numClients] = i;
759 numClients++;
760 }
761 }
762
763 if (numClients)
764 {
765 return iClients[GetRandomInt(0, numClients-1)];
766 }
767 return -1;
768}
769
770stock int GetClientCountFix(bool includespec = true)
771{
772 int counter = 0;
773 for (int i = 1; i <= MaxClients; i++)
774 {
775 if(IsClientInGame(i) && !IsClientSourceTV(i) && (includespec || GetClientTeam(i) != 1))
776 {
777 counter++;
778 }
779 }
780 return counter;
781}
782
783stock int GetRandomGrenadeSet(int team)
784{
785 int iSets[MAXPLAYERS + 1];
786 int numSets;
787
788 if(team == 3)
789 {
790 for (int i = 0; i < GRENADESSETCTCOUNT; i++)
791 {
792 if(!gb_CTGrenadeSetsFlags[i])
793 {
794 iSets[numSets] = i;
795 numSets++;
796 }
797 }
798 }
799 else
800 {
801 for (int i = 0; i < GRENADESSETTCOUNT; i++)
802 {
803 if(!gb_TGrenadeSetsFlags[i])
804 {
805 iSets[numSets] = i;
806 numSets++;
807 }
808 }
809 }
810
811 if (numSets)
812 {
813 return iSets[GetRandomInt(0, numSets-1)];
814 }
815 return -1;
816}
817
818public Action Event_OnFullConnect(Event event, const char[] name, bool dontBroadcast)
819{
820 if(!gb_EditMode && !gb_WarmUp)
821 {
822 int client = GetClientOfUserId(GetEventInt(event, "userid"));
823 if(GetClientCountFix() > 1)
824 {
825 SetEntPropFloat(client, Prop_Send, "m_fForceTeam", 3600.0);
826 ChangeClientTeam(client, 1);
827 AddPlayerToQueue(client);
828 }
829 if(!gb_PreferenceLoaded[client])
830 {
831 Command_Guns(client, 0);
832 }
833 }
834}
835
836public void OnClientDisconnect_Post(int client)
837{
838 if(!gb_WaitForPlayers && GetClientCountFix() < 2 && !gb_WarmUp)
839 {
840 gb_WaitForPlayers = true;
841 SetConfig(true);
842 ServerCommand("mp_restartgame 1");
843 }
844 gb_PreferenceLoaded[client] = false;
845 int index = -1;
846 for (int i = 0; i < gi_QueueCounter; i++)
847 {
848 if(client == gi_PlayerQueue[i])
849 {
850 index = i;
851 break;
852 }
853 }
854 if(index != -1)
855 {
856 DeletePlayerFromQueue(index);
857 }
858}
859
860stock int GetCtBalanceCount(bool includespec = false)
861{
862 int ctCount = RoundToFloor(GetClientCountFix(includespec) / 2.0);
863 if(ctCount > 3)
864 ctCount = 3;
865 return ctCount;
866}
867
868stock int GetNextTeamCount(int team, bool next = true)
869{
870 if(!next)
871 return GetTeamClientCount(team);
872 int count = 0;
873 for (int i = 1; i < MaxClients; i++)
874 {
875 if(gi_NextRoundTeam[i] == team)
876 count++;
877 }
878 return count;
879}
880
881void AddPlayerToQueue(int client)
882{
883 gi_PlayerQueue[gi_QueueCounter] = client;
884 gi_QueueCounter++;
885 PrintToChat(client, "%sYou are now \x02%d\x04 place in the queue", PREFIX, gi_QueueCounter);
886 if(gi_QueueCounter == MAXPLAYERS)
887 {
888 gi_QueueCounter = 0;
889 }
890}
891
892void DeletePlayerFromQueue(int index)
893{
894 for (int i = index+1; i < gi_QueueCounter; i++)
895 {
896 gi_PlayerQueue[i-1] = gi_PlayerQueue[i];
897 }
898 gi_QueueCounter--;
899 if(gi_QueueCounter < 0)
900 {
901 gi_QueueCounter = 0;
902 }
903}
904
905public Action Event_OnPlayerChangeTeam(Event event, const char[] name, bool dontBroadcast)
906{
907 dontBroadcast = true;
908 if(gb_WaitForPlayers && !gb_WarmUp)
909 {
910 if(GetClientCountFix() >= 2)
911 {
912 gb_WaitForPlayers = false;
913 ServerCommand("mp_restartgame 5");
914 SetConfig(false);
915 }
916 else
917 {
918 PrintToChatAll("%sWaiting for players to join", PREFIX);
919 }
920 }
921 return Plugin_Changed;
922}
923
924public Action Event_OnPlayerDamged(Event event, const char[] name, bool dontBroadcast)
925{
926 int attacker = GetClientOfUserId(GetEventInt(event, "attacker"));
927 int dhealth = GetEventInt(event, "dmg_health");
928 gi_DamageCount[attacker] += dhealth;
929}
930
931public Action Event_PlayerDeath(Event event, const char[] name, bool dontBroadcast)
932{
933 if(!gb_EditMode)
934 {
935 int attacker = GetClientOfUserId(GetEventInt(event, "attacker"));
936 gi_DamageCount[attacker]++;
937 }
938}
939
940public Action Hook_ChangeTeam(int client, const char[] command, int argc)
941{
942 if(!gb_EditMode && !gb_WaitForPlayers && !gb_WarmUp)
943 return Plugin_Stop;
944 return Plugin_Changed;
945}
946
947public Action Command_Say(int client, const char[] command, int argc)
948{
949 char sText[192];
950 GetCmdArgString(sText, sizeof(sText));
951 StripQuotes(sText);
952 if(StrEqual(sText, "guns") || StrEqual(sText, "weapons") || StrEqual(sText, "weps"))
953 {
954 Command_Guns(client, 0);
955 return Plugin_Handled;
956 }
957 return Plugin_Continue;
958}
959
960public Action Command_Guns(int client, int args)
961{
962 Handle menu = CreateMenu(MenuHandler_M4, MENU_ACTIONS_ALL);
963 SetMenuTitle(menu, "Choose Ct Weapon:");
964 AddMenuItem(menu, "0", "M4A4");
965 AddMenuItem(menu, "1", "M4A1-S");
966 DisplayMenu(menu, client, MENU_TIME_FOREVER);
967 return Plugin_Handled;
968}
969
970public int MenuHandler_M4(Handle menu, MenuAction action, int param1, int param2)
971{
972 if(action == MenuAction_Select)
973 {
974 char sArg[6];
975 GetMenuItem(menu, param2, sArg, sizeof(sArg));
976 gb_WantSilencer[param1] = view_as<bool>(StringToInt(sArg));
977 int convInt = gb_WantSilencer[param1] ? 1 : 0;
978 char buffer[16];
979 IntToString(convInt, buffer, sizeof(buffer));
980 SetClientCookie(param1, gh_SilencedM4, buffer);
981
982 Handle hmenu = CreateMenu(MenuHandler_Awp, MENU_ACTIONS_ALL);
983 SetMenuTitle(hmenu, "Do you want to play with Awp:");
984 AddMenuItem(hmenu, "1", "Always");
985 AddMenuItem(hmenu, "2", "Sometimes");
986 AddMenuItem(hmenu, "0", "Never");
987 DisplayMenu(hmenu, param1, MENU_TIME_FOREVER);
988 }
989}
990
991public int MenuHandler_Awp(Handle menu, MenuAction action, int param1, int param2)
992{
993 if(action == MenuAction_Select)
994 {
995 char sArg[6];
996 GetMenuItem(menu, param2, sArg, sizeof(sArg));
997 gi_WantAwp[param1] = StringToInt(sArg);
998 char buffer[16];
999 IntToString(gi_WantAwp[param1], buffer, sizeof(buffer));
1000 SetClientCookie(param1, gh_WantAwp, buffer);
1001 if(gi_WantAwp[param1] != 0)
1002 {
1003 Handle hmenu = CreateMenu(MenuHandler_Pistol, MENU_ACTIONS_ALL);
1004 SetMenuTitle(hmenu, "Which Pistol you want with Awp:");
1005 AddMenuItem(hmenu, "0", "P2000/Glock");
1006 if(gi_CzChancePercent == 100)
1007 AddMenuItem(hmenu, "1", "CZ275");
1008 else if(gi_CzChancePercent > 0)
1009 AddMenuItem(hmenu, "1", "CZ275/P250");
1010 AddMenuItem(hmenu, "2", "P250");
1011 DisplayMenu(hmenu, param1, MENU_TIME_FOREVER);
1012 }
1013 }
1014}
1015
1016public int MenuHandler_Pistol(Handle menu, MenuAction action, int param1, int param2)
1017{
1018 if(action == MenuAction_Select)
1019 {
1020 char sArg[6];
1021 GetMenuItem(menu, param2, sArg, sizeof(sArg));
1022 gi_PistolPrefence[param1] = StringToInt(sArg);
1023 char buffer[16];
1024 IntToString(gi_PistolPrefence[param1], buffer, sizeof(buffer));
1025 SetClientCookie(param1, gh_PistolPrefence, buffer);
1026 }
1027}
1028
1029public Action Command_AddWall(int client, int args)
1030{
1031 RestartWallEditor(client);
1032 g_WallEditors[client][Step] = 1;
1033 DisplaySelectPointMenu(client, 1);
1034 return Plugin_Handled;
1035}
1036
1037public Action Command_DeleteWall(int client, int args)
1038{
1039 float vec[3];
1040 GetCollisionPoint(client, vec);
1041 float Cords[3];
1042 float Size[3];
1043 int index = -1;
1044 float minDistance;
1045 float Distance;
1046 for (int i = 0; i < gi_WallsCounter; i++)
1047 {
1048 for (int k = 0; k < 3; k++)
1049 {
1050 if(g_Walls[i][Point1][k] > g_Walls[i][Point2][k])
1051 {
1052 Cords[k] = g_Walls[i][Point2][k];
1053 Size[k] = g_Walls[i][Point1][k] - g_Walls[i][Point2][k];
1054 }
1055 else
1056 {
1057 Cords[k] = g_Walls[i][Point1][k];
1058 Size[k] = g_Walls[i][Point2][k] - g_Walls[i][Point1][k];
1059 }
1060 }
1061 Distance = GetVectorDistance(Cords, vec);
1062 if(((vec[0] >= Cords[0] && vec[0] <= Cords[0] + Size[0]) || vec[1] >= Cords[1] && vec[1] <= Cords[1] + Size[1]) && (index == -1 || minDistance > Distance))
1063 {
1064 index = i;
1065 minDistance = Distance;
1066 }
1067 }
1068 if(index == -1)
1069 {
1070 PrintToChat(client, "%sYou need to look at wall to delete", PREFIX);
1071 }
1072 else
1073 {
1074 char sQuery[64];
1075 FormatEx(sQuery, sizeof(sQuery), "DELETE FROM walls WHERE id = %d", g_Walls[index][Id]);
1076 SQL_TQuery(gh_Sql, DeleteWallCallBack, sQuery, client, DBPrio_High);
1077 }
1078 return Plugin_Handled;
1079}
1080
1081public Action Command_Edit(int client, int args)
1082{
1083 gb_EditMode = !gb_EditMode;
1084 PrintToChatAll("%sEdit mode is now %s", PREFIX, gb_EditMode ? "Enabled":"Disabled");
1085 SetConfig(gb_EditMode);
1086 ServerCommand("mp_restartgame 1");
1087 return Plugin_Handled;
1088}
1089
1090public void DeleteWallCallBack(Handle owner, Handle hndl, const char[] error, any data)
1091{
1092 if (hndl == INVALID_HANDLE)
1093 {
1094 LogError("SQL Error on DeleteWall: %s", error);
1095 return;
1096 }
1097
1098 LoadWalls();
1099
1100 if (IsClientInGame(data))
1101 {
1102 PrintToChat(data, "%sDeleted wall", PREFIX);
1103 }
1104}
1105
1106public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3], float angles[3], int &weapon, int &subtype, int &cmdnum, int &tickcount, int &seed, int mouse[2])
1107{
1108 static PressedUse[MAXPLAYERS+1];
1109 if (buttons & IN_USE)
1110 {
1111 if (!PressedUse[client] && g_WallEditors[client][Step] != 0)
1112 {
1113 if (g_WallEditors[client][Step] == 1)
1114 {
1115 float vOrigin[3];
1116 GetCollisionPoint(client, vOrigin);
1117 g_WallEditors[client][Point1] = vOrigin;
1118 g_WallEditors[client][Step] = 2;
1119 CreateTimer(0.1, DrawAdminBox, GetClientSerial(client), TIMER_REPEAT);
1120 DisplaySelectPointMenu(client, 2);
1121 }
1122 else if (g_WallEditors[client][Step] == 2)
1123 {
1124 float vOrigin[3];
1125 GetCollisionPoint(client, vOrigin);
1126 g_WallEditors[client][Point2][0] = g_WallEditors[client][Point1][0];
1127 g_WallEditors[client][Point2][1] = g_WallEditors[client][Point1][1];
1128 g_WallEditors[client][Point2][2] = vOrigin[2];
1129 g_WallEditors[client][Step] = 3;
1130 DisplaySelectPointMenu(client, 3);
1131 }
1132 else if (g_WallEditors[client][Step] == 3)
1133 {
1134 float vOrigin[3];
1135 GetCollisionPoint(client, vOrigin);
1136 g_WallEditors[client][Point2][0] = vOrigin[0];
1137 g_WallEditors[client][Point2][1] = vOrigin[1];
1138 g_WallEditors[client][Step] = 4;
1139 if(!gb_BRush)
1140 DisplaySelectSiteMenu(client);
1141 else
1142 {
1143 AddWall(client, SITEB);
1144 }
1145 }
1146 }
1147 PressedUse[client] = true;
1148 }
1149 else
1150 {
1151 PressedUse[client] = false;
1152 }
1153}
1154
1155void DisplaySelectSiteMenu(int client)
1156{
1157 Handle menu = CreateMenu(MenuHandler_Site);
1158 SetMenuTitle(menu, "Select Site:");
1159 AddMenuItem(menu, "0", "A");
1160 AddMenuItem(menu, "1", "B");
1161 SetMenuExitButton(menu, true);
1162 DisplayMenu(menu, client, MENU_TIME_FOREVER);
1163}
1164
1165public int MenuHandler_Site(Handle menu, MenuAction action, int param1, int param2)
1166{
1167 if(action == MenuAction_Select)
1168 {
1169 char sArg[6];
1170 GetMenuItem(menu, param2, sArg, sizeof(sArg));
1171 AddWall(param1, StringToInt(sArg));
1172 }
1173}
1174
1175void AddWall(int client, int site)
1176{
1177 char sQuery[512];
1178 FormatEx(sQuery, sizeof(sQuery), "INSERT INTO walls (map, site, pos1_x, pos1_y, pos1_z, pos2_x, pos2_y, pos2_z) VALUES ('%s', '%d', %f, %f, %f, %f, %f, %f);", gs_CurrentMap, site, g_WallEditors[client][Point1][0], g_WallEditors[client][Point1][1], g_WallEditors[client][Point1][2], g_WallEditors[client][Point2][0], g_WallEditors[client][Point2][1], g_WallEditors[client][Point2][2]);
1179 SQL_TQuery(gh_Sql, AddWallCallback, sQuery, _, DBPrio_Normal);
1180 RestartWallEditor(client);
1181}
1182
1183public void AddWallCallback(Handle owner, Handle hndl, const char[] error, any data)
1184{
1185 if (hndl == INVALID_HANDLE)
1186 {
1187 LogError("SQL Error on AddSpawn: %s", error);
1188 return;
1189 }
1190 LoadWalls(true);
1191}
1192
1193void DisplaySelectPointMenu(int client, int n)
1194{
1195 Handle panel = CreatePanel();
1196
1197 char sMessage[255];
1198 char sBuffer[64];
1199 if(n == 1)
1200 strcopy(sBuffer, sizeof(sBuffer), "FIRST LOW");
1201 else if(n == 2)
1202 strcopy(sBuffer, sizeof(sBuffer), "HIGHEST");
1203 else
1204 strcopy(sBuffer, sizeof(sBuffer), "SECOND");
1205
1206 FormatEx(sMessage, sizeof(sMessage), "Please aim at the %s point of the wall,\nand press E", sBuffer);
1207
1208 DrawPanelItem(panel, sMessage, ITEMDRAW_RAWLINE);
1209
1210 FormatEx(sMessage, sizeof(sMessage), "Cancel");
1211 DrawPanelItem(panel, sMessage);
1212
1213 SendPanelToClient(panel, client, PointSelect, 540);
1214 CloseHandle(panel);
1215}
1216
1217public int PointSelect(Handle menu, MenuAction action, int param1, int param2)
1218{
1219 if (action == MenuAction_End)
1220 {
1221 CloseHandle(menu);
1222 }
1223 else if (action == MenuAction_Select)
1224 {
1225 RestartWallEditor(param1);
1226 }
1227}
1228
1229public Action DrawAdminBox(Handle timer, any serial)
1230{
1231 int client = GetClientFromSerial(serial);
1232
1233 if (g_WallEditors[client][Step] == 0)
1234 {
1235 return Plugin_Stop;
1236 }
1237
1238 float a[3];
1239 float b[3];
1240
1241 Array_Copy(g_WallEditors[client][Point1], b, 3);
1242
1243 if (g_WallEditors[client][Step] == 4)
1244 {
1245 Array_Copy(g_WallEditors[client][Point2], a, 3);
1246 }
1247 else if(g_WallEditors[client][Step] == 3)
1248 {
1249 GetCollisionPoint(client, a);
1250 a[2] = g_WallEditors[client][Point2][2];
1251 }
1252 else if(g_WallEditors[client][Step] == 2)
1253 {
1254 GetCollisionPoint(client, a);
1255 a[0] = b[0];
1256 a[1] = b[1];
1257 }
1258
1259 int color[4] = {255, 255, 255, 255};
1260
1261 DrawBox(a, b, 0.1, color, false, g_precacheLaser);
1262 return Plugin_Continue;
1263}
1264
1265void RestartWallEditor(int client)
1266{
1267 g_WallEditors[client][Step] = 0;
1268
1269 for (int i = 0; i < 3; i++)
1270 {
1271 g_WallEditors[client][Point1][i] = 0.0;
1272 g_WallEditors[client][Point2][i] = 0.0;
1273 }
1274}
1275
1276//Thanks to alongub
1277void DrawBox(float fFrom[3], float fTo[3], float fLife, int color[4], bool flat, int laser)
1278{
1279 //initialize tempoary variables bottom front
1280 float fLeftBottomFront[3];
1281 fLeftBottomFront[0] = fFrom[0];
1282 fLeftBottomFront[1] = fFrom[1];
1283 if(flat)
1284 {
1285 fLeftBottomFront[2] = fTo[2]-2;
1286 }
1287 else
1288 {
1289 fLeftBottomFront[2] = fTo[2];
1290 }
1291
1292 float fRightBottomFront[3];
1293 fRightBottomFront[0] = fTo[0];
1294 fRightBottomFront[1] = fFrom[1];
1295 if(flat)
1296 {
1297 fRightBottomFront[2] = fTo[2]-2;
1298 }
1299 else
1300 {
1301 fRightBottomFront[2] = fTo[2];
1302 }
1303
1304 //initialize tempoary variables bottom back
1305 float fLeftBottomBack[3];
1306 fLeftBottomBack[0] = fFrom[0];
1307 fLeftBottomBack[1] = fTo[1];
1308 if(flat)
1309 {
1310 fLeftBottomBack[2] = fTo[2]-2;
1311 }
1312 else
1313 {
1314 fLeftBottomBack[2] = fTo[2];
1315 }
1316
1317 float fRightBottomBack[3];
1318 fRightBottomBack[0] = fTo[0];
1319 fRightBottomBack[1] = fTo[1];
1320 if(flat)
1321 {
1322 fRightBottomBack[2] = fTo[2]-2;
1323 }
1324 else
1325 {
1326 fRightBottomBack[2] = fTo[2];
1327 }
1328
1329 //initialize tempoary variables top front
1330 float lefttopfront[3];
1331 lefttopfront[0] = fFrom[0];
1332 lefttopfront[1] = fFrom[1];
1333 lefttopfront[2] = fFrom[2]+3;
1334
1335
1336 float righttopfront[3];
1337 righttopfront[0] = fTo[0];
1338 righttopfront[1] = fFrom[1];
1339 righttopfront[2] = fFrom[2]+3;
1340
1341
1342 //initialize tempoary variables top back
1343 float fLeftTopBack[3];
1344 fLeftTopBack[0] = fFrom[0];
1345 fLeftTopBack[1] = fTo[1];
1346 fLeftTopBack[2] = fFrom[2]+3;
1347
1348
1349 float fRightTopBack[3];
1350 fRightTopBack[0] = fTo[0];
1351 fRightTopBack[1] = fTo[1];
1352 fRightTopBack[2] = fFrom[2]+3;
1353
1354
1355 //create the box
1356 TE_SetupBeamPoints(righttopfront,lefttopfront,laser,0,0,0,fLife,3.0,3.0,10,0.0,color,0);TE_SendToAll(0.0);//TE_SendToClient(client, 0.0);
1357 TE_SetupBeamPoints(lefttopfront,fLeftTopBack,laser,0,0,0,fLife,3.0,3.0,10,0.0,color,0);TE_SendToAll(0.0);//TE_SendToClient(client, 0.0);
1358 TE_SetupBeamPoints(fLeftTopBack,fRightTopBack,laser,0,0,0,fLife,3.0,3.0,10,0.0,color,0);TE_SendToAll(0.0);//TE_SendToClient(client, 0.0);
1359 TE_SetupBeamPoints(fRightTopBack,righttopfront,laser,0,0,0,fLife,3.0,3.0,10,0.0,color,0);TE_SendToAll(0.0);//TE_SendToClient(client, 0.0);
1360
1361 if(!flat)
1362 {
1363 TE_SetupBeamPoints(fRightBottomBack,fLeftBottomBack,laser,0,0,0,fLife,3.0,3.0,10,0.0,color,0);TE_SendToAll(0.0);//TE_SendToClient(client, 0.0);
1364 TE_SetupBeamPoints(fRightBottomBack,fRightBottomFront,laser,0,0,0,fLife,3.0,3.0,10,0.0,color,0);TE_SendToAll(0.0);//TE_SendToClient(client, 0.0);
1365 TE_SetupBeamPoints(fRightBottomBack,fRightTopBack,laser,0,0,0,fLife,3.0,3.0,10,0.0,color,0);TE_SendToAll(0.0);//TE_SendToClient(client, 0.0);
1366
1367 TE_SetupBeamPoints(fLeftBottomFront,fRightBottomFront,laser,0,0,0,fLife,3.0,3.0,10,0.0,color,0);TE_SendToAll(0.0);//TE_SendToClient(client, 0.0);
1368 TE_SetupBeamPoints(fLeftBottomFront,fLeftBottomBack,laser,0,0,0,fLife,3.0,3.0,10,0.0,color,0);TE_SendToAll(0.0);//TE_SendToClient(client, 0.0);
1369 TE_SetupBeamPoints(fLeftBottomFront,lefttopfront,laser,0,0,0,fLife,3.0,3.0,10,0.0,color,0);TE_SendToAll(0.0);//TE_SendToClient(client, 0.0);
1370
1371 TE_SetupBeamPoints(fRightBottomFront,righttopfront,laser,0,0,0,fLife,3.0,3.0,10,0.0,color,0);TE_SendToAll(0.0);//TE_SendToClient(client, 0.0);
1372 TE_SetupBeamPoints(fLeftBottomBack,fLeftTopBack,laser,0,0,0,fLife,3.0,3.0,10,0.0,color,0);TE_SendToAll(0.0);//TE_SendToClient(client, 0.0);
1373 }
1374}
1375
1376void CreateCrateWall(int index, int color[4] = {255, 255, 255, 255})
1377{
1378 float Cords[3];
1379 float Size[3];
1380 for (int i = 0; i < 3; i++)
1381 {
1382 if(g_Walls[index][Point1][i] > g_Walls[index][Point2][i])
1383 {
1384 Cords[i] = g_Walls[index][Point2][i];
1385 Size[i] = g_Walls[index][Point1][i] - g_Walls[index][Point2][i];
1386 }
1387 else
1388 {
1389 Cords[i] = g_Walls[index][Point1][i];
1390 Size[i] = g_Walls[index][Point2][i] - g_Walls[index][Point1][i];
1391 }
1392 }
1393 //Fix Cords and Size Because Crate spawn in the center and not in the corner
1394 Cords[0] += CRATEWIDTH/2;
1395 Size[0] += CRATEWIDTH/2;
1396
1397 Cords[1] += CRATEWIDTH/2;
1398 Size[1] += CRATEWIDTH/2;
1399
1400 int length[3];
1401 length[0] = RoundToCeil(FloatAbs(Size[0]) / CRATEWIDTH);
1402 length[1] = RoundToCeil(FloatAbs(Size[1]) / CRATEWIDTH);
1403 length[2] = RoundToCeil(FloatAbs(Size[2]) / CRATEHEIGHT);
1404 for (int i = 0; i < 3; i++)
1405 {
1406 if(length[i] == 0)
1407 length[i] = 1;
1408 }
1409
1410 float pos[3];
1411 int ent;
1412 for (int x = 0; x < length[0]; x++)
1413 {
1414 for (int y = 0; y < length[1]; y++)
1415 {
1416 for (int z = 0; z < length[2]; z++)
1417 {
1418 pos[0] = Cords[0] + (x * CRATEWIDTH);
1419 pos[1] = Cords[1] + (y * CRATEWIDTH);
1420 pos[2] = Cords[2] + (z * CRATEHEIGHT);
1421 ent = CreateCrate(pos, color);
1422 if(x == 0 && y == 0 && z == 0)
1423 g_Walls[index][StartEnt] = ent;
1424 }
1425 }
1426 }
1427 g_Walls[index][EndEnt] = ent;
1428}
1429
1430stock int CreateCrate(float pos[3], int color[4])
1431{
1432 int ent = CreateEntityByName("prop_physics_override");
1433 if (ent != -1)
1434 {
1435 DispatchKeyValue(ent, "model", CRATEMODEL);
1436 DispatchKeyValue(ent, "spawnflags", "264");
1437 DispatchSpawn(ent);
1438 TeleportEntity(ent, pos, NULL_VECTOR, NULL_VECTOR);
1439 Entity_SetRenderColor(ent, color[0], color[1], color[2], color[3]);
1440 }
1441 return ent;
1442}
1443
1444stock void GetCollisionPoint(int client, float pos[3])
1445{
1446 float vOrigin[3];
1447 float vAngles[3];
1448
1449 GetClientEyePosition(client, vOrigin);
1450 GetClientEyeAngles(client, vAngles);
1451
1452 Handle trace = TR_TraceRayFilterEx(vOrigin, vAngles, MASK_SOLID, RayType_Infinite, TraceEntityFilterPlayer);
1453
1454 if(TR_DidHit(trace))
1455 {
1456 TR_GetEndPosition(pos, trace);
1457 CloseHandle(trace);
1458
1459 return;
1460 }
1461
1462 CloseHandle(trace);
1463}
1464
1465public bool TraceEntityFilterPlayer(int entity, int contentsMask)
1466{
1467 return entity > MaxClients;
1468}
1469
1470//Sql
1471void ConnectSQL()
1472{
1473 if (gh_Sql != INVALID_HANDLE)
1474 {
1475 CloseHandle(gh_Sql);
1476 }
1477
1478 gh_Sql = INVALID_HANDLE;
1479
1480 if (SQL_CheckConfig("rushes"))
1481 {
1482 SQL_TConnect(ConnectSQLCallback, "rushes");
1483 }
1484}
1485
1486public void ConnectSQLCallback(Handle owner, Handle hndl, const char[] error, any data)
1487{
1488 if (gi_ReconncetCounter >= 5)
1489 {
1490 LogError("PLUGIN STOPPED - Reason: reconnect counter reached max - PLUGIN STOPPED");
1491 return;
1492 }
1493
1494 if (hndl == INVALID_HANDLE)
1495 {
1496 LogError("Connection to SQL database has failed, Reason: %s", error);
1497
1498 gi_ReconncetCounter++;
1499 ConnectSQL();
1500
1501 return;
1502 }
1503
1504 char sDriver[16];
1505 SQL_GetDriverIdent(owner, sDriver, sizeof(sDriver));
1506
1507 gh_Sql = CloneHandle(hndl);
1508
1509 if (StrEqual(sDriver, "mysql", false))
1510 {
1511 SQL_TQuery(gh_Sql, CreateSQLTableCallback, "CREATE TABLE IF NOT EXISTS `walls` (`id` int(11) NOT NULL AUTO_INCREMENT, `site` int(11) NOT NULL, `map` varchar(32) NOT NULL, `pos1_x` float NOT NULL, `pos1_y` float NOT NULL, `pos1_z` float NOT NULL, `pos2_x` float NOT NULL, `pos2_y` float NOT NULL, `pos2_z` float NOT NULL, PRIMARY KEY (`id`));");
1512 }
1513 else if (StrEqual(sDriver, "sqlite", false))
1514 {
1515 SQL_TQuery(gh_Sql, CreateSQLTableCallback, "CREATE TABLE IF NOT EXISTS `walls` (`id` INTEGER PRIMARY KEY, `site` INTEGER NOT NULL, `map` varchar(32) NOT NULL, `pos1_x` float NOT NULL, `pos1_y` float NOT NULL, `pos1_z` float NOT NULL, `pos2_x` float NOT NULL, `pos2_y` float NOT NULL, `pos2_z` float NOT NULL);");
1516 }
1517
1518 gi_ReconncetCounter = 0;
1519}
1520
1521public void CreateSQLTableCallback(Handle owner, Handle hndl, const char[] error, any data)
1522{
1523 if (owner == INVALID_HANDLE)
1524 {
1525 LogError("SQL:Reconnect");
1526 gi_ReconncetCounter++;
1527 ConnectSQL();
1528
1529 return;
1530 }
1531
1532 if (hndl == INVALID_HANDLE)
1533 {
1534 LogError("SQL CreateTable:%s", error);
1535 return;
1536 }
1537
1538 LoadWalls();
1539}
1540
1541void LoadWalls(bool drawlast = false)
1542{
1543 if (gh_Sql == INVALID_HANDLE)
1544 {
1545 ConnectSQL();
1546 }
1547 else
1548 {
1549 char sQuery[384];
1550 FormatEx(sQuery, sizeof(sQuery), "SELECT id, site, pos1_x, pos1_y, pos1_z, pos2_x, pos2_y, pos2_z FROM walls WHERE map = '%s'", gs_CurrentMap);
1551 SQL_TQuery(gh_Sql, LoadWallsCallBack, sQuery, drawlast, DBPrio_High);
1552 }
1553}
1554
1555public void LoadWallsCallBack(Handle owner, Handle hndl, const char[] error, any data)
1556{
1557 if (hndl == INVALID_HANDLE)
1558 {
1559 LogError("SQL Error on LoadWalls: %s", error);
1560 return;
1561 }
1562
1563 gi_WallsCounter = 0;
1564 while (SQL_FetchRow(hndl) && gi_WallsCounter < MAXWALLS)
1565 {
1566 g_Walls[gi_WallsCounter][Id] = SQL_FetchInt(hndl, 0);
1567 g_Walls[gi_WallsCounter][Site] = SQL_FetchInt(hndl, 1);
1568 g_Walls[gi_WallsCounter][Point1][0] = SQL_FetchFloat(hndl, 2);
1569 g_Walls[gi_WallsCounter][Point1][1] = SQL_FetchFloat(hndl, 3);
1570 g_Walls[gi_WallsCounter][Point1][2] = SQL_FetchFloat(hndl, 4);
1571 g_Walls[gi_WallsCounter][Point2][0] = SQL_FetchFloat(hndl, 5);
1572 g_Walls[gi_WallsCounter][Point2][1] = SQL_FetchFloat(hndl, 6);
1573 g_Walls[gi_WallsCounter][Point2][2] = SQL_FetchFloat(hndl, 7);
1574
1575 gi_WallsCounter++;
1576 }
1577
1578 if(gi_WallsCounter == 0)
1579 {
1580 gb_EditMode = true;
1581 PrintToChatAll("%sEdit mode is now Enabled becuase there is no walls", PREFIX);
1582 }
1583 else if(data && gb_EditMode)
1584 {
1585 int color[4];
1586 if(g_Walls[gi_WallsCounter-1][Site] == SITEA)
1587 {
1588 color[0] = 255;
1589 color[1] = 0;
1590 color[2] = 0;
1591 color[3] = 255;
1592 }
1593 else
1594 {
1595 color[0] = 0;
1596 color[1] = 0;
1597 color[2] = 255;
1598 color[3] = 255;
1599 }
1600 CreateCrateWall(gi_WallsCounter-1, color);
1601 }
1602}
1603
1604public Action Timer_MapLoadDelay(Handle timer)
1605{
1606 if(GetClientCountFix() >= 2)
1607 {
1608 gb_WaitForPlayers = false;
1609 gb_balancedTeams = false;
1610 ScrambleTeams();
1611 SetConfig(false);
1612 ServerCommand("mp_restartgame 1");
1613 }
1614 else
1615 {
1616 PrintToChatAll("%sWaiting for more players to join", PREFIX);
1617 }
1618 gb_WarmUp = false;
1619}
1620
1621public Action Timer_PrintHintWarmup(Handle timer)
1622{
1623 if(GetEngineTime() - gf_MapLoadTime >= 30)
1624 return Plugin_Stop;
1625 PrintHintTextToAll("\n<font size='22'> Rushes will start in:</font><font size='22' color='#E22C56'>%.00f seconds</font>", 30 - (GetEngineTime() - gf_MapLoadTime));
1626 return Plugin_Continue;
1627}
1628
1629public Action Timer_PrintHintSite(Handle timer, any site)
1630{
1631 if(GetEngineTime() - gf_StartRoundTime >= 3)
1632 return Plugin_Stop;
1633 PrintHintTextToAll(" <font size='22'> <font color = '#01A9DB'>%d CT</font> vs <font color = '#FE2E2E'> %d T</font>\n Rush to Site:<font color='#E22C56'>%s</font></font>", GetTeamClientCount(3), GetTeamClientCount(2), site == SITEA ? "A":"B");
1634 return Plugin_Continue;
1635}
1636
1637void SetConfig(bool warmup)
1638{
1639 ServerCommand("exec rushes.cfg");
1640 if(!warmup)
1641 {
1642 ServerCommand("exec rushes_live.cfg");
1643 }
1644 else
1645 {
1646 ServerCommand("exec rushes_warmup.cfg");
1647 }
1648}