Рекурсия в коде
#1

Всех приветствую. Компилятор обнаружил рекурсию в коде, нужна помощь в исправлении.

PHP код:
    foreach(new x: Player)
    {
        if(!
IsPlayerConnected(x)) continue;
        if(
GetPlayerState(x) == PLAYER_STATE_SPECTATING && gSpectateID[x] == playerid)
        {
            
AdvanceSpectate(x);
        }
    } 


Полный код

PHP код:
stock StartSpectate(playerid, specid)
{
    
SetPVarInt(playerid,"PlayerSpec",1);
    if(
GetPlayerState(playerid) != PLAYER_STATE_SPECTATING)
    {
        
ShowMenuForPlayer(OdminMeny,playerid);
        
GetPlayerPos(playerid, TeleportDest[playerid][0],TeleportDest[playerid][1],TeleportDest[playerid][2]);
        
TeleportDestNoFloat[playerid][0] = GetPlayerInterior(playerid);
        
TeleportDestNoFloat[playerid][1] = GetPlayerVirtualWorld(playerid);
    }
    foreach(new 
x: Player)
    {
        if(!
IsPlayerConnected(x)) continue;
        if(
GetPlayerState(x) == PLAYER_STATE_SPECTATING && gSpectateID[x] == playerid)
        {
            
AdvanceSpectate(x);
        }
    }
    if(
IsPlayerInAnyVehicle(specid))
    {
        
SetPlayerInterior(playerid,GetPlayerInterior(specid));
        
SetPlayerVirtualWorld(playerid, GetPlayerVirtualWorld(specid));
        
TogglePlayerSpectating(playerid, 1);
        
PlayerSpectateVehicle(playerid, GetPlayerVehicleID(specid));
        
gSpectateID[playerid] = specid;
        
gSpectateType[playerid] = ADMIN_SPEC_TYPE_VEHICLE;
    }
    else
    {
        
SetPlayerInterior(playerid,GetPlayerInterior(specid));
        
SetPlayerVirtualWorld(playerid, GetPlayerVirtualWorld(specid));
        
TogglePlayerSpectating(playerid, 1);
        
PlayerSpectatePlayer(playerid, specid);
        
gSpectateID[playerid] = specid;
        
gSpectateType[playerid] = ADMIN_SPEC_TYPE_PLAYER;
    }
    
SpecAd[playerid] = specid;
    
SpecID[specid] = playerid;
    
PlayerTextDrawShow(playerid, FULLRECON[playerid]);
    return 
true;
} 
Reply
#2

playerid != x не?
Reply
#3

Quote:
Originally Posted by James_Braga
Посмотреть сообщение
playerid != x не?
Не, где-то тут, если закрыть в StartSpectate "AdvanceSpectate" - рекурсии нет так как Advance не вызывается.
А если раскоментировать Advance то рекурсия появится
PHP код:
stock AdvanceSpectate(playerid) 
{ 
    if(
ConnectedPlayers() == 2) 
    { 
        
StopSpectate(playerid); 
        return 
true; 
    } 
    if(
GetPlayerState(playerid) == PLAYER_STATE_SPECTATING && gSpectateID[playerid] != INVALID_PLAYER_ID) 
    { 
        for(new 
x = gSpectateID[playerid]+1; x <= MAX_PLAYERS; x++) 
        { 
            if(
x == MAX_PLAYERS) 
            { 
                
x = 0; 
            } 
            if(
IsPlayerConnected(x) && x != playerid) 
            { 
                if(
GetPlayerState(x) == PLAYER_STATE_SPECTATING && gSpectateID[x] != INVALID_PLAYER_ID || 
                        (
GetPlayerState(x) != 1 && GetPlayerState(x) != 2 && GetPlayerState(x) != 3)) 
                { 
                    continue; 
                } 
                else 
                { 
                    
StartSpectate(playerid, x); 
                    break; 
                } 
            } 
        } 
    } 
    return 
true; 
} 
Reply
#4

Quote:
Originally Posted by Parlianment
Посмотреть сообщение
Не, где-то тут, если закрыть в StartSpectate "AdvanceSpectate" - рекурсии нет так как Advance не вызывается.
А если раскоментировать Advance то рекурсия появится
PHP код:
stock AdvanceSpectate(playerid) 
{ 
    if(
ConnectedPlayers() == 2) 
    { 
        
StopSpectate(playerid); 
        return 
true; 
    } 
    if(
GetPlayerState(playerid) == PLAYER_STATE_SPECTATING && gSpectateID[playerid] != INVALID_PLAYER_ID) 
    { 
        for(new 
x = gSpectateID[playerid]+1; x <= MAX_PLAYERS; x++) 
        { 
            if(
x == MAX_PLAYERS) 
            { 
                
x = 0; 
            } 
            if(
IsPlayerConnected(x) && x != playerid) 
            { 
                if(
GetPlayerState(x) == PLAYER_STATE_SPECTATING && gSpectateID[x] != INVALID_PLAYER_ID || 
                        (
GetPlayerState(x) != 1 && GetPlayerState(x) != 2 && GetPlayerState(x) != 3)) 
                { 
                    continue; 
                } 
                else 
                { 
                    
StartSpectate(playerid, x); 
                    break; 
                } 
            } 
        } 
    } 
    return 
true; 
} 
естественно находит, внутри StartSpectate вызывается AdvanceSpectate. А в AdvanceSpectate при некоторых событиях вызывается StartSpectate. В итоге компилятор видит очевидную рекурсию. Рекомендации: переписать систему слежения за игроками или же забить (Я за первый вариант)
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)