· 7 years ago · Jan 06, 2019, 05:04 PM
1#include <sourcemod>
2#include <console>
3#include <clients>
4#include <events>
5#include <cstrike>
6#include <sdktools>
7
8#define MAX_CLASS_NUMBER 50
9#define MAX_ITEM_NUMBER 100
10#define MAX_NAME_LONG 30
11#define MAX_DESCRIPTION_LONG 64
12#define MAX_WEAPONS_ARRAY_SIZE 10
13#define MAX_WEAPONS_NAME_LONG 64
14#define MAX_STATS_DESCRIPTION_LONG 64
15#define PLAYER_BASE_HP 100
16#define DB_ERROR_BUFFER_SIZE 512
17
18#define MOD_TAG "[Cmod]"
19
20new Handle:expKill,
21 Handle:maxLvl,
22 Handle:lvlRatio;
23
24new Handle:sql;
25new String:dbError[DB_ERROR_BUFFER_SIZE+1]
26
27new classNum,
28 itemNum;
29
30new String:className[MAX_CLASS_NUMBER+1][MAX_NAME_LONG+1],
31 String:classDescription[MAX_CLASS_NUMBER+1][MAX_DESCRIPTION_LONG+1];
32
33new minItemValue[MAX_ITEM_NUMBER+1],
34 maxItemValue[MAX_ITEM_NUMBER+1];
35
36new Handle:classPlugin[MAX_CLASS_NUMBER+1] = INVALID_HANDLE,
37 Handle:itemPlugin[MAX_ITEM_NUMBER+1] = INVALID_HANDLE;
38
39new classInt[MAX_CLASS_NUMBER+1],
40 classCon[MAX_CLASS_NUMBER+1],
41 classStr[MAX_CLASS_NUMBER+1],
42 classDex[MAX_CLASS_NUMBER+1],
43 String:classWeapons[MAX_CLASS_NUMBER+1][MAX_WEAPONS_ARRAY_SIZE+1][MAX_WEAPONS_NAME_LONG+1],
44 classWeaponsNumber[MAX_CLASS_NUMBER+1];
45
46new bonusInt[MAXPLAYERS+1],
47 bonusCon[MAXPLAYERS+1],
48 bonusStr[MAXPLAYERS+1],
49 bonusDex[MAXPLAYERS+1],
50 bonusExp[MAXPLAYERS+1],
51 String:bonusWeapons[MAXPLAYERS+1][MAX_WEAPONS_ARRAY_SIZE+1][MAX_WEAPONS_NAME_LONG+1],
52 bonusWeaponsNumber[MAXPLAYERS+1];
53
54new String:itemName[MAX_ITEM_NUMBER+1][MAX_NAME_LONG+1],
55 String:itemDescription[MAX_ITEM_NUMBER+1][MAX_DESCRIPTION_LONG+1];
56
57new playerClass[MAXPLAYERS+1],
58 playerNewClass[MAXPLAYERS+1],
59 playerLvl[MAXPLAYERS+1],
60 playerExp[MAXPLAYERS+1],
61 playerItem[MAXPLAYERS+1],
62 playerItemValue[MAXPLAYERS+1],
63 playerPoints[MAXPLAYERS+1],
64 playerInt[MAXPLAYERS+1],
65 playerCon[MAXPLAYERS+1],
66 playerStr[MAXPLAYERS+1],
67 playerDex[MAXPLAYERS+1],
68 Float:playerSpeed[MAXPLAYERS+1];
69
70
71new const allowWeaponNumber = 3;
72new const String:allowWeapon[][] = {
73 "weapon_knife",
74 "weapon_c4",
75 "item_defuser"
76};
77
78public OnPluginStart()
79{
80 RegConsoleCmd("sm_klasa", cmdClassSelect);
81 RegConsoleCmd("sm_class", cmdClassSelect);
82
83 RegConsoleCmd("sm_klasy", cmdClassList);
84 RegConsoleCmd("sm_classinfo", cmdClassList);
85
86 RegConsoleCmd("sm_statystyki", cmdShowStats);
87 RegConsoleCmd("sm_staty", cmdShowStats);
88 RegConsoleCmd("sm_stats", cmdShowStats);
89
90 RegConsoleCmd("sm_item", cmdShowItemDesc);
91 RegConsoleCmd("sm_perk", cmdShowItemDesc);
92
93 RegConsoleCmd("sm_drop", cmdDrop);
94 RegConsoleCmd("sm_wyrzuc", cmdDrop);
95
96 RegConsoleCmd("sm_reset", cmdReset);
97
98 RegConsoleCmd("sm_useitem", cmdUseItem);
99 RegConsoleCmd("sm_useskill", cmdUseSkill);
100
101 HookEvent("player_death", eventPlayerDeath);
102 HookEvent("player_spawn", eventPlayerSpawn);
103 HookEvent("item_equip", eventItemEquip);
104
105 expKill = CreateConVar("cmod_expkill", "10", "Kill exp");
106 maxLvl = CreateConVar("cmod_maxlvl", "200", "Max lvl");
107 lvlRatio = CreateConVar("cmod_lvlratio", "35", "exp for 1st lvl");
108
109 AutoExecConfig(true, "cmod");
110
111 strcopy(className[0], MAX_NAME_LONG, "Brak");
112 strcopy(classDescription[0], MAX_DESCRIPTION_LONG, "Brak");
113 strcopy(itemName[0], MAX_NAME_LONG, "Brak");
114 strcopy(itemDescription[0], MAX_DESCRIPTION_LONG, "Brak");
115 classWeaponsNumber[0] = 3;
116 classWeapons[0][0] = "weapon_glock";
117 classWeapons[0][1] = "weapon_hkp2000";
118 classWeapons[0][2] = "weapon_knife";
119
120 CreateTimer(0.1, showHUD, _, TIMER_REPEAT);
121 //start (found in internet)
122 if(GetUserMessageType() == UM_Protobuf)
123 {
124 HookUserMessage(GetUserMessageId("TextMsg"), TextMsg, true);
125 }
126 //stop
127
128 sql = SQLite_UseDatabase("codmod_lvl", dbError, DB_ERROR_BUFFER_SIZE);
129 if(sql == INVALID_HANDLE)
130 PrintToServer("Could not connect: %s", dbError);
131
132 SQL_FastQuery(sql, "CREATE VIRTUAL TABLE IF NOT EXISTS codmod_info USING fts4(steamid, class);");
133
134 SQL_FastQuery(sql, "CREATE TABLE IF NOT EXISTS codmod (id INTEGER primary key autoincrement, steamid TEXT references codmod_info(steamid), class TEXT references codmod_info(class), lvl INTEGER, exp INTEGER, sPoints INTEGER, sInt INTEGER, sCon INTEGER, sStr INTEGER, sDex INTEGER, UNIQUE(steamid, class) ON CONFLICT REPLACE);");
135
136}
137
138public OnClientDisconnect(id)
139{
140 if(IsClientInGame(id))
141 saveToDB(id);
142}
143
144//start (found in internet)
145public Action:TextMsg(UserMsg:msg_id, Handle:pb, players[], playersNum, bool:reliable, bool:init)
146{
147 if(!reliable || PbReadInt(pb, "msg_dst") != 3)
148 {
149 return Plugin_Continue;
150 }
151
152 new String:buffer[256];
153 PbReadString(pb, "params", buffer, sizeof(buffer), 0);
154
155 if(StrContains(buffer, "#Player_Cash_Award_") == 0 || StrContains(buffer, "#Team_Cash_Award_") == 0)
156 {
157 return Plugin_Handled;
158 }
159
160 return Plugin_Continue;
161}
162//stop
163
164public OnClientConnected(id)
165{
166 playerClass[id] = 0;
167 playerNewClass[id] = 0;
168 playerLvl[id] = 1;
169 playerExp[id] = 0;
170 playerItem[id] = 0;
171 playerPoints[id] = 0;
172 playerInt[id] = 0;
173 playerCon[id] = 0;
174 playerStr[id] = 0;
175 playerDex[id] = 0;
176}
177
178
179
180public classSelectHandler(Handle:menu, MenuAction:action, param1, param2)
181{
182 if (action == MenuAction_Select){
183 decl String:info[32];
184 GetMenuItem(menu, param2, info, sizeof(info));
185 playerNewClass[param1] = param2 + 1;
186
187 if(!playerClass[param1]){
188 setNewClass(param1);
189 return;
190 }
191 PrintToChat(param1, "\x01\x0B\x01 \x07%s \x06Klasa zostanie zmieniona w następnej rundzie.", MOD_TAG);
192 }else if (action == MenuAction_End){
193 CloseHandle(menu);
194 }
195}
196
197public classSelect(id)
198{
199 if(!classNum){
200 PrintToChat(id, "\x01\x0B\x01 \x07%s \x06Nie znaleziono żadnej klasy!", MOD_TAG, playerLvl[id]);
201 }
202
203 new String:name[MAX_NAME_LONG+32];
204 new Handle:menu = CreateMenu(classSelectHandler);
205 SetMenuTitle(menu, "Wybierz klase:");
206
207 for(new i = 1; i <= classNum; i++){
208 Format(name, sizeof(name), "%s (LVL: %d)", className[i], readLvlClassFromDB(id, i));
209 AddMenuItem(menu, className[i], name);
210 }
211
212 DisplayMenu(menu, id, MENU_TIME_FOREVER);
213}
214
215
216public classDescHandler(Handle:menu, MenuAction:action, param1, param2)
217{
218 if(action == MenuAction_End){
219 CloseHandle(menu);
220 }
221}
222
223public classDesc(id, classID)
224{
225 if(!classNum){
226 PrintToChat(id, "\x01\x0B\x01 \x07%s \x06Nie znaleziono żadnej klasy!", MOD_TAG, playerLvl[id]);
227 }
228
229 new String:weapons[200] = "Bronie:\n";
230 new String:stats[80];
231 new String:name[MAX_NAME_LONG+9];
232 new String:desc[MAX_DESCRIPTION_LONG+8];
233
234 Format(name, sizeof(name), "Klasa:\n%s", className[classID]);
235 Format(desc, sizeof(desc), "Opis: \n%s", classDescription[classID]);
236 Format(stats, sizeof(stats), "Staty:\nINT: %d\nCON: %d\nSTR: %d\nDEX: %d", classInt[classID], classCon[classID], classStr[classID], classDex[classID]);
237
238 for(new i; i < classWeaponsNumber[classID]; i++){
239 StrCat(weapons, sizeof(weapons), classWeapons[classID][i]);
240 StrCat(weapons, sizeof(weapons), "\n");
241 }
242
243 new Handle:menu = CreateMenu(classDescHandler) ;
244
245 AddMenuItem(menu, "nazwa", name);
246 AddMenuItem(menu, "opis", desc);
247 AddMenuItem(menu, "int", stats);
248 AddMenuItem(menu, "bronie", weapons);
249
250
251 DisplayMenu(menu, id, MENU_TIME_FOREVER);
252}
253
254public classListHandler(Handle:menu, MenuAction:action, param1, param2)
255{
256 if (action == MenuAction_Select){
257 classDesc(param1, param2 + 1);
258
259 }else if (action == MenuAction_End){
260 CloseHandle(menu);
261 }
262}
263
264public classList(id)
265{
266 if(!classNum){
267 PrintToChat(id, "\x01\x0B\x01 \x07%s \x06Nie znaleziono żadnej klasy!", MOD_TAG, playerLvl[id]);
268 }
269
270 new Handle:menu = CreateMenu(classListHandler);
271 SetMenuTitle(menu, "Wybierz klase:");
272
273 for(new i = 1; i <= classNum; i++){
274 AddMenuItem(menu, className[i], className[i]);
275 }
276
277 DisplayMenu(menu, id, MENU_TIME_FOREVER);
278}
279
280public Action:cmdClassList(id, args)
281{
282 classList(id);
283 return Plugin_Handled;
284}
285//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA <- THER I END \/
286public nativeGetInt(Handle:plugin, numParams)
287{
288 return getInt(GetNativeCell(1), GetNativeCell(2), GetNativeCell(3), GetNativeCell(4));
289}
290
291public nativeGetCon(Handle:plugin, numParams)
292{
293 return getCon(GetNativeCell(1), GetNativeCell(2), GetNativeCell(3), GetNativeCell(4));
294}
295
296public nativeGetStr(Handle:plugin, numParams)
297{
298 return getStr(GetNativeCell(1), GetNativeCell(2), GetNativeCell(3), GetNativeCell(4));
299}
300
301public nativeGetDex(Handle:plugin, numParams)
302{
303 return getDex(GetNativeCell(1), GetNativeCell(2), GetNativeCell(3), GetNativeCell(4));
304}
305
306public nativeGetBonusExp(Handle:plugin, numParams)
307{
308 return bonusExp[GetNativeCell(1)]
309}
310
311public nativeGetCNameByCId(Handle:plugin, numParams)
312{
313 new tmp = GetNativeCell(1);
314 if(tmp <= classNum && tmp >= 0){
315 SetNativeString(2, className[tmp], GetNativeCell(3));
316 return 1;
317 }else{
318 return 0;
319 }
320}
321
322public nativeGetCIdByCName(Handle:plugin, numParams)
323{
324 decl String:tmp[MAX_NAME_LONG+1];
325 GetNativeString(1, tmp, sizeof(tmp));
326 for(new i; i <= classNum; i++){
327 if(StrEqual(tmp, className[i])){
328 return i;
329 }
330 }
331 return -1;
332}
333
334public nativeGetINameByIId(Handle:plugin, numParams)
335{
336 new tmp = GetNativeCell(1);
337 if(tmp <= itemNum && tmp >= 0){
338 SetNativeString(2, itemName[tmp], GetNativeCell(3));
339 return 1;
340 }else{
341 return 0;
342 }
343}
344
345public nativeGetIIdByIName(Handle:plugin, numParams)
346{
347 decl String:tmp[MAX_NAME_LONG+1];
348 GetNativeString(1, tmp, sizeof(tmp));
349 for(new i; i <= itemNum; i++){
350 if(StrEqual(tmp, itemName[i])){
351 return i;
352 }
353 }
354 return -1;
355}
356
357public nativeGetPlayerClass(Handle:plugin, numParams)
358{
359 new tmp = GetNativeCell(1);
360 if(IsValidClient(tmp)){
361 return playerClass[tmp];
362 }else{
363 return -1;
364 }
365}
366
367public nativeGetPlayerItem(Handle:plugin, numParams)
368{
369 new tmp = GetNativeCell(1);
370 if(IsValidClient(tmp)){
371 return playerItem[tmp];
372 }else{
373 return -1;
374 }
375}
376
377public nativeGetPlayerItemValue(Handle:plugin, numParams)
378{
379 new tmp = GetNativeCell(1);
380 if(IsValidClient(tmp)){
381 return playerItemValue[tmp];
382 }else{
383 return 0;
384 }
385}
386
387public nativeGetPlayerLvl(Handle:plugin, numParams)
388{
389 new tmp = GetNativeCell(1);
390 if(IsValidClient(tmp)){
391 return playerLvl[tmp];
392 }else{
393 return 0;
394 }
395}
396
397public nativeGetPlayerExp(Handle:plugin, numParams)
398{
399 new tmp = GetNativeCell(1);
400 if(IsValidClient(tmp)){
401 return playerExp[tmp];
402 }else{
403 return 0;
404 }
405}
406
407public nativeGetClassNum(Handle:plugin, numParams)
408{
409 return classNum;
410}
411
412public nativeGetItemNum(Handle:plugin, numParams)
413{
414 return itemNum;
415}
416
417public nativeSetPlayerItem(Handle:plugin, numParams)
418{
419 new id = GetNativeCell(1);
420 if(IsValidClient(id))
421 return 1;
422
423 new tmp = GetNativeCell(2);
424 if(!(tmp <= itemNum && tmp >= 0))
425 return 2;
426
427 removeItem(id);
428 setPlayerItem(id, tmp);
429
430 return 0;
431}
432
433public nativeSetBonusInt(Handle:plugin, numParams)
434{
435 bonusInt[GetNativeCell(1)] = GetNativeCell(2);
436}
437
438public nativeSetBonusCon(Handle:plugin, numParams)
439{
440 bonusCon[GetNativeCell(1)] = GetNativeCell(2);
441}
442
443public nativeSetBonusStr(Handle:plugin, numParams)
444{
445 bonusStr[GetNativeCell(1)] = GetNativeCell(2);
446}
447
448public nativeSetBonusDex(Handle:plugin, numParams)
449{
450 bonusDex[GetNativeCell(1)] = GetNativeCell(2);
451}
452
453public nativeSetBonusExp(Handle:plugin, numParams)
454{
455 bonusExp[GetNativeCell(1)] = GetNativeCell(2);
456}
457
458public nativeGiveExp(Handle:plugin, numParams)
459{
460 new tmp = GetNativeCell(1);
461 if(!IsValidClient(tmp))
462 return 0;
463 playerExp[tmp] += GetNativeCell(2);
464 checkLvl(tmp);
465 return 1;
466}
467
468getInt(id, bool:pPlayer = true, bool:pBonus = true, bool:pClass = true)
469{
470 new point
471 if(pPlayer)
472 point += playerInt[id];
473 if(pBonus)
474 point += bonusInt[id];
475 if(pClass)
476 point += classInt[playerClass[id]];
477 return point;
478}
479
480getCon(id, bool:pPlayer = true, bool:pBonus = true, bool:pClass = true)
481{
482 new poCon
483 if(pPlayer)
484 poCon += playerCon[id];
485 if(pBonus)
486 poCon += bonusCon[id];
487 if(pClass)
488 poCon += classCon[playerClass[id]];
489 return poCon;
490}
491
492getStr(id, bool:pPlayer = true, bool:pBonus = true, bool:pClass = true)
493{
494 new poStr
495 if(pPlayer)
496 poStr += playerStr[id];
497 if(pBonus)
498 poStr += bonusStr[id];
499 if(pClass)
500 poStr += classStr[playerClass[id]];
501 return poStr;
502}
503
504getDex(id, bool:pPlayer = true, bool:pBonus = true, bool:pClass = true)
505{
506 new poDex
507 if(pPlayer)
508 poDex += playerDex[id];
509 if(pBonus)
510 poDex += bonusDex[id];
511 if(pClass)
512 poDex += classDex[playerClass[id]];
513 return poDex;
514}
515
516public statsHandler(Handle:menu, MenuAction:action, param1, param2)
517{
518 if (action == MenuAction_Select){
519
520 if(!playerPoints[param1])
521 return;
522
523 switch(param2){
524 case 0:{
525 if(playerInt[param1] < GetConVarInt(maxLvl)/2){
526 playerInt[param1]++;
527 playerPoints[param1]--;
528 }else {
529 PrintToChat(param1, "\x01\x0B\x01 \x07%s \x06Posiadasz maksymalny poziom \x03Inteligencji", MOD_TAG);
530 }
531 }
532 case 1:{
533 if(playerCon[param1] < GetConVarInt(maxLvl)/2){
534 playerCon[param1]++;
535 playerPoints[param1]--;
536 }else {
537 PrintToChat(param1, "\x01\x0B\x01 \x07%s \x06Posiadasz maksymalny poziom \x03Zdrowia", MOD_TAG);
538 }
539 }
540 case 2:{
541 if(playerStr[param1] < GetConVarInt(maxLvl)/2){
542 playerStr[param1]++;
543 playerPoints[param1]--;
544 }else {
545 PrintToChat(param1, "\x01\x0B\x01 \x07%s \x06Posiadasz maksymalny poziom \x03Siły", MOD_TAG);
546 }
547 }
548 case 3:{
549 if(playerDex[param1] < GetConVarInt(maxLvl)){
550 playerDex[param1]++;
551 playerPoints[param1]--;
552 }else {
553 PrintToChat(param1, "\x01\x0B\x01 \x07%s \x06Posiadasz maksymalny poziom \x03Kondycji", MOD_TAG);
554 }
555 }
556 }
557
558 if(playerPoints[param1] > 0)
559 showStats(param1);
560
561 }else if (action == MenuAction_End){
562 CloseHandle(menu);
563 }
564}
565
566public showStats(id)
567{
568 new Handle:menu = CreateMenu(statsHandler);
569
570 decl String:descInt[MAX_STATS_DESCRIPTION_LONG+1],
571 String:descCon[MAX_STATS_DESCRIPTION_LONG+1],
572 String:descStr[MAX_STATS_DESCRIPTION_LONG+1],
573 String:descDex[MAX_STATS_DESCRIPTION_LONG+1],
574 String:title[25];
575
576 Format(title, sizeof(title), "Przydziel Punkty(%d):\n \n", playerPoints[id]);
577 Format(descInt, sizeof(descInt), "Inteligencja(INT): %d \nZwieksza sile perkow i umiejetnosci klasy", getInt(id));
578 Format(descCon, sizeof(descCon), "Zdrowie(CON): %d \nZwieksza ilość HP", getCon(id));
579 Format(descStr, sizeof(descStr), "Siła(STR): %i \nZwiększa ARMOR", getStr(id));
580 Format(descDex, sizeof(descDex), "Kondycja(DEX): %i \nZwieksza tempo chodu", getDex(id));
581
582 SetMenuTitle(menu, title);
583 AddMenuItem(menu, "int", descInt);
584 AddMenuItem(menu, "con", descCon);
585 AddMenuItem(menu, "str", descStr);
586 AddMenuItem(menu, "dex", descDex);
587 DisplayMenu(menu, id, MENU_TIME_FOREVER);
588
589}
590
591public Action:cmdClassSelect(id, args)
592{
593 classSelect(id);
594 return Plugin_Handled;
595}
596
597public Action:cmdShowStats(id, args)
598{
599 showStats(id);
600 return Plugin_Handled;
601}
602
603public Action:cmdShowItemDesc(id, args)
604{
605 if(playerItem[id]){
606 PrintToChat(id, "\x01\x0B\x01 \x06perk:\x03%s \x06opis: \x03%s", itemName[playerItem[id]], itemDescription[playerItem[id]]);
607 }else{
608 PrintToChat(id, "\x01\x0B\x01 \x07%s \x06Nie posiadasz żadnego \x03itemu\x06, aby zdobyć item musisz kogoś zabić!", MOD_TAG);
609 }
610 return Plugin_Handled;
611}
612
613public Action:cmdDrop(id, args)
614{
615 if(playerItem[id]){
616 PrintToChat(id, "\x01\x0B\x01 \x07%s \x06Wyrzuciłeś \x03%s", MOD_TAG, itemName[playerItem[id]]);
617 removeItem(id);
618 }else{
619 PrintToChat(id, "\x01\x0B\x01 \x07%s \x06Nie posiadasz żadnego \x03itemu\x06, aby zdobyć item musisz kogoś zabić!", MOD_TAG);
620 }
621 return Plugin_Handled;
622}
623
624public removeItem(id)
625{
626 new Function:func;
627 func = GetFunctionByName(itemPlugin[playerItem[id]], "OnItemDisabled");
628 if(func != INVALID_FUNCTION){
629 Call_StartFunction(itemPlugin[playerItem[id]], func);
630 Call_PushCell(id);
631 Call_PushCell(playerItem[id]);
632 Call_Finish();
633 }
634 playerItem[id] = 0;
635}
636
637public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)
638{
639 CreateNative("RegisterClass", registerClass);
640 CreateNative("RegisterItem", registerItem);
641
642 CreateNative("GetInt", nativeGetInt);
643 CreateNative("GetCon", nativeGetCon);
644 CreateNative("GetStr", nativeGetStr);
645 CreateNative("GetDex", nativeGetDex);
646 CreateNative("GetBonusExp", nativeGetBonusExp);
647 CreateNative("GetCNameByCId", nativeGetCNameByCId);
648 CreateNative("GetCIdByCName", nativeGetCIdByCName);
649 CreateNative("GetPlayerClass", nativeGetPlayerClass);
650 CreateNative("GetPlayerItem", nativeGetPlayerItem);
651 CreateNative("GetPlayerItemValue", nativeGetPlayerItemValue);
652 CreateNative("GetPlayerLvl", nativeGetPlayerLvl);
653 CreateNative("GetPlayerExp", nativeGetPlayerExp);
654
655 CreateNative("GetClassNum", nativeGetClassNum);
656 CreateNative("GetItemNum", nativeGetItemNum);
657
658 CreateNative("SetPlayerItem", nativeSetPlayerItem);
659 CreateNative("SetBonusInt", nativeSetBonusInt);
660 CreateNative("SetBonusCon", nativeSetBonusCon);
661 CreateNative("SetBonusStr", nativeSetBonusStr);
662 CreateNative("SetBonusDex", nativeSetBonusDex);
663 CreateNative("SetBonusExp", nativeSetBonusExp);
664
665 CreateNative("GiveExp", nativeGiveExp);
666
667 return APLRes_Success;
668}
669
670public eventPlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
671{
672 new attacker = GetClientOfUserId(GetEventInt(event, "attacker"));
673 new victim = GetClientOfUserId(GetEventInt(event, "userid"));
674
675 if(!IsFakeClient(attacker) && (attacker != victim) && (playerClass[attacker] != 0)){
676 new exp = GetConVarInt(expKill) + bonusExp[attacker];
677 if(!IsFakeClient(victim)){
678 if(playerLvl[victim] > playerLvl[attacker])
679 exp += (playerLvl[victim]-playerLvl[attacker])*(GetConVarInt(expKill)/10);
680 }else{
681 exp = 1;
682 }
683 giveExp(attacker, exp);
684 PrintToChat(attacker, "\x01\x0B\x01 \x07%s \x06Otrzymujesz \x03+%dxp \x06za zabójstwo", MOD_TAG, exp);
685 if(!playerItem[attacker]){
686 new random = GetRandomInt(1, itemNum);
687 setPlayerItem(attacker, random);
688 }
689 }
690}
691
692public eventPlayerSpawn(Handle:event, const String:name[], bool:dontBroadcast)
693{
694 new userID = GetClientOfUserId(GetEventInt(event, "userid"));
695 CreateTimer(0.1, timerSpawn, userID, TIMER_FLAG_NO_MAPCHANGE);
696}
697
698public eventItemEquip(Handle:event, const String:name[], bool:dontBroadcast)
699{
700 new userID = GetClientOfUserId(GetEventInt(event, "userid"));
701 new hClientWeapon = GetEntPropEnt(userID, Prop_Send, "m_hActiveWeapon");
702 if(checkWeapon(userID))
703 RemovePlayerItem(userID, hClientWeapon);
704 //CS_DropWeapon(userID, hClientWeapon, false);
705 SetEntPropFloat(userID, Prop_Send, "m_flLaggedMovementValue", playerSpeed[userID]);
706}
707
708checkWeapon(id)
709{
710 if(IsValidClient(id, true) && !IsFakeClient(id)){
711 decl String:weapon[64];
712 GetClientWeapon(id, weapon, sizeof(weapon));
713 for(new i; i < classWeaponsNumber[playerClass[id]]; i++){
714 //PrintToServer("id:%d %d/%d %s %s", id, i, classWeaponsNumber[id], weapon, classWeapons[playerClass[id]][i]);
715 if(StrEqual(weapon, classWeapons[playerClass[id]][i]))
716 return 0;
717 }
718
719 for(new i; i < bonusWeaponsNumber[id]; i++){
720 if(StrEqual(weapon, bonusWeapons[id][i]))
721 return 0;
722 }
723
724 for(new i; i < allowWeaponNumber; i++){
725 if(StrEqual(weapon, allowWeapon[i]))
726 return 0;
727 }
728 return 1;
729 }
730 return 0;
731
732}
733/*
734public eventRoundEnd(Handle:event, const String:name[], bool:dontBroadcast)
735{
736 new userID = GetClientOfUserId(GetEventInt(event, "userid"));
737 giveExp(userID, winExp + bonusExp[userID]);
738 PrintToChat(userID, "\x01\x0B\x01 \x07%s \x06Otrzymujesz \x03+%dxp \x06za wygranie rundy", MOD_TAG, winExp + bonusExp[userID]);
739}
740*/
741public Action:showHUD(Handle:timer)
742{
743 for(new id = 1; id <= MaxClients; id++){
744 if(IsValidClient(id, true)){
745 PrintHintText(id, "[Klasa: %s]\n[LVL: %d][EXP %d/%d]\n[Item: %s]", className[playerClass[id]], playerLvl[id], playerExp[id], getExpForLvl(playerLvl[id]), itemName[playerItem[id]]);
746 }
747 }
748}
749
750stock bool:IsValidClient(client, bool:alive = false)
751{
752 if(client >= 1 && client <= MaxClients && IsClientConnected(client) && IsClientInGame(client) && (alive == false || IsPlayerAlive(client)))
753 {
754 return true;
755 }
756
757 return false;
758}
759
760public giveExp(id, value)
761{
762 if(!IsValidClient(id))
763 return 1;
764
765 playerExp[id] += value;
766 checkLvl(id);
767 return 0;
768}
769
770setPlayerItem(id, itemID, bool:info = true)
771{
772 if(!itemNum)
773 return;
774
775 new Function:func;
776 playerItem[id] = itemID;
777
778 func = GetFunctionByName(itemPlugin[playerItem[id]], "OnItemEnabled");
779 if(func != INVALID_FUNCTION){
780 Call_StartFunction(itemPlugin[playerItem[id]], func);
781 Call_PushCell(id);
782 Call_PushCell(playerItem[id]);
783 Call_Finish();
784 }
785
786 if(info)
787 PrintToChat(id, "\x01\x0B\x01 \x07%s \x06Znalazłeś \x03%s \x06", MOD_TAG, itemName[playerItem[id]]);
788}
789
790public Action:cmdReset(id, args)
791{
792 statsReset(id);
793 PrintToChat(id, "\x01\x0B\x01 \x07%s \x06Twoje statystyki zostały zrestartowane.", MOD_TAG);
794 return Plugin_Handled;
795}
796
797
798public statsReset(id)
799{
800 playerPoints[id] = (playerLvl[id]-1)*2;
801 playerInt[id] = 0;
802 playerCon[id] = 0;
803 playerStr[id] = 0;
804 playerDex[id] = 0;
805
806 if(playerPoints[id])
807 showStats(id);
808}
809
810public checkLvl(id)
811{
812 new bool:lvlUp = false;
813 new bool:lvlDown = false;
814
815 if(!IsClientConnected(id))
816 return;
817
818 while(playerExp[id] >= getExpForLvl(playerLvl[id]) && playerLvl[id] < GetConVarInt(maxLvl)){
819 playerLvl[id]++;
820 playerPoints[id] = (playerLvl[id]-1)*2-playerInt[id]-playerCon[id]-playerStr[id]-playerDex[id];
821 lvlUp = true;
822 }
823 while(playerExp[id] < getExpForLvl(playerLvl[id]-1)){
824 playerLvl[id]--;
825 lvlDown = true;
826 }
827
828 if(playerLvl[id] > GetConVarInt(maxLvl)){
829 playerLvl[id] = GetConVarInt(maxLvl);
830 statsReset(id);
831 }
832
833 if(lvlDown){
834 statsReset(id);
835 PrintToChat(id, "\x01\x0B\x01 \x07%s \x06Spadłeś na \x03%d \x06poziom!", MOD_TAG, playerLvl[id]);
836 }else if(lvlUp){
837 playerPoints[id] = (playerLvl[id]-1)*2-playerInt[id]-playerCon[id]-playerStr[id]-playerDex[id];
838 showStats(id);
839 PrintToChat(id, "\x01\x0B\x01 \x07%s \x06Awansowałeś na \x03%d \x06poziom!", MOD_TAG, playerLvl[id]);
840 }
841
842}
843
844public getExpForLvl(lvl)
845{
846 return lvl*lvl*GetConVarInt(lvlRatio);
847}
848
849public Action:cmdUseItem(id, args)
850{
851 new Function:func;
852
853 func = GetFunctionByName(itemPlugin[playerItem[id]], "OnPlayerUseItem");
854 if(func != INVALID_FUNCTION){
855 Call_StartFunction(itemPlugin[playerItem[id]], func);
856 Call_PushCell(id);
857 Call_PushCell(playerItem[id]);
858 Call_Finish();
859 }
860 return Plugin_Handled;
861}
862
863public Action:cmdUseSkill(id, args)
864{
865 new Function:func;
866 func = GetFunctionByName(classPlugin[playerClass[id]], "OnPlayerUseSkill");
867 if(func != INVALID_FUNCTION){
868 Call_StartFunction(classPlugin[playerClass[id]], func);
869 Call_PushCell(id);
870 Call_PushCell(playerClass[id]);
871 Call_Finish();
872 }
873 return Plugin_Handled;
874}
875
876public registerClass(Handle:plugin, numParams)
877{
878 if(numParams != 7){
879 ThrowNativeError(SP_ERROR_NATIVE, "Bad registerClass NumParams(%d)", numParams);
880 return -1;
881 }
882 if(++classNum > MAX_CLASS_NUMBER){
883 ThrowNativeError(SP_ERROR_NATIVE, "classNum(%d) == MAX_CLASS_NUMBER(%d)", classNum, MAX_CLASS_NUMBER);
884 return -2;
885 }
886
887 classPlugin[classNum] = plugin;
888
889 GetNativeString(1, className[classNum], MAX_NAME_LONG);
890 GetNativeString(2, classDescription[classNum], MAX_DESCRIPTION_LONG);
891
892 classInt[classNum] = GetNativeCell(3);
893 classCon[classNum] = GetNativeCell(4);
894 classStr[classNum] = GetNativeCell(5);
895 classDex[classNum] = GetNativeCell(6);
896
897 new Handle:tmp = GetNativeCell(7);
898 classWeaponsNumber[classNum] = GetArraySize(tmp);
899 if(classWeaponsNumber[classNum] < MAX_WEAPONS_ARRAY_SIZE){
900 for(new i; i < classWeaponsNumber[classNum]; i++)
901 GetArrayString(tmp, i, classWeapons[classNum][i], MAX_WEAPONS_NAME_LONG);
902 }else{
903 for(new i; i < MAX_WEAPONS_ARRAY_SIZE; i++)
904 GetArrayString(tmp, i, classWeapons[classNum][i], MAX_WEAPONS_NAME_LONG);
905 }
906
907
908 return classNum;
909}
910
911public registerItem(Handle:plugin, numParams)
912{
913 if(numParams != 4){
914 ThrowNativeError(SP_ERROR_NATIVE, "Bad registerItem NumParams(%d)", numParams);
915 return 1;
916 }
917
918 if(++itemNum > MAX_ITEM_NUMBER){
919 ThrowNativeError(SP_ERROR_NATIVE, "itemNum(%d) == MAX_ITEM_NUMBER(%d)", itemNum, MAX_ITEM_NUMBER);
920 return -1;
921 }
922
923 itemPlugin[itemNum] = plugin;
924 GetNativeString(1, itemName[itemNum], MAX_NAME_LONG);
925 GetNativeString(2, itemDescription[itemNum], MAX_DESCRIPTION_LONG);
926 minItemValue[itemNum] = GetNativeCell(3);
927 maxItemValue[itemNum] = GetNativeCell(4);
928
929 return itemNum;
930}
931
932public setNewClass(id)
933{
934 new result;
935 new Function:func;
936
937 func = GetFunctionByName(classPlugin[playerClass[id]], "OnClassDisabled");
938 if(func != INVALID_FUNCTION){
939 Call_StartFunction(classPlugin[playerClass[id]], func);
940 Call_PushCell(id);
941 Call_PushCell(playerClass[id]);
942 Call_Finish(result);
943 }
944
945 func = GetFunctionByName(classPlugin[playerNewClass[id]], "OnClassEnabled");
946 if(func != INVALID_FUNCTION){
947 Call_StartFunction(classPlugin[playerNewClass[id]], func);
948 Call_PushCell(id);
949 Call_PushCell(playerClass[id]);
950 Call_Finish(result);
951 }
952
953 if(result == 4){
954 playerClass[id] = 0;
955 playerNewClass[id] = 0;
956 classSelect(id);
957 return 1;
958 }
959
960 saveToDB(id);
961 playerClass[id] = playerNewClass[id];
962 playerNewClass[id] = 0;
963 readClassFromDB(id, playerClass[id]);
964
965 if(IsValidClient(id, true) && !IsFakeClient(id)){
966 removeWeapons(id);
967 giveWeapons(id);
968 activeStats(id);
969 }
970 return 0;
971}
972
973
974
975public removeWeapons(id)
976{
977 if(IsValidClient(id, true) && !IsFakeClient(id)){
978 new slot = -1;
979
980 slot = GetPlayerWeaponSlot(id, CS_SLOT_PRIMARY);
981 if(slot != -1)
982 RemovePlayerItem(id, slot);
983
984 slot = GetPlayerWeaponSlot(id, CS_SLOT_SECONDARY);
985 if(slot != -1)
986 RemovePlayerItem(id, slot);
987
988 slot = GetPlayerWeaponSlot(id, CS_SLOT_KNIFE);
989 if(slot != -1)
990 RemovePlayerItem(id, slot);
991
992 slot = GetPlayerWeaponSlot(id, CS_SLOT_GRENADE);
993 if(slot != -1)
994 RemovePlayerItem(id, slot);
995 }
996}
997
998
999public giveWeapons(id)
1000{
1001 if(IsValidClient(id, true) && !IsFakeClient(id)){
1002 for(new i; i < classWeaponsNumber[playerClass[id]]; i++){
1003 GivePlayerItem(id, classWeapons[playerClass[id]][i]);
1004 }
1005 for(new i; i < bonusWeaponsNumber[id]; i++)
1006 GivePlayerItem(id, bonusWeapons[id][i]);
1007 }
1008}
1009
1010public Action:timerSpawn(Handle:timer, any:client)
1011{
1012 if(IsClientConnected(client) && IsClientInGame(client)){
1013 if(playerNewClass[client])
1014 setNewClass(client);
1015
1016 if(!playerClass[client])
1017 classSelect(client);
1018
1019 if(playerPoints[client])
1020 showStats(client);
1021
1022 removeWeapons(client);
1023 giveWeapons(client);
1024 activeStats(client);
1025 }
1026}
1027
1028public readClassFromDB(id, classN)
1029{
1030 new String:tmp[513];
1031 decl String:authid[64];
1032 if(!GetClientAuthId(id, AuthId_Steam2, authid, 63))
1033 return -1;
1034
1035 Format(tmp, sizeof(tmp), "SELECT lvl, exp, sPoints, sInt, sCon, sStr, sDex FROM codmod WHERE steamID = '%s' AND class = '%s';", authid, className[classN]);
1036 new Handle:query = SQL_Query(sql, tmp);
1037
1038 if(query == INVALID_HANDLE){
1039 SQL_GetError(sql, dbError, sizeof(dbError))
1040 PrintToServer("Failed to readClassFromDB query (error: %s)", dbError)
1041 return 0;
1042 }
1043
1044 if(SQL_GetRowCount(query)){
1045 playerLvl[id] = SQL_FetchInt(query, 0);
1046 playerExp[id] = SQL_FetchInt(query, 1);
1047 playerPoints[id] = SQL_FetchInt(query, 2);
1048 playerInt[id] = SQL_FetchInt(query, 3);
1049 playerCon[id] = SQL_FetchInt(query, 4);
1050 playerStr[id] = SQL_FetchInt(query, 5);
1051 playerDex[id] = SQL_FetchInt(query, 6);
1052 }else{
1053 playerLvl[id] = 1;
1054 playerExp[id] = 0;
1055 playerPoints[id] = 0;
1056 playerInt[id] = 0;
1057 playerCon[id] = 0;
1058 playerStr[id] = 0;
1059 playerDex[id] = 0;
1060 }
1061
1062 CloseHandle(query)
1063 return 1;
1064}
1065
1066public saveToDB(id)
1067{
1068 if(IsFakeClient(id))
1069 return -2;
1070 new String:tmp[1025];
1071 decl String:authid[64];
1072 if(!GetClientAuthId(id, AuthId_Steam2, authid, 63))
1073 return -1;
1074
1075 Format(tmp, sizeof(tmp), "INSERT INTO codmod (steamid, class, lvl, exp, sPoints, sInt, sCon, sStr, sDex) VALUES ('%s', '%s', %d, %d, %d, %d, %d, %d, %d);", authid, className[playerClass[id]], playerLvl[id], playerExp[id], playerPoints[id], playerInt[id], playerCon[id], playerStr[id], playerDex[id]);
1076 if(!SQL_FastQuery(sql, tmp)){
1077 SQL_GetError(sql, dbError, sizeof(dbError))
1078 PrintToServer("Failed to INSERT query (error: %s)", dbError)
1079 return 1;
1080 }
1081 return 0;
1082}
1083
1084public readLvlClassFromDB(id, classN)
1085{
1086 new String:tmp[513];
1087 decl String:authid[64];
1088 if(!GetClientAuthId(id, AuthId_Steam2, authid, 63))
1089 return -1;
1090 Format(tmp, sizeof(tmp), "SELECT lvl FROM codmod WHERE steamID = '%s' AND class = '%s';", authid, className[classN]);
1091 new Handle:query = SQL_Query(sql, tmp);
1092
1093 if(query == INVALID_HANDLE){
1094 SQL_GetError(sql, dbError, sizeof(dbError))
1095 PrintToServer("Failed to query readLvlClassFromDB (error: %s)", dbError)
1096 return -2;
1097 }
1098
1099 if(SQL_GetRowCount(query)){
1100 new r = SQL_FetchInt(query, 0);
1101 CloseHandle(query);
1102 return r;
1103 }else{
1104 CloseHandle(query);
1105 return 1;
1106 }
1107}
1108
1109public activeStats(client)
1110{
1111 SetEntData(client, FindDataMapOffs(client, "m_iMaxHealth"), PLAYER_BASE_HP+getCon(client), 4, true);
1112 SetEntData(client, FindDataMapOffs(client, "m_iHealth"), PLAYER_BASE_HP+getCon(client), 4, true);
1113
1114 playerSpeed[client] = 1.0 + (getDex(client)/100);
1115
1116 if(getStr(client)>=0)
1117 SetEntProp(client, Prop_Data, "m_ArmorValue", getStr(client), 4);
1118}
1119
1120public Plugin:myinfo =
1121{
1122 name = "Cmod core",
1123 author = "PLX",
1124 description = "Easy RPG Mod",
1125 version = "0.1",
1126 url = "http://steamcommunity.com/id/plx211"
1127};