Spec (TogglePlayerSpectating) Problem!
#1

Hello,

I'm using this /spec command in my server.

Код:
COMMAND:spectate(playerid, params[])
{
	if (PlayerInfo[playerid][pAdminlevel] > 0)
	{
	if (PlayerInfo[playerid][pSpawned] == 1)
	{
	new TargetID,string[256];
	new Float:X,Float:Y,Float:Z,Float:A,I,W,vehicleid;

	if(sscanf(params, "u", TargetID))
    {
	SendClientMessage(playerid, COLOR_ERROR, "USAGE: /spectate (Name/Id) - Enter A Valid Name/Id");
	return 1;
    }
    
    if(!IsPlayerConnected(TargetID) || TargetID == INVALID_PLAYER_ID)
	{
	SendClientMessage(playerid, COLOR_ERROR, "That Player Is Not Connected.");
	return 1;
	}

    if(IsPlayerNPC(TargetID))
	{
	SendClientMessage(playerid,COLOR_ERROR,"You Cannot Spectate a BOT.");
	return 1;
	}

	if (PlayerInfo[TargetID][pSpawned] == 0)
	{
	format(string, sizeof(string), "%s (%i) Has Not Spawned.",PlayerInfo[TargetID][pName],TargetID);
	SendClientMessage(playerid, COLOR_ERROR, string);
	return 1;
	}

    format(string, sizeof(string), "Spectating %s (%i).",PlayerInfo[TargetID][pName],TargetID);
    SendClientMessage(playerid,COLOR_ADMIN, string);

	if (PlayerInfo[playerid][pSpecID] == -1)
	{
	GetPlayerPos(playerid,X,Y,Z);
	GetPlayerFacingAngle(playerid,A);
	I = GetPlayerInterior(playerid);
	W = GetPlayerVirtualWorld(playerid);

	PlayerInfo[playerid][pSpecX] = X;
	PlayerInfo[playerid][pSpecY] = Y;
	PlayerInfo[playerid][pSpecZ] = Z;
	PlayerInfo[playerid][pSpecA] = A;
	PlayerInfo[playerid][pSpecI] = I;
	PlayerInfo[playerid][pSpecW] = W;
	}
	PlayerInfo[playerid][pSpecID] = TargetID;

	if (IsPlayerInAnyVehicle(TargetID)) {

	vehicleid = GetPlayerVehicleID(TargetID);

	TogglePlayerSpectating(playerid, 1);
	PlayerSpectateVehicle(playerid, vehicleid);

	SetPlayerInterior(playerid,GetPlayerInterior(TargetID));
	SetPlayerVirtualWorld(playerid,GetPlayerVirtualWorld(TargetID));
	}
	else
	{
	TogglePlayerSpectating(playerid, 1);
	PlayerSpectatePlayer(playerid, TargetID);

	SetPlayerInterior(playerid,GetPlayerInterior(TargetID));
	SetPlayerVirtualWorld(playerid,GetPlayerVirtualWorld(TargetID));
	}
	}else{
	SendClientMessage(playerid, COLOR_ERROR, "You Cannot Use This Command While You're Dead.");
    }
	}else{
	SendClientMessage(playerid, COLOR_ERROR, "Unknown Command! Type /cmds For Available Commands.");
	}
	return 1;
}
I can't see anything wrong in the code.

But sometimes, the spec mode gets off randomly?


When an admin is spectating some player, after few sec/mins the spec mode is off? why without /stopspec it shouldn't go off? but it does.

How can i fix this.
Reply
#2

Maybe your player which you spectating enter into interior?
Reply
#3

Yes, it gets stopped when a targetid enters a interior as well.

But even if the targetplayer doesn't enter, it gets stopped after random time.
Reply
#4

https://sampwiki.blast.hk/wiki/OnPlayerInteriorChange
https://sampwiki.blast.hk/wiki/OnPlayerStateChange

When a player changes interior and there are players spectate that player, change their interior as well.
When a player changes their state (on foot, in vehicle) and there are players spectate that player, re-spectate them (PlayerSpectatePlayer, PlayerSpectateVehicle).
When a player changes virtual world (hook SetPlayerVirtualWorld and call a new callback OnPlayerVirtualWorldChange when the VW changes) and there are players spectate that player, change their VW as well.
Reply
#5

So you mean, the admin which is spectating the player should do everything same as targetplayer

statechange, interior e.t.c?

So how i can do that? a lil help with coding?
Reply
#6

simply... use timer!

under OnGameModeInt( ... )
pawn Код:
SetTimerEx("OnPlayerSpectate", 1000, 1, "d", "d");
anywhere in script..
pawn Код:
forward OnPlayerSpectate();
pawn Код:
public OnPlayerSpectate()
{
    new vehicleid,specid;
    for (new i = 0; i < GetMaxPlayers(); i++)
    {
        if (IsPlayerConnected(i) && !IsPlayerNPC(i) && PlayerInfo[i][pSpecID] > -1)
        {
            specid = PlayerInfo[i][pSpecID];

            if (IsPlayerConnected(specid) && PlayerInfo[specid][pSpawned] == 1)
            {

                if (IsPlayerInAnyVehicle(specid))
                {
                    vehicleid = GetPlayerVehicleID(specid);
                    PlayerSpectateVehicle(i, vehicleid);
                    SetPlayerInterior(i,GetPlayerInterior(specid));
                    SetPlayerVirtualWorld(i,GetPlayerVirtualWorld(specid));
                }else{
                    PlayerSpectatePlayer(i, specid);
                    SetPlayerInterior(i,GetPlayerInterior(specid));
                    SetPlayerVirtualWorld(i,GetPlayerVirtualWorld(specid));
                }
            }
            else
            {
                TogglePlayerSpectating(i, 0);
            }
        }
    }
}
and you can further edit it as interior change i've given you example!

[EDIT]: or try this......
pawn Код:
public OnPlayerInteriorChange(playerid, newinteriorid, oldinteriorid)
{
    new specid;
    if (IsPlayerConnected(playerid) && !IsPlayerNPC(playerid) && PlayerInfo[playerid][pSpecID] > -1)
    {
        specid = PlayerInfo[playerid][pSpecID];

        if (IsPlayerConnected(specid) && PlayerInfo[specid][pSpawned] == 1)
        {
            if (GetPlayerInterior(playerid) != GetPlayerInterior(specid))
            {
                PlayerSpectatePlayer(playerid, specid);
                SetPlayerInterior(playerid,GetPlayerInterior(specid));
                SetPlayerVirtualWorld(playerid,GetPlayerVirtualWorld(specid));
            }
        }
        else
        {
            TogglePlayerSpectating(i, 0);
        }
    }
    return 1;
}
Reply
#7

@danish007 Bad Bad Bad wont work if more than 1 admin is specing.Moreover using timers is bad.You are executing code unnecessarily though the player does not change interior/state.

https://sampwiki.blast.hk/wiki/OnPlayerInteriorChange
https://sampwiki.blast.hk/wiki/OnPlayerStateChange

When the interior changes for a player, the admin who is specing and the player will be in different interiors.Therefore the admin cannot see the player.

Make an array which stores the player id who is being speced for each admin.Loop through the array and check if the spec id matches with playerid(whose interior changed), if there was an admin specing that player then set the admins interior id to the players.Similarly do it in OnPlayerStateChange.You'll have to make an admin spec a vehicle (vehicle of the player who has to be spectated) rather than specing the player directly.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)