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


Como criar uma nova lista de interador pra forEach? - hiwyn - 27/03/2023

Eu queria criar uma lista de veiculos renderizados pelos players pra depois fazer um loop sobre ela, percorro o loop o servidor laga e trava todo

O que eu to fazendo de errado?

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

Código:
public OnVehicleStreamIn(vehicleid, forplayerid)
{
    Iter_Add(StreamedVehicles[forplayerid], vehicleid);
    return 1;
}
public OnVehicleStreamOut(vehicleid, forplayerid)
{
    Iter_Remove(StreamedVehicles[forplayerid], vehicleid);
    return 1;
}

quando eu executo isso aqui crasha tudo Sad
Código:
CMD:test(playerid) {
    foreach (new vehid : StreamedVehicles[playerid]) {
        printf("%i", vehid);
    }
    return true;
}

E printa milhares de zeros no server_log.txt
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
[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
[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
[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
[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



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

Não encontrei a distância em que os veículos aparecem para os jogadores, mas você pode ver isso utilizando a função OnVehicleStreamIn e no momento em que for chamada você pega a distância entre o player e o veículo.
Utilizando essa distância-base basta criar um loop com o mesmo alcance e identificar quais veículos estão dentro desta condição.


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

(28/03/2023 08:06)Dr Editor Escreveu: Não encontrei a distância em que os veículos aparecem para os jogadores, mas você pode ver isso utilizando a função OnVehicleStreamIn e no momento em que for chamada você pega a distância entre o player e o veículo.
Utilizando essa distância-base basta criar um loop com o mesmo alcance e identificar quais veículos estão dentro desta condição.

A questão não é a distancia

O problema do tópico que é o que eu não sei fazer é:
Como criar a lista de veiculos streammados pra players com o Interator da lib foreach

E conseguir percorrer ela sem cair meu servidor


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

(28/03/2023 10:10)hiwyn Escreveu:
(28/03/2023 08:06)Dr Editor Escreveu: Não encontrei a distância em que os veículos aparecem para os jogadores, mas você pode ver isso utilizando a função OnVehicleStreamIn e no momento em que for chamada você pega a distância entre o player e o veículo.
Utilizando essa distância-base basta criar um loop com o mesmo alcance e identificar quais veículos estão dentro desta condição.

A questão não é a distancia

O problema do tópico que é o que eu não sei fazer é:
Como criar a lista de veiculos streammados pra players com o Interator da lib foreach

E conseguir percorrer ela sem cair meu servidor

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.


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

(28/03/2023 10:53)Dr Editor Escreveu:
(28/03/2023 10:10)hiwyn Escreveu:
(28/03/2023 08:06)Dr Editor Escreveu: Não encontrei a distância em que os veículos aparecem para os jogadores, mas você pode ver isso utilizando a função OnVehicleStreamIn e no momento em que for chamada você pega a distância entre o player e o veículo.
Utilizando essa distância-base basta criar um loop com o mesmo alcance e identificar quais veículos estão dentro desta condição.

A questão não é a distancia

O problema do tópico que é o que eu não sei fazer é:
Como criar a lista de veiculos streammados pra players com o Interator da lib foreach

E conseguir percorrer ela sem cair meu servidor

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.


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

(28/03/2023 11:02)hiwyn Escreveu:
(28/03/2023 10:53)Dr Editor Escreveu:
(28/03/2023 10:10)hiwyn Escreveu:
(28/03/2023 08:06)Dr Editor Escreveu: Não encontrei a distância em que os veículos aparecem para os jogadores, mas você pode ver isso utilizando a função OnVehicleStreamIn e no momento em que for chamada você pega a distância entre o player e o veículo.
Utilizando essa distância-base basta criar um loop com o mesmo alcance e identificar quais veículos estão dentro desta condição.

A questão não é a distancia

O problema do tópico que é o que eu não sei fazer é:
Como criar a lista de veiculos streammados pra players com o Interator da lib foreach

E conseguir percorrer ela sem cair meu servidor

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.


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

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;
}



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

(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:
(28/03/2023 10:10)hiwyn Escreveu:
(28/03/2023 08:06)Dr Editor Escreveu: Não encontrei a distância em que os veículos aparecem para os jogadores, mas você pode ver isso utilizando a função OnVehicleStreamIn e no momento em que for chamada você pega a distância entre o player e o veículo.
Utilizando essa distância-base basta criar um loop com o mesmo alcance e identificar quais veículos estão dentro desta condição.

A questão não é a distancia

O problema do tópico que é o que eu não sei fazer é:
Como criar a lista de veiculos streammados pra players com o Interator da lib foreach

E conseguir percorrer ela sem cair meu servidor

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?


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

(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:
(28/03/2023 10:10)hiwyn Escreveu: A questão não é a distancia

O problema do tópico que é o que eu não sei fazer é:
Como criar a lista de veiculos streammados pra players com o Interator da lib foreach

E conseguir percorrer ela sem cair meu servidor

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.


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

https://team.sa-mp.com/wiki/IsVehicleStreamedIn.html

olha so