Portal SAMP
[Ajuda] Como criar uma nova lista de interador pra forEach? - Versão de Impressão

+- Portal SAMP (https://portalsamp.com)
+-- Fórum: SA-MP (https://portalsamp.com/forumdisplay.php?fid=5)
+--- Fórum: Área de suporte (https://portalsamp.com/forumdisplay.php?fid=6)
+--- Tópico: [Ajuda] Como criar uma nova lista de interador pra forEach? (/showthread.php?tid=3478)

Páginas: 1 2


RE: Como criar uma nova lista de interador pra forEach? - hiwyn - 28/03/2023

(28/03/2023 16:55)Vel Escreveu:
(28/03/2023 16:41)hiwyn Escreveu:
(28/03/2023 11:50)Vel Escreveu: Não precisa fazer isso, já é feito internamente.
Código:
StreamedVehicle

Código:
CMD:test(playerid) {
    foreach (new vehid : StreamedVehicle[playerid]) {
        printf("%i", vehid);
    }
    return true;
}

Na lib que eu to usando não tem
Na lib YSI tem, eu não queria usar a lib YSI, mas de qualquer forma eu queria conseguir criar as minhas proprias listas interativas
pq esse do carro é só um exemplo, vou usar pra varias outras coisas que só tem no meu servidor...

A lib que eu to usando é a foreach padrão do samp

https://github.com/karimcambridge/samp-foreach/blob/master/foreach.inc

Nos comentários dela tem uma função chamada
`Iter_Create - Create a new iterator value set.`
será que eu deveria usar ela?
eu to fazendo algo errado parece, mas não to sabendo descobrir oq é

(28/03/2023 11:24)Dr Editor Escreveu:
(28/03/2023 11:02)hiwyn Escreveu:
(28/03/2023 10:53)Dr Editor Escreveu: Entendi exatamente o ponto do tópico e te dei um norte de como resolver isso através de outra alternativa.
Seu código é curto e não apresenta nenhum erro lógico. Neste caso temos que otpar por um plano B.
Espero que consiga compreender com o exemplo abaixo baseado na minha primeira resposta:

Vamos supor que a distância do stream de veículos é 200;

Código:
CMD:test(playerid) {
    new Float:stream = 200.0, Float:x, Float:y, Float:z;
    for(new i = 0; i < MAX_VEHICLES; i ++) {
        if(!IsValidVehicle(i))
             continue;
        GetVehiclePos(i, x, y, z);
        if(IsPlayerInRangeOfPoint(playerid, stream, x, y, z))
             printf("%i", vehid);
    }
    return true;
}

É um código apenas para exemplificar o que estava tentando explicar. Fiz na marra, não compilei e serve apenas para se basear na lógica.
Para maior precisão basta diminuir a distância de stream.

Eu to tentando criar listas personalizadas pra evitar esse tipo de código (que é o que eu atualmente uso no meu GM)
Os carros foram só um exemplo, queria criar diversas listas

Imagina se MAX_VEHICLES é 2000, esse seu código vai percorrer 2.000 vezes e fazer 2 verificações (uma delas que não é muito leve)
No caso um jogador pode ter só 3 carros stremmados pra ele... Isso a longo prazo ou rodando em timers cresce exponencialmente.

Mas obrigado por tentar ajudar.

Só pra finalizar acho válido tentar utilizar outros recursos do foreach.

1 - Inicialize o iterator com Iter_Init
2 - Se ele está duplicando o valor nos demais índices, é cabível conferir se o valor já está adicionado à lista usando Iter_Contains

Dê uma olhada na documentação para ajudar.

Muito obrigado!

Não achei a documentação, tava lendo o texto da lib comentado, mas não me ajudou muito

2-
assim né?
Código:
public OnVehicleStreamIn(vehicleid, forplayerid)
{
    new string[32];
    format(string, sizeof(string), "You can now see vehicle %d.", vehicleid);
    SendClientMessage(forplayerid, 0xFFFFFFFF, string);
    if(!Iter_Contains(StreamedVehicles[forplayerid], vehicleid)) {
        Iter_Add(StreamedVehicles[forplayerid], vehicleid);
    }
    return 1;
}
public OnVehicleStreamOut(vehicleid, forplayerid)
{
    new string[48];
    format(string, sizeof(string), "Your client is no longer streaming vehicle %d", vehicleid);
    SendClientMessage(forplayerid, 0xFFFFFFFF, string);
    if(Iter_Contains(StreamedVehicles[forplayerid], vehicleid)) {
        Iter_Remove(StreamedVehicles[forplayerid], vehicleid);
    }
    return 1;
}

1-
Não entendi pode me dar um exemplo de código por favor?

Testei seu código inicial usando a lib YSI e não tive nenhum problema, e não parece ter nenhum mesmo... deve ser algo com a lib foreach, afinal é uma versão obsoleta.

É que eu fiz o código baseado na lib YSI
provavelmente na lib foreach deve ser diferente
não tem muito conteúdo sobre isso na net com o forum samp fechado a YSI tem documentação

Eu tive vários problemas com o YSI, posso tentar de novo depois, mas de qualquer forma eu não ia usar as funcionalidades deles, tem essa funcionalidade no foreach deveria funcionar né, eu que não devo ta sabendo usar


Eu acho que pra criar uma matrix de interator (2 dimenssões: MAX_PLAYERS, MAX_VEHICLES)
deve ser diferente pq

Só com:
Código:
new Iterator:StreamedVehicles[MAX_PLAYERS]<MAX_VEHICLES>;

CMD:test(playerid) {
    foreach (new vehid : StreamedVehicles[playerid]) {
        printf("%i", vehid);
    }
    return true;
}
sem nenhuma adição nessa lista
até com warning de sem uso (warning 203: symbol is never used: "StreamedVehicles@YSII_Cg")

quando eu rodo /test aparece um flood infinito de:
Código:
[19:28:05] 0
[19:28:05] 0
[19:28:05] 0
[19:28:05] 0
[19:28:05] 0
[19:28:05] 0
[19:28:05] 0
[19:28:05] 0
[19:28:05] 0


no server_log.txt


se eu troco pra:
Código:
new Iterator:StreamedVehicles<MAX_VEHICLES>;

public OnVehicleStreamIn(vehicleid, forplayerid)
{
    new string[32];
    format(string, sizeof(string), "You can now see vehicle %d.", vehicleid);
    SendClientMessage(forplayerid, 0xFFFFFFFF, string);
    Iter_Add(StreamedVehicles, vehicleid);
    return 1;
}
public OnVehicleStreamOut(vehicleid, forplayerid)
{
    new string[48];
    format(string, sizeof(string), "Your client is no longer streaming vehicle %d", vehicleid);
    SendClientMessage(forplayerid, 0xFFFFFFFF, string);
    Iter_Remove(StreamedVehicles, vehicleid);
    return 1;
}

CMD:test(playerid) {
    foreach (new vehid : StreamedVehicles) {
        printf("%i", vehid);
    }
    return true;
}

funciona de boa (o problema é que eu preciso de uma lista pra cada player nesse caso e em varios outros customizados que eu vou criar

lendo isso aqui vc consegue entender como criar certo?
https://github.com/karimcambridge/samp-foreach/blob/master/foreach.inc#L271
pq eu não entendo nada do que ta aqui

ou tem algum outro jeito de fazer isso?


RE: Como criar uma nova lista de interador pra forEach? - Dr Editor - 28/03/2023

(28/03/2023 16:41)hiwyn Escreveu: Muito obrigado!

Não achei a documentação, tava lendo o texto da lib comentado, mas não me ajudou muito

2-
assim né?
Código:
public OnVehicleStreamIn(vehicleid, forplayerid)
{
    new string[32];
    format(string, sizeof(string), "You can now see vehicle %d.", vehicleid);
    SendClientMessage(forplayerid, 0xFFFFFFFF, string);
    if(!Iter_Contains(StreamedVehicles[forplayerid], vehicleid)) {
        Iter_Add(StreamedVehicles[forplayerid], vehicleid);
    }
    return 1;
}
public OnVehicleStreamOut(vehicleid, forplayerid)
{
    new string[48];
    format(string, sizeof(string), "Your client is no longer streaming vehicle %d", vehicleid);
    SendClientMessage(forplayerid, 0xFFFFFFFF, string);
    if(Iter_Contains(StreamedVehicles[forplayerid], vehicleid)) {
        Iter_Remove(StreamedVehicles[forplayerid], vehicleid);
    }
    return 1;
}

1-
Não entendi pode me dar um exemplo de código por favor?

Achei outra biblioteca standalone de foreach que já possui o que você precisa. Segue: https://github.com/Open-GTO/foreach
Utilize o iterator PlayerVehiclesStream.

Só para complementar: Com base nesta include você estava fazendo da forma correta desde o início, porém a única diferença é que é utilizado o Iter_Init para inicializar o iterator.
Teste essa versão e diga se resolveu.


RE: Como criar uma nova lista de interador pra forEach? - hiwyn - 28/03/2023

(28/03/2023 19:27)Dr Editor Escreveu:
(28/03/2023 16:41)hiwyn Escreveu: Muito obrigado!

Não achei a documentação, tava lendo o texto da lib comentado, mas não me ajudou muito

2-
assim né?
Código:
public OnVehicleStreamIn(vehicleid, forplayerid)
{
    new string[32];
    format(string, sizeof(string), "You can now see vehicle %d.", vehicleid);
    SendClientMessage(forplayerid, 0xFFFFFFFF, string);
    if(!Iter_Contains(StreamedVehicles[forplayerid], vehicleid)) {
        Iter_Add(StreamedVehicles[forplayerid], vehicleid);
    }
    return 1;
}
public OnVehicleStreamOut(vehicleid, forplayerid)
{
    new string[48];
    format(string, sizeof(string), "Your client is no longer streaming vehicle %d", vehicleid);
    SendClientMessage(forplayerid, 0xFFFFFFFF, string);
    if(Iter_Contains(StreamedVehicles[forplayerid], vehicleid)) {
        Iter_Remove(StreamedVehicles[forplayerid], vehicleid);
    }
    return 1;
}

1-
Não entendi pode me dar um exemplo de código por favor?

Achei outra biblioteca standalone de foreach que já possui o que você precisa. Segue: https://github.com/Open-GTO/foreach
Utilize o iterator PlayerVehiclesStream.

Só para complementar: Com base nesta include você estava fazendo da forma correta desde o início, porém a única diferença é que é utilizado o Iter_Init para inicializar o iterator.
Teste essa versão e diga se resolveu.

nossa muito obrigado por achar essa lib pra mim, obrigadão mesmo


RE: Como criar uma nova lista de interador pra forEach? - pushline - 29/03/2023

Por que você não deseja usar a lib ysi?