Salut à tous,
alors je vais expliqué rapidement ce que j'ai compris aux différents opérateurs présents en pawn,
si vous vous y connaissez bien, je vous prie de bien ajouter vos connaissances...
L'opérateur '!':Le point d'exclamation (appelé NOT) permet d'inverser les bits d'une variable:
!true =
falseon peut en déduire que
!false =
trueDonc, dans une variable on obtient ceci:
EXEMPLE:
!010111000011101011qui est équivalent à:
101000111100010100(tous les 1 deviennent des 0 et vice versa)
ainsi, utilisé dans un if(....) il permet de vérifier si une expression est fausse et non vrai ( if(!...) )
Les strings compressés :Le point d'exclamation peut également servir à la création de "packed string", soit des string compressés,
Il est évident que ceci permet de sauver une grande quantité de mémoire, par contre la plupart des fonction en pawn ne supportent pas les string compressés.
Ainsi, il est plutôt rares qu'ils soient utilisés.
vous pouvez créer des string compressés à la base dès leur création:
new string[12] = "Salut à tous";//12 cell 48 bytes
new string[12 char] = !"Salut à tous";//3 cell 12 bytes
Comme on peut le voir d'après les commentaires (code original de Y_Less), le string compressé est 4 fois plus petit.
Il existe également deux fonctions dans le string.inc qui permettent de compresser/décompresser des string, il s'agit de strpack et strunpack
strpack(dest[],const source[],maxlenght) -
dest: Le string de destination (sous la forme var[nb char]
-
source: le string d'où provient les données
-
maxlenght: la longueur maximale de la chaîne à copier (paramètre optionnel)
strunpack(dest[],const source[],maxlenght) -
dest: Le string de destination (string décompressé)
-
source: le string d'où proviennent les données compressées
-
maxlenght: la longueur maximale de la chaîne de caractère à décompresser
Le caractère '=' :Seul, le signe = change la valeur de la variable de gauche pour la valeur de celle de droite(dans le sens <<------), souvent employé comme ceci:
time = GetTickCount();
Il en va ainsi pour toutes les variables,
par contre il faut l'employé avec une certaine précaution, seules les variables(j'entend ainsi également les valeurs retournés par les fonctions) de même type peuvent être impliqués dans les '='
EXEMPLE:
new Float:x,nb,string[128],string2[64],Float:y,maVar;
//les expressions suivantes sont fausses:
x=nb;//type de variable différent
string = string2//longueur de string différent
maVar = y;//type différent
y=string;//type différent
//Les expressions suivantes sont vraies:
x=maVar;//deux entiers
x=y;//deux float
format(string,sizeof(string),"%s",string2);//ici on change les caractère de string pour devenir ceux de string2, du moins en partie (car string plus long que string2)
nb = string[34];//comme l'on prend seulement le 34e caractère, il s'agit d'un nombre entier tout comme nb, donc aucun problème ici
maVar=floatround(y);//on arrondi le nombre à virgule, donc on obtient un entier
Le caractère '==' :Il s'agit d'un opérateur logique d'égalité, employé pour les conditions, la valeur retournée est
true si l'expression de droite à la même valeur que l'expression de gauche,
false dans le cas contraire.
Note : On ne peut comparé deux string de cette façon, la façon de faire est dans l'exemple suivant
L'utilisation de cet opérateur se fait comme suit:
new int1 = 3;
new int2 = 45;
new int3 = 3;
if(int1 == 3)//on compare avec une valeur constante
{
//le code suivant sera exécuté
}
if(int2 == 34)
{
//le code suivant ne sera pas exécuté (int2 n'égale pas 45)
}
if(int1 == int3)//on compare les variables entre eux
{
//le code suivant sera exécuté
}
if(int2 == int3)
{
//le code suivant ne sera pas exécuté
}
if(GetPlayerVehicleID == int2)//ici on compare la valeur retourné par la fonction et la variable
{
//le code suivant sera peut-être exécuté, dépendant de la valeur retournée par la fonction
}
new Float:float1 = 34.3453;
new Float:float2 = 456.5461;
new Float:float3 = 34.3453;
new Float:x,Float:y,Float:z;
GetPlayerPos(23,x,y,z);//on récupère la position du joueur numéro 23
if(float1 == float3)//on compare les deux variable
{
//ce code sera exécuté
}
if(float2 == 345.231)//compare une variable à virgule avec un nombre à virgule constant
{
//ce code ne sera pas exécuté
}
if(float2 == y)/on compare le y du GetPlayerPos avec la float2
{
//ce code peut être exécuté selon la position du joueur 23
}
L'opérateur logique '&':Si vous ne savez pas ce qu'est un bit, je vous suggère de sauter cette partie.
Seul '&' permet la comparaison de bits (il s'agit en quelque sorte d'un ET),
si le bit que l'on vérifie est à 1, la valeur retournée est vraie,
par exemple si l'on veut extraire le 4e bit d'une variable quelconque:
new variable = 857;
if(variable & 16)..//si la variable à le 4e bit à 1...
Il est possible de créer une fonction afin de déterminer si un nombre est pair ou impair grâce à cet opérateur:
stock IsImpair(Number)
{
return number & 1;
}
Encore, il est possible d'améliorer cette fonction à l'aide de DEFINE (voir plus bas)
#define IsImpair(%0) %0 & 1
L'opérateur logique '&&':Le symbole
&& il constitue l'opérateur de logique "ET", il permet d'ajouter une condition à un if , d'une certaine façon
EXEMPLE:
if(IsPlayerConnected(playerid) && IsPlayerInAnyVehicle(playerid))....//ce code ne s'exécutera que si le joueur est connecté ET dans un véhicule
Les opérateurs '<', '>', '<='et '>=' :Ils permettent de vérifier quelle valeur de celle de gauche ou de droite est la plus grande.
Ils peuvent également être accompagnés de l'opérateur '=' afin d'accepter également la possibilité d'une égalité..
Bref,
- '<' => Plus petit que....
- '>' => Plus grand que....
- '>=' => Plus grand ou égal à....
- '<=' => Plus petit ou égal à....
new local1 = 2,
local2 = 3,
local3 = 2;
if(local1 < local2)...//le code sera exécuté car local1 est plus petit que local2
if(local1 < local3)...//ne sera pas exécuté car local1 n'est pas plus petit que local2
if(local1 <= local3)....//sera exécuté car local1 est égale à local3
if(local2 > local3)....//sera exécuté car local2 est plus grand que local3
Les opérateurs '<<'et '>>' :Ces opérateurs permettent de faire des opération bits à bits, << permet de décaler des bits vers la gauche (division par deux) tandis que '>>' décale plutôt les bits vers la droite, une multiplication par 2
NB : Dans les décalages de bits, les bits qui "sortent" par la gauche ou la droite sont perdus. Ainsi (13>>2)<<2 ne donnera pas 13 mais 12if ((a << 30) >>> 31)
L'opérateur '|' :Seul '|' est un OU bit à bit
EXEMPLE:
0|0 = 0
1|0 = 1
0|1 = 1
1|1 = 1
L'opérateur '||' :Il correspond à l'opérateur logique "ou" dans toute condition
Dès qu'une des valeurs est vraie, l'expression retourne vrai (voir exemple)
EXEMPLE:
if(IsPlayerInAnyVehicle(playerid) || GetPlayerState(playerid) != PLAYER_STATE_ONFOOT)....//le joueur est dans un véhicule ou encore il n'est pas à pied
Le mot clé 'if' :Il permet de faire un test de logique, les parenthèses le suivant continent une expression qui retourne une valeur, si cette expression est vraie, le code suivant le if (entre les {} la plupart du temps) sera exécuté, dans le cas contraire il sera sauté
EXEMPLE:
if(GetPlayerState(playerid) == PLAYER_STATE_DRIVER)//si le joueur conduit un véhicule
{
AddVehicleComponent(GetPlayerVehicleID(playerid),1010);//on lui donne de la nitro
}
Le mot clé 'else' :Il doit être utilisé de concert avec le mot clé
if et le code le suivant sera appelé si et seulement si le
if est faux et le code suivant le
if n'est pas exécuté.
EXEMPLE:
if(30 == 10)//expression évidemment fausse
{
AddVehicleComponent(GetPlayerVehicleID(playerid),1010);//on donne de la nitro
}
else
{
SendClientMessage(playerid,COLOR_RED,"Tu ne peut avoir de la nitro, car tu a été méchant ^^");
}
Le
else et le
if peuvent être combiné afin d'obtenir de multiples possibilités selon la valeur de différents paramètres, ce qui donne le mot clé
else ifEXEMPLE:
if(GetPlayerState(playerid) == PLAYER_STATE_DRIVER)//si le joueur conduit un véhicule
{
AddVehicleComponent(GetPlayerVehicleID(playerid),1010);//on lui donne de la nitro
}
else if(IsOn == 2)
{
SendClientMessage(playerid,COLOR_RED,"Tu ne peut avoir de la nitro, car tu a été méchant ^^");
}
else if(IsOn == 3)
{
SendClientMessage(playerid,COLOR_RED,"Tu ne peut avoir de la nitro, car tu n'as pas mangé ton gateau ^^");
}
else if(IsOn == 4)
{
SendClientMessage(playerid,COLOR_RED,"Tu ne peut avoir de la nitro, car tu n'as pas nourrit le chien ^^");
}
else
{
SendClientMessage(playerid,COLOR_RED,"Tu ne peut avoir de la nitro, car tu n,est pas en véhicule!");
}
Les FORWARD :le forward permet d'indiquer au compiler qu'une fonction existe avant qu'il ne la rencontre.
Si vous obtenez le warning "function used before definition, forcing reparse",
Placez un forward de votre fonction au haut de votre script où déplacez votre fonction afin de la placer avant son usage.
Notez bien que les fonction public ont obligatoirement besoin d'un forward
Les NEW :l'expression new indique au compiler que le mot suivant est une variable, cette variable peut être un texte, un nombre à virgule, un simple entier ou encore une valeur booléenne (vrai ou faux)
Par contre, afin de ne pas créer un simple entier, il faut placer un "tag" devant le nom de la variable (voir exemple)
EXEMPLES:
new entier;//un entier
new Float:NbVirgules;//un nombre a virgule (float en anglais pour floating point (point flottant, bref qui bouge^^))
new MyText[128];//un string, array, peut contenir du texte comme la suivante
new MyText2[] = "salut à tous!!!";//lorsque l'on place déjà un texte dans une variable, aucun besoin d'assigner une taille à la variable
new bool:MyBool;//on crée une variable booléenne (vrai ou faux)
new MyArray[32] = {-1,0,2,3,5,6,74,45...};//un array, contient différentes valeurs ayant toutes une signification quelconque;
Dans la même catégorie l'on retrouve également les
static qui sont en quelque sorte comme les new,
mais à l'exception qu'ils ne sont accessible que dans la section du script les contenant,
par exemple un static dans un include ne peut être utilisé dans le script, alors qu'un new le pourrait
Une notion importante en lien avec les NEW est bien entendu l'intialisation, c'est à dire l'assignement d'une valeur à la variable lors de sa création.
Il est possible d'assigner la valeur que l'on désire (en restant dans le bon type de variable) à la variable créée
EXEMPLE:
new playerid = 9;
new entier = playerid;
playerid = 13;
new entier2 = playerid;
entier = entier2;
Les '++' :Cet expression permet d'ajouter 1 à une valeur, généralement placé après une variable afin d'en augmenter la valeur de 1.
Il est à noter que ceci modifie la valeur de la variable en question.
EXEMPLES:
new entier = 6;//un entier
printf("%d",entier);//écrit 6
entier++;
printf("%d",entier);//écrit 7 (6+1)
Les '--' :Cet expression permet d'enlever 1 à une valeur, généralement placé après une variable afin d'en réduire la valeur de 1.
Il est à noter que ceci modifie la valeur de la variable en question.
EXEMPLES:
new entier = 6;//un entier
printf("%d",entier);//écrit 6
entier--;
printf("%d",entier);//écrit 5 (6-1)
Les '+=' :Cet expression permet d'ajouter une valeur à une valeur,
placé après une variable afin d'en augmenter la valeur du nombre suivant cet opérateur. (voir exemple)
Il est à noter que ceci modifie la valeur de la variable en question.
EXEMPLES:
new entier = 6;//un entier
printf("%d",entier);//écrit 6
entier+= 10;
printf("%d",entier);//écrit 16 (6+10)
Les '-=' :Cet expression permet d'enlever une valeur à une valeur,
généralement placé après une variable afin d'en réduire la valeur du nombre suivant cet opérateur (-=).(voir exemple)
Il est à noter que ceci modifie la valeur de la variable en question.
EXEMPLES:
new entier = 58;//un entier
printf("%d",entier);//écrit 58
entier-=25;
printf("%d",entier);//écrit 33 (58-25)
Les '*=' :Cet expression permet de multiplier la valeur de gauche par la valeur de droite.
Il est à noter que ceci modifie la valeur de la variable en question.
EXEMPLES:
new entier = 6;//un entier
printf("%d",entier);//écrit 6
entier*=5;
printf("%d",entier);//écrit 30 (6*5)
Les STOCK :un stock sert à déclaré une fonction ou une variable qui peut ne pas être utilisée, ce type d'initialisation est très utile dans les includes.
L'avantage du stock sur le
#pragma unused ... est que la fonction/variable déclaré en stock ne sera pas compilée si inutilisée, contrairement au
#pragma qui ne fait qu'éliminer l'avertissement
ainsi si je déclare la variable mais ne m'en sert pas, il n'y a aucun problème:
new stock myNumber = 5;
new ILike = 15;
printf("%d",ILike);
Dans ce code
myNumber ne sera pas compiler car il n'est pas utilisé
Par contre, dans le code suivant, elle le sera:
new stock myNumber = 5;
printf("%d",myNumber);
Les LOOPS :En tout premier lieu, vous devez savoir qu'il existe trois différents type de loops que l'on rencontre fréquemment sur les codes en PAWN pour SA-MP:
- Les do-while
- Les while
- Les for
Les DO-WHILE :Cette boucle suit la structure suivante:
do
{
......//votre code
}
while(//une condition);
ainsi le code passera en premier par le
do{....} et ce code sera exécuté, par la suite, si la condition est vraie, on refait le
do{....} ainsi de suite jusqu'à ce que la condition ne soit plus vraie.
Les WHILE :Cette boucle suit la structure suivante:
while(//une condition)
{
.....
}
Ainsi, le code test en premier lieu la condition et si elle s'avère vraie, le code contenu entre les {} sera exécuté, un fois cela fait, on retourne au début et si la condition est vraie, on recommence le code, sinon, on passe par dessus et continue la suite du code...
Ce genre de boucle est souvent utilisé avec la déclaration préalable d'une variable qui sera modifié dans le
while d'une façon où d'une autre...
Par exemple, pour arrêter un
timer, il serait possible, je dit bien possible de faire le code suivant:
new IsOk;
while(IsOk == 0)
{
IsOk = KillTimer(timerquelconque);
}
bien entendu, le résultat de cette loop est quelque peut étrange (je ne suis pas sûr d'où vient la plupart des problèmes de
timers qui ne se stoppent pas, mais s'il s'agit de la fonction qui ne fonctionne pas correctement, ceci devrait corrigé le problème.
P.S. il est cité dans le wiki que plusieurs fonction ne retournent aucune valeurs spécifique, or dans la plupart des cas une valeur est retourné, vrai si la fonction à réussi, faux dans le cas contraire
Les FOR :Cette boucle suit la structure suivante:
for(new i = 0; i<VALEUR; i++)
{
.....
}
Donc, à voir la structure de cette loop, on voit aisément qu'une variable doit être déclaré, on pose ensuite une condition, et une variation de cette variable à chaque fois que le code est exécuté.
La loop précédante serait aussi équivalente à:
new i;
while(i<VALEUR)
{
......
i++;
}
Il est également possible d'ajouter certaines déclaration dans cette loop, par exemple une nouvelle variable et l'appel à une fonction afin d'obtenir une valeur:
for(new i = 0,j = getMaxPlayers(); i<j; i++)
{
...
}
Les SWITCH :En tout premier lieu, qu'es-ce qu'un
switch?
Un
switch est un opérateur logique un peu dans le genre du
if/else if/... et sert à principalement à remplacer une longue série de
if/else ifIl s'écrit de la façon suivante:
switch(variable ou expression)
{
case /*les/la valeur(s) pour lesquelles la même action sera exécutés/*:
{
....
}
case/*d'autre(s) valeur(s) pour lesquelles on exécutera le même code*/:
{
....
}
default:
{
//tous les cas qui ne sont pas énumérés plus haut
}
}
Le principal avantage d'un
switch, est la possibilité de regroupé différentes valeurs ensemble afin de simplifier l'écriture du code.
D'un autre côté, son principal défaut est l'impossibilité de placer comme valeur désirée une variable, il faut absolument y placer une constante, ici je parle des valeurs dans les
case, la valeur dans le
switch() peut bien évidemment être une variable.
Les CASE :Cette expression est utilisé de concert avec les
switch, il s'agit de l'expression qui indique au programme que les valeurs le suivant et devant les
':' sont les valeurs à rechercher
(EXEMPLE: voir code ci-dessus)
Les DEFAULT :Cette expression est utilisé de concert avec les
switch,
il peut être pris en compte comme un case, à la différence qu'il doit être à la fin et suivit d'aucune valeur.
Il s'agit du code qui sera appelé si aucune des autres valeurs n'a été appelée, de son nom, la valeur par défaut.
(EXEMPLE: voir code ci-dessus)
Les Directives de compilation:Les '#define' :Ces expressions peuvent avoir trois différentes utilités:
Éviter de compilé certaines partie de code que l'on ne désire pas, on en retrouve un exemple parfait dans le new.pwn que l'on retrouve dans le dossier pawno
EXEMPLE:
#define USE_LANGUE_SYS
#if defined USE_LANG_SYS
SendMsg(playerid........);
#else
SendClientMessage(playerid.....);
#endif
Les autres expressions contenues dans cet exemples seront cités plus loin
Les define peuvent servir à définir des valeurs reprise à plein d'endroit, afin de pouvoir en changer la valeur aisément.
Il suffit que de penser à l'expression
MAX_PLAYERS définie par a_samp.inc
EXEMPLE:
#define NOMBRE_DE_KICK_AVANT_BAN 3
public OnPlayerDisconnect(playerid,reason)
{
if(KickCount[playerid] == NOMBRE_DE_KICK_AVANT_BAN)Ban(playerid);
}
Et nous arrivons à l'utilité la moins utilisé: la création de simples fonctions.
Les defines peuvent prendres certains paramètres variables, il faut alors les représenter par %(nombre)
EXEMPLE:
#define dcmd(%1,%2,%3) if ((strcmp((%3)[1], #%1, true, (%2)) == 0) && ((((%3)[(%2) + 1] == 0) && (dcmd_%1(playerid, "")))||(((%3)[(%2) + 1] == 32) && (dcmd_%1(playerid, (%3)[(%2) + 2]))))) return 1
Les '#if' :sert à faire un test directement par le compiler, ainsi si certaines expressions sont vraies, défini, on peut ajouter ou non une partie de code
EXEMPLE:
#define USE_POWER
#if defined USE_POWER
#include .....inc
#else
#error Could not load include
#endif
Les '#else' :Si le premier test avec un #if était faut, ce qui suit sera pris en compte
(voir exemple au dessus)
Les '#endif' :sert à fermer un #if , exactement comme un '}' avec un if normal
(voir exemple au dessus)
Pour une liste complète, mais en anglais:
http://forum.sa-mp.co.uk/index.php/topic,248.0.html#post_directives
REMERCIEMENTS:Un énorme merci à Syg pour toutes ses précisions, ajouts et corrections
Merci à [viruz]rider_77 pour ses suggestions d'ajouts
Merci à Bayshore pour sa suggestion
Pour conclure,j'espère bien vous avoir appris au moins 2 ou 3 trucs dans ce petit tuto,
merci de votre attention ;)
++Sim++