[Tutorial] Comprobando y modificando el estado de las puertas
#1

Introducciуn

En este tutorial les explicarй como saber el estado de las puertas de los autos, con puertas me refiero a las delanteras, cofre (capу) y cajuela (maletero), las puertas traseras no son sincronizadas por SA-MP, por lo tanto no se incluyen aqui.

Conocimientos previos

Debido a que los estados se manejan en binario hay que tener conocimientos previos que son los siguientes:
  • Las variables comъnes en PAWN son de 32 bits, por lo que significa que estб compuesto por 32 digitos en 0 y 1, dividos en grupos de 4 bytes (8 bits)
  • Binario
  • Operadores de bits
  • Operador ternario (opcional)
Contenido
  • Comprobaciуn
  • Modificaciуn
* Comprobaciуn

El estado se obtiene mediante la funcion GetVehicleDamageStatus, que retorna un numero para los diferentes estados, dicho numero estб hecho en base a operadores de bits, dichos operadores son los que usaremos para leer y escribir el estado.

Para empezar, leemos el estado de las puertas en decimal.
pawn Код:
new panels,doors,lights,tires;
GetVehicleDamageStatus(vehicleid,panels,doors,lights,tires);
printf("Vehicle Status : [Panels] : %d - [Doors] : %d - [Lights] : %d - [Tires] : %d",panels,doors,lights,tires);
Tomando como ejemplo el numero de la wiki, doors vale 16909060, en este numero estб cada estado de las puertas, bueno pues para poder entender su funcionamiento hay que convertirlo a binario, dicho numero es

Код:
00000001000000100000001100000100
Cada byte del numero anterior contiene informaciуn para las puertas, bien, para comprender aun mejor lo separamos en bytes ( 8 bits )

Код:
00000001 00000010 00000011 00000100
Ahora, їquй almacena cada byte?

Leyendo los bytes de derecha a izquierda:
  • El primer byte almacena el estado del cofre/capу
  • El segundo byte almacena el estado de la cajuela/maletero
  • El tercer byte el estado de la puerta del conductor (izquierda)
  • El cuarto byte el estado de la puerta del co-piloto (derecha)
Bien, ahora que los tenemos divididos en bytes, їquй almacena cada bit (dнgito)?

Leyendo los bits de derecha a izquierda:
  • El pimer bit contiene informacion si la puerta estб abierta (1) o no (0)
  • El segundo bit contiene informacion si la puerta estб daсada (1) o no (0)
  • El tercer bit contiene informacion si la puerta estб caнda/removida (1) o adherida (0)
Listo, totalmente comprensible, asн nosotros podemos deducir el estado de cada cosa con tan solo verlo, pero ese no es el caso, si no saberlo con programaciуn.

Yo lo harй de la forma mas comprensible (al menos para mi) y me basarй en el estado de la cajuela/maletero

Para empezar, debemos obtener este byte (tercer) en una variable aparte, no es necesario haciendolo con el otro mйtodo, pero como dije es mбs comprensible... Bueno lo hacemos desplazando 8 bits a la derecha y apagamos los demбs.

Код:
Desplazamos los primeros 8 a la derecha.

00000001000000100000001100000100 >> 8 =
00000000000000010000001000000011

Ahora apagamos el resto para que sea el tercer byte el ъnico que nos quede en la nueva variable,
esto lo hacemos con el operador AND y con el valor de 255 o 0xFF en hex

00000000000000010000001000000011 &
00000000000000000000000011111111 =
00000000000000000000000000000011
El cуdigo equivalente en PAWN serнa
pawn Код:
new cajuela = (doors >> 8) & 0xFF;
Ahora para poder saber los 3 estados posibles de la puerta, haremos lo mismo para cada bit, apagamos los demas y comprobamos si el numero es mayor a 0

Код:
00000011 &
00000001 =
00000001  // Este es 1, mayor de 0 = estб abierta
pawn Код:
if(cajuela & 1)
{
    // abierta
}
printf("La puerta %s", (cajuela & 1)?("esta abierta"):("esta cerrada")); // esta abierta
Eso fue para el primer bit, ahora haremos para el segundo y tercer bit (daсo y posicion)

Код:
00000011 &
00000010 =
00000010  // Este es 2, mayor de 0 = estб daсada

