· 8 years ago · Jul 03, 2018, 05:42 PM
1// =================================================
2// BEGIN EDITING HERE
3// =================================================
4
5// Should the plugin save player data in SQL database?
6// To save player data in a vault, change "#define USING_SQL" to "//#define USING_SQL"
7// To save player data in SQL, change "//#define USING_SQL" to "#define USING_SQL"
8
9//#define USING_SQL
10
11// The prefix in all of the plugin's messages
12
13new const MESSAGE_TAG[] = "^4[cW`.Hns^4]";
14
15// If the player hasn't ever been to your server, they will get this much xp to start with
16
17#define ENTRY_XP 150
18
19// These determine if these abilities should be enabled or disabled
20// 1 = enabled
21// 0 = disabled
22
23#define ENABLE_GRENADE 1
24#define ENABLE_FLASHBANG_1 1
25#define ENABLE_FLASHBANG_2 1
26#define ENABLE_SMOKEGRENADE 1
27#define ENABLE_TERR_HEALTH 1
28#define ENABLE_CT_HEALTH 1
29#define ENABLE_TERR_ARMOR 1
30#define ENABLE_CT_ARMOR 1
31#define ENABLE_TERR_RESPAWN 1
32#define ENABLE_CT_RESPAWN 1
33#define ENABLE_TERR_NOFALL 1
34#define ENABLE_CT_NOFALL 1
35
36// The maximum level for each ability
37
38#define MAXLEVEL_GRENADE 8
39#define MAXLEVEL_FLASHBANG_1 4
40#define MAXLEVEL_FLASHBANG_2 4
41#define MAXLEVEL_SMOKEGRENADE 4
42#define MAXLEVEL_TERR_HEALTH 10
43#define MAXLEVEL_CT_HEALTH 5
44#define MAXLEVEL_TERR_ARMOR 8
45#define MAXLEVEL_CT_ARMOR 6
46#define MAXLEVEL_TERR_RESPAWN 4
47#define MAXLEVEL_CT_RESPAWN 4
48#define MAXLEVEL_TERR_NOFALL 8
49#define MAXLEVEL_CT_NOFALL 8
50
51// The xp amount required to buy the first level
52
53#define FIRST_XP_GRENADE 200
54#define FIRST_XP_FLASHBANG_1 200
55#define FIRST_XP_FLASHBANG_2 200
56#define FIRST_XP_SMOKEGRENADE 200
57#define FIRST_XP_TERR_HEALTH 200
58#define FIRST_XP_CT_HEALTH 200
59#define FIRST_XP_TERR_ARMOR 200
60#define FIRST_XP_CT_ARMOR 200
61#define FIRST_XP_TERR_RESPAWN 10000
62#define FIRST_XP_CT_RESPAWN 3000
63#define FIRST_XP_TERR_NOFALL 200
64#define FIRST_XP_CT_NOFALL 200
65
66// The maximum chance possible for this ability (happens when player has maximum level)
67
68#define CHANCE_MAX_GRENADE 100
69#define CHANCE_MAX_FLASHBANG_1 100
70#define CHANCE_MAX_FLASHBANG_2 100
71#define CHANCE_MAX_SMOKEGRENADE 100
72#define CHANCE_MAX_TERR_RESPAWN 50
73#define CHANCE_MAX_CT_RESPAWN 100
74#define CHANCE_MAX_TERR_NOFALL 80
75#define CHANCE_MAX_CT_NOFALL 80
76
77// =================================================
78// STOP EDITING HERE
79// =================================================
80
81
82#include <amxmodx>
83#include <amxmisc>
84#include <cstrike>
85#include <hamsandwich>
86#include <fun>
87#include <regex>
88#include <hlsdk_const>
89
90#if defined USING_SQL
91#include <sqlx>
92
93new Handle:g_sql_tuple;
94#else
95#include <nvault>
96
97new g_vault;
98#endif
99
100
101new const VERSION[] = "0.0.1";
102
103
104#pragma semicolon 1
105
106enum _:Grenades
107{
108 NADE_HE,
109 NADE_FL1,
110 NADE_FL2,
111 NADE_SM
112};
113
114new const g_nade_enabled[Grenades] =
115{
116 ENABLE_GRENADE,
117 ENABLE_FLASHBANG_1,
118 ENABLE_FLASHBANG_2,
119 ENABLE_SMOKEGRENADE
120};
121
122new const g_any_nade_enabled = ENABLE_GRENADE + ENABLE_FLASHBANG_1 + ENABLE_FLASHBANG_2 + ENABLE_SMOKEGRENADE;
123
124new const g_nade_names[Grenades][] =
125{
126 "HE Grenade",
127 "Flashbang #1",
128 "Flashbang #2",
129 "Frost Nade"
130};
131
132new const g_nade_classnames[Grenades][] =
133{
134 "weapon_hegrenade",
135 "weapon_flashbang",
136 "weapon_flashbang",
137 "weapon_smokegrenade"
138};
139
140new const g_nade_maxlevels[Grenades] =
141{
142 MAXLEVEL_GRENADE,
143 MAXLEVEL_FLASHBANG_1,
144 MAXLEVEL_FLASHBANG_2,
145 MAXLEVEL_SMOKEGRENADE
146};
147
148new const g_nade_first_xp[Grenades] =
149{
150 FIRST_XP_GRENADE,
151 FIRST_XP_FLASHBANG_1,
152 FIRST_XP_FLASHBANG_2,
153 FIRST_XP_SMOKEGRENADE
154};
155
156new const g_nade_max_chance[Grenades] =
157{
158 CHANCE_MAX_GRENADE,
159 CHANCE_MAX_FLASHBANG_1,
160 CHANCE_MAX_FLASHBANG_2,
161 CHANCE_MAX_SMOKEGRENADE
162};
163
164new const g_team_names[CsTeams][] =
165{
166 "Spectator",
167 "Terrorist",
168 "Counter-Terrorist",
169 "Spectator"
170};
171
172new const g_health_enabled[CsTeams] =
173{
174 0,
175 ENABLE_TERR_HEALTH,
176 ENABLE_CT_HEALTH,
177 0
178};
179
180new const g_any_health_enabled = ENABLE_TERR_HEALTH + ENABLE_CT_HEALTH;
181
182new const g_health_names[CsTeams][] =
183{
184 "",
185 "T Extra Health",
186 "CT Extra Health",
187 ""
188};
189
190new const g_health_maxamount[CsTeams] =
191{
192 0,
193 100,
194 50,
195 0
196};
197
198new const g_health_maxlevels[CsTeams] =
199{
200 0,
201 MAXLEVEL_TERR_HEALTH,
202 MAXLEVEL_CT_HEALTH,
203 0
204};
205
206new const g_health_first_xp[CsTeams] =
207{
208 0,
209 FIRST_XP_TERR_HEALTH,
210 FIRST_XP_CT_HEALTH,
211 0
212};
213
214new const g_armor_enabled[CsTeams] =
215{
216 0,
217 ENABLE_TERR_ARMOR,
218 ENABLE_CT_ARMOR,
219 0
220};
221
222new const g_any_armor_enabled = ENABLE_TERR_ARMOR + ENABLE_CT_ARMOR;
223
224new const g_armor_names[CsTeams][] =
225{
226 "",
227 "T Armor",
228 "CT Armor",
229 ""
230};
231
232new const g_armor_maxamount[CsTeams] =
233{
234 0,
235 200,
236 150,
237 0
238};
239
240new const g_armor_maxlevels[CsTeams] =
241{
242 0,
243 MAXLEVEL_TERR_ARMOR,
244 MAXLEVEL_CT_ARMOR,
245 0
246};
247
248new const g_armor_first_xp[CsTeams] =
249{
250 0,
251 FIRST_XP_TERR_ARMOR,
252 FIRST_XP_CT_ARMOR,
253 0
254};
255
256new const g_respawn_enabled[CsTeams] =
257{
258 0,
259 ENABLE_TERR_RESPAWN,
260 ENABLE_CT_RESPAWN,
261 0
262};
263
264new const g_any_respawn_enabled = ENABLE_TERR_RESPAWN + ENABLE_CT_RESPAWN;
265
266new const g_respawn_names[CsTeams][] =
267{
268 "",
269 "T Respawn Chance",
270 "CT Respawn Chance",
271 ""
272};
273
274new const g_respawn_maxlevels[CsTeams] =
275{
276 0,
277 MAXLEVEL_TERR_RESPAWN,
278 MAXLEVEL_CT_RESPAWN,
279 0
280};
281
282new const g_respawn_first_xp[CsTeams] =
283{
284 0,
285 FIRST_XP_TERR_RESPAWN,
286 FIRST_XP_CT_RESPAWN,
287 0
288};
289
290new const g_respawn_max_chance[CsTeams] =
291{
292 0,
293 CHANCE_MAX_TERR_RESPAWN,
294 CHANCE_MAX_CT_RESPAWN,
295 0
296};
297
298new const g_nofall_enabled[CsTeams] =
299{
300 0,
301 ENABLE_TERR_NOFALL,
302 ENABLE_CT_NOFALL,
303 0
304};
305
306new const g_any_nofall_enabled = ENABLE_TERR_NOFALL + ENABLE_CT_NOFALL;
307
308new const g_nofall_names[CsTeams][] =
309{
310 "",
311 "T Fall Damage Reducer",
312 "CT Fall Damage Reducer",
313 ""
314};
315
316new const g_nofall_maxlevels[CsTeams] =
317{
318 0,
319 MAXLEVEL_TERR_NOFALL,
320 MAXLEVEL_CT_NOFALL,
321 0
322};
323
324new const g_nofall_first_xp[CsTeams] =
325{
326 0,
327 FIRST_XP_TERR_NOFALL,
328 FIRST_XP_CT_NOFALL,
329 0
330};
331
332new const g_nofall_max_chance[CsTeams] =
333{
334 0,
335 CHANCE_MAX_TERR_NOFALL,
336 CHANCE_MAX_CT_NOFALL,
337 0
338};
339
340#define ANY_ABILITY_ENABLED (g_any_nade_enabled || g_any_health_enabled || g_any_armor_enabled || g_any_respawn_enabled || g_any_nofall_enabled)
341
342new g_authid[33][35];
343
344new g_xp[33];
345
346new g_first_time[33];
347#if defined USING_SQL
348new g_loaded_data[33];
349#endif
350
351new g_used_revive[33];
352
353new g_nade_level[33][Grenades];
354new g_armor_level[33][CsTeams];
355new g_respawn_level[33][CsTeams];
356new g_health_level[33][CsTeams];
357new g_nofall_level[33][CsTeams];
358
359new cvar_xp_suicide;
360new cvar_xp_kill;
361new cvar_xp_headshot;
362new cvar_xp_grenade;
363new cvar_xp_survive;
364new cvar_xp_win;
365new cvar_spawn_nade_delay;
366
367new Float:g_nade_give_time;
368
369new Regex:g_SteamID_pattern;
370new g_regex_return;
371
372new g_first_client;
373new g_max_clients;
374
375new g_msgid_SayText;
376
377#if defined USING_SQL
378public plugin_precache()
379{
380 g_sql_tuple = SQL_MakeStdTuple();
381
382 SQL_ThreadQuery(g_sql_tuple, "QueryCreateTable", "CREATE TABLE IF NOT EXISTS `hns_xp` ( `name` VARCHAR(32) NOT NULL, `authid` VARCHAR(35) NOT NULL, `data` VARCHAR(256) NOT NULL );" );
383}
384
385public QueryCreateTable(failstate, Handle:query, error[], errnum, data[], size, Float:queuetime)
386{
387 if( failstate == TQUERY_CONNECT_FAILED
388 || failstate == TQUERY_QUERY_FAILED )
389 {
390 set_fail_state(error);
391 }
392}
393#endif
394
395public plugin_init()
396{
397 register_plugin("HideNSeek XP Mod", VERSION, "Exolent");
398 register_cvar("hnsxp_author", "Exolent", FCVAR_SPONLY);
399 register_cvar("hnsxp_version", VERSION, FCVAR_SPONLY);
400
401 register_clcmd("say /xp", "CmdMainMenu");
402
403 register_concmd("hnsxp_give_xp", "CmdGiveXP", ADMIN_RCON, "<nick, #userid, authid> <xp>");
404 register_concmd("hnsxp_remove_xp", "CmdRemoveXP", ADMIN_RCON, "<nick, #userid, authid> <xp>");
405
406 register_event("HLTV", "EventNewRound", "a", "1=0", "2=0");
407 register_event("DeathMsg", "EventDeathMsg", "a");
408 register_logevent("EventRoundStart", 2, "1=Round_Start");
409 register_logevent("EventRoundEnd", 2, "1=Round_End");
410 register_event("TextMsg", "EventRoundRestart", "a", "2&#Game_C", "2&#Game_w");
411
412 RegisterHam(Ham_Spawn, "player", "FwdPlayerSpawn", 1);
413 RegisterHam(Ham_Killed, "player", "FwdPlayerDeath", 1);
414 RegisterHam(Ham_TakeDamage, "player", "FwdPlayerDamage");
415
416 cvar_xp_suicide = register_cvar("hnsxp_xp_suicide", "5");
417 cvar_xp_kill = register_cvar("hnsxp_xp_kill", "35");
418 cvar_xp_headshot = register_cvar("hnsxp_xp_headshot", "45");
419 cvar_xp_grenade = register_cvar("hnsxp_xp_grenade", "45");
420 cvar_xp_survive = register_cvar("hnsxp_xp_survive", "8");
421 cvar_xp_win = register_cvar("hnsxp_xp_win", "10");
422 cvar_spawn_nade_delay = register_cvar("hnsxp_spawn_nade_delay", "10");
423
424 #if !defined USING_SQL
425 g_vault = nvault_open("hnsxp");
426 #endif
427
428 new err[2];
429 g_SteamID_pattern = regex_compile("^^STEAM_0:(0|1):\d+$", g_regex_return, err, sizeof(err) - 1);
430
431 g_first_client = 1;
432 g_max_clients = get_maxplayers();
433
434 g_msgid_SayText = get_user_msgid("SayText");
435}
436
437#if !defined USING_SQL
438public plugin_end()
439{
440 nvault_close(g_vault);
441}
442#endif
443
444public plugin_natives()
445{
446 register_library("hns_xp");
447 register_native("hnsxp_get_user_xp", "_get_xp");
448 register_native("hnsxp_set_user_xp", "_set_xp");
449}
450
451public _get_xp(plugin, params)
452{
453 return g_xp[get_param(1)];
454}
455
456public _set_xp(plugin, params)
457{
458 new client = get_param(1);
459 g_xp[client] = max(0, get_param(2));
460 Save(client);
461 return g_xp[client];
462}
463
464public client_authorized(client)
465{
466 if( !is_user_bot(client) && !is_user_hltv(client) )
467 {
468 /* is this still called in LAN, non-steam, etc? */
469 get_user_authid(client, g_authid[client], sizeof(g_authid[]) - 1);
470
471 if( !IsValidAuthid(g_authid[client]) )
472 {
473 g_authid[client][0] = 0;
474 }
475 else
476 {
477 Load(client);
478 }
479 }
480}
481
482public client_disconnect(client)
483{
484 Save(client);
485
486 g_authid[client][0] = 0;
487 g_first_time[client] = 0;
488 #if defined USING_SQL
489 g_loaded_data[client] = 0;
490 #endif
491 g_used_revive[client] = 0;
492}
493
494public CmdMainMenu(client)
495{
496 ShowMainMenu(client);
497}
498
499public CmdGiveXP(client, level, cid)
500{
501 if( !cmd_access(client, level, cid, 3) ) return PLUGIN_HANDLED;
502
503 static arg[35];
504 read_argv(1, arg, sizeof(arg) - 1);
505
506 new target = cmd_target(client, arg, CMDTARGET_OBEY_IMMUNITY|CMDTARGET_NO_BOTS);
507 if( !target ) return PLUGIN_HANDLED;
508
509 if( !IsUserAuthorized(target) )
510 {
511 console_print(client, "Target has not authorized with the server.");
512 return PLUGIN_HANDLED;
513 }
514
515 read_argv(2, arg, sizeof(arg) - 1);
516 new xp = str_to_num(arg);
517
518 if( xp <= 0 )
519 {
520 console_print(client, "XP must be a value greater than 0!");
521 if( xp < 0 )
522 {
523 console_print(client, "Use hnsxp_remove_xp instead.");
524 }
525 return PLUGIN_HANDLED;
526 }
527
528 g_xp[target] += xp;
529
530 Save(target);
531
532 static name[2][32];
533 get_user_name(client, name[0], sizeof(name[]) - 1);
534 get_user_name(target, name[1], sizeof(name[]) - 1);
535
536 Print(0, "%s gave %i XP to %s.", name[0], xp, name[1]);
537
538 static steamid[2][35];
539 get_user_authid(client, steamid[0], sizeof(steamid[]) - 1);
540 get_user_authid(target, steamid[1], sizeof(steamid[]) - 1);
541
542 log_amx("%s (%s) gave %i XP to %s (%s)", name[0], steamid[0], xp, name[1], steamid[1]);
543
544 return PLUGIN_HANDLED;
545}
546
547public CmdRemoveXP(client, level, cid)
548{
549 if( !cmd_access(client, level, cid, 3) ) return PLUGIN_HANDLED;
550
551 static arg[35];
552 read_argv(1, arg, sizeof(arg) - 1);
553
554 new target = cmd_target(client, arg, CMDTARGET_OBEY_IMMUNITY|CMDTARGET_NO_BOTS);
555 if( !target ) return PLUGIN_HANDLED;
556
557 if( !IsUserAuthorized(target) )
558 {
559 console_print(client, "Target has not authorized with the server.");
560 return PLUGIN_HANDLED;
561 }
562
563 read_argv(2, arg, sizeof(arg) - 1);
564 new xp = str_to_num(arg);
565
566 if( xp <= 0 )
567 {
568 console_print(client, "XP must be a value greater than 0!");
569 if( xp < 0 )
570 {
571 console_print(client, "Use hnsxp_give_xp instead.");
572 }
573 return PLUGIN_HANDLED;
574 }
575
576 g_xp[target] -= xp;
577
578 Save(target);
579
580 static name[2][32];
581 get_user_name(client, name[0], sizeof(name[]) - 1);
582 get_user_name(target, name[1], sizeof(name[]) - 1);
583
584 Print(0, "%s removed %i XP from %s.", name[0], xp, name[1]);
585
586 static steamid[2][35];
587 get_user_authid(client, steamid[0], sizeof(steamid[]) - 1);
588 get_user_authid(target, steamid[1], sizeof(steamid[]) - 1);
589
590 log_amx("%s (%s) removed %i XP from %s (%s)", name[0], steamid[0], xp, name[1], steamid[1]);
591
592 return PLUGIN_HANDLED;
593}
594
595public EventNewRound()
596{
597 arrayset(g_used_revive, 0, sizeof(g_used_revive));
598
599 g_nade_give_time = 9999999.9;
600}
601
602public EventDeathMsg()
603{
604 new killer = read_data(1);
605 new victim = read_data(2);
606
607 if( (g_first_client <= killer <= g_max_clients) && victim != killer )
608 {
609 if( IsUserAuthorized(killer) )
610 {
611 // regular kill
612 new xp = get_pcvar_num(cvar_xp_kill);
613
614 if( read_data(3) )
615 {
616 // headshot kill
617 xp += get_pcvar_num(cvar_xp_headshot);
618 }
619 else
620 {
621 static weapon[20];
622 read_data(4, weapon, sizeof(weapon) - 1);
623
624 if( contain(weapon, "grenade") >= 0 )
625 {
626 // grenade kill (or frostnade)
627 xp += get_pcvar_num(cvar_xp_grenade);
628 }
629 }
630
631 g_xp[killer] += xp;
632
633 Print(killer, "You gained %i XP!", xp);
634
635 Save(killer);
636 }
637 }
638 else if( IsUserAuthorized(victim) )
639 {
640 // victim died of map causes or killed self
641 new xp = get_pcvar_num(cvar_xp_suicide);
642
643 g_xp[victim] -= xp;
644
645 Print(victim, "You lost %i XP!", xp);
646
647 Save(victim);
648 }
649}
650
651public EventRoundStart()
652{
653 g_nade_give_time = get_pcvar_float(cvar_spawn_nade_delay);
654
655 set_task(g_nade_give_time, "TaskGiveNades", 1234);
656
657 g_nade_give_time += get_gametime();
658}
659
660public EventRoundEnd()
661{
662 EventRoundRestart();
663
664 new hider, seeker, hider_alive;
665
666 for( new i = g_first_client; i <= g_max_clients; i++ )
667 {
668 if( is_user_connected(i) )
669 {
670 switch( cs_get_user_team(i) )
671 {
672 case CS_TEAM_CT:
673 {
674 if( !seeker )
675 {
676 seeker = i;
677 }
678 }
679 case CS_TEAM_T:
680 {
681 if( !hider )
682 {
683 hider = i;
684
685 if( !hider_alive && is_user_alive(i) )
686 {
687 hider_alive = i;
688 }
689 }
690 }
691 }
692
693 if( seeker && hider && hider_alive )
694 {
695 break;
696 }
697 }
698 }
699
700 if( !hider || !seeker )
701 {
702 return;
703 }
704
705 new CsTeams:winner = CS_TEAM_CT;
706
707 if( hider_alive )
708 {
709 winner = CS_TEAM_T;
710
711 new survive = get_pcvar_num(cvar_xp_survive);
712 for( new client = g_first_client; client <= g_max_clients; client++ )
713 {
714 if( IsUserAuthorized(client) && is_user_alive(client) && cs_get_user_team(client) == CS_TEAM_T )
715 {
716 g_xp[client] += survive;
717 Save(client);
718
719 Print(client, "You gained %i XP for surviving!", survive);
720 }
721 }
722 }
723
724 new win = get_pcvar_num(cvar_xp_win);
725 for( new client = g_first_client; client <= g_max_clients; client++ )
726 {
727 if( IsUserAuthorized(client) && is_user_alive(client) && cs_get_user_team(client) == winner )
728 {
729 g_xp[client] += win;
730 Save(client);
731
732 Print(client, "You gained %i XP for winning the round!", win);
733 }
734 }
735}
736
737public EventRoundRestart()
738{
739 remove_task(1234);
740
741 g_nade_give_time = 9999999.9;
742}
743
744public FwdPlayerSpawn(client)
745{
746 if( is_user_alive(client) )
747 {
748 new CsTeams:team = cs_get_user_team(client);
749 if( team == CS_TEAM_T || team == CS_TEAM_CT )
750 {
751 if( g_first_time[client] )
752 {
753 Print(client, "It is your first time playing this HideNSeek XP mod, so you are rewarded with %i XP!", ENTRY_XP);
754 Print(client, "You earn XP based upon your gameplay, and you can buy more levels in the menu.");
755 Print(client, "[cW`] Type /xp to view what you can get!");
756
757 g_first_time[client] = 0;
758 }
759 else
760 {
761 if( g_health_enabled[team] )
762 {
763 new health = g_health_maxamount[team] * g_health_level[client][team] / g_health_maxlevels[team];
764 if( health > 0 )
765 {
766 set_user_health(client, get_user_health(client) + health);
767 }
768 }
769
770 if( g_armor_enabled[team] )
771 {
772 new armorvalue = g_armor_maxamount[team] * g_armor_level[client][team] / g_armor_maxlevels[team];
773 if( armorvalue == 0 )
774 {
775 cs_set_user_armor(client, armorvalue, CS_ARMOR_NONE);
776 }
777 else if( armorvalue < 100 )
778 {
779 cs_set_user_armor(client, armorvalue, CS_ARMOR_KEVLAR);
780 }
781 else
782 {
783 cs_set_user_armor(client, armorvalue, CS_ARMOR_VESTHELM);
784 }
785 }
786 }
787
788 if( get_gametime() >= g_nade_give_time )
789 {
790 GiveNades(client);
791 }
792 }
793 }
794}
795
796public FwdPlayerDeath(client, killer, shouldgib)
797{
798 if( !g_used_revive[client] )
799 {
800 new CsTeams:team = cs_get_user_team(client);
801 if( team == CS_TEAM_T || team == CS_TEAM_CT )
802 {
803 if( g_respawn_enabled[team] )
804 {
805 new percent = g_respawn_max_chance[team] * g_respawn_level[client][team] / g_respawn_maxlevels[team];
806 if( random_num(1, 100) <= percent )
807 {
808 if( HasTeammateAlive(client, team) )
809 {
810 set_task(0.5, "TaskRespawn", client);
811
812 Print(client, "You have been respawned! (%i%% chance)", percent);
813
814 g_used_revive[client] = 1;
815 }
816 }
817 }
818 }
819 }
820}
821
822public FwdPlayerDamage(client, inflictor, attacker, Float:damage, damagebits)
823{
824 if( is_user_alive(client) && (damagebits & DMG_FALL) )
825 {
826 new CsTeams:team = cs_get_user_team(client);
827 if( team == CS_TEAM_T || team == CS_TEAM_CT )
828 {
829 if( g_nofall_enabled[team] )
830 {
831 new percent = g_nofall_max_chance[team] * g_nofall_level[client][team] / g_nofall_maxlevels[team];
832 SetHamParamFloat(4, damage * (1.0 - (float(percent) / 100.0)));
833 }
834 }
835 }
836}
837
838public TaskRespawn(client)
839{
840 ExecuteHamB(Ham_CS_RoundRespawn, client);
841}
842
843public TaskGiveNades()
844{
845 for( new client = g_first_client; client <= g_max_clients; client++ )
846 {
847 if( is_user_alive(client) )
848 {
849 GiveNades(client);
850 }
851 }
852}
853
854HasTeammateAlive(client, CsTeams:team)
855{
856 for( new i = g_first_client; i <= g_max_clients; i++ )
857 {
858 if( i == client ) continue;
859
860 if( is_user_alive(i) && cs_get_user_team(i) == team )
861 {
862 return 1;
863 }
864 }
865
866 return 0;
867}
868
869GiveNades(client)
870{
871 new CsTeams:team = cs_get_user_team(client);
872
873 if( team == CS_TEAM_T )
874 {
875 static percent;
876 for( new i = 0; i < Grenades; i++ )
877 {
878 if( g_nade_enabled[i] )
879 {
880 percent = g_nade_max_chance[i] * g_nade_level[client][i] / g_nade_maxlevels[i];
881 if( percent > 0 && (percent == 100 || random_num(1, 100) <= percent) )
882 {
883 give_item(client, g_nade_classnames[i]);
884
885 if( percent < 100 )
886 {
887 Print(client, "You received your %s! (%i%% chance)", g_nade_names[i], percent);
888 }
889 }
890 }
891 }
892 }
893}
894
895ShowMainMenu(client)
896{
897 static title[128];
898 formatex(title, sizeof(title) - 1, "[HNS XP by Exolent]^n[cW`Hns]MainMenu^n^nYour XP: \w%i", g_xp[client]);
899 new menu = menu_create(title, "MenuMain");
900
901 menu_additem(menu, "\yHelp", "*");
902 if( g_any_nade_enabled )
903 {
904 menu_additem(menu, "Grenades Menu", "1");
905 }
906 if( g_any_health_enabled )
907 {
908 menu_additem(menu, "Health Menu", "2");
909 }
910 if( g_any_armor_enabled )
911 {
912 menu_additem(menu, "Armor Menu", "3");
913 }
914 if( g_any_respawn_enabled )
915 {
916 menu_additem(menu, "Respawn Menu", "4");
917 }
918 if( g_any_nofall_enabled )
919 {
920 menu_additem(menu, "Fall Damage Menu^n", "5");
921 }
922 if( ANY_ABILITY_ENABLED )
923 {
924 menu_additem(menu, "Player Info", "6");
925 }
926
927 menu_display(client, menu);
928}
929
930public MenuMain(client, menu, item)
931{
932 if( item == MENU_EXIT )
933 {
934 menu_destroy(menu);
935 return;
936 }
937
938 static _access, info[4], callback;
939 menu_item_getinfo(menu, item, _access, info, sizeof(info) - 1, _, _, callback);
940 menu_destroy(menu);
941
942 switch( info[0] )
943 {
944 case '*':
945 {
946 static motd[2500];
947 new len = formatex(motd, sizeof(motd) - 1, "<body style=^"background-color:#030303; color:#FF8F00^">");
948 len += format(motd[len], sizeof(motd) - len - 1, "<p align=^"center^">");
949 len += format(motd[len], sizeof(motd) - len - 1, "HideNSeek XP Mod is an experienced based addon for HideNSeek.<br>");
950 len += format(motd[len], sizeof(motd) - len - 1, "Players earn experience points by how well they play the game.<br>");
951 len += format(motd[len], sizeof(motd) - len - 1, "<br>");
952 len += format(motd[len], sizeof(motd) - len - 1, "<table border=0>");
953 len += format(motd[len], sizeof(motd) - len - 1, "<tr><th>Action</th><th>XP</th></tr>");
954 len += format(motd[len], sizeof(motd) - len - 1, "<tr><td>Kill</td><td>+%i</td></tr>", get_pcvar_num(cvar_xp_kill));
955 len += format(motd[len], sizeof(motd) - len - 1, "<tr><td>Grenade</td><td>+%i</td></tr>", get_pcvar_num(cvar_xp_grenade));
956 len += format(motd[len], sizeof(motd) - len - 1, "<tr><td>Headshot</td><td>+%i</td></tr>", get_pcvar_num(cvar_xp_headshot));
957 len += format(motd[len], sizeof(motd) - len - 1, "<tr><td>Suicide</td><td>-%i</td></tr>", get_pcvar_num(cvar_xp_suicide));
958 len += format(motd[len], sizeof(motd) - len - 1, "<tr><td>Survive as a T</td><td>+%i</td></tr>", get_pcvar_num(cvar_xp_survive));
959 len += format(motd[len], sizeof(motd) - len - 1, "<tr><td>Win Round</td><td>+%i</td></tr>", get_pcvar_num(cvar_xp_win));
960 len += format(motd[len], sizeof(motd) - len - 1, "</table>");
961 len += format(motd[len], sizeof(motd) - len - 1, "With these XP points, you can buy upgrades.<br>");
962 len += format(motd[len], sizeof(motd) - len - 1, "For a list of these upgrades, type /xp again and view the other menus inside.");
963 len += format(motd[len], sizeof(motd) - len - 1, "</p>");
964 len += format(motd[len], sizeof(motd) - len - 1, "</body>");
965
966 show_motd(client, motd, "HideNSeek XP Mod Info");
967 }
968 case '1':
969 {
970 ShowGrenadesMenu(client);
971 }
972 case '2':
973 {
974 ShowHealthMenu(client);
975 }
976 case '3':
977 {
978 ShowArmorMenu(client);
979 }
980 case '4':
981 {
982 ShowRespawnMenu(client);
983 }
984 case '5':
985 {
986 ShowNoFallMenu(client);
987 }
988 case '6':
989 {
990 ShowPlayerMenu(client);
991 }
992 }
993}
994
995ShowGrenadesMenu(client)
996{
997 static title[128];
998 formatex(title, sizeof(title) - 1, "[HNS XP by Exolent]^nGrenades Menu^n^nNote: \wGrenade abilities are for \rT's Only!\y^n^nYour XP: \w%i", g_xp[client]);
999 new menu = menu_create(title, "MenuGrenades");
1000 new callback = menu_makecallback("CallbackGrenades");
1001
1002 menu_additem(menu, "\yHelp", "*", _, callback);
1003
1004 static level, xp, percent, item[128], info[4];
1005 for( new i = 0; i < Grenades; i++ )
1006 {
1007 if( g_nade_enabled[i] )
1008 {
1009 level = g_nade_level[client][i] + 1;
1010 percent = g_nade_max_chance[i] * level / g_nade_maxlevels[i];
1011
1012 if( g_nade_level[client][i] < g_nade_maxlevels[i] )
1013 {
1014 xp = g_nade_first_xp[i] * (1 << (level - 1));
1015 formatex(item, sizeof(item) - 1, "%s: \yLevel %i (%i%%) \r[\w%i XP\r]", g_nade_names[i], level, percent, xp);
1016 }
1017 else
1018 {
1019 formatex(item, sizeof(item) - 1, "%s: \yLevel %i (%i%%) \r[\wMaxed Out!\r]", g_nade_names[i], level, percent);
1020 }
1021
1022 num_to_str(i, info, sizeof(info) - 1);
1023
1024 menu_additem(menu, item, info, _, callback);
1025 }
1026 }
1027
1028 menu_display(client, menu);
1029}
1030
1031public MenuGrenades(client, menu, item)
1032{
1033 if( item == MENU_EXIT )
1034 {
1035 menu_destroy(menu);
1036 ShowMainMenu(client);
1037 return;
1038 }
1039
1040 static _access, info[4], callback;
1041 menu_item_getinfo(menu, item, _access, info, sizeof(info) - 1, _, _, callback);
1042 menu_destroy(menu);
1043
1044 if( info[0] == '*' )
1045 {
1046 static motd[2500];
1047 new len = formatex(motd, sizeof(motd) - 1, "<body style=^"background-color:#030303; color:#FF8F00^">");
1048 len += format(motd[len], sizeof(motd) - len - 1, "<p align=^"center^">");
1049 len += format(motd[len], sizeof(motd) - len - 1, "The Grenades ability for the XP Mod is for Terrorists only.<br>");
1050 len += format(motd[len], sizeof(motd) - len - 1, "The Grenades ability contains the HE Grenade, 2 Flashbangs, and Frost Nade.<br>");
1051 len += format(motd[len], sizeof(motd) - len - 1, "These are the grenades you are given when you receive the your items after the hide timer ends.<br>");
1052 len += format(motd[len], sizeof(motd) - len - 1, "<br>");
1053 len += format(motd[len], sizeof(motd) - len - 1, "<table>");
1054 len += format(motd[len], sizeof(motd) - len - 1, "<tr>");
1055 len += format(motd[len], sizeof(motd) - len - 1, "<th></th>");
1056 for( new i = 0; i < Grenades; i++ )
1057 {
1058 if( g_nade_enabled[i] )
1059 {
1060 len += format(motd[len], sizeof(motd) - len - 1, "<th>%s</th>", g_nade_names[i]);
1061 }
1062 }
1063 len += format(motd[len], sizeof(motd) - len - 1, "</tr>");
1064 len += format(motd[len], sizeof(motd) - len - 1, "<tr>");
1065 len += format(motd[len], sizeof(motd) - len - 1, "<th>Chance Intervals</th>");
1066 for( new i = 0; i < Grenades; i++ )
1067 {
1068 if( g_nade_enabled[i] )
1069 {
1070 len += format(motd[len], sizeof(motd) - len - 1, "<td>%i%%</td>", (g_nade_max_chance[i] / g_nade_maxlevels[i]));
1071 }
1072 }
1073 len += format(motd[len], sizeof(motd) - len - 1, "</tr>");
1074 len += format(motd[len], sizeof(motd) - len - 1, "<tr>");
1075 len += format(motd[len], sizeof(motd) - len - 1, "<th>Max Level</th>");
1076 for( new i = 0; i < Grenades; i++ )
1077 {
1078 if( g_nade_enabled[i] )
1079 {
1080 len += format(motd[len], sizeof(motd) - len - 1, "<td>%i</td>", g_nade_maxlevels[i]);
1081 }
1082 }
1083 len += format(motd[len], sizeof(motd) - len - 1, "</tr>");
1084 len += format(motd[len], sizeof(motd) - len - 1, "<th>Max Chance</th>");
1085 for( new i = 0; i < Grenades; i++ )
1086 {
1087 if( g_nade_enabled[i] )
1088 {
1089 len += format(motd[len], sizeof(motd) - len - 1, "<td>%i%%</td>", g_nade_max_chance[i]);
1090 }
1091 }
1092 len += format(motd[len], sizeof(motd) - len - 1, "</tr>");
1093 len += format(motd[len], sizeof(motd) - len - 1, "</table>");
1094 len += format(motd[len], sizeof(motd) - len - 1, "</p>");
1095 len += format(motd[len], sizeof(motd) - len - 1, "</body>");
1096
1097 show_motd(client, motd, "XP Grenades Info");
1098 }
1099 else
1100 {
1101 new upgrade = str_to_num(info);
1102
1103 new level = g_nade_level[client][upgrade] + 1;
1104 new xp = g_nade_first_xp[upgrade] * (1 << (level - 1));
1105 new percent = g_nade_max_chance[upgrade] * level / g_nade_maxlevels[upgrade];
1106
1107 g_xp[client] -= xp;
1108 g_nade_level[client][upgrade] = level;
1109
1110 Save(client);
1111
1112 Print(client, "You bought %s Level %i (%i%%) for %i XP!", g_nade_names[upgrade], level, percent, xp);
1113 }
1114
1115 ShowGrenadesMenu(client);
1116}
1117
1118public CallbackGrenades(client, menu, item)
1119{
1120 static _access, info[4], callback;
1121 menu_item_getinfo(menu, item, _access, info, sizeof(info) - 1, _, _, callback);
1122
1123 if( info[0] == '*' ) return ITEM_ENABLED;
1124
1125 new upgrade = str_to_num(info);
1126 if( g_nade_level[client][upgrade] == g_nade_maxlevels[upgrade] )
1127 {
1128 return ITEM_DISABLED;
1129 }
1130
1131 new xp = g_nade_first_xp[upgrade] * (1 << g_nade_level[client][upgrade]);
1132 if( g_xp[client] < xp )
1133 {
1134 return ITEM_DISABLED;
1135 }
1136
1137 return ITEM_ENABLED;
1138}
1139
1140ShowHealthMenu(client)
1141{
1142 static title[128];
1143 formatex(title, sizeof(title) - 1, "[HNS XP by Exolent]^nHealth Menu^n^nYour XP: \w%i", g_xp[client]);
1144 new menu = menu_create(title, "MenuHealth");
1145 new callback = menu_makecallback("CallbackHealth");
1146
1147 menu_additem(menu, "\yHelp", "*", _, callback);
1148
1149 static level, xp, amount, item[128], info[4];
1150 for( new CsTeams:i = CS_TEAM_T; i <= CS_TEAM_CT; i++ )
1151 {
1152 if( g_health_enabled[i] )
1153 {
1154 level = g_health_level[client][i] + 1;
1155 amount = g_health_maxamount[i] * level / g_health_maxlevels[i];
1156
1157 if( g_health_level[client][i] < g_health_maxlevels[i] )
1158 {
1159 xp = g_health_first_xp[i] * (1 << (level - 1));
1160 formatex(item, sizeof(item) - 1, "%s: \yLevel %i (%i HP) \r[\w%i XP\r]", g_health_names[i], level, amount, xp);
1161 }
1162 else
1163 {
1164 formatex(item, sizeof(item) - 1, "\w%s: \yLevel %i (%i HP) \r[\wMaxed Out!\r]", g_health_names[i], level, amount);
1165 }
1166
1167 num_to_str(_:i, info, sizeof(info) - 1);
1168
1169 menu_additem(menu, item, info, _, callback);
1170 }
1171 }
1172
1173 menu_display(client, menu);
1174}
1175
1176public MenuHealth(client, menu, item)
1177{
1178 if( item == MENU_EXIT )
1179 {
1180 menu_destroy(menu);
1181 ShowMainMenu(client);
1182 return;
1183 }
1184
1185 static _access, info[4], callback;
1186 menu_item_getinfo(menu, item, _access, info, sizeof(info) - 1, _, _, callback);
1187 menu_destroy(menu);
1188
1189 if( info[0] == '*' )
1190 {
1191 static motd[2500];
1192 new len = formatex(motd, sizeof(motd) - 1, "<body style=^"background-color:#030303; color:#FF8F00^">");
1193 len += format(motd[len], sizeof(motd) - len - 1, "<p align=^"center^">");
1194 len += format(motd[len], sizeof(motd) - len - 1, "The Health ability is the amount of HP that is added to your spawn health.<br>");
1195 len += format(motd[len], sizeof(motd) - len - 1, "<br>");
1196 len += format(motd[len], sizeof(motd) - len - 1, "<table>");
1197 len += format(motd[len], sizeof(motd) - len - 1, "<tr>");
1198 len += format(motd[len], sizeof(motd) - len - 1, "<th></th>");
1199 for( new CsTeams:i = CS_TEAM_T; i <= CS_TEAM_CT; i++ )
1200 {
1201 if( g_health_enabled[i] )
1202 {
1203 len += format(motd[len], sizeof(motd) - len - 1, "<th>%s</th>",g_team_names[i]);
1204 }
1205 }
1206 len += format(motd[len], sizeof(motd) - len - 1, "</tr>");
1207 len += format(motd[len], sizeof(motd) - len - 1, "<tr>");
1208 len += format(motd[len], sizeof(motd) - len - 1, "<th>Health Intervals</th>");
1209 for( new CsTeams:i = CS_TEAM_T; i <= CS_TEAM_CT; i++ )
1210 {
1211 if( g_health_enabled[i] )
1212 {
1213 len += format(motd[len], sizeof(motd) - len - 1, "<td>%i</td>", (g_health_maxamount[i] / g_health_maxlevels[i]));
1214 }
1215 }
1216 len += format(motd[len], sizeof(motd) - len - 1, "</tr>");
1217 len += format(motd[len], sizeof(motd) - len - 1, "<tr>");
1218 len += format(motd[len], sizeof(motd) - len - 1, "<th>Max Level</th>");
1219 for( new CsTeams:i = CS_TEAM_T; i <= CS_TEAM_CT; i++ )
1220 {
1221 if( g_health_enabled[i] )
1222 {
1223 len += format(motd[len], sizeof(motd) - len - 1, "<td>%i</td>", g_health_maxlevels[i]);
1224 }
1225 }
1226 len += format(motd[len], sizeof(motd) - len - 1, "</tr>");
1227 len += format(motd[len], sizeof(motd) - len - 1, "<th>Max Health</th>");
1228 for( new CsTeams:i = CS_TEAM_T; i <= CS_TEAM_CT; i++ )
1229 {
1230 if( g_health_enabled[i] )
1231 {
1232 len += format(motd[len], sizeof(motd) - len - 1, "<td>%i</td>", g_health_maxamount[i]);
1233 }
1234 }
1235 len += format(motd[len], sizeof(motd) - len - 1, "</tr>");
1236 len += format(motd[len], sizeof(motd) - len - 1, "</table>");
1237 len += format(motd[len], sizeof(motd) - len - 1, "</p>");
1238 len += format(motd[len], sizeof(motd) - len - 1, "</body>");
1239
1240 show_motd(client, motd, "XP Health Info");
1241 }
1242 else
1243 {
1244 new CsTeams:upgrade = CsTeams:str_to_num(info);
1245
1246 new level = g_health_level[client][upgrade] + 1;
1247 new xp = g_health_first_xp[upgrade] * (1 << (level - 1));
1248 new amount = g_health_maxamount[upgrade] * level / g_health_maxlevels[upgrade];
1249
1250 g_xp[client] -= xp;
1251 g_health_level[client][upgrade] = level;
1252
1253 Save(client);
1254
1255 Print(client, "You bought %s Level %i (%i HP) for %i XP!", g_health_names[upgrade], level, amount, xp);
1256 }
1257
1258 ShowHealthMenu(client);
1259}
1260
1261public CallbackHealth(client, menu, item)
1262{
1263 static _access, info[4], callback;
1264 menu_item_getinfo(menu, item, _access, info, sizeof(info) - 1, _, _, callback);
1265
1266 if( info[0] == '*' ) return ITEM_ENABLED;
1267
1268 new CsTeams:upgrade = CsTeams:str_to_num(info);
1269 if( g_health_level[client][upgrade] == g_health_maxlevels[upgrade] )
1270 {
1271 return ITEM_DISABLED;
1272 }
1273
1274 new xp = g_health_first_xp[upgrade] * (1 << g_health_level[client][upgrade]);
1275 if( g_xp[client] < xp )
1276 {
1277 return ITEM_DISABLED;
1278 }
1279
1280 return ITEM_ENABLED;
1281}
1282
1283ShowArmorMenu(client)
1284{
1285 static title[128];
1286 formatex(title, sizeof(title) - 1, "[HNS XP by Exolent]^nArmor Menu^n^nYour XP: \w%i", g_xp[client]);
1287 new menu = menu_create(title, "MenuArmor");
1288 new callback = menu_makecallback("CallbackArmor");
1289
1290 menu_additem(menu, "\yHelp", "*", _, callback);
1291
1292 static level, xp, amount, item[128], info[4];
1293 for( new CsTeams:i = CS_TEAM_T; i <= CS_TEAM_CT; i++ )
1294 {
1295 if( g_armor_enabled[i] )
1296 {
1297 level = g_armor_level[client][i] + 1;
1298 amount = g_armor_maxamount[i] * level / g_armor_maxlevels[i];
1299
1300 if( g_armor_level[client][i] < g_armor_maxlevels[i] )
1301 {
1302 xp = g_armor_first_xp[i] * (1 << (level - 1));
1303 formatex(item, sizeof(item) - 1, "%s: \yLevel %i (%i AP) \r[\w%i XP\r]", g_armor_names[i], level, amount, xp);
1304 }
1305 else
1306 {
1307 formatex(item, sizeof(item) - 1, "\w%s: \yLevel %i (%i AP) \r[\wMaxed Out!\r]", g_armor_names[i], level, amount);
1308 }
1309
1310 num_to_str(_:i, info, sizeof(info) - 1);
1311
1312 menu_additem(menu, item, info, _, callback);
1313 }
1314 }
1315
1316 menu_display(client, menu);
1317}
1318
1319public MenuArmor(client, menu, item)
1320{
1321 if( item == MENU_EXIT )
1322 {
1323 menu_destroy(menu);
1324 ShowMainMenu(client);
1325 return;
1326 }
1327
1328 static _access, info[4], callback;
1329 menu_item_getinfo(menu, item, _access, info, sizeof(info) - 1, _, _, callback);
1330 menu_destroy(menu);
1331
1332 if( info[0] == '*' )
1333 {
1334 static motd[2500];
1335 new len = formatex(motd, sizeof(motd) - 1, "<body style=^"background-color:#030303; color:#FF8F00^">");
1336 len += format(motd[len], sizeof(motd) - len - 1, "<p align=^"center^">");
1337 len += format(motd[len], sizeof(motd) - len - 1, "The Armor ability is the amount of AP that given to you at spawn.<br>");
1338 len += format(motd[len], sizeof(motd) - len - 1, "<br>");
1339 len += format(motd[len], sizeof(motd) - len - 1, "<table>");
1340 len += format(motd[len], sizeof(motd) - len - 1, "<tr>");
1341 len += format(motd[len], sizeof(motd) - len - 1, "<th></th>");
1342 for( new CsTeams:i = CS_TEAM_T; i <= CS_TEAM_CT; i++ )
1343 {
1344 if( g_armor_enabled[i] )
1345 {
1346 len += format(motd[len], sizeof(motd) - len - 1, "<th>%s</th>",g_team_names[i]);
1347 }
1348 }
1349 len += format(motd[len], sizeof(motd) - len - 1, "</tr>");
1350 len += format(motd[len], sizeof(motd) - len - 1, "<tr>");
1351 len += format(motd[len], sizeof(motd) - len - 1, "<th>Armor Intervals</th>");
1352 for( new CsTeams:i = CS_TEAM_T; i <= CS_TEAM_CT; i++ )
1353 {
1354 if( g_armor_enabled[i] )
1355 {
1356 len += format(motd[len], sizeof(motd) - len - 1, "<td>%i</td>", (g_armor_maxamount[i] / g_armor_maxlevels[i]));
1357 }
1358 }
1359 len += format(motd[len], sizeof(motd) - len - 1, "</tr>");
1360 len += format(motd[len], sizeof(motd) - len - 1, "<tr>");
1361 len += format(motd[len], sizeof(motd) - len - 1, "<th>Max Level</th>");
1362 for( new CsTeams:i = CS_TEAM_T; i <= CS_TEAM_CT; i++ )
1363 {
1364 if( g_armor_enabled[i] )
1365 {
1366 len += format(motd[len], sizeof(motd) - len - 1, "<td>%i</td>", g_armor_maxlevels[i]);
1367 }
1368 }
1369 len += format(motd[len], sizeof(motd) - len - 1, "</tr>");
1370 len += format(motd[len], sizeof(motd) - len - 1, "<th>Max Armor</th>");
1371 for( new CsTeams:i = CS_TEAM_T; i <= CS_TEAM_CT; i++ )
1372 {
1373 if( g_armor_enabled[i] )
1374 {
1375 len += format(motd[len], sizeof(motd) - len - 1, "<td>%i</td>", g_armor_maxamount[i]);
1376 }
1377 }
1378 len += format(motd[len], sizeof(motd) - len - 1, "</tr>");
1379 len += format(motd[len], sizeof(motd) - len - 1, "</table>");
1380 len += format(motd[len], sizeof(motd) - len - 1, "</p>");
1381 len += format(motd[len], sizeof(motd) - len - 1, "</body>");
1382
1383 show_motd(client, motd, "XP Armor Info");
1384 }
1385 else
1386 {
1387 new CsTeams:upgrade = CsTeams:str_to_num(info);
1388
1389 new level = g_armor_level[client][upgrade] + 1;
1390 new xp = g_armor_first_xp[upgrade] * (1 << (level - 1));
1391 new amount = g_armor_maxamount[upgrade] * level / g_armor_maxlevels[upgrade];
1392
1393 g_xp[client] -= xp;
1394 g_armor_level[client][upgrade] = level;
1395
1396 Save(client);
1397
1398 Print(client, "You bought %s Level %i (%i AP) for %i XP!", g_armor_names[upgrade], level, amount, xp);
1399 }
1400
1401 ShowArmorMenu(client);
1402}
1403
1404public CallbackArmor(client, menu, item)
1405{
1406 static _access, info[4], callback;
1407 menu_item_getinfo(menu, item, _access, info, sizeof(info) - 1, _, _, callback);
1408
1409 if( info[0] == '*' ) return ITEM_ENABLED;
1410
1411 new CsTeams:upgrade = CsTeams:str_to_num(info);
1412 if( g_armor_level[client][upgrade] == g_armor_maxlevels[upgrade] )
1413 {
1414 return ITEM_DISABLED;
1415 }
1416
1417 new xp = g_armor_first_xp[upgrade] * (1 << g_armor_level[client][upgrade]);
1418 if( g_xp[client] < xp )
1419 {
1420 return ITEM_DISABLED;
1421 }
1422
1423 return ITEM_ENABLED;
1424}
1425
1426ShowRespawnMenu(client)
1427{
1428 static title[128];
1429 formatex(title, sizeof(title) - 1, "[HNS XP by Exolent]^nRespawn Menu^n^nYour XP: \w%i", g_xp[client]);
1430 new menu = menu_create(title, "MenuRespawn");
1431 new callback = menu_makecallback("CallbackRespawn");
1432
1433 menu_additem(menu, "\yHelp", "*", _, callback);
1434
1435 static level, xp, percent, item[128], info[4];
1436 for( new CsTeams:i = CS_TEAM_T; i <= CS_TEAM_CT; i++ )
1437 {
1438 if( g_respawn_enabled[i] )
1439 {
1440 level = g_respawn_level[client][i] + 1;
1441 percent = g_respawn_max_chance[i] * level / g_respawn_maxlevels[i];
1442
1443 if( g_respawn_level[client][i] < g_respawn_maxlevels[i] )
1444 {
1445 xp = g_respawn_first_xp[i] * (1 << (level - 1));
1446 formatex(item, sizeof(item) - 1, "%s: \yLevel %i (%i%%) \r[\w%i XP\r]", g_respawn_names[i], level, percent, xp);
1447 }
1448 else
1449 {
1450 formatex(item, sizeof(item) - 1, "%s: \yLevel %i (%i%%) \r[\wMaxed Out!\r]", g_respawn_names[i], level, percent);
1451 }
1452
1453 num_to_str(_:i, info, sizeof(info) - 1);
1454
1455 menu_additem(menu, item, info, _, callback);
1456 }
1457 }
1458
1459 menu_display(client, menu);
1460}
1461
1462public MenuRespawn(client, menu, item)
1463{
1464 if( item == MENU_EXIT )
1465 {
1466 menu_destroy(menu);
1467 ShowMainMenu(client);
1468 return;
1469 }
1470
1471 static _access, info[4], callback;
1472 menu_item_getinfo(menu, item, _access, info, sizeof(info) - 1, _, _, callback);
1473 menu_destroy(menu);
1474
1475 if( info[0] == '*' )
1476 {
1477 static motd[2500];
1478 new len = formatex(motd, sizeof(motd) - 1, "<body style=^"background-color:#030303; color:#FF8F00^">");
1479 len += format(motd[len], sizeof(motd) - len - 1, "<p align=^"center^">");
1480 len += format(motd[len], sizeof(motd) - len - 1, "The Respawn ability is chance to be respawned when you die.<br>");
1481 len += format(motd[len], sizeof(motd) - len - 1, "<br>");
1482 len += format(motd[len], sizeof(motd) - len - 1, "<table>");
1483 len += format(motd[len], sizeof(motd) - len - 1, "<tr>");
1484 len += format(motd[len], sizeof(motd) - len - 1, "<th></th>");
1485 for( new CsTeams:i = CS_TEAM_T; i <= CS_TEAM_CT; i++ )
1486 {
1487 if( g_respawn_enabled[i] )
1488 {
1489 len += format(motd[len], sizeof(motd) - len - 1, "<th>%s</th>",g_team_names[i]);
1490 }
1491 }
1492 len += format(motd[len], sizeof(motd) - len - 1, "</tr>");
1493 len += format(motd[len], sizeof(motd) - len - 1, "<tr>");
1494 len += format(motd[len], sizeof(motd) - len - 1, "<th>Chance Intervals</th>");
1495 for( new CsTeams:i = CS_TEAM_T; i <= CS_TEAM_CT; i++ )
1496 {
1497 if( g_respawn_enabled[i] )
1498 {
1499 len += format(motd[len], sizeof(motd) - len - 1, "<td>%i%%</td>", (g_respawn_max_chance[i] / g_respawn_maxlevels[i]));
1500 }
1501 }
1502 len += format(motd[len], sizeof(motd) - len - 1, "</tr>");
1503 len += format(motd[len], sizeof(motd) - len - 1, "<tr>");
1504 len += format(motd[len], sizeof(motd) - len - 1, "<th>Max Level</th>");
1505 for( new CsTeams:i = CS_TEAM_T; i <= CS_TEAM_CT; i++ )
1506 {
1507 if( g_respawn_enabled[i] )
1508 {
1509 len += format(motd[len], sizeof(motd) - len - 1, "<td>%i</td>", g_respawn_maxlevels[i]);
1510 }
1511 }
1512 len += format(motd[len], sizeof(motd) - len - 1, "</tr>");
1513 len += format(motd[len], sizeof(motd) - len - 1, "<th>Max Chance</th>");
1514 for( new CsTeams:i = CS_TEAM_T; i <= CS_TEAM_CT; i++ )
1515 {
1516 if( g_respawn_enabled[i] )
1517 {
1518 len += format(motd[len], sizeof(motd) - len - 1, "<td>%i%%</td>", g_respawn_max_chance[i]);
1519 }
1520 }
1521 len += format(motd[len], sizeof(motd) - len - 1, "</tr>");
1522 len += format(motd[len], sizeof(motd) - len - 1, "</table>");
1523 len += format(motd[len], sizeof(motd) - len - 1, "</p>");
1524 len += format(motd[len], sizeof(motd) - len - 1, "</body>");
1525
1526 show_motd(client, motd, "XP Respawn Info");
1527 }
1528 else
1529 {
1530 new CsTeams:upgrade = CsTeams:str_to_num(info);
1531
1532 new level = g_respawn_level[client][upgrade] + 3;
1533 new xp = g_respawn_first_xp[upgrade] * (1 << (level - 1));
1534 new percent = g_respawn_max_chance[upgrade] * level / g_respawn_maxlevels[upgrade];
1535
1536 g_xp[client] -= xp;
1537 g_respawn_level[client][upgrade] = level;
1538
1539 Save(client);
1540
1541 Print(client, "You bought %s Level %i (%i%%) for %i XP!", g_respawn_names[upgrade], level, percent, xp);
1542 }
1543
1544 ShowRespawnMenu(client);
1545}
1546
1547public CallbackRespawn(client, menu, item)
1548{
1549 static _access, info[4], callback;
1550 menu_item_getinfo(menu, item, _access, info, sizeof(info) - 1, _, _, callback);
1551
1552 if( info[0] == '*' ) return ITEM_ENABLED;
1553
1554 new CsTeams:upgrade = CsTeams:str_to_num(info);
1555 if( g_respawn_level[client][upgrade] == g_respawn_maxlevels[upgrade] )
1556 {
1557 return ITEM_DISABLED;
1558 }
1559
1560 new xp = g_respawn_first_xp[upgrade] * (1 << g_respawn_level[client][upgrade]);
1561 if( g_xp[client] < xp || g_respawn_level[client][upgrade] == g_respawn_maxlevels[upgrade] )
1562 {
1563 return ITEM_DISABLED;
1564 }
1565
1566 return ITEM_ENABLED;
1567}
1568
1569ShowNoFallMenu(client)
1570{
1571 static title[128];
1572 formatex(title, sizeof(title) - 1, "[HNS XP by Exolent]^nFall Damage Menu^n^nYour XP: \w%i", g_xp[client]);
1573 new menu = menu_create(title, "MenuNoFall");
1574 new callback = menu_makecallback("CallbackNoFall");
1575
1576 menu_additem(menu, "\yHelp", "*", _, callback);
1577
1578 static level, xp, percent, item[128], info[4];
1579 for( new CsTeams:i = CS_TEAM_T; i <= CS_TEAM_CT; i++ )
1580 {
1581 if( g_nofall_enabled[i] )
1582 {
1583 level = g_nofall_level[client][i] + 1;
1584 percent = g_nofall_max_chance[i] * level / g_nofall_maxlevels[i];
1585
1586 if( g_nofall_level[client][i] < g_nofall_maxlevels[i] )
1587 {
1588 xp = g_nofall_first_xp[i] * (1 << (level - 1));
1589 formatex(item, sizeof(item) - 1, "%s: \yLevel %i (%i%%) \r[\w%i XP\r]", g_nofall_names[i], level, percent, xp);
1590 }
1591 else
1592 {
1593 formatex(item, sizeof(item) - 1, "%s: \yLevel %i (%i%%) \r[\wMaxed Out!\r]", g_nofall_names[i], level, percent);
1594 }
1595
1596 num_to_str(_:i, info, sizeof(info) - 1);
1597
1598 menu_additem(menu, item, info, _, callback);
1599 }
1600 }
1601
1602 menu_display(client, menu);
1603}
1604
1605public MenuNoFall(client, menu, item)
1606{
1607 if( item == MENU_EXIT )
1608 {
1609 menu_destroy(menu);
1610 ShowMainMenu(client);
1611 return;
1612 }
1613
1614 static _access, info[4], callback;
1615 menu_item_getinfo(menu, item, _access, info, sizeof(info) - 1, _, _, callback);
1616 menu_destroy(menu);
1617
1618 if( info[0] == '*' )
1619 {
1620 static motd[2500];
1621 new len = formatex(motd, sizeof(motd) - 1, "<body style=^"background-color:#030303; color:#FF8F00^">");
1622 len += format(motd[len], sizeof(motd) - len - 1, "<p align=^"center^">");
1623 len += format(motd[len], sizeof(motd) - len - 1, "The Fall Damage ability reduces the amount of damage inflicted from falling.<br>");
1624 len += format(motd[len], sizeof(motd) - len - 1, "<br>");
1625 len += format(motd[len], sizeof(motd) - len - 1, "<table>");
1626 len += format(motd[len], sizeof(motd) - len - 1, "<tr>");
1627 len += format(motd[len], sizeof(motd) - len - 1, "<th></th>");
1628 for( new CsTeams:i = CS_TEAM_T; i <= CS_TEAM_CT; i++ )
1629 {
1630 if( g_nofall_enabled[i] )
1631 {
1632 len += format(motd[len], sizeof(motd) - len - 1, "<th>%s</th>",g_team_names[i]);
1633 }
1634 }
1635 len += format(motd[len], sizeof(motd) - len - 1, "</tr>");
1636 len += format(motd[len], sizeof(motd) - len - 1, "<tr>");
1637 len += format(motd[len], sizeof(motd) - len - 1, "<th>Reduction Intervals</th>");
1638 for( new CsTeams:i = CS_TEAM_T; i <= CS_TEAM_CT; i++ )
1639 {
1640 if( g_nofall_enabled[i] )
1641 {
1642 len += format(motd[len], sizeof(motd) - len - 1, "<td>%i%%</td>", (g_nofall_max_chance[i] / g_nofall_maxlevels[i]));
1643 }
1644 }
1645 len += format(motd[len], sizeof(motd) - len - 1, "</tr>");
1646 len += format(motd[len], sizeof(motd) - len - 1, "<tr>");
1647 len += format(motd[len], sizeof(motd) - len - 1, "<th>Max Level</th>");
1648 for( new CsTeams:i = CS_TEAM_T; i <= CS_TEAM_CT; i++ )
1649 {
1650 if( g_nofall_enabled[i] )
1651 {
1652 len += format(motd[len], sizeof(motd) - len - 1, "<td>%i</td>", g_nofall_maxlevels[i]);
1653 }
1654 }
1655 len += format(motd[len], sizeof(motd) - len - 1, "</tr>");
1656 len += format(motd[len], sizeof(motd) - len - 1, "<th>Max Chance</th>");
1657 for( new CsTeams:i = CS_TEAM_T; i <= CS_TEAM_CT; i++ )
1658 {
1659 if( g_nofall_enabled[i] )
1660 {
1661 len += format(motd[len], sizeof(motd) - len - 1, "<td>%i%%</td>", g_nofall_max_chance[i]);
1662 }
1663 }
1664 len += format(motd[len], sizeof(motd) - len - 1, "</tr>");
1665 len += format(motd[len], sizeof(motd) - len - 1, "</table>");
1666 len += format(motd[len], sizeof(motd) - len - 1, "</p>");
1667 len += format(motd[len], sizeof(motd) - len - 1, "</body>");
1668
1669 show_motd(client, motd, "XP Fall Damage Info");
1670 }
1671 else
1672 {
1673 new CsTeams:upgrade = CsTeams:str_to_num(info);
1674
1675 new level = g_nofall_level[client][upgrade] + 1;
1676 new xp = g_nofall_first_xp[upgrade] * (1 << (level - 1));
1677 new percent = g_nofall_max_chance[upgrade] * level / g_nofall_maxlevels[upgrade];
1678
1679 g_xp[client] -= xp;
1680 g_nofall_level[client][upgrade] = level;
1681
1682 Save(client);
1683
1684 Print(client, "You bought %s Level %i (%i%%) for %i XP!", g_nofall_names[upgrade], level, percent, xp);
1685 }
1686
1687 ShowNoFallMenu(client);
1688}
1689
1690public CallbackNoFall(client, menu, item)
1691{
1692 static _access, info[4], callback;
1693 menu_item_getinfo(menu, item, _access, info, sizeof(info) - 1, _, _, callback);
1694
1695 if( info[0] == '*' ) return ITEM_ENABLED;
1696
1697 new CsTeams:upgrade = CsTeams:str_to_num(info);
1698 if( g_nofall_level[client][upgrade] == g_nofall_maxlevels[upgrade] )
1699 {
1700 return ITEM_DISABLED;
1701 }
1702
1703 new xp = g_nofall_first_xp[upgrade] * (1 << g_nofall_level[client][upgrade]);
1704 if( g_xp[client] < xp || g_nofall_level[client][upgrade] == g_nofall_maxlevels[upgrade] )
1705 {
1706 return ITEM_DISABLED;
1707 }
1708
1709 return ITEM_ENABLED;
1710}
1711
1712ShowPlayerMenu(client)
1713{
1714 new menu = menu_create("Player Info Menu", "MenuPlayer");
1715
1716 new name[32], authid[35];
1717 for( new i = 1; i <= g_max_clients; i++ )
1718 {
1719 if( !is_user_connected(i) ) continue;
1720
1721 get_user_name(i, name, sizeof(name) - 1);
1722 get_user_authid(i, authid, sizeof(authid) - 1);
1723
1724 menu_additem(menu, name, authid);
1725 }
1726
1727 menu_display(client, menu);
1728}
1729
1730public MenuPlayer(client, menu, item)
1731{
1732 if( item == MENU_EXIT )
1733 {
1734 menu_destroy(menu);
1735 ShowMainMenu(client);
1736 return;
1737 }
1738
1739 static _access, authid[35], callback;
1740 menu_item_getinfo(menu, item, _access, authid, sizeof(authid) - 1, _, _, callback);
1741 menu_destroy(menu);
1742
1743 new player = find_player("c", authid);
1744 if( !is_user_connected(player) )
1745 {
1746 ShowMainMenu(client);
1747 return;
1748 }
1749
1750 new name[32];
1751 get_user_name(player, name, sizeof(name) - 1);
1752
1753 static motd[2500];
1754 new len = copy(motd, sizeof(motd) - 1, "<html>");
1755 len += format(motd[len], sizeof(motd) - len - 1, "<b><font size=^"4^">Name:</font></b> %s<br><br>", name);
1756 len += format(motd[len], sizeof(motd) - len - 1, "<b><font size=^"4^">XP:</font></b> %i<br><br>", g_xp[player]);
1757 if( g_any_nade_enabled )
1758 {
1759 len += format(motd[len], sizeof(motd) - len - 1, "<b><font size=^"4^">Grenades Levels:</font></b><br>");
1760 for( new i = 0; i < Grenades; i++ )
1761 {
1762 if( g_nade_enabled[i] )
1763 {
1764 len += format(motd[len], sizeof(motd) - len - 1, "<b>%s:</b> %i/%i<br>", g_nade_names[i], g_nade_level[player][i], g_nade_maxlevels[i]);
1765 }
1766 }
1767 }
1768 if( g_any_health_enabled )
1769 {
1770 len += format(motd[len], sizeof(motd) - len - 1, "<br><b><font size=^"4^">Health Levels:</font></b><br>");
1771 for( new CsTeams:i = CS_TEAM_T; i <= CS_TEAM_CT; i++ )
1772 {
1773 if( g_health_enabled[i] )
1774 {
1775 len += format(motd[len], sizeof(motd) - len - 1, "<b>%s:</b> %i/%i (%i/%i HP)<br>",\
1776 g_health_names[i], g_health_level[player][i], g_health_maxlevels[i],\
1777 (g_health_maxamount[i] * g_health_level[player][i] / g_health_maxlevels[i]), g_health_maxamount[i]);
1778 }
1779 }
1780 }
1781 if( g_any_armor_enabled )
1782 {
1783 len += format(motd[len], sizeof(motd) - len - 1, "<br><b><font size=^"4^">Armor Levels:</font></b><br>");
1784 for( new CsTeams:i = CS_TEAM_T; i <= CS_TEAM_CT; i++ )
1785 {
1786 if( g_armor_enabled[i] )
1787 {
1788 len += format(motd[len], sizeof(motd) - len - 1, "<b>%s:</b> %i/%i (%i/%i AP)<br>",\
1789 g_armor_names[i], g_armor_level[player][i], g_armor_maxlevels[i],\
1790 (g_armor_maxamount[i] * g_armor_level[player][i] / g_armor_maxlevels[i]), g_armor_maxamount[i]);
1791 }
1792 }
1793 }
1794 if( g_any_respawn_enabled )
1795 {
1796 len += format(motd[len], sizeof(motd) - len - 1, "<br><b><font size=^"4^">Respawn Levels:</font></b><br>");
1797 for( new CsTeams:i = CS_TEAM_T; i <= CS_TEAM_CT; i++ )
1798 {
1799 if( g_respawn_enabled[i] )
1800 {
1801 len += format(motd[len], sizeof(motd) - len - 1, "<b>%s:</b> %i/%i (%i/%i %%)<br>",\
1802 g_respawn_names[i], g_respawn_level[player][i], g_respawn_maxlevels[i],\
1803 (g_respawn_max_chance[i] * g_respawn_level[player][i] / g_respawn_maxlevels[i]), g_respawn_max_chance[i]);
1804 }
1805 }
1806 }
1807 if( g_any_nofall_enabled )
1808 {
1809 len += format(motd[len], sizeof(motd) - len - 1, "<br><b><font size=^"4^">Fall Damage Levels:</font></b><br>");
1810 for( new CsTeams:i = CS_TEAM_T; i <= CS_TEAM_CT; i++ )
1811 {
1812 if( g_nofall_enabled[i] )
1813 {
1814 len += format(motd[len], sizeof(motd) - len - 1, "<b>%s:</b> %i/%i (%i/%i %%)<br>",\
1815 g_nofall_names[i], g_nofall_level[player][i], g_nofall_maxlevels[i],\
1816 (g_nofall_max_chance[i] * g_nofall_level[player][i] / g_nofall_maxlevels[i]), g_nofall_max_chance[i]);
1817 }
1818 }
1819 }
1820 len += format(motd[len], sizeof(motd) - len - 1, "</html>");
1821
1822 show_motd(client, motd, "HNS XP Mod Info");
1823
1824 ShowPlayerMenu(client);
1825}
1826
1827IsValidAuthid(authid[])
1828{
1829 return (regex_match_c(authid, g_SteamID_pattern, g_regex_return) > 0);
1830}
1831
1832IsUserAuthorized(client)
1833{
1834 return g_authid[client][0] != 0;
1835}
1836
1837Print(client, const msg_fmt[], any:...)
1838{
1839 static message[192];
1840 new len = formatex(message, sizeof(message) - 1, "%s^x03 ", MESSAGE_TAG);
1841 vformat(message[len], sizeof(message) - len - 1, msg_fmt, 3);
1842
1843 if( client )
1844 {
1845 message_begin(MSG_ONE_UNRELIABLE, g_msgid_SayText, _, client);
1846 write_byte(client);
1847 write_string(message);
1848 message_end();
1849 }
1850 else
1851 {
1852 for( new i = g_first_client; i <= g_max_clients; i++ )
1853 {
1854 if( is_user_connected(i) )
1855 {
1856 message_begin(MSG_ONE_UNRELIABLE, g_msgid_SayText, _, i);
1857 write_byte(i);
1858 write_string(message);
1859 message_end();
1860 }
1861 }
1862 }
1863}
1864
1865Load(client)
1866{
1867 #if defined USING_SQL
1868 static query[128];
1869 formatex(query, sizeof(query) - 1, "SELECT `data` FROM `hns_xp` WHERE `authid` = '%s';", g_authid[client]);
1870
1871 static data[2];
1872 data[0] = client;
1873
1874 SQL_ThreadQuery(g_sql_tuple, "QueryLoadData", query, data, sizeof(data));
1875 #else
1876 static data[256], timestamp;
1877 if( nvault_lookup(g_vault, g_authid[client], data, sizeof(data) - 1, timestamp) )
1878 {
1879 ParseLoadData(client, data);
1880 return;
1881 }
1882 else
1883 {
1884 NewUser(client);
1885 }
1886 #endif
1887}
1888
1889#if defined USING_SQL
1890public QueryLoadData(failstate, Handle:query, error[], errnum, data[], size, Float:queuetime)
1891{
1892 if( failstate == TQUERY_CONNECT_FAILED
1893 || failstate == TQUERY_QUERY_FAILED )
1894 {
1895 set_fail_state(error);
1896 }
1897 else
1898 {
1899 if( SQL_NumResults(query) )
1900 {
1901 static sqldata[256];
1902 SQL_ReadResult(query, 0, sqldata, sizeof(sqldata) - 1);
1903 ParseLoadData(data[0], sqldata);
1904 }
1905 else
1906 {
1907 NewUser(data[0]);
1908 }
1909 }
1910}
1911#endif
1912
1913ParseLoadData(client, data[256])
1914{
1915 static num[6];
1916 strbreak(data, num, sizeof(num) - 1, data, sizeof(data) - 1);
1917
1918 g_xp[client] = str_to_num(num);
1919
1920 for( new i = 0; i < Grenades; i++ )
1921 {
1922 strbreak(data, num, sizeof(num) - 1, data, sizeof(data) - 1);
1923 g_nade_level[client][i] = clamp(str_to_num(num), 0, g_nade_maxlevels[i]);
1924 }
1925
1926 for( new CsTeams:i = CS_TEAM_T; i <= CS_TEAM_CT; i++ )
1927 {
1928 strbreak(data, num, sizeof(num) - 1, data, sizeof(data) - 1);
1929 g_armor_level[client][i] = clamp(str_to_num(num), 0, g_armor_maxlevels[i]);
1930 }
1931
1932 for( new CsTeams:i = CS_TEAM_T; i <= CS_TEAM_CT; i++ )
1933 {
1934 strbreak(data, num, sizeof(num) - 1, data, sizeof(data) - 1);
1935 g_respawn_level[client][i] = clamp(str_to_num(num), 0, g_respawn_maxlevels[i]);
1936 }
1937
1938 for( new CsTeams:i = CS_TEAM_T; i <= CS_TEAM_CT; i++ )
1939 {
1940 strbreak(data, num, sizeof(num) - 1, data, sizeof(data) - 1);
1941 g_health_level[client][i] = clamp(str_to_num(num), 0, g_health_maxlevels[i]);
1942 }
1943
1944 for( new CsTeams:i = CS_TEAM_T; i <= CS_TEAM_CT; i++ )
1945 {
1946 strbreak(data, num, sizeof(num) - 1, data, sizeof(data) - 1);
1947 g_nofall_level[client][i] = clamp(str_to_num(num), 0, g_nofall_maxlevels[i]);
1948 }
1949
1950 #if defined USING_SQL
1951 g_loaded_data[client] = 1;
1952 #endif
1953}
1954
1955NewUser(client)
1956{
1957 g_first_time[client] = 1;
1958
1959 g_xp[client] = ENTRY_XP;
1960 arrayset(g_nade_level[client], 0, sizeof(g_nade_level[]));
1961 for( new CsTeams:i = CS_TEAM_T; i <= CS_TEAM_CT; i++ )
1962 {
1963 g_armor_level[client][i] = 0;
1964 g_respawn_level[client][i] = 0;
1965 g_health_level[client][i] = 0;
1966 g_nofall_level[client][i] = 0;
1967 }
1968}
1969
1970Save(client)
1971{
1972 if( !IsUserAuthorized(client) ) return;
1973
1974 static data[256];
1975 new len = formatex(data, sizeof(data) - 1, "%i", g_xp[client]);
1976
1977 for( new i = 0; i < Grenades; i++ )
1978 {
1979 len += formatex(data[len], sizeof(data) - len - 1, " %i", g_nade_level[client][i]);
1980 }
1981
1982 for( new CsTeams:i = CS_TEAM_T; i <= CS_TEAM_CT; i++ )
1983 {
1984 len += formatex(data[len], sizeof(data) - len - 1, " %i", g_armor_level[client][i]);
1985 }
1986
1987 for( new CsTeams:i = CS_TEAM_T; i <= CS_TEAM_CT; i++ )
1988 {
1989 len += formatex(data[len], sizeof(data) - len - 1, " %i", g_respawn_level[client][i]);
1990 }
1991
1992 for( new CsTeams:i = CS_TEAM_T; i <= CS_TEAM_CT; i++ )
1993 {
1994 len += formatex(data[len], sizeof(data) - len - 1, " %i", g_health_level[client][i]);
1995 }
1996
1997 for( new CsTeams:i = CS_TEAM_T; i <= CS_TEAM_CT; i++ )
1998 {
1999 len += formatex(data[len], sizeof(data) - len - 1, " %i", g_nofall_level[client][i]);
2000 }
2001
2002 #if defined USING_SQL
2003 static name[32];
2004 get_user_name(client, name, sizeof(name) - 1);
2005
2006 static query[512];
2007 if( g_loaded_data[client] )
2008 {
2009 formatex(query, sizeof(query) - 1, "UPDATE `hns_xp` SET `name` = '%s', `data` = '%s' WHERE `authid` = '%s';", name, data, g_authid[client]);
2010 }
2011 else
2012 {
2013 formatex(query, sizeof(query) - 1, "INSERT INTO `hns_xp` ( `name`, `authid`, `data` ) VALUES ( '%s', '%s', '%s' );", name, g_authid[client], data);
2014 }
2015
2016 SQL_ThreadQuery(g_sql_tuple, "QuerySaveData", query);
2017 #else
2018 nvault_set(g_vault, g_authid[client], data);
2019 #endif
2020}
2021
2022#if defined USING_SQL
2023public QuerySaveData(failstate, Handle:query, error[], errnum, data[], size, Float:queuetime)
2024{
2025 if( failstate == TQUERY_CONNECT_FAILED
2026 || failstate == TQUERY_QUERY_FAILED )
2027 {
2028 set_fail_state(error);
2029 }
2030}
2031#endif