View difference between Paste ID: GnXyahrV and Cuuubkde
SHOW: | | - or go back to the newest paste.
1
#include <sourcemod>
2
#include <sdkhooks>
3
#include <tf2>
4
#include <tf2_stocks>
5
#include <sdktools>
6
7
#undef REQUIRE_PLUGIN
8
#include <adminmenu>
9
#define REQUIRE_PLUGIN
10-
new Handle:h_Mode = INVALID_HANDLE;
10+
11-
new Handle:h_MaxValue = INVALID_HANDLE;
11+
//* * * * * * * * * * * * * * * * * * * * * * * * * *
12-
new Handle:h_MinValue = INVALID_HANDLE;
12+
//Defines
13
//* * * * * * * * * * * * * * * * * * * * * * * * * *
14-
new RoundWin = 1;
14+
//- The default Field of Vision to apply to clients.
15-
new Adding = 1;
15+
#define cDefaultVision 90
16-
new TheValue = 90;
16+
17-
new bool:ShowFov[MAXPLAYERS + 1];
17+
//* * * * * * * * * * * * * * * * * * * * * * * * * *
18
//Handles
19-
new bool:sfov_check[MAXPLAYERS + 1];
19+
//* * * * * * * * * * * * * * * * * * * * * * * * * *
20-
new bool:sfov_on[MAXPLAYERS + 1];
20+
new Handle:h_Mode = INVALID_HANDLE;				//ConVar for fov order.
21-
new sfovmode;
21+
new Handle:h_MaxValue = INVALID_HANDLE;			//ConVar for max fov.
22-
new Max;
22+
new Handle:h_MinValue = INVALID_HANDLE;			//ConVar for min fov.
23-
new Min;
23+
new Handle:hTopMenu = INVALID_HANDLE;			//AdminMenu
24
25-
new Handle:hTopMenu = INVALID_HANDLE;
25+
//* * * * * * * * * * * * * * * * * * * * * * * * * *
26
//Variables
27-
public Plugin:myinfo = 
27+
//* * * * * * * * * * * * * * * * * * * * * * * * * *
28
new g_bEnding;									//Stores the state of round end.
29
new g_bLateLoad;								//Stores the state of load.
30
31
//* * * * * * * * * * * * * * * * * * * * * * * * * *
32
//Clients
33
//* * * * * * * * * * * * * * * * * * * * * * * * * *
34
new g_iCurrentVision[MAXPLAYERS + 1] = { cDefaultVision, ... };			//Stores current FoV.
35
new bool:g_bActiveVision[MAXPLAYERS + 1];		//Stores whether FoV is modified.
36
new bool:g_bForcedVision[MAXPLAYERS + 1];		//Stores whether FoV is active from admin.
37
new bool:g_bZoomVision[MAXPLAYERS + 1];			//
38-
	RegAdminCmd("sm_sfov_reload", Command_reload, ADMFLAG_GENERIC);
38+
39-
	h_Mode = CreateConVar("sm_sfov_mode", "1", "Max FoV.", FCVAR_PLUGIN, true, 1.0, true, 2.0); 
39+
public Plugin:myinfo =
40-
	h_MaxValue = CreateConVar("sm_sfov_max", "170", "Max FoV.", FCVAR_PLUGIN, true, 90.0, true, 180.0); 
40+
41-
	h_MinValue = CreateConVar("sm_sfov_min", "20", "Min FoV.", FCVAR_PLUGIN, true, 0.0, true, 90.0); 
41+
42
	author = "Benjamin",
43-
	LoadTranslations("sFoV_player.phrases");
43+
44-
	RegAdminCmd("sm_fov", CmdFovStrange, ADMFLAG_SLAY);
44+
45-
	HookEvent("teamplay_round_win", Event_teamplay_round_win);
45+
46-
	HookEvent("arena_round_start", Event_teamplay_round_start);
46+
47
48
public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)
49
{
50
	g_bLateLoad = late;
51-
		ShowFov[i] = false;
51+
	return APLRes_Success;
52
}
53
54
public OnPluginStart()
55-
		sfov_on[i] = false;
55+
56
	LoadTranslations("common.phrases");
57
	//LoadTranslations("sFoV_player.phrases");
58
59-
		sfov_check[i] = false;
59+
	h_Mode = CreateConVar("sm_sfov_mode", "1", "Max FoV.", FCVAR_PLUGIN, true, 1.0, true, 2.0);
