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