Advertisement
EnzoMetlc

[Include] PHY.inc

May 1st, 2016
233
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pawn 10.82 KB | None | 0 0
  1. /*
  2. * PHY.inc - Creado por EnzoMetlc, código base hecho por adri1.
  3. * http://forum.sa-mp.com/showthread.php?t=606272
  4. */
  5.  
  6. #if !defined PHY_MAX_SLOTS
  7. #define PHY_MAX_SLOTS               (50)
  8. #endif
  9.  
  10. #if !defined FLOAT_INFINITY
  11.     #define FLOAT_INFINITY      (Float:0x7F800000)
  12. #endif
  13.  
  14.  
  15.  
  16. /* Aceleraciones (por gravedad, por fricción) */
  17. #define PHY_GRAVITY                 (9.81)
  18. #define PHY_FRICTION                (5.0)
  19.  
  20. /* Modos */
  21. #define PHY_MODE_NONE               (0) // Movimiento inválido
  22. #define PHY_MODE_LAUNCH             (1) // Moviminto parabólico/oblicúo
  23. #define PHY_MODE_ROLL               (2) // Movimiento orizontal, (por ejemplo, rodar una pelota)
  24. #define PHY_MODE_VERTICAL           (3) // Movimiento vertical o caída libre.
  25.  
  26. /* Tipos */
  27. #define PHY_TYPE_NONE               (0)
  28. #define PHY_TYPE_VEHICLE            (1)
  29. #define PHY_TYPE_OBJECT             (2)
  30. #define PHY_TYPE_PLAYER             (3)
  31. #define PHY_TYPE_NPC                (4)
  32. #define PHY_TYPE_ACTOR              (5)
  33. #define PHY_TYPE_PICKUP             (6)
  34. #define PHY_TYPE_TEXTDRAW           (7)
  35.  
  36. /* Direcciones */
  37. #define PHY_DIRECTION_UP            (1)
  38. #define PHY_DIRECTION_DOWN          (0)
  39.  
  40.  
  41. /* Establecer valores */
  42. #define PHY_SetMode(%1,%2)          PHY_Info[%1][PHY_Mode]      = %2
  43. #define PHY_SetType(%1,%2)          PHY_Info[%1][PHY_Type]      = %2
  44. #define PHY_SetTypeID(%1,%2)        PHY_Info[%1][PHY_TypeID]    = %2
  45. #define PHY_SetSpeed(%1,%2)         PHY_Info[%1][PHY_Speed]     = %2
  46. #define PHY_SetAcc(%1,%2)           PHY_Info[%1][PHY_Acc]       = %2    // Recomendado: (-9.81) para Launch Mode, (-5.0) para Roll Mode
  47. #define PHY_SetAngle(%1,%2)         PHY_Info[%1][PHY_Angle]     = %2
  48. #define PHY_SetHeightAngle(%1,%2)   PHY_Info[%1][PHY_hAng]      = -(%2 - 90.0)
  49. #define PHY_SetBound(%1,%2)         PHY_Info[%1][PHY_Bound]     = %2
  50. #define PHY_RestartMovement(%1)     PHY_Info[%1][PHY_Tick]      = GetTickCount()
  51.  
  52. /* Extraer valores */
  53. #define PHY_GetMode(%1)             (PHY_Info[%1][PHY_Mode])
  54. #define PHY_GetType(%1)             (PHY_Info[%1][PHY_Type])
  55. #define PHY_GetTypeID(%1)           (PHY_Info[%1][PHY_TypeID])
  56. #define PHY_GetTick(%1)             (PHY_Info[%1][PHY_Tick])
  57. #define PHY_GetSpeed(%1)            (PHY_Info[%1][PHY_Speed])
  58. #define PHY_GetAcc(%1)              (PHY_Info[%1][PHY_Acc])
  59. #define PHY_GetAngle(%1)            (((PHY_Info[%1][PHY_Mode] == PHY_MODE_LAUNCH) ? (180.0) : (0.0)) + PHY_Info[%1][PHY_Angle]) // Areglar unos bugs de ángulos
  60. #define PHY_GetHeightAngle(%1)      (PHY_Info[%1][PHY_hAng] + 90.0)
  61. #define PHY_GetBound(%1)            (PHY_Info[%1][PHY_Bound])
  62.  
  63. /* Otros */
  64. #define PHY_Init()                  for(new phy_ii = 0; phy_ii < PHY_MAX_SLOTS; phy_ii++) PHY_Info[phy_ii][PHY_Mode] = -1
  65. #define PHY_Stop()                  KillTimer(PHY_Timer); PHY_Timer = -1
  66. #define PHY_IsValid(%1)             (PHY_Info[%1][PHY_Mode] != -1)
  67. #define PHY_GetPoolSize()           (PHY_PoolSize)
  68.  
  69.  
  70. enum PHY_Info_enum
  71. {
  72.     PHY_Mode,
  73.     PHY_Type,
  74.     PHY_TypeID,
  75.     PHY_Tick,           // Tiempo transcurrido (en mms)
  76.  
  77.     Float:PHY_fX,       // Posición X inicial
  78.     Float:PHY_fY,       // Posición Y inicial
  79.     Float:PHY_fZ,       // Posición Z inicial
  80.     Float:PHY_Speed,    // Velocidad inicial (V1)
  81.     Float:PHY_Acc,      // "Acceleration" o "Gravity (aceleración por la gravedad)", como quieras llamarlo...
  82.     Float:PHY_Angle,    // Ángulo de direción del movimiento
  83.     Float:PHY_hAng,     // Ángulo de altura del movimiento
  84.     Float:PHY_Bound,    // Launch Mode = límite Z, Roll Mode = distancia máxima
  85.     Float:PHY_LastPos,  // Última posición Z en Launch Mode, última distancia en Roll Mode. La utilizamos para saber cuándo finalizar el movimiento.
  86. };
  87. new PHY_Info[PHY_MAX_SLOTS][PHY_Info_enum];
  88. new PHY_PoolSize    = -1; // ID del último índice válido.
  89. new PHY_Timer       = -1; // ID del temporizador que actualiza el movimiento
  90.  
  91.  
  92.        
  93. /* Actualizar la posición del movimiento */
  94. forward PHY_UpdateMovement();
  95. public PHY_UpdateMovement()
  96. {
  97.     static Float:vX, Float:vY; // Velocidad XY
  98.     static Float:fX, Float:fY, Float:fZ; // Posición del movimiento
  99.     static Float:t, Float:d; // "tick" y "dist"
  100.     static i; // iterate
  101.  
  102.     for(i = 0; i <= PHY_PoolSize; i++)
  103.     {
  104.         switch(PHY_Info[i][PHY_Mode])
  105.         {
  106.             case PHY_MODE_LAUNCH:
  107.             {
  108.                 t   = float(GetTickCount() - PHY_Info[i][PHY_Tick]) / 1000.0; // tiempo transcurrido
  109.                 vX  = (PHY_Info[i][PHY_Speed] * floatsin(-PHY_Info[i][PHY_hAng], degrees)) * t; // dirección X|Y
  110.                 vY  = (PHY_Info[i][PHY_Speed] * floatcos(-(PHY_Info[i][PHY_hAng]), degrees)) * t; // dirección Z
  111.  
  112.                 fX  = PHY_Info[i][PHY_fX] + (vX * floatsin(-(PHY_Info[i][PHY_Angle]), degrees));
  113.                 fY  = PHY_Info[i][PHY_fY] + (vX * floatcos(-(PHY_Info[i][PHY_Angle]), degrees));
  114.                 fZ  = (PHY_Info[i][PHY_fZ] + vY) + ((PHY_Info[i][PHY_Acc] / 2.0) * (t * t));
  115.  
  116.                 if(!(PHY_Info[i][PHY_LastPos] > fZ && fZ < PHY_Info[i][PHY_Bound])) // Si no llegó al limite Z
  117.                 {
  118.                     PHY_OnUpdate(i, fX, fY, fZ, PHY_Info[i][PHY_Speed], floatround(t * 1000.0), fZ > PHY_Info[i][PHY_LastPos]);
  119.                     PHY_Info[i][PHY_LastPos] = fZ;
  120.                 }
  121.                 else PHY_OnFinish(i, fX, fY, PHY_Info[i][PHY_Bound], PHY_Info[i][PHY_Speed], floatround(t * 1000.0));
  122.             }
  123.             case PHY_MODE_ROLL:
  124.             {
  125.                 t       = float(GetTickCount() - PHY_Info[i][PHY_Tick]) / 1000.0; // tiempo transcurrido
  126.                 d       = (PHY_Info[i][PHY_Speed] * t) + ((PHY_Info[i][PHY_Acc] * (t * t)) / 2.0); // distancia recorrida - utiizamos la fórumula de espacio: V1 * t + ((acc * t^2) / 2)
  127.                 fX      = PHY_Info[i][PHY_fX] + (d * floatsin(-PHY_Info[i][PHY_Angle], degrees));
  128.                 fY      = PHY_Info[i][PHY_fY] + (d * floatcos(-PHY_Info[i][PHY_Angle], degrees));
  129.                
  130.                 if(!(d > PHY_Info[i][PHY_Bound] || PHY_Info[i][PHY_LastPos] > d)) // Si no llegó o sobrepasó la distancia máxima o distancia límite
  131.                 {
  132.                     PHY_OnUpdate(i, fX, fY, PHY_Info[i][PHY_fZ], PHY_Info[i][PHY_Speed] + PHY_Info[i][PHY_Acc] * t, floatround(t * 1000.0), -1);
  133.                     PHY_Info[i][PHY_LastPos] = d;
  134.                 }
  135.                 else // Si sobrepasa el límite de distancia máxima o si ya llegó a su distancia máxima posible (V2 = 0.0)
  136.                 {
  137.                     //t         = floatabs(PHY_Info[i][PHY_Speed] / PHY_Info[i][PHY_Acc]); // Tiempo total
  138.                     //t       = (t > 0) ? (t) : (float(GetTickCount() - PHY_Info[i][PHY_Tick]) / 1000.0); // Arreglar unos bugs
  139.                     d       = (PHY_Info[i][PHY_Speed] * t) + ((PHY_Info[i][PHY_Acc] * (t * t)) / 2.0); // Distancia total
  140.                     t       = floatsqroot((2.0 * d) / PHY_Info[i][PHY_Acc]); // Otra fórmula para obtener el tiempo total
  141.                     fX      = PHY_Info[i][PHY_fX] + (d * floatsin(-PHY_Info[i][PHY_Angle], degrees));
  142.                     fY      = PHY_Info[i][PHY_fY] + (d * floatcos(-PHY_Info[i][PHY_Angle], degrees));
  143.  
  144.                     PHY_OnFinish(i, fX, fY, PHY_Info[i][PHY_fZ], PHY_Info[i][PHY_Speed] + PHY_Info[i][PHY_Acc] * t, floatround(t * 1000.0));
  145.                 }
  146.             }
  147.             case PHY_MODE_VERTICAL: // Lo mismo que "PHY mode(PHY_MODE_LAUNCH) & h_ang(90.0)", pero se ejecuta mas rápido. Utiliza las mismas fórmulas que PHY_MODE_ROLL, pero en dirección vertical
  148.             {
  149.                 t       = float(GetTickCount() - PHY_Info[i][PHY_Tick]) / 1000.0;
  150.                 fX      = PHY_Info[i][PHY_fX];
  151.                 fY      = PHY_Info[i][PHY_fY];
  152.                 fZ      = PHY_Info[i][PHY_fZ] + ((PHY_Info[i][PHY_Speed] * t) - (-PHY_Info[i][PHY_Acc] * (t * t)) / 2.0);
  153.  
  154.                 if(fZ > PHY_Info[i][PHY_Bound]) PHY_OnUpdate(i, fX, fY, fZ, PHY_Info[i][PHY_Speed] + PHY_Info[i][PHY_Acc] * t, floatround(t * 1000.0), fZ > PHY_Info[i][PHY_LastPos]);
  155.                 else PHY_OnFinish(i, fX, fY, PHY_Info[i][PHY_Bound], PHY_Info[i][PHY_Speed] + PHY_Info[i][PHY_Acc] * t, floatround(t * 1000.0));
  156.                
  157.                 PHY_Info[i][PHY_LastPos] = fZ;
  158.             }
  159.         }
  160.     }
  161.     return 1;
  162. }
  163.  
  164.  
  165.  
  166. /* Funciones */
  167. stock PHY_Create(type_id, Float:fX, Float:fY, Float:fZ) // Buscar un slot disponible
  168. {
  169.     for(new i = 0; i < PHY_MAX_SLOTS; i++)
  170.     {
  171.         if(PHY_Info[i][PHY_Mode] == -1) // Encontramos un slot no usado
  172.         {
  173.             PHY_Info[i][PHY_Mode]   = PHY_MODE_NONE;
  174.             PHY_Info[i][PHY_TypeID] = type_id;
  175.             PHY_Info[i][PHY_fX]     = fX;
  176.             PHY_Info[i][PHY_fY]     = fY;
  177.             PHY_Info[i][PHY_fZ]     = fZ;
  178.            
  179.             if(i > PHY_PoolSize) PHY_PoolSize = i; // Este slot será el último disponible
  180.             return i;
  181.         }
  182.     }
  183.     return -1;
  184. }
  185.  
  186. stock PHY_Finish(slotid) // Finalizar un movimiento
  187. {
  188.     for(new i = 0; i < sizeof(PHY_Info[]); i++) PHY_Info[slotid][PHY_Info_enum:i] = 0;
  189.     PHY_Info[slotid][PHY_Mode] = -1;
  190.  
  191.     if(slotid == PHY_PoolSize) // Este es el último slot disponible, así que buscaremos uno nuevo
  192.     {
  193.         for(new i = PHY_PoolSize; i >= -1; i--) // Un bucle que va de mayor a menor
  194.         {
  195.             if(i > -1)
  196.             {
  197.                 if(PHY_Info[i][PHY_Mode] != -1 && i != slotid) // Encontramos un slot disponible, así que ése será el último
  198.                 {
  199.                     PHY_PoolSize = i;
  200.                     break;
  201.                 }
  202.                 continue;
  203.             }
  204.            
  205.             // No encontramos un slot disponible, o sea todos los movimientos ya no existen
  206.             KillTimer(PHY_Timer);
  207.             PHY_Timer = PHY_PoolSize = -1;
  208.         }
  209.     }
  210.     return 1;
  211. }
  212.  
  213. stock PHY_Start(slotid, mode = PHY_MODE_LAUNCH, interval = 20) // Comenzar el movimiento
  214. {
  215.     PHY_Info[slotid][PHY_Tick] = GetTickCount();
  216.     PHY_Info[slotid][PHY_Mode] = mode;
  217.     PHY_Info[slotid][PHY_Angle] -= (mode == PHY_MODE_LAUNCH) ? (180.0) : (0.0); // Arreglar algunos bugs de ángulos.
  218.    
  219.     if(PHY_Timer == -1 && PHY_PoolSize != -1) PHY_Timer = SetTimer("PHY_UpdateMovement", interval, true); // Comenzar el temporizador que actualizará TODOS los movimientos disponibles
  220.     return 1;
  221. }
  222.  
  223. stock PHY_SetPos(slotid, Float:fX, Float:fY, Float:fZ) // Establecer una nueva posición al movimiento
  224. {
  225.     PHY_Info[slotid][PHY_fX] = fX;
  226.     PHY_Info[slotid][PHY_fY] = fY;
  227.     PHY_Info[slotid][PHY_fZ] = fZ;
  228.     return 1;
  229. }
  230.  
  231.    
  232. forward PHY_OnUpdate(slotid, Float:fX, Float:fY, Float:fZ, Float:speed, tick, direction); // Cuando PHY_UpdateMovement es llamado
  233. forward PHY_OnFinish(slotid, Float:fX, Float:fY, Float:fZ, Float:speed, tick); // Cuando se termina el movimiento.
  234.  
  235. /* @Natives
  236.  
  237. native PHY_Create(type_id, Float:fX, Float:fY, Float:fZ);
  238. native PHY_Finish(slotid);
  239. native PHY_Start(slotid, mode = PHY_MODE_LAUNCH, interval = 20);
  240. native PHY_SetPos(slotid, Float:fX, Float:fY, Float:fZ);
  241.  
  242. native PHY_SetMode(slotid, mode);
  243. native PHY_SetType(slotid, type);
  244. native PHY_SetTypeID(slotid, type_id);
  245. native PHY_SetSpeed(slotid, Float:speed);
  246. native PHY_SetAcc(slotid, Float:acceleration);
  247. native PHY_SetAngle(slotid, Float:angle);
  248. native PHY_SetHeightAngle(slotid, Float:h_angle);
  249. native PHY_SetBound(slotid, Float:bound);
  250. native PHY_RestarMovement(slotid);
  251.  
  252. native PHY_GetMode(slotid);
  253. native PHY_GetType(slotid);
  254. native PHY_GetTypeID(slotid);
  255. native PHY_GetTick(slotid);
  256. native PHY_GetSpeed(slotid);
  257. native PHY_GetAcc(slotid);
  258. native PHY_GetAngle(slotid);
  259. native PHY_GetHeightAngle(slotid);
  260. native PHY_GetBound(slotid);
  261.  
  262. native PHY_Init();
  263. native PHY_Stop();
  264. native PHY_IsValid(slotid);
  265. native PHY_GetPoolSize();
  266. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement