Uso de sscanf em Dialog - KruCz - 16/04/2023
Oi pessoal, boa noite! Tudo bem?
Recentemente fiz um comando para localizar jogadores próximos, através de dialog. Estou com problema em definir uma variável para o segundo jogador próximo, e como é em dialog, não encontrei algo semelhante ao método padrão (sscanf).
Com isso, ao usar o comando, o valor sempre é 0, no caso apresentado ao ID 0. Após isso, tentei utilizar com um loop, porém, quando efetuo a ação o loop também pega o meu ID e conta como proximidade
Código PHP: public OnPlayerKeyStateChange(playerid, newkeys, oldkeys) { new str[15];
format(str, sizeof(str), "dinheiro: \t\t %i", PPL[playerid][moneyAtPPL]); ShowPlayerDialog(playerid, trade_money, DIALOG_STYLE_LIST, "dinheiro", str, "Enviar", "Fechar"); return 1; }
OnDialogResponse(...) { if(dialogid == 613) { new str[140];
if(response) { if(listitem == 0) { for(new i; i < MAX_PLAYERS; ++i) { if(GetDistanceBetweenPlayers(playerid, i) <= 3) { format(str, sizeof(str), "Quanto deseja enviar para %s?", nomep(i)); ShowPlayerDialog(playerid, 630, DIALOG_STYLE_INPUT, "dinheiro", str, "Enviar", "Cancelar"); } else { SendClientMessage(playerid, -1, "Ninguem por perto."); } } } }
if(dialogid == 630) { if(response) { new str[120]; { for(new i; i < MAX_PLAYERS; ++i) { if(moneyreturn(playerid) < strval(inputtext)) return SendClientMessage(playerid, -1, "voce não possui essa quantia");
if(GetDistanceBetweenPlayers(playerid, i) <= 3)) { moneyAtPPL(i, strval(inputtext)); moneyAtPPL(playerid, - strval(inputtext));
format(str, sizeof(str), "%i enviado para %s.", strval(inputtext), nomep(i)); SendClientMessage(playerid, -1, str); } } else { SendClientMessage(playerid, -1, "ninguem por perto."); } } } }
Alguém poderia me ajudar?
RE: Uso de sscanf em Dialog - Carlos Victor - 16/04/2023
Se você quer pegar os dados de jogadores próximo, deverá criar um loop em todos os jogadores e verificar se estão próximos ou não, e também não é recomendado utilizar a callback OnPlayerStateChange da forma que foi apresentada acima, lembre-se que ela é chamada toda vez que um jogador clique em um botão válido, então imagina quantas vezes ela será chamada em uma servidor com 10/20 jogadores, bastante, enfim... Deixarei um código abaixo, não sei se é isso que você quis dizer, mas é o que eu entendi.
Código PHP: CMD:proximo(playerid) { static _name[MAX_PLAYER_NAME], count, str[32], string[1024];
count = 0; string[0] = 0; str[0] = 0;
format(string, sizeof(string), "ID\tNome\tDinheiro\n"); for(new i = 0, j = GetPlayerPoolSize(); i <= j; i++) { if(IsPlayerConnected(i) && IsPlayerNearPlayer(i, playerid, 20.0)) { GetPlayerName(playerid, _name, sizeof(_name)); format(string, sizeof(string), "%s{FFFFFF}%d\t%s\t%d\n", string, i, _name, GetPlayerMoney(i));
count++; } }
if(!count) return SendClientMessage(playerid, -1, "* Você não está próximo de nenhum jogador.");
format(str, sizeof(str), "Jogadores Proximos (%d)", count); ShowPlayerDialog(playerid, DIALOG_PLAYERS_NEAR, DIALOG_STYLE_TABLIST, str, string, "Selecionar", "Fechar"); return 1; }
public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[]) { switch(dialogid) { case DIALOG_PLAYERS_NEAR: { if(response) { new Float:x, Float:y, Float:z, string[128], _name[MAX_PLAYER_NAME], id = strval(inputtext);
if(!IsPlayerConnected(id)) return SendClientMessage(playerid, -1, "* O jogador selecionado desconectou-se do servidor.");
GetPlayerName(id, _name, sizeof(_name)); GetPlayerPos(id, x, y, z); SetPlayerPos(playerid, x, y, z + 1.0);
format(string, sizeof(string), "* Você foi até o jogador %s.", _name); SendClientMessage(playerid, -1, string); } } } return 1; }
No código acima utilizei variáveis estáticas no comando para evitar o grande consumo de memória, já que iremos trabalhar com string's grandes, e também o teleporte que eu fiz caso selecionar um X jogador na dialog é um exeplo do que você pode fazer, seja criativo e faça o que quiser usando o paramêtro ID como o jogador selecionado.
RE: Uso de sscanf em Dialog - KruCz - 16/04/2023
(16/04/2023 21:24)Carlos Victor Escreveu: Se você quer pegar os dados de jogadores próximo, deverá criar um loop em todos os jogadores e verificar se estão próximos ou não, e também não é recomendado utilizar a callback OnPlayerStateChange da forma que foi apresentada acima, lembre-se que ela é chamada toda vez que um jogador clique em um botão válido, então imagina quantas vezes ela será chamada em uma servidor com 10/20 jogadores, bastante, enfim... Deixarei um código abaixo, não sei se é isso que você quis dizer, mas é o que eu entendi.
Código PHP: CMD:proximo(playerid) { static _name[MAX_PLAYER_NAME], count, str[32], string[1024];
count = 0; string[0] = 0; str[0] = 0;
format(string, sizeof(string), "ID\tNome\tDinheiro\n"); for(new i = 0, j = GetPlayerPoolSize(); i <= j; i++) { if(IsPlayerConnected(i) && IsPlayerNearPlayer(i, playerid, 20.0)) { GetPlayerName(playerid, _name, sizeof(_name)); format(string, sizeof(string), "%s{FFFFFF}%d\t%s\t%d\n", string, i, _name, GetPlayerMoney(i));
count++; } }
if(!count) return SendClientMessage(playerid, -1, "* Você não está próximo de nenhum jogador.");
format(str, sizeof(str), "Jogadores Proximos (%d)", count); ShowPlayerDialog(playerid, DIALOG_PLAYERS_NEAR, DIALOG_STYLE_TABLIST, str, string, "Selecionar", "Fechar"); return 1; }
public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[]) { switch(dialogid) { case DIALOG_PLAYERS_NEAR: { if(response) { new Float:x, Float:y, Float:z, string[128], _name[MAX_PLAYER_NAME], id = strval(inputtext);
if(!IsPlayerConnected(id)) return SendClientMessage(playerid, -1, "* O jogador selecionado desconectou-se do servidor.");
GetPlayerName(id, _name, sizeof(_name)); GetPlayerPos(id, x, y, z); SetPlayerPos(playerid, x, y, z + 1.0);
format(string, sizeof(string), "* Você foi até o jogador %s.", _name); SendClientMessage(playerid, -1, string); } } } return 1; }
No código acima utilizei variáveis estáticas no comando para evitar o grande consumo de memória, já que iremos trabalhar com string's grandes, e também o teleporte que eu fiz caso selecionar um X jogador na dialog é um exeplo do que você pode fazer, seja criativo e faça o que quiser usando o paramêtro ID como o jogador selecionado.
Oi Carlos, boa noite! Primeiramente agradeço a atenção!
A dúvida que postei, foi sobre um "método de transferência", um jogador transferir dinheiro para o jogador mais próximo a ele.
No código publicado, o jogador pressiona a tecla na callback OnPlayerKeyStateChange, e seleciona a opção "Dinheiro" na dialog. Após isso, a ideia é perguntar quanto ele quer transferir para o usuário mais próximo a ele.
Meu problema é que não estou conseguindo definir uma variável para localizar esse jogador mais próximo para efetuar a ação. Se fosse em comando, eu poderia definir uma variável através do sscanf. Porém, estou fazendo em dialog.
RE: Uso de sscanf em Dialog - Carlos Victor - 17/04/2023
O jogador mais próximo dentro de um raio ou o mais próximo valendo o mapa todo?
RE: Uso de sscanf em Dialog - KruCz - 17/04/2023
(17/04/2023 11:53)Carlos Victor Escreveu: O jogador mais próximo dentro de um raio ou o mais próximo valendo o mapa todo?
A ideia era ser o mais próximo dentro de um raio, usei o GetDistanceBetweenPlayers, porém, a a dificuldade é com a variável.
RE: Uso de sscanf em Dialog - White_Blue - 17/04/2023
(17/04/2023 12:29)KruCz Escreveu: (17/04/2023 11:53)Carlos Victor Escreveu: O jogador mais próximo dentro de um raio ou o mais próximo valendo o mapa todo?
A ideia era ser o mais próximo dentro de um raio, usei o GetDistanceBetweenPlayers, porém, a a dificuldade é com a variável.
Qual o problema?
Para o uso de sscanf em dialog você usa o parâmetro inputtext da OnDialogResponse para escanear a variável
Exemplo:
Código PHP: public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[]) { if(dialogid == sua_dialog) { new id; if(sscanf(inputtext, "u", id)) return SendClientMessage(playerid, -1, "Digite o ID do jogador!"), ShowPlayerDialog(playerid, sua_dialog, DIALOG_STYLE_INPUT, "Digite o ID do jogador", "{FFFFFF}Digite o ID do jogador desejado:"); } return 1; }
RE: Uso de sscanf em Dialog - Carlos Victor - 18/04/2023
Desculpa a demora, mas com base no que você disse, eu fiz o código:
Código PHP: new targetID[MAX_PLAYERS] = {INVALID_PLAYER_ID, ...};
public OnPlayerKeyStateChange(playerid, newkeys, oldkeys) { new str[32];
format(str, sizeof(str), "dinheiro: \t\t %i", PPL[playerid][moneyAtPPL]); ShowPlayerDialog(playerid, trade_money, DIALOG_STYLE_LIST, "dinheiro", str, "Enviar", "Fechar"); return 1; }
OnDialogResponse(...) { if(dialogid == 613) { if(response) { new string[128];
if((targetID[playerid] = GetNearestPlayer(playerid)) == INVALID_PLAYER_ID) return SendClientMessage(playerid, -1, "Nao tem ninguem proximo de voce.");
format(str, sizeof(str), "Quanto deseja enviar para %s?", nomep(id)); ShowPlayerDialog(playerid, 630, DIALOG_STYLE_INPUT, "dinheiro", str, "Enviar", "Cancelar"); } }
if(dialogid == 630) { if(response) { new string[128], id = targetID[playerid];
if(moneyreturn(playerid) < strval(inputtext)) return SendClientMessage(playerid, -1, "voce não possui essa quantia");
if(!IsPlayerConnected(id)) return SendClientMessage(playerid, -1, "O jogador desconectou-se.");
if(!IsPlayerNearPlayer(playerid, id, 3.0)) return SendClientMessage(playerid, -1, "O jogador se afastou demais!");
moneyAtPPL(i, strval(inputtext)); moneyAtPPL(playerid, - strval(inputtext));
format(string, sizeof(string), "Voce enviou $%d para %s.", strval(inputtext), nomep(i)); SendClientMessage(playerid, -1, string); } } return 1; }
stock GetNearestPlayer(playerid) { for(new i = 0, j = GetPlayerPoolSize(); i <= j; i++) { if(IsPlayerConnected(i) && IsPlayerNearPlayer(playerid, i, 3.0)) { return i; } } return INVALID_PLAYER_ID; }
stock IsPlayerNearPlayer(playerid, targetid, Float:radius) { static Float:fX, Float:fY, Float:fZ;
GetPlayerPos(targetid, fX, fY, fZ);
return (GetPlayerInterior(playerid) == GetPlayerInterior(targetid) && GetPlayerVirtualWorld(playerid) == GetPlayerVirtualWorld(targetid)) && IsPlayerInRangeOfPoint(playerid, radius, fX, fY, fZ); }
Ele inclui:
- Verificar o jogador mais próximo.
- Enviar dinheiro a esse jogador mais próximo.
|