· 7 years ago · Dec 11, 2018, 07:16 PM
1/*================================================================================
2
3 ***********************************************************
4 *********** [Bullet Damage with Ranking 3.0.2] ************
5 ***********************************************************
6
7 ----------------------
8 -*- Licensing Info -*-
9 ----------------------
10
11 Bullet Damage with Ranking
12 by schmurgel1983(@msn.com)
13 Copyright (C) 2009-2011 Stefan "schmurgel1983" Focke
14
15 This program is free software: you can redistribute it and/or modify it
16 under the terms of the GNU General Public License as published by the
17 Free Software Foundation, either version 3 of the License, or (at your
18 option) any later version.
19
20 This program is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
23 Public License for more details.
24
25 You should have received a copy of the GNU General Public License along
26 with this program. If not, see <http://www.gnu.org/licenses/>.
27
28 In addition, as a special exception, the author gives permission to
29 link the code of this program with the Half-Life Game Engine ("HL
30 Engine") and Modified Game Libraries ("MODs") developed by Valve,
31 L.L.C ("Valve"). You must obey the GNU General Public License in all
32 respects for all of the code used other than the HL Engine and MODs
33 from Valve. If you modify this file, you may extend this exception
34 to your version of the file, but you are not obligated to do so. If
35 you do not wish to do so, delete this exception statement from your
36 version.
37
38 No warranties of any kind. Use at your own risk.
39
40 -------------------
41 -*- Description -*-
42 -------------------
43
44 Display single, multiple, grenade or take Damage via Hud message.
45 Can give a Chat announce, if you score a new weapon/personal record.
46 The Chat command /bd show up a menu to configuration your bd.
47
48 --------------------
49 -*- Requirements -*-
50 --------------------
51
52 * Mods: Counter-Strike 1.6 or Condition-Zero
53 * AMXX: Version 1.8.0 or later
54 * Module: cstrike, fakemeta, hamsandwich
55
56 ----------------
57 -*- Commands -*-
58 ----------------
59
60 say: /bd - open bd menu
61 con: bd_reset "argument" - look bd_reset.txt for all possible bd_reset commands!
62
63 -------------------------------
64 -*- CVARS and Customization -*-
65 -------------------------------
66
67 For a complete and in-depth cvar list, look at the bulletdamage.cfg file
68 located in the amxmodx\configs directory.
69
70 ---------------
71 -*- Credits -*-
72 ---------------
73
74 * MeRcyLeZZ: for some useful stuff
75 * worldspawn: for few ideas - motd style, damage sorting, new command and bd_no_over_dmg ;)
76 * Pneumatic: for the bd_multi_dmg 2 idea
77 * ConnorMcLeod: for Ham_TakeDamage forward idea (v2.2.0 -> HE-Grenade compatibility)
78 * Alucard^: for the enable/disable (global) HUD-Damage idea
79 * Hawk552: for approve and optimization plugin
80 * GAARA54: for colored chat idea and Zombie Plague Advance 1.6 Compatibility request
81
82 -----------------
83 -*- Changelog -*-
84 -----------------
85
86 + Added feature or noticeable improvement
87 - Bug fix or something removed
88 * Changed or Information
89 ! Important - Take note!
90
91 * v1.1: (?)
92 + display multiple damage
93
94 * v1.2: (?)
95 + new cvar bd_more_time
96 + announce (name, damage, weapon) in chat
97 + anti cheat (ARC) if u change your weapon in a long task like awp
98
99 * v1.3: (21st Dec 2009)
100 + new cvar bd_chat
101 + new command /top
102 + save and load records
103 + motd to show the records in table style
104 * announce (name, damage, weapon and hits) in chat
105
106 * v1.4: (22nd Dec 2009)
107 + new cvars bd_multi_dmg, bd_save_stats, bd_save_bots, bd_motd_method
108 + new motd sytle like top15 from statsx.sma
109 * chat command from /top to /bdtop
110
111 * v1.5: (23rd Dec 2009)
112 + new cvars bd_color, bd_color_style, bd_color_holdtime, bd_motd_sorting
113 + new motd sorting method
114 * some stuff
115
116 * v1.5.1: (24th Dec 2009)
117 * show_top
118
119 * v2.0: (25th Jan 2010)
120 ! teammate attack protection (record cheat)
121 + new command to reset all records
122 * plugin name from achievement to ranking
123 * some stuff
124
125 * v2.1: (16th Feb 2010)
126 + bd_multi_dmg 2 = display single & multiple damage together
127 * some stuff
128
129 * v2.1.1: (17th Feb 2010)
130 + firerate time multiply for record task (look Plugin Customization section)
131 + full knife atk1 & atk2 compatible
132 * weapon firerate using fastest orginal rates
133 - query player zooming
134
135 * v2.1.2: (2nd Mar 2010)
136 + multi language support
137
138 * v2.1.3: (12th Mar 2010)
139 + cvar bd_no_over_dmg
140
141 * v2.2.0: (30th Mar 2010)
142 + HE-Grenade compatibility
143 + HE-Grenade has now a own record task
144 * some stuff
145
146 * v2.3.0: (30th Mar 2010)
147 + RC1 new client command to enable/disable HUD-Damage
148 + RC1 new cvar to enable/disable global HUD-Damage
149 * RC2 HE-Grenade HUD-Damage Sync Object
150 - RC3 /bdhud showing wrong chat info (enable/disable print)
151
152 * v2.3.1: (3rd Apr 2010)
153 + more Customization
154 + bulletdamage.cfg file
155 * some stuff (lower CPU usage)
156 * admin console command bd_reset
157 - /bdtop not showing all weapons
158
159 * v2.4.0: (5th Apr 2010)
160 + cvar bd_hud_dmg_wall
161 + show HUD-Damage when you hit the enemy and he is behind a wall
162 + cvar bd_ffa_dmg enable "free for all" damage for FFA servers
163 * damage stuff
164
165 * v2.4.1: (7th Apr 2010)
166 + Shield support
167 - clear unusing stuff
168
169 * v2.4.2: (18th Apr 2010)
170 * Knife attack 2 is now _Post not _Pre
171 * damage stuff (timers)
172 - fixing read/save/reset "top bullet damage"
173
174 * v2.5.0: (23rd Apr 2010)
175 ! Knife attack 2 is again _Pre forward
176 + Zombie Plague 4.3 Compatibility
177 + records now saved by Steam ID, only steam authorized players can made records
178 * motd misstep, when it calls 2 times to fast
179
180 * v2.5.1: (24th Apr 2010)
181 ! Damage vars not reseting for non-steam players
182
183 * v2.5.2: (17th Jun 2010)
184 * ARC and some stuff
185 - wrong counting of hits, most by HE-Grenade (CZ)
186 - Remove ML 'BDwR_CHEAT'
187
188 * v2.5.3: (26th Jun 2010)
189 ! new ARC system
190 + admin reset and hud flag cvar
191 + admin show HUD-Damage
192 + admin show HUD-Damage when you hit the enemy and he is behind a wall
193 + Lan Server support
194 - bd_motd_method only Top15 style possible
195
196 * v2.5.4: (27th Jun 2010)
197 - HUD-Damage for HE-Grenade with the new cvars
198 - fix cvar combination bd_hud_dmg 1 and bd_hud_dmg_wall 2 not showing HUD-Damage for normal players
199 - Remove scripter query in fwd_TraceAttack (plugin test query)
200
201 * v2.5.5: (3rd Jul 2010)
202 + Zombie Plague Advance 1.6 Compatibility
203 + colored chat
204 - Remove zp4.3 infect querys, not need more with the new ARC system
205
206 * v2.5.6: (21st Jul 2010)
207 * clearing the code
208
209 * v2.5.7: (29th Jul 2010)
210 ! fix authorized bug (thanks craigy09)
211
212 * v2.5.8: (5th Sep 2010)
213 ! showing fault overpower damage on zombie servers
214
215 * v2.5.9: (13th Sep 2010)
216 - damage not showing through glass and players
217
218 * v3.0.0: (27th Jan 2011)
219 + Menu to configurate own player hud messages for
220 + colors
221 + position (x,y)
222 + flicker
223 + holdtime
224 + personal records
225 + all weapon records
226 + admin menu
227
228 * v3.0.1: (31st Jan 2011)
229 ! admin menu (bug found, by converting this plugin to DoD)
230
231 * v3.0.2: (12th Jul 2012)
232 ! FPS drop with HUD Sync Objects
233 ! Unique crash on private data
234 - Records/configs not being saved on windows (hopefully)
235
236 + Added feature or noticeable improvement
237 - Bug fix or something removed
238 * Changed or Information
239 ! Important - Take note!
240
241=================================================================================*/
242
243#include <amxmodx>
244#include <amxmisc>
245#include <cstrike>
246#include <fakemeta>
247#include <xs>
248
249#if AMXX_VERSION_NUM < 180
250 #assert AMX Mod X v1.8.0 or later library required!
251#endif
252
253#include <hamsandwich>
254
255/*================================================================================
256 [Plugin Customization]
257=================================================================================*/
258
259// Save Records File
260new const BD_RECORD_FILE[] = "bullet_damage_ranks"
261
262// Firerate Time Multiply for Record Task
263// 1.0 is normal | 2.0 is double
264const Float:FIRERATE_MULTI = 1.5
265
266// uncomment the line to have Zombie Plague 4.3 Compatibility
267//#define ZOMBIE_PLAGUE_MOD
268// uncomment the line to have Zombie Plague Advance 1.6 Compatibility
269//#define ZOMBIE_PLAGUE_ADVANCE_MOD
270
271/*================================================================================
272 Customization ends here! Yes, that's it. Editing anything beyond
273 here is not officially supported. Proceed at your own risk...
274=================================================================================*/
275
276/*================================================================================
277 [Constants, Offsets, Macros]
278=================================================================================*/
279
280// Plugin Version
281new const PLUGIN_VERSION[] = "3.0.2"
282
283// Config file sections
284enum
285{
286 SECTION_NONE = 0,
287 SECTION_HUD,
288 SECTION_COLORS,
289 SECTION_POSITIONS,
290 SECTION_TIMES,
291 MAX_SECTIONS
292}
293
294// Access flags
295enum
296{
297 ACCESS_RESET = 0,
298 ACCESS_HUD,
299 MAX_ACCESS_FLAGS
300}
301
302// Task offsets
303enum (+= 100)
304{
305 TASK_DAMAGE = 2000,
306 TASK_KNIFE,
307 TASK_GRENADE
308}
309
310// Color vars
311enum
312{
313 COLOR_RED = 0,
314 COLOR_GREEN,
315 COLOR_BLUE,
316 COLOR_STYLE,
317 MAX_COLORS
318}
319
320// IDs inside tasks
321#define ID_DAMAGE (taskid - TASK_DAMAGE)
322#define ID_KNIFE (taskid - TASK_KNIFE)
323#define ID_GRENADE (taskid - TASK_GRENADE)
324
325// few constants
326const FM_PDATA_SAFE = 2
327const MOTD_MAX_WEAPONS = 26 // CSW_P90 (30) - is_ignore_weapon_id (4)
328const DMG_HEGRENADE = (1<<24)
329const Float:POSI_TYPE_TRUE = 0.10
330const Float:POSI_TYPE_FALSE = 0.01
331const Float:TIME_TYPE_TRUE = 1.00
332const Float:TIME_TYPE_FALSE = 0.10
333
334// CS Weapon CBase Offset (win32)
335const OFFSET_WEAPONOWNER = 41
336
337// Linux diff
338const OFFSET_LINUX_WEAPONS = 4
339
340// Weapon Names
341new const WPN_NAMES[][] = {
342 "", "228 Compact", "", "Schmidt Scout", "HE Grenade", "Leone YG1265 Auto Shotgun", "", "Ingram MAC-10",
343 "Bullpup", "", ".40 Dual Elites", "ES Five-Seven", "KM UMP45", "Krieg 550 Commando",
344 "IDF Defender", "Clarion 5.56", "KM .45 Tactical", "9x19mm Sidearm", "Magnum Sniper Rifle", "KM Sub-Machine Gun",
345 "M249", "Leone 12 Gauge Super", "Maverick M4A1 Carbine", "Schmidt Machine Pistol", "D3/AU1", "", "Night Hawk .50C",
346 "Krieg 552", "CV-47", "Knife", "ES C90"
347}
348
349// short Weapon Names
350new const WPN_SHORTNAMES[][7] = {
351 "", "p228", "", "scout", "hegren", "xm1014", "", "mac10",
352 "aug", "", "elites", "fn57", "ump45", "sg550",
353 "galil", "famas", "usp", "glock", "awp", "mp5",
354 "m249", "m3", "m4a1", "tmp", "g3sg1", "", "deagle",
355 "sg552", "ak47", "knife", "p90"
356}
357
358// Weapon entity names
359new const WPN_ENTNAMES[][] = {
360 "", "weapon_p228", "", "weapon_scout", "", "weapon_xm1014", "", "weapon_mac10", "weapon_aug",
361 "", "weapon_elite", "weapon_fiveseven", "weapon_ump45", "weapon_sg550", "weapon_galil",
362 "weapon_famas", "weapon_usp", "weapon_glock18", "weapon_awp", "weapon_mp5navy", "weapon_m249",
363 "weapon_m3", "weapon_m4a1", "weapon_tmp", "weapon_g3sg1", "", "weapon_deagle", "weapon_sg552",
364 "weapon_ak47", "weapon_knife", "weapon_p90"
365}
366
367// Weapon fastest firerate time
368new const Float:WPN_FIRERATE[] = {
369 0.1, // --- (NOTHING)
370 0.16, // P228
371 0.1, // --- (NOTHING)
372 1.26, // SCOUT
373 0.1, // HEGRENADE
374 0.25, // XM1014
375 0.1, // --- (C4)
376 0.08, // MAC10
377 0.09, // AUG
378 0.1, // --- (SMOKEGRENADE)
379 0.1, // ELITE
380 0.16, // FIVESEVEN
381 0.11, // UMP45
382 0.25, // SG550
383 0.09, // GALIL
384 0.09, // FAMAS
385 0.15, // USP
386 0.16, // GLOCK18
387 1.46, // AWP
388 0.08, // MP5NAVY
389 0.11, // M249
390 0.88, // M3
391 0.09, // M4A1
392 0.08, // TMP
393 0.25, // G3SG1
394 0.1, // --- (FLASHBANG)
395 0.23, // DEAGLE
396 0.09, // SG552
397 0.1, // AK47
398 0.41, // KNIFE
399 0.07 // P90
400}
401const Float:ZOOMED_AUG_SG552 = 0.14
402const Float:BURST_FAMAS = 0.41
403const Float:BURST_GLOCK18 = 0.5
404const Float:ATK2_KNIFE = 1.11
405
406// Menu keys
407const KEYSMENU = MENU_KEY_1|MENU_KEY_2|MENU_KEY_3|MENU_KEY_4|MENU_KEY_5|MENU_KEY_6|MENU_KEY_7|MENU_KEY_8|MENU_KEY_9|MENU_KEY_0
408
409/*================================================================================
410 [Zombie Plague Advance Compatibility Checking]
411=================================================================================*/
412
413// try include "zombie_plague_advance.inc"
414#if defined ZOMBIE_PLAGUE_ADVANCE_MOD
415
416#tryinclude <zombie_plague_advance>
417
418 #if !defined _zombie_plague_advance_included
419 #assert zombie_plague_advance.inc library required!
420 #endif
421#endif
422
423/*================================================================================
424 [Zombie Plague Compatibility Checking]
425=================================================================================*/
426
427// try include "zombieplague.inc"
428#if defined ZOMBIE_PLAGUE_MOD
429 #if !defined _zombie_plague_advance_included
430
431 #tryinclude <zombieplague>
432
433 #if !defined _zombieplague_included
434 #assert zombieplague.inc library required!
435 #endif
436 #endif
437#endif
438
439/*================================================================================
440 [Global Variables]
441=================================================================================*/
442
443// Player vars
444new g_iDamageDealt[33] // total damage
445new g_iWeaponUse[33] // current weapon
446new g_iWeaponEntity[33] // weapon entity
447new g_iHits[33] // hits
448new g_bAttack2Knife[33] // knife attack2 (stab)
449new g_iPreHealth[33] // pre health
450new g_iPostHealth[33] // post health
451new g_iGrenadeDamageDealt[33] // HE total damage
452new g_iGrenadeHits[33] // HE hits
453new Float:g_flWallOrigin[33][33][3] // visible [owner][other][origin]
454new g_iAuthorized[33] // authorized steam player
455new g_bWhileRecordTask[33] // while record task
456new g_bGrenadeWallVisible[33] // HE grenade damage is visible
457
458// Player Hud stuff
459new g_iShowSingleHud[33] // show hud single damage message
460new g_iShowMultipleHud[33] // show hud multi damage message
461new g_iShowGrenadeHud[33] // show hud he damage message
462new g_iShowTakeHud[33] // show hud take damage message
463new g_iDynamicMenu[33] // what section u are in dynamic menu
464new g_iMenuType[33] // Position type 0.01 or 0.1 and Time type 1.0 or 0.1
465
466// Player Hud config stuff
467new g_iSingleColor[33][MAX_COLORS] // single colors and style
468new g_iMultipleColor[33][MAX_COLORS] // multi colors and style
469new g_iGrenadeColor[33][MAX_COLORS] // he colors and style
470new g_iTakeColor[33][MAX_COLORS] // take colors and style
471new Float:g_flSinglePosition_X[33] // single X position message
472new Float:g_flSinglePosition_Y[33] // single Y position message
473new Float:g_flMultiplePosition_X[33] // multi X position message
474new Float:g_flMultiplePosition_Y[33] // multi Y position message
475new Float:g_flGrenadePosition_X[33] // he X position message
476new Float:g_flGrenadePosition_Y[33] // he Y position message
477new Float:g_flTakePosition_X[33] // take X position message
478new Float:g_flTakePosition_Y[33] // take Y position message
479new Float:g_flSingleTime[33] // single holdtime message
480new Float:g_flMultipleTime[33] // multi holdtime message
481new Float:g_flGrenadeTime[33] // he holdtime message
482new Float:g_flTakeTime[33] // take holdtime message
483
484// Game vars
485new g_iMaxPlayers // max player counter
486new g_HudSyncSingle, g_HudSyncMultiple, g_HudSyncGrenade, g_HudSyncTake // message sync objects
487new g_bHamCzBots // whether ham forwards are registered for CZ bots
488new g_bMotdPrepair // flag for whenever a Motd prepairs
489
490// Message IDs vars
491new g_msgSayText
492
493// Access vars
494new g_access_flag[MAX_ACCESS_FLAGS]
495
496// CVAR pointers
497new cvar_BulletDamage, cvar_HudDamageWall, cvar_SaveStatsPersonal,
498cvar_ChatWeapon, cvar_ChatPersonal, cvar_MotdSort, cvar_AdminHudFlag,
499cvar_AdminResetFlag, cvar_Single, cvar_Multiple, cvar_NoOverDamage,
500cvar_GrenadeDamage, cvar_TakeDamage, cvar_MoreTime, cvar_HudDamage,
501cvar_SaveStats, cvar_SvLan, cvar_BotQuota, cvar_FFA, cvar_SaveBots
502
503// Zombie Plague Compatibility
504#if defined _zombieplague_included || defined _zombie_plague_advance_included
505
506// CVAR pointers
507new cvar_zpNemesisDamage, cvar_zpSurvivorDamage
508
509#endif
510
511// Zombie Plague Advance Compatibility
512#if defined _zombie_plague_advance_included
513
514// CVAR pointers
515new cvar_zpAssassinDamage, cvar_zpSniperDamage
516
517#endif
518
519// Record vars
520new g_szDataDir[64] // file parth of data folder
521new g_szRecordFile[128] // file parth of BD_RECORD_FILE
522new g_iRecord[CSW_P90+1] // for sorting method
523new g_szCachedNames[CSW_P90+1][32] // cached record names
524new g_szCachedSteamIDs[CSW_P90+1][32] // cached record steam id's
525new g_iCachedDamage[CSW_P90+1] // cached record damage
526new g_iCachedHits[CSW_P90+1] // cached record hits
527new g_iCachedResets[CSW_P90+1] // cached record resets
528
529// Personal record vars
530new g_iPersonalDamage[33][CSW_P90+1] // personal record damage
531new g_iPersonalHits[33][CSW_P90+1] // personal record hits
532new g_iPersonalResets[33][CSW_P90+1] // personal record resets
533
534// Cached stuff for players
535new g_bIsConnected[33] // whether player is connected
536new g_bIsBot[33] // whether player is a bot
537new g_szPlayerName[33][32] // player's name
538new g_szSteamID[33][32] // player's Steam ID
539
540// Macros
541#define is_user_valid_connected(%1) (1 <= %1 <= g_iMaxPlayers && g_bIsConnected[%1])
542#define is_ignore_weapon_id(%1) (%1 == 2 || %1 == 6 || %1 == 9 || %1 == 25)
543#define user_has_flag(%1,%2) (get_user_flags(%1) & g_access_flag[%2])
544
545/*================================================================================
546 [Precache, Init and Cfg]
547=================================================================================*/
548
549public plugin_precache()
550{
551 // Tampering with the author and plugin name will violate copyrights
552 // Register earlier to show up in plugins list properly after plugin disable/error at loading
553 register_plugin("Bullet Damage with Ranking", PLUGIN_VERSION, "schmurgel1983")
554}
555
556public plugin_init()
557{
558 // Language files
559 register_dictionary("bullet_damage_ranking.txt")
560
561 // HAM Forwards "player"
562 RegisterHam(Ham_TakeDamage, "player", "fwd_TakeDamage_Post", 1)
563 RegisterHam(Ham_TraceAttack, "player", "fwd_TraceAttack")
564
565 // HAM Forwards "entity"
566 RegisterHam(Ham_Weapon_SecondaryAttack, "weapon_knife", "fwd_Knife_SecAtk")
567 for (new i = 1; i < sizeof WPN_ENTNAMES; i++)
568 if (WPN_ENTNAMES[i][0]) RegisterHam(Ham_Item_Deploy, WPN_ENTNAMES[i], "fwd_Item_Deploy_Post", 1)
569
570 // Client Commands
571 register_clcmd("say /bd", "clcmd_saymenu")
572 register_clcmd("say_team /bd", "clcmd_saymenu")
573
574 // Menus
575 register_menu("Main Menu", KEYSMENU, "menu_main")
576 register_menu("Config Menu", KEYSMENU, "menu_config")
577 register_menu("Dynamic Menu Main", KEYSMENU, "menu_dynamic_main")
578 register_menu("Dynamic Menu Color", KEYSMENU, "menu_dynamic_color")
579 register_menu("Dynamic Menu Posi", KEYSMENU, "menu_dynamic_posi")
580 register_menu("Dynamic Menu Time", KEYSMENU, "menu_dynamic_time")
581
582 // Admin Commands
583 register_concmd("bd_reset", "cmd_reset", _, "<argument> - Record Reset", 0)
584
585 // Message IDs
586 g_msgSayText = get_user_msgid("SayText")
587
588 // Message hooks
589 register_message(get_user_msgid("Damage"), "message_damage")
590 register_message(get_user_msgid("Health"), "message_health")
591
592 // CVARS - General Purpose
593 cvar_BulletDamage = register_cvar("bd_on", "1")
594 cvar_SaveBots = register_cvar("bd_save_bots", "1")
595 cvar_SaveStats = register_cvar("bd_save_stats", "1")
596 cvar_SaveStatsPersonal = register_cvar("bd_save_stats_personal", "1")
597 cvar_ChatWeapon = register_cvar("bd_chat_weapon", "1")
598 cvar_ChatPersonal = register_cvar("bd_chat_personal", "1")
599 cvar_MotdSort = register_cvar("bd_motd_sorting", "0")
600 cvar_FFA = register_cvar("bd_ffa_dmg", "0")
601 cvar_NoOverDamage = register_cvar("bd_no_over_dmg", "0")
602 cvar_MoreTime = register_cvar("bd_more_time", "1.0")
603
604 // CVARS - Admin
605 cvar_AdminHudFlag = register_cvar("bd_hud_flag", "c")
606 cvar_AdminResetFlag = register_cvar("bd_reset_flag", "g")
607
608 // CVARS - HUD Messages
609 cvar_HudDamage = register_cvar("bd_hud_dmg", "1")
610 cvar_HudDamageWall = register_cvar("bd_hud_dmg_wall", "1")
611 cvar_Single = register_cvar("bd_single_dmg", "1")
612 cvar_Multiple = register_cvar("bd_multiple_dmg", "1")
613 cvar_GrenadeDamage = register_cvar("bd_grenade_dmg", "1")
614 cvar_TakeDamage = register_cvar("bd_take_dmg", "1")
615
616 // Zombie Plague Compatibility
617 #if defined _zombieplague_included || defined _zombie_plague_advance_included
618
619 // CVARS - Zombie Plague
620 cvar_zpNemesisDamage = register_cvar("bd_nem_dmg_record", "0")
621 cvar_zpSurvivorDamage = register_cvar("bd_surv_dmg_record", "0")
622
623 #endif
624
625 // Zombie Plague Advance Compatibility
626 #if defined _zombie_plague_advance_included
627
628 // CVARS - Zombie Plague Advance
629 cvar_zpAssassinDamage = register_cvar("bd_assa_dmg_record", "0")
630 cvar_zpSniperDamage = register_cvar("bd_snip_dmg_record", "0")
631
632 #endif
633
634 // CVARS - Others
635 cvar_SvLan = get_cvar_pointer("sv_lan")
636 cvar_BotQuota = get_cvar_pointer("bot_quota")
637 register_cvar("BDwR_version", PLUGIN_VERSION, FCVAR_SERVER|FCVAR_SPONLY)
638 set_cvar_string("BDwR_version", PLUGIN_VERSION)
639
640 // Create the HUD Sync Object
641 g_HudSyncSingle = CreateHudSyncObj()
642 g_HudSyncMultiple = CreateHudSyncObj()
643 g_HudSyncGrenade = CreateHudSyncObj()
644 g_HudSyncTake = CreateHudSyncObj()
645
646 // Get Max Players
647 g_iMaxPlayers = get_maxplayers()
648}
649
650public plugin_cfg()
651{
652 // Get configs dir
653 new configsdir[32], folder[128]
654 get_configsdir(configsdir, charsmax(configsdir))
655
656 // Execute config file (bulletdamage.cfg)
657 server_cmd("exec %s/bulletdamage.cfg", configsdir)
658
659 // Cache data dir
660 get_datadir(g_szDataDir, charsmax(g_szDataDir))
661
662 // Cache record file
663 format(g_szRecordFile, charsmax(g_szRecordFile), "%s/%s.ini", g_szDataDir, BD_RECORD_FILE)
664
665 // Read record file
666 load_top()
667
668 // check if folder bd_configs exists, if not create one
669 format(folder, charsmax(folder), "%s/bd_configs", g_szDataDir)
670 if (!dir_exists(folder)) mkdir(folder)
671
672 // check if folder bd_records exists, if not create one
673 format(folder, charsmax(folder), "%s/bd_records", g_szDataDir)
674 if (!dir_exists(folder)) mkdir(folder)
675
676 // Get Access Flags
677 new szFlags[24]
678 get_pcvar_string(cvar_AdminResetFlag, szFlags, charsmax(szFlags))
679 g_access_flag[ACCESS_RESET] = read_flags(szFlags)
680 get_pcvar_string(cvar_AdminHudFlag, szFlags, charsmax(szFlags))
681 g_access_flag[ACCESS_HUD] = read_flags(szFlags)
682}
683
684public client_putinserver(id)
685{
686 // Player fully connected
687 g_bIsConnected[id] = true
688
689 // Player vars
690 set_player_vars(id)
691
692 // Cache player's name and authid
693 get_user_info(id, "name", g_szPlayerName[id], charsmax(g_szPlayerName[]))
694 get_user_authid(id, g_szSteamID[id], charsmax(g_szSteamID[]))
695
696 // authorized?
697 g_iAuthorized[id] = str_to_num(g_szSteamID[id][10])
698
699 // Cached bot stuff
700 if (is_user_bot(id))
701 {
702 // Set bot flag
703 g_bIsBot[id] = true
704
705 // Bots are always Authorized
706 g_iAuthorized[id] = 1
707
708 // Load personal top & hud standard
709 set_hud_vars(id)
710 load_personal_top(id)
711 check_resets(id)
712
713 // CZ bots seem to use a different "classtype" for player entities
714 // (or something like that) which needs to be hooked separately
715 if (!g_bHamCzBots && cvar_BotQuota)
716 {
717 // Set a task to let the private data initialize
718 set_task(0.1, "register_ham_czbots", id)
719 }
720 }
721 else
722 {
723 // Set a task to let Display Help
724 set_task(20.0, "DisplayBulletDamageHelp", id)
725
726 // Load personal top & hud config
727 load_hud_vars(id)
728 load_personal_top(id)
729 check_resets(id)
730
731 // Not authorized
732 if (!g_iAuthorized[id]) return
733
734 // Check if Player have Records
735 new szSteam[32], save
736 szSteam = g_szSteamID[id]
737
738 for (new i = CSW_P228; i <= CSW_P90; i++)
739 {
740 // check steam id
741 if (is_ignore_weapon_id(i) || !equali(szSteam, g_szCachedSteamIDs[i])) continue
742
743 // Cache new name
744 replace_all(g_szPlayerName[id], charsmax(g_szPlayerName[]), "^^", "_")
745 g_szCachedNames[i] = g_szPlayerName[id]
746 save = true
747 }
748 // Save?
749 if (save && get_pcvar_num(cvar_SaveStats))
750 save_top()
751 }
752}
753
754public client_disconnect(id)
755{
756 // Player disconnected
757 g_bIsConnected[id] = false
758
759 // Remove Tasks
760 remove_task(id)
761 remove_task(id+TASK_DAMAGE)
762 remove_task(id+TASK_KNIFE)
763 remove_task(id+TASK_GRENADE)
764
765 // Clear player vars
766 set_player_vars(id)
767}
768
769public client_infochanged(id)
770{
771 // Cache player's name and authid
772 get_user_info(id, "name", g_szPlayerName[id], charsmax(g_szPlayerName[]))
773 get_user_authid(id, g_szSteamID[id], charsmax(g_szSteamID[]))
774
775 // authorized?
776 g_iAuthorized[id] = str_to_num(g_szSteamID[id][10])
777
778 // Check if Player have Records
779 if (g_iAuthorized[id])
780 {
781 // Check if Player have Records
782 new szSteam[32], save
783 szSteam = g_szSteamID[id]
784
785 for (new i = CSW_P228; i <= CSW_P90; i++)
786 {
787 // check steam id
788 if (is_ignore_weapon_id(i) || !equali(szSteam, g_szCachedSteamIDs[i])) continue
789
790 // Cache new name
791 g_szCachedNames[i] = g_szPlayerName[id]
792 save = true
793 }
794 // Save?
795 if (save && get_pcvar_num(cvar_SaveStats))
796 save_top()
797 }
798
799 // Bots are always Authorized or Lan Server?
800 if (g_bIsBot[id] || get_pcvar_num(cvar_SvLan))
801 g_iAuthorized[id] = 1
802}
803
804/*================================================================================
805 [Main Forwards]
806=================================================================================*/
807
808public fwd_TakeDamage_Post(victim, inflictor, attacker, Float:damage, damage_type)
809{
810 if (!get_pcvar_num(cvar_BulletDamage)) return HAM_IGNORED
811
812 new dmg_take
813 if ((dmg_take = pev(victim, pev_dmg_take)) <= 0) return HAM_IGNORED
814
815 if (g_iShowTakeHud[victim] && get_pcvar_num(cvar_TakeDamage))
816 {
817 ClearSyncHud(victim, g_HudSyncTake)
818 set_hudmessage(g_iTakeColor[victim][COLOR_RED], g_iTakeColor[victim][COLOR_GREEN], g_iTakeColor[victim][COLOR_BLUE], g_flTakePosition_X[victim], g_flTakePosition_Y[victim], g_iTakeColor[victim][COLOR_STYLE], 0.0, g_flTakeTime[victim], 1.0, 1.0, -1)
819 ShowSyncHudMsg(victim, g_HudSyncTake, "%i", dmg_take)
820 }
821
822 if (!is_user_valid_connected(attacker) || victim == attacker || (!get_pcvar_num(cvar_FFA) && cs_get_user_team(victim) == cs_get_user_team(attacker)) || (!get_pcvar_num(cvar_SaveBots) && g_bIsBot[attacker])) return HAM_IGNORED
823
824 // Damage by HE grenade
825 if (damage_type & DMG_HEGRENADE)
826 {
827 // Remove HE Damage Timer
828 remove_task(attacker+TASK_GRENADE)
829
830 // NO over Damage?
831 if (get_pcvar_num(cvar_NoOverDamage))
832 {
833 // Get post health
834 g_iPostHealth[victim] = g_iPreHealth[victim] - dmg_take
835 clamp(g_iPostHealth[victim], 0, 999999)
836
837 // Damage higher as Health
838 if (dmg_take > g_iPreHealth[victim] - g_iPostHealth[victim])
839 dmg_take = g_iPreHealth[victim]
840
841 // New pre health
842 g_iPreHealth[victim] = g_iPostHealth[victim]
843 }
844
845 // Damage deal and Hits
846 g_iGrenadeDamageDealt[attacker] += dmg_take
847 g_iGrenadeHits[attacker]++
848
849 // HE-Grenade Wall Damage visible?
850 if (!g_bGrenadeWallVisible[attacker])
851 g_bGrenadeWallVisible[attacker] = ExecuteHam(Ham_FVisible, attacker, victim)
852
853 // Set Task for multiple Damage
854 set_task(WPN_FIRERATE[CSW_HEGRENADE], "damage_deal_he", attacker+TASK_GRENADE)
855
856 return HAM_IGNORED
857 }
858
859 // I will made a new Record! (bugfix)
860 g_bWhileRecordTask[attacker] = true
861
862 // Remove Damage Timer
863 remove_task(attacker+TASK_DAMAGE)
864
865 // NO over Damage?
866 if (get_pcvar_num(cvar_NoOverDamage))
867 {
868 // Get post health
869 g_iPostHealth[victim] = g_iPreHealth[victim] - dmg_take
870 clamp(g_iPostHealth[victim], 0, 999999)
871
872 // Damage higher as Health
873 if (dmg_take > g_iPreHealth[victim] - g_iPostHealth[victim])
874 dmg_take = g_iPreHealth[victim]
875
876 // New pre health
877 g_iPreHealth[victim] = g_iPostHealth[victim]
878 }
879
880 // Damage deal and Hits
881 g_iDamageDealt[attacker] += dmg_take
882 g_iHits[attacker]++
883
884 // Valid entity
885 if (pev_valid(g_iWeaponEntity[attacker]))
886 {
887 // Setup Timer
888 static Float:timer
889 switch (g_iWeaponUse[attacker])
890 {
891 case CSW_KNIFE:
892 {
893 if (g_bAttack2Knife[attacker])
894 timer = ATK2_KNIFE * FIRERATE_MULTI
895 else
896 timer = WPN_FIRERATE[CSW_KNIFE] * FIRERATE_MULTI
897 }
898 case CSW_AUG, CSW_SG552:
899 {
900 if (cs_get_user_zoom(attacker) == 4)
901 timer = ZOOMED_AUG_SG552 * FIRERATE_MULTI
902 else
903 timer = WPN_FIRERATE[g_iWeaponUse[attacker]] * FIRERATE_MULTI
904 }
905 case CSW_FAMAS:
906 {
907 if (cs_get_weapon_burst(g_iWeaponEntity[attacker]))
908 timer = BURST_FAMAS * FIRERATE_MULTI
909 else
910 timer = WPN_FIRERATE[CSW_FAMAS] * FIRERATE_MULTI
911 }
912 case CSW_GLOCK18:
913 {
914 if (cs_get_weapon_burst(g_iWeaponEntity[attacker]))
915 timer = BURST_GLOCK18 * FIRERATE_MULTI
916 else
917 timer = WPN_FIRERATE[CSW_GLOCK18] * FIRERATE_MULTI
918 }
919 default: timer = WPN_FIRERATE[g_iWeaponUse[attacker]] * FIRERATE_MULTI
920 }
921
922 // Set Task for multiple Damage
923 set_task(timer+get_pcvar_float(cvar_MoreTime), "damage_deal", attacker+TASK_DAMAGE)
924 }
925 // Invalid entity, make single Damage
926 else
927 damage_deal(attacker+TASK_DAMAGE)
928
929 // Static Hud Damage Wall
930 static HudDamageWall, HudVisible
931 HudDamageWall = get_pcvar_num(cvar_HudDamageWall)
932 HudVisible = fm_is_visible(attacker, g_flWallOrigin[attacker][victim])
933
934 // Display HUD damage?
935 switch (get_pcvar_num(cvar_HudDamage))
936 {
937 case 2: // Admin
938 {
939 if (!user_has_flag(attacker, ACCESS_HUD) || (!HudDamageWall && !HudVisible)) return HAM_IGNORED
940
941 // Display option
942 if (g_iShowMultipleHud[attacker] && get_pcvar_num(cvar_Multiple))
943 {
944 ClearSyncHud(attacker, g_HudSyncMultiple)
945 set_hudmessage(g_iMultipleColor[attacker][COLOR_RED], g_iMultipleColor[attacker][COLOR_GREEN], g_iMultipleColor[attacker][COLOR_BLUE], g_flMultiplePosition_X[attacker], g_flMultiplePosition_Y[attacker], g_iMultipleColor[attacker][COLOR_STYLE], 0.0, g_flMultipleTime[attacker], 1.0, 1.0, -1)
946 ShowSyncHudMsg(attacker, g_HudSyncMultiple, "%i", g_iDamageDealt[attacker])
947 }
948 if (g_iShowSingleHud[attacker] && get_pcvar_num(cvar_Single))
949 {
950 ClearSyncHud(attacker, g_HudSyncSingle)
951 set_hudmessage(g_iSingleColor[attacker][COLOR_RED], g_iSingleColor[attacker][COLOR_GREEN], g_iSingleColor[attacker][COLOR_BLUE], g_flSinglePosition_X[attacker], g_flSinglePosition_Y[attacker], g_iSingleColor[attacker][COLOR_STYLE], 0.0, g_flSingleTime[attacker], 1.0, 1.0, -1)
952 ShowSyncHudMsg(attacker, g_HudSyncSingle, "%i", dmg_take)
953 }
954 }
955 case 1: // Player
956 {
957 if ((HudDamageWall == 2 && !user_has_flag(attacker, ACCESS_HUD) && !HudVisible) || (!HudDamageWall && !HudVisible)) return HAM_IGNORED
958
959 // Display option
960 if (g_iShowMultipleHud[attacker] && get_pcvar_num(cvar_Multiple))
961 {
962 ClearSyncHud(attacker, g_HudSyncMultiple)
963 set_hudmessage(g_iMultipleColor[attacker][COLOR_RED], g_iMultipleColor[attacker][COLOR_GREEN], g_iMultipleColor[attacker][COLOR_BLUE], g_flMultiplePosition_X[attacker], g_flMultiplePosition_Y[attacker], g_iMultipleColor[attacker][COLOR_STYLE], 0.0, g_flMultipleTime[attacker], 1.0, 1.0, -1)
964 ShowSyncHudMsg(attacker, g_HudSyncMultiple, "%i", g_iDamageDealt[attacker])
965 }
966 if (g_iShowSingleHud[attacker] && get_pcvar_num(cvar_Single))
967 {
968 ClearSyncHud(attacker, g_HudSyncSingle)
969 set_hudmessage(g_iSingleColor[attacker][COLOR_RED], g_iSingleColor[attacker][COLOR_GREEN], g_iSingleColor[attacker][COLOR_BLUE], g_flSinglePosition_X[attacker], g_flSinglePosition_Y[attacker], g_iSingleColor[attacker][COLOR_STYLE], 0.0, g_flSingleTime[attacker], 1.0, 1.0, -1)
970 ShowSyncHudMsg(attacker, g_HudSyncSingle, "%i", dmg_take)
971 }
972 }
973 }
974 return HAM_IGNORED
975}
976
977public fwd_TraceAttack(victim, attacker, Float:damage, Float:direction[3], tracehandle, damage_type)
978{
979 // Plugin off
980 if (!get_pcvar_num(cvar_BulletDamage)) return HAM_IGNORED
981
982 // Allow to trace?
983 if (!(damage_type & DMG_BULLET) || !is_user_valid_connected(attacker) || victim == attacker || (!get_pcvar_num(cvar_FFA) && cs_get_user_team(victim) == cs_get_user_team(attacker))) return HAM_IGNORED
984
985 // get bullet impacting origin
986 get_tr2(tracehandle, TR_vecEndPos, g_flWallOrigin[attacker][victim])
987
988 return HAM_IGNORED
989}
990
991public fwd_Knife_SecAtk(weapon_ent)
992{
993 // Plugin off
994 if (!get_pcvar_num(cvar_BulletDamage)) return HAM_IGNORED
995
996 // Get weapon's owner
997 static owner
998 owner = ham_cs_get_weapon_ent_owner(weapon_ent)
999
1000 // Owner not safe, bots can made records?
1001 if (!owner || !get_pcvar_num(cvar_SaveBots) && g_bIsBot[owner]) return HAM_IGNORED
1002
1003 // remove knife atk2 task
1004 remove_task(owner+TASK_KNIFE)
1005
1006 // set knife atk2
1007 g_bAttack2Knife[owner] = true
1008 set_task(0.2, "reset_atk2_knife", owner+TASK_KNIFE)
1009
1010 return HAM_IGNORED
1011}
1012
1013public fwd_Item_Deploy_Post(weapon_ent)
1014{
1015 // Get weapon's owner
1016 static owner
1017 owner = ham_cs_get_weapon_ent_owner(weapon_ent)
1018
1019 // Check Cheating (bugfix)
1020 if (g_bWhileRecordTask[owner])
1021 {
1022 // Cheat detected
1023 remove_task(owner+TASK_DAMAGE)
1024 damage_deal(owner+TASK_DAMAGE)
1025 }
1026
1027 // Store current weapon's id for reference
1028 g_iWeaponUse[owner] = cs_get_weapon_id(weapon_ent)
1029 g_iWeaponEntity[owner] = weapon_ent
1030
1031 return HAM_IGNORED
1032}
1033
1034/*================================================================================
1035 [Client Commands]
1036=================================================================================*/
1037
1038// Say "bd"
1039public clcmd_saymenu(id)
1040{
1041 if (get_pcvar_num(cvar_BulletDamage))
1042 show_menu_main(id) // show main menu
1043}
1044
1045/*================================================================================
1046 [Admin Commands]
1047=================================================================================*/
1048
1049public cmd_reset(id, level, cid)
1050{
1051 // Get Access
1052 if (!cmd_access(id, g_access_flag[ACCESS_RESET], cid, 2))
1053 {
1054 console_print(id, "[BD] %L.", id, "BD_NOT_ACCESS")
1055 return PLUGIN_HANDLED
1056 }
1057
1058 // Retrieve string arguments
1059 new arg[6]
1060 read_argv(1, arg, charsmax(arg))
1061
1062 // Switch string
1063 switch (arg[0])
1064 {
1065 case 'a':
1066 {
1067 switch (arg[1])
1068 {
1069 case 'l':
1070 {
1071 // Reset all records and give console confirmation
1072 reset_top(0, 1)
1073 console_print(id, "[BD] %L %L", id, "MENU_RESET_ALL", id, "MENU_RESET_RECORD")
1074 return PLUGIN_HANDLED
1075 }
1076 case 'k':
1077 {
1078 // Reset AK47 record and give console confirmation
1079 reset_top(CSW_AK47)
1080 console_print(id, "[BD] %s %L", WPN_NAMES[CSW_AK47], id, "MENU_RESET_RECORD")
1081 return PLUGIN_HANDLED
1082 }
1083 case 'u':
1084 {
1085 // Reset AUG record and give console confirmation
1086 reset_top(CSW_AUG)
1087 console_print(id, "[BD] %s %L", WPN_NAMES[CSW_AUG], id, "MENU_RESET_RECORD")
1088 return PLUGIN_HANDLED
1089 }
1090 case 'w':
1091 {
1092 // Reset AWP record and give console confirmation
1093 reset_top(CSW_AWP)
1094 console_print(id, "[BD] %s %L", WPN_NAMES[CSW_AWP], id, "MENU_RESET_RECORD")
1095 return PLUGIN_HANDLED
1096 }
1097 }
1098 }
1099 case 'd':
1100 {
1101 // Reset DEAGLE record and give console confirmation
1102 reset_top(CSW_DEAGLE)
1103 console_print(id, "[BD] %s %L", WPN_NAMES[CSW_DEAGLE], id, "MENU_RESET_RECORD")
1104 return PLUGIN_HANDLED
1105 }
1106 case 'e':
1107 {
1108 // Reset ELITE record and give console confirmation
1109 reset_top(CSW_ELITE)
1110 console_print(id, "[BD] %s %L", WPN_NAMES[CSW_ELITE], id, "MENU_RESET_RECORD")
1111 return PLUGIN_HANDLED
1112 }
1113 case 'f':
1114 {
1115 switch (arg[1])
1116 {
1117 case 'a':
1118 {
1119 // Reset FAMAS record and give console confirmation
1120 reset_top(CSW_FAMAS)
1121 console_print(id, "[BD] %s %L", WPN_NAMES[CSW_FAMAS], id, "MENU_RESET_RECORD")
1122 return PLUGIN_HANDLED
1123 }
1124 case 'i':
1125 {
1126 // Reset FIVESEVEN record and give console confirmation
1127 reset_top(CSW_FIVESEVEN)
1128 console_print(id, "[BD] %s %L", WPN_NAMES[CSW_FIVESEVEN], id, "MENU_RESET_RECORD")
1129 return PLUGIN_HANDLED
1130 }
1131 }
1132 }
1133 case 'g':
1134 {
1135 switch (arg[1])
1136 {
1137 case '3':
1138 {
1139 // Reset G3SG1 record and give console confirmation
1140 reset_top(CSW_G3SG1)
1141 console_print(id, "[BD] %s %L", WPN_NAMES[CSW_G3SG1], id, "MENU_RESET_RECORD")
1142 return PLUGIN_HANDLED
1143 }
1144 case 'a':
1145 {
1146 // Reset GALIL record and give console confirmation
1147 reset_top(CSW_GALIL)
1148 console_print(id, "[BD] %s %L", WPN_NAMES[CSW_GALIL], id, "MENU_RESET_RECORD")
1149 return PLUGIN_HANDLED
1150 }
1151 case 'l':
1152 {
1153 // Reset GLOCK18 record and give console confirmation
1154 reset_top(CSW_GLOCK18)
1155 console_print(id, "[BD] %s %L", WPN_NAMES[CSW_GLOCK18], id, "MENU_RESET_RECORD")
1156 return PLUGIN_HANDLED
1157 }
1158 }
1159 }
1160 case 'h':
1161 {
1162 // Reset HEGRENADE record and give console confirmation
1163 reset_top(CSW_HEGRENADE)
1164 console_print(id, "[BD] %s %L", WPN_NAMES[CSW_HEGRENADE], id, "MENU_RESET_RECORD")
1165 return PLUGIN_HANDLED
1166 }
1167 case 'k':
1168 {
1169 // Reset KNIFE record and give console confirmation
1170 reset_top(CSW_KNIFE)
1171 console_print(id, "[BD] %s %L", WPN_NAMES[CSW_KNIFE], id, "MENU_RESET_RECORD")
1172 return PLUGIN_HANDLED
1173 }
1174 case 'm':
1175 {
1176 switch (arg[1])
1177 {
1178 case '2':
1179 {
1180 // Reset M249 record and give console confirmation
1181 reset_top(CSW_M249)
1182 console_print(id, "[BD] %s %L", WPN_NAMES[CSW_M249], id, "MENU_RESET_RECORD")
1183 return PLUGIN_HANDLED
1184 }
1185 case '3':
1186 {
1187 // Reset M3 record and give console confirmation
1188 reset_top(CSW_M3)
1189 console_print(id, "[BD] %s %L", WPN_NAMES[CSW_M3], id, "MENU_RESET_RECORD")
1190 return PLUGIN_HANDLED
1191 }
1192 case '4':
1193 {
1194 // Reset M4A1 record and give console confirmation
1195 reset_top(CSW_M4A1)
1196 console_print(id, "[BD] %s %L", WPN_NAMES[CSW_M4A1], id, "MENU_RESET_RECORD")
1197 return PLUGIN_HANDLED
1198 }
1199 case 'a':
1200 {
1201 // Reset MAC10 record and give console confirmation
1202 reset_top(CSW_MAC10)
1203 console_print(id, "[BD] %s %L", WPN_NAMES[CSW_MAC10], id, "MENU_RESET_RECORD")
1204 return PLUGIN_HANDLED
1205 }
1206 case 'p':
1207 {
1208 // Reset MP5NAVY record and give console confirmation
1209 reset_top(CSW_MP5NAVY)
1210 console_print(id, "[BD] %s %L", WPN_NAMES[CSW_MP5NAVY], id, "MENU_RESET_RECORD")
1211 return PLUGIN_HANDLED
1212 }
1213 }
1214 }
1215 case 'p':
1216 {
1217 switch (arg[1])
1218 {
1219 case '2':
1220 {
1221 // Reset P228 record and give console confirmation
1222 reset_top(CSW_P228)
1223 console_print(id, "[BD] %s %L", WPN_NAMES[CSW_P228], id, "MENU_RESET_RECORD")
1224 return PLUGIN_HANDLED
1225 }
1226 case '9':
1227 {
1228 // Reset P90 record and give console confirmation
1229 reset_top(CSW_P90)
1230 console_print(id, "[BD] %s %L", WPN_NAMES[CSW_P90], id, "MENU_RESET_RECORD")
1231 return PLUGIN_HANDLED
1232 }
1233 }
1234 }
1235 case 's':
1236 {
1237 if (arg[1] == 'c')
1238 {
1239 // Reset SCOUT record and give console confirmation
1240 reset_top(CSW_SCOUT)
1241 console_print(id, "[BD] %s %L", WPN_NAMES[CSW_SCOUT], id, "MENU_RESET_RECORD")
1242 return PLUGIN_HANDLED
1243 }
1244 else if (arg[4] == '0')
1245 {
1246 // Reset SG550 record and give console confirmation
1247 reset_top(CSW_SG550)
1248 console_print(id, "[BD] %s %L", WPN_NAMES[CSW_SG550], id, "MENU_RESET_RECORD")
1249 return PLUGIN_HANDLED
1250 }
1251 else if (arg[4] == '2')
1252 {
1253 // Reset SG552 record and give console confirmation
1254 reset_top(CSW_SG552)
1255 console_print(id, "[BD] %s %L", WPN_NAMES[CSW_SG552], id, "MENU_RESET_RECORD")
1256 return PLUGIN_HANDLED
1257 }
1258 }
1259 case 't':
1260 {
1261 // Reset TMP record and give console confirmation
1262 reset_top(CSW_TMP)
1263 console_print(id, "[BD] %s %L", WPN_NAMES[CSW_TMP], id, "MENU_RESET_RECORD")
1264 return PLUGIN_HANDLED
1265 }
1266 case 'u':
1267 {
1268 switch (arg[1])
1269 {
1270 case 's':
1271 {
1272 // Reset USP record and give console confirmation
1273 reset_top(CSW_USP)
1274 console_print(id, "[BD] %s %L", WPN_NAMES[CSW_USP], id, "MENU_RESET_RECORD")
1275 return PLUGIN_HANDLED
1276 }
1277 case 'm':
1278 {
1279 // Reset UMP45 record and give console confirmation
1280 reset_top(CSW_UMP45)
1281 console_print(id, "[BD] %s %L", WPN_NAMES[CSW_UMP45], id, "MENU_RESET_RECORD")
1282 return PLUGIN_HANDLED
1283 }
1284 }
1285 }
1286 case 'x':
1287 {
1288 // Reset XM1014 record and give console confirmation
1289 reset_top(CSW_XM1014)
1290 console_print(id, "[BD] %s %L", WPN_NAMES[CSW_XM1014], id, "MENU_RESET_RECORD")
1291 return PLUGIN_HANDLED
1292 }
1293 }
1294
1295 // Retrieve integer arguments
1296 new weapon
1297 weapon = str_to_num(arg)
1298
1299 // Switch integer
1300 if (!is_ignore_weapon_id(weapon) && weapon > 0 && weapon < 31)
1301 {
1302 // Reset "argument" record and give console confirmation
1303 reset_top(weapon)
1304 console_print(id, "[BD] %s %L", WPN_NAMES[weapon], id, "MENU_RESET_RECORD")
1305 return PLUGIN_HANDLED
1306 }
1307 else
1308 {
1309 // Error :(
1310 console_print(id, "[BD] %L", id, "MENU_RESET_UNKNOWN")
1311 }
1312 return PLUGIN_HANDLED
1313}
1314
1315/*================================================================================
1316 [Menus]
1317=================================================================================*/
1318
1319// Main Menu
1320show_menu_main(id)
1321{
1322 static menu[512], len
1323 len = 0
1324
1325 // Title
1326 len += formatex(menu[len], charsmax(menu) - len, "\yBullet Damage^n^n")
1327
1328 // 1. Hud Single Damage
1329 if (!get_pcvar_num(cvar_Single))
1330 len += formatex(menu[len], charsmax(menu) - len, "\d1. %L [%L]^n", id, "MENU_SINGLE", id, "MENU_OFF")
1331 else if (g_iShowSingleHud[id])
1332 len += formatex(menu[len], charsmax(menu) - len, "\r1.\w %L\y [%L]^n", id, "MENU_SINGLE", id, "MENU_ON")
1333 else
1334 len += formatex(menu[len], charsmax(menu) - len, "\r1.\w %L\y [\r%L\y]^n", id, "MENU_SINGLE", id, "MENU_OFF")
1335
1336 // 2. Hud Multi Damage
1337 if (!get_pcvar_num(cvar_Multiple))
1338 len += formatex(menu[len], charsmax(menu) - len, "\d2. %L [%L]^n", id, "MENU_MULTI", id, "MENU_OFF")
1339 else if (g_iShowMultipleHud[id])
1340 len += formatex(menu[len], charsmax(menu) - len, "\r2.\w %L\y [%L]^n", id, "MENU_MULTI", id, "MENU_ON")
1341 else
1342 len += formatex(menu[len], charsmax(menu) - len, "\r2.\w %L\y [\r%L\y]^n", id, "MENU_MULTI", id, "MENU_OFF")
1343
1344 // 3. Hud HE Damage
1345 if (!get_pcvar_num(cvar_GrenadeDamage))
1346 len += formatex(menu[len], charsmax(menu) - len, "\d3. %L [%L]^n", id, "MENU_GRENADE", id, "MENU_OFF")
1347 else if (g_iShowGrenadeHud[id])
1348 len += formatex(menu[len], charsmax(menu) - len, "\r3.\w %L\y [%L]^n", id, "MENU_GRENADE", id, "MENU_ON")
1349 else
1350 len += formatex(menu[len], charsmax(menu) - len, "\r3.\w %L\y [\r%L\y]^n", id, "MENU_GRENADE", id, "MENU_OFF")
1351
1352 // 4. Hud Take Damage
1353 if (!get_pcvar_num(cvar_TakeDamage))
1354 len += formatex(menu[len], charsmax(menu) - len, "\d4. %L [%L]^n^n", id, "MENU_TAKE", id, "MENU_OFF")
1355 else if (g_iShowTakeHud[id])
1356 len += formatex(menu[len], charsmax(menu) - len, "\r4.\w %L\y [%L]^n^n", id, "MENU_TAKE", id, "MENU_ON")
1357 else
1358 len += formatex(menu[len], charsmax(menu) - len, "\r4.\w %L\y [\r%L\y]^n^n", id, "MENU_TAKE", id, "MENU_OFF")
1359
1360 // 5. Configuration Menu
1361 len += formatex(menu[len], charsmax(menu) - len, "\r5.\w %L^n^n", id, "MENU_CONFIG_TITLE")
1362
1363 // 6. Top Damage: Personal
1364 if (!get_pcvar_num(cvar_SaveStatsPersonal))
1365 len += formatex(menu[len], charsmax(menu) - len, "\d6. %L^n", id, "MENU_TOP_PER")
1366 else
1367 len += formatex(menu[len], charsmax(menu) - len, "\r6.\w %L^n", id, "MENU_TOP_PER")
1368
1369 // 7. Top Damage: All
1370 if (!get_pcvar_num(cvar_SaveStats))
1371 len += formatex(menu[len], charsmax(menu) - len, "\d7. %L^n^n", id, "MENU_TOP_ALL")
1372 else
1373 len += formatex(menu[len], charsmax(menu) - len, "\r7.\w %L^n^n", id, "MENU_TOP_ALL")
1374
1375 // 9. Admin Menu
1376 if (user_has_flag(id, ACCESS_RESET))
1377 len += formatex(menu[len], charsmax(menu) - len, "\r9.\w %L", id, "MENU_ADMIN_TITLE")
1378 else
1379 len += formatex(menu[len], charsmax(menu) - len, "\d9. %L", id, "MENU_ADMIN_TITLE")
1380
1381 // 0. Exit
1382 len += formatex(menu[len], charsmax(menu) - len, "^n^n\r0.\w %L", id, "MENU_EXIT")
1383
1384 show_menu(id, KEYSMENU, menu, -1, "Main Menu")
1385}
1386
1387// Configuration Menu
1388show_menu_config(id)
1389{
1390 static menu[512], len
1391 len = 0
1392
1393 // Title
1394 len += formatex(menu[len], charsmax(menu) - len, "\y%L^n^n", id, "MENU_CONFIG_TITLE")
1395
1396 // 1. Single
1397 len += formatex(menu[len], charsmax(menu) - len, "\r1.\w %L %L^n", id, "MENU_SINGLE_TITLE", id, "MENU_MENU")
1398
1399 // 2. Multiple
1400 len += formatex(menu[len], charsmax(menu) - len, "\r2.\w %L %L^n", id, "MENU_MULTI_TITLE", id, "MENU_MENU")
1401
1402 // 3. Grenade
1403 len += formatex(menu[len], charsmax(menu) - len, "\r3.\w %L %L^n", id, "MENU_GRENADE_TITLE", id, "MENU_MENU")
1404
1405 // 4. Take
1406 len += formatex(menu[len], charsmax(menu) - len, "\r4.\w %L %L^n^n", id, "MENU_TAKE_TITLE", id, "MENU_MENU")
1407
1408 // 5. Save
1409 len += formatex(menu[len], charsmax(menu) - len, "\r5.\w %L", id, "MENU_SAVE_TITLE")
1410
1411 // 0. Back / Exit
1412 len += formatex(menu[len], charsmax(menu) - len, "^n^n\r0.\w %L / %L", id, "MENU_BACK", id, "MENU_EXIT")
1413
1414 show_menu(id, KEYSMENU, menu, -1, "Config Menu")
1415}
1416
1417// Dynamic (single, multi, grenade & take)
1418show_menu_dynamic_main(id)
1419{
1420 static menu[512], len
1421 len = 0
1422
1423 // Dynamic ?
1424 switch (g_iDynamicMenu[id])
1425 {
1426 case 0: // Single
1427 {
1428 // Title
1429 len += formatex(menu[len], charsmax(menu) - len, "\y%L %L^n^n", id, "MENU_SINGLE_TITLE", id, "MENU_MENU")
1430
1431 // 1. Color
1432 len += formatex(menu[len], charsmax(menu) - len, "\r1.\w %L^n", id, "MENU_DYNAMIC_COLOR")
1433
1434 // 2. Style
1435 if (g_iSingleColor[id][COLOR_STYLE])
1436 len += formatex(menu[len], charsmax(menu) - len, "\r2.\w %L\y [%L]^n", id, "MENU_DYNAMIC_STYLE", id, "MENU_ON")
1437 else
1438 len += formatex(menu[len], charsmax(menu) - len, "\r2.\w %L\y [%L]^n", id, "MENU_DYNAMIC_STYLE", id, "MENU_OFF")
1439
1440 // 3. Position
1441 len += formatex(menu[len], charsmax(menu) - len, "\r3.\w %L^n", id, "MENU_DYNAMIC_POSI")
1442
1443 // 4. Holdtime
1444 len += formatex(menu[len], charsmax(menu) - len, "\r4.\w %L\y [%.1f %L]^n^n", id, "MENU_DYNAMIC_TIME", g_flSingleTime[id], id, "MENU_SECONDS")
1445 }
1446 case 1: // Multi
1447 {
1448 // Title
1449 len += formatex(menu[len], charsmax(menu) - len, "\y%L %L^n^n", id, "MENU_MULTI_TITLE", id, "MENU_MENU")
1450
1451 // 1. Color
1452 len += formatex(menu[len], charsmax(menu) - len, "\r1.\w %L^n", id, "MENU_DYNAMIC_COLOR")
1453
1454 // 2. Style
1455 if (g_iMultipleColor[id][COLOR_STYLE])
1456 len += formatex(menu[len], charsmax(menu) - len, "\r2.\w %L\y [%L]^n", id, "MENU_DYNAMIC_STYLE", id, "MENU_ON")
1457 else
1458 len += formatex(menu[len], charsmax(menu) - len, "\r2.\w %L\y [%L]^n", id, "MENU_DYNAMIC_STYLE", id, "MENU_OFF")
1459
1460 // 3. Position
1461 len += formatex(menu[len], charsmax(menu) - len, "\r3.\w %L^n", id, "MENU_DYNAMIC_POSI")
1462
1463 // 4. Holdtime
1464 len += formatex(menu[len], charsmax(menu) - len, "\r4.\w %L\y [%.1f %L]^n^n", id, "MENU_DYNAMIC_TIME", g_flMultipleTime[id], id, "MENU_SECONDS")
1465 }
1466 case 2: // Grenade
1467 {
1468 // Title
1469 len += formatex(menu[len], charsmax(menu) - len, "\y%L %L^n^n", id, "MENU_GRENADE_TITLE", id, "MENU_MENU")
1470
1471 // 1. Color
1472 len += formatex(menu[len], charsmax(menu) - len, "\r1.\w %L^n", id, "MENU_DYNAMIC_COLOR")
1473
1474 // 2. Style
1475 if (g_iGrenadeColor[id][COLOR_STYLE])
1476 len += formatex(menu[len], charsmax(menu) - len, "\r2.\w %L\y [%L]^n", id, "MENU_DYNAMIC_STYLE", id, "MENU_ON")
1477 else
1478 len += formatex(menu[len], charsmax(menu) - len, "\r2.\w %L\y [%L]^n", id, "MENU_DYNAMIC_STYLE", id, "MENU_OFF")
1479
1480 // 3. Position
1481 len += formatex(menu[len], charsmax(menu) - len, "\r3.\w %L^n", id, "MENU_DYNAMIC_POSI")
1482
1483 // 4. Holdtime
1484 len += formatex(menu[len], charsmax(menu) - len, "\r4.\w %L\y [%.1f %L]^n^n", id, "MENU_DYNAMIC_TIME", g_flGrenadeTime[id], id, "MENU_SECONDS")
1485 }
1486 case 3: // Take
1487 {
1488 // Title
1489 len += formatex(menu[len], charsmax(menu) - len, "\y%L %L^n^n", id, "MENU_TAKE_TITLE", id, "MENU_MENU")
1490
1491 // 1. Color
1492 len += formatex(menu[len], charsmax(menu) - len, "\r1.\w %L^n", id, "MENU_DYNAMIC_COLOR")
1493
1494 // 2. Style
1495 if (g_iTakeColor[id][COLOR_STYLE])
1496 len += formatex(menu[len], charsmax(menu) - len, "\r2.\w %L\y [%L]^n", id, "MENU_DYNAMIC_STYLE", id, "MENU_ON")
1497 else
1498 len += formatex(menu[len], charsmax(menu) - len, "\r2.\w %L\y [%L]^n", id, "MENU_DYNAMIC_STYLE", id, "MENU_OFF")
1499
1500 // 3. Position
1501 len += formatex(menu[len], charsmax(menu) - len, "\r3.\w %L^n", id, "MENU_DYNAMIC_POSI")
1502
1503 // 4. Holdtime
1504 len += formatex(menu[len], charsmax(menu) - len, "\r4.\w %L\y [%.1f %L]^n^n", id, "MENU_DYNAMIC_TIME", g_flTakeTime[id], id, "MENU_SECONDS")
1505 }
1506 }
1507
1508 // 5. Test
1509 len += formatex(menu[len], charsmax(menu) - len, "\r5.\w %L", id, "MENU_TEST_TITLE")
1510
1511 // 0. Back / Exit
1512 len += formatex(menu[len], charsmax(menu) - len, "^n^n\r0.\w %L / %L", id, "MENU_BACK", id, "MENU_EXIT")
1513
1514 show_menu(id, KEYSMENU, menu, -1, "Dynamic Menu Main")
1515}
1516
1517// Dynamic Color (single, multi, grenade & take)
1518show_menu_dynamic_color(id)
1519{
1520 static menu[512], len
1521 len = 0
1522
1523 // Dynamic ?
1524 switch (g_iDynamicMenu[id])
1525 {
1526 case 0: // Single
1527 {
1528 // Title
1529 len += formatex(menu[len], charsmax(menu) - len, "\y%L %L^n^n", id, "MENU_SINGLE_TITLE", id, "MENU_DYNAMIC_COLOR")
1530 }
1531 case 1: // Multi
1532 {
1533 // Title
1534 len += formatex(menu[len], charsmax(menu) - len, "\y%L %L^n^n", id, "MENU_MULTI_TITLE", id, "MENU_DYNAMIC_COLOR")
1535 }
1536 case 2: // Grenade
1537 {
1538 // Title
1539 len += formatex(menu[len], charsmax(menu) - len, "\y%L %L^n^n", id, "MENU_GRENADE_TITLE", id, "MENU_DYNAMIC_COLOR")
1540 }
1541 case 3: // Take
1542 {
1543 // Title
1544 len += formatex(menu[len], charsmax(menu) - len, "\y%L %L^n^n", id, "MENU_TAKE_TITLE", id, "MENU_DYNAMIC_COLOR")
1545 }
1546 }
1547
1548 // 1. Red Color
1549 len += formatex(menu[len], charsmax(menu) - len, "\r1.\w %L^n", id, "MENU_COLOR_RED")
1550
1551 // 2. Green Color
1552 len += formatex(menu[len], charsmax(menu) - len, "\r2.\w %L^n", id, "MENU_COLOR_GREEN")
1553
1554 // 3. Blue Color
1555 len += formatex(menu[len], charsmax(menu) - len, "\r3.\w %L^n", id, "MENU_COLOR_BLUE")
1556
1557 // 4. Yellow Color
1558 len += formatex(menu[len], charsmax(menu) - len, "\r4.\w %L^n", id, "MENU_COLOR_YELLOW")
1559
1560 // 5. Cyan Color
1561 len += formatex(menu[len], charsmax(menu) - len, "\r5.\w %L^n", id, "MENU_COLOR_CYAN")
1562
1563 // 6. White Color
1564 len += formatex(menu[len], charsmax(menu) - len, "\r6.\w %L", id, "MENU_COLOR_WHITE")
1565
1566 // 0. Back / Exit
1567 len += formatex(menu[len], charsmax(menu) - len, "^n^n\r0.\w %L / %L", id, "MENU_BACK", id, "MENU_EXIT")
1568
1569 show_menu(id, KEYSMENU, menu, -1, "Dynamic Menu Color")
1570}
1571
1572// Dynamic Positions (single, multi, grenade & take)
1573show_menu_dynamic_posi(id)
1574{
1575 static menu[512], len
1576 len = 0
1577
1578 // Dynamic ?
1579 switch (g_iDynamicMenu[id])
1580 {
1581 case 0: // Single
1582 {
1583 // Title
1584 len += formatex(menu[len], charsmax(menu) - len, "\y%L %L^n^n", id, "MENU_SINGLE_TITLE", id, "MENU_DYNAMIC_POSI")
1585
1586 // Info
1587 len += formatex(menu[len], charsmax(menu) - len, "\y%L \w[X: %.2f - Y: %.2f]^n^n", id, "MENU_DYNAMIC_POSI", g_flSinglePosition_X[id], g_flSinglePosition_Y[id])
1588 }
1589 case 1: // Multi
1590 {
1591 // Title
1592 len += formatex(menu[len], charsmax(menu) - len, "\y%L %L^n^n", id, "MENU_MULTI_TITLE", id, "MENU_DYNAMIC_POSI")
1593
1594 // Info
1595 len += formatex(menu[len], charsmax(menu) - len, "\y%L \w[X: %.2f - Y: %.2f]^n^n", id, "MENU_DYNAMIC_POSI", g_flMultiplePosition_X[id], g_flMultiplePosition_Y[id])
1596 }
1597 case 2: // Grenade
1598 {
1599 // Title
1600 len += formatex(menu[len], charsmax(menu) - len, "\y%L %L^n^n", id, "MENU_GRENADE_TITLE", id, "MENU_DYNAMIC_POSI")
1601
1602 // Info
1603 len += formatex(menu[len], charsmax(menu) - len, "\y%L \w[X: %.2f - Y: %.2f]^n^n", id, "MENU_DYNAMIC_POSI", g_flGrenadePosition_X[id], g_flGrenadePosition_Y[id])
1604 }
1605 case 3: // Take
1606 {
1607 // Title
1608 len += formatex(menu[len], charsmax(menu) - len, "\y%L %L^n^n", id, "MENU_TAKE_TITLE", id, "MENU_DYNAMIC_POSI")
1609
1610 // Info
1611 len += formatex(menu[len], charsmax(menu) - len, "\y%L \w[X: %.2f - Y: %.2f]^n^n", id, "MENU_DYNAMIC_POSI", g_flTakePosition_X[id], g_flTakePosition_Y[id])
1612 }
1613 }
1614
1615 // 1. Up
1616 len += formatex(menu[len], charsmax(menu) - len, "\r1.\w %L^n", id, "MENU_POSI_UP")
1617
1618 // 2. Down
1619 len += formatex(menu[len], charsmax(menu) - len, "\r2.\w %L^n", id, "MENU_POSI_DOWN")
1620
1621 // 3. Right
1622 len += formatex(menu[len], charsmax(menu) - len, "\r3.\w %L^n", id, "MENU_POSI_RIGHT")
1623
1624 // 4. Left
1625 len += formatex(menu[len], charsmax(menu) - len, "\r4.\w %L^n^n", id, "MENU_POSI_LEFT")
1626
1627 // 5. Type
1628 len += formatex(menu[len], charsmax(menu) - len, "\r5.\w %L: \y[\w%s\y]", id, "MENU_POSI_TYPE", g_iMenuType[id] ? "0.1" : "0.01")
1629
1630 // 0. Back / Exit
1631 len += formatex(menu[len], charsmax(menu) - len, "^n^n\r0.\w %L / %L", id, "MENU_BACK", id, "MENU_EXIT")
1632
1633 show_menu(id, KEYSMENU, menu, -1, "Dynamic Menu Posi")
1634}
1635
1636// Dynamic Holdtime (single, multi, grenade & take)
1637show_menu_dynamic_time(id)
1638{
1639 static menu[512], len
1640 len = 0
1641
1642 // Dynamic ?
1643 switch (g_iDynamicMenu[id])
1644 {
1645 case 0: // Single
1646 {
1647 // Title
1648 len += formatex(menu[len], charsmax(menu) - len, "\y%L %L^n^n", id, "MENU_SINGLE_TITLE", id, "MENU_DYNAMIC_TIME")
1649
1650 // Info
1651 len += formatex(menu[len], charsmax(menu) - len, "\y%L \w[%.1f %L]^n^n", id, "MENU_DYNAMIC_TIME", g_flSingleTime[id], id, "MENU_SECONDS")
1652 }
1653 case 1: // Multi
1654 {
1655 // Title
1656 len += formatex(menu[len], charsmax(menu) - len, "\y%L %L^n^n", id, "MENU_MULTI_TITLE", id, "MENU_DYNAMIC_TIME")
1657
1658 // Info
1659 len += formatex(menu[len], charsmax(menu) - len, "\y%L \w[%.1f %L]^n^n", id, "MENU_DYNAMIC_TIME", g_flMultipleTime[id], id, "MENU_SECONDS")
1660 }
1661 case 2: // Grenade
1662 {
1663 // Title
1664 len += formatex(menu[len], charsmax(menu) - len, "\y%L %L^n^n", id, "MENU_GRENADE_TITLE", id, "MENU_DYNAMIC_TIME")
1665
1666 // Info
1667 len += formatex(menu[len], charsmax(menu) - len, "\y%L \w[%.1f %L]^n^n", id, "MENU_DYNAMIC_TIME", g_flGrenadeTime[id], id, "MENU_SECONDS")
1668 }
1669 case 3: // Take
1670 {
1671 // Title
1672 len += formatex(menu[len], charsmax(menu) - len, "\y%L %L^n^n", id, "MENU_TAKE_TITLE", id, "MENU_DYNAMIC_TIME")
1673
1674 // Info
1675 len += formatex(menu[len], charsmax(menu) - len, "\y%L \w[%.1f %L]^n^n", id, "MENU_DYNAMIC_TIME", g_flTakeTime[id], id, "MENU_SECONDS")
1676 }
1677 }
1678
1679 // 1. Increase
1680 len += formatex(menu[len], charsmax(menu) - len, "\r1.\w %L^n", id, "MENU_TIME_UP")
1681
1682 // 2. Decrease
1683 len += formatex(menu[len], charsmax(menu) - len, "\r2.\w %L^n^n", id, "MENU_TIME_DOWN")
1684
1685 // 3. Type
1686 len += formatex(menu[len], charsmax(menu) - len, "\r3.\w %L: \y[\w%s\y]^n^n", id, "MENU_POSI_TYPE", g_iMenuType[id] ? "1.0" : "0.1")
1687
1688 // 4. Test
1689 len += formatex(menu[len], charsmax(menu) - len, "\r4.\w %L", id, "MENU_TEST_TITLE")
1690
1691 // 0. Back / Exit
1692 len += formatex(menu[len], charsmax(menu) - len, "^n^n\r0.\w %L / %L", id, "MENU_BACK", id, "MENU_EXIT")
1693
1694 show_menu(id, KEYSMENU, menu, -1, "Dynamic Menu Time")
1695}
1696
1697// Player List Menu
1698show_menu_player_list(id)
1699{
1700 static menuid, menu[128], player, buffer[2]
1701
1702 // Title
1703 formatex(menu, charsmax(menu), "\y%L\r", id, "MENU_TOP_PER")
1704
1705 // Create Menu
1706 menuid = menu_create(menu, "menu_player_list")
1707
1708 // Player List
1709 for (player = 1; player <= g_iMaxPlayers; player++)
1710 {
1711 // Skip if not connected
1712 if (!g_bIsConnected[player]) continue
1713
1714 // Format text depending on the action to take
1715 formatex(menu, charsmax(menu), "%s", g_szPlayerName[player])
1716
1717 // Add player
1718 buffer[0] = player
1719 buffer[1] = 0
1720 menu_additem(menuid, menu, buffer)
1721 }
1722
1723 // Back - Next - Exit
1724 formatex(menu, charsmax(menu), "%L", id, "MENU_BACK")
1725 menu_setprop(menuid, MPROP_BACKNAME, menu)
1726 formatex(menu, charsmax(menu), "%L", id, "MENU_NEXT")
1727 menu_setprop(menuid, MPROP_NEXTNAME, menu)
1728 formatex(menu, charsmax(menu), "%L", id, "MENU_EXIT")
1729 menu_setprop(menuid, MPROP_EXITNAME, menu)
1730
1731 menu_display(id, menuid)
1732}
1733
1734// Admin Menu
1735show_menu_admin(id)
1736{
1737 static menuid, menu[128], weapon, buffer[2]
1738
1739 // Title
1740 formatex(menu, charsmax(menu), "\y%L\r", id, "MENU_ADMIN_TITLE")
1741
1742 // Create Menu
1743 menuid = menu_create(menu, "menu_weapon_list")
1744
1745 // Weapon List
1746 for (weapon = 0; weapon <= CSW_P90; weapon++)
1747 {
1748 // Skip if ignore weapon
1749 if (is_ignore_weapon_id(weapon)) continue
1750
1751 // Format text depending on the action to take
1752 if (weapon == 0)
1753 formatex(menu, charsmax(menu), "%L", id, "MENU_RESET_ALL")
1754 else
1755 formatex(menu, charsmax(menu), "%s", WPN_NAMES[weapon])
1756
1757 // Add player
1758 buffer[0] = weapon
1759 buffer[1] = 0
1760 menu_additem(menuid, menu, buffer)
1761 }
1762
1763 // Back - Next - Exit
1764 formatex(menu, charsmax(menu), "%L", id, "MENU_BACK")
1765 menu_setprop(menuid, MPROP_BACKNAME, menu)
1766 formatex(menu, charsmax(menu), "%L", id, "MENU_NEXT")
1767 menu_setprop(menuid, MPROP_NEXTNAME, menu)
1768 formatex(menu, charsmax(menu), "%L", id, "MENU_EXIT")
1769 menu_setprop(menuid, MPROP_EXITNAME, menu)
1770
1771 menu_display(id, menuid)
1772}
1773
1774// Show Top Damage (all)
1775public show_top_all(id)
1776{
1777 // Not Connected (bugfix)
1778 if (!g_bIsConnected[id] || g_bMotdPrepair) return
1779
1780 // Prepair motd starts
1781 g_bMotdPrepair = true
1782
1783 static buffer[2048], len
1784 len = format(buffer, charsmax(buffer), "<body bgcolor=#000000><font color=#FFB000><pre>")
1785 len += format(buffer[len], charsmax(buffer) - len, "%7s %-22.22s %6s %4s %5s^n", "Weapon", "Nick", "Damage", "Hits", "Yours")
1786
1787 if (get_pcvar_num(cvar_MotdSort))
1788 {
1789 // most damage sorting methode
1790 for (new j = CSW_P228; j <= CSW_P90; j++)
1791 g_iRecord[j] = g_iCachedDamage[j]
1792
1793 new record
1794 for (new i = CSW_P228; i <= MOTD_MAX_WEAPONS; i++)
1795 {
1796 record = get_record()
1797
1798 if (record)
1799 len += format(buffer[len], charsmax(buffer) - len, "%7s %-22.22s %6i %4i %5s^n",
1800 WPN_SHORTNAMES[record], g_szCachedNames[record], g_iCachedDamage[record], g_iCachedHits[record],
1801 (equali(g_szPlayerName[id], g_szCachedNames[record])) ? " *" : "")
1802 }
1803 }
1804 else
1805 {
1806 for (new i = CSW_P228; i <= CSW_P90; i++)
1807 {
1808 if (is_ignore_weapon_id(i)) continue
1809
1810 len += format(buffer[len], charsmax(buffer) - len, "%7s %-22.22s %6i %4i %5s^n",
1811 WPN_SHORTNAMES[i], g_szCachedNames[i], g_iCachedDamage[i], g_iCachedHits[i],
1812 (equali(g_szPlayerName[id], g_szCachedNames[i])) ? " *" : "")
1813 }
1814 }
1815
1816 // Show motd
1817 new motd[64]
1818 formatex(motd[0], charsmax(motd), "%L", id, "MENU_TOP_ALL")
1819 show_motd(id, buffer, motd)
1820
1821 // Prepair motd ends (bugfix)
1822 g_bMotdPrepair = false
1823}
1824
1825// Show Top Damage (personal)
1826public show_top_personal(id, other)
1827{
1828 // Not Connected (bugfix)
1829 if (!g_bIsConnected[id] || !g_bIsConnected[other] || g_bMotdPrepair) return
1830
1831 // Prepair motd starts
1832 g_bMotdPrepair = true
1833
1834 static buffer[2048], len
1835 len = format(buffer, charsmax(buffer), "<body bgcolor=#000000><font color=#FFB000><pre>")
1836 len += format(buffer[len], charsmax(buffer) - len, "%7s %6s %4s %5s^n", "Weapon", "Damage", "Hits", "Top")
1837
1838 if (get_pcvar_num(cvar_MotdSort))
1839 {
1840 // most damage sorting methode
1841 for (new j = CSW_P228; j <= CSW_P90; j++)
1842 g_iRecord[j] = g_iPersonalDamage[other][j]
1843
1844 new record
1845 for (new i = CSW_P228; i <= MOTD_MAX_WEAPONS; i++)
1846 {
1847 record = get_record()
1848
1849 if (record)
1850 len += format(buffer[len], charsmax(buffer) - len, "%7s %6i %4i %5s^n",
1851 WPN_SHORTNAMES[record], g_iPersonalDamage[other][record], g_iPersonalHits[other][record],
1852 (g_iPersonalDamage[other][record] == g_iCachedDamage[record]) ? " *" : "")
1853 }
1854 }
1855 else
1856 {
1857 for (new i = CSW_P228; i <= CSW_P90; i++)
1858 {
1859 if (is_ignore_weapon_id(i)) continue
1860
1861 len += format(buffer[len], charsmax(buffer) - len, "%7s %6i %4i %5s^n",
1862 WPN_SHORTNAMES[i], g_iPersonalDamage[other][i], g_iPersonalHits[other][i],
1863 (g_iPersonalDamage[other][i] == g_iCachedDamage[i]) ? " *" : "")
1864 }
1865 }
1866
1867 // Show motd
1868 new motd[96]
1869 formatex(motd[0], charsmax(motd), "%L (%s)", id, "MENU_TOP_PER", g_szPlayerName[other])
1870 show_motd(id, buffer, motd)
1871
1872 // Prepair motd ends (bugfix)
1873 g_bMotdPrepair = false
1874}
1875
1876/*================================================================================
1877 [Menu Handlers]
1878=================================================================================*/
1879
1880// Main Menu
1881public menu_main(id, key)
1882{
1883 switch (key)
1884 {
1885 case 0: // Hud Single Damage
1886 {
1887 if (get_pcvar_num(cvar_Single))
1888 g_iShowSingleHud[id] = !(g_iShowSingleHud[id])
1889
1890 show_menu_main(id)
1891 }
1892 case 1: // Hud Multi Damage
1893 {
1894 if (get_pcvar_num(cvar_Multiple))
1895 g_iShowMultipleHud[id] = !(g_iShowMultipleHud[id])
1896
1897 show_menu_main(id)
1898 }
1899 case 2: // Hud Grenade Damage
1900 {
1901 if (get_pcvar_num(cvar_GrenadeDamage))
1902 g_iShowGrenadeHud[id] = !(g_iShowGrenadeHud[id])
1903
1904 show_menu_main(id)
1905 }
1906 case 3: // Hud Take Damage
1907 {
1908 if (get_pcvar_num(cvar_TakeDamage))
1909 g_iShowTakeHud[id] = !(g_iShowTakeHud[id])
1910
1911 show_menu_main(id)
1912 }
1913 case 4: // Configuration Menu
1914 {
1915 g_iMenuType[id] = 0
1916 show_menu_config(id)
1917 }
1918 case 5: // Top Damage: Personal
1919 {
1920 if (get_pcvar_num(cvar_SaveStatsPersonal))
1921 show_menu_player_list(id)
1922 else
1923 show_menu_main(id)
1924 }
1925 case 6: // Top Damage: All
1926 {
1927 if (get_pcvar_num(cvar_SaveStats))
1928 show_top_all(id)
1929
1930 show_menu_main(id)
1931 }
1932 case 7: // nothing
1933 {
1934 show_menu_main(id)
1935 }
1936 case 8: // Admin Menu
1937 {
1938 // Check if player has the required access
1939 if (user_has_flag(id, ACCESS_RESET))
1940 show_menu_admin(id)
1941 else
1942 colored_print(id, "^x04[BD]^x01 %L", id, "BD_NOT_ACCESS")
1943 }
1944 }
1945 return PLUGIN_HANDLED
1946}
1947
1948// Config Menu
1949public menu_config(id, key)
1950{
1951 g_iDynamicMenu[id] = key
1952
1953 switch (key)
1954 {
1955 case 0,1,2,3: // Single, Multi, Grenade, Take
1956 {
1957 test_hud_vars(id)
1958 show_menu_dynamic_main(id)
1959 }
1960 case 4: // Save
1961 {
1962 save_hud_vars(id)
1963 show_menu_config(id)
1964 colored_print(id, "^x04[BD]^x01 %L", id, "MENU_SAVED")
1965 }
1966 case 9: // Back / Exit
1967 {
1968 show_menu_main(id)
1969 }
1970 default: show_menu_config(id)
1971 }
1972 return PLUGIN_HANDLED
1973}
1974
1975// Dynamic Menu Main
1976public menu_dynamic_main(id, key)
1977{
1978 switch (key)
1979 {
1980 case 0: // Color
1981 {
1982 test_hud_vars(id)
1983 show_menu_dynamic_color(id)
1984 }
1985 case 1: // Style
1986 {
1987 switch (g_iDynamicMenu[id])
1988 {
1989 case 0: g_iSingleColor[id][COLOR_STYLE] = !(g_iSingleColor[id][COLOR_STYLE]) // Single
1990 case 1: g_iMultipleColor[id][COLOR_STYLE] = !(g_iMultipleColor[id][COLOR_STYLE]) // Multi
1991 case 2: g_iGrenadeColor[id][COLOR_STYLE] = !(g_iGrenadeColor[id][COLOR_STYLE]) // Grenade
1992 case 3: g_iTakeColor[id][COLOR_STYLE] = !(g_iTakeColor[id][COLOR_STYLE]) // Take
1993 }
1994 test_hud_vars(id)
1995 show_menu_dynamic_main(id)
1996 }
1997 case 2: // Position
1998 {
1999 test_hud_vars(id)
2000 show_menu_dynamic_posi(id)
2001 }
2002 case 3: // Holdtime
2003 {
2004 test_hud_vars(id)
2005 show_menu_dynamic_time(id)
2006 }
2007 case 4: // Test
2008 {
2009 test_hud_vars(id)
2010 show_menu_dynamic_main(id)
2011 }
2012 case 9: // Back / Exit
2013 {
2014 show_menu_config(id)
2015 }
2016 default: show_menu_dynamic_main(id)
2017 }
2018 return PLUGIN_HANDLED
2019}
2020
2021// Dynamic Menu Color
2022public menu_dynamic_color(id, key)
2023{
2024 switch (key)
2025 {
2026 case 0: // Red
2027 {
2028 switch (g_iDynamicMenu[id])
2029 {
2030 case 0: // Single
2031 {
2032 g_iSingleColor[id][COLOR_RED] = 200
2033 g_iSingleColor[id][COLOR_GREEN] = g_iSingleColor[id][COLOR_BLUE] = 0
2034 }
2035 case 1: // Multi
2036 {
2037 g_iMultipleColor[id][COLOR_RED] = 200
2038 g_iMultipleColor[id][COLOR_GREEN] = g_iMultipleColor[id][COLOR_BLUE] = 0
2039 }
2040 case 2: // Grenade
2041 {
2042 g_iGrenadeColor[id][COLOR_RED] = 200
2043 g_iGrenadeColor[id][COLOR_GREEN] = g_iGrenadeColor[id][COLOR_BLUE] = 0
2044 }
2045 case 3: // Take
2046 {
2047 g_iTakeColor[id][COLOR_RED] = 200
2048 g_iTakeColor[id][COLOR_GREEN] = g_iTakeColor[id][COLOR_BLUE] = 0
2049 }
2050 }
2051 test_hud_vars(id)
2052 show_menu_dynamic_color(id)
2053 }
2054 case 1: // Green
2055 {
2056 switch (g_iDynamicMenu[id])
2057 {
2058 case 0: // Single
2059 {
2060 g_iSingleColor[id][COLOR_RED] = g_iSingleColor[id][COLOR_BLUE] = 0
2061 g_iSingleColor[id][COLOR_GREEN] = 200
2062 }
2063 case 1: // Multi
2064 {
2065 g_iMultipleColor[id][COLOR_RED] = g_iMultipleColor[id][COLOR_BLUE] = 0
2066 g_iMultipleColor[id][COLOR_GREEN] = 200
2067 }
2068 case 2: // Grenade
2069 {
2070 g_iGrenadeColor[id][COLOR_RED] = g_iGrenadeColor[id][COLOR_BLUE] = 0
2071 g_iGrenadeColor[id][COLOR_GREEN] = 200
2072 }
2073 case 3: // Take
2074 {
2075 g_iTakeColor[id][COLOR_RED] = g_iTakeColor[id][COLOR_BLUE] = 0
2076 g_iTakeColor[id][COLOR_GREEN] = 200
2077 }
2078 }
2079 test_hud_vars(id)
2080 show_menu_dynamic_color(id)
2081 }
2082 case 2: // Blue
2083 {
2084 switch (g_iDynamicMenu[id])
2085 {
2086 case 0: // Single
2087 {
2088 g_iSingleColor[id][COLOR_RED] = g_iSingleColor[id][COLOR_GREEN] = 0
2089 g_iSingleColor[id][COLOR_BLUE] = 200
2090 }
2091 case 1: // Multi
2092 {
2093 g_iMultipleColor[id][COLOR_RED] = g_iMultipleColor[id][COLOR_GREEN] = 0
2094 g_iMultipleColor[id][COLOR_BLUE] = 200
2095 }
2096 case 2: // Grenade
2097 {
2098 g_iGrenadeColor[id][COLOR_RED] = g_iGrenadeColor[id][COLOR_GREEN] = 0
2099 g_iGrenadeColor[id][COLOR_BLUE] = 200
2100 }
2101 case 3: // Take
2102 {
2103 g_iTakeColor[id][COLOR_RED] = g_iTakeColor[id][COLOR_GREEN] = 0
2104 g_iTakeColor[id][COLOR_BLUE] = 200
2105 }
2106 }
2107 test_hud_vars(id)
2108 show_menu_dynamic_color(id)
2109 }
2110 case 3: // Yellow
2111 {
2112 switch (g_iDynamicMenu[id])
2113 {
2114 case 0: // Single
2115 {
2116 g_iSingleColor[id][COLOR_RED] = g_iSingleColor[id][COLOR_GREEN] = 200
2117 g_iSingleColor[id][COLOR_BLUE] = 0
2118 }
2119 case 1: // Multi
2120 {
2121 g_iMultipleColor[id][COLOR_RED] = g_iMultipleColor[id][COLOR_GREEN] = 200
2122 g_iMultipleColor[id][COLOR_BLUE] = 0
2123 }
2124 case 2: // Grenade
2125 {
2126 g_iGrenadeColor[id][COLOR_RED] = g_iGrenadeColor[id][COLOR_GREEN] = 200
2127 g_iGrenadeColor[id][COLOR_BLUE] = 0
2128 }
2129 case 3: // Take
2130 {
2131 g_iTakeColor[id][COLOR_RED] = g_iTakeColor[id][COLOR_GREEN] = 200
2132 g_iTakeColor[id][COLOR_BLUE] = 0
2133 }
2134 }
2135 test_hud_vars(id)
2136 show_menu_dynamic_color(id)
2137 }
2138 case 4: // Cyan
2139 {
2140 switch (g_iDynamicMenu[id])
2141 {
2142 case 0: // Single
2143 {
2144 g_iSingleColor[id][COLOR_RED] = 0
2145 g_iSingleColor[id][COLOR_GREEN] = g_iSingleColor[id][COLOR_BLUE] = 200
2146 }
2147 case 1: // Multi
2148 {
2149 g_iMultipleColor[id][COLOR_RED] = 0
2150 g_iMultipleColor[id][COLOR_GREEN] = g_iMultipleColor[id][COLOR_BLUE] = 200
2151 }
2152 case 2: // Grenade
2153 {
2154 g_iGrenadeColor[id][COLOR_RED] = 0
2155 g_iGrenadeColor[id][COLOR_GREEN] = g_iGrenadeColor[id][COLOR_BLUE] = 200
2156 }
2157 case 3: // Take
2158 {
2159 g_iTakeColor[id][COLOR_RED] = 0
2160 g_iTakeColor[id][COLOR_GREEN] = g_iTakeColor[id][COLOR_BLUE] = 200
2161 }
2162 }
2163 test_hud_vars(id)
2164 show_menu_dynamic_color(id)
2165 }
2166 case 5: // White
2167 {
2168 switch (g_iDynamicMenu[id])
2169 {
2170 case 0: g_iSingleColor[id][COLOR_RED] = g_iSingleColor[id][COLOR_GREEN] = g_iSingleColor[id][COLOR_BLUE] = 200 // Single
2171 case 1: g_iMultipleColor[id][COLOR_RED] = g_iMultipleColor[id][COLOR_GREEN] = g_iMultipleColor[id][COLOR_BLUE] = 200 // Multi
2172 case 2: g_iGrenadeColor[id][COLOR_RED] = g_iGrenadeColor[id][COLOR_GREEN] = g_iGrenadeColor[id][COLOR_BLUE] = 200 // Grenade
2173 case 3: g_iTakeColor[id][COLOR_RED] = g_iTakeColor[id][COLOR_GREEN] = g_iTakeColor[id][COLOR_BLUE] = 200 // Take
2174 }
2175 test_hud_vars(id)
2176 show_menu_dynamic_color(id)
2177 }
2178 case 9: // Back / Exit
2179 {
2180 show_menu_dynamic_main(id)
2181 }
2182 default: show_menu_dynamic_color(id)
2183 }
2184 return PLUGIN_HANDLED
2185}
2186
2187// Dynamic Menu Positions
2188public menu_dynamic_posi(id, key)
2189{
2190 static Float:type
2191 if (g_iMenuType[id])
2192 type = POSI_TYPE_TRUE
2193 else
2194 type = POSI_TYPE_FALSE
2195
2196 switch (key)
2197 {
2198 case 0: // Up
2199 {
2200 switch (g_iDynamicMenu[id])
2201 {
2202 case 0: // Single
2203 {
2204 if (g_flSinglePosition_Y[id] <= -1.0)
2205 g_flSinglePosition_Y[id] = 1.0 - type
2206 else if (g_flSinglePosition_Y[id] < 0.01)
2207 g_flSinglePosition_Y[id] = -1.0
2208 else if (g_flSinglePosition_Y[id] - type <= 0.0)
2209 g_flSinglePosition_Y[id] = 0.0
2210 else
2211 g_flSinglePosition_Y[id] -= type
2212 }
2213 case 1: // Multi
2214 {
2215 if (g_flMultiplePosition_Y[id] <= -1.0)
2216 g_flMultiplePosition_Y[id] = 1.0 - type
2217 else if (g_flMultiplePosition_Y[id] < 0.01)
2218 g_flMultiplePosition_Y[id] = -1.0
2219 else if (g_flMultiplePosition_Y[id] - type <= 0.0)
2220 g_flMultiplePosition_Y[id] = 0.0
2221 else
2222 g_flMultiplePosition_Y[id] -= type
2223 }
2224 case 2: // Grenade
2225 {
2226 if (g_flGrenadePosition_Y[id] <= -1.0)
2227 g_flGrenadePosition_Y[id] = 1.0 - type
2228 else if (g_flGrenadePosition_Y[id] < 0.01)
2229 g_flGrenadePosition_Y[id] = -1.0
2230 else if (g_flGrenadePosition_Y[id] - type <= 0.0)
2231 g_flGrenadePosition_Y[id] = 0.0
2232 else
2233 g_flGrenadePosition_Y[id] -= type
2234 }
2235 case 3: // Take
2236 {
2237 if (g_flTakePosition_Y[id] <= -1.0)
2238 g_flTakePosition_Y[id] = 1.0 - type
2239 else if (g_flTakePosition_Y[id] < 0.01)
2240 g_flTakePosition_Y[id] = -1.0
2241 else if (g_flTakePosition_Y[id] - type <= 0.0)
2242 g_flTakePosition_Y[id] = 0.0
2243 else
2244 g_flTakePosition_Y[id] -= type
2245 }
2246 }
2247 test_hud_vars(id)
2248 show_menu_dynamic_posi(id)
2249 }
2250 case 1: // Down
2251 {
2252 switch (g_iDynamicMenu[id])
2253 {
2254 case 0: // Single
2255 {
2256 if (g_flSinglePosition_Y[id] > 0.99)
2257 g_flSinglePosition_Y[id] = -1.0
2258 else if (g_flSinglePosition_Y[id] <= -1.0)
2259 g_flSinglePosition_Y[id] = 0.0 + type
2260 else if (g_flSinglePosition_Y[id] + type >= 1.0)
2261 g_flSinglePosition_Y[id] = 1.0
2262 else
2263 g_flSinglePosition_Y[id] += type
2264 }
2265 case 1: // Multi
2266 {
2267 if (g_flMultiplePosition_Y[id] > 0.99)
2268 g_flMultiplePosition_Y[id] = -1.0
2269 else if (g_flMultiplePosition_Y[id] <= -1.0)
2270 g_flMultiplePosition_Y[id] = 0.0 + type
2271 else if (g_flMultiplePosition_Y[id] + type >= 1.0)
2272 g_flMultiplePosition_Y[id] = 1.0
2273 else
2274 g_flMultiplePosition_Y[id] += type
2275 }
2276 case 2: // Grenade
2277 {
2278 if (g_flGrenadePosition_Y[id] > 0.99)
2279 g_flGrenadePosition_Y[id] = -1.0
2280 else if (g_flGrenadePosition_Y[id] <= -1.0)
2281 g_flGrenadePosition_Y[id] = 0.0 + type
2282 else if (g_flGrenadePosition_Y[id] + type >= 1.0)
2283 g_flGrenadePosition_Y[id] = 1.0
2284 else
2285 g_flGrenadePosition_Y[id] += type
2286 }
2287 case 3: // Take
2288 {
2289 if (g_flTakePosition_Y[id] > 0.99)
2290 g_flTakePosition_Y[id] = -1.0
2291 else if (g_flTakePosition_Y[id] <= -1.0)
2292 g_flTakePosition_Y[id] = 0.0 + type
2293 else if (g_flTakePosition_Y[id] + type >= 1.0)
2294 g_flTakePosition_Y[id] = 1.0
2295 else
2296 g_flTakePosition_Y[id] += type
2297 }
2298 }
2299 test_hud_vars(id)
2300 show_menu_dynamic_posi(id)
2301 }
2302 case 2: // Right
2303 {
2304 switch (g_iDynamicMenu[id])
2305 {
2306 case 0: // Single
2307 {
2308 if (g_flSinglePosition_X[id] > 0.99)
2309 g_flSinglePosition_X[id] = -1.0
2310 else if (g_flSinglePosition_X[id] <= -1.0)
2311 g_flSinglePosition_X[id] = 0.0 + type
2312 else if (g_flSinglePosition_X[id] + type >= 1.0)
2313 g_flSinglePosition_X[id] = 1.0
2314 else
2315 g_flSinglePosition_X[id] += type
2316 }
2317 case 1: // Multi
2318 {
2319 if (g_flMultiplePosition_X[id] > 0.99)
2320 g_flMultiplePosition_X[id] = -1.0
2321 else if (g_flMultiplePosition_X[id] <= -1.0)
2322 g_flMultiplePosition_X[id] = 0.0 + type
2323 else if (g_flMultiplePosition_X[id] + type >= 1.0)
2324 g_flMultiplePosition_X[id] = 1.0
2325 else
2326 g_flMultiplePosition_X[id] += type
2327 }
2328 case 2: // Grenade
2329 {
2330 if (g_flGrenadePosition_X[id] > 0.99)
2331 g_flGrenadePosition_X[id] = -1.0
2332 else if (g_flGrenadePosition_X[id] <= -1.0)
2333 g_flGrenadePosition_X[id] = 0.0 + type
2334 else if (g_flGrenadePosition_X[id] + type >= 1.0)
2335 g_flGrenadePosition_X[id] = 1.0
2336 else
2337 g_flGrenadePosition_X[id] += type
2338 }
2339 case 3: // Take
2340 {
2341 if (g_flTakePosition_X[id] > 0.99)
2342 g_flTakePosition_X[id] = -1.0
2343 else if (g_flTakePosition_X[id] <= -1.0)
2344 g_flTakePosition_X[id] = 0.0 + type
2345 else if (g_flTakePosition_X[id] + type >= 1.0)
2346 g_flTakePosition_X[id] = 1.0
2347 else
2348 g_flTakePosition_X[id] += type
2349 }
2350 }
2351 test_hud_vars(id)
2352 show_menu_dynamic_posi(id)
2353 }
2354 case 3: // Left
2355 {
2356 switch (g_iDynamicMenu[id])
2357 {
2358 case 0: // Single
2359 {
2360 if (g_flSinglePosition_X[id] <= -1.0)
2361 g_flSinglePosition_X[id] = 1.0 - type
2362 else if (g_flSinglePosition_X[id] < 0.01)
2363 g_flSinglePosition_X[id] = -1.0
2364 else if (g_flSinglePosition_X[id] - type <= 0.0)
2365 g_flSinglePosition_X[id] = 0.0
2366 else
2367 g_flSinglePosition_X[id] -= type
2368 }
2369 case 1: // Multi
2370 {
2371 if (g_flMultiplePosition_X[id] <= -1.0)
2372 g_flMultiplePosition_X[id] = 1.0 - type
2373 else if (g_flMultiplePosition_X[id] < 0.01)
2374 g_flMultiplePosition_X[id] = -1.0
2375 else if (g_flMultiplePosition_X[id] - type <= 0.0)
2376 g_flMultiplePosition_X[id] = 0.0
2377 else
2378 g_flMultiplePosition_X[id] -= type
2379 }
2380 case 2: // Grenade
2381 {
2382 if (g_flGrenadePosition_X[id] <= -1.0)
2383 g_flGrenadePosition_X[id] = 1.0 - type
2384 else if (g_flGrenadePosition_X[id] < 0.01)
2385 g_flGrenadePosition_X[id] = -1.0
2386 else if (g_flGrenadePosition_X[id] - type <= 0.0)
2387 g_flGrenadePosition_X[id] = 0.0
2388 else
2389 g_flGrenadePosition_X[id] -= type
2390 }
2391 case 3: // Take
2392 {
2393 if (g_flTakePosition_X[id] <= -1.0)
2394 g_flTakePosition_X[id] = 1.0 - type
2395 else if (g_flTakePosition_X[id] < 0.01)
2396 g_flTakePosition_X[id] = -1.0
2397 else if (g_flTakePosition_X[id] - type <= 0.0)
2398 g_flTakePosition_X[id] = 0.0
2399 else
2400 g_flTakePosition_X[id] -= type
2401 }
2402 }
2403 test_hud_vars(id)
2404 show_menu_dynamic_posi(id)
2405 }
2406 case 4: // Type
2407 {
2408 g_iMenuType[id] = !(g_iMenuType[id])
2409 show_menu_dynamic_posi(id)
2410 }
2411 case 9: // Back / Exit
2412 {
2413 show_menu_dynamic_main(id)
2414 }
2415 default: show_menu_dynamic_posi(id)
2416 }
2417 return PLUGIN_HANDLED
2418}
2419
2420// Dynamic Menu Positions
2421public menu_dynamic_time(id, key)
2422{
2423 static Float:type
2424 if (g_iMenuType[id])
2425 type = TIME_TYPE_TRUE
2426 else
2427 type = TIME_TYPE_FALSE
2428
2429 switch (key)
2430 {
2431 case 0: // Increase
2432 {
2433 switch (g_iDynamicMenu[id])
2434 {
2435 case 0: // Single
2436 {
2437 if (g_flSingleTime[id] + type >= 15.0)
2438 g_flSingleTime[id] = 15.0
2439 else
2440 g_flSingleTime[id] += type
2441 }
2442 case 1: // Multi
2443 {
2444 if (g_flMultipleTime[id] + type >= 15.0)
2445 g_flMultipleTime[id] = 15.0
2446 else
2447 g_flMultipleTime[id] += type
2448 }
2449 case 2: // Grenade
2450 {
2451 if (g_flGrenadeTime[id] + type >= 15.0)
2452 g_flGrenadeTime[id] = 15.0
2453 else
2454 g_flGrenadeTime[id] += type
2455 }
2456 case 3: // Take
2457 {
2458 if (g_flTakeTime[id] + type >= 15.0)
2459 g_flTakeTime[id] = 15.0
2460 else
2461 g_flTakeTime[id] += type
2462 }
2463 }
2464 show_menu_dynamic_time(id)
2465 }
2466 case 1: // Decrease
2467 {
2468 switch (g_iDynamicMenu[id])
2469 {
2470 case 0: // Single
2471 {
2472 if (g_flSingleTime[id] - type <= 0.1)
2473 g_flSingleTime[id] = 0.1
2474 else
2475 g_flSingleTime[id] -= type
2476 }
2477 case 1: // Multi
2478 {
2479 if (g_flMultipleTime[id] - type <= 0.1)
2480 g_flMultipleTime[id] = 0.1
2481 else
2482 g_flMultipleTime[id] -= type
2483 }
2484 case 2: // Grenade
2485 {
2486 if (g_flGrenadeTime[id] - type <= 0.1)
2487 g_flGrenadeTime[id] = 0.1
2488 else
2489 g_flGrenadeTime[id] -= type
2490 }
2491 case 3: // Take
2492 {
2493 if (g_flTakeTime[id] - type <= 0.1)
2494 g_flTakeTime[id] = 0.1
2495 else
2496 g_flTakeTime[id] -= type
2497 }
2498 }
2499 show_menu_dynamic_time(id)
2500 }
2501 case 2: // Type
2502 {
2503 g_iMenuType[id] = !(g_iMenuType[id])
2504 show_menu_dynamic_time(id)
2505 }
2506 case 3: // Test
2507 {
2508 test_hud_vars(id)
2509 show_menu_dynamic_time(id)
2510 }
2511 case 9: // Back / Exit
2512 {
2513 show_menu_dynamic_main(id)
2514 }
2515 default: show_menu_dynamic_time(id)
2516 }
2517 return PLUGIN_HANDLED
2518}
2519
2520// Player List Menu
2521public menu_player_list(id, menuid, item)
2522{
2523 // Menu was closed
2524 if (item == MENU_EXIT)
2525 {
2526 menu_destroy(menuid)
2527 show_menu_main(id)
2528 return PLUGIN_HANDLED
2529 }
2530
2531 // Retrieve player id
2532 static buffer[2], dummy, playerid
2533 menu_item_getinfo(menuid, item, dummy, buffer, charsmax(buffer), _, _, dummy)
2534 playerid = buffer[0]
2535
2536 // Perform action on player
2537
2538 // Make sure it's still connected
2539 if (g_bIsConnected[playerid])
2540 show_top_personal(id, playerid)
2541
2542 menu_destroy(menuid)
2543 show_menu_player_list(id)
2544 return PLUGIN_HANDLED
2545}
2546
2547public menu_weapon_list(id, menuid, item)
2548{
2549 // Menu was closed
2550 if (item == MENU_EXIT)
2551 {
2552 menu_destroy(menuid)
2553 show_menu_main(id)
2554 return PLUGIN_HANDLED
2555 }
2556
2557 // Retrieve player id
2558 static buffer[2], dummy, weapon
2559 menu_item_getinfo(menuid, item, dummy, buffer, charsmax(buffer), _, _, dummy)
2560 weapon = buffer[0]
2561
2562 // Perform action on weapon
2563 if (weapon == 0)
2564 {
2565 reset_top(0, 1)
2566 colored_print(id, "^x04[BD]^x01 %L %L", id, "MENU_RESET_ALL", id, "MENU_RESET_RECORD")
2567 }
2568 else
2569 {
2570 reset_top(weapon)
2571 colored_print(id, "^x04[BD]^x01 %s %L", WPN_NAMES[weapon], id, "MENU_RESET_RECORD")
2572 }
2573
2574 menu_destroy(menuid)
2575 show_menu_admin(id)
2576 return PLUGIN_HANDLED
2577}
2578
2579/*================================================================================
2580 [Other Functions and Tasks]
2581=================================================================================*/
2582
2583public reset_atk2_knife(taskid)
2584{
2585 // Not Connected
2586 if (!g_bIsConnected[ID_KNIFE]) return
2587
2588 // reset knife atk2 var
2589 g_bAttack2Knife[ID_KNIFE] = false
2590}
2591
2592public damage_deal(taskid)
2593{
2594 // Not Connected
2595 if (!g_bIsConnected[ID_DAMAGE]) return
2596
2597 // Record trial finished!
2598 g_bWhileRecordTask[ID_DAMAGE] = false
2599
2600 // non-steam player...
2601 if (!g_iAuthorized[ID_DAMAGE])
2602 {
2603 reset_record_vars(ID_DAMAGE)
2604 return
2605 }
2606
2607 // Zombie Plague Compatibility
2608 #if defined _zombieplague_included || defined _zombie_plague_advance_included
2609
2610 if (!get_pcvar_num(cvar_zpNemesisDamage) && zp_get_user_nemesis(ID_DAMAGE) || !get_pcvar_num(cvar_zpSurvivorDamage) && zp_get_user_survivor(ID_DAMAGE))
2611 {
2612 reset_record_vars(ID_DAMAGE)
2613 return
2614 }
2615
2616 #endif
2617
2618 // Zombie Plague Advance Compatibility
2619 #if defined _zombie_plague_advance_included
2620
2621 if (!get_pcvar_num(cvar_zpAssassinDamage) && zp_get_user_assassin(ID_DAMAGE) || !get_pcvar_num(cvar_zpSniperDamage) && zp_get_user_sniper(ID_DAMAGE))
2622 {
2623 reset_record_vars(ID_DAMAGE)
2624 return
2625 }
2626
2627 #endif
2628
2629 // Using weapon
2630 static weapon
2631 weapon = g_iWeaponUse[ID_DAMAGE]
2632
2633 // Made a new Personal record
2634 if (g_iDamageDealt[ID_DAMAGE] > g_iPersonalDamage[ID_DAMAGE][weapon])
2635 {
2636 // Set players name, damage done and hits to cached records
2637 g_iPersonalDamage[ID_DAMAGE][weapon] = clamp(g_iDamageDealt[ID_DAMAGE], 1, 999999)
2638 g_iPersonalHits[ID_DAMAGE][weapon] = clamp(g_iHits[ID_DAMAGE], 1, 9999)
2639 g_iPersonalResets[ID_DAMAGE][weapon] = g_iCachedResets[weapon]
2640
2641 // Display new Record in Chat
2642 if (get_pcvar_num(cvar_ChatPersonal))
2643 colored_print(ID_DAMAGE, "^x04[BD]^x01 %L", ID_DAMAGE, "BD_PERSONAL_RECORD", g_iPersonalDamage[ID_DAMAGE][weapon], WPN_NAMES[weapon], g_iPersonalHits[ID_DAMAGE][weapon])
2644
2645 // Save new Record
2646 if (get_pcvar_num(cvar_SaveStatsPersonal))
2647 save_personal_top(ID_DAMAGE)
2648 }
2649
2650 // Made a new Record
2651 if (g_iDamageDealt[ID_DAMAGE] > g_iCachedDamage[weapon])
2652 {
2653 // Set players name, damage done and hits to cached records
2654 g_szCachedNames[weapon] = g_szPlayerName[ID_DAMAGE]
2655 g_szCachedSteamIDs[weapon] = g_szSteamID[ID_DAMAGE]
2656 g_iCachedDamage[weapon] = clamp(g_iDamageDealt[ID_DAMAGE], 1, 999999)
2657 g_iCachedHits[weapon] = clamp(g_iHits[ID_DAMAGE], 1, 9999)
2658
2659 // Display new Record in Chat
2660 if (get_pcvar_num(cvar_ChatWeapon))
2661 colored_print(0, "^x04[BD]^x01 %L", LANG_PLAYER, "BD_RECORD", g_szCachedNames[weapon], g_iCachedDamage[weapon], WPN_NAMES[weapon], g_iCachedHits[weapon])
2662
2663 // Save new Record
2664 if (get_pcvar_num(cvar_SaveStats))
2665 save_top()
2666 }
2667
2668 // Clear record Player vars
2669 reset_record_vars(ID_DAMAGE)
2670}
2671
2672public damage_deal_he(taskid)
2673{
2674 // Not Connected
2675 if (!g_bIsConnected[ID_GRENADE]) return
2676
2677 // Display HUD damage?
2678 show_grenade_damage(ID_GRENADE)
2679
2680 // Not Authorized
2681 if (!g_iAuthorized[ID_GRENADE])
2682 {
2683 reset_record_vars(ID_GRENADE, 1)
2684 return
2685 }
2686
2687 // Zombie Plague Compatibility
2688 #if defined _zombieplague_included || defined _zombie_plague_advance_included
2689
2690 if (!get_pcvar_num(cvar_zpNemesisDamage) && zp_get_user_nemesis(ID_GRENADE) || !get_pcvar_num(cvar_zpSurvivorDamage) && zp_get_user_survivor(ID_GRENADE))
2691 {
2692 reset_record_vars(ID_GRENADE, 1)
2693 return
2694 }
2695
2696 #endif
2697
2698 // Zombie Plague Advance Compatibility
2699 #if defined _zombie_plague_advance_included
2700
2701 if (!get_pcvar_num(cvar_zpAssassinDamage) && zp_get_user_assassin(ID_GRENADE) || !get_pcvar_num(cvar_zpSniperDamage) && zp_get_user_sniper(ID_GRENADE))
2702 {
2703 reset_record_vars(ID_GRENADE, 1)
2704 return
2705 }
2706
2707 #endif
2708
2709 // Made a new Personal record
2710 if (g_iDamageDealt[ID_GRENADE] > g_iPersonalDamage[ID_GRENADE][CSW_HEGRENADE])
2711 {
2712 // Set players name, damage done and hits to cached records
2713 g_iPersonalDamage[ID_GRENADE][CSW_HEGRENADE] = clamp(g_iGrenadeDamageDealt[ID_GRENADE], 1, 999999)
2714 g_iPersonalHits[ID_GRENADE][CSW_HEGRENADE] = clamp(g_iGrenadeHits[ID_GRENADE], 1, 9999)
2715 g_iPersonalResets[ID_GRENADE][CSW_HEGRENADE] = g_iCachedResets[CSW_HEGRENADE]
2716
2717 // Display new Record in Chat
2718 if (get_pcvar_num(cvar_ChatPersonal))
2719 colored_print(ID_GRENADE, "^x04[BD]^x01 %L", ID_GRENADE, "BD_PERSONAL_RECORD", g_iPersonalDamage[ID_GRENADE][CSW_HEGRENADE], WPN_NAMES[CSW_HEGRENADE], g_iPersonalHits[ID_GRENADE][CSW_HEGRENADE])
2720
2721 // Save new Record
2722 if (get_pcvar_num(cvar_SaveStatsPersonal))
2723 save_personal_top(ID_GRENADE)
2724 }
2725
2726 // Made a new Record
2727 if (g_iGrenadeDamageDealt[ID_GRENADE] > g_iCachedDamage[CSW_HEGRENADE])
2728 {
2729 // Set players name, damage done and hits to cached records
2730 g_szCachedNames[CSW_HEGRENADE] = g_szPlayerName[ID_GRENADE]
2731 g_szCachedSteamIDs[CSW_HEGRENADE] = g_szSteamID[ID_GRENADE]
2732 g_iCachedDamage[CSW_HEGRENADE] = clamp(g_iGrenadeDamageDealt[ID_GRENADE], 1, 999999)
2733 g_iCachedHits[CSW_HEGRENADE] = clamp(g_iGrenadeHits[ID_GRENADE], 1, 9999)
2734
2735 // Display new Record in Chat
2736 if (get_pcvar_num(cvar_ChatWeapon))
2737 colored_print(0, "^x04[BD]^x01 %L", LANG_PLAYER, "BD_RECORD", g_szCachedNames[CSW_HEGRENADE], g_iCachedDamage[CSW_HEGRENADE], WPN_NAMES[CSW_HEGRENADE], g_iCachedHits[CSW_HEGRENADE])
2738
2739 // Save new Record
2740 if (get_pcvar_num(cvar_SaveStats))
2741 save_top()
2742 }
2743
2744 // Clear Player vars
2745 reset_record_vars(ID_GRENADE, 1)
2746}
2747
2748public register_ham_czbots(id)
2749{
2750 // Make sure it's a CZ bot and it's still connected
2751 if (g_bHamCzBots || !g_bIsConnected[id] || !get_pcvar_num(cvar_BotQuota)) return
2752
2753 RegisterHamFromEntity(Ham_TakeDamage, id, "fwd_TakeDamage_Post", 1)
2754 RegisterHamFromEntity(Ham_TraceAttack, id, "fwd_TraceAttack")
2755
2756 // Ham forwards for CZ bots succesfully registered
2757 g_bHamCzBots = true
2758}
2759
2760get_record()
2761{
2762 new dmg = 0, j = 0
2763
2764 for (new i = CSW_P228; i <= CSW_P90; i++)
2765 {
2766 if (is_ignore_weapon_id(i)) continue
2767
2768 if (g_iRecord[i] >= dmg)
2769 {
2770 dmg = g_iRecord[i]
2771 j = i
2772 }
2773 }
2774 g_iRecord[j] = -1
2775
2776 return j;
2777}
2778
2779replace_windows_letters(const id, Name[], const len)
2780{
2781 copy(Name, len, g_szPlayerName[id])
2782 replace_all(Name, len, "\", "_")
2783 replace_all(Name, len, "/", "_")
2784 replace_all(Name, len, ":", "_")
2785 replace_all(Name, len, "*", "_")
2786 replace_all(Name, len, "?", "_")
2787 replace_all(Name, len, "^"", "_")
2788 replace_all(Name, len, "<", "_")
2789 replace_all(Name, len, ">", "_")
2790 replace_all(Name, len, "|", "_")
2791}
2792
2793load_top()
2794{
2795 // File not present
2796 if (!file_exists(g_szRecordFile))
2797 {
2798 save_top()
2799 return
2800 }
2801
2802 // Set up some vars to hold parsing info
2803 new linedata[44], key[12], value[32], section
2804
2805 // Open config file for reading
2806 new file = fopen(g_szRecordFile, "rt")
2807
2808 // file not open
2809 if (!file) return
2810
2811 while (!feof(file))
2812 {
2813 // Read one line at a time
2814 fgets(file, linedata, charsmax(linedata))
2815
2816 // Replace newlines with a null character to prevent headaches
2817 replace(linedata, charsmax(linedata), "^n", "")
2818
2819 // Blank line or comment
2820 if (!linedata[0] || linedata[0] == ';') continue
2821
2822 // New section starting
2823 if (linedata[0] == '[')
2824 {
2825 section++
2826 continue
2827 }
2828
2829 // Is ignore Weapon
2830 if (is_ignore_weapon_id(section))
2831 section++
2832
2833 // Get key and value(s)
2834 strtok(linedata, key, charsmax(key), value, charsmax(value), '=')
2835
2836 // Trim spaces
2837 trim(key)
2838 trim(value)
2839
2840 if (equal(key, "NAME"))
2841 g_szCachedNames[section] = value
2842 else if (equal(key, "STEAM ID"))
2843 g_szCachedSteamIDs[section] = value
2844 else if (equal(key, "DAMAGE"))
2845 g_iCachedDamage[section] = str_to_num(value)
2846 else if (equal(key, "HITS"))
2847 g_iCachedHits[section] = str_to_num(value)
2848 else if (equal(key, "RESETS"))
2849 g_iCachedResets[section] = str_to_num(value)
2850 }
2851 fclose(file)
2852}
2853
2854/* is_linux_server() */
2855
2856load_personal_top(id)
2857{
2858 // Get config file
2859 // Not allowed letters (windows) \ / : * ? " < > |
2860 // STEAM_0:X:XXXXXX
2861 new szPersonalRecord[128]
2862 if (get_pcvar_num(cvar_SvLan) || g_bIsBot[id])
2863 {
2864 new Name[32]
2865 replace_windows_letters(id, Name, charsmax(Name))
2866 format(szPersonalRecord, charsmax(szPersonalRecord), "%s/bd_records/%s.ini", g_szDataDir, Name)
2867 }
2868 else
2869 {
2870 format(szPersonalRecord, charsmax(szPersonalRecord), "%s/bd_records/%s.ini", g_szDataDir, g_szSteamID[id])
2871 replace_all(szPersonalRecord, charsmax(szPersonalRecord), ":", "_")
2872 }
2873
2874 // File not present
2875 if (!file_exists(szPersonalRecord))
2876 {
2877 for (new i = CSW_P228; i <= CSW_P90; i++)
2878 {
2879 g_iPersonalDamage[id][i] = g_iPersonalHits[id][i] = 0
2880 g_iPersonalResets[id][i] = g_iCachedResets[i]
2881 }
2882 return
2883 }
2884
2885 // Set up some vars to hold parsing info
2886 new linedata[24], key[12], value[12], section
2887
2888 // Open config file for reading
2889 new file = fopen(szPersonalRecord, "rt")
2890
2891 // file not open
2892 if (!file) return
2893
2894 while (!feof(file))
2895 {
2896 // Read one line at a time
2897 fgets(file, linedata, charsmax(linedata))
2898
2899 // Replace newlines with a null character to prevent headaches
2900 replace(linedata, charsmax(linedata), "^n", "")
2901
2902 // Blank line or comment
2903 if (!linedata[0] || linedata[0] == ';') continue
2904
2905 // New section starting
2906 if (linedata[0] == '[')
2907 {
2908 section++
2909 continue
2910 }
2911
2912 // Is ignore Weapon
2913 if (is_ignore_weapon_id(section))
2914 section++
2915
2916 // Get key and value(s)
2917 strtok(linedata, key, charsmax(key), value, charsmax(value), '=')
2918
2919 // Trim spaces
2920 trim(key)
2921 trim(value)
2922
2923 if (equal(key, "DAMAGE"))
2924 g_iPersonalDamage[id][section] = str_to_num(value)
2925 else if (equal(key, "HITS"))
2926 g_iPersonalHits[id][section] = str_to_num(value)
2927 else if (equal(key, "RESETS"))
2928 g_iPersonalResets[id][section] = str_to_num(value)
2929 }
2930 fclose(file)
2931}
2932
2933save_top()
2934{
2935 // Record file exists, delete it!
2936 if (file_exists(g_szRecordFile)) delete_file(g_szRecordFile)
2937
2938 // Open not exists config file for appending data (this create a new one)
2939 new file = fopen(g_szRecordFile, "wt"), buffer[512]
2940
2941 // file not open
2942 if (!file) return
2943
2944 // Add any configuration from the player
2945 for (new section = CSW_P228; section <= CSW_P90; section++)
2946 {
2947 if (is_ignore_weapon_id(section)) continue
2948
2949 // Add section name
2950 format(buffer, charsmax(buffer), "[%s]", WPN_NAMES[section])
2951 fputs(file, buffer)
2952
2953 // Add record
2954 format(buffer, charsmax(buffer), "^nNAME = %s^nSTEAM ID = %s^nDAMAGE = %i^nHITS = %i^nRESETS = %i^n^n",
2955 g_szCachedNames[section], g_szCachedSteamIDs[section], g_iCachedDamage[section], g_iCachedHits[section], g_iCachedResets[section])
2956 fputs(file, buffer)
2957 }
2958 fclose(file)
2959}
2960
2961save_personal_top(id)
2962{
2963 // Get config file
2964 // Not allowed letters (windows) \ / : * ? " < > |
2965 // STEAM_0:X:XXXXXX
2966 new szPersonalRecord[128]
2967 if (get_pcvar_num(cvar_SvLan) || g_bIsBot[id])
2968 {
2969 new Name[32]
2970 replace_windows_letters(id, Name, charsmax(Name))
2971 format(szPersonalRecord, charsmax(szPersonalRecord), "%s/bd_records/%s.ini", g_szDataDir, Name)
2972 }
2973 else
2974 {
2975 format(szPersonalRecord, charsmax(szPersonalRecord), "%s/bd_records/%s.ini", g_szDataDir, g_szSteamID[id])
2976 replace_all(szPersonalRecord, charsmax(szPersonalRecord), ":", "_")
2977 }
2978
2979 // config file exists, delete it!
2980 if (file_exists(szPersonalRecord)) delete_file(szPersonalRecord)
2981
2982 // Open not exists config file for appending data (this create a new one)
2983 new file = fopen(szPersonalRecord, "wt"), buffer[512]
2984
2985 // file not open
2986 if (!file) return
2987
2988 // Add any configuration from the player
2989 for (new section = CSW_P228; section <= CSW_P90; section++)
2990 {
2991 if (is_ignore_weapon_id(section)) continue
2992
2993 // Add section name
2994 format(buffer, charsmax(buffer), "[%s]", WPN_NAMES[section])
2995 fputs(file, buffer)
2996
2997 // Add record
2998 format(buffer, charsmax(buffer), "^nDAMAGE = %i^nHITS = %i^nRESETS = %i^n^n",
2999 g_iPersonalDamage[id][section], g_iPersonalHits[id][section], g_iPersonalResets[id][section])
3000 fputs(file, buffer)
3001 }
3002 fclose(file)
3003}
3004
3005reset_top(resetweapon = 0, resetall = 0)
3006{
3007 // Reset one cached Records
3008 if (resetweapon)
3009 {
3010 // Reset cache
3011 g_szCachedSteamIDs[resetweapon] = ""
3012 g_szCachedNames[resetweapon] = ""
3013 g_iCachedDamage[resetweapon] = g_iCachedHits[resetweapon] = 0
3014 g_iCachedResets[resetweapon]++
3015 }
3016 // Reset all cached Records
3017 else if (resetall)
3018 {
3019 for (new i = CSW_P228; i <= CSW_P90; i++)
3020 {
3021 g_szCachedSteamIDs[i] = ""
3022 g_szCachedNames[i] = ""
3023 g_iCachedDamage[i] = g_iCachedHits[i] = 0
3024 g_iCachedResets[i]++
3025 }
3026 }
3027 save_top()
3028 check_resets()
3029}
3030
3031check_resets(target = 0)
3032{
3033 if (target)
3034 {
3035 for (new i = CSW_P228; i <= CSW_P90; i++)
3036 {
3037 if (g_iPersonalResets[target][i] >= g_iCachedResets[i]) continue
3038
3039 g_iPersonalDamage[target][i] = g_iPersonalHits[target][i] = 0
3040 g_iPersonalResets[target][i] = g_iCachedResets[i]
3041 }
3042 save_personal_top(target)
3043 }
3044 else
3045 {
3046 static player
3047 for (player = 1; player <= g_iMaxPlayers; player++)
3048 {
3049 // Not connected
3050 if (!g_bIsConnected[player]) continue
3051
3052 for (new i = CSW_P228; i <= CSW_P90; i++)
3053 {
3054 if (g_iPersonalResets[player][i] >= g_iCachedResets[i]) continue
3055
3056 g_iPersonalDamage[player][i] = g_iPersonalHits[player][i] = 0
3057 g_iPersonalResets[player][i] = g_iCachedResets[i]
3058 }
3059 save_personal_top(player)
3060 }
3061 }
3062}
3063
3064public DisplayBulletDamageHelp(id)
3065{
3066 // Plugin enable and it's still connected
3067 if (!get_pcvar_num(cvar_BulletDamage) || !g_bIsConnected[id]) return
3068
3069 colored_print(id, "^x04[BD]^x01 %L", id, "BD_INFO")
3070}
3071
3072set_player_vars(id)
3073{
3074 g_iAuthorized[id] = g_iMenuType[id] = 0
3075 g_iDamageDealt[id] = g_iGrenadeDamageDealt[id] = 0
3076 g_iWeaponUse[id] = g_iWeaponEntity[id] = 0
3077 g_iHits[id] = g_iGrenadeHits[id] = 0
3078 g_iPreHealth[id] = g_iPostHealth[id] = 0
3079 g_bAttack2Knife[id] = g_bWhileRecordTask[id] = g_bGrenadeWallVisible[id] = g_bIsBot[id] = false
3080}
3081
3082load_hud_vars(id)
3083{
3084 // Cache record file
3085 // Not allowed letters (windows) \ / : * ? " < > |
3086 // STEAM_0:X:XXXXXX
3087 new szPersonalConfig[128]
3088 if (get_pcvar_num(cvar_SvLan))
3089 {
3090 new Name[32]
3091 replace_windows_letters(id, Name, charsmax(Name))
3092 format(szPersonalConfig, charsmax(szPersonalConfig), "%s/bd_configs/%s.ini", g_szDataDir, Name)
3093 }
3094 else
3095 {
3096 format(szPersonalConfig, charsmax(szPersonalConfig), "%s/bd_configs/%s.ini", g_szDataDir, g_szSteamID[id])
3097 replace_all(szPersonalConfig, charsmax(szPersonalConfig), ":", "_")
3098 }
3099
3100 // File not present or Bot
3101 if (!file_exists(szPersonalConfig))
3102 {
3103 set_hud_vars(id)
3104 return
3105 }
3106
3107 // Set up some vars to hold parsing info
3108 new linedata[1024], key[64], value[960], section
3109
3110 // Open config file for reading
3111 new file = fopen(szPersonalConfig, "rt")
3112
3113 // file not open
3114 if (!file) return
3115
3116 while (!feof(file))
3117 {
3118 // Read one line at a time
3119 fgets(file, linedata, charsmax(linedata))
3120
3121 // Replace newlines with a null character to prevent headaches
3122 replace(linedata, charsmax(linedata), "^n", "")
3123
3124 // Blank line or comment
3125 if (!linedata[0] || linedata[0] == ';') continue
3126
3127 // New section starting
3128 if (linedata[0] == '[')
3129 {
3130 section++
3131 continue
3132 }
3133
3134 // Get key and value(s)
3135 strtok(linedata, key, charsmax(key), value, charsmax(value), '=')
3136
3137 // Trim spaces
3138 trim(key)
3139 trim(value)
3140
3141 switch (section)
3142 {
3143 case SECTION_HUD:
3144 {
3145 if (equal(key, "SINGLE"))
3146 g_iShowSingleHud[id] = str_to_num(value)
3147 else if (equal(key, "MULTIPLE"))
3148 g_iShowMultipleHud[id] = str_to_num(value)
3149 else if (equal(key, "GRENADE"))
3150 g_iShowGrenadeHud[id] = str_to_num(value)
3151 else if (equal(key, "TAKE"))
3152 g_iShowTakeHud[id] = str_to_num(value)
3153 }
3154 case SECTION_COLORS:
3155 {
3156 if (equal(key, "SINGLE RED"))
3157 g_iSingleColor[id][COLOR_RED] = str_to_num(value)
3158 else if (equal(key, "SINGLE GREEN"))
3159 g_iSingleColor[id][COLOR_GREEN] = str_to_num(value)
3160 else if (equal(key, "SINGLE BLUE"))
3161 g_iSingleColor[id][COLOR_BLUE] = str_to_num(value)
3162 else if (equal(key, "SINGLE STYLE"))
3163 g_iSingleColor[id][COLOR_STYLE] = str_to_num(value)
3164 else if (equal(key, "MULTIPLE RED"))
3165 g_iMultipleColor[id][COLOR_RED] = str_to_num(value)
3166 else if (equal(key, "MULTIPLE GREEN"))
3167 g_iMultipleColor[id][COLOR_GREEN] = str_to_num(value)
3168 else if (equal(key, "MULTIPLE BLUE"))
3169 g_iMultipleColor[id][COLOR_BLUE] = str_to_num(value)
3170 else if (equal(key, "MULTIPLE STYLE"))
3171 g_iMultipleColor[id][COLOR_STYLE] = str_to_num(value)
3172 else if (equal(key, "GRENADE RED"))
3173 g_iGrenadeColor[id][COLOR_RED] = str_to_num(value)
3174 else if (equal(key, "GRENADE GREEN"))
3175 g_iGrenadeColor[id][COLOR_GREEN] = str_to_num(value)
3176 else if (equal(key, "GRENADE BLUE"))
3177 g_iGrenadeColor[id][COLOR_BLUE] = str_to_num(value)
3178 else if (equal(key, "GRENADE STYLE"))
3179 g_iGrenadeColor[id][COLOR_STYLE] = str_to_num(value)
3180 else if (equal(key, "TAKE RED"))
3181 g_iTakeColor[id][COLOR_RED] = str_to_num(value)
3182 else if (equal(key, "TAKE GREEN"))
3183 g_iTakeColor[id][COLOR_GREEN] = str_to_num(value)
3184 else if (equal(key, "TAKE BLUE"))
3185 g_iTakeColor[id][COLOR_BLUE] = str_to_num(value)
3186 else if (equal(key, "TAKE STYLE"))
3187 g_iTakeColor[id][COLOR_STYLE] = str_to_num(value)
3188 }
3189 case SECTION_POSITIONS:
3190 {
3191 if (equal(key, "SINGLE X"))
3192 g_flSinglePosition_X[id] = str_to_float(value)
3193 else if (equal(key, "SINGLE Y"))
3194 g_flSinglePosition_Y[id] = str_to_float(value)
3195 else if (equal(key, "MULTIPLE X"))
3196 g_flMultiplePosition_X[id] = str_to_float(value)
3197 else if (equal(key, "MULTIPLE Y"))
3198 g_flMultiplePosition_Y[id] = str_to_float(value)
3199 else if (equal(key, "GRENADE X"))
3200 g_flGrenadePosition_X[id] = str_to_float(value)
3201 else if (equal(key, "GRENADE Y"))
3202 g_flGrenadePosition_Y[id] = str_to_float(value)
3203 else if (equal(key, "TAKE X"))
3204 g_flTakePosition_X[id] = str_to_float(value)
3205 else if (equal(key, "TAKE Y"))
3206 g_flTakePosition_Y[id] = str_to_float(value)
3207 }
3208 case SECTION_TIMES:
3209 {
3210 if (equal(key, "SINGLE"))
3211 g_flSingleTime[id] = str_to_float(value)
3212 else if (equal(key, "MULTIPLE"))
3213 g_flMultipleTime[id] = str_to_float(value)
3214 else if (equal(key, "GRENADE"))
3215 g_flGrenadeTime[id] = str_to_float(value)
3216 else if (equal(key, "TAKE"))
3217 g_flTakeTime[id] = str_to_float(value)
3218 }
3219 }
3220 }
3221 fclose(file)
3222}
3223
3224save_hud_vars(id)
3225{
3226 // Get config file
3227 // Not allowed letters (windows) \ / : * ? " < > |
3228 // STEAM_0:X:XXXXXX
3229 new szPersonalConfig[128]
3230 if (get_pcvar_num(cvar_SvLan))
3231 {
3232 new Name[32]
3233 replace_windows_letters(id, Name, charsmax(Name))
3234 format(szPersonalConfig, charsmax(szPersonalConfig), "%s/bd_configs/%s.ini", g_szDataDir, Name)
3235 }
3236 else
3237 {
3238 format(szPersonalConfig, charsmax(szPersonalConfig), "%s/bd_configs/%s.ini", g_szDataDir, g_szSteamID[id])
3239 replace_all(szPersonalConfig, charsmax(szPersonalConfig), ":", "_")
3240 }
3241
3242 // config file exists, delete it!
3243 if (file_exists(szPersonalConfig)) delete_file(szPersonalConfig)
3244
3245 // Open not exists config file for appending data (this create a new one)
3246 new file = fopen(szPersonalConfig, "wt"), buffer[512]
3247
3248 // file not open
3249 if (!file) return
3250
3251 // Add any configuration from the player
3252 for (new section = SECTION_HUD; section < MAX_SECTIONS; section++)
3253 {
3254 switch (section)
3255 {
3256 case SECTION_HUD:
3257 {
3258 // Add section name
3259 format(buffer, charsmax(buffer), "[HUD]")
3260 fputs(file, buffer)
3261
3262 // Add hud config
3263 format(buffer, charsmax(buffer), "^nSINGLE = %i^nMULTIPLE = %i^nGRENADE = %i^nTAKE = %i",
3264 g_iShowSingleHud[id], g_iShowMultipleHud[id], g_iShowGrenadeHud[id], g_iShowTakeHud[id])
3265 fputs(file, buffer)
3266 }
3267 case SECTION_COLORS:
3268 {
3269 // Add section name
3270 format(buffer, charsmax(buffer), "^n^n[COLORS]")
3271 fputs(file, buffer)
3272
3273 // Add single
3274 format(buffer, charsmax(buffer), "^nSINGLE RED = %i^nSINGLE GREEN = %i^nSINGLE BLUE = %i^nSINGLE STYLE = %i",
3275 g_iSingleColor[id][COLOR_RED], g_iSingleColor[id][COLOR_GREEN], g_iSingleColor[id][COLOR_BLUE], g_iSingleColor[id][COLOR_STYLE])
3276 fputs(file, buffer)
3277
3278 // Add multi
3279 format(buffer, charsmax(buffer), "^nMULTIPLE RED = %i^nMULTIPLE GREEN = %i^nMULTIPLE BLUE = %i^nMULTIPLE STYLE = %i",
3280 g_iMultipleColor[id][COLOR_RED], g_iMultipleColor[id][COLOR_GREEN], g_iMultipleColor[id][COLOR_BLUE], g_iMultipleColor[id][COLOR_STYLE])
3281 fputs(file, buffer)
3282
3283 // Add he
3284 format(buffer, charsmax(buffer), "^nGRENADE RED = %i^nGRENADE GREEN = %i^nGRENADE BLUE = %i^nGRENADE STYLE = %i",
3285 g_iGrenadeColor[id][COLOR_RED], g_iGrenadeColor[id][COLOR_GREEN], g_iGrenadeColor[id][COLOR_BLUE], g_iGrenadeColor[id][COLOR_STYLE])
3286 fputs(file, buffer)
3287
3288 // Add take
3289 format(buffer, charsmax(buffer), "^nTAKE RED = %i^nTAKE GREEN = %i^nTAKE BLUE = %i^nTAKE STYLE = %i",
3290 g_iTakeColor[id][COLOR_RED], g_iTakeColor[id][COLOR_GREEN], g_iTakeColor[id][COLOR_BLUE], g_iTakeColor[id][COLOR_STYLE])
3291 fputs(file, buffer)
3292 }
3293 case SECTION_POSITIONS:
3294 {
3295 // Add section name
3296 format(buffer, charsmax(buffer), "^n^n[POSITIONS]")
3297 fputs(file, buffer)
3298
3299 // Add single
3300 format(buffer, charsmax(buffer), "^nSINGLE X = %.2f^nSINGLE Y = %.2f",
3301 g_flSinglePosition_X[id], g_flSinglePosition_Y[id])
3302 fputs(file, buffer)
3303
3304 // Add multi
3305 format(buffer, charsmax(buffer), "^nMULTIPLE X = %.2f^nMULTIPLE Y = %.2f",
3306 g_flMultiplePosition_X[id], g_flMultiplePosition_Y[id])
3307 fputs(file, buffer)
3308
3309 // Add he
3310 format(buffer, charsmax(buffer), "^nGRENADE X = %.2f^nGRENADE Y = %.2f",
3311 g_flGrenadePosition_X[id], g_flGrenadePosition_Y[id])
3312 fputs(file, buffer)
3313
3314 // Add take
3315 format(buffer, charsmax(buffer), "^nTAKE X = %.2f^nTAKE Y = %.2f",
3316 g_flTakePosition_X[id], g_flTakePosition_Y[id])
3317 fputs(file, buffer)
3318 }
3319 case SECTION_TIMES:
3320 {
3321 // Add section name
3322 format(buffer, charsmax(buffer), "^n^n[TIMERS]")
3323 fputs(file, buffer)
3324
3325 // Add time config
3326 format(buffer, charsmax(buffer), "^nSINGLE = %.2f^nMULTIPLE = %.2f^nGRENADE = %.2f^nTAKE = %.2f",
3327 g_flSingleTime[id], g_flMultipleTime[id], g_flGrenadeTime[id], g_flTakeTime[id])
3328 fputs(file, buffer)
3329 }
3330 }
3331 }
3332 fclose(file)
3333}
3334
3335test_hud_vars(id)
3336{
3337 ClearSyncHud(id, g_HudSyncTake)
3338 set_hudmessage(g_iTakeColor[id][COLOR_RED], g_iTakeColor[id][COLOR_GREEN], g_iTakeColor[id][COLOR_BLUE], g_flTakePosition_X[id], g_flTakePosition_Y[id], g_iTakeColor[id][COLOR_STYLE], 0.0, g_flTakeTime[id], 1.0, 1.0, -1)
3339 ShowSyncHudMsg(id, g_HudSyncTake, "%L", id, "MENU_TAKE_TITLE")
3340
3341 ClearSyncHud(id, g_HudSyncSingle)
3342 set_hudmessage(g_iSingleColor[id][COLOR_RED], g_iSingleColor[id][COLOR_GREEN], g_iSingleColor[id][COLOR_BLUE], g_flSinglePosition_X[id], g_flSinglePosition_Y[id], g_iSingleColor[id][COLOR_STYLE], 0.0, g_flSingleTime[id], 1.0, 1.0, -1)
3343 ShowSyncHudMsg(id, g_HudSyncSingle, "%L", id, "MENU_SINGLE_TITLE")
3344
3345 ClearSyncHud(id, g_HudSyncMultiple)
3346 set_hudmessage(g_iMultipleColor[id][COLOR_RED], g_iMultipleColor[id][COLOR_GREEN], g_iMultipleColor[id][COLOR_BLUE], g_flMultiplePosition_X[id], g_flMultiplePosition_Y[id], g_iMultipleColor[id][COLOR_STYLE], 0.0, g_flMultipleTime[id], 1.0, 1.0, -1)
3347 ShowSyncHudMsg(id, g_HudSyncMultiple, "%L", id, "MENU_MULTI_TITLE")
3348
3349 ClearSyncHud(id, g_HudSyncGrenade)
3350 set_hudmessage(g_iGrenadeColor[id][COLOR_RED], g_iGrenadeColor[id][COLOR_GREEN], g_iGrenadeColor[id][COLOR_BLUE], g_flGrenadePosition_X[id], g_flGrenadePosition_Y[id], g_iGrenadeColor[id][COLOR_STYLE], 0.0, g_flGrenadeTime[id], 1.0, 1.0, -1)
3351 ShowSyncHudMsg(id, g_HudSyncGrenade, "%L", id, "MENU_GRENADE_TITLE")
3352}
3353
3354set_hud_vars(id)
3355{
3356 g_iShowSingleHud[id] = 1
3357 g_iShowMultipleHud[id] = 1
3358 g_iShowGrenadeHud[id] = 1
3359 g_iShowTakeHud[id] = 1
3360
3361 g_iSingleColor[id][COLOR_RED] = 0
3362 g_iMultipleColor[id][COLOR_RED] = 0
3363 g_iGrenadeColor[id][COLOR_RED] = 200
3364 g_iTakeColor[id][COLOR_RED] = 200
3365 g_iSingleColor[id][COLOR_GREEN] = 200
3366 g_iMultipleColor[id][COLOR_GREEN] = 200
3367 g_iGrenadeColor[id][COLOR_GREEN] = 0
3368 g_iTakeColor[id][COLOR_GREEN] = 0
3369 g_iSingleColor[id][COLOR_BLUE] = 0
3370 g_iMultipleColor[id][COLOR_BLUE] = 0
3371 g_iGrenadeColor[id][COLOR_BLUE] = 0
3372 g_iTakeColor[id][COLOR_BLUE] = 0
3373
3374 g_flMultiplePosition_X[id] = 0.30
3375 g_flMultiplePosition_Y[id] = 0.35
3376 g_flSinglePosition_X[id] = 0.30
3377 g_flSinglePosition_Y[id] = 0.45
3378 g_flTakePosition_X[id] = 0.30
3379 g_flTakePosition_Y[id] = 0.55
3380 g_flGrenadePosition_X[id] = 0.30
3381 g_flGrenadePosition_Y[id] = 0.65
3382
3383 g_flSingleTime[id] = 2.50
3384 g_flMultipleTime[id] = 2.50
3385 g_flGrenadeTime[id] = 2.50
3386 g_flTakeTime[id] = 2.50
3387}
3388
3389reset_record_vars(id, grenade = 0)
3390{
3391 if (grenade)
3392 {
3393 g_iGrenadeDamageDealt[id] = g_iGrenadeHits[id] = 0
3394 g_bGrenadeWallVisible[id] = false
3395 }
3396 else
3397 g_iDamageDealt[id] = g_iHits[id] = 0
3398}
3399
3400show_grenade_damage(id)
3401{
3402 // Enable grenade damage?
3403 if (!get_pcvar_num(cvar_GrenadeDamage)) return
3404
3405 // Static Hud Damage Wall num
3406 static HudDamageWall
3407 HudDamageWall = get_pcvar_num(cvar_HudDamageWall)
3408
3409 switch (get_pcvar_num(cvar_HudDamage))
3410 {
3411 case 2: // Admin
3412 {
3413 if (!g_iShowGrenadeHud[id] || !user_has_flag(id, ACCESS_HUD) || (!HudDamageWall && !g_bGrenadeWallVisible[id])) return
3414
3415 ClearSyncHud(id, g_HudSyncGrenade)
3416 set_hudmessage(g_iGrenadeColor[id][COLOR_RED], g_iGrenadeColor[id][COLOR_GREEN], g_iGrenadeColor[id][COLOR_BLUE], g_flGrenadePosition_X[id], g_flGrenadePosition_Y[id], g_iGrenadeColor[id][COLOR_STYLE], 0.0, g_flGrenadeTime[id], 1.0, 1.0, -1)
3417 ShowSyncHudMsg(id, g_HudSyncGrenade, "%i", g_iGrenadeDamageDealt[id])
3418 }
3419 case 1: // Player
3420 {
3421 if (!g_iShowGrenadeHud[id] || (HudDamageWall == 2 && !user_has_flag(id, ACCESS_HUD) && !g_bGrenadeWallVisible[id]) || (!HudDamageWall && !g_bGrenadeWallVisible[id])) return
3422
3423 ClearSyncHud(id, g_HudSyncGrenade)
3424 set_hudmessage(g_iGrenadeColor[id][COLOR_RED], g_iGrenadeColor[id][COLOR_GREEN], g_iGrenadeColor[id][COLOR_BLUE], g_flGrenadePosition_X[id], g_flGrenadePosition_Y[id], g_iGrenadeColor[id][COLOR_STYLE], 0.0, g_flGrenadeTime[id], 1.0, 1.0, -1)
3425 ShowSyncHudMsg(id, g_HudSyncGrenade, "%i", g_iGrenadeDamageDealt[id])
3426 }
3427 }
3428}
3429
3430/*================================================================================
3431 [Message Hooks]
3432=================================================================================*/
3433
3434public message_damage(msg_id, msg_dest, msg_entity)
3435{
3436 // set damage take (bugfix)
3437 set_pev(msg_entity, pev_dmg_take, 0.0)
3438}
3439
3440public message_health(msg_id, msg_dest, msg_entity)
3441{
3442 // Get player's health
3443 static health
3444 health = get_msg_arg_int(1)
3445
3446 if (health > 0)
3447 g_iPreHealth[msg_entity] = health
3448}
3449
3450colored_print(target, const message[], any:...)
3451{
3452 static buffer[512], i, argscount
3453 argscount = numargs()
3454
3455 // Send to everyone
3456 if (!target)
3457 {
3458 static player
3459 for (player = 1; player <= g_iMaxPlayers; player++)
3460 {
3461 // Not connected
3462 if (!g_bIsConnected[player]) continue
3463
3464 // Remember changed arguments
3465 static changed[5], changedcount // [5] = max LANG_PLAYER occurencies
3466 changedcount = 0
3467
3468 // Replace LANG_PLAYER with player id
3469 for (i = 2; i < argscount; i++)
3470 {
3471 if (getarg(i) == LANG_PLAYER)
3472 {
3473 setarg(i, 0, player)
3474 changed[changedcount] = i
3475 changedcount++
3476 }
3477 }
3478
3479 // Format message for player
3480 vformat(buffer, charsmax(buffer), message, 3)
3481
3482 // Send it
3483 message_begin(MSG_ONE_UNRELIABLE, g_msgSayText, _, player)
3484 write_byte(player)
3485 write_string(buffer)
3486 message_end()
3487
3488 // Replace back player id's with LANG_PLAYER
3489 for (i = 0; i < changedcount; i++)
3490 setarg(changed[i], 0, LANG_PLAYER)
3491 }
3492 }
3493 // Send to specific target
3494 else
3495 {
3496 // Format message for player
3497 vformat(buffer, charsmax(buffer), message, 3)
3498
3499 // Send it
3500 message_begin(MSG_ONE, g_msgSayText, _, target)
3501 write_byte(target)
3502 write_string(buffer)
3503 message_end()
3504 }
3505}
3506
3507/*================================================================================
3508 [Stocks]
3509=================================================================================*/
3510
3511stock ham_cs_get_weapon_ent_owner(ent)
3512{
3513 if (pev_valid(ent) != FM_PDATA_SAFE)
3514 return 0;
3515
3516 return get_pdata_cbase(ent, OFFSET_WEAPONOWNER, OFFSET_LINUX_WEAPONS);
3517}
3518
3519stock bool:fm_is_visible(index, const Float:point[3])
3520{
3521 static Float:start[3], Float:view_ofs[3]
3522
3523 pev(index, pev_origin, start)
3524 pev(index, pev_view_ofs, view_ofs)
3525 xs_vec_add(start, view_ofs, start)
3526
3527 engfunc(EngFunc_TraceLine, start, point, IGNORE_GLASS|IGNORE_MONSTERS, index, 0)
3528
3529 static Float:fraction
3530 get_tr2(0, TR_flFraction, fraction)
3531 if (fraction == 1.0)
3532 return true;
3533
3534 return false;
3535}