00000011 &
00000100 =
00000000  // Este es cero = no estб caнda
pawn Код:
if(cajuela & 2)
{
    // daсada
}
if(cajuela & 4)
{
   // caнda
}

printf("La puerta %s\n", (cajuela & 2)?("esta daсada"):("no esta daсada"));
printf("La puerta %s\n", (cajuela & 4)?("esta caнda/removida"):("esta en su lugar"));
* Modificaciуn
La modificaciуn es un poco mбs complejo por el hecho de que hay que apagar o encender determinados bits y guardarlos en la variable, la modificaciуn consta de varias formas, por lo que mejor hice una pequeсa funciуn para acortar las cosas


En este caso usaremos el estado de la puerta del copiloto (derecha), para eso desplazamos 24 bits a la derecha ya que es el ultimo byte

Код:
00000001000000100000001100000100 >> 24 =
00000000000000000000000000000001
pawn Код:
stock decodificar(door, &o, &d, &r)
{
   o = door & 1;
   d = (door >> 1) & 1;
   r = (door >> 2) & 1;
}

stock codificar(o, d, r)
{
    /*
    o = abierta (1), cerrada (0)
    d = daсada (1), no daсada (0)
    r = removida (1), no removida(0)
    */

    return o | ( d << 1) | (r << 2);
}


new panels, doors, lights, tires;  
GetVehicleDamageStatus(vehicleid, panels, doors, lights, tires);
new copiloto = doors >> 24;

new o, d, r;
decodificar(copiloto, o, d, r);
copiloto = codificar(o, 1, r);

doors |= (copiloto << 24);
UpdateVehicleDamageStatus(vehicleid, panels, doors, lights, tires);

Una buena calculadora para poder realizar todas sus operaciones es esta: http://calc.50x.eu/
Cualquier duda que tengan, pregunten aquн, si me he equivocado en algo, hacermelo saber para repararlo

Referencias:
https://sampwiki.blast.hk/wiki/DoorStates
Reply
#2

Me parece muy interesante,Voy a descargar el tema y luego lo leo con mбs calma
Reply
#3

Buen tutorial, un buen uso de los operadores de bits que estбn un poco en desuso si no es en colores y teclas. Hay gente que le va a servir.
Reply
#4

Encantado, creo que con esto muchos querrбn saber un poco mas de binarios y sus operadores.
Reply
#5

Quote:
Originally Posted by Josstaa
Посмотреть сообщение
[B][U][SIZE="4"]Yo lo harй de la forma mas comprensible (al menos para mi) y me basarй en el estado del cofre/capу
Si no me estoy equivocando seria la cajuela/maletero.

Код:
->Inicial:

puerta A puerta B  cajuela   capу
00000001 00000010 00000011 00000100


->Luego del shift

    -    puerta A puerta B cajuela
00000000 00000001 00000010 00000011


->Luego del AND
    -    puerta A puerta B cajuela
00000000 00000000 00000000 00000011
Aqui hay un buen ejemplo completo de la funcion GetVehicleDamageStatus, el cual simplifica mucho su uso: http://forum.sa-mp.com/showpost.php?...9&postcount=12
Reply
#6

Quote:
Originally Posted by the_chaoz
Посмотреть сообщение
Si no me estoy equivocando seria la cajuela/maletero.

Код:
->Inicial:

puerta A puerta B  cajuela   capу
00000001 00000010 00000011 00000100


->Luego del shift

    -    puerta A puerta B cajuela
00000000 00000001 00000010 00000011


->Luego del AND
    -    puerta A puerta B cajuela
00000000 00000000 00000000 00000011
Tienes razуn, es la cajuela, me equivoque

Quote:
Originally Posted by the_chaoz
Посмотреть сообщение
Aqui hay un buen ejemplo completo de la funcion GetVehicleDamageStatus, el cual simplifica mucho su uso: http://forum.sa-mp.com/showpost.php?...9&postcount=12
Pude hacerlo de esa manera, pero intentй detallarlo mejor
Reply
#7

El link lo deje porque tiene metodos mas simples/abreviados, pero tu explicacion es mucho mejor.
Reply
#8

Y yo que en tiempos pasados lo hice de otra manera creyendo tener el mejor y ъnico mйtodo

http://forum.sa-mp.com/showpost.php?...&postcount=352
http://forum.sa-mp.com/showpost.php?...&postcount=354
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)