Problem mit Spectator (/tv) System

Wichtiger Hinweis: Bitte ändert nicht manuell die Schriftfarbe auf schwarz sondern belasst es bei der Standardeinstellung. Somit tragt ihr dazu bei dass euer Text auch bei Verwendung unseren dunklen Forenstils noch lesbar ist!

Tipp: Ihr wollt längere Codeausschnitte oder Logfiles bereitstellen? Benutzt unseren eigenen PasteBin-Dienst Link
  • Hey,


    habe ein Problem mit meine Spectator-System.
    Wenn der zu beobachtende Spieler das Interior und der virtuelle Welt wechselt, updatet das Specsystem bzw. ich werde nicht in das Interior oder in die virtuelle Welt gesetzt.
    (Ich sehe dann nur Himmel)


    Specbefehl:


    ocmd:tv(playerid, params[]){
    if(!SpielerInfo[playerid][pEingeloggt])return SendClientMessage(playerid,Grau,"Du bist nicht eingeloggt.");
    if(!IstAdmin(playerid, 1))return SendClientMessage(playerid,Grau,"Du hast nicht die benötigten Rechte für diesen Befehl.");
    {
    new pID;
    if(sscanf(params,"u",pID))return SendClientMessage(playerid,Gelb,"/tv [Spieler/ID]");
    if(pID == playerid)return SendClientMessage(playerid,Grau,"Du kannst Dich nicht selber beobachten.");
    if(!IsPlayerConnected(pID))return SendClientMessage(playerid,Grau,"Der Spieler ist nicht verbunden.");
    if(IsSpecing[playerid] == 1)return SendClientMessage(playerid,Grau,"Du bist bereits im Beobachtungsmodus.");
    GetPlayerPos(playerid,sx[playerid],sy[playerid],sz[playerid]);
    inter[playerid] = GetPlayerInterior(playerid);
    vWorld[playerid] = GetPlayerVirtualWorld(playerid);
    TogglePlayerSpectating(playerid,true);
    if(IsPlayerInAnyVehicle(pID) == 1){
    if(GetPlayerInterior(pID) > 0){
    SetPlayerInterior(playerid,GetPlayerInterior(pID));
    }
    if(GetPlayerVirtualWorld(pID) > 0){
    SetPlayerVirtualWorld(playerid,GetPlayerVirtualWorld(pID));
    }
    PlayerSpectateVehicle(playerid,GetPlayerVehicleID(pID));
    }else{
    if(GetPlayerInterior(pID) > 0){
    SetPlayerInterior(playerid,GetPlayerInterior(pID));
    }
    if(GetPlayerVirtualWorld(pID) > 0){
    SetPlayerVirtualWorld(playerid,GetPlayerVirtualWorld(pID));
    }
    PlayerSpectatePlayer(playerid,pID);
    }
    PlayerPlaySound(playerid,5201,0.0,0.0,0.0);
    new str[64],str1[64];
    format(str,sizeof(str),"Du beobachtest nun %s",SpielerName(pID));
    format(str1,sizeof(str1),"%s beobachtet nun %s",SpielerName(playerid),SpielerName(pID));
    SendClientMessage(playerid,Tuerkies,str);
    SendAdminChat(1,Hellgruen,str1);
    IsSpecing[playerid] = 1;
    IsBeingSpeced[pID] = 1;
    spectatorid[playerid] = pID;
    }
    return 1;
    }


    Callback


    public OnPlayerInteriorChange(playerid, newinteriorid, oldinteriorid)
    {
    if(IsBeingSpeced[playerid] == 1){
    for(new i=0;i<MAX_PLAYERS;i++){
    if(spectatorid[i] == playerid){
    SetPlayerInterior(i,GetPlayerInterior(playerid));
    SetPlayerVirtualWorld(i,GetPlayerVirtualWorld(playerid));
    }
    }
    }
    return 1;
    }


    Habe es schon mit


    GetPlayerPos();


    Versucht, ist leider gescheitert.

  • Prinzipiell spricht nichts gegen dein Code im OnPlayerInteriorChange. Kannst du bitte nach jedem Schritt (in deinem Fall nach dem ersten If, dem "for", dem if) ein print setzen, damit man sehen kann, bis wohin dein Callback kommt? (print 1, print 2, print 3)

  • Probiere es so:


    public OnPlayerInteriorChange(playerid, newinteriorid, oldinteriorid)
    {
    if(IsBeingSpeced[playerid] == 1){
    for(new i=0;i<MAX_PLAYERS;i++){
    if(spectatorid[i] == playerid){
    TogglePlayerSpectating(i, false);
    SetPlayerInterior(i,GetPlayerInterior(playerid));
    SetPlayerVirtualWorld(i,GetPlayerVirtualWorld(playerid));
    TogglePlayerSpectating(i, true);
    }
    }
    }
    return 1;
    }

  • Versuche es so, möglicherweise reicht das schon.
    public OnPlayerInteriorChange(playerid, newinteriorid, oldinteriorid)
    {
    if(IsBeingSpeced[playerid] == 1){
    for(new i=0;i<MAX_PLAYERS;i++){
    if(spectatorid[i] == playerid){
    SetPlayerInterior(i,newinteriorid);
    SetPlayerVirtualWorld(i,GetPlayerVirtualWorld(playerid));
    }
    }
    }
    return 1;
    }
    Wenn nicht, dann muss der Code debuggt werden.

  • Jeffry: Hat leider nicht funktioniert


    Hab mal den Code gedebuggt:


    public OnPlayerInteriorChange(playerid, newinteriorid, oldinteriorid)
    {
    if(IsBeingSpeced[playerid] == 1){
    print("Spieler wird beobachtet");
    for(new i=0;i<MAX_PLAYERS;i++){
    print("for-Schleife wird ausgeführt");
    if(spectatorid[i] == playerid){
    print("ID wird abgefragt");
    SetPlayerInterior(i,newinteriorid);
    print("Inter wird gewechselt");
    SetPlayerVirtualWorld(i,GetPlayerVirtualWorld(playerid));
    print("vWorld wurde geupdatet");
    }
    }
    }
    return 1;
    }


    Das hat die Konsole ausgespuckt:



    (Gut, dass ich MAX_PLAYERS vordefiniert habe)


    Es scheint wohl nichts fehlerhaft zu sein.

  • Ändert der Spieler der spectated wird auch seine Position? Es ist nämlich ein bekannter Fehler, dass der Spectator Modus in den Himmel geht, wenn der Spieler die Position ändert, zu einem Punkt weiters weg.


    Starte mal dort einen kurzen SetTimerEx von einer Sekunde und starte dann den Spectator Modus für den Spieler neu, im public des Timers, das sollte den Fehler zumindest größtenteils automatisch beheben.

  • Bau mal bitte dein Script um, sodass die for Schleife wegfällt. Speichere die ID des Admins der beobachtete, in einem User-Array. Sodass du per z.B. userSpectedFrom[playerid] abfragen kamnst, welcher admin den Nutzer "playerid" beobachtet.


    1. Ressourcenschonender und 2. bringt uns das vielleicht weiter.