Les variables qui contiennent les touches sont en fait des masques (1 bit pour chaque touche).
Donc lorsque l'on appuie sur KEY_FIRE, un certain bit de la variable va prendre la valeur 1.
Si on ne fait qu'appuyer sur la touche KEY_FIRE alors, et seulement dans ce cas, newkeys vaudra effectivement KEY_FIRE.
Mais si on appuie sur une autre touche, un autre bit sera positionné et la valeur de newkeys sera modifiée.
Il faut donc ne tester que le bit qui nous intéresse.
Pour ce faire, il faut utiliser l'opérateur & (et bit à bit).
Si je reprend ton bout de script il aurai fallu écrire :
public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
{
if((newkeys & KEY_FIRE) && GetPlayerWeapon(playerid) == 41)
{
SetTimerEx("OnPlayerSpray",2000,0,"d",playerid);
}
Explication :
KEY_FIRE vaut 4 soit 00000100 en binaire
KEY_SPRINT vaut 8 soit 00001000 en binaire.
Si le joueur appuie en même temps sur KEY_FIRE et KEY_SPRINT, la valeur de newkeys sera :
00001100 (=8+4=12).
On voit que cette valeur n'est égale ni à KEY_FIRE ni à KEY_SPRINT.
Par contre, si on fait un & entre newkeys et KEY_FIRE on obtient :
00001100 (newkeys)
00000100 (KEY_FIRE)
00000100 = KEY_FIRE
Le test correct devrait donc être
if ((newkeys & KEY_FIRE) == KEY_FIRE ...
Mais on peut simplifié car il suffit que (newkeys & KEY_FIRE) soit différent de 0 pour être sûr qu'il contient KEY_FIRE.
Autre exemple de test d'une touche qui n'est pas enfoncé (le joueur appuie en même temps sur KEY_FIRE et KEY_SPRINT) :
00001100 (newkeys)
00000010 (KEY_CROUCH=2, la touche qu'on veut tester)
00000000 (aucun bit positionné, la touche KEY_CROUCH n'est pas enfoncée)
++
Syg