Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on Jul 20th, 2012  |  syntax: PAWN  |  size: 26.53 KB  |  hits: 24  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. /*              **TODO:
  2. *       @Add commands for checking credits (Admins commands to add/remove creds)
  3. *       Events so players can earn credits
  4. *       Betting system
  5. */
  6.  
  7. #include <sourcemod>
  8. #include <sdktools>
  9. #include <sdkhooks>
  10.  
  11. new Handle:g_hStoreDb;
  12. new Handle:g_StoreMenu = INVALID_HANDLE
  13. new Handle:g_StoreMenuCat;
  14. new Handle:g_kvSkins;
  15. new Handle:g_kvTrails;
  16. new g_iClientSpriteEntIndex[MAXPLAYERS+1];
  17. new Handle:gH_Cvar_PluginEnabled = INVALID_HANDLE;
  18.  
  19. #define STARTING_CREDITS 10
  20. #define CREDITS_MIN_PLAYERS 4
  21.  
  22. public Plugin:myinfo =
  23. {
  24.         name = "TCH Store",
  25.         author = "B-Man",
  26.         description = "Store for TCH servers",
  27.         version = "0.5",
  28.         url = ""
  29. }
  30.  
  31. public OnPluginStart()
  32. {
  33.         gH_Cvar_PluginEnabled = CreateConVar("sm_store_enable", "1", "Enables/Disables Store", FCVAR_PLUGIN, true, 0.0, true, 1.0);
  34.        
  35.         RegConsoleCmd("sm_store", Command_OpenStore);
  36.         RegConsoleCmd("sm_credits", Command_Credits);
  37.         RegAdminCmd("sm_credits_add", Command_AddCredits, ADMFLAG_RCON, "Add credits");
  38.         RegAdminCmd("sm_credits_sub", Command_SubtractCredits, ADMFLAG_RCON, "Subtract Credits");
  39.         RegAdminCmd("sm_credits_set", Command_SetCredits, ADMFLAG_RCON, "Set credits");
  40.        
  41.         HookEvent("player_spawn", Event_PlayerSpawn, EventHookMode_Post);
  42.         HookEvent("player_death", Hook_PlayerDeath);
  43.         HookEvent("round_end", Hook_RoundEnd);
  44. }
  45.  
  46. public DB_Connect()
  47. {
  48.         decl String:sError[256];
  49.         g_hStoreDb = SQLite_UseDatabase("tchstore",sError,sizeof(sError));
  50.         if(g_hStoreDb == INVALID_HANDLE)
  51.         {
  52.                 SetFailState("[STORE] Unable to connect to the database (%s)",sError);
  53.         }
  54.         SQL_LockDatabase(g_hStoreDb);
  55.         new String:sQuery[1200];
  56.         sQuery = "CREATE TABLE IF NOT EXISTS [items] ([item_id] INTEGER  PRIMARY KEY AUTOINCREMENT NOT NULL,[item_type] VARCHAR(50)  NOT NULL,[item_cost] INTEGER  NOT NULL,[item_name] VARCHAR(50)  NOT NULL,[item_data] VARCHAR(255)  NULL);";
  57.         SQL_FastQuery(g_hStoreDb,sQuery);
  58.         sQuery = "CREATE TABLE IF NOT EXISTS [players] ([steamid] VARCHAR(50)  UNIQUE NOT NULL PRIMARY KEY,[credits] INTEGER DEFAULT '0' NOT NULL);";
  59.         SQL_FastQuery(g_hStoreDb,sQuery);
  60.         sQuery = "CREATE TABLE IF NOT EXISTS [purchases] ([steamid] VARCHAR(50)  NOT NULL,[item_id] INTEGER  NOT NULL);";
  61.         SQL_FastQuery(g_hStoreDb,sQuery);
  62.        
  63.         SQL_UnlockDatabase(g_hStoreDb);
  64. }
  65.  
  66. public OnConfigsExecuted()
  67. {
  68.         DB_Connect();
  69.         g_kvSkins = CreateKeyValues("Skins");
  70.         g_kvTrails = CreateKeyValues("Trails");
  71.        
  72.         // Read the the player's model settings
  73.         new String:file[256];
  74.         BuildPath(Path_SM, file, 255, "data/store_skins.ini");
  75.         FileToKeyValues(g_kvSkins, file);
  76.        
  77.         // Read the the player's trail settings
  78.         BuildPath(Path_SM, file, 255, "data/store_trails.ini");
  79.         FileToKeyValues(g_kvTrails, file);
  80.        
  81.        
  82.         CreateTimer(60.0, Timer_TimeCredits, _, TIMER_REPEAT);          //Give players a credit every 60 seconds... if they are on a valid team
  83. }
  84.  
  85. public OnMapStart()
  86. {
  87.         //PrecacheModel("models/player/slow/banana_joe/slow.mdl");
  88. }
  89.  
  90. public OnClientDisconnect(client)
  91. {              
  92.         Trail_Remove(client);
  93. }
  94.  
  95. Handle:BuildCategoryMenu(client)
  96. {
  97.         new Handle:menu = CreateMenu(Menu_Category);
  98.         AddMenuItem(menu, "CreditsHelp", "How do I get credits?");
  99.         AddMenuItem(menu, "model", "Skins");
  100.         AddMenuItem(menu, "trail", "Trails");
  101.        
  102.        
  103.         new credits = GetPlayerCredits(client);
  104.         new String:title[50];
  105.         Format(title, sizeof(title), "Welcome to the store! [Credits: %i]", credits);
  106.         SetMenuTitle(menu, title);
  107.        
  108.         return menu;
  109. }
  110.  
  111. public Menu_Category(Handle:menu, MenuAction:action, param1, param2)
  112. {
  113.         if (action == MenuAction_Select)
  114.         {
  115.                 new String:info[255];
  116.  
  117.                 /* Get item info */
  118.                 new bool:found = GetMenuItem(menu, param2, info, sizeof(info));
  119.                
  120.                 if (!found)
  121.                         return;
  122.                
  123.                 if (!StrEqual(info, "CreditsHelp", false))
  124.                 {
  125.                         g_StoreMenu = BuildStoreMenu(param1, info);
  126.                         DisplayMenu(g_StoreMenu, param1, MENU_TIME_FOREVER);
  127.                 }
  128.                 else
  129.                 {
  130.                         /*new Handle:panel = CreatePanel();
  131.                         SetPanelTitle(panel, "How you earn credits");
  132.                         DrawPanelItem(panel, "1 credit per minute\n1 credit = kill\n2 credits = headshot\n3credits = Knife");                  
  133.                         SendPanelToClient(panel, param1, PanelHandler1, 20);
  134.                         CloseHandle(panel);
  135.                         */
  136.                        
  137.                         new Handle:help_Menu = CreateMenu(Menu_NULL);
  138.                         //SetMenuTitle(help_Menu, "How you earn credits");
  139.                         AddMenuItem(help_Menu, "", "How to earn credits\n---------\n1 credit per minute\n1 credit for kills\n2 credits for headshots\n3 credits knife kills");
  140.                         //AddMenuItem(help_Menu, "", "1 credit per minute");
  141.                         //AddMenuItem(help_Menu, "", "1 credit = Kill");
  142.                         //AddMenuItem(help_Menu, "", "2 credits = Headshot");
  143.                         //AddMenuItem(help_Menu, "", "3 credits = Knife");
  144.                         SetMenuExitButton(help_Menu, false);
  145.                         DisplayMenu(help_Menu, param1, MENU_TIME_FOREVER);
  146.                 }
  147.         }
  148. }
  149.  
  150. public Menu_NULL(Handle:menu, MenuAction:action, param1, param2)
  151. {
  152.         //DO Nothing
  153. }
  154.  
  155. Handle:BuildStoreMenu(client, String:type[])
  156. {      
  157.         /* Create the menu Handle */
  158.         new Handle:menu = CreateMenu(Menu_BuyItem);
  159.        
  160.         if (StrContains(type, "model", false) > -1)
  161.                 AddMenuItem(menu, "NoSkin", "Remove Skin");     //Remove the skin
  162.         else if (StrContains(type, "trail", false) > -1)
  163.                 AddMenuItem(menu, "NoTrail", "Remove Trail");   //Remove the skin
  164.        
  165.         new credits = GetPlayerCredits(client);
  166.        
  167.         new String:steamId[25];
  168.         GetClientAuthString(client, steamId, sizeof(steamId));
  169.        
  170.         //SQL
  171.         if(g_hStoreDb == INVALID_HANDLE)
  172.         {
  173.                 SetFailState("[STORE] Unable to connect to the database");
  174.         }
  175.        
  176.         SQL_LockDatabase(g_hStoreDb);
  177.         new String:sQuery[1000];
  178.         Format(sQuery, sizeof(sQuery), "SELECT item_type, item_cost, item_name, item_data, purchases.steamid FROM items LEFT OUTER JOIN purchases ON items.item_id = purchases.item_id AND purchases.steamid = '%s' ORDER BY items.item_name ASC", steamId, type);
  179.         new Handle:query = SQL_Query(g_hStoreDb, sQuery)
  180.         if (query == INVALID_HANDLE || SQL_GetRowCount(query) == 0)
  181.         {
  182.                 new String:error[255];
  183.                 SQL_GetError(g_hStoreDb, error, sizeof(error));
  184.                 PrintToServer("Failed to query (error: %s)", error);
  185.                 PrintToConsole(client, "Failed to query (error: %s)", error);
  186.         } else {
  187.                 new String:itemType[50];
  188.                 new String:itemName[50];
  189.                 new String:itemData[255];
  190.                 new itemCost = 0;
  191.                 while (SQL_FetchRow(query))
  192.                 {
  193.                         SQL_FetchString(query, 0, itemType, sizeof(itemType));
  194.                         if (StrContains(itemType, type) == -1)
  195.                         {
  196.                                 continue;
  197.                         }
  198.                         itemCost = SQL_FetchInt(query, 1);
  199.                         SQL_FetchString(query, 2, itemName, sizeof(itemName));
  200.                         SQL_FetchString(query, 3, itemData, sizeof(itemData));
  201.                         new String:itemInfo[60];
  202.                        
  203.                         if (SQL_IsFieldNull(query, 4))
  204.                         {
  205.                                 Format(itemInfo, sizeof(itemInfo), "%s [%i]", itemName, itemCost);
  206.                        
  207.                                 if (credits < itemCost)
  208.                                 {
  209.                                         AddMenuItem(menu, itemData, itemInfo, ITEMDRAW_DISABLED);
  210.                                 }
  211.                                 else
  212.                                 {
  213.                                         AddMenuItem(menu, itemData, itemInfo);
  214.                                 }
  215.                         }
  216.                         else
  217.                         {
  218.                                 Format(itemInfo, sizeof(itemInfo), "%s [Purchased]", itemName);
  219.                                 AddMenuItem(menu, itemData, itemInfo);
  220.                         }
  221.                 }
  222.                 SQL_UnlockDatabase(g_hStoreDb);
  223.                 /* Free the Handle */
  224.                 CloseHandle(query);
  225.         }
  226.        
  227.         //AddMenuItem(menu, mapname, mapname);
  228.         //AddMenuItem(menu, "TestDisabled", "Test", ITEMDRAW_DISABLED);
  229.  
  230.         /* Finally, set the title */
  231.         new String:title[50];
  232.         Format(title, sizeof(title), "Welcome to the store! [Credits: %i]", credits);
  233.         SetMenuTitle(menu, title);
  234.  
  235.         return menu;
  236. }
  237.  
  238. public Menu_BuyItem(Handle:menu, MenuAction:action, param1, param2)
  239. {
  240.         if (action == MenuAction_Select)
  241.         {
  242.                 new String:info[255];
  243.  
  244.                 /* Get item info */
  245.                 new bool:found = GetMenuItem(menu, param2, info, sizeof(info));
  246.                
  247.                 if (!found)
  248.                         return;
  249.                
  250.                 new String:steamId[25];
  251.                 GetClientAuthString(param1, steamId, sizeof(steamId));
  252.                
  253.                 if(StrContains(info, ".mdl", false) > -1)               //its a skin because it contains .mdl
  254.                 {
  255.                         if (!StrEqual(info,"") && IsClientConnected(param1))
  256.                         {
  257.                                 new bool:alreadyPurchased = CheckPurchaseByItemData(info, param1);
  258.                                 if(!alreadyPurchased)
  259.                                 {
  260.                                         SubtractCredits(param1, GetCostByItemData(info));
  261.                                         PurchaseItem(param1, info);
  262.                                 }
  263.                                
  264.                                 KvSetString(g_kvSkins, steamId, info);
  265.                                
  266.                                 if (GetConVarInt(gH_Cvar_PluginEnabled) && IsModelPrecached(info))
  267.                                 {
  268.                                         if (IsPlayerAlive(param1))
  269.                                         {
  270.                                                 SetEntityModel(param1, info);
  271.                                                 SetEntityRenderColor(param1, 255, 255, 255, 255);
  272.                                         }
  273.                                        
  274.                                         new String:item_name[50];
  275.                                         GetItemNameByItemData(info, item_name, sizeof(item_name))
  276.                                         //PrintHintText(param1, "You are now wearing the skin:\n %s", item_name);
  277.                                         SendDialogToOne(param1, 10, "Current skin: [%s]", item_name);
  278.                                         PrintToChat(param1, "\x04[\x03Store\x04]\x01 You are now wearing the skin: \x03%s", item_name);
  279.                                         ShowoffSkin(param1);
  280.                                 }
  281.                                 else
  282.                                 {
  283.                                         if (alreadyPurchased)
  284.                                         {
  285.                                                 PrintToChat(param1, "\x04[\x03Store\x04]\x01 Selection successful, although skins are not enabled at this time");
  286.                                         }
  287.                                         else
  288.                                         {
  289.                                                 PrintToChat(param1, "\x04[\x03Store\x04]\x01 Purchase successful, although skins are not enabled at this time");
  290.                                         }
  291.                                 }
  292.                         }
  293.                 }
  294.                 else if(StrContains(info, ".vtf", false) > -1 || StrContains(info, ".vmt", false) >-1)          //Its a trail since it contains .vmt or .vtf
  295.                 {
  296.                         new bool:alreadyPurchased = CheckPurchaseByItemData(info, param1);
  297.                         if(!alreadyPurchased)
  298.                         {
  299.                                 SubtractCredits(param1, GetCostByItemData(info));
  300.                                 PurchaseItem(param1, info);
  301.                         }
  302.                        
  303.                         KvSetString(g_kvTrails, steamId, info);
  304.                         Trail_Remove(param1);
  305.                        
  306.                         new String:item_name[50];
  307.                         GetItemNameByItemData(info, item_name, sizeof(item_name))
  308.                        
  309.                         if (GetConVarInt(gH_Cvar_PluginEnabled))
  310.                         {
  311.                                 CreateTimer(0.2, Timer_AttachTrail, param1, TIMER_FLAG_NO_MAPCHANGE);
  312.                                 PrintToChat(param1, "\x04[\x03Store\x04]\x01 You have equipped the trail: \x03%s", item_name);
  313.                         }
  314.                         else
  315.                         {
  316.                                 if (alreadyPurchased)
  317.                                         PrintToChat(param1, "\x04[\x03Store\x04]\x01 You have equipped the trail: \x03%s", item_name);
  318.                                 else
  319.                                         PrintToChat(param1, "\x04[\x03Store\x04]\x01 You have purchased the trail: \x03%s \x01Although trails are not enabled atg this time", item_name);
  320.                         }
  321.                 }
  322.                 else if (StrEqual(info, "NoTrail"))
  323.                 {
  324.                         KvSetString(g_kvTrails, steamId, "");
  325.                         Trail_Remove(param1);  
  326.                 }
  327.                 else if (StrEqual(info, "NoSkin"))
  328.                 {
  329.                         KvSetString(g_kvSkins, steamId, "");
  330.                         if (IsPlayerAlive(param1))
  331.                         {
  332.                                 PrintToChat(param1, "\x04[\x03Store\x04]\x01 Your skil will be removed next time you spawn");
  333.                                 //PrintHintText(param1, "Your skin will be removed next spawn");
  334.                         }
  335.                 }
  336.                
  337.                 /* Tell the client */
  338.                 //PrintToConsole(param1, "You selected item: %d (found? %d info: %s)", param2, found, info);
  339.                 //PrintToConsole(param1, "SteamID: %s", steamId);
  340.         }
  341. }
  342.  
  343. public Action:Command_OpenStore(client, args)
  344. {
  345.         g_StoreMenuCat = BuildCategoryMenu(client);
  346.         DisplayMenu(g_StoreMenuCat, client, MENU_TIME_FOREVER);
  347.                
  348.         return Plugin_Handled;
  349. }
  350.  
  351. public Action:Command_Credits(client, args)
  352. {
  353.         //PrintHintText(client, "You have %i credits", GetPlayerCredits(client));
  354.         new creds = GetPlayerCredits(client);
  355.         SendDialogToOne(client, 10, "You have %i credits", creds);
  356.         PrintToChat(client, "\x04[\x03Store\x04]\x01 You have \x03%i \x01credits", creds);
  357.         return Plugin_Continue;
  358. }
  359.  
  360. public Action:Command_AddCredits(client, args)
  361. {
  362.         new String:s_target[50];
  363.         GetCmdArg(1, s_target, sizeof(s_target));
  364.         new target = FindTarget(client, s_target, true);
  365.        
  366.         if (IsClientInGame(target))
  367.         {
  368.                 new String:s_amount[9];
  369.                 GetCmdArg(2, s_amount, sizeof(s_amount));
  370.                 new amount = StringToInt(s_amount);
  371.                
  372.                 if (amount > 0)
  373.                 {
  374.                         new String:s_name[50];
  375.                         GetClientName(target, s_name, sizeof(s_name));
  376.                         AddCredits(target, amount);
  377.                         PrintToChat(client, "\x04[\x03Store\x04]\x01 Added \x03%i \x01credits to \x03%s", amount, s_name);
  378.                         PrintToChat(target, "\x04[\x03Store\x04]\x01 You now have \x03%i \x01credits", GetPlayerCredits(client));
  379.                 }
  380.         }
  381.        
  382.         return Plugin_Continue;
  383. }
  384.  
  385. public Action:Command_SubtractCredits(client, args)
  386. {
  387.         new String:s_target[50];
  388.         GetCmdArg(1, s_target, sizeof(s_target));
  389.         new target = FindTarget(client, s_target, true);
  390.        
  391.         if (IsClientInGame(target))
  392.         {
  393.                 new String:s_amount[9];
  394.                 GetCmdArg(2, s_amount, sizeof(s_amount));
  395.                 new amount = StringToInt(s_amount);
  396.                
  397.                 if (amount > 0)
  398.                 {
  399.                         new String:s_name[50];
  400.                         GetClientName(target, s_name, sizeof(s_name));
  401.                         SubtractCredits(target, amount);
  402.                         PrintToChat(client, "\x04[\x03Store\x04]\x01 Subtracted \x03%i \x01credits from \x03%s", amount, s_name);
  403.                         PrintToChat(target, "\x04[\x03Store\x04]\x01 You now have \x03%i \x01credits", GetPlayerCredits(client));
  404.                 }
  405.         }
  406.        
  407.         return Plugin_Continue;
  408. }
  409.  
  410. public Action:Command_SetCredits(client, args)
  411. {
  412.         new String:s_target[50];
  413.         GetCmdArg(1, s_target, sizeof(s_target));
  414.         new target = FindTarget(client, s_target, true);
  415.        
  416.         if (IsClientInGame(target))
  417.         {
  418.                 new String:s_amount[9];
  419.                 GetCmdArg(2, s_amount, sizeof(s_amount));
  420.                 new amount = StringToInt(s_amount);
  421.                
  422.                 if (amount > 0)
  423.                 {
  424.                         new String:s_name[50];
  425.                         GetClientName(target, s_name, sizeof(s_name));
  426.                         SetCredits(target, amount);
  427.                         PrintToChat(client, "\x04[\x03Store\x04]\x01 Set player \x03%s \x01to \x03%i \x01credits", s_name, amount);
  428.                         PrintToChat(target, "\x04[\x03Store\x04]\x01 You now have \x03%i \x01credits", GetPlayerCredits(client));
  429.                 }
  430.         }
  431.        
  432.         return Plugin_Continue;
  433. }
  434.  
  435. public Event_PlayerSpawn(Handle:event, const String:name[], bool:dontBroadcast)
  436. {
  437.         if (GetConVarInt(gH_Cvar_PluginEnabled))
  438.         {      
  439.                 //Skins stuff
  440.                 // Get the userid and client
  441.                 new clientId = GetEventInt(event, "userid");
  442.                 new client = GetClientOfUserId(clientId);      
  443.                 new String:steamId[25];
  444.                 GetClientAuthString(client, steamId, sizeof(steamId));
  445.                
  446.                 new String:model[255];
  447.                 new String:item_name[50];
  448.                 //KvJumpToKey(kvSkins, steamId, true);
  449.                 KvGetString(g_kvSkins, steamId, model, sizeof(model), "");
  450.                
  451.                
  452.                 // Make sure that they have a valid model pref
  453.                 /*if (!StrEqual(model,"", false) && IsModelPrecached(model))
  454.                 {
  455.                         // Set the model
  456.                         SetEntityModel(client, model);
  457.                         SetEntityRenderColor(client, 255, 255, 255, 255);
  458.                 }*/
  459.                 if (!StrEqual(model,"") && IsModelPrecached(model))
  460.                 {
  461.                         SetEntityModel(client, model);
  462.                         SetEntityRenderColor(client, 255, 255, 255, 255);
  463.                        
  464.                         GetItemNameByItemData(model, item_name, sizeof(item_name))
  465.                         //PrintHintText(client, "You are wearing the skin:\n %s", item_name);
  466.                         SendDialogToOne(client, 15, "Current skin: [%s]", item_name);
  467.                         PrintToChat(client, "\x04[\x03Store\x04]\x01 Current skin: [\x03%s\x01]", item_name);
  468.                 }
  469.                
  470.                
  471.                 KvRewind(g_kvSkins);
  472.                
  473.                 //Trails stuff
  474.                
  475.                 new String:trail[255];
  476.                 //KvJumpToKey(kvSkins, steamId, true);
  477.                 KvGetString(g_kvTrails, steamId, trail, sizeof(trail), "");
  478.                
  479.                 if (!IsFakeClient(client) && !StrEqual(trail,"", false))
  480.                 {
  481.                         CreateTimer(0.2, Timer_AttachTrail, client, TIMER_FLAG_NO_MAPCHANGE);
  482.                 }
  483.         }
  484. }
  485.  
  486. public Hook_RoundEnd(Handle:event, const String:name[], bool:DontBroadcast)
  487. {
  488.         //Remove trails for dead people :)
  489.         for (new idx = 1; idx <= MaxClients; idx++)
  490.         {
  491.                 Trail_Remove(idx);
  492.         }
  493. }
  494.  
  495. public Hook_PlayerDeath(Handle:event, const String:name[], bool:DontBroadcast)
  496. {
  497.         new attacker = GetClientOfUserId(GetEventInt(event, "attacker"));
  498.         new victim = GetClientOfUserId(GetEventInt(event, "userid"));
  499.        
  500.         Trail_Remove(victim);
  501.        
  502.         //Win Credits
  503.         if (IsFakeClient(victim) || IsFakeClient(attacker))
  504.         {
  505.                 //We dont count bots!
  506.         } else if (victim == attacker || attacker == 0)
  507.         {
  508.                 //Suicide
  509.         } else if (GetClientTeam(attacker) == GetClientTeam(victim))
  510.         {
  511.                 //Teamkill
  512.         } else
  513.         {
  514.                 new credits = 0;
  515.                 new bool:headshot = GetEventBool(event, "headshot");
  516.                 credits++;
  517.                 if (headshot)
  518.                         credits++;
  519.                
  520.                 decl String:weapon[64];
  521.                 GetEventString(event, "weapon", weapon, sizeof(weapon));
  522.                 ReplaceString(weapon,sizeof(weapon),"weapon_","");
  523.                
  524.                 if(StrEqual(weapon,"knife"))
  525.                 {
  526.                         credits = 3;
  527.                 }
  528.                
  529.                 AddCredits(attacker, credits);
  530.         }
  531. }
  532.  
  533. public OnPluginEnd()
  534. {
  535.         SaveAndClose();
  536. }
  537.  
  538. public SaveAndClose()
  539. {
  540.         KvRewind(g_kvSkins);
  541.         KvRewind(g_kvTrails);
  542.         // Write the the player's model settings
  543.         new String:file[256];
  544.         BuildPath(Path_SM, file, 255, "data/store_skins.ini");
  545.         KeyValuesToFile(g_kvSkins, file);
  546.         CloseHandle(g_kvSkins);
  547.        
  548.         BuildPath(Path_SM, file, 255, "data/store_trails.ini");
  549.         KeyValuesToFile(g_kvTrails, file);
  550.         CloseHandle(g_kvTrails);
  551.        
  552.         CloseHandle(g_hStoreDb);
  553. }
  554.  
  555. public GetPlayerCredits(client)
  556. {
  557.         new String:steamId[25];
  558.         GetClientAuthString(client, steamId, sizeof(steamId));
  559.        
  560.         SQL_LockDatabase(g_hStoreDb);
  561.         new String:sQuery[1000];
  562.         Format(sQuery, sizeof(sQuery), "SELECT credits FROM players WHERE steamid = '%s'", steamId);
  563.         new Handle:query = SQL_Query(g_hStoreDb, sQuery)
  564.         if (query == INVALID_HANDLE)
  565.         {
  566.                 new String:error[255]
  567.                 SQL_GetError(g_hStoreDb, error, sizeof(error))
  568.                 PrintToServer("Failed to query (error: %s)", error)
  569.                 PrintToConsole(client, "Failed to query (error: %s)", error);
  570.                 return 0;
  571.         }
  572.         if (SQL_GetRowCount(query) == 0)
  573.         {
  574.                 SQL_UnlockDatabase(g_hStoreDb);
  575.                 AddNewPlayer(client);
  576.                 CloseHandle(query);
  577.                 return STARTING_CREDITS;
  578.         }
  579.         else
  580.         {
  581.                 new itemCost = SQL_FetchInt(query, 0);
  582.                 SQL_UnlockDatabase(g_hStoreDb);
  583.                 CloseHandle(query);
  584.                 return itemCost;
  585.         }
  586. }
  587.  
  588. public GetCostByItemData(String:model[])
  589. {
  590.         new String:sQuery[1000];
  591.         Format(sQuery, sizeof(sQuery), "SELECT item_cost FROM items WHERE item_data = '%s'", model);
  592.         new Handle:query = SQL_Query(g_hStoreDb, sQuery)
  593.         if (query == INVALID_HANDLE)
  594.         {
  595.                 new String:error[255]
  596.                 SQL_GetError(g_hStoreDb, error, sizeof(error))
  597.                 PrintToServer("Failed to query (error: %s)", error)
  598.                 return 9999999;
  599.         }
  600.         new itemCost = SQL_FetchInt(query, 0);
  601.         CloseHandle(query);
  602.         return itemCost;
  603. }
  604.  
  605. public SubtractCredits(client, amount)
  606. {
  607.         new String:steamId[25];
  608.         GetClientAuthString(client, steamId, sizeof(steamId));
  609.        
  610.         SQL_LockDatabase(g_hStoreDb);
  611.         new String:sQuery[1000];
  612.         Format(sQuery, sizeof(sQuery), "UPDATE players SET credits = credits - %i WHERE steamid = '%s'", amount, steamId);
  613.         if (!SQL_FastQuery(g_hStoreDb, sQuery))
  614.         {
  615.                 new String:error[255];
  616.                 SQL_GetError(g_hStoreDb, error, sizeof(error));
  617.                 PrintToServer("Failed to query (error: %s)", error);
  618.                 PrintToConsole(client, "Failed to query (error: %s)", error);
  619.         }
  620.         SQL_UnlockDatabase(g_hStoreDb);
  621. }
  622.  
  623. public AddCredits(client, amount)
  624. {
  625.         new String:steamId[25];
  626.         GetClientAuthString(client, steamId, sizeof(steamId));
  627.        
  628.         SQL_LockDatabase(g_hStoreDb);
  629.         new String:sQuery[1000];
  630.         Format(sQuery, sizeof(sQuery), "UPDATE players SET credits = credits + %i WHERE steamid = '%s'", amount, steamId);
  631.         if (!SQL_FastQuery(g_hStoreDb, sQuery))
  632.         {
  633.                 new String:error[255]
  634.                 SQL_GetError(g_hStoreDb, error, sizeof(error))
  635.                 PrintToServer("Failed to query (error: %s)", error)
  636.                 PrintToConsole(client, "Failed to query (error: %s)", error);
  637.         }
  638.         SQL_UnlockDatabase(g_hStoreDb);
  639. }
  640.  
  641. public SetCredits(client, amount)
  642. {
  643.         new String:steamId[25];
  644.         GetClientAuthString(client, steamId, sizeof(steamId));
  645.        
  646.         SQL_LockDatabase(g_hStoreDb);
  647.         new String:sQuery[1000];
  648.         Format(sQuery, sizeof(sQuery), "UPDATE players SET credits = %i WHERE steamid = '%s'", amount, steamId);
  649.         if (!SQL_FastQuery(g_hStoreDb, sQuery))
  650.         {
  651.                 new String:error[255]
  652.                 SQL_GetError(g_hStoreDb, error, sizeof(error))
  653.                 PrintToServer("Failed to query (error: %s)", error)
  654.                 PrintToConsole(client, "Failed to query (error: %s)", error);
  655.         }
  656.         SQL_UnlockDatabase(g_hStoreDb);
  657. }
  658.  
  659. public PurchaseItem(client, String:model[])
  660. {
  661.         new itemId = GetItemIdByItemData(model);
  662.        
  663.         new String:steamId[25];
  664.         GetClientAuthString(client, steamId, sizeof(steamId));
  665.        
  666.         SQL_LockDatabase(g_hStoreDb);
  667.         new String:sQuery[1000];
  668.         Format(sQuery, sizeof(sQuery), "INSERT INTO purchases (steamid, item_id) VALUES ('%s', %i)", steamId, itemId);
  669.         if (!SQL_FastQuery(g_hStoreDb, sQuery))
  670.         {
  671.                 new String:error[255]
  672.                 SQL_GetError(g_hStoreDb, error, sizeof(error))
  673.                 PrintToServer("Failed to query (error: %s)", error)
  674.                 PrintToConsole(client, "Failed to query (error: %s)", error);
  675.         }
  676.         SQL_UnlockDatabase(g_hStoreDb);
  677. }
  678.  
  679. public GetItemIdByItemData(String:model[])
  680. {
  681.         SQL_LockDatabase(g_hStoreDb);
  682.         new String:sQuery[1000];
  683.         Format(sQuery, sizeof(sQuery), "SELECT item_id FROM items WHERE item_data = '%s'", model);
  684.         new Handle:query = SQL_Query(g_hStoreDb, sQuery)
  685.         if (query == INVALID_HANDLE)
  686.         {
  687.                 new String:error[255];
  688.                 SQL_GetError(g_hStoreDb, error, sizeof(error));
  689.                 PrintToServer("Failed to query (error: %s)", error);
  690.                 SQL_UnlockDatabase(g_hStoreDb);
  691.                 return -1;
  692.         }
  693.         if (SQL_GetRowCount(query) == 1)
  694.         {
  695.                 SQL_UnlockDatabase(g_hStoreDb);
  696.                 return SQL_FetchInt(query, 0);
  697.         }
  698.         SQL_UnlockDatabase(g_hStoreDb);
  699.         return -1;
  700. }
  701.  
  702. public GetItemNameByItemData(String:model[], String:buffer[], buffer_size)
  703. {
  704.        
  705.         SQL_LockDatabase(g_hStoreDb);
  706.         new String:sQuery[1000];
  707.         Format(sQuery, sizeof(sQuery), "SELECT item_name FROM items WHERE item_data = '%s'", model);
  708.         new Handle:query = SQL_Query(g_hStoreDb, sQuery)
  709.         if (query == INVALID_HANDLE)
  710.         {
  711.                 new String:error[255];
  712.                 SQL_GetError(g_hStoreDb, error, sizeof(error));
  713.                 PrintToServer("Failed to query (error: %s)", error);
  714.                 SQL_UnlockDatabase(g_hStoreDb);
  715.                 return false;
  716.         }
  717.         if (SQL_GetRowCount(query) == 1)
  718.         {
  719.                 SQL_FetchString(query, 0, buffer, buffer_size);
  720.                 SQL_UnlockDatabase(g_hStoreDb);
  721.                 return true;
  722.         }
  723.         SQL_UnlockDatabase(g_hStoreDb);
  724.         return false;
  725. }
  726.  
  727. public bool:CheckPurchaseByItemData(String:model[], client)
  728. {
  729.         new String:steamId[25];
  730.         GetClientAuthString(client, steamId, sizeof(steamId));
  731.        
  732.         SQL_LockDatabase(g_hStoreDb);
  733.         new String:sQuery[1000];
  734.         Format(sQuery, sizeof(sQuery), "SELECT items.item_name, purchases.steamid FROM items JOIN purchases ON items.item_id = purchases.item_id WHERE items.item_data = '%s' AND purchases.steamid = '%s'", model, steamId);
  735.         new Handle:query = SQL_Query(g_hStoreDb, sQuery)
  736.         if (query == INVALID_HANDLE)
  737.         {
  738.                 new String:error[255]
  739.                 SQL_GetError(g_hStoreDb, error, sizeof(error))
  740.                 PrintToServer("Failed to query (error: %s)", error)
  741.                 PrintToConsole(client, "Failed to query (error: %s)", error);
  742.                 SQL_UnlockDatabase(g_hStoreDb);
  743.                 return false;
  744.         }
  745.         if (SQL_GetRowCount(query) == 1)
  746.         {
  747.                 SQL_UnlockDatabase(g_hStoreDb);
  748.                 CloseHandle(query);
  749.                 return true;
  750.         }
  751.         SQL_UnlockDatabase(g_hStoreDb);
  752.         CloseHandle(query);
  753.         return false;
  754. }
  755.  
  756. public bool:AddNewPlayer(client)
  757. {
  758.         new String:steamId[25];
  759.         GetClientAuthString(client, steamId, sizeof(steamId));
  760.        
  761.         SQL_LockDatabase(g_hStoreDb);
  762.         new String:sQuery[1000];
  763.         Format(sQuery, sizeof(sQuery), "INSERT INTO players (steamid, credits) VALUES ('%s', %i)", steamId, STARTING_CREDITS);
  764.         if (!SQL_FastQuery(g_hStoreDb, sQuery))
  765.         {
  766.                 new String:error[255]
  767.                 SQL_GetError(g_hStoreDb, error, sizeof(error))
  768.                 PrintToServer("Failed to query (error: %s)", error)
  769.                 PrintToConsole(client, "Failed to query (error: %s)", error);
  770.                 SQL_UnlockDatabase(g_hStoreDb);
  771.                 return false;
  772.         }
  773.         SQL_UnlockDatabase(g_hStoreDb);
  774.         return true;
  775. }
  776.  
  777. public void:Trail_Attach(client)
  778. {
  779.        
  780.         new String:steamId[25];
  781.         GetClientAuthString(client, steamId, sizeof(steamId));
  782.        
  783.         new String:trail[255];
  784.         KvGetString(g_kvTrails, steamId, trail, sizeof(trail), "");
  785.         if (StrEqual(trail,"", false))
  786.         {
  787.                 return;
  788.         }
  789.        
  790.         decl String:sTempName[64];
  791.         Format(sTempName, sizeof(sTempName), "PlayerTrail_%d", GetClientUserId(client));
  792.         DispatchKeyValue(client, "targetname", sTempName);
  793.        
  794.         new entIndex = CreateEntityByName("env_spritetrail");
  795.         if (entIndex > 0 && IsValidEntity(entIndex))
  796.         {
  797.                 // mark that we made a sprite trail for this client
  798.                 g_iClientSpriteEntIndex[client] = entIndex;
  799.                        
  800.                 DispatchKeyValue(entIndex, "parentname", sTempName);
  801.                 DispatchKeyValue(entIndex, "spritename", trail);
  802.                 SetEntPropFloat(entIndex, Prop_Send, "m_flTextureRes", 0.05);
  803.                
  804.                 DispatchKeyValue(entIndex, "renderamt", "255"); //Not sure what this does yet
  805.                 //DispatchKeyValue(entIndex, "rendercolor", "65 105 225");
  806.                
  807.                 DispatchKeyValueFloat(entIndex, "lifetime", 2.0);       //4 seconds lifetime?
  808.                 DispatchKeyValueFloat(entIndex, "startwidth", 15.0);
  809.                 DispatchKeyValueFloat(entIndex, "endwidth", 5.0);
  810.                 DispatchKeyValue(entIndex, "rendermode", "5");
  811.                
  812.                 DispatchSpawn(entIndex);
  813.                 new Float:f_origin[3];
  814.                 GetClientAbsOrigin(client, f_origin);
  815.                 f_origin[2] += 14.0; // 34
  816.                 TeleportEntity(entIndex, f_origin, NULL_VECTOR, NULL_VECTOR);
  817.                 SetVariantString(sTempName);
  818.                 AcceptEntityInput(entIndex, "SetParent", entIndex, entIndex);
  819.                        
  820.                 SDKHook(entIndex, SDKHook_SetTransmit, Hook_SetTransmit);
  821.         }
  822. }
  823.  
  824. public void:Trail_Remove(client)
  825. {
  826.         new ent = g_iClientSpriteEntIndex[client];
  827.         if (ent != 0)
  828.         {
  829.                 if (IsValidEntity(ent))
  830.                 {
  831.                         SDKUnhook(ent, SDKHook_SetTransmit, Hook_SetTransmit);
  832.                         AcceptEntityInput(ent, "Kill");
  833.                 }
  834.         }
  835. }
  836.  
  837.  
  838. //This can block trails depending on conditions
  839. public Action:Hook_SetTransmit(entity, client)
  840. {
  841.         /*  NOT NEEDED, FUTURE USE POSSIBLY
  842.         // find entity's owner
  843.         new parent = -1;
  844.         for (new idx = 1; idx <= MaxClients; idx++)
  845.         {
  846.                 if (g_iClientSpriteEntIndex[idx] == entity)
  847.                 {
  848.                         if (IsClientInGame(idx))
  849.                         {
  850.                                 parent = idx;
  851.                         }
  852.                 }
  853.         }*/    
  854.        
  855.         return Plugin_Continue;
  856. }
  857.  
  858. public Action:Timer_AttachTrail(Handle:timer, any:client)
  859. {
  860.        
  861.         if (IsClientInGame(client) && IsPlayerAlive(client) && (GetClientTeam(client) > 1))
  862.         {
  863.                 // attach trail to client
  864.                 Trail_Attach(client);
  865.         }
  866.        
  867.         return Plugin_Handled;
  868. }
  869.  
  870. public ShowoffSkin(client)
  871. {
  872.         if (!IsFakeClient (client) && IsClientInGame(client) && IsPlayerAlive(client) && (GetClientTeam(client) > 1))
  873.         {
  874.                 ClientCommand (client, "3rd_on");
  875.                 CreateTimer(2.0, Timer_ShowoffSkin, client, TIMER_FLAG_NO_MAPCHANGE);
  876.         }
  877. }
  878.  
  879. public Action:Timer_ShowoffSkin(Handle:timer, any:client)
  880. {
  881.        
  882.         if (IsClientInGame(client) && IsPlayerAlive(client) && (GetClientTeam(client) > 1))
  883.         {
  884.                 ClientCommand (client, "3rd_off");
  885.         }
  886.        
  887.         return Plugin_Handled;
  888. }
  889.  
  890. public Action:Timer_TimeCredits(Handle:timer)
  891. {
  892.         new i;
  893.         for(i=1;i<=MaxClients;i++)
  894.         {
  895.                 if (IsClientInGame(i))
  896.                 {
  897.                         AddCredits(i, 1);
  898.                 }
  899.         }
  900.        
  901.         return Plugin_Continue;
  902. }
  903.  
  904. public OnMapEnd()
  905. {
  906.         for (new idx = 1; idx <= MaxClients; idx++)
  907.         {
  908.                 new ent = g_iClientSpriteEntIndex[idx];
  909.                 if (ent != 0)
  910.                 {
  911.                         if (IsValidEntity(ent))
  912.                         {
  913.                                 SDKUnhook(ent, SDKHook_SetTransmit, Hook_SetTransmit);
  914.                                 AcceptEntityInput(ent, "Kill");
  915.                         }
  916.                 }
  917.         }
  918.         SaveAndClose();
  919. }
  920.  
  921. SendDialogToOne(client, duration, String:text[], any:...)
  922. {
  923.     new String:message[100];
  924.     VFormat(message, sizeof(message), text, 4);    
  925.    
  926.     new Handle:kv = CreateKeyValues("Stuff", "title", message);
  927.     KvSetColor(kv, "color", 0, 191, 255, 255);
  928.     KvSetNum(kv, "level", 1);
  929.     KvSetNum(kv, "time", duration);
  930.    
  931.     CreateDialog(client, kv, DialogType_Msg);
  932.    
  933.     CloseHandle(kv);    
  934. }