Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * PHY.inc - Creado por EnzoMetlc, código base hecho por adri1.
- * http://forum.sa-mp.com/showthread.php?t=606272
- */
- #if !defined PHY_MAX_SLOTS
- #define PHY_MAX_SLOTS (50)
- #endif
- #if !defined FLOAT_INFINITY
- #define FLOAT_INFINITY (Float:0x7F800000)
- #endif
- /* Aceleraciones (por gravedad, por fricción) */
- #define PHY_GRAVITY (9.81)
- #define PHY_FRICTION (5.0)
- /* Modos */
- #define PHY_MODE_NONE (0) // Movimiento inválido
- #define PHY_MODE_LAUNCH (1) // Moviminto parabólico/oblicúo
- #define PHY_MODE_ROLL (2) // Movimiento orizontal, (por ejemplo, rodar una pelota)
- #define PHY_MODE_VERTICAL (3) // Movimiento vertical o caída libre.
- /* Tipos */
- #define PHY_TYPE_NONE (0)
- #define PHY_TYPE_VEHICLE (1)
- #define PHY_TYPE_OBJECT (2)
- #define PHY_TYPE_PLAYER (3)
- #define PHY_TYPE_NPC (4)
- #define PHY_TYPE_ACTOR (5)
- #define PHY_TYPE_PICKUP (6)
- #define PHY_TYPE_TEXTDRAW (7)
- /* Direcciones */
- #define PHY_DIRECTION_UP (1)
- #define PHY_DIRECTION_DOWN (0)
- /* Establecer valores */
- #define PHY_SetMode(%1,%2) PHY_Info[%1][PHY_Mode] = %2
- #define PHY_SetType(%1,%2) PHY_Info[%1][PHY_Type] = %2
- #define PHY_SetTypeID(%1,%2) PHY_Info[%1][PHY_TypeID] = %2
- #define PHY_SetSpeed(%1,%2) PHY_Info[%1][PHY_Speed] = %2
- #define PHY_SetAcc(%1,%2) PHY_Info[%1][PHY_Acc] = %2 // Recomendado: (-9.81) para Launch Mode, (-5.0) para Roll Mode
- #define PHY_SetAngle(%1,%2) PHY_Info[%1][PHY_Angle] = %2
- #define PHY_SetHeightAngle(%1,%2) PHY_Info[%1][PHY_hAng] = -(%2 - 90.0)
- #define PHY_SetBound(%1,%2) PHY_Info[%1][PHY_Bound] = %2
- #define PHY_RestartMovement(%1) PHY_Info[%1][PHY_Tick] = GetTickCount()
- /* Extraer valores */
- #define PHY_GetMode(%1) (PHY_Info[%1][PHY_Mode])
- #define PHY_GetType(%1) (PHY_Info[%1][PHY_Type])
- #define PHY_GetTypeID(%1) (PHY_Info[%1][PHY_TypeID])
- #define PHY_GetTick(%1) (PHY_Info[%1][PHY_Tick])
- #define PHY_GetSpeed(%1) (PHY_Info[%1][PHY_Speed])
- #define PHY_GetAcc(%1) (PHY_Info[%1][PHY_Acc])
- #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
- #define PHY_GetHeightAngle(%1) (PHY_Info[%1][PHY_hAng] + 90.0)
- #define PHY_GetBound(%1) (PHY_Info[%1][PHY_Bound])
- /* Otros */
- #define PHY_Init() for(new phy_ii = 0; phy_ii < PHY_MAX_SLOTS; phy_ii++) PHY_Info[phy_ii][PHY_Mode] = -1
- #define PHY_Stop() KillTimer(PHY_Timer); PHY_Timer = -1
- #define PHY_IsValid(%1) (PHY_Info[%1][PHY_Mode] != -1)
- #define PHY_GetPoolSize() (PHY_PoolSize)
- enum PHY_Info_enum
- {
- PHY_Mode,
- PHY_Type,
- PHY_TypeID,
- PHY_Tick, // Tiempo transcurrido (en mms)
- Float:PHY_fX, // Posición X inicial
- Float:PHY_fY, // Posición Y inicial
- Float:PHY_fZ, // Posición Z inicial
- Float:PHY_Speed, // Velocidad inicial (V1)
- Float:PHY_Acc, // "Acceleration" o "Gravity (aceleración por la gravedad)", como quieras llamarlo...
- Float:PHY_Angle, // Ángulo de direción del movimiento
- Float:PHY_hAng, // Ángulo de altura del movimiento
- Float:PHY_Bound, // Launch Mode = límite Z, Roll Mode = distancia máxima
- Float:PHY_LastPos, // Última posición Z en Launch Mode, última distancia en Roll Mode. La utilizamos para saber cuándo finalizar el movimiento.
- };
- new PHY_Info[PHY_MAX_SLOTS][PHY_Info_enum];
- new PHY_PoolSize = -1; // ID del último índice válido.
- new PHY_Timer = -1; // ID del temporizador que actualiza el movimiento
- /* Actualizar la posición del movimiento */
- forward PHY_UpdateMovement();
- public PHY_UpdateMovement()
- {
- static Float:vX, Float:vY; // Velocidad XY
- static Float:fX, Float:fY, Float:fZ; // Posición del movimiento
- static Float:t, Float:d; // "tick" y "dist"
- static i; // iterate
- for(i = 0; i <= PHY_PoolSize; i++)
- {
- switch(PHY_Info[i][PHY_Mode])
- {
- case PHY_MODE_LAUNCH:
- {
- t = float(GetTickCount() - PHY_Info[i][PHY_Tick]) / 1000.0; // tiempo transcurrido
- vX = (PHY_Info[i][PHY_Speed] * floatsin(-PHY_Info[i][PHY_hAng], degrees)) * t; // dirección X|Y
- vY = (PHY_Info[i][PHY_Speed] * floatcos(-(PHY_Info[i][PHY_hAng]), degrees)) * t; // dirección Z
- fX = PHY_Info[i][PHY_fX] + (vX * floatsin(-(PHY_Info[i][PHY_Angle]), degrees));
- fY = PHY_Info[i][PHY_fY] + (vX * floatcos(-(PHY_Info[i][PHY_Angle]), degrees));
- fZ = (PHY_Info[i][PHY_fZ] + vY) + ((PHY_Info[i][PHY_Acc] / 2.0) * (t * t));
- if(!(PHY_Info[i][PHY_LastPos] > fZ && fZ < PHY_Info[i][PHY_Bound])) // Si no llegó al limite Z
- {
- PHY_OnUpdate(i, fX, fY, fZ, PHY_Info[i][PHY_Speed], floatround(t * 1000.0), fZ > PHY_Info[i][PHY_LastPos]);
- PHY_Info[i][PHY_LastPos] = fZ;
- }
- else PHY_OnFinish(i, fX, fY, PHY_Info[i][PHY_Bound], PHY_Info[i][PHY_Speed], floatround(t * 1000.0));
- }
- case PHY_MODE_ROLL:
- {
- t = float(GetTickCount() - PHY_Info[i][PHY_Tick]) / 1000.0; // tiempo transcurrido
- 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)
- fX = PHY_Info[i][PHY_fX] + (d * floatsin(-PHY_Info[i][PHY_Angle], degrees));
- fY = PHY_Info[i][PHY_fY] + (d * floatcos(-PHY_Info[i][PHY_Angle], degrees));
- 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
- {
- 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);
- PHY_Info[i][PHY_LastPos] = d;
- }
- else // Si sobrepasa el límite de distancia máxima o si ya llegó a su distancia máxima posible (V2 = 0.0)
- {
- //t = floatabs(PHY_Info[i][PHY_Speed] / PHY_Info[i][PHY_Acc]); // Tiempo total
- //t = (t > 0) ? (t) : (float(GetTickCount() - PHY_Info[i][PHY_Tick]) / 1000.0); // Arreglar unos bugs
- d = (PHY_Info[i][PHY_Speed] * t) + ((PHY_Info[i][PHY_Acc] * (t * t)) / 2.0); // Distancia total
- t = floatsqroot((2.0 * d) / PHY_Info[i][PHY_Acc]); // Otra fórmula para obtener el tiempo total
- fX = PHY_Info[i][PHY_fX] + (d * floatsin(-PHY_Info[i][PHY_Angle], degrees));
- fY = PHY_Info[i][PHY_fY] + (d * floatcos(-PHY_Info[i][PHY_Angle], degrees));
- 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));
- }
- }
- 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
- {
- t = float(GetTickCount() - PHY_Info[i][PHY_Tick]) / 1000.0;
- fX = PHY_Info[i][PHY_fX];
- fY = PHY_Info[i][PHY_fY];
- fZ = PHY_Info[i][PHY_fZ] + ((PHY_Info[i][PHY_Speed] * t) - (-PHY_Info[i][PHY_Acc] * (t * t)) / 2.0);
- 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]);
- 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));
- PHY_Info[i][PHY_LastPos] = fZ;
- }
- }
- }
- return 1;
- }
- /* Funciones */
- stock PHY_Create(type_id, Float:fX, Float:fY, Float:fZ) // Buscar un slot disponible
- {
- for(new i = 0; i < PHY_MAX_SLOTS; i++)
- {
- if(PHY_Info[i][PHY_Mode] == -1) // Encontramos un slot no usado
- {
- PHY_Info[i][PHY_Mode] = PHY_MODE_NONE;
- PHY_Info[i][PHY_TypeID] = type_id;
- PHY_Info[i][PHY_fX] = fX;
- PHY_Info[i][PHY_fY] = fY;
- PHY_Info[i][PHY_fZ] = fZ;
- if(i > PHY_PoolSize) PHY_PoolSize = i; // Este slot será el último disponible
- return i;
- }
- }
- return -1;
- }
- stock PHY_Finish(slotid) // Finalizar un movimiento
- {
- for(new i = 0; i < sizeof(PHY_Info[]); i++) PHY_Info[slotid][PHY_Info_enum:i] = 0;
- PHY_Info[slotid][PHY_Mode] = -1;
- if(slotid == PHY_PoolSize) // Este es el último slot disponible, así que buscaremos uno nuevo
- {
- for(new i = PHY_PoolSize; i >= -1; i--) // Un bucle que va de mayor a menor
- {
- if(i > -1)
- {
- if(PHY_Info[i][PHY_Mode] != -1 && i != slotid) // Encontramos un slot disponible, así que ése será el último
- {
- PHY_PoolSize = i;
- break;
- }
- continue;
- }
- // No encontramos un slot disponible, o sea todos los movimientos ya no existen
- KillTimer(PHY_Timer);
- PHY_Timer = PHY_PoolSize = -1;
- }
- }
- return 1;
- }
- stock PHY_Start(slotid, mode = PHY_MODE_LAUNCH, interval = 20) // Comenzar el movimiento
- {
- PHY_Info[slotid][PHY_Tick] = GetTickCount();
- PHY_Info[slotid][PHY_Mode] = mode;
- PHY_Info[slotid][PHY_Angle] -= (mode == PHY_MODE_LAUNCH) ? (180.0) : (0.0); // Arreglar algunos bugs de ángulos.
- if(PHY_Timer == -1 && PHY_PoolSize != -1) PHY_Timer = SetTimer("PHY_UpdateMovement", interval, true); // Comenzar el temporizador que actualizará TODOS los movimientos disponibles
- return 1;
- }
- stock PHY_SetPos(slotid, Float:fX, Float:fY, Float:fZ) // Establecer una nueva posición al movimiento
- {
- PHY_Info[slotid][PHY_fX] = fX;
- PHY_Info[slotid][PHY_fY] = fY;
- PHY_Info[slotid][PHY_fZ] = fZ;
- return 1;
- }
- forward PHY_OnUpdate(slotid, Float:fX, Float:fY, Float:fZ, Float:speed, tick, direction); // Cuando PHY_UpdateMovement es llamado
- forward PHY_OnFinish(slotid, Float:fX, Float:fY, Float:fZ, Float:speed, tick); // Cuando se termina el movimiento.
- /* @Natives
- native PHY_Create(type_id, Float:fX, Float:fY, Float:fZ);
- native PHY_Finish(slotid);
- native PHY_Start(slotid, mode = PHY_MODE_LAUNCH, interval = 20);
- native PHY_SetPos(slotid, Float:fX, Float:fY, Float:fZ);
- native PHY_SetMode(slotid, mode);
- native PHY_SetType(slotid, type);
- native PHY_SetTypeID(slotid, type_id);
- native PHY_SetSpeed(slotid, Float:speed);
- native PHY_SetAcc(slotid, Float:acceleration);
- native PHY_SetAngle(slotid, Float:angle);
- native PHY_SetHeightAngle(slotid, Float:h_angle);
- native PHY_SetBound(slotid, Float:bound);
- native PHY_RestarMovement(slotid);
- native PHY_GetMode(slotid);
- native PHY_GetType(slotid);
- native PHY_GetTypeID(slotid);
- native PHY_GetTick(slotid);
- native PHY_GetSpeed(slotid);
- native PHY_GetAcc(slotid);
- native PHY_GetAngle(slotid);
- native PHY_GetHeightAngle(slotid);
- native PHY_GetBound(slotid);
- native PHY_Init();
- native PHY_Stop();
- native PHY_IsValid(slotid);
- native PHY_GetPoolSize();
- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement