diff --git a/Spectate/scripting/Spectate.sp b/Spectate/scripting/Spectate.sp new file mode 100644 index 00000000..74cb7406 --- /dev/null +++ b/Spectate/scripting/Spectate.sp @@ -0,0 +1,108 @@ +#pragma semicolon 1 + +#include +#include +#include + +#pragma newdecls required + +public Plugin myinfo = +{ + name = "Spectate", + description = "Adds a command to spectate specific players and removes broken spectate mode.", + author = "Obus + BotoX", + version = "1.0", + url = "" +} + +// Spectator Movement modes (from smlib) +enum Obs_Mode +{ + OBS_MODE_NONE = 0, // not in spectator mode + OBS_MODE_DEATHCAM, // special mode for death cam animation + OBS_MODE_FREEZECAM, // zooms to a target, and freeze-frames on them + OBS_MODE_FIXED, // view from a fixed camera position + OBS_MODE_IN_EYE, // follow a player in first person view + OBS_MODE_CHASE, // follow a player in third person view + OBS_MODE_POI, // PASSTIME point of interest - game objective, big fight, anything interesting; added in the middle of the enum due to tons of hard-coded "(StringToInt(sSpecMode)); + + // Skip broken OBS_MODE_POI + if (iObserverMode == OBS_MODE_POI) + { + ClientCommand(client, "cl_spec_mode %d", OBS_MODE_ROAMING); + if(IsClientInGame(client)) + SetEntProp(client, Prop_Send, "m_iObserverMode", OBS_MODE_ROAMING); + } +} + +public Action Command_Spectate(int client, int argc) +{ + if (!client) + { + PrintToServer("[SM] Cannot use command from server console."); + return Plugin_Handled; + } + + if (!argc) + { + if (GetClientTeam(client) != CS_TEAM_SPECTATOR) + { + ForcePlayerSuicide(client); + ChangeClientTeam(client, CS_TEAM_SPECTATOR); + } + + return Plugin_Handled; + } + + char sTarget[MAX_TARGET_LENGTH]; + GetCmdArg(1, sTarget, sizeof(sTarget)); + + int iTarget; + if (!(iTarget = FindTarget(client, sTarget, false, false))) + return Plugin_Handled; + + if (!IsPlayerAlive(iTarget)) + { + ReplyToCommand(client, "[SM] %t", "Target must be alive"); + return Plugin_Handled; + } + + if (GetClientTeam(client) != CS_TEAM_SPECTATOR) + { + ForcePlayerSuicide(client); + ChangeClientTeam(client, CS_TEAM_SPECTATOR); + } + + SetEntPropEnt(client, Prop_Send, "m_hObserverTarget", iTarget); + + Obs_Mode iObserverMode = view_as(GetEntProp(client, Prop_Send, "m_iObserverMode")); + // If the client is currently in free roaming then switch them to first person view + if (iObserverMode == OBS_MODE_ROAMING) + { + SetEntProp(client, Prop_Send, "m_iObserverMode", OBS_MODE_IN_EYE); + ClientCommand(client, "cl_spec_mode %d", OBS_MODE_ROAMING); + } + + PrintToChat(client, "\x01[SM] Spectating \x04%N\x01.", iTarget); + + return Plugin_Handled; +}