60
	h_MaxValue = CreateConVar("sm_sfov_max", "170", "Max FoV.", FCVAR_PLUGIN, true, 90.0, true, 180.0);
61
	h_MinValue = CreateConVar("sm_sfov_min", "20", "Min FoV.", FCVAR_PLUGIN, true, 0.0, true, 90.0);
62
63
	RegAdminCmd("sm_fov", Command_Vision, ADMFLAG_SLAY);
64
65
	AddCommandListener(attack2CallBack, "-attack2");
66
67
	//Client Events
68
	HookEvent("player_spawn", Event_OnPlayerSpawn);
69
	HookEvent("player_death", Event_OnPlayerDeath);
70
	HookEvent("player_team", Event_OnPlayerTeam);
71-
	sfovmode = GetConVarInt(h_Mode);
71+
72-
	Max = GetConVarInt(h_MaxValue);
72+
	//Round Events
73-
	Min = GetConVarInt(h_MinValue);
73+
	HookEvent("teamplay_round_start", Event_OnRoundStart);
74
	HookEvent("teamplay_round_win", Event_OnRoundEnd);
75
	HookEvent("arena_round_start", Event_OnRoundStart);
76
	HookEvent("arena_win_panel", Event_OnRoundEnd);
77
78
	new Handle:topmenu;
79
	if (LibraryExists("adminmenu") && ((topmenu = GetAdminTopMenu()) != INVALID_HANDLE))
80-
		ShowFov[i] = false;
80+
81
		OnAdminMenuReady(topmenu);
82
	}
83
}
84-
		sfov_on[i] = false;
84+
85
//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
86
//* Fires when the plugin is unloaded.
87
public OnPluginEnd()
88-
public Action:Event_teamplay_round_win(Handle:event, const String:name[], bool:dontBroadcast)
88+
89
	for(new i = 1; i <= MaxClients; i++)
90
	{
91
		if(!IsClientInGame(i) || IsFakeClient(i))
92-
	ShowFov[i] = false;
92+
			continue;
93
		
94-
	RoundWin = 2;
94+
		//Disable the vision effect for anyone that has it enabled.
95
		if(g_bActiveVision[i])
96
		{
97-
public Action:Event_teamplay_round_start(Handle:event, const String:name[], bool:dontBroadcast)
97+
			SetClientVision(i, 0);
98
		}
99-
	RoundWin = 1;
99+
100
}
101
102
//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
103
//* Fires after OnMapStart when all configs are executed.
104-
	ShowFov[client] = false;
