//So, we need to create in the top of gamemode this variable
new Spectating[MAX_PLAYERS]; //Simple variable to define the spected ID for the spectator ID.
//Using this variable:
//Use Spectating[playerid] = -1; To set a none spected ID for the spectador ID.
//Use Spectating[playerid] = spectedid; To set the ID of the spected player.
//Now, we need to create or use an existing commands to spec a player.
/spec - To spectate another player.
/specoff - To stop spectating.
//We gonna use this folowing callbacks and functions to make the system.
OnPlayerConnect(); - To set Spectating[playerid] = -1;(Not spectating)
OnPlayerStreamOut(); - Called when the player Streamed out for another player.
OnPlayerStateChange(); - Called when the player change your state(Die, Spawn, Enter a vehicle, Exit a vehicle, etc).
TogglePlayerSpectating(); - To Toggle on or Toggle off the spectating mode.
PlayerSpectateVehicle(); - To set spectating mode if the spectedid is in a vehicle.
PlayerSpectatePlayer(); - To set spectating mode if the spectedid is on foot.
//This callback we gonna create too.
UpdateSpectatingStatus(); - Will be called when the player change the state or stream out for a player.
//You make it too in OnPlayerDisconnect(playerid) and OnPlayerSpawn(playerid) or another like want.
public OnPlayerConnect(playerid)
{
Spectating[playerid] = -1;
//Setting this variable to -1 we toggle non-spectaing ID to the spectador ID.
return 1;
}
//Here you can use the or make like you want.
//The tools and functions to execute the commands are old(but works too).
//This is only a example to make the Update Spectating Status work.
public OnPlayerCommandText(playerid, cmdtext[])
{
new cmd[256],tmp[256],giveplayerid,idx;
cmd = strtok(cmdtext, idx);
if(strcmp(cmd, "/spec", true) == 0)
{
tmp = strtok(cmdtext, idx);//Here we gonna set the spected ID, example: /spec 5
giveplayerid = ReturnUser(tmp);//Getting the spected ID to the variable "giveplayerid".
if(IsPlayerConnected(giveplayerid))
{
//Getting the virtual world and interior of the spected ID and setting it to the spectator ID.
SetPlayerVirtualWorld(playerid,GetPlayerVirtualWorld(giveplayerid));
SetPlayerInterior(playerid,GetPlayerInterior(giveplayerid));
//Now we gonna set the spected ID(giveplayerid) to the spectator ID(playerid).
Spectating[playerid] = giveplayerid;
//This function will start the spectating mode for the spectator ID.
TogglePlayerSpectating(playerid, 1);
//Define between PlayerSpectateVehicle(); - (if spected ID is in a vehicle) or PlayerSpectatePlayer(); - (if spected ID is not in a vehicle).
if(IsPlayerInAnyVehicle(giveplayerid)) PlayerSpectateVehicle(playerid, GetPlayerVehicleID(giveplayerid), SPECTATE_MODE_NORMAL);
else PlayerSpectatePlayer(playerid, giveplayerid, SPECTATE_MODE_NORMAL);
}
else return SendClientMessage(playerid, -1, "Warning: This player is not connected!");
return 1;
}
if(strcmp(cmd, "/specoff", true) == 0)
{
if(IsPlayerConnected(playerid))
{
//Here we gonna set a default virtual world and interior to the spectator ID.
SetPlayerVirtualWorld(playerid,0);
SetPlayerInterior(playerid,0);
//Setting a none spected ID(important to stop the Updating system).
Spectating[playerid] = -1;
//Now the spectating mode is off.
TogglePlayerSpectating(playerid, 1);
}
return 1;
}
return 0;
}
public OnPlayerStreamOut(playerid, forplayerid)
{
//When the spected ID(playerid) teleport, change the virtual world or interior, go away, etc...
//"forplayerid" is the spectator ID in this case.
if(IsPlayerConnected(forplayerid))
{
if(Spectating[forplayerid] == playerid)//Check if "forplayerid" is spectating the playerid.
{
//This new callback will check the status of the spected ID and update it to the spectator ID.
UpdateSpectatingStatus(forplayerid, playerid);
}
}
return 1;
}
public OnPlayerStateChange(playerid, newstate, oldstate)
{
//If the spected ID(playerid) enter/exit the vehicle, spawn, etc...
for(new i = 0; i < GetMaxPlayers(); i++)
{
if(IsPlayerConnected(i))
{
if(Spectating[i] == playerid)//Check if someone is spectating him.
{
//This new callback will check the status of the spected ID(playerid) and update it to the spectator ID(i).
UpdateSpectatingStatus(i, playerid);
}
}
}
return 1;
}
stock UpdateSpectatingStatus(spectatorid, spectedid);
{
//If the spectator ID is really spectating the spected ID...
if(Spectating[spectatorid] == spectedid)
{
//This warnings you can use or not...
if(GetPlayerState(spectedid) == PLAYER_STATE_WASTED) return GameTextForPlayer(spectatorid, "~r~Target wasted!", 5000, 3);
if(GetPlayerState(spectedid) == PLAYER_STATE_SPECTATING) return GameTextForPlayer(spectatorid, "~r~Target in spectating mode!", 5000, 3);
if(!IsPlayerConnected(spectedid)) return GameTextForPlayer(spectatorid, "~r~Target disconnected!", 5000, 3);
//Again setting the virtual world and interior for the spectator ID.
SetPlayerVirtualWorld(spectatorid,GetPlayerVirtualWorld(spectedid));
SetPlayerInterior(spectatorid,GetPlayerInterior(spectedid));
//Put the spectator ID in the spectating mode.
TogglePlayerSpectating(spectatorid, 1);
if(IsPlayerInAnyVehicle(spectedid)) PlayerSpectateVehicle(spectatorid, GetPlayerVehicleID(spectedid), SPECTATE_MODE_NORMAL);
else PlayerSpectatePlayer(spectatorid, spectedid, SPECTATE_MODE_NORMAL);
}
return 1;
}
//==============================================================================//
// Update Spectating Status
// Creator: JR_Junior
// Date: February, 19, 2015
//
//==============================================================================//
#include <a_samp>
new Spectating[MAX_PLAYERS];
public OnPlayerConnect(playerid)
{
Spectating[playerid] = -1;
return 1;
}
public OnPlayerCommandText(playerid, cmdtext[])
{
new cmd[256],tmp[256],giveplayerid,idx;
cmd = strtok(cmdtext, idx);
if(strcmp(cmd, "/spec", true) == 0)
{
tmp = strtok(cmdtext, idx);
giveplayerid = ReturnUser(tmp);
if(IsPlayerConnected(giveplayerid))
{
SetPlayerVirtualWorld(playerid,GetPlayerVirtualWorld(giveplayerid));
SetPlayerInterior(playerid,GetPlayerInterior(giveplayerid));
Spectating[playerid] = giveplayerid;
TogglePlayerSpectating(playerid, 1);
if(IsPlayerInAnyVehicle(giveplayerid)) PlayerSpectateVehicle(playerid, GetPlayerVehicleID(giveplayerid), SPECTATE_MODE_NORMAL);
else PlayerSpectatePlayer(playerid, giveplayerid, SPECTATE_MODE_NORMAL);
}
else return SendClientMessage(playerid, -1, "Warning: This player is not connected!");
return 1;
}
if(strcmp(cmd, "/specoff", true) == 0)
{
if(IsPlayerConnected(playerid))
{
SetPlayerVirtualWorld(playerid,0);
SetPlayerInterior(playerid,0);
Spectating[playerid] = -1;
TogglePlayerSpectating(playerid, 1);
}
return 1;
}
return 0;
}
public OnPlayerStreamOut(playerid, forplayerid)
{
if(IsPlayerConnected(forplayerid))
{
if(Spectating[forplayerid] == playerid)
{
UpdateSpectatingStatus(forplayerid, playerid);
}
}
return 1;
}
public OnPlayerStateChange(playerid, newstate, oldstate)
{
for(new i = 0; i < GetMaxPlayers(); i++)
{
if(IsPlayerConnected(i))
{
if(Spectating[i] == playerid)
{
UpdateSpectatingStatus(i, playerid);
}
}
}
return 1;
}
stock UpdateSpectatingStatus(spectatorid, spectedid);
{
if(Spectating[spectatorid] == spectedid)
{
if(GetPlayerState(spectedid) == PLAYER_STATE_WASTED) return GameTextForPlayer(spectatorid, "~r~Target wasted!", 5000, 3);
if(GetPlayerState(spectedid) == PLAYER_STATE_SPECTATING) return GameTextForPlayer(spectatorid, "~r~Target in spectating mode!", 5000, 3);
if(!IsPlayerConnected(spectedid)) return GameTextForPlayer(spectatorid, "~r~Target disconnected!", 5000, 3);
SetPlayerVirtualWorld(spectatorid,GetPlayerVirtualWorld(spectedid));
SetPlayerInterior(spectatorid,GetPlayerInterior(spectedid));
TogglePlayerSpectating(spectatorid, 1);
if(IsPlayerInAnyVehicle(spectedid)) PlayerSpectateVehicle(spectatorid, GetPlayerVehicleID(spectedid), SPECTATE_MODE_NORMAL);
else PlayerSpectatePlayer(spectatorid, spectedid, SPECTATE_MODE_NORMAL);
}
return 1;
}
//If you dont have this following funtions in yours includes or game mode, you will need it to test this script.
ReturnUser(text[])
{
new pos = 0;
while (text[pos] < 0x21)
{
if (text[pos] == 0) return INVALID_PLAYER_ID;
pos++;
}
new userid = INVALID_PLAYER_ID;
if (IsNumeric(text[pos]))
{
userid = strval(text[pos]);
if(userid >=0 && userid < MAX_PLAYERS)
{
if(!IsPlayerConnected(userid)) userid = INVALID_PLAYER_ID;
else return userid;
}
}
new len = strlen(text[pos]);
new count = 0;
new name[MAX_PLAYER_NAME];
for (new i = 0; i < MAX_PLAYERS; i++)
{
if(IsPlayerConnected(i))
{
GetPlayerName(i, name, sizeof (name));
if (strcmp(name, text[pos], true, len) == 0)
{
if (len == strlen(name)) return i;
else count++,userid = i;
}
}
}
if(count != 1) userid = INVALID_PLAYER_ID;
return userid;
}
IsNumeric(const string[])
{
for (new i = 0, j = strlen(string); i < j; i++) if(string[i] > '9' || string[i] < '0') return 0;
return 1;
}
strtok(string[],&idx,seperator = ' ')
{
new ret[128], i = 0, len = strlen(string);
while(string[idx] == seperator && idx < len) idx++;
while(string[idx] != seperator && idx < len) ret[i] = string[idx],i++,idx++;
while(string[idx] == seperator && idx < len) idx++;
return ret;
}
You have explained absolutely nothing and you are using outdated tools.
I didn't even bother looking at the rest of the code. This is, just like many, a copy-paste topic. Post it as a filterscript in the right section instead of a poorly written tutorial. |
Meh, you didn't even explain anything here, you are just throwing out code at us.
Go to the filterscripts section if you want to create and share a script, in a tutorial you should explain to people how and why they need to do things. Also, you are using heavily outdated methods, such as strcmp in OnPlayerCommandText, and strtok. |
You're using outdated and slower methods. Even though the code is basic it still needs more explanation.
https://sampforum.blast.hk/showthread.php?tid=65567 |
UpdateSpectatingStatus
public OnPlayerCommandText(playerid, cmdtext[])
strcmp
strtok
Code:
UpdateSpectatingStatus |
Code:
UpdateSpectatingStatus Code:
public OnPlayerCommandText(playerid, cmdtext[]) Code:
strcmp Code:
strtok |
FuncName(parameters)
stock FuncName(parameters)
new stock VariableName;
public FuncName(parameters)
Excel, "stock" and a function is 2 different things.
Stock will make the compiler ignore something if it's not used in your script, thereby also hiding warnings/errors, and not including it in your .amx file. Example of a normal function: pawn Code:
pawn Code:
pawn Code:
I believe that public functions can be called between filterscripts etc. by adding it like this: pawn Code:
|