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 | } |