Pawn Elipse. - rjjj - 29.07.2011
Pawn Elipse.
Por rjjj ou Ken
Neste tutorial darei explicaзхes relacionadas ao entendimento da declaraзгo Elipse, as "reticкncias" do Pawn (
...)

.
Obs: "Argumento" = Valor passado a um parвmetro de uma funзгo durante a chamada da mesma.
Bem, a Elipse pode aparecer em diferentes tipos de cуdigos, mas й notбvel que em todas as suas apariзхes, ela tem a funзгo de equivaler б vбrios elementos

.
pawn Код:
new x[7] = {2, 3, 5, ...};
No caso acima:
x[
0] й igual б
2 (pois
2 foi o primeiro definido na estrutura, por isso ele й o valor da parte da array que tem index
0 (primeira parte da array).
x[
1] й igual б
3 (pois
3 foi o segundo definido na estrutura, por isso ele й o valor da parte da array que tem index
1 (segunda parte da array).
x[
2] й igual б
5 (pois
5 foi o terceiro definido na estrutura, por isso ele й o valor da parte da array que tem index
2 (terceira parte da array).
Mas qual seria o valor de x[
3] (sendo que й na posiзгo
3 onde estб a Elipse) ? seria 5? seria 3 ? ou seria 0 ?
Vamos descobrir isso e muito mais

.
1 - Elipse na inicializaзгo de variбveis arrays.
Na criaзгo de uma variбvel array, podemos optar por definir o valor que serб armazenado por cada cell da array usando a estrutura:
pawn Код:
new x[4] = {/*valores*/};
Como demonstrei no comeзo do tutorial

.
Nesse caso, a Elipse pode aparecer como um dos valores, e quando isso acontecer, provocarб diferentes efeitos:
* Efeito quando apenas uma ъnica "parte da array" for definida e logo apуs for seguida de Elipse:
Exemplos:
pawn Код:
new x[4] = {4, ...}; //1є caso
new y[6] = {-1, ...}; //2є caso
new z[3] = {67, ...}; //3° caso
Em cada um dos casos acima, a Elipse farб com que todos os outros elementos da variбvel array sejam iguais ao primeiro.
No 1є caso, alйm do primeiro elemento (x[
0]) adquirir valor
4 (que foi definido pelo programador), a Elipse farб com que todos os outros elementos (x[
1], x[
2], etc) tornem-se 4.
* Efeito quando mais de uma "parte da array" for definida e, logo apуs, tudo for seguido de Elipse:
pawn Код:
new a[10] = {4, 5, 6, 8, ...}; //1є caso
new b[44] = {1, 4, ...}; //2є caso
new c[32] = {5, 9, ...}; //3° caso
Nesses casos, os dois ъltimos valores definidos dentro da estrutura
{/*valores*/} constituirгo uma progressгo aritmйtica (P.A) na qual esses dois valores serгo o primeiro e o segundo termo da sequencia numйrica

.
Em outras palavras, se temos:
Код:
new a[10] = {4, 5, 6, 8, ...};
O
6 e o
8 constituiraзгo uma P.A de razгo 2 (para se achar a razгo, subtrai-se um termo da P.A pelo termo anterior б este), ou seja, que terб seus valores crescendo de 2 em 2

.
pawn Код:
//P.A formada:
6, 8, 10, 12, 14, 16,... // e vai crescendo.... atй que a ъltima cell da array seja ocupada por um valor :D
Portanto, a Elipse farб com que a variбvel array que citei antes seja

:
pawn Код:
new a[10] = {4, 5, 6, 8, 10, 12, 14, 16, 19, 21}; //Parou de crescer no 21, por que um valor foi atribuнdo б "a[9]" (ъltima parte da array).
2 - Elipse como parвmetros de funзхes.
Se temos uma funзгo:
pawn Код:
stock LOL(...)
{
return 1;
}
Podemos chamб-la com quantos parвmetros quisermos:
pawn Код:
LOL(1, 3, 5, 7);
LOL(1,5);
LOL("!");
Muitos jб devem ter visto a
native da funзгo
format 
:
pawn Код:
native format(output[], len, const format[], {Float,_}:...);
Vejam que a Elipse aparece como o ъltimo parвmetro

, isso explica por que podemos colocar incontбveis sнmbolos no ъltimo parвmetro do
format quando o chamamos.
* getarg(argid)
A funзгo
getarg(argid) retorna o valor de um argumento. Sendo assim pode-se usб-la para obter o que for colocado no lugar da Elipse

.
Exemplo:
Se temos uma funзгo:
pawn Код:
stock xD(...)
{
printf("ARG 1: %i ARG 2: %i ARG 3: %i", getarg(0), getarg(1), getarg(2));
return 1;
}
Quando a chamarmos dessa forma:
O seguinte texto serб imprimido

:
pawn Код:
"ARG 1: 30 ARG 2: 40 ARG 3: 50"
Exceзгo:
Se a funзгo fosse assim

:
pawn Код:
stock xD(...)
{
printf("ARG 1: %s ARG 2: %s ARG 3: %s", getarg(0), getarg(1), getarg(2));
return 1;
}
E tivйssemos chamado a funзгo com vбrias strings no lugar da Elipse

:
O que seria imprimido seria uma fusгo das iniciais de cada string:
pawn Код:
"ARG 1: a ARG 2: da ARG 3: gda"
Isso ocorre devido б um conflito entre a Elipse (que equivale б vбrios nъmeros em sequencia), a string (que equivale б vбrios nъmeros tambйm) e o
getarg (que pode retornar apenas um nъmero da Elipse, que se for composta de ainda mais nъmeros (string) deixa tudo tenso))

.
* numargs()
A funзгo
numargs() retorna a quantidade de argumentos passados a uma funзгo

.
Exemplo: Se temos a funзгo:
pawn Код:
stock Total(...)
{
printf("Total de Argumentos: %d", numargs());
return 1;
}
E a chamamos desta forma:
pawn Код:
Total(15, 45, 90); //3 argumentos
Isto serб imprimido
* setarg(argid, index, valor)
A funзгo
setarg(argid, index, valor) muda o valor de um argumento. Retorna
0 se o argumento for invбlido.
Exemplo: Se temos a funзгo:
pawn Код:
stock Go(...)
{
setarg(0, 0, 5); //O Segundo parametro deve ser sempre 0 quando o que estiver no lugar da Elipse nгo for uma parte de uma array
printf("ARG 1: %d", getarg(0));
return 1;
}
E a chamamos desta forma:
O valor imprimido nгo serб
3, e sim
5.
3 - Curiosidades.
O ъnico mйtodo atual de se criar a famosa funзгo
SendClientMessageEx (que envia uma mensagem ao jogador, jб formatada) funcionando 100% й atravйs de
#defines

:
pawn Код:
#define SendClientMessageEx(%0, %1, %2); new x[128]; format(x,128,%2), SendClientMessage(%0, %1, %2);
Isso por que "misteriosamente" a exceзгo das strings em Elipse (que ocorre a fusгo das iniciais, etc) nгo se aplica б Elipse do
format, pois o mesmo consegue muito bem ter strings como parвmetros finais

.
Entretanto, o
SendClientMessageEx pode ser criado de uma maneira bem otimizada, ficando quase idкntico ao mesmo se tivesse sido criado atravйs de uma stock com Elipse, desta forma:
pawn Код:
new x[128]; //Sendo x uma variбvel global, vбrias variбveis nгo precisam ser criadas a cada uso da funзгo
#define SendClientMessageEx(%0, %1, %2); \
format(x,128,%2), SendClientMessage(%0, %1, %2);
E й isso, dъvidas ? Perguntem

.
Espero ter ajudado

.
Re: Pawn Elipse. -
ViniBorn - 29.07.2011
Sempre com уtimos tutoriais. Parabйns.
Re: Pawn Elipse. -
SlashPT - 29.07.2011
Quote:
Originally Posted by rjjj
...
O ъnico mйtodo atual de se criar a famosa funзгo SendClientMessageEx (que envia uma mensagem ao jogador, jб formatada) funcionando 100% й atravйs de #defines  :
|
bom trabalho porem sim existe maneira de fazer o SendClientMessage sem precisar de define ...
Estб aqui uma versao alterada por ****** do original codigo do Zeex
pawn Код:
#define BYTES_PER_CELL 4
stock CPF(playerid, color, fstring[], {Float, _}:...)
{
// This is the number of parameters which are not variable that are passed
// to this function (i.e. the number of named parameters).
static const
STATIC_ARGS = 3;
// Get the number of variable arguments.
new
n = (numargs() - STATIC_ARGS) * BYTES_PER_CELL;
if (n)
{
new
message[128],
arg_start,
arg_end;
// Load the real address of the last static parameter. Do this by
// loading the address of the last known static parameter and then
// adding the value of [FRM].
#emit CONST.alt fstring
#emit LCTRL 5
#emit ADD
#emit STOR.S.pri arg_start
// Load the address of the last variable parameter. Do this by adding
// the number of variable parameters on the value just loaded.
#emit LOAD.S.alt n
#emit ADD
#emit STOR.S.pri arg_end
// Push the variable arguments. This is done by loading the value of
// each one in reverse order and pushing them. I'd love to be able to
// rewrite this to use the values of pri and alt for comparison,
// instead of having to constantly load and reload two variables.
do
{
#emit LOAD.I
#emit PUSH.pri
arg_end -= BYTES_PER_CELL;
#emit LOAD.S.pri arg_end
}
while (arg_end > arg_start);
// Push the static format parameters.
#emit PUSH.S fstring
#emit PUSH.C 128
#emit PUSH.ADR message
// Now push the number of arguments passed to format, including both
// static and variable ones and call the function.
n += BYTES_PER_CELL * 3;
#emit PUSH.S n
#emit SYSREQ.C format
// Remove all data, including the return value, from the stack.
n += BYTES_PER_CELL;
#emit LCTRL 4
#emit LOAD.S.alt n
#emit ADD
#emit SCTRL 4
return SendClientMessage(playerid, color, message);
//return print(message);
}
else
{
return SendClientMessage(playerid, color, fstring);
//return print(fstring);
}
}
Porem nem eu a uso pois ja existe a maneira do define... :3
Re: Pawn Elipse. -
Rodox_Mortein - 29.07.2011
[ame]http://www.youtube.com/watch?v=DgqOEsX74T0[/ame]
Re: Pawn Elipse. - rjjj - 29.07.2011
@Viniborn
Muito Obrigado !

.
@SlashPT
Bem, eu cheguei a testar alguns dos projetos que postaram aqui no fуrum e sempre tinha algum problema em relaзгo б maneira que o
format utiliza

.
Esse que vocк postou tentei usar mas ele crashou o Filterscript que uso pra testes

,quando iniciei o server (defini BYTES_PER_CELL igual б 4, o tamanho de uma cell em bytes)

.
Bem, mas talvez usando
format pelo
#emit realmente dк para burlar os errors que o compilador gera quando colocamos assim dentro de uma funзгo com Elipse com argumento, por exemplo:
Код:
new string[100];
format(string, sizeof(string), ...);
Mas nгo deve valer a pena bater cabeзa com isso

, pois jб temos a modo
#define que й 100% funcional

.
@Rodox_Mortein
Spam ?

.
Re: Pawn Elipse. -
SlashPT - 29.07.2011
estranho pois comigo nao crashou testei agora mesmo que ate me tinha esquecido de definir a Byte por cell e apуs definir deu certinho, e pelo que ouvi falar nao da problemas.
O problema й que й muito lento acho que percebes porque... xD
Re: Pawn Elipse. - [S]trong - 29.07.2011
Testei, e nгo crashou tambйm...
Re: Pawn Elipse. - rjjj - 29.07.2011
@Rodox_Mortein
Exemplifiquei bastante para que ficasse fбcil de entender

.
Se vocк tiver um bom conhecimento sobre variбveis arrays, acho que pode entender o tutorial sу vendo os exemplos

.
Tambйm tentei usar os termos conhecidos aqui no fуrum (como "array", por exemplo), para facilitar o entendimento

.
@SlashPT

.
@[S]trong
Й, bem estranho

, testei no lvdm tambйm e crashou, talvez seja aquilo do tamanho de uma cell бs vezes mudar de sistema operacional pra sistema operacional

.
Muito obrigado б todos que aprovaram o Tutorial

!
Re: Pawn Elipse. - [S]trong - 29.07.2011
Bom tutorial, eu acabei de ligar o SAMP-SERVER.exe usando ela e nгo deu crash, mas como vocк falou, deve ser o sistema operacional.
Re: Pawn Elipse. -
Juninho_Oakley - 22.08.2011
Quote:
Originally Posted by Rodox_Mortein
|
Eu tambem ??