#include #include #include #include #include #pragma semicolon 1 #define UID(%0) GetClientUserId(%0) #define CID(%0) GetClientOfUserId(%0) #define PLUGIN_VERSION "1.0" #define HUD_X -1.0; #define HUD_Y 0.4; #define HUD_HOLD 1.0; new Handle:g_cmd_timeout; new Handle:g_cmd_timeout_vip; new Handle:g_EffectTimer[MAXPLAYERS+2] = {INVALID_HANDLE, ...}; char g_SQL_RANDOM[256]; //char g_SQL_EFFECT[256]; int g_ClientStartTime[MAXPLAYERS+2] = {0, ...}; int g_ClientEndTime[MAXPLAYERS+2] = {0, ...}; int g_ClientLastUse[MAXPLAYERS+2] = {0, ...}; int g_ClientLastActivate[MAXPLAYERS+2] = {0, ...}; char g_ClientActivateCmd[MAXPLAYERS+2][256]; char g_ClientDeactivateCmd[MAXPLAYERS+2][256]; bool g_ClientDeactivateIfDead[MAXPLAYERS+2] = {false, ...}; char g_ClientEffectName[MAXPLAYERS+2][256]; bool g_ClientSettedEffect[MAXPLAYERS+2] = {false, ...}; bool g_ClientUpdatedEffect[MAXPLAYERS+2] = {false, ...}; bool g_ClientShowHud[MAXPLAYERS+2] = {false, ...}; new Handle:g_Database = INVALID_HANDLE; new Handle:g_hCounterHud = INVALID_HANDLE; public Plugin:myinfo = { name = "RTD ULTIMATE", author = "gsd", description = "SQL RTD VERSION WITH WEIGHT RANDOM AND SERVER COMMAND EXECUTE", version = PLUGIN_VERSION, url = "http://vk.com/facti13" } public OnPluginStart(){ SQL_Start(); HookEvent("post_inventory_application", Event_Spawn); CreateConVar("sm_rtd_version", PLUGIN_VERSION, "RTD ULTIMATE VERSION", FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY|FCVAR_DONTRECORD); g_cmd_timeout = CreateConVar("sm_rtd_timeout", "120", "Amount of time in seconds a player roll the ULTIMATE DICE FACTI 13", FCVAR_NOTIFY, true, 0.0); g_cmd_timeout_vip = CreateConVar("sm_rtd_timeout_vip", "180", "Amount of time in seconds a vip player roll the ULTIMATE DICE FACTI 13", FCVAR_NOTIFY, true, 0.0); RegConsoleCmd("rtd", User_roll); //RegAdminCmd("sm_rrtd", User_roll, ADMFLAG_RESERVATION, "Roll the ULTIMATE DICE"); RegAdminCmd("sm_rtd_use", Admin_roll, ADMFLAG_ROOT, "Roll the ULTIMATE DICE to user"); RegAdminCmd("sm_rtd_addcond", Command_AddCondition, ADMFLAG_GENERIC, "Add a condition to the target(s), Usage: sm_rtd_addcond \"target\" \"condition number\" \"duration\""); RegAdminCmd("sm_rtd_removecond", Command_RemoveCondition, ADMFLAG_GENERIC, "Add a condition to the target(s), Usage: sm_rtd_removecond \"target\" \"condition number\""); RegAdminCmd("sm_rtd_kill", Command_Kill, ADMFLAG_GENERIC, "Kill target', Usage: sm_rtd_kill \"target\" \"condition number\""); RegAdminCmd("sm_rtd_reset", Command_Reset, ADMFLAG_GENERIC, "Reset RTD timeout on target', Usage: sm_rtd_reset \"target\""); RegAdminCmd("sm_rtd_playsound", Command_PlaySound, ADMFLAG_GENERIC, "Play sound on target', Usage: sm_rtd_playsound \"target\""); g_hCounterHud = CreateHudSynchronizer(); } public OnPluginEnd(){ for (new i = 0; i < MAXPLAYERS + 2; i ++){ if(g_EffectTimer[i] != INVALID_HANDLE){ TriggerTimer(g_EffectTimer[i]); } else { DeactivateEffect(i); } } } //SQL INIT FUNCTIONS stock SQL_Start(){ Format(g_SQL_RANDOM, sizeof(g_SQL_RANDOM), "SELECT name, activate, deactivate, time, de_ondead, alarm_all, -LOG(random()) / chance as priority FROM rtd_ultimate ORDER BY priority LIMIT 1"); //Format(g_SQL_EFFECT, sizeof(g_SQL_EFFECT), "SELECT name, activate, deactivate, time, de_ondead FROM rtd_ultimate WHERE id LIKE %i LIMIT 1"); SQL_TConnect(SQL_SetDatabase, "rtd_ultimate"); } public SQL_SetDatabase(Handle:owner, Handle:hndl, const String:error[], any:data) { if (hndl == INVALID_HANDLE) { LogError("Database Connection Error: %s", error); } else { g_Database = hndl; } } //CLIENT CONNECTION/SPAWN public void OnClientAuthorized(client){ DeactivateEffect(client); g_ClientLastUse[client] = GetTime(); g_EffectTimer[client] = INVALID_HANDLE; } public void OnClientDisconnect(client){ if(g_EffectTimer[client] != INVALID_HANDLE){ KillTimer(g_EffectTimer[client]); } g_EffectTimer[client] = INVALID_HANDLE; DeactivateEffect(client); } public Event_Spawn(Event event, const char[] name, bool dontBroadcast){ new client = CID(GetEventInt(event, "userid")); //LogMessage("Client effect setted: %b Client currenly updating: %b", g_ClientSettedEffect[cid], g_ClientUpdatedEffect[cid]); if (g_ClientSettedEffect[client] && !g_ClientUpdatedEffect[client]) { /* if (g_ClientDeactivateIfDead[client]){ LogMessage("Deactivate effect on %i client", cid); DeactivateEffect(cid); } else { LogMessage("Refresh effect on %i client", cid); RefreshEffect(cid); } */ //LogMessage("Refresh effect on %i client", cid); float time = float(g_ClientEndTime[client] - GetTime()); if (time <= 2.0){ DeactivateEffect(client); } else { RefreshEffect(client); } } return Plugin_Continue; } public void OnGameFrame(){ for(int i = 1; i < MaxClients; i++){ if(IsClientInGame(i) && g_ClientShowHud[i]){ if (g_ClientEndTime[i] - GetTime() >= 0){ SetHudTextParams(-1.0, 0.45, 1, 255, 255, 255, 255); ShowSyncHudText(i, g_hCounterHud,"%i", g_ClientEndTime[i] - GetTime()); } } } } //STOCK's FUNCTiONs stock SecToHuman(int i_time, char[] s_time, int str_size){ int s, m; m = i_time / 60; s = i_time % 60; char minutes[64]; char seconds[64]; ////////////////////////////////////////////////////////////// if (m > 10 && m < 20){ Format(minutes, sizeof(minutes), "%i минут", m); } else { if (m % 10 > 1 && m % 10 < 5){ Format(minutes, sizeof(minutes), "%i минуты", m); } else { if (m % 10 == 1){ Format(minutes, sizeof(minutes), "%i минута", m); } else { Format(minutes, sizeof(minutes), "%i минут", m); } } } ////////////////////////////////////////////////////////////// if (s > 10 && s < 20){ Format(seconds, sizeof(seconds), "%i секунд", s); } else { if (s % 10 > 1 && s % 10 < 5){ Format(seconds, sizeof(seconds), "%i секунды", s); } else { if (s % 10 == 1){ Format(seconds, sizeof(seconds), "%i секунда", s); } else { Format(seconds, sizeof(seconds), "%i секунд", s); } } } ////////////////////////////////////////////////////////////// if (m > 0){ Format(s_time, str_size, "%s %s", minutes, seconds); } else { Format(s_time, str_size, "%s", seconds); } } stock ActivateEffect(int client, const char[] name, const char[] act_cmd, const char[] deact_cmd, int time, bool reset_on_dead){ if (g_ClientSettedEffect[client]){ DeactivateEffect(client); } strcopy(g_ClientActivateCmd[client], 256, act_cmd); strcopy(g_ClientDeactivateCmd[client], 256, deact_cmd); ReplaceCmdString(client); strcopy(g_ClientEffectName[client],256, name); g_ClientStartTime[client] = GetTime(); if (time < 0){ g_ClientEndTime[client] = GetTime(); } else { g_ClientEndTime[client] = GetTime() + time; } g_ClientDeactivateIfDead[client] = reset_on_dead; g_ClientSettedEffect[client] = true; RefreshEffect(client); } stock ReplaceCmdString(int client){ char s_uid[32]; Format(s_uid, sizeof(s_uid), "#%i", UID(client)); ReplaceString(g_ClientActivateCmd[client], 256, "%i", s_uid); ReplaceString(g_ClientDeactivateCmd[client], 256, "%i", s_uid); ///////////////////////////////////////////////////////////////////////////////////////////// if (StrContains(g_ClientActivateCmd[client], "%team%") != -1){ switch (TF2_GetClientTeam(client)) { case TFTeam_Red: ReplaceString(g_ClientActivateCmd[client], 256, "%team%", "@red"); case TFTeam_Blue: ReplaceString(g_ClientActivateCmd[client], 256, "%team%", "@blue"); default: ReplaceString(g_ClientActivateCmd[client], 256, "%team%", ""); } } if (StrContains(g_ClientActivateCmd[client], "%class") != -1){ switch (TF2_GetPlayerClass(client)){ case TFClass_Scout: ReplaceString(g_ClientActivateCmd[client], 256, "%class%", "scout"); case TFClass_Soldier: ReplaceString(g_ClientActivateCmd[client], 256, "%class%", "soldier"); case TFClass_Pyro: ReplaceString(g_ClientActivateCmd[client], 256, "%class%", "pyro"); case TFClass_DemoMan: ReplaceString(g_ClientActivateCmd[client], 256, "%class%", "demoman"); case TFClass_Heavy: ReplaceString(g_ClientActivateCmd[client], 256, "%class%", "heavy"); case TFClass_Engineer: ReplaceString(g_ClientActivateCmd[client], 256, "%class%", "engineer"); case TFClass_Medic: ReplaceString(g_ClientActivateCmd[client], 256, "%class%", "medic"); case TFClass_Sniper: ReplaceString(g_ClientActivateCmd[client], 256, "%class%", "sniper"); case TFClass_Spy: ReplaceString(g_ClientActivateCmd[client], 256, "%class%", "spy"); default: ReplaceString(g_ClientActivateCmd[client], 256, "%class%", ""); } } ///////////////////////////////////////////////////////////////////////////////////////////// if (StrContains(g_ClientDeactivateCmd[client], "%team%") != -1){ switch (TF2_GetClientTeam(client)) { case TFTeam_Red: ReplaceString(g_ClientDeactivateCmd[client], 256, "%team%", "@red"); case TFTeam_Blue: ReplaceString(g_ClientDeactivateCmd[client], 256, "%team%", "@blue"); default: ReplaceString(g_ClientDeactivateCmd[client], 256, "%team%", ""); } } if (StrContains(g_ClientDeactivateCmd[client], "%class%") != -1){ switch (TF2_GetPlayerClass(client)){ case TFClass_Scout: ReplaceString(g_ClientDeactivateCmd[client], 256, "%class%", "scout"); case TFClass_Soldier: ReplaceString(g_ClientDeactivateCmd[client], 256, "%class%", "soldier"); case TFClass_Pyro: ReplaceString(g_ClientDeactivateCmd[client], 256, "%class%", "pyro"); case TFClass_DemoMan: ReplaceString(g_ClientDeactivateCmd[client], 256, "%class%", "demoman"); case TFClass_Heavy: ReplaceString(g_ClientDeactivateCmd[client], 256, "%class%", "heavy"); case TFClass_Engineer: ReplaceString(g_ClientDeactivateCmd[client], 256, "%class%", "engineer"); case TFClass_Medic: ReplaceString(g_ClientDeactivateCmd[client], 256, "%class%", "medic"); case TFClass_Sniper: ReplaceString(g_ClientDeactivateCmd[client], 256, "%class%", "sniper"); case TFClass_Spy: ReplaceString(g_ClientDeactivateCmd[client], 256, "%class%", "spy"); default: ReplaceString(g_ClientDeactivateCmd[client], 256, "%class%", ""); } } } stock RefreshEffect(int client){ //LogMessage("Effect setted: %b, De_ondead:%b, Start: %i, End: %i",g_ClientSettedEffect[client], g_ClientDeactivateIfDead[client], g_ClientStartTime[client], g_ClientEndTime[client]); if (g_ClientUpdatedEffect[client]){ //LogMessage("Effect currently try update..."); return; } else { g_ClientUpdatedEffect[client] = true; } if (!IsClientInGame(client) || !IsPlayerAlive(client)) { g_ClientUpdatedEffect[client] = false; return; } if (GetTime() - g_ClientLastActivate[client] >= 0.5){ if(g_EffectTimer[client] != INVALID_HANDLE){ if (g_ClientDeactivateIfDead[client]) { TriggerTimer(g_EffectTimer[client]); g_ClientUpdatedEffect[client] = false; return; } } ExecuteActivateCmd(client); }/* else { LogMessage("Ignore refresh effect on %i client", client); }*/ if (g_ClientStartTime[client] != g_ClientEndTime[client]){ float time = float(g_ClientEndTime[client] - GetTime()); if (time <= 2){ DeactivateEffect(client); return; } } g_ClientUpdatedEffect[client] = false; return; } stock ExecuteActivateCmd(int client){ g_ClientShowHud[client] = true; g_ClientLastActivate[client] = GetTime(); if (g_ClientStartTime[client] == g_ClientEndTime[client]){ ServerCommand(g_ClientActivateCmd[client]); PrintCenterText(client, "Наложен эффект: %s", g_ClientEffectName[client]); LogMessage("(%L) Наложен эффект: %s", client, g_ClientEffectName[client]); g_ClientUpdatedEffect[client] = false; return; } else { float time = float(g_ClientEndTime[client] - GetTime()); if(time > 0){ ServerCommand(g_ClientActivateCmd[client]); if (g_EffectTimer[client] == INVALID_HANDLE){ g_EffectTimer[client] = CreateTimer(time, DeactivateTimer, client, TIMER_FLAG_NO_MAPCHANGE); } PrintCenterText(client, "Наложен эффект:%s, длительностью %i секунд", g_ClientEffectName[client], RoundFloat(time)); LogMessage("(%L) Наложен эффект:%s, длительностью %i секунд", client, g_ClientEffectName[client], RoundFloat(time)); } else { DeactivateEffect(client); } g_ClientUpdatedEffect[client] = false; return; } } stock DeactivateEffect(int client){ if(g_EffectTimer[client] != INVALID_HANDLE) TriggerTimer(g_EffectTimer[client]); g_ClientShowHud[client] = false; g_ClientUpdatedEffect[client] = false; g_ClientSettedEffect[client] = false; strcopy(g_ClientActivateCmd[client], 256,""); strcopy(g_ClientDeactivateCmd[client], 256, ""); strcopy(g_ClientEffectName[client], 256, ""); g_ClientStartTime[client] = 0; g_ClientEndTime[client] = 0; g_ClientDeactivateIfDead[client] = false; } // TIMERs public Action:DeactivateTimer(Handle:timer, any:client){ g_ClientUpdatedEffect[client] = true; ServerCommand(g_ClientDeactivateCmd[client]); PrintCenterText(client, "Эффект: %s, был снят", g_ClientEffectName[client]); LogMessage("(%L) Эффект: %s, был снят", client, g_ClientEffectName[client]); DeactivateEffect(client); g_EffectTimer[client] = INVALID_HANDLE; return Plugin_Stop; } // SQL FUNCTIONs public SQL_SetEffect(Handle:owner, Handle:hndl, const String:error[], any:data) { int client; if ((client = CID(data)) == 0) { return; } if(g_EffectTimer[client] != INVALID_HANDLE){ TriggerTimer(g_EffectTimer[client]); } else { DeactivateEffect(client); } if (hndl == INVALID_HANDLE) { LogError("Query failed! %s", error); g_ClientLastUse[client] = 0; PrintToChat(client, "Невозможно выдать рандомный эффект из-за ошибки базы данных!"); return; } else { g_ClientLastUse[client] = GetTime(); } if (SQL_FetchRow(hndl)) { char effect_name[256]; SQL_FetchString(hndl, 0, effect_name, sizeof(effect_name)); char activate_cmd[256]; SQL_FetchString(hndl, 1, activate_cmd, sizeof(activate_cmd)); char deactivate_cmd[256]; SQL_FetchString(hndl, 2, deactivate_cmd, sizeof(deactivate_cmd)); int time = SQL_FetchInt(hndl, 3); bool de_ondead = SQL_FetchInt(hndl, 4); bool alarm_all = SQL_FetchInt(hndl, 5); if (alarm_all) { PrintCenterTextAll("Игрок: %N, применил для всех эффект: %s", client, effect_name); LogMessage("Игрок: %L, применил для всех эффект: %s", client, effect_name); } ActivateEffect(client, effect_name, activate_cmd, deactivate_cmd, time, de_ondead); if (time == 0) { DeactivateEffect(client); } } else { PrintToChat(client, "Применяемый эффект не найден в базе..."); } return; } // COMMAND FUNTION's public Action:User_roll(client, args){ if (g_ClientSettedEffect[client]){ PrintToChat(client, "У тебя уже присутствует эффект: %s", g_ClientEffectName[client]); return Plugin_Handled; } int timeout = GetTime() - g_ClientLastUse[client]; int cmd_timeout; if (CheckCommandAccess(client, "sm_rtd_vip", ADMFLAG_RESERVATION, false)){ cmd_timeout = GetConVarInt(g_cmd_timeout_vip); } else { cmd_timeout = GetConVarInt(g_cmd_timeout); cmd_timeout = cmd_timeout + cmd_timeout * GetClientCount(true) / 5; } //if (GetClientCount(true)/5 > 0){ // cmd_timeout = cmd_timeout + cmd_timeout * GetClientCount(true) / 5; //} if (timeout < cmd_timeout){ char s_timeout[64]; SecToHuman(cmd_timeout - timeout, s_timeout, sizeof(s_timeout)); PrintToChat(client, "Ты еще не можешь ролить рандомный эффект, подожди еще %s", s_timeout); return Plugin_Handled; } PrintToChat(client, "Крутим колесо фартуны......"); SQL_TQuery(g_Database, SQL_SetEffect, g_SQL_RANDOM, UID(client)); return Plugin_Handled; } public Action:Admin_roll(client, args){ if (args > 2 || args == 0) { ReplyToCommand(client, "Usage: sm_rtd_player "); return Plugin_Handled; } new String:buffer[64];GetCmdArg(1, buffer, sizeof(buffer)); new String:target_name[MAX_NAME_LENGTH]; new target_list[MAXPLAYERS]; new target_count; new bool:tn_is_ml; if ((target_count = ProcessTargetString( buffer, client, target_list, MAXPLAYERS, COMMAND_FILTER_CONNECTED, target_name, sizeof(target_name), tn_is_ml)) <= 0) { ReplyToTargetError(client, target_count); return Plugin_Handled; } if(target_count > 0){ new count = 0; for (new i = 0; i < target_count; i ++){ if (args == 1){ SQL_TQuery(g_Database, SQL_SetEffect, g_SQL_RANDOM, UID(target_list[i])); count++; } else { char SQL[256]; char strBuffer[16]; GetCmdArg(2, strBuffer, sizeof(strBuffer)); int effect_id = StringToInt(strBuffer); Format(SQL, sizeof(SQL), "SELECT name, activate, deactivate, time, de_ondead, alarm_all FROM rtd_ultimate WHERE id LIKE %i LIMIT 1", effect_id); SQL_TQuery(g_Database, SQL_SetEffect, SQL, UID(target_list[i])); count++; } } ReplyToCommand(client, "Было заролено %i раз", count); return Plugin_Handled; } else { ReplyToCommand(client, "Не было найдено целей для использования команды..."); return Plugin_Handled; } } public Action:Command_Kill(client, args){ if(args != 1){ ReplyToCommand(client, "[SM] Usage: sm_rtd_kill \"target\""); return Plugin_Handled; } new String:strBuffer[MAX_NAME_LENGTH], String:target_name[MAX_TARGET_LENGTH], target_list[MAXPLAYERS], target_count, bool:tn_is_ml; GetCmdArg(1, strBuffer, sizeof(strBuffer)); if ((target_count = ProcessTargetString(strBuffer, client, target_list, MAXPLAYERS, COMMAND_FILTER_ALIVE, target_name, sizeof(target_name), tn_is_ml)) <= 0) { ReplyToTargetError(client, target_count); return Plugin_Handled; } for(new i = 0; i < target_count; i++) { FakeClientCommand(target_list[i], "explode"); //SDKHooks_TakeDamage(target_list[i], target_list[i], target_list[i], 99999999.0); } return Plugin_Handled; } public Action:Command_Reset(client, args){ if(args != 1){ ReplyToCommand(client, "[SM] Usage: sm_rtd_reset \"target\""); return Plugin_Handled; } new String:strBuffer[MAX_NAME_LENGTH], String:target_name[MAX_TARGET_LENGTH], target_list[MAXPLAYERS], target_count, bool:tn_is_ml; GetCmdArg(1, strBuffer, sizeof(strBuffer)); if ((target_count = ProcessTargetString(strBuffer, client, target_list, MAXPLAYERS, COMMAND_FILTER_ALIVE, target_name, sizeof(target_name), tn_is_ml)) <= 0) { ReplyToTargetError(client, target_count); return Plugin_Handled; } int count = 0; for(new i = 0; i < target_count; i++) { g_ClientLastUse[target_list[i]] = 0; count++; } ReplyToCommand(client, "RTD таймер был сброшен у %i игроков", count); return Plugin_Handled; } public Action:Command_AddCondition(client, args){ if(args != 3) { ReplyToCommand(client, "[SM] Usage: sm_rtd_addcond \"target\" \"condition number\" \"duration\""); return Plugin_Handled; } new String:strBuffer[MAX_NAME_LENGTH], String:target_name[MAX_TARGET_LENGTH], target_list[MAXPLAYERS], target_count, bool:tn_is_ml; GetCmdArg(1, strBuffer, sizeof(strBuffer)); if ((target_count = ProcessTargetString(strBuffer, client, target_list, MAXPLAYERS, COMMAND_FILTER_ALIVE, target_name, sizeof(target_name), tn_is_ml)) <= 0) { ReplyToTargetError(client, target_count); return Plugin_Handled; } new iCondition, Float:flDuration; GetCmdArg(2, strBuffer, sizeof(strBuffer)); iCondition = StringToInt(strBuffer); GetCmdArg(3, strBuffer, sizeof(strBuffer)); flDuration = StringToFloat(strBuffer); for(new i = 0; i < target_count; i++) { TF2_AddCondition(target_list[i], TFCond:iCondition, flDuration); } return Plugin_Handled; } public Action:Command_RemoveCondition(client, args){ if(args != 2) { ReplyToCommand(client, "[SM] Usage: sm_rtd_removecond \"target\" \"condition number\""); return Plugin_Handled; } new String:strBuffer[MAX_NAME_LENGTH], String:target_name[MAX_TARGET_LENGTH], target_list[MAXPLAYERS], target_count, bool:tn_is_ml; GetCmdArg(1, strBuffer, sizeof(strBuffer)); if ((target_count = ProcessTargetString(strBuffer, client, target_list, MAXPLAYERS, COMMAND_FILTER_ALIVE, target_name, sizeof(target_name), tn_is_ml)) <= 0) { ReplyToTargetError(client, target_count); return Plugin_Handled; } new iCondition; GetCmdArg(2, strBuffer, sizeof(strBuffer)); iCondition = StringToInt(strBuffer); for(new i = 0; i < target_count; i++) { TF2_RemoveCondition(target_list[i], TFCond:iCondition); } return Plugin_Handled; } public Action:Command_PlaySound(client, args){ if(args != 2) { ReplyToCommand(client, "[SM] Usage: sm_rtd_playsound \"target\" \"filepath\""); return Plugin_Handled; } new String:strBuffer[MAX_NAME_LENGTH], String:target_name[MAX_TARGET_LENGTH], target_list[MAXPLAYERS], target_count, bool:tn_is_ml; GetCmdArg(1, strBuffer, sizeof(strBuffer)); if ((target_count = ProcessTargetString(strBuffer, client, target_list, MAXPLAYERS, COMMAND_FILTER_ALIVE, target_name, sizeof(target_name), tn_is_ml)) <= 0) { ReplyToTargetError(client, target_count); return Plugin_Handled; } char SoundPath[256]; GetCmdArg(2, SoundPath, sizeof(SoundPath)); for(new i = 0; i < target_count; i++) { EmitSoundToClient(target_list[i], SoundPath); } return Plugin_Handled; }