Advertisement
Guest User

Untitled

a guest
Jul 2nd, 2013
179
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pawn 19.36 KB | None | 0 0
  1. /*
  2.  * SA-MP Spike Strips
  3.  *
  4.  * Copyright (c) 2013, Stylock
  5.  * This file is provided as is with no warranties of any kind.
  6.  */
  7.  
  8. #include <foreach>
  9. #include <YSI\y_hooks>
  10.  
  11. #include debug
  12.  
  13. /*
  14.  * SA-MP Spike Strips
  15.  *
  16.  * Copyright (c) 2013, Stylock
  17.  * This file is provided as is with no warranties of any kind.
  18.  */
  19.  
  20. #define MAX_SPIKE_STRIPS    (128)
  21. #define SS_TIME_INTERVAL    (250)
  22. #define SS_LINE_SEGMENTS    (4) // 1, 2 or 4
  23.  
  24. // Spike strip models
  25. #define SPIKE_STRIP_LONG    (2892)
  26. #define SPIKE_STRIP_SHORT   (2899)
  27.  
  28. /*
  29. native SpikeStrip_Create(modelid, Float:x, Float:y, Float:z, Float:angle, bool:FindZ = true);
  30. */
  31.  
  32. /*
  33. native SpikeStrip_Delete(spikeid);
  34. */
  35.  
  36. forward OnSpikeStripPop(vehicleid, spikeid);
  37.  
  38. static stock
  39.     g_SpikeStrip[MAX_SPIKE_STRIPS],
  40.     Iterator:g_Spike<MAX_SPIKE_STRIPS>,
  41.     Float:g_Spike_x1[MAX_SPIKE_STRIPS],
  42.     Float:g_Spike_y1[MAX_SPIKE_STRIPS],
  43.     Float:g_Spike_x2[MAX_SPIKE_STRIPS],
  44.     Float:g_Spike_y2[MAX_SPIKE_STRIPS],
  45.     Float:g_Spike_x3[MAX_SPIKE_STRIPS],
  46.     Float:g_Spike_y3[MAX_SPIKE_STRIPS],
  47.     Float:g_Spike_x4[MAX_SPIKE_STRIPS],
  48.     Float:g_Spike_y4[MAX_SPIKE_STRIPS],
  49.     Float:g_Spike_zA[MAX_SPIKE_STRIPS],
  50.     Float:g_Tire1_x1[MAX_PLAYERS],
  51.     Float:g_Tire1_y1[MAX_PLAYERS],
  52.     Float:g_Tire1_z1[MAX_PLAYERS],
  53.     Float:g_Tire1_x2[MAX_PLAYERS],
  54.     Float:g_Tire1_y2[MAX_PLAYERS],
  55.     Float:g_Tire1_z2[MAX_PLAYERS],
  56.     Float:g_Tire1_x3[MAX_PLAYERS],
  57.     Float:g_Tire1_y3[MAX_PLAYERS],
  58.     Float:g_Tire1_z3[MAX_PLAYERS],
  59.     Float:g_Tire1_x4[MAX_PLAYERS],
  60.     Float:g_Tire1_y4[MAX_PLAYERS],
  61.     Float:g_Tire1_z4[MAX_PLAYERS],
  62.     Float:g_Tire2_x1[MAX_PLAYERS],
  63.     Float:g_Tire2_y1[MAX_PLAYERS],
  64.     Float:g_Tire2_x2[MAX_PLAYERS],
  65.     Float:g_Tire2_z1[MAX_PLAYERS],
  66.     Float:g_Tire2_y2[MAX_PLAYERS],
  67.     Float:g_Tire2_z2[MAX_PLAYERS],
  68.     g_GetTireState[MAX_PLAYERS char],
  69.     g_GetTireCount[MAX_PLAYERS char],
  70.     g_GetVehicleID[MAX_PLAYERS],
  71.     g_GetTickCount[MAX_PLAYERS],
  72.     g_GetServerTC,
  73.     g_Timer;
  74.  
  75. enum (<<= 1)
  76. {
  77.     e_TIRE_RR = 0b0001,
  78.     e_TIRE_FR,
  79.     e_TIRE_RL,
  80.     e_TIRE_FL,
  81. }
  82.  
  83. forward SS_GetTickCount();
  84. public SS_GetTickCount()
  85. {
  86.     // Store the tick count for fast access. Better than
  87.     // calling the function 20 times per second per player.
  88.     g_GetServerTC = GetTickCount();
  89. }
  90.  
  91. hook OnGameModeInit()
  92. {
  93.     g_Timer = SetTimer("SS_GetTickCount", true, 50);
  94.     return 1;
  95. }
  96.  
  97. hook OnGameModeExit()
  98. {
  99.     foreach (new i : g_Spike)
  100.     {
  101.         DestroyObject(g_SpikeStrip[i]);
  102.         Iter_SafeRemove(g_Spike, i, i);
  103.     }
  104.     KillTimer(g_Timer);
  105.     return 1;
  106. }
  107.  
  108. hook OnPlayerUpdate(playerid)
  109. {
  110.     #if defined ArePlayerTiresPoppable
  111.     if(!ArePlayerTiresPoppable(playerid)) return 1;
  112.     #endif
  113.  
  114.     static
  115.         Float:matrix3x3[9],
  116.         Float:x1, Float:y1, Float:z1,
  117.         Float:x2, Float:y2, Float:z2,
  118.         Float:x3, Float:y3, Float:z3,
  119.         Float:x4, Float:y4, Float:z4;
  120.     if (g_GetTickCount[playerid] < g_GetServerTC)
  121.     {
  122.         if (GetPlayerState(playerid) == 2) // Driver
  123.         {
  124.             if (IsPlayerNPC(playerid))
  125.             {
  126.                 return 1;
  127.             }
  128.             new
  129.                 vid = GetPlayerVehicleID(playerid);
  130.             if (vid != g_GetVehicleID[playerid])
  131.             {
  132.                 new
  133.                     mid = GetVehicleModel(vid);
  134.                 g_GetTireCount{playerid} = SS_GetTireCount(mid);
  135.                 g_GetTireState{playerid} = SS_GetTireState(vid);
  136.                 GetVehicleModelInfo(mid, 6, x1, y1, z1);
  137.                 SS_GetTireSize(mid, e_TIRE_RR, z2);
  138.                 // Save rear wheel offsets
  139.                 g_Tire2_x1[playerid] = x1,
  140.                 g_Tire2_y1[playerid] = y1,
  141.                 g_Tire2_z1[playerid] = z1 - z2 / 2;
  142.                 GetVehicleModelInfo(mid, 5, x1, y1, z1);
  143.                 SS_GetTireSize(mid, e_TIRE_FR, z2);
  144.                 // Save front wheel offsets
  145.                 g_Tire2_x2[playerid] = x1,
  146.                 g_Tire2_y2[playerid] = y1,
  147.                 g_Tire2_z2[playerid] = z1 - z2 / 2;
  148.             }
  149.             if (g_GetTireCount{playerid}) // Check if the player's vehicle has any tires
  150.             {
  151.                 if (g_GetTireState{playerid} < 0b1111) // Check if atleast one tire is not flat (0b1111 = all tires are flat)
  152.                 {
  153.                     SS_GetVehicleRotationMatrix(vid, matrix3x3);
  154.                     // If the tire is not flat, then get its position
  155.                     !(g_GetTireState{playerid} & e_TIRE_RR) && SS_GetTirePos(vid, x1, y1, z1, g_Tire2_x1[playerid], g_Tire2_y1[playerid], g_Tire2_z1[playerid], matrix3x3), // RR
  156.                     !(g_GetTireState{playerid} & e_TIRE_FR) && SS_GetTirePos(vid, x2, y2, z2, g_Tire2_x2[playerid], g_Tire2_y2[playerid], g_Tire2_z2[playerid], matrix3x3); // FR
  157.                     if (g_GetTireCount{playerid} > 2)
  158.                     {
  159.                         !(g_GetTireState{playerid} & e_TIRE_RL) && SS_GetTirePos(vid, x3, y3, z3, -g_Tire2_x1[playerid], g_Tire2_y1[playerid], g_Tire2_z1[playerid], matrix3x3), // RL
  160.                         !(g_GetTireState{playerid} & e_TIRE_FL) && SS_GetTirePos(vid, x4, y4, z4, -g_Tire2_x2[playerid], g_Tire2_y2[playerid], g_Tire2_z2[playerid], matrix3x3); // FL
  161.                     }
  162.                     if (vid == g_GetVehicleID[playerid])
  163.                     {
  164.                         foreach (new i : g_Spike)
  165.                         {
  166.                             if (IsPlayerInRangeOfPoint(playerid, 60.0, g_Spike_x1[i], g_Spike_y1[i], g_Spike_zA[i]))
  167.                             {
  168.                                 // If the tire is not flat, then monitor it
  169.                                 !(g_GetTireState{playerid} & e_TIRE_RR) && SS_MonitorTire(vid, e_TIRE_RR, i, x1, y1, z1, g_Tire1_x1[playerid], g_Tire1_y1[playerid], g_Tire1_z1[playerid]), // RR
  170.                                 !(g_GetTireState{playerid} & e_TIRE_FR) && SS_MonitorTire(vid, e_TIRE_FR, i, x2, y2, z2, g_Tire1_x2[playerid], g_Tire1_y2[playerid], g_Tire1_z2[playerid]); // FR
  171.                                 if (g_GetTireCount{playerid} > 2)
  172.                                 {
  173.                                     !(g_GetTireState{playerid} & e_TIRE_RL) && SS_MonitorTire(vid, e_TIRE_RL, i, x3, y3, z3, g_Tire1_x3[playerid], g_Tire1_y3[playerid], g_Tire1_z3[playerid]), // RL
  174.                                     !(g_GetTireState{playerid} & e_TIRE_FL) && SS_MonitorTire(vid, e_TIRE_FL, i, x4, y4, z4, g_Tire1_x4[playerid], g_Tire1_y4[playerid], g_Tire1_z4[playerid]); // FL
  175.                                 }
  176.                             }
  177.                         }
  178.                     }
  179.                     // If the tire is not flat, then save its position
  180.                     !(g_GetTireState{playerid} & e_TIRE_RR) && (g_Tire1_x1[playerid] = x1, g_Tire1_y1[playerid] = y1, g_Tire1_z1[playerid] = z1),
  181.                     !(g_GetTireState{playerid} & e_TIRE_FR) && (g_Tire1_x2[playerid] = x2, g_Tire1_y2[playerid] = y2, g_Tire1_z2[playerid] = z2);
  182.                     if (g_GetTireCount{playerid} > 2)
  183.                     {
  184.                         !(g_GetTireState{playerid} & e_TIRE_RL) && (g_Tire1_x3[playerid] = x3, g_Tire1_y3[playerid] = y3, g_Tire1_z3[playerid] = z3),
  185.                         !(g_GetTireState{playerid} & e_TIRE_FL) && (g_Tire1_x4[playerid] = x4, g_Tire1_y4[playerid] = y4, g_Tire1_z4[playerid] = z4);
  186.                     }
  187.                 }
  188.             }
  189.             g_GetVehicleID[playerid] = vid;
  190.         }
  191.         g_GetTickCount[playerid] = g_GetServerTC + SS_TIME_INTERVAL;
  192.     }
  193.     return 1;
  194. }
  195.  
  196. hook OnVehicleDamageStatusUpdate(vehicleid, playerid)
  197. {
  198.     new
  199.         tire_state = SS_GetTireState(vehicleid);
  200.     if (tire_state != g_GetTireState{playerid})
  201.     {
  202.         if (g_GetTireState{playerid} > tire_state) // Check if atleast on tire is fixed
  203.         {
  204.             new
  205.                 Float:matrix3x3[9];
  206.             SS_GetVehicleRotationMatrix(vehicleid, matrix3x3);
  207.             if (e_TIRE_RR & (g_GetTireState{playerid} & ~tire_state)) // If a flat tire is fixed
  208.             {
  209.                 SS_GetTirePos(vehicleid, g_Tire1_x1[playerid], g_Tire1_y1[playerid], g_Tire1_z1[playerid], g_Tire2_x1[playerid], g_Tire2_y1[playerid], g_Tire2_z1[playerid], matrix3x3);
  210.             }
  211.             if (e_TIRE_FR & (g_GetTireState{playerid} & ~tire_state)) // If a flat tire is fixed
  212.             {
  213.                 SS_GetTirePos(vehicleid, g_Tire1_x2[playerid], g_Tire1_y2[playerid], g_Tire1_z2[playerid], g_Tire2_x2[playerid], g_Tire2_y2[playerid], g_Tire2_z2[playerid], matrix3x3);
  214.             }
  215.             if (e_TIRE_RL & (g_GetTireState{playerid} & ~tire_state)) // If a flat tire is fixed
  216.             {
  217.                 SS_GetTirePos(vehicleid, g_Tire1_x3[playerid], g_Tire1_y3[playerid], g_Tire1_z3[playerid], -g_Tire2_x1[playerid], g_Tire2_y1[playerid], g_Tire2_z1[playerid], matrix3x3);
  218.             }
  219.             if (e_TIRE_FL & (g_GetTireState{playerid} & ~tire_state)) // If a flat tire is fixed
  220.             {
  221.                 SS_GetTirePos(vehicleid, g_Tire1_x4[playerid], g_Tire1_y4[playerid], g_Tire1_z4[playerid], -g_Tire2_x2[playerid], g_Tire2_y2[playerid], g_Tire2_z2[playerid], matrix3x3);
  222.             }
  223.         }
  224.         g_GetTireState{playerid} = tire_state;
  225.     }
  226.     return 1;
  227. }
  228.  
  229. stock SS_MonitorTire(vid, tire, sid, Float:x1, Float:y1, Float:z1, Float:x2, Float:y2, Float:z2)
  230. {
  231.     new
  232.         Float:distance = 1.0;
  233.     if (SS_SegmentsIntersect_2D(g_Spike_x1[sid], g_Spike_y1[sid], g_Spike_x2[sid], g_Spike_y2[sid], x1, y1, x2, y2))
  234.     {
  235.         SS_DistanceLineToLine_3D(g_Spike_x1[sid], g_Spike_y1[sid], g_Spike_zA[sid], g_Spike_x2[sid], g_Spike_y2[sid], g_Spike_zA[sid], x1, y1, z1, x2, y2, z2, distance);
  236.     }
  237.  
  238.     #if SS_LINE_SEGMENTS >= 2
  239.  
  240.     else if (SS_SegmentsIntersect_2D(g_Spike_x3[sid], g_Spike_y3[sid], g_Spike_x4[sid], g_Spike_y4[sid], x1, y1, x2, y2))
  241.     {
  242.         SS_DistanceLineToLine_3D(g_Spike_x3[sid], g_Spike_y3[sid], g_Spike_zA[sid], g_Spike_x4[sid], g_Spike_y4[sid], g_Spike_zA[sid], x1, y1, z1, x2, y2, z2, distance);
  243.     }
  244.  
  245.     #endif
  246.  
  247.     #if SS_LINE_SEGMENTS == 4
  248.  
  249.     else if (SS_SegmentsIntersect_2D(g_Spike_x1[sid], g_Spike_y1[sid], g_Spike_x3[sid], g_Spike_y3[sid], x1, y1, x2, y2))
  250.     {
  251.         SS_DistanceLineToLine_3D(g_Spike_x1[sid], g_Spike_y1[sid], g_Spike_zA[sid], g_Spike_x3[sid], g_Spike_y3[sid], g_Spike_zA[sid], x1, y1, z1, x2, y2, z2, distance);
  252.     }
  253.     else if (SS_SegmentsIntersect_2D(g_Spike_x2[sid], g_Spike_y2[sid], g_Spike_x4[sid], g_Spike_y4[sid], x1, y1, x2, y2))
  254.     {
  255.         SS_DistanceLineToLine_3D(g_Spike_x2[sid], g_Spike_y2[sid], g_Spike_zA[sid], g_Spike_x4[sid], g_Spike_y4[sid], g_Spike_zA[sid], x1, y1, z1, x2, y2, z2, distance);
  256.     }
  257.  
  258.     #endif
  259.  
  260.     if (distance < 1)
  261.     {
  262.         new
  263.             data1,
  264.             data2,
  265.             data3,
  266.             data4;
  267.         GetVehicleDamageStatus(vid, data1, data2, data3, data4);
  268.         UpdateVehicleDamageStatus(vid, data1, data2, data3, (data4 | tire)); // Pop
  269.        
  270.         CallRemoteFunction("OnSpikeStripPop", "ii", vid, sid);
  271.     }
  272.     return 1;
  273. }
  274.  
  275. stock SS_GetTireState(vid)
  276. {
  277.     new
  278.         data;
  279.     GetVehicleDamageStatus(vid, data, data, data, data);
  280.     return data;
  281. }
  282.  
  283. stock SS_GetTireCount(mid)
  284. {
  285.     static const
  286.         tire_data[] =
  287.     {
  288.         4, 4, 4, 6, 4, 4, 4, 4, 6, 4,
  289.         4, 4, 4, 4, 4, 4, 4, 0, 4, 4,
  290.         4, 4, 4, 4, 4, 0, 4, 4, 4, 4,
  291.         0, 6, 4, 6, 4, 4, 4, 6, 4, 4,
  292.         4, 0, 4, 6, 4, 4, 0, 0, 2, 0,
  293.         4, 4, 0, 0, 0, 6, 4, 4, 4, 4,
  294.         0, 2, 2, 2, 0, 0, 4, 4, 2, 0,
  295.         4, 4, 0, 0, 4, 4, 0, 4, 4, 4,
  296.         4, 0, 4, 4, 0, 4, 4, 0, 0, 4,
  297.         4, 4, 4, 0, 4, 4, 4, 0, 4, 4,
  298.         4, 0, 4, 4, 4, 4, 4, 4, 4, 0,
  299.         0, 0, 0, 0, 6, 6, 4, 4, 4, 0,
  300.         0, 2, 2, 2, 6, 4, 4, 4, 4, 4,
  301.         4, 4, 6, 4, 4, 4, 4, 0, 0, 0,
  302.         4, 4, 4, 4, 4, 4, 4, 4, 0, 4,
  303.         4, 4, 4, 0, 4, 4, 4, 4, 4, 4,
  304.         4, 4, 4, 0, 0, 4, 4, 4, 4, 0,
  305.         0, 4, 4, 4, 4, 4, 4, 0, 6, 4,
  306.         4, 2, 4, 4, 4, 4, 2, 4, 4, 4,
  307.         0, 4, 0, 0, 0, 0, 4, 4, 4, 4,
  308.         4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
  309.         4, 4
  310.     };
  311.     // Aircraft, boats, bicycles, trains
  312.     // and RC vehicles return zero tires
  313.     return tire_data[mid - 400];
  314. }
  315.  
  316. stock SS_GetTireSize(mid, tire, &Float:size)
  317. {
  318.     static const
  319.         Float:tire_size_R[] =
  320.     {
  321.         // Rear wheel size (from vehicles.ide)
  322.         0.7680, 0.7749, 0.6999, 1.1000, 0.6600, 0.6999, 2.2799, 1.0000, 1.0599, 0.7500,
  323.         0.8000, 0.6999, 0.6999, 0.7200, 0.7599, 0.6800, 0.8640, 0.0000, 0.6999, 0.6399,
  324.         0.7879, 0.6499, 0.6999, 0.6999, 0.9200, 0.0000, 0.6999, 0.9359, 0.9139, 0.6999,
  325.         0.0000, 1.0000, 1.2999, 1.2000, 0.8000, 1.1000, 0.6999, 1.0000, 0.6999, 0.6999,
  326.         0.6999, 0.0000, 0.6800, 1.0820, 1.5000, 0.6800, 0.0000, 0.0000, 0.4639, 0.0000,
  327.         1.1000, 0.7500, 0.0000, 0.0000, 0.0000, 1.2000, 0.8399, 0.5000, 0.7200, 0.6999,
  328.         0.0000, 0.6700, 0.4639, 0.5600, 0.0000, 0.0000, 0.6999, 0.6999, 0.6200, 0.0000,
  329.         0.8939, 0.6000, 0.0000, 0.0000, 0.6999, 0.6999, 0.0000, 0.7599, 0.6999, 0.6999,
  330.         0.6999, 0.0000, 0.6999, 0.6600, 0.0000, 0.6000, 1.5000, 0.0000, 0.0000, 0.8999,
  331.         0.9200, 0.6499, 0.6999, 0.0000, 0.8199, 0.9720, 0.6999, 0.0000, 0.7599, 0.8000,
  332.         0.8000, 0.0000, 0.8199, 0.8199, 0.6999, 0.8999, 0.7730, 0.6999, 0.8000, 0.0000,
  333.         0.0000, 0.0000, 0.0000, 0.0000, 1.1059, 1.1799, 0.7500, 0.7500, 0.6600, 0.0000,
  334.         0.0000, 0.6800, 0.6800, 0.6700, 1.0000, 0.9200, 0.6999, 0.6999, 0.8500, 0.6999,
  335.         0.4499, 1.2999, 1.0000, 0.6999, 0.6999, 0.7400, 0.6999, 0.0000, 0.0000, 0.0000,
  336.         0.6999, 1.0000, 0.7400, 0.6999, 1.0000, 0.6999, 0.6999, 0.6999, 0.0000, 0.6840,
  337.         0.7599, 0.7500, 0.8399, 0.0000, 0.8399, 0.6999, 1.5000, 1.5000, 0.7879, 0.6999,
  338.         0.8700, 0.6999, 0.6800, 0.0000, 0.0000, 0.6399, 0.6999, 0.6999, 0.6999, 0.0000,
  339.         0.0000, 0.2599, 0.5600, 1.1399, 0.5000, 0.6999, 0.6999, 0.0000, 1.0000, 0.8999,
  340.         0.7799, 0.6800, 0.7699, 0.7500, 1.1200, 0.7400, 0.6539, 0.6999, 0.8600, 0.7400,
  341.         0.0000, 1.1000, 0.0000, 0.0000, 0.0000, 0.0000, 0.6999, 0.6999, 0.6999, 0.9499,
  342.         0.6999, 1.3660, 0.6999, 0.6999, 0.6999, 0.6999, 0.6000, 0.6000, 0.6000, 0.7599,
  343.         0.3199, 0.6800
  344.        
  345.     };
  346.     if (tire & (e_TIRE_RR | e_TIRE_RL))
  347.     {
  348.         size = tire_size_R[mid - 400];
  349.         return 1;
  350.     }
  351.     static const
  352.         Float:tire_size_F[] =
  353.     {
  354.         // Front wheel size (from vehicles.ide)
  355.         0.7680, 0.7749, 0.6999, 1.1000, 0.6600, 0.6999, 2.2799, 1.0000, 1.0599, 0.7500,
  356.         0.8000, 0.6999, 0.6999, 0.7200, 0.7599, 0.6800, 0.8640, 0.0000, 0.6999, 0.6399,
  357.         0.7879, 0.6499, 0.6999, 0.6999, 0.8399, 0.0000, 0.6999, 0.9359, 0.9139, 0.6999,
  358.         0.0000, 1.0000, 1.2999, 1.2000, 0.7200, 1.1000, 0.6999, 1.0000, 0.6999, 0.6999,
  359.         0.6999, 0.0000, 0.6800, 1.0820, 1.5000, 0.6800, 0.0000, 0.0000, 0.4639, 0.0000,
  360.         1.1000, 0.6999, 0.0000, 0.0000, 0.0000, 1.2000, 0.8399, 0.5000, 0.7200, 0.6999,
  361.         0.0000, 0.6700, 0.4639, 0.7799, 0.0000, 0.0000, 0.6999, 0.6999, 0.6800, 0.0000,
  362.         0.8939, 0.6000, 0.0000, 0.0000, 0.6999, 0.6999, 0.0000, 0.7599, 0.6999, 0.6999,
  363.         0.6999, 0.0000, 0.6999, 0.6600, 0.0000, 0.6000, 1.5000, 0.0000, 0.0000, 0.8999,
  364.         0.9200, 0.6499, 0.6999, 0.0000, 0.8199, 0.9720, 0.6999, 0.0000, 0.7599, 0.8000,
  365.         0.8000, 0.0000, 0.8199, 0.8199, 0.6999, 0.8999, 0.7730, 0.6999, 0.8000, 0.0000,
  366.         0.0000, 0.0000, 0.0000, 0.0000, 1.1059, 1.1799, 0.7500, 0.7500, 0.6600, 0.0000,
  367.         0.0000, 0.6800, 0.6800, 0.6700, 1.1200, 0.9200, 0.6999, 0.6999, 0.8500, 0.6999,
  368.         0.4499, 0.6800, 0.5879, 0.6999, 0.6999, 0.7400, 0.6999, 0.0000, 0.0000, 0.0000,
  369.         0.6999, 1.0000, 0.7400, 0.6999, 1.0000, 0.6999, 0.6999, 0.6999, 0.0000, 0.6840,
  370.         0.7599, 0.7500, 0.8399, 0.0000, 0.8399, 0.6999, 1.5000, 1.5000, 0.7879, 0.6999,
  371.         0.8700, 0.6999, 0.6800, 0.0000, 0.0000, 0.6399, 0.6999, 0.6999, 0.5500, 0.0000,
  372.         0.0000, 0.2599, 0.4799, 1.1399, 0.5000, 0.6999, 0.6999, 0.0000, 1.0000, 0.8999,
  373.         0.7799, 0.6800, 0.7699, 0.6600, 1.1200, 0.7400, 0.6539, 0.6999, 0.8600, 0.7400,
  374.         0.0000, 1.1000, 0.0000, 0.0000, 0.0000, 0.0000, 0.6999, 0.6999, 0.6999, 0.9499,
  375.         0.6999, 1.3660, 0.6999, 0.6999, 0.6999, 0.6999, 0.6000, 0.6000, 0.6000, 0.7599,
  376.         0.3199, 0.6800
  377.     };
  378.     if (tire & (e_TIRE_FR | e_TIRE_FL))
  379.     {
  380.         size = tire_size_F[mid - 400];
  381.         return 1;
  382.     }
  383.     return 1;
  384. }
  385.  
  386. stock SS_GetTirePos(vid, &Float:px, &Float:py, &Float:pz, Float:ox, Float:oy, Float:oz, Float:matrix3x3[])
  387. {
  388.     GetVehiclePos(vid, px, py, pz);
  389.     px = px + ox * (1 - 2 * (matrix3x3[4] + matrix3x3[7])) + oy * (2 * (matrix3x3[1] + matrix3x3[8])) + oz * (2 * (matrix3x3[2] - matrix3x3[6])),
  390.     py = py + ox * (2 * (matrix3x3[1] - matrix3x3[8])) + oy * (1 - 2 * (matrix3x3[0] + matrix3x3[7])) + oz * (2 * (matrix3x3[5] + matrix3x3[3])),
  391.     pz = pz + ox * (2 * (matrix3x3[2] + matrix3x3[6])) + oy * (2 * (matrix3x3[5] - matrix3x3[3])) + oz * (1 - 2 * (matrix3x3[0] + matrix3x3[4]));
  392.     return 1;
  393. }
  394.  
  395. stock SS_GetVehicleRotationMatrix(vid, Float:matrix3x3[])
  396. {
  397.     new
  398.         Float:qw,
  399.         Float:qx,
  400.         Float:qy,
  401.         Float:qz;
  402.     GetVehicleRotationQuat(vid, qw, qx, qy, qz);
  403.     matrix3x3[0] = qx * qx, matrix3x3[1] = qx * qy, matrix3x3[2] = qx * qz,
  404.     matrix3x3[3] = qx * qw, matrix3x3[4] = qy * qy, matrix3x3[5] = qy * qz,
  405.     matrix3x3[6] = qy * qw, matrix3x3[7] = qz * qz, matrix3x3[8] = qz * qw;
  406.     return 1;
  407. }
  408.  
  409. /*
  410. This function checks if two line segments intersect (2D space)
  411. */
  412. stock SS_SegmentsIntersect_2D(Float:x1, Float:y1, Float:x2, Float:y2, Float:x3, Float:y3, Float:x4, Float:y4)
  413. {
  414.     new
  415.         Float:xA = x2 - x1,
  416.         Float:yA = y2 - y1,
  417.         Float:xB = x4 - x3,
  418.         Float:yB = y4 - y3,
  419.         Float:d  = xA * yB - yA * xB;
  420.     if (!d)
  421.     {
  422.         // Lines are parallel, or one or
  423.         // both segments are zero-length
  424.         return 0;
  425.     }
  426.     new
  427.         Float:xC = x3 - x1,
  428.         Float:yC = y3 - y1,
  429.         Float:pA = (xC * yB - yC * xB) / d,
  430.         Float:pB = (xC * yA - yC * xA) / d;
  431.     if (pA < 0 || pA > 1 || pB < 0 || pB > 1)
  432.     {
  433.         return 0;
  434.     }
  435.     // Compute intersection point
  436.     // xi = x1 + pA * xA
  437.     // yi = y1 + pA * yA
  438.     return 1;
  439. }
  440.  
  441. /*
  442. This function computes the shortest distance between two lines (3D space)
  443. */
  444. stock SS_DistanceLineToLine_3D(Float:x1, Float:y1, Float:z1, Float:x2, Float:y2, Float:z2, Float:x3, Float:y3, Float:z3, Float:x4, Float:y4, Float:z4, &Float:distance)
  445. {
  446.     new
  447.         Float:ux = x2 - x1,
  448.         Float:uy = y2 - y1,
  449.         Float:uz = z2 - z1,
  450.         Float:vx = x4 - x3,
  451.         Float:vy = y4 - y3,
  452.         Float:vz = z4 - z3,
  453.         Float:wx = x1 - x3,
  454.         Float:wy = y1 - y3,
  455.         Float:wz = z1 - z3,
  456.         Float:uu = ux * ux + uy * uy + uz * uz,
  457.         Float:uv = ux * vx + uy * vy + uz * vz,
  458.         Float:uw = ux * wx + uy * wy + uz * wz,
  459.         Float:vv = vx * vx + vy * vy + vz * vz,
  460.         Float:vw = vx * wx + vy * wy + vz * wz,
  461.         Float:d  = uu * vv - uv * uv,
  462.         Float:pA = (uv * vw - vv * uw) / d,
  463.         Float:pB = (uu * vw - uv * uw) / d,
  464.         // The difference of the two closest points
  465.         Float:dx = wx + pA * ux - pB * vx,
  466.         Float:dy = wy + pA * uy - pB * vy,
  467.         Float:dz = wz + pA * uz - pB * vz;
  468.     distance = floatsqroot(dx * dx + dy * dy + dz * dz);
  469.     return 1;
  470. }
  471.  
  472. stock SpikeStrip_Create(modelid, Float:x, Float:y, Float:z, Float:angle, bool:FindZ = true)
  473. {
  474.     new
  475.         idx = Iter_Free(g_Spike);
  476.     if (idx != -1)
  477.     {
  478.         new
  479.             Float:length,
  480.             Float:ground;
  481.         switch (modelid)
  482.         {
  483.             case 2892:
  484.             {
  485.                 length = 5.0;
  486.                 ground = ((FindZ) ? 1.0 : 0.0);
  487.             }
  488.             case 2899:
  489.             {
  490.                 length = 2.5;
  491.                 ground = ((FindZ) ? 0.88 : 0.0);
  492.             }
  493.             default:
  494.             {
  495.                 return INVALID_OBJECT_ID;
  496.             }
  497.         }
  498.         new
  499.             id = CreateObject(modelid, x, y, z - ground, 0.0, 0.0, angle - 90.0);
  500.         if (id != INVALID_OBJECT_ID)
  501.         {
  502.             angle = -angle;
  503.             Iter_Add(g_Spike, idx);
  504.             g_SpikeStrip[idx] = id;
  505.  
  506.             #if SS_LINE_SEGMENTS == 1
  507.                
  508.             g_Spike_x1[idx] = x + length * floatsin(angle - 90.0, degrees);
  509.             g_Spike_y1[idx] = y + length * floatcos(angle - 90.0, degrees);
  510.             g_Spike_x2[idx] = x - length * floatsin(angle - 90.0, degrees);
  511.             g_Spike_y2[idx] = y - length * floatcos(angle - 90.0, degrees);
  512.  
  513.             #endif
  514.            
  515.             #if SS_LINE_SEGMENTS >= 2
  516.            
  517.             new
  518.                 value;
  519.             modelid != 2892 && (value = 10) || (value = 5);
  520.             g_Spike_x1[idx] = x + length * floatsin(angle - (90.0 + value), degrees);
  521.             g_Spike_y1[idx] = y + length * floatcos(angle - (90.0 + value), degrees);
  522.             g_Spike_x3[idx] = x + length * floatsin(angle - (90.0 - value), degrees);
  523.             g_Spike_y3[idx] = y + length * floatcos(angle - (90.0 - value), degrees);
  524.            
  525.             #if SS_LINE_SEGMENTS == 2
  526.            
  527.             g_Spike_x2[idx] = x - length * floatsin(angle - (90.0 + value), degrees);
  528.             g_Spike_y2[idx] = y - length * floatcos(angle - (90.0 + value), degrees);
  529.             g_Spike_x4[idx] = x - length * floatsin(angle - (90.0 - value), degrees);
  530.             g_Spike_y4[idx] = y - length * floatcos(angle - (90.0 - value), degrees);
  531.  
  532.             #endif
  533.  
  534.             #if SS_LINE_SEGMENTS == 4
  535.  
  536.             g_Spike_x2[idx] = x - length * floatsin(angle - (90.0 - value), degrees);
  537.             g_Spike_y2[idx] = y - length * floatcos(angle - (90.0 - value), degrees);
  538.             g_Spike_x4[idx] = x - length * floatsin(angle - (90.0 + value), degrees);
  539.             g_Spike_y4[idx] = y - length * floatcos(angle - (90.0 + value), degrees);
  540.  
  541.             #endif
  542.            
  543.             #endif
  544.  
  545.             g_Spike_zA[idx] = z - 0.9;
  546.             return idx;
  547.         }
  548.     }
  549.     return INVALID_OBJECT_ID;
  550. }
  551.  
  552. stock SpikeStrip_Delete(spikeid)
  553. {
  554.     if (Iter_Contains(g_Spike, spikeid))
  555.     {
  556.         Iter_Remove(g_Spike, spikeid);
  557.         DestroyObject(g_SpikeStrip[spikeid]);
  558.         g_SpikeStrip[spikeid] = 0;
  559.     }
  560.     return 1;
  561. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement