Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <sourcemod>
- #include <sdkhooks>
- #include <tf2>
- #include <tf2_stocks>
- #include <sdktools>
- #undef REQUIRE_PLUGIN
- #include <adminmenu>
- #define REQUIRE_PLUGIN
- //* * * * * * * * * * * * * * * * * * * * * * * * * *
- //Defines
- //* * * * * * * * * * * * * * * * * * * * * * * * * *
- //- The default Field of Vision to apply to clients.
- #define cDefaultVision 90
- //* * * * * * * * * * * * * * * * * * * * * * * * * *
- //Handles
- //* * * * * * * * * * * * * * * * * * * * * * * * * *
- new Handle:h_Mode = INVALID_HANDLE; //ConVar for fov order.
- new Handle:h_MaxValue = INVALID_HANDLE; //ConVar for max fov.
- new Handle:h_MinValue = INVALID_HANDLE; //ConVar for min fov.
- new Handle:hTopMenu = INVALID_HANDLE; //AdminMenu
- //* * * * * * * * * * * * * * * * * * * * * * * * * *
- //Variables
- //* * * * * * * * * * * * * * * * * * * * * * * * * *
- new g_bEnding; //Stores the state of round end.
- new g_bLateLoad; //Stores the state of load.
- //* * * * * * * * * * * * * * * * * * * * * * * * * *
- //Clients
- //* * * * * * * * * * * * * * * * * * * * * * * * * *
- new g_iCurrentVision[MAXPLAYERS + 1] = { cDefaultVision, ... }; //Stores current FoV.
- new bool:g_bActiveVision[MAXPLAYERS + 1]; //Stores whether FoV is modified.
- new bool:g_bForcedVision[MAXPLAYERS + 1]; //Stores whether FoV is active from admin.
- new bool:g_bZoomVision[MAXPLAYERS + 1]; //
- public Plugin:myinfo =
- {
- name = "Strange FoV",
- author = "Benjamin",
- description = "What the fuuuuuuuuuuuuuuuuu...",
- version = "1.1",
- url = "http://steamcommunity.com/id/BenjaminHT/"
- }
- public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)
- {
- g_bLateLoad = late;
- return APLRes_Success;
- }
- public OnPluginStart()
- {
- LoadTranslations("common.phrases");
- //LoadTranslations("sFoV_player.phrases");
- h_Mode = CreateConVar("sm_sfov_mode", "1", "Max FoV.", FCVAR_PLUGIN, true, 1.0, true, 2.0);
- h_MaxValue = CreateConVar("sm_sfov_max", "170", "Max FoV.", FCVAR_PLUGIN, true, 90.0, true, 180.0);
- h_MinValue = CreateConVar("sm_sfov_min", "20", "Min FoV.", FCVAR_PLUGIN, true, 0.0, true, 90.0);
- RegAdminCmd("sm_fov", Command_Vision, ADMFLAG_SLAY);
- AddCommandListener(attack2CallBack, "-attack2");
- //Client Events
- HookEvent("player_spawn", Event_OnPlayerSpawn);
- HookEvent("player_death", Event_OnPlayerDeath);
- HookEvent("player_team", Event_OnPlayerTeam);
- //Round Events
- HookEvent("teamplay_round_start", Event_OnRoundStart);
- HookEvent("teamplay_round_win", Event_OnRoundEnd);
- HookEvent("arena_round_start", Event_OnRoundStart);
- HookEvent("arena_win_panel", Event_OnRoundEnd);
- new Handle:topmenu;
- if (LibraryExists("adminmenu") && ((topmenu = GetAdminTopMenu()) != INVALID_HANDLE))
- {
- OnAdminMenuReady(topmenu);
- }
- }
- //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- //* Fires when the plugin is unloaded.
- public OnPluginEnd()
- {
- for(new i = 1; i <= MaxClients; i++)
- {
- if(!IsClientInGame(i) || IsFakeClient(i))
- continue;
- //Disable the vision effect for anyone that has it enabled.
- if(g_bActiveVision[i])
- {
- SetClientVision(i, 0);
- }
- }
- }
- //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- //* Fires after OnMapStart when all configs are executed.
- public OnConfigsExecuted()
- {
- if(g_bLateLoad)
- {
- //Loop through valid clients, hook them.
- for(new i = 1; i <= MaxClients; i++)
- {
- if(!IsClientInGame(i) || IsFakeClient(i))
- continue;
- SDKHook(i, SDKHook_PostThink, OnPostThink);
- }
- g_bLateLoad = false;
- }
- }
- //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- //* Fires at the start of a new map, or after the plugin has been loaded.
- public OnMapStart()
- {
- //Set the end of the round to False.
- g_bEnding = false;
- }
- //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- //* Fires at the end of the map, after everyone has disconnected but before map changes.
- public OnMapEnd()
- {
- //Set the end of the round to True.
- g_bEnding = true;
- }
- //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- //* Fires when a client physically disconnects or when the map is changing.
- public OnClientDisconnect(client)
- {
- //Ignore if it wasn't a valid client (rare).
- if(!IsClientInGame(client))
- return;
- //Reset data back to defaults for next client.
- g_bActiveVision[client] = false;
- g_bForcedVision[client] = false;
- }
- //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- //* Fires when a client is officially in-game and is a valid target.
- public OnClientPutInServer(client)
- {
- //Ignore if it wasn't a valid client (rare).
- if(!IsClientInGame(client))
- return;
- g_iCurrentVision[client] = cDefaultVision;
- SDKHook(client, SDKHook_PostThink, OnPostThink);
- }
- //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- //* SDKHook_PostThink CallBack
- public OnPostThink(client)
- {
- //Ignore if ending, their vision is disabled, they're in the process of disconnecting, or dying.
- if(g_bEnding || !g_bActiveVision[client] || !IsClientInGame(client) || !IsPlayerAlive(client))
- return;
- //If their current vision is negative, don't use that value!
- new iVision = g_iCurrentVision[client];
- if(iVision < 0)
- {
- iVision *= -1;
- }
- PrintHintText(client, "%d %d", g_iCurrentVision[client], iVision);
- //Apply the FoV.
- SetEntProp(client, Prop_Send, "m_iFOV", iVision);
- //Determine FoV order
- switch(GetConVarInt(h_Mode))
- {
- case 1:
- {
- //If the client is at the upper bounds, reverse.
- if(iVision >= GetConVarInt(h_MaxValue))
- {
- //If their vision is 170, set it to -170 so that it counts down.
- g_iCurrentVision[client] *= -1;
- }
- //If the client is at the lower bounds, reverse.
- if(iVision <= GetConVarInt(h_MinValue))
- {
- //If their vision is -20, set it to 20 so that it counts up
- g_iCurrentVision[client] *= -1;
- }
- }
- case 2:
- {
- if(g_iCurrentVision[client] >= GetConVarInt(h_MaxValue))
- {
- g_iCurrentVision[client] = GetConVarInt(h_MinValue);
- }
- }
- }
- //Increment their current FoV by one every frame.
- g_iCurrentVision[client] += 1;
- }
- //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- //* Fires at the end of Team Play or Arena. (Can't Confirm)
- public Action:Event_OnRoundEnd(Handle:event, const String:name[], bool:dontBroadcast)
- {
- //Set the end of the round to True.
- g_bEnding = true;
- //Loop through all active players in-game.
- for (new i = 1; i < MaxClients; i++)
- {
- if(!IsClientInGame(i) || IsFakeClient(i))
- continue;
- //Disable any active effects, reset their vision.
- if(g_bActiveVision[i])
- {
- SetClientVision(i, 0);
- }
- }
- }
- //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- //* Fires at the start of Team Play or Arena. (Can't Confirm)
- public Action:Event_OnRoundStart(Handle:event, const String:name[], bool:dontBroadcast)
- {
- //Set the end of the round to false.
- g_bEnding = false;
- }
- //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- //* Fires on connection as well as every time a player spawns.
- public Action:Event_OnPlayerSpawn(Handle:event, const String:name[], bool:dontBroadcast)
- {
- //Get the client from the event.
- new client = GetClientOfUserId(GetEventInt(event, "userid"));
- if(!client || !IsClientInGame(client))
- {
- return Plugin_Continue;
- }
- //Ignore any spawning attempts while the player is not alive (i.e. connecting)
- if(!IsPlayerAlive(client))
- {
- return Plugin_Continue;
- }
- //Re-apply the FoV effect if the client has had their state enabled.
- if(g_bForcedVision[client])
- {
- SetClientVision(client, g_iCurrentVision[client]);
- }
- return Plugin_Continue;
- }
- //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- //* Fires whenever a player dies in-game.
- public Action:Event_OnPlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
- {
- //Get the client from the event.
- new client = GetClientOfUserId(GetEventInt(event, "userid"));
- if(!client || !IsClientInGame(client))
- {
- return Plugin_Continue;
- }
- //Reset the client's FoV if they had an active effect & disable it.
- if(g_bActiveVision[client])
- {
- SetClientVision(client, 0);
- }
- return Plugin_Continue;
- }
- //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- //* Fires whenever a player changes their team.
- public Action:Event_OnPlayerTeam(Handle:event, const String:name[], bool:dontBroadcast)
- {
- //Get the client from the event.
- new client = GetClientOfUserId(GetEventInt(event, "userid"));
- if(!client || !IsClientInGame(client))
- {
- return Plugin_Continue;
- }
- //Reset the client's FoV if they join Spectate.
- if(GetEventInt(event, "team") == _:TFTeam_Spectator)
- {
- SetClientVision(client, 0);
- }
- //Re-apply the FoV effect on team change just to be safe.
- else if(g_bForcedVision[client])
- {
- SetClientVision(client, g_iCurrentVision[client]);
- }
- return Plugin_Continue;
- }
- //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- //* Simple stock for modifying the client's FoV.
- stock SetClientVision(client, range)
- {
- if(range == 0)
- {
- g_bActiveVision[client] = false;
- SetEntProp(client, Prop_Send, "m_iFOV", cDefaultVision);
- }
- else
- {
- g_bActiveVision[client] = true;
- SetEntProp(client, Prop_Send, "m_iFOV", range);
- }
- }
- //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- //* CallBack for the vision command.
- public Action:Command_Vision(client, args)
- {
- //Ignore the command if it's used during the end of the round.
- if(g_bEnding)
- {
- ReplyToCommand(client, "[SM] This command can only be used during the round!");
- return Plugin_Handled;
- }
- if(!args)
- {
- //Console has no reason to toggle effects, nor do invalid clients.
- if(!client || GetClientTeam(client) <= _:TFTeam_Spectator || !IsPlayerAlive(client))
- {
- ReplyToCommand(client, "[SM] This command cannot be toggled on invalid clients!");
- return Plugin_Handled;
- }
- //Check to see if the client has self-access.
- if(client && !CheckCommandAccess(client, "StrangeFoVSelf", ADMFLAG_GENERIC))
- {
- ReplyToCommand(client, "[SM] Usage: sm_fov");
- return Plugin_Handled;
- }
- g_bForcedVision[client] = !g_bForcedVision[client];
- ShowActivity2(client, "[SM] ", "Set his/her StrangeFoV state to %s", g_bForcedVision[client] ? "on" : "off");
- LogAction(client, client, "%L set his/her StrangeFoV state to %s", client, g_bForcedVision[client] ? "on" : "off");
- if(g_bForcedVision[client])
- SetClientVision(client, g_iCurrentVision[client]);
- else
- SetClientVision(client, 0);
- return Plugin_Handled;
- }
- if(args)
- {
- //Notify on the event of invalid.
- if(args > 2)
- {
- ReplyToCommand(client, "[SM] This command cannot be toggled on invalid clients!");
- return Plugin_Handled;
- }
- //Check to see if the client has other-access.
- if(client && !CheckCommandAccess(client, "StrangeFoVOther", ADMFLAG_GENERIC))
- {
- ReplyToCommand(client, "[SM] Usage: sm_fov <target> [optional: 0|1]");
- return Plugin_Handled;
- }
- //Declare necessary information to process command; grab argument string.
- decl iBreak, String:sText[192], String:sPattern[64], String:sBuffer[64];
- new iTargets[MAXPLAYERS + 1], bool:bTemp, bool:bState;
- GetCmdArgString(sText, sizeof(sText));
- //Store pattern, check to see if there's an additional argument.
- iBreak = BreakString(sText, sPattern, sizeof(sPattern));
- if(iBreak != -1)
- {
- iBreak += BreakString(sText[iBreak], sBuffer, sizeof(sBuffer));
- bState = bool:StringToInt(sBuffer);
- }
- //Only let the command target non-bots currently in-game.
- new iCount = ProcessTargetString(sPattern, client, iTargets, sizeof(iTargets), COMMAND_FILTER_NO_BOTS|COMMAND_FILTER_CONNECTED, sBuffer, sizeof(sBuffer), bTemp);
- if(iCount)
- {
- //Loop through all clients currently in-game.
- for (new i = 0; i < iCount; i++)
- {
- if(!IsClientInGame(iTargets[i]))
- {
- continue;
- }
- //BreakString returns -1 if there was no string to break, thus 1 parameter.
- if(iBreak == -1)
- {
- //No parameters, so toggle the client's current state.
- if(g_bForcedVision[iTargets[i]])
- {
- SetClientVision(iTargets[i], 0);
- }
- else
- {
- SetClientVision(iTargets[i], g_iCurrentVision[iTargets[i]]);
- }
- g_bForcedVision[iTargets[i]] = !g_bForcedVision[iTargets[i]];
- LogAction(client, iTargets[i], "%L set StrangeFoV on %L to %s", client, iTargets[i], g_bForcedVision[iTargets[i]] ? "on" : "off");
- ShowActivity2(client, "[SM] ", "Set StrangeFoV on %N to %s", iTargets[i], g_bForcedVision[iTargets[i]] ? "on" : "off");
- }
- else
- {
- //Second argument was specified, force whatever values are desired.
- if(bState)
- {
- //It's being enabled, ignore anyone that already has it.
- if(g_bForcedVision[iTargets[i]])
- {
- if(!g_bActiveVision[iTargets[i]])
- SetClientVision(iTargets[i], g_iCurrentVision[iTargets[i]]);
- continue;
- }
- g_bForcedVision[iTargets[i]] = true;
- SetClientVision(iTargets[i], g_iCurrentVision[iTargets[i]]);
- LogAction(client, iTargets[i], "%L set StrangeFoV on %L to %s", client, iTargets[i], g_bForcedVision[iTargets[i]] ? "on" : "off");
- ShowActivity2(client, "[SM] ", "Set StrangeFoV on %N to %s", iTargets[i], g_bForcedVision[iTargets[i]] ? "on" : "off");
- }
- else
- {
- //It's being disabled, ignore anyone that already doesn't have it.
- if(!g_bForcedVision[iTargets[i]])
- {
- if(g_bActiveVision[iTargets[i]])
- SetClientVision(iTargets[i], 0);
- continue;
- }
- g_bForcedVision[iTargets[i]] = false;
- SetClientVision(iTargets[i], 0);
- LogAction(client, iTargets[i], "%L set StrangeFoV on %L to %s", client, iTargets[i], g_bForcedVision[iTargets[i]] ? "on" : "off");
- ShowActivity2(client, "[SM] ", "Set StrangeFoV on %N to %s", iTargets[i], g_bForcedVision[iTargets[i]] ? "on" : "off");
- }
- }
- }
- }
- }
- return Plugin_Handled;
- }
- public Action:attack2CallBack(client, const String:command[], argc)
- {
- g_bForcedVision[client] = !g_bForcedVision[client];
- if(GetEntProp(client, Prop_Send, "m_iFOV") == 90 && g_bForcedVision[client] == false)
- {
- g_bZoomVision[client] = false;
- }
- else
- {
- g_bZoomVision[client] = true;
- }
- if(GetEntProp(client, Prop_Send, "m_iFOV") == 90 && g_bForcedVision[client] == true)
- {
- g_bForcedVision[client] = !g_bForcedVision[client];
- }
- }
- public OnAdminMenuReady(Handle:topmenu)
- {
- /* Block us from being called twice */
- if (topmenu == hTopMenu)
- {
- return;
- }
- /* Save the Handle */
- hTopMenu = topmenu;
- /* Build the "Player Commands" category */
- new TopMenuObject:player_commands = FindTopMenuCategory(hTopMenu, ADMINMENU_PLAYERCOMMANDS);
- if (player_commands != INVALID_TOPMENUOBJECT)
- {
- AddToTopMenu(hTopMenu,
- "sm_fov",
- TopMenuObject_Item,
- AdminMenu_FoV,
- player_commands,
- "sm_fov",
- ADMFLAG_SLAY);
- }
- }
- public OnLibraryRemoved(const String:name[])
- {
- if (strcmp(name, "adminmenu") == 0)
- {
- hTopMenu = INVALID_HANDLE;
- }
- }
- //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- //* AdminMenu Callback - Only re-written cause of OCD.
- public AdminMenu_FoV(Handle:topmenu, TopMenuAction:action, TopMenuObject:object_id, param, String:buffer[], maxlength)
- {
- switch(action)
- {
- case TopMenuAction_DisplayOption:
- {
- Format(buffer, maxlength, "Set Strange FoV", param);
- //Format(buffer, maxlength, "%T", "sFoV player", param);
- }
- case TopMenuAction_SelectOption:
- {
- DisplayFoVMenu(param);
- }
- }
- }
- DisplayFoVMenu(client)
- {
- new Handle:hMenu = CreateMenu(MenuHandler_FoV);
- decl String:sBuffer[128], String:sDisplay[64], String:sUser[4];
- Format(sBuffer, sizeof(sBuffer), "Select Player:", client);
- //Format(sBuffer, sizeof(sBuffer), "%T:", "sFoV player", client);
- SetMenuTitle(hMenu, sBuffer);
- SetMenuExitBackButton(hMenu, true);
- //These should be translations, but for now, just graphics.
- new String:sActive[] = "[*]";
- new String:sDisabled[] = "[ ]";
- //Loop through all active clients. Ignore bots and players the admin can't target.
- // We're making our own loop instad of using AddTargetsToMenu to display the state
- // of the effect prior to toggling.
- for(new i = 1; i <= MaxClients; i++)
- {
- if(!IsClientInGame(i) || IsFakeClient(i) || (client != i && !CanUserTarget(client, i)))
- continue;
- //Format the string so it shows who has it enabled/disabled.
- //1) [ ] Panda
- //2) [*] Benja
- Format(sDisplay, sizeof(sDisplay), "%s %N", g_bForcedVision[i] ? sActive : sDisabled, i);
- //Pass the userid along so it's available.
- IntToString(GetClientUserId(i), sUser, sizeof(sUser));
- AddMenuItem(hMenu, sUser, sDisplay);
- }
- DisplayMenu(hMenu, client, MENU_TIME_FOREVER);
- }
- //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- //* Menu Callback - Only re-written cause of OCD.
- public MenuHandler_FoV(Handle:menu, MenuAction:action, param1, param2)
- {
- switch(action)
- {
- case MenuAction_End:
- {
- CloseHandle(menu);
- }
- case MenuAction_Cancel:
- {
- if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
- {
- DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
- }
- }
- case MenuAction_Select:
- {
- decl String:info[32];
- GetMenuItem(menu, param2, info, sizeof(info));
- new userid = StringToInt(info);
- new target = GetClientOfUserId(userid);
- if(!target)
- {
- PrintToChat(param1, "[SM] The player you were targeting is no longer available.");
- //PrintToChat(param1, "[SM] %t", "Player no longer available");
- }
- else if(!CanUserTarget(param1, target))
- {
- PrintToChat(param1, "[SM] You are unable to target %N!", target);
- //PrintToChat(param1, "[SM] %t", "Unable to target");
- }
- else
- {
- //Toggle the effect based on the current state.
- if(g_bForcedVision[target])
- SetClientVision(target, 0);
- else
- SetClientVision(target, g_iCurrentVision[target]);
- g_bForcedVision[target] = !g_bForcedVision[target];
- LogAction(param1, target, "%L set StrangeFoV on %L to %s", param1, target, g_bForcedVision[target] ? "on" : "off");
- ShowActivity2(param1, "[SM] ", "Set StrangeFoV on %N to %s", target, g_bForcedVision[target] ? "on" : "off");
- }
- //Display the menu back to the admin, if possible.
- if (IsClientInGame(param1) && !IsClientInKickQueue(param1))
- {
- DisplayFoVMenu(param1);
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment