· 3 years ago · Apr 10, 2022, 01:30 PM
1#pragma semicolon 1
2
3#define CVARS FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY
4#define DEFAULT_FLAGS FCVAR_NOTIFY
5#define TAG_CHAT "[SHOW DAMAGE] - "
6#define PLUGIN_VERSION "1.1.2"
7#define MAX_TYPE_WEAPONS 10
8#define MAX_SHOW_DAMAGE_STEAMID 25
9
10#undef REQUIRE_PLUGIN
11#include <sourcemod>
12#include <clientprefs>
13#include <autoexec>
14
15#pragma newdecls required
16
17Handle cvar_active_show_damage;
18Handle cvar_active_show_damage_dev;
19
20Handle cvar_show_damage_sniper_time;
21Handle cvar_show_damage_mg_time;
22Handle cvar_show_damage_rifle_time;
23Handle cvar_show_damage_mp_time;
24Handle cvar_show_damage_pump_time;
25Handle cvar_show_damage_pistol_time;
26
27Handle Array_Victim[MAXPLAYERS + 1];
28Handle Cookie_ShowDamage;
29
30Handle Timer_ShowDamage[MAXPLAYERS + 1];
31
32bool B_active_show_damage = false;
33bool B_active_show_damage_dev = false;
34
35bool B_ShowDamage_SteamID[MAXPLAYERS+1][MAX_TYPE_WEAPONS];
36
37float TimerDamage[MAXPLAYERS + 1];
38
39float F_show_damage_sniper_time;
40float F_show_damage_mg_time;
41float F_show_damage_rifle_time;
42float F_show_damage_mp_time;
43float F_show_damage_pump_time;
44float F_show_damage_pistol_time;
45
46char S_new_weapon[MAXPLAYERS + 1][64];
47char S_old_weapon[MAXPLAYERS + 1][64];
48
49char S_showdamageflag[MAX_TYPE_WEAPONS][64];
50char S_showdamagesteamid[MAX_TYPE_WEAPONS][MAX_SHOW_DAMAGE_STEAMID][64];
51
52int C_CountVictim[MAXPLAYERS + 1] = 1;
53int C_TotalDamage[MAXPLAYERS + 1];
54int C_TotalDamageArmor[MAXPLAYERS + 1];
55C_ShowDamage[MAXPLAYERS + 1];
56
57int max_type_weapons;
58int max_show_damage_steamid[MAX_SHOW_DAMAGE_STEAMID];
59
60public Plugin myinfo =
61{
62 name = "DR.API SHOW DAMAGE",
63 author = "Dr. Api",
64 description = "DR.API SHOW DAMAGE by Dr. Api",
65 version = PLUGIN_VERSION,
66 url = "http://zombie4ever.eu"
67}
68
69public void OnPluginStart()
70{
71 LoadTranslations("drapi/drapi_show_damage.phrases");
72 AutoExecConfig_SetFile("drapi_show_damage", "sourcemod/drapi");
73
74 AutoExecConfig_CreateConVar("aio_show_damage_version", PLUGIN_VERSION, "Version", CVARS);
75
76 cvar_active_show_damage = AutoExecConfig_CreateConVar("drapi_active_show_damage", "1", "Enable/Disable Show Damage", DEFAULT_FLAGS, true, 0.0, true, 1.0);
77 cvar_active_show_damage_dev = AutoExecConfig_CreateConVar("drapi_active_show_damage_dev", "0", "Enable/Disable Show Damage Dev", DEFAULT_FLAGS, true, 0.0, true, 1.0);
78
79 cvar_show_damage_sniper_time = AutoExecConfig_CreateConVar("drapi_show_damage_sniper_time", "0.5", "SNIPERS Time Between shots", DEFAULT_FLAGS);
80 cvar_show_damage_mg_time = AutoExecConfig_CreateConVar("drapi_show_damage_mg_time", "0.5", "MGuns Time Between shots", DEFAULT_FLAGS);
81 cvar_show_damage_rifle_time = AutoExecConfig_CreateConVar("drapi_show_damage_rifle_time", "0.5", "RIFLES Time Between shots", DEFAULT_FLAGS);
82 cvar_show_damage_mp_time = AutoExecConfig_CreateConVar("drapi_show_damage_mp_time", "0.5", "MPs Time Between shots", DEFAULT_FLAGS);
83 cvar_show_damage_pump_time = AutoExecConfig_CreateConVar("drapi_show_damage_pump_time", "0.5", "PUMPS Time Between shots", DEFAULT_FLAGS);
84 cvar_show_damage_pistol_time = AutoExecConfig_CreateConVar("drapi_show_damage_pistol_time", "0.5", "PISTOLS Time Between shots", DEFAULT_FLAGS);
85
86 HookEvents();
87
88 HookEvent("player_hurt", Event_PlayerHurt);
89
90 RegAdminCmd("sm_array", Command_Array, ADMFLAG_CHANGEMAP, "");
91 RegConsoleCmd("sm_sd", Command_BuildMenuShowDamage, "");
92
93 Cookie_ShowDamage = RegClientCookie("Cookie_ShowDamage", "", CookieAccess_Private);
94 int info;
95 SetCookieMenuItem(ShowDamageCookieHandler, info, "Show Damage");
96
97 AutoExecConfig_ExecuteFile();
98
99 int i = 1;
100 while (i <= MaxClients)
101 {
102 if(IsClientInGame(i))
103 {
104 if(Array_Victim[i] == INVALID_HANDLE)
105 {
106 Array_Victim[i] = CreateArray(3);
107 }
108
109 if(AreClientCookiesCached(i))
110 {
111 OnClientCookiesCached(i);
112 }
113 }
114 i++;
115 }
116}
117
118public void OnPluginEnd()
119{
120 int i = 1;
121 while (i <= MaxClients)
122 {
123 if(IsClientInGame(i))
124 {
125 if(Array_Victim[i] != INVALID_HANDLE)
126 {
127 CloseHandle(Array_Victim[i]);
128 Array_Victim[i] = INVALID_HANDLE;
129 }
130 }
131 i++;
132 }
133}
134
135void HookEvents()
136{
137 HookConVarChange(cvar_active_show_damage, Event_CvarChange);
138 HookConVarChange(cvar_active_show_damage_dev, Event_CvarChange);
139
140 HookConVarChange(cvar_show_damage_sniper_time, Event_CvarChange);
141 HookConVarChange(cvar_show_damage_mg_time, Event_CvarChange);
142 HookConVarChange(cvar_show_damage_rifle_time, Event_CvarChange);
143 HookConVarChange(cvar_show_damage_mp_time, Event_CvarChange);
144 HookConVarChange(cvar_show_damage_pump_time, Event_CvarChange);
145 HookConVarChange(cvar_show_damage_pistol_time, Event_CvarChange);
146}
147
148public void Event_CvarChange(Handle cvar, const char[] oldValue, const char[] newValue)
149{
150 UpdateState();
151}
152
153void UpdateState()
154{
155 B_active_show_damage = GetConVarBool(cvar_active_show_damage);
156 B_active_show_damage_dev = GetConVarBool(cvar_active_show_damage_dev);
157
158 F_show_damage_sniper_time = GetConVarFloat(cvar_show_damage_sniper_time);
159 F_show_damage_mg_time = GetConVarFloat(cvar_show_damage_mg_time);
160 F_show_damage_rifle_time = GetConVarFloat(cvar_show_damage_rifle_time);
161 F_show_damage_mp_time = GetConVarFloat(cvar_show_damage_mp_time);
162 F_show_damage_pump_time = GetConVarFloat(cvar_show_damage_pump_time);
163 F_show_damage_pistol_time = GetConVarFloat(cvar_show_damage_pistol_time);
164}
165
166public void OnClientPutInServer(int client)
167{
168 Array_Victim[client] = CreateArray(3);
169}
170
171public void OnClientDisconnect(int client)
172{
173 if(Array_Victim[client] != INVALID_HANDLE)
174 {
175 CloseHandle(Array_Victim[client]);
176 Array_Victim[client] = INVALID_HANDLE;
177 }
178}
179
180public void OnClientCookiesCached(int client)
181{
182 char value[16];
183
184 GetClientCookie(client, Cookie_ShowDamage, value, sizeof(value));
185 if(strlen(value) > 0)
186 {
187 C_ShowDamage[client] = StringToInt(value);
188 }
189 else
190 {
191 C_ShowDamage[client] = 1;
192 }
193}
194
195public void OnConfigsExecuted()
196{
197 LoadSettings();
198}
199
200public void OnMapStart()
201{
202 UpdateState();
203}
204
205public Action Command_BuildMenuShowDamage(int client, int args)
206{
207 BuildMenuShowDamage(client);
208}
209
210public void ShowDamageCookieHandler(int client, CookieMenuAction action, any info, char [] buffer, int maxlen)
211{
212 BuildMenuShowDamage(client);
213}
214
215void BuildMenuShowDamage(int client)
216{
217 char title[40], show_damage[40], status_show_damage[40];
218
219 Menu menu = CreateMenu(MenuShowDamageAction);
220
221 Format(status_show_damage, sizeof(status_show_damage), "%T", (C_ShowDamage[client]) ? "Enabled" : "Disabled", client);
222 Format(show_damage, sizeof(show_damage), "%T", "ShowDamage_HUD_MENU_TITLE", client, status_show_damage);
223 AddMenuItem(menu, "M_show_damage_hud", show_damage);
224
225 Format(title, sizeof(title), "%T", "ShowDamage_TITLE", client);
226 menu.SetTitle(title);
227 SetMenuExitBackButton(menu, true);
228 menu.Display(client, MENU_TIME_FOREVER);
229}
230
231public int MenuShowDamageAction(Menu menu, MenuAction action, int param1, int param2)
232{
233 switch(action)
234 {
235 case MenuAction_End:
236 {
237 CloseHandle(menu);
238 }
239 case MenuAction_Cancel:
240 {
241 if (param2 == MenuCancel_ExitBack)
242 {
243 FakeClientCommand(param1, "sm_settings");
244 }
245 }
246 case MenuAction_Select:
247 {
248 char menu1[56];
249 menu.GetItem(param2, menu1, sizeof(menu1));
250
251 if(StrEqual(menu1, "M_show_damage_hud"))
252 {
253 C_ShowDamage[param1] = !C_ShowDamage[param1];
254 SetClientCookie(param1, Cookie_ShowDamage, (C_ShowDamage[param1]) ? "1" : "0");
255 }
256 BuildMenuShowDamage(param1);
257 }
258 }
259}
260
261public Action Command_Array(int client, int args)
262{
263 /*
264 Handle Array_Test = CreateArray(3);
265 PushArrayCell(Array_Test, 10);
266 PushArrayCell(Array_Test, 10);
267 PushArrayCell(Array_Test, 22);
268 PushArrayCell(Array_Test, 33);
269 PushArrayCell(Array_Test, 33);
270
271 PrintToChat(client, "------FULL SIZE------");
272 for(int i = 0; i <= GetArraySize(Array_Test) - 1; i++)
273 {
274 PrintToChat(client, "%i", GetArrayCell(Array_Test, i));
275 }
276
277 PrintToChat(client, "------REMOVE SIZE------");
278 Array_RemoveDuplicateInt(Array_Test);
279
280 for(int i = 0; i <= GetArraySize(Array_Test) - 1; i++)
281 {
282 PrintToChat(client, "%i", GetArrayCell(Array_Test, i));
283 }
284 */
285
286 /*
287 PrintToChat(client, "------FULL SIZE------");
288 for(int i = 0; i <= GetArraySize(Array_Victim[client]) - 1; i++)
289 {
290 PrintToChat(client, "%i", GetArrayCell(Array_Victim[client], i));
291 }
292 */
293
294 SortADTArray(Array_Victim[client], Sort_Ascending, Sort_Integer);
295
296 PrintToChat(client, "------FULL SIZE------");
297 for(int i = 0; i <= GetArraySize(Array_Victim[client]) - 1; i++)
298 {
299 PrintToChat(client, "%i", GetArrayCell(Array_Victim[client], i));
300 }
301}
302
303public Action Event_PlayerHurt(Handle event, char[] name, bool dontBroadcast)
304{
305 if(B_active_show_damage)
306 {
307 char S_weapon[64];
308
309 int victim = GetClientOfUserId(GetEventInt(event, "userid"));
310 int attacker = GetClientOfUserId(GetEventInt(event, "attacker"));
311 int damage_health = GetEventInt(event, "dmg_health");
312 int damage_armor = GetEventInt(event, "dmg_armor");
313 int hitgroup = GetEventInt(event, "hitgroup");
314 GetEventString(event, "weapon", S_weapon, sizeof(S_weapon));
315
316 if(!C_ShowDamage[attacker]) return;
317
318 if(Client_IsIngame(attacker) && Client_IsIngame(victim))
319 {
320 strcopy(S_new_weapon[attacker], 64, S_weapon);
321
322 float time;
323 int type;
324 if(StrEqual(S_weapon, "inferno", false))
325 {
326 time = GetConVarFloat(FindConVar("inferno_flame_lifetime"));
327 type = 1;
328 }
329
330 //Grenade need at least 1s to catch all victims.
331 else if(StrEqual(S_weapon, "hegrenade", false))
332 {
333 time = 1.0;
334 type = 2;
335 }
336
337 else if(StrEqual(S_weapon, "awp", false)
338 || StrEqual(S_weapon, "ssg08", false)
339 || StrEqual(S_weapon, "sg556", false)
340 || StrEqual(S_weapon, "aug", false)
341 || StrEqual(S_weapon, "scar20", false)
342 || StrEqual(S_weapon, "g3sg1", false)
343 )
344 {
345 time = F_show_damage_sniper_time;
346 type = 3;
347 }
348 else if(StrEqual(S_weapon, "negev", false)
349 || StrEqual(S_weapon, "m249", false)
350 )
351 {
352 time = F_show_damage_mg_time;
353 type = 4;
354 }
355 else if(StrEqual(S_weapon, "m4a1", false)
356 || StrEqual(S_weapon, "ak47", false)
357 || StrEqual(S_weapon, "famas", false)
358 || StrEqual(S_weapon, "galilar", false)
359 )
360 {
361 time = F_show_damage_rifle_time;
362 type = 5;
363 }
364 else if(StrEqual(S_weapon, "p90", false)
365 || StrEqual(S_weapon, "ump45", false)
366 || StrEqual(S_weapon, "mac10", false)
367 || StrEqual(S_weapon, "mp7", false)
368 || StrEqual(S_weapon, "mp9", false)
369 || StrEqual(S_weapon, "bizon", false)
370 )
371 {
372 time = F_show_damage_mp_time;
373 type = 6;
374 }
375 else if(StrEqual(S_weapon, "nova", false)
376 || StrEqual(S_weapon, "sawedoff", false)
377 || StrEqual(S_weapon, "xm1014", false)
378 || StrEqual(S_weapon, "mag7", false)
379 )
380 {
381 time = F_show_damage_pump_time;
382 type = 7;
383 }
384 else if(StrEqual(S_weapon, "hkp2000", false)
385 || StrEqual(S_weapon, "cz75a", false)
386 || StrEqual(S_weapon, "p250", false)
387 || StrEqual(S_weapon, "fiveseven", false)
388 || StrEqual(S_weapon, "deagle", false)
389 || StrEqual(S_weapon, "glock", false)
390 || StrEqual(S_weapon, "tec9", false)
391 || StrEqual(S_weapon, "elite", false)
392 )
393 {
394 time = F_show_damage_pistol_time;
395 type = 8;
396 }
397 else
398 {
399 time = 0.0;
400 type = 9;
401 }
402
403 if(!CheckAccessShowDamage(attacker, type)) return;
404
405 float now = GetEngineTime();
406 if(now >= TimerDamage[attacker] || !StrEqual(S_new_weapon[attacker], S_old_weapon[attacker], false))
407 {
408 C_CountVictim[attacker] = 0;
409 TimerDamage[attacker] = now + time;
410 C_TotalDamage[attacker] = 0;
411 C_TotalDamageArmor[attacker] = 0;
412 S_old_weapon[attacker] = S_new_weapon[attacker];
413 ClearArray(Array_Victim[attacker]);
414 }
415
416 C_TotalDamage[attacker] += damage_health;
417 C_TotalDamageArmor[attacker] += damage_armor;
418
419
420 Handle dataPackHandle;
421 ClearTimer(Timer_ShowDamage[attacker]);
422 Timer_ShowDamage[attacker] = CreateDataTimer(0.0, TimerData_ShowDamage, dataPackHandle);
423 WritePackString(dataPackHandle, S_weapon);
424 WritePackCell(dataPackHandle, GetClientUserId(attacker));
425 WritePackCell(dataPackHandle, GetClientUserId(victim));
426 WritePackCell(dataPackHandle, hitgroup);
427
428 if(Array_Victim[attacker] == INVALID_HANDLE)
429 {
430 Array_Victim[attacker] = CreateArray(3);
431 }
432 PushArrayCell(Array_Victim[attacker], victim);
433 Array_RemoveDuplicateInt(Array_Victim[attacker]);
434 C_CountVictim[attacker] = GetArraySize(Array_Victim[attacker]);
435 }
436 }
437}
438
439public Action TimerData_ShowDamage(Handle timer, Handle dataPackHandle)
440{
441 ResetPack(dataPackHandle);
442
443 char S_weapon[64];
444 ReadPackString(dataPackHandle, S_weapon, sizeof(S_weapon));
445 int attacker = GetClientOfUserId(ReadPackCell(dataPackHandle));
446 int victim = GetClientOfUserId(ReadPackCell(dataPackHandle));
447 int hitgroup = ReadPackCell(dataPackHandle);
448
449 ShowDamage(S_weapon, attacker, victim, hitgroup, C_CountVictim[attacker], C_TotalDamage[attacker], C_TotalDamageArmor[attacker]);
450
451 //PrintToChat(attacker, "%s", S_weapon);
452 //PrintToChat(attacker, "%i, %N", C_CountVictim[attacker], victim);
453 //PrintToChat(attacker, "new:%s, old:%s | %i", S_new_weapon[attacker], S_old_weapon[attacker], C_CountVictim[attacker]);
454}
455
456void ShowDamage(char[] weapon, int attacker, int victim, int hitgroup, int count, int damage_health, int damage_armor)
457{
458 //PrintToChat(attacker, "cookie:%i", C_show_damage[attacker]);
459 /* hitgroup 0 = generic */
460 /* hitgroup 1 = head */
461 /* hitgroup 2 = chest */
462 /* hitgroup 3 = stomach */
463 /* hitgroup 4 = left arm */
464 /* hitgroup 5 = right arm */
465 /* hitgroup 6 = left leg */
466 /* hitgroup 7 = right leg */
467
468 if(count > 1 || StrEqual(weapon, "inferno", false) || StrEqual(weapon, "hegrenade", false))
469 {
470 if(StrEqual(weapon, "inferno", false))
471 {
472 SetHudTextParams(0.24, 0.09, 1.5, 0, 255, 0, 1, 0, 0.0, 0.0, 0.2);
473 ShowHudText(attacker, 5, "%t", "Show damage inferno", count, damage_health, damage_armor);
474 }
475 else if(StrEqual(weapon, "hegrenade", false))
476 {
477 SetHudTextParams(0.24, 0.09, 1.5, 0, 255, 0, 1, 0, 0.0, 0.0, 0.2);
478 ShowHudText(attacker, 5, "%t", "Show damage hegrenade", count, damage_health, damage_armor);
479 }
480 else
481 {
482 SetHudTextParams(0.24, 0.09, 1.5, 0, 255, 0, 1, 0, 0.0, 0.0, 0.2);
483 ShowHudText(attacker, 5, "%t", "Show damage multiple", weapon, count, damage_health, damage_armor);
484 }
485 }
486 else
487 {
488 char S_hitgroup_message[256];
489 switch(hitgroup)
490 {
491 case 0:
492 {
493 S_hitgroup_message = "";
494 }
495 case 1:
496 {
497 //S_hitgroup_message = "Head";
498 Format(S_hitgroup_message, sizeof(S_hitgroup_message), "%T", "Head", attacker);
499 }
500 case 2:
501 {
502 //S_hitgroup_message = "Chest";
503 Format(S_hitgroup_message, sizeof(S_hitgroup_message), "%T", "Chest", attacker);
504 }
505 case 3:
506 {
507 //S_hitgroup_message = "Stomach";
508 Format(S_hitgroup_message, sizeof(S_hitgroup_message), "%T", "Stomach", attacker);
509 }
510 case 4:
511 {
512 //S_hitgroup_message = "Left arm";
513 Format(S_hitgroup_message, sizeof(S_hitgroup_message), "%T", "Left arm", attacker);
514 }
515 case 5:
516 {
517 //S_hitgroup_message = "Right arm";
518 Format(S_hitgroup_message, sizeof(S_hitgroup_message), "%T", "Right arm", attacker);
519 }
520 case 6:
521 {
522 //S_hitgroup_message = "Left leg";
523 Format(S_hitgroup_message, sizeof(S_hitgroup_message), "%T", "Left leg", attacker);
524 }
525 case 7:
526 {
527 //S_hitgroup_message = "Right leg";
528 Format(S_hitgroup_message, sizeof(S_hitgroup_message), "%T", "Right leg", attacker);
529 }
530 }
531
532 if(Client_IsIngame(attacker) && Client_IsIngame(victim) && attacker != victim && GetClientTeam(attacker) != GetClientTeam(victim))
533 {
534 if(strlen(S_hitgroup_message))
535 {
536 SetHudTextParams(0.24, 0.09, 1.5, 0, 255, 0, 1, 0, 0.0, 0.0, 0.2);
537 ShowHudText(attacker, 5, "%t", "Show damage hit message body", S_hitgroup_message, damage_health, damage_armor);
538 }
539 else
540 {
541 SetHudTextParams(0.24, 0.09, 1.5, 0, 255, 0, 1, 0, 0.0, 0.0, 0.2);
542 ShowHudText(attacker, 5, "%t", "Show damage hit message", damage_health, damage_armor);
543 }
544 }
545 }
546 Timer_ShowDamage[attacker] = INVALID_HANDLE;
547}
548
549bool CheckAccessShowDamage(int client, int type)
550{
551 char S_steamid[64];
552 GetClientAuthId(client, AuthId_Steam2, S_steamid, sizeof(S_steamid));
553
554 for(int steamid = 1; steamid <= max_show_damage_steamid[type]; ++steamid)
555 {
556
557 if(StrEqual(S_showdamagesteamid[type][steamid], S_steamid ,false))
558 {
559 B_ShowDamage_SteamID[client][type] = true;
560 }
561 }
562
563 if( (B_ShowDamage_SteamID[client][type] == true && StrEqual(S_showdamageflag[type], "steamid", false)) //Steamid only
564 || (IsAdminEx(client) && StrEqual(S_showdamageflag[type], "admin", false) || B_ShowDamage_SteamID[client][type] == true) //Admin + steamid
565 || ( (IsVip(client)|| IsAdminEx(client)) && StrEqual(S_showdamageflag[type], "vip", false) || B_ShowDamage_SteamID[client][type] == true) //Vip + steamid
566 || StrEqual(S_showdamageflag[type], "public", false) ) //Public
567 {
568 return true;
569 }
570 else
571 {
572 return false;
573 }
574}
575
576public void LoadSettings()
577{
578 char hc[PLATFORM_MAX_PATH];
579 BuildPath(Path_SM, hc, sizeof(hc), "configs/drapi/show_damage.cfg");
580
581 Handle kv = CreateKeyValues("ShowDamage");
582 FileToKeyValues(kv, hc);
583
584 max_type_weapons = 1;
585
586 if(KvGotoFirstSubKey(kv))
587 {
588 do
589 {
590 if(KvJumpToKey(kv, "ShowDamageAccess"))
591 {
592 if(KvGotoFirstSubKey(kv))
593 {
594 do
595 {
596 char S_info[3];
597 if(KvGetSectionName(kv, S_info, 3))
598 {
599 KvGetString(kv, "flags", S_showdamageflag[max_type_weapons], 64);
600
601 max_show_damage_steamid[max_type_weapons] = 1;
602
603 if(KvJumpToKey(kv, "SteamIDs"))
604 {
605 for(int i = 1; i <= MAX_SHOW_DAMAGE_STEAMID; ++i)
606 {
607 char key[3];
608 IntToString(i, key, 3);
609
610 if(KvGetString(kv, key, S_showdamagesteamid[max_type_weapons][i], 64) && strlen(S_showdamagesteamid[max_type_weapons][i]))
611 {
612 if(B_active_show_damage_dev)
613 {
614 LogMessage("%s [%i] - ID: %i, STEAMID: %s", TAG_CHAT, max_type_weapons, i, S_showdamagesteamid[max_type_weapons][i]);
615 }
616 max_show_damage_steamid[max_type_weapons] = i;
617 }
618 else
619 {
620 break;
621 }
622
623 }
624 KvGoBack(kv);
625 }
626
627 if(B_active_show_damage_dev)
628 {
629 LogMessage("%s, %s", S_info, S_showdamageflag[max_type_weapons]);
630 }
631 max_type_weapons++;
632 }
633 }
634 while (KvGotoNextKey(kv));
635 }
636 }
637
638 }
639 while (KvGotoNextKey(kv));
640 }
641 CloseHandle(kv);
642
643}
644
645stock bool Client_IsValid(int client, bool checkConnected=true)
646{
647 if (client > 4096)
648 {
649 client = EntRefToEntIndex(client);
650 }
651
652 if (client < 1 || client > MaxClients)
653 {
654 return false;
655 }
656
657 if (checkConnected && !IsClientConnected(client))
658 {
659 return false;
660 }
661
662 return true;
663}
664
665stock bool Client_IsIngame(int client)
666{
667 if (!Client_IsValid(client, false))
668 {
669 return false;
670 }
671
672 return IsClientInGame(client);
673}
674
675stock void Array_RemoveDuplicateInt(Handle array, bool sorted = false)
676{
677 // Sort array if not sorted.
678 if (!sorted)
679 {
680 // Sort the array so duplicate entries will be next to eachother.
681 SortADTArray(array, Sort_Ascending, Sort_Integer);
682 }
683
684 int len = GetArraySize(array);
685 if (len < 2)
686 {
687 // Arrays with one or zero elements can't have duplicates.
688 return;
689 }
690
691 int currentVal;
692 int lastVal = GetArrayCell(array, len - 1);
693
694 // Iterate backwards through elements and remove duplicates. Elements are
695 // removed at the end first so that minimal amount of elements must be
696 // shifted.
697 for (int i = len - 2; i >= 0; i--)
698 {
699 currentVal = GetArrayCell(array, i);
700 if (lastVal == currentVal)
701 {
702 // Remove last duplicate (the one after this).
703 RemoveFromArray(array, i + 1);
704 }
705 lastVal = currentVal;
706 }
707}
708
709stock bool IsVip(int client)
710{
711 if(GetUserFlagBits(client) & ADMFLAG_CUSTOM1
712 || GetUserFlagBits(client) & ADMFLAG_CUSTOM2
713 || GetUserFlagBits(client) & ADMFLAG_CUSTOM3
714 || GetUserFlagBits(client) & ADMFLAG_CUSTOM4
715 || GetUserFlagBits(client) & ADMFLAG_CUSTOM5
716 || GetUserFlagBits(client) & ADMFLAG_CUSTOM6)
717 {
718 return true;
719 }
720 return false;
721}
722
723stock bool IsAdminEx(int client)
724{
725 if(
726 /*|| GetUserFlagBits(client) & ADMFLAG_RESERVATION*/
727 GetUserFlagBits(client) & ADMFLAG_GENERIC
728 || GetUserFlagBits(client) & ADMFLAG_KICK
729 || GetUserFlagBits(client) & ADMFLAG_BAN
730 || GetUserFlagBits(client) & ADMFLAG_UNBAN
731 || GetUserFlagBits(client) & ADMFLAG_SLAY
732 || GetUserFlagBits(client) & ADMFLAG_CHANGEMAP
733 || GetUserFlagBits(client) & ADMFLAG_CONVARS
734 || GetUserFlagBits(client) & ADMFLAG_CONFIG
735 || GetUserFlagBits(client) & ADMFLAG_CHAT
736 || GetUserFlagBits(client) & ADMFLAG_VOTE
737 || GetUserFlagBits(client) & ADMFLAG_PASSWORD
738 || GetUserFlagBits(client) & ADMFLAG_RCON
739 || GetUserFlagBits(client) & ADMFLAG_CHEATS
740 || GetUserFlagBits(client) & ADMFLAG_ROOT)
741 {
742 return true;
743 }
744 return false;
745}
746
747stock void ClearTimer(Handle &timer)
748{
749 if (timer != INVALID_HANDLE)
750 {
751 KillTimer(timer);
752 timer = INVALID_HANDLE;
753 }
754}