104+
public OnConfigsExecuted()
105
{
106
	if(g_bLateLoad)
107-
public Action:CmdFovStrange(client, args) {
107+
108-
	if(RoundWin == 1)
108+
		//Loop through valid clients, hook them.
109
		for(new i = 1; i <= MaxClients; i++)
110-
        if(args != 0 && args != 1 && args != 2) {
110+
111-
                ReplyToCommand(client, "[SM] Usage: sm_fov <target> [1/0]");
111+
			if(!IsClientInGame(i) || IsFakeClient(i))
112-
                return Plugin_Handled;
112+
				continue;
113-
        }
113+
				
114-
        if(args == 0) {
114+
			SDKHook(i, SDKHook_PostThink, OnPostThink);
115-
				if(ShowFov[client]) {
115+
116-
						ShowFov[client] = false;
116+
117-
				} else {
117+
		g_bLateLoad = false;
118-
						ShowFov[client] = true;
118+
119
}
120-
				ShowActivity2(client, "[SM] ", "Toggled StrangeFoV on self.");
120+
121-
				LogAction(client, client, "%L toggled StrangeFoV on themself", client);
121+
//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
122-
				return Plugin_Handled;
122+
//* Fires at the start of a new map, or after the plugin has been loaded.
123-
        }
123+
124-
        if(!CheckCommandAccess(client, "StrangeFoVOther", ADMFLAG_GENERIC)) {
124+
125-
                ReplyToCommand(client, "[SM] Usage: sm_fov");
125+
	//Set the end of the round to False.
126-
                return Plugin_Handled;
126+
	g_bEnding = false;
127-
        }
127+
128-
        if(args == 1) {
128+
129-
                decl String:target_name[MAX_NAME_LENGTH];
129+
//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
130-
                new target_list[MAXPLAYERS];
130+
//* Fires at the end of the map, after everyone has disconnected but before map changes.
131-
                new target_count;
131+
132-
                new bool:tn_is_ml;
132+
133-
                decl String:arg1[MAX_NAME_LENGTH];
133+
	//Set the end of the round to True.
134-
                GetCmdArg(1, arg1, sizeof(arg1));
134+
	g_bEnding = true;
135-
                if((target_count = ProcessTargetString(arg1, client, target_list, MAXPLAYERS, COMMAND_FILTER_NO_BOTS, target_name, sizeof(target_name), tn_is_ml)) <= 0) {
135+
136-
                        ReplyToTargetError(client, target_count);
136+
137-
                        return Plugin_Handled;
137+
//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
138-
                }
138+
//* Fires when a client physically disconnects or when the map is changing.
139-
                for(new i = 0; i < target_count; i++) {
139+
140-
                        if(ShowFov[target_list[i]]) {
140+
141-
                                ShowFov[target_list[i]] = false;
141+
	//Ignore if it wasn't a valid client (rare).
142-
                        } else {
142+
	if(!IsClientInGame(client))
143-
                                ShowFov[target_list[i]] = true;
143+
144-
                        }
144+
145-
                        LogAction(client, target_list[i], "%L toggled StrangeFoV on %L", client, target_list[i]);
145+
	//Reset data back to defaults for next client.
146-
                }
146+
	g_bActiveVision[client] = false;
147-
                ShowActivity2(client, "[SM] ", "Toggled StrangeFoV on %s.", target_name);
147+
	g_bForcedVision[client] = false;
148-
                return Plugin_Handled;
148+
149-
        }
149+
150-
        if(args == 2) {
150+
//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
151-
                decl String:target_name[MAX_NAME_LENGTH];
151+
//* Fires when a client is officially in-game and is a valid target.
152-
                new target_list[MAXPLAYERS];
152+
153-
                new target_count;
153+
154-
                new bool:tn_is_ml;
154+
	//Ignore if it wasn't a valid client (rare).
155-
                decl String:arg1[MAX_NAME_LENGTH], String:arg2[4];
155+
	if(!IsClientInGame(client))
156-
                GetCmdArg(1, arg1, sizeof(arg1));
156+
157-
                GetCmdArg(2, arg2, sizeof(arg2));
157+
158-
                new iState = StringToInt(arg2);
158+
	g_iCurrentVision[client] = cDefaultVision;
159-
                if(iState != 0 && iState != 1) {
159+
160-
                        ReplyToCommand(client, "[SM] Usage: sm_fov <target> [1/0]");
160+
161-
                        return Plugin_Handled;
161+
162-
                }
162+
//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
163-
                new bool:bState = false;
163+
//* SDKHook_PostThink CallBack
164-
                if(iState == 1) {
164+
165-
					bState = true;
165+
166-
                }
166+
	//Ignore if ending, their vision is disabled, they're in the process of disconnecting, or dying.
167-
                decl String:sState[8];
167+
	if(g_bEnding || !g_bActiveVision[client] || !IsClientInGame(client) || !IsPlayerAlive(client))
168-
                if(bState) {
168+
169-
                        strcopy(sState, sizeof(sState), "on");
169+
170-
                } else {
170+
	//If their current vision is negative, don't use that value!
171-
                        strcopy(sState, sizeof(sState), "off");
171+
	new iVision = g_iCurrentVision[client];
172-
                }
172+
	if(iVision < 0)
173-
                if((target_count = ProcessTargetString(arg1, client, target_list, MAXPLAYERS, COMMAND_FILTER_NO_BOTS, target_name, sizeof(target_name), tn_is_ml)) <= 0) {
173+
174-
                        ReplyToTargetError(client, target_count);
174+
		iVision *= -1;
175-
                        return Plugin_Handled;
175+
176-
                }
176+
177-
                for(new i = 0; i < target_count; i++) {
177+
	PrintHintText(client, "%d %d", g_iCurrentVision[client], iVision);
178-
                        ShowFov[target_list[i]] = bState;
178+
179-
                        LogAction(client, target_list[i], "%L set StrangeFoV on %L %s", client, target_list[i], sState);
179+
	//Apply the FoV.
180-
                }
180+
	SetEntProp(client, Prop_Send, "m_iFOV", iVision);
181-
                ShowActivity2(client, "[SM] ", "Set StrangeFoV on %s %s", target_name, sState);
181+
182-
                return Plugin_Handled;
182+
	//Determine FoV order
183-
        }
183+
	switch(GetConVarInt(h_Mode))
184-
        ReplyToCommand(client, "[SM] An unknown error occurred.");
184+
185
		case 1:
186
		{
187
			//If the client is at the upper bounds, reverse.
188
			if(iVision >= GetConVarInt(h_MaxValue))
189
			{
190
				//If their vision is 170, set it to -170 so that it counts down.
191-
public Action:Command_reload(client, args)
191+
				g_iCurrentVision[client] *= -1;
192
			}
193-
	sfovmode = GetConVarInt(h_Mode);
193+
194-
	Max = GetConVarInt(h_MaxValue);
194+
			//If the client is at the lower bounds, reverse.
195-
	Min = GetConVarInt(h_MinValue);
195+
			if(iVision <= GetConVarInt(h_MinValue))
196-
	ReplyToCommand(client, "[SM] Reloaded sFoV successfully")
196+
			{
197
				//If their vision is -20, set it to 20 so that it counts up
198
				g_iCurrentVision[client] *= -1;
199
			}
200
		}
201
		case 2:
202
		{
203
			if(g_iCurrentVision[client] >= GetConVarInt(h_MaxValue))
204-
public OnGameFrame()
204+
			{
205
				g_iCurrentVision[client] = GetConVarInt(h_MinValue);
206-
	if(sfovmode == 1)
206+
			}
207
		}
208-
		if(TheValue > Max)
208+
209
210-
			Adding = -1;
210+
	//Increment their current FoV by one every frame.
211
	g_iCurrentVision[client] += 1;
212-
		if(TheValue < Min)
212+
213
214-
			Adding = 1;
214+
//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
215
//* Fires at the end of Team Play or Arena. (Can't Confirm)
216-
		TheValue += Adding;
216+
public Action:Event_OnRoundEnd(Handle:event, const String:name[], bool:dontBroadcast)
217
{
218-
	if(sfovmode == 2)
218+
	//Set the end of the round to True.
219
	g_bEnding = true;
220-
		Adding = 1;
220+
221-
		if(TheValue > 180)
221+
	//Loop through all active players in-game.
222
	for (new i = 1; i < MaxClients; i++)
223-
			TheValue = 0;
223+
224
		if(!IsClientInGame(i) || IsFakeClient(i))
225-
		TheValue += Adding;
225+
			continue;
226-
	}	
226+
227
		//Disable any active effects, reset their vision.
228
		if(g_bActiveVision[i])
229-
/*public Action:OnPlayerRunCmd(client, &buttons, &impulse, Float:vel[3], Float:angles[3], &weapon)
229+
230
			SetClientVision(i, 0);
231-
	if (buttons & IN_ATTACK2 && sfov_check[client] == false)
231+
232-
    {
232+
233-
		sfov_on[client] = true;
233+
234
235-
}*/
235+
//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
236
//* Fires at the start of Team Play or Arena. (Can't Confirm)
237
public Action:Event_OnRoundStart(Handle:event, const String:name[], bool:dontBroadcast)
238-
	sfov_check[client] = !sfov_check[client];
238+
239-
	if(GetEntProp(client, Prop_Send, "m_iFOV") == 90 && sfov_check[client] == false)
239+
	//Set the end of the round to false.
240
	g_bEnding = false;
241-
		sfov_on[client] = false;
241+
242
243
//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
244
//* Fires on connection as well as every time a player spawns.
245-
		sfov_on[client] = true;
245+
public Action:Event_OnPlayerSpawn(Handle:event, const String:name[], bool:dontBroadcast)
246
{
247-
	if(GetEntProp(client, Prop_Send, "m_iFOV") == 90 && sfov_check[client] == true)
247+
	//Get the client from the event.
248
	new client = GetClientOfUserId(GetEventInt(event, "userid"));
249-
		sfov_check[client] = !sfov_check[client];
249+
	if(!client || !IsClientInGame(client))
250
	{
251
		return Plugin_Continue;
252
	}
253
254
	//Ignore any spawning attempts while the player is not alive (i.e. connecting)
255-
	if(IsClientInGame(client) && IsPlayerAlive(client) && sfov_on[client] == false)
255+
	if(!IsPlayerAlive(client))
256
	{
257-
		if(ShowFov[client])
257+
		return Plugin_Continue;
258
	}
259-
			SetEntProp(client, Prop_Send, "m_iFOV", TheValue);
259+
260
	//Re-apply the FoV effect if the client has had their state enabled.
261
	if(g_bForcedVision[client])
262
	{
263-
			SetEntProp(client, Prop_Send, "m_iFOV", 90);
263+
		SetClientVision(client, g_iCurrentVision[client]);
264
	}
265
266-
	if(IsClientInGame(client) && !IsPlayerAlive(client))
266+
	return Plugin_Continue;
267
}
268-
		if(ShowFov[client])
268+
269
//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
270-
			ShowFov[client] = !ShowFov[client];
270+
//* Fires whenever a player dies in-game.
271-
			PrintToChat(client, "");
271+
public Action:Event_OnPlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
272-
			SetEntProp(client, Prop_Send, "m_iFOV", 90);
272+
273
	//Get the client from the event.
274
	new client = GetClientOfUserId(GetEventInt(event, "userid"));
275
	if(!client || !IsClientInGame(client))
276
	{
277
		return Plugin_Continue;
278
	}
279
280
	//Reset the client's FoV if they had an active effect & disable it.
281
	if(g_bActiveVision[client])
282
	{
283
		SetClientVision(client, 0);
284
	}
285
286
	return Plugin_Continue;
287
}
288
289
//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
290
//* Fires whenever a player changes their team.
291
public Action:Event_OnPlayerTeam(Handle:event, const String:name[], bool:dontBroadcast)
292
{
293
	//Get the client from the event.
294
	new client = GetClientOfUserId(GetEventInt(event, "userid"));
295
	if(!client || !IsClientInGame(client))
296
	{
297
		return Plugin_Continue;
298
	}
299-
			ADMFLAG_SLAY);	
299+
300
	//Reset the client's FoV if they join Spectate.
301
	if(GetEventInt(event, "team") == _:TFTeam_Spectator)
302
	{
303
		SetClientVision(client, 0);
304-
PerformFoV(client, target)
304+
305
	//Re-apply the FoV effect on team change just to be safe.
306-
	if(ShowFov[target] == true)
306+
	else if(g_bForcedVision[client])
307
	{
308-
		LogAction(client, target, "\"%L\" set a Strange Field of View on \"%L\"", client, target);
308+
		SetClientVision(client, g_iCurrentVision[client]);
309-
		ShowFov[target] = false;
309+
310-
	} 
310+
311-
	else 
311+
	return Plugin_Continue;
312
}
313-
		ShowFov[target] = true;
313+
314-
		LogAction(client, target, "\"%L\" removed the Strange Field of View from \"%L\"", client, target);
314+
//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
315
//* Simple stock for modifying the client's FoV.
316
stock SetClientVision(client, range)
317
{
318
	if(range == 0)
319
	{
320
		g_bActiveVision[client] = false;
321
		SetEntProp(client, Prop_Send, "m_iFOV", cDefaultVision);
322
	}
323
	else
324
	{
325
		g_bActiveVision[client] = true;
326-
public AdminMenu_FoV(Handle:topmenu, 
326+
		SetEntProp(client, Prop_Send, "m_iFOV", range);
327-
					  TopMenuAction:action,
327+
328-
					  TopMenuObject:object_id,
328+
329-
					  param,
329+
330-
					  String:buffer[],
330+
//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
331-
					  maxlength)
331+
//* CallBack for the vision command.
332
public Action:Command_Vision(client, args)
333-
	if (action == TopMenuAction_DisplayOption)
333+
334
	//Ignore the command if it's used during the end of the round.
335-
		Format(buffer, maxlength, "%T", "sFoV player", param);
335+
	if(g_bEnding)
336
	{
337-
	else if (action == TopMenuAction_SelectOption)
337+
		ReplyToCommand(client, "[SM] This command can only be used during the round!");
338
		return Plugin_Handled;
339-
		DisplayFoVMenu(param);
339+
340
341
	if(!args)
342
	{
343
		//Console has no reason to toggle effects, nor do invalid clients.
344
		if(!client || GetClientTeam(client) <= _:TFTeam_Spectator || !IsPlayerAlive(client))
345-
	new Handle:menu = CreateMenu(MenuHandler_FoV);
345+
346
			ReplyToCommand(client, "[SM] This command cannot be toggled on invalid clients!");
347-
	decl String:title[100];
347+
			return Plugin_Handled;
348-
	Format(title, sizeof(title), "%T:", "sFoV player", client);
348+
349-
	SetMenuTitle(menu, title);
349+
350-
	SetMenuExitBackButton(menu, true);
350+
		//Check to see if the client has self-access.
351
		if(client && !CheckCommandAccess(client, "StrangeFoVSelf", ADMFLAG_GENERIC))
352-
	AddTargetsToMenu(menu, client, true, true);
352+
353
			ReplyToCommand(client, "[SM] Usage: sm_fov");
354-
	DisplayMenu(menu, client, MENU_TIME_FOREVER);
354+
			return Plugin_Handled;
355
		}
356
357
		g_bForcedVision[client] = !g_bForcedVision[client];
358
		ShowActivity2(client, "[SM] ", "Set his/her StrangeFoV state to %s", g_bForcedVision[client] ? "on" : "off");
359-
	if (action == MenuAction_End)
359+
		LogAction(client, client, "%L set his/her StrangeFoV state to %s", client, g_bForcedVision[client] ? "on" : "off");
360
		if(g_bForcedVision[client])
361-
		CloseHandle(menu);
361+
			SetClientVision(client, g_iCurrentVision[client]);
362
		else
363-
	else if (action == MenuAction_Cancel)
363+
			SetClientVision(client, 0);
364
		
365-
		if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
365+
		return Plugin_Handled;
366
	}
367-
			DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
367+
368
	if(args)
369
	{
370-
	else if (action == MenuAction_Select)
370+
		//Notify on the event of invalid.
371
		if(args > 2)
372-
		decl String:info[32];
372+
373-
		new userid, target;
373+
			ReplyToCommand(client, "[SM] This command cannot be toggled on invalid clients!");
374
			return Plugin_Handled;
375-
		GetMenuItem(menu, param2, info, sizeof(info));
375+
376-
		userid = StringToInt(info);
376+
377
		//Check to see if the client has other-access.
378-
		if ((target = GetClientOfUserId(userid)) == 0)
378+
		if(client && !CheckCommandAccess(client, "StrangeFoVOther", ADMFLAG_GENERIC))
379
		{
380-
			PrintToChat(param1, "[SM] %t", "Player no longer available");
380+
			ReplyToCommand(client, "[SM] Usage: sm_fov <target> [optional: 0|1]");
381
			return Plugin_Handled;
382-
		else if (!CanUserTarget(param1, target))
382+
383
384-
			PrintToChat(param1, "[SM] %t", "Unable to target");
384+
		//Declare necessary information to process command; grab argument string.
385
		decl iBreak, String:sText[192], String:sPattern[64], String:sBuffer[64];
386
		new iTargets[MAXPLAYERS + 1], bool:bTemp, bool:bState;
387
		GetCmdArgString(sText, sizeof(sText));
388-
			new String:name[32];
388+
389-
			GetClientName(target, name, sizeof(name));
389+
		//Store pattern, check to see if there's an additional argument.
390
		iBreak = BreakString(sText, sPattern, sizeof(sPattern));
391-
			PerformFoV(param1, target);
391+
		if(iBreak != -1)
392-
			ShowActivity2(param1, "[SM] ", "%t", "Toggled Strange Field of View on target", "_s", name);
392+
393
			iBreak += BreakString(sText[iBreak], sBuffer, sizeof(sBuffer));
394
			bState = bool:StringToInt(sBuffer);
395-
		/* Re-draw the menu if they're still valid */
395+
396-
		if (IsClientInGame(param1) && !IsClientInKickQueue(param1))
396+
397
		//Only let the command target non-bots currently in-game.
398-
			DisplayFoVMenu(param1);
398+
		new iCount = ProcessTargetString(sPattern, client, iTargets, sizeof(iTargets), COMMAND_FILTER_NO_BOTS|COMMAND_FILTER_CONNECTED, sBuffer, sizeof(sBuffer), bTemp);
399
		if(iCount)
400
		{
401
			//Loop through all clients currently in-game.
402
			for (new i = 0; i < iCount; i++)
403
			{
404
				if(!IsClientInGame(iTargets[i]))
405
				{
406
					continue;
407
				}
408
409
				//BreakString returns -1 if there was no string to break, thus 1 parameter.
410
				if(iBreak == -1)
411
				{
412
					//No parameters, so toggle the client's current state.
413
					if(g_bForcedVision[iTargets[i]])
414
					{
415
						SetClientVision(iTargets[i], 0);
416
					}
417
					else
418
					{
419
						SetClientVision(iTargets[i], g_iCurrentVision[iTargets[i]]);
420
					}
421
422
					g_bForcedVision[iTargets[i]] = !g_bForcedVision[iTargets[i]];
423
					LogAction(client, iTargets[i], "%L set StrangeFoV on %L to %s", client, iTargets[i], g_bForcedVision[iTargets[i]] ? "on" : "off");
424
					ShowActivity2(client, "[SM] ", "Set StrangeFoV on %N to %s", iTargets[i], g_bForcedVision[iTargets[i]] ? "on" : "off");
425
				}
426
				else
427
				{
428
					//Second argument was specified, force whatever values are desired.
429
					if(bState)
430
					{
431
						//It's being enabled, ignore anyone that already has it.
432
						if(g_bForcedVision[iTargets[i]])
433
						{
434
							if(!g_bActiveVision[iTargets[i]])
435
								SetClientVision(iTargets[i], g_iCurrentVision[iTargets[i]]);
436
						
437
							continue;
438
						}
439
440
						g_bForcedVision[iTargets[i]] = true;
441
						SetClientVision(iTargets[i], g_iCurrentVision[iTargets[i]]);
442
						LogAction(client, iTargets[i], "%L set StrangeFoV on %L to %s", client, iTargets[i], g_bForcedVision[iTargets[i]] ? "on" : "off");
443
						ShowActivity2(client, "[SM] ", "Set StrangeFoV on %N to %s", iTargets[i], g_bForcedVision[iTargets[i]] ? "on" : "off");
444
					}
445
					else
446
					{
447
						//It's being disabled, ignore anyone that already doesn't have it.
448
						if(!g_bForcedVision[iTargets[i]])
449
						{
450
							if(g_bActiveVision[iTargets[i]])
451
								SetClientVision(iTargets[i], 0);
452
						
453
							continue;
454
						}
455
456
						g_bForcedVision[iTargets[i]] = false;
457
						SetClientVision(iTargets[i], 0);
458
						LogAction(client, iTargets[i], "%L set StrangeFoV on %L to %s", client, iTargets[i], g_bForcedVision[iTargets[i]] ? "on" : "off");
459
						ShowActivity2(client, "[SM] ", "Set StrangeFoV on %N to %s", iTargets[i], g_bForcedVision[iTargets[i]] ? "on" : "off");
460
					}
461
				}
462
			}
463
		}
464
	}
465
466
	return Plugin_Handled;
467
}
468
469
public Action:attack2CallBack(client, const String:command[], argc)
470
{
471
	g_bForcedVision[client] = !g_bForcedVision[client];
472
	if(GetEntProp(client, Prop_Send, "m_iFOV") == 90 && g_bForcedVision[client] == false)
473
	{
474
		g_bZoomVision[client] = false;
475
	}
476
	else
477
	{
478
		g_bZoomVision[client] = true;
479
	}
480
	if(GetEntProp(client, Prop_Send, "m_iFOV") == 90 && g_bForcedVision[client] == true)
481
	{
482
		g_bForcedVision[client] = !g_bForcedVision[client];
483
	}
484
}
485
486
public OnAdminMenuReady(Handle:topmenu)
487
{
488
	/* Block us from being called twice */
489
	if (topmenu == hTopMenu)
490
	{
491
		return;
492
	}
493
494
	/* Save the Handle */
495
	hTopMenu = topmenu;
496
497
	/* Build the "Player Commands" category */
498
	new TopMenuObject:player_commands = FindTopMenuCategory(hTopMenu, ADMINMENU_PLAYERCOMMANDS);
499
500
	if (player_commands != INVALID_TOPMENUOBJECT)
501
	{
502
		AddToTopMenu(hTopMenu,
503
			"sm_fov",
504
			TopMenuObject_Item,
505
			AdminMenu_FoV,
506
			player_commands,
507
			"sm_fov",
508
			ADMFLAG_SLAY);
509
	}
510
}
511
512
public OnLibraryRemoved(const String:name[])
513
{
514
	if (strcmp(name, "adminmenu") == 0)
515
	{
516
		hTopMenu = INVALID_HANDLE;
517
	}
518
}
519
520
//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
521
//* AdminMenu Callback - Only re-written cause of OCD.
522
public AdminMenu_FoV(Handle:topmenu, TopMenuAction:action, TopMenuObject:object_id, param, String:buffer[], maxlength)
523
{
524
	switch(action)
525
	{
526
		case TopMenuAction_DisplayOption:
527
		{
528
			Format(buffer, maxlength, "Set Strange FoV", param);
529
			//Format(buffer, maxlength, "%T", "sFoV player", param);
530
		}
531
		case TopMenuAction_SelectOption:
532
		{
533
			DisplayFoVMenu(param);
534
		}
535
	}
536
}
537
538
DisplayFoVMenu(client)
539
{
540
	new Handle:hMenu = CreateMenu(MenuHandler_FoV);
541
542
	decl String:sBuffer[128], String:sDisplay[64], String:sUser[4];
543
	Format(sBuffer, sizeof(sBuffer), "Select Player:", client);
544
	//Format(sBuffer, sizeof(sBuffer), "%T:", "sFoV player", client);
545
	SetMenuTitle(hMenu, sBuffer);
546
	SetMenuExitBackButton(hMenu, true);
547
548
	//These should be translations, but for now, just graphics.
549
	new String:sActive[] = "[*]";
550
	new String:sDisabled[] = "[  ]";
551
	
552
	//Loop through all active clients. Ignore bots and players the admin can't target.
553
	// We're making our own loop instad of using AddTargetsToMenu to display the state
554
	//  of the effect prior to toggling.
555
	
556
	for(new i = 1; i <= MaxClients; i++)
557
	{
558
		if(!IsClientInGame(i) || IsFakeClient(i) || (client != i && !CanUserTarget(client, i)))
559
			continue;
560
		
561
		//Format the string so it shows who has it enabled/disabled.
562
		//1) [ ] Panda
563
		//2) [*] Benja
564
		Format(sDisplay, sizeof(sDisplay), "%s %N", g_bForcedVision[i] ? sActive : sDisabled, i);
565
		
566
		//Pass the userid along so it's available.
567
		IntToString(GetClientUserId(i), sUser, sizeof(sUser));
568
		AddMenuItem(hMenu, sUser, sDisplay);
569
	}
570
571
	DisplayMenu(hMenu, client, MENU_TIME_FOREVER);
572
}
573
574
//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
575
//* Menu Callback - Only re-written cause of OCD.
576
public MenuHandler_FoV(Handle:menu, MenuAction:action, param1, param2)
577
{
578
	switch(action)
579
	{
580
		case MenuAction_End:
581
		{
582
			CloseHandle(menu);
583
		}
584
		case MenuAction_Cancel:
585
		{
586
			if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
587
			{
588
				DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
589
			}
590
		}
591
		case MenuAction_Select:
592
		{
593
			decl String:info[32];
594
			GetMenuItem(menu, param2, info, sizeof(info));
595
596
			new userid = StringToInt(info);
597
			new target = GetClientOfUserId(userid);
598
			
599
			if(!target)
600
			{
601
				PrintToChat(param1, "[SM] The player you were targeting is no longer available.");
602
				//PrintToChat(param1, "[SM] %t", "Player no longer available");
603
			}
604
			else if(!CanUserTarget(param1, target))
605
			{
606
				PrintToChat(param1, "[SM] You are unable to target %N!", target);
607
				//PrintToChat(param1, "[SM] %t", "Unable to target");
608
			}
609
			else
610
			{
611
				//Toggle the effect based on the current state.
612
				if(g_bForcedVision[target])
613
					SetClientVision(target, 0);
614
				else
615
					SetClientVision(target, g_iCurrentVision[target]);
616
617
				g_bForcedVision[target] = !g_bForcedVision[target];
618
				LogAction(param1, target, "%L set StrangeFoV on %L to %s", param1, target, g_bForcedVision[target] ? "on" : "off");
619
				ShowActivity2(param1, "[SM] ", "Set StrangeFoV on %N to %s", target, g_bForcedVision[target] ? "on" : "off");
620
			}
621
622
			//Display the menu back to the admin, if possible.
623
			if (IsClientInGame(param1) && !IsClientInKickQueue(param1))
624
			{
625
				DisplayFoVMenu(param1);
626
			}
627
		}
628
	}
629
}