Advertisement
Guest User

SA-MP Spike Strips (update 3)

a guest
Aug 12th, 2013
1,103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pawn 22.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. /*
  9.  * Changelog
  10.  *
  11.  *      13/8/2013
  12.  *          ~ shortened the prefix from "SpikeStrip" to "Stinger"
  13.  *          ~ added a config option to enable/disable the OnSpikeStripPopTire callback
  14.  *          ~ added a config option to enable/disable the Streamer plugin support
  15.  *
  16.  *      5/7/2013:
  17.  *          ~ changed parameter order in OnSpikeStripPopTire callback
  18.  *          ~ fixed a bug where OnSpikeStripPopTire callback wasn't getting called
  19.  *          ~ fixed incorrect arguments being passed to SetTimer function
  20.  *          ~ added a function named SpikeStrip_DeleteAll that deletes all spike strips
  21.  *
  22.  *      4/7/2013:
  23.  *          ~ removed the auto-adjustment of the Z coordinate when creating a spike strip
  24.  *          ~ added a callback named OnSpikeStripPopTire that is called when a tire is popped
  25.  *          ~ added a function named SpikeStrip_IsValid that checks the validity of a spike strip
  26.  *          ~ added a function named SpikeStrip_SetGhost that toggles a player's ghost mode
  27.  *          ~ added a function named SpikeStrip_IsGhost that checks a player's ghost mode
  28.  *
  29.  *      3/7/2013:
  30.  *          ~ initial release
  31.  */
  32.  
  33. #include <a_samp>
  34. // Alternatively use foreach
  35. #include <YSI\y_iterate>
  36.  
  37. #define MAX_SPIKE_STRIPS    (100)
  38. #define SS_TIME_INTERVAL    (250)
  39. #define SS_LINE_SEGMENTS    (2) // 1, 2 or 4
  40.  
  41. #define SS_USE_CALLBACK     (true)  // OnSpikeStripPopTire
  42. #define SS_USE_STREAMER     (false) // Streamer plugin support
  43.  
  44. // Spike strip models
  45. #define SPIKE_STRIP_LONG    (2892)
  46. #define SPIKE_STRIP_SHORT   (2899)
  47.  
  48. static stock
  49.     g_SpikeStrip[MAX_SPIKE_STRIPS],
  50.     Iterator:g_Spike<MAX_SPIKE_STRIPS>,
  51.     Float:g_Spike_x1[MAX_SPIKE_STRIPS],
  52.     Float:g_Spike_y1[MAX_SPIKE_STRIPS],
  53.     Float:g_Spike_x2[MAX_SPIKE_STRIPS],
  54.     Float:g_Spike_y2[MAX_SPIKE_STRIPS],
  55.     Float:g_Spike_x3[MAX_SPIKE_STRIPS],
  56.     Float:g_Spike_y3[MAX_SPIKE_STRIPS],
  57.     Float:g_Spike_x4[MAX_SPIKE_STRIPS],
  58.     Float:g_Spike_y4[MAX_SPIKE_STRIPS],
  59.     Float:g_Spike_zA[MAX_SPIKE_STRIPS],
  60.     Float:g_Tire1_x1[MAX_PLAYERS],
  61.     Float:g_Tire1_y1[MAX_PLAYERS],
  62.     Float:g_Tire1_z1[MAX_PLAYERS],
  63.     Float:g_Tire1_x2[MAX_PLAYERS],
  64.     Float:g_Tire1_y2[MAX_PLAYERS],
  65.     Float:g_Tire1_z2[MAX_PLAYERS],
  66.     Float:g_Tire1_x3[MAX_PLAYERS],
  67.     Float:g_Tire1_y3[MAX_PLAYERS],
  68.     Float:g_Tire1_z3[MAX_PLAYERS],
  69.     Float:g_Tire1_x4[MAX_PLAYERS],
  70.     Float:g_Tire1_y4[MAX_PLAYERS],
  71.     Float:g_Tire1_z4[MAX_PLAYERS],
  72.     Float:g_Tire2_x1[MAX_PLAYERS],
  73.     Float:g_Tire2_y1[MAX_PLAYERS],
  74.     Float:g_Tire2_x2[MAX_PLAYERS],
  75.     Float:g_Tire2_z1[MAX_PLAYERS],
  76.     Float:g_Tire2_y2[MAX_PLAYERS],
  77.     Float:g_Tire2_z2[MAX_PLAYERS],
  78.     g_GetGhostMode[MAX_PLAYERS char],
  79.     g_GetTireState[MAX_PLAYERS char],
  80.     g_GetTireCount[MAX_PLAYERS char],
  81.     g_GetVehicleID[MAX_PLAYERS],
  82.     g_GetTickCount[MAX_PLAYERS],
  83.     g_GetServerTC;
  84.  
  85. enum (<<= 1)
  86. {
  87.     e_TIRE_RR = 0b0001,
  88.     e_TIRE_FR,
  89.     e_TIRE_RL,
  90.     e_TIRE_FL,
  91. }
  92.  
  93. // Forwards
  94. forward SS_GetTickCount();
  95. forward OnSpikeStripPopTire(spikeid, vehicleid, playerid, tire);
  96.  
  97. public SS_GetTickCount()
  98. {
  99.     // Store the tick count for fast access. Better than
  100.     // calling the function 20 times per second per player.
  101.     g_GetServerTC = GetTickCount();
  102.     return 1;
  103. }
  104.  
  105. public OnGameModeInit()
  106. {
  107.     SetTimer("SS_GetTickCount", 50, 1);
  108.     #if defined SS_OnGameModeInit
  109.         return SS_OnGameModeInit();
  110.     #else
  111.         return 1;
  112.     #endif
  113. }
  114.  
  115. #if defined _ALS_OnGameModeInit
  116.     #undef OnGameModeInit
  117. #else
  118.     #define _ALS_OnGameModeInit
  119. #endif
  120. #define OnGameModeInit SS_OnGameModeInit
  121. #if defined SS_OnGameModeInit
  122.     forward SS_OnGameModeInit();
  123. #endif
  124.  
  125. public OnPlayerUpdate(playerid)
  126. {
  127.     static
  128.         Float:matrix3x3[9],
  129.         Float:x1, Float:y1, Float:z1,
  130.         Float:x2, Float:y2, Float:z2,
  131.         Float:x3, Float:y3, Float:z3,
  132.         Float:x4, Float:y4, Float:z4;
  133.     if (g_GetTickCount[playerid] < g_GetServerTC)
  134.     {
  135.         if (GetPlayerState(playerid) == 2) // Driver
  136.         {
  137.             if (IsPlayerNPC(playerid))
  138.             {
  139.                 return 1;
  140.             }
  141.             if (!g_GetGhostMode{playerid})
  142.             {
  143.                 new
  144.                     vid = GetPlayerVehicleID(playerid);
  145.                 if (vid != g_GetVehicleID[playerid])
  146.                 {
  147.                     new
  148.                         mid = GetVehicleModel(vid);
  149.                     g_GetTireCount{playerid} = SS_GetTireCount(mid);
  150.                     g_GetTireState{playerid} = SS_GetTireState(vid);
  151.                     GetVehicleModelInfo(mid, 6, x1, y1, z1);
  152.                     SS_GetTireSize(mid, e_TIRE_RR, z2);
  153.                     // Save rear wheel offsets
  154.                     g_Tire2_x1[playerid] = x1,
  155.                     g_Tire2_y1[playerid] = y1,
  156.                     g_Tire2_z1[playerid] = z1 - z2 / 2;
  157.                     GetVehicleModelInfo(mid, 5, x1, y1, z1);
  158.                     SS_GetTireSize(mid, e_TIRE_FR, z2);
  159.                     // Save front wheel offsets
  160.                     g_Tire2_x2[playerid] = x1,
  161.                     g_Tire2_y2[playerid] = y1,
  162.                     g_Tire2_z2[playerid] = z1 - z2 / 2;
  163.                 }
  164.                 if (g_GetTireCount{playerid}) // Check if the player's vehicle has any tires
  165.                 {
  166.                     if (g_GetTireState{playerid} < 0b1111) // Check if at least one tire is not flat (0b1111 = all tires are flat)
  167.                     {
  168.                         SS_GetVehicleRotationMatrix(vid, matrix3x3);
  169.                         // If the tire is not flat, then get its position
  170.                         !(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
  171.                         !(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
  172.                         if (g_GetTireCount{playerid} > 2)
  173.                         {
  174.                             !(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
  175.                             !(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
  176.                         }
  177.                         foreach (new i : g_Spike)
  178.                         {
  179.                             if (IsPlayerInRangeOfPoint(playerid, 60.0, g_Spike_x1[i], g_Spike_y1[i], g_Spike_zA[i]))
  180.                             {
  181.                                 // If the tire is not flat, then monitor it
  182.                                 !(g_GetTireState{playerid} & e_TIRE_RR) && SS_MonitorTire(vid, e_TIRE_RR, i, playerid, x1, y1, z1, g_Tire1_x1[playerid], g_Tire1_y1[playerid], g_Tire1_z1[playerid]), // RR
  183.                                 !(g_GetTireState{playerid} & e_TIRE_FR) && SS_MonitorTire(vid, e_TIRE_FR, i, playerid, x2, y2, z2, g_Tire1_x2[playerid], g_Tire1_y2[playerid], g_Tire1_z2[playerid]); // FR
  184.                                 if (g_GetTireCount{playerid} > 2)
  185.                                 {
  186.                                     !(g_GetTireState{playerid} & e_TIRE_RL) && SS_MonitorTire(vid, e_TIRE_RL, i, playerid, x3, y3, z3, g_Tire1_x3[playerid], g_Tire1_y3[playerid], g_Tire1_z3[playerid]), // RL
  187.                                     !(g_GetTireState{playerid} & e_TIRE_FL) && SS_MonitorTire(vid, e_TIRE_FL, i, playerid, x4, y4, z4, g_Tire1_x4[playerid], g_Tire1_y4[playerid], g_Tire1_z4[playerid]); // FL
  188.                                 }
  189.                             }
  190.                         }
  191.                         // If the tire is not flat, then save its position
  192.                         !(g_GetTireState{playerid} & e_TIRE_RR) && (g_Tire1_x1[playerid] = x1, g_Tire1_y1[playerid] = y1, g_Tire1_z1[playerid] = z1),
  193.                         !(g_GetTireState{playerid} & e_TIRE_FR) && (g_Tire1_x2[playerid] = x2, g_Tire1_y2[playerid] = y2, g_Tire1_z2[playerid] = z2);
  194.                         if (g_GetTireCount{playerid} > 2)
  195.                         {
  196.                             !(g_GetTireState{playerid} & e_TIRE_RL) && (g_Tire1_x3[playerid] = x3, g_Tire1_y3[playerid] = y3, g_Tire1_z3[playerid] = z3),
  197.                             !(g_GetTireState{playerid} & e_TIRE_FL) && (g_Tire1_x4[playerid] = x4, g_Tire1_y4[playerid] = y4, g_Tire1_z4[playerid] = z4);
  198.                         }
  199.                     }
  200.                 }
  201.                 g_GetVehicleID[playerid] = vid;
  202.             }
  203.         }
  204.         g_GetTickCount[playerid] = g_GetServerTC + SS_TIME_INTERVAL;
  205.     }
  206.     #if defined SS_OnPlayerUpdate
  207.         return SS_OnPlayerUpdate(playerid);
  208.     #else
  209.         return 1;
  210.     #endif  
  211. }
  212.  
  213. #if defined _ALS_OnPlayerUpdate
  214.     #undef OnPlayerUpdate
  215. #else
  216.     #define _ALS_OnPlayerUpdate
  217. #endif
  218. #define OnPlayerUpdate SS_OnPlayerUpdate
  219. #if defined SS_OnPlayerUpdate
  220.     forward SS_OnPlayerUpdate(playerid);
  221. #endif
  222.  
  223. public OnVehicleDamageStatusUpdate(vehicleid, playerid)
  224. {
  225.     new
  226.         tire_state = SS_GetTireState(vehicleid);
  227.     if (tire_state != g_GetTireState{playerid})
  228.     {
  229.         if (g_GetTireState{playerid} > tire_state) // Check if at least one tire is fixed
  230.         {
  231.             new
  232.                 Float:matrix3x3[9];
  233.             SS_GetVehicleRotationMatrix(vehicleid, matrix3x3);
  234.             if (e_TIRE_RR & (g_GetTireState{playerid} & ~tire_state)) // If a flat tire is fixed
  235.             {
  236.                 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);
  237.             }
  238.             if (e_TIRE_FR & (g_GetTireState{playerid} & ~tire_state)) // If a flat tire is fixed
  239.             {
  240.                 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);
  241.             }
  242.             if (e_TIRE_RL & (g_GetTireState{playerid} & ~tire_state)) // If a flat tire is fixed
  243.             {
  244.                 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);
  245.             }
  246.             if (e_TIRE_FL & (g_GetTireState{playerid} & ~tire_state)) // If a flat tire is fixed
  247.             {
  248.                 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);
  249.             }
  250.         }
  251.         g_GetTireState{playerid} = tire_state;
  252.     }
  253.     #if defined SS_OnVehicleDamageStatusUpdate
  254.         return SS_OnVehicleDamageStatusUpdate(vehicleid, playerid);
  255.     #else
  256.         return 1;
  257.     #endif
  258. }
  259.  
  260. #if defined _ALS_OnVehicleDamageStatusUpd
  261.     #undef OnVehicleDamageStatusUpdate
  262. #else
  263.     #define _ALS_OnVehicleDamageStatusUpd
  264. #endif
  265. #define OnVehicleDamageStatusUpdate SS_OnVehicleDamageStatusUpdate
  266. #if defined SS_OnVehicleDamageStatusUpdate
  267.     forward SS_OnVehicleDamageStatusUpdate(vehicleid, playerid);
  268. #endif
  269.    
  270. stock SS_MonitorTire(vid, tire, sid, pid, Float:x1, Float:y1, Float:z1, Float:x2, Float:y2, Float:z2)
  271. {
  272.     new
  273.         Float:distance = 1.0;
  274.     if (SS_SegmentsIntersect_2D(g_Spike_x1[sid], g_Spike_y1[sid], g_Spike_x2[sid], g_Spike_y2[sid], x1, y1, x2, y2))
  275.     {
  276.         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);
  277.     }
  278.  
  279.     #if SS_LINE_SEGMENTS >= 2
  280.  
  281.     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))
  282.     {
  283.         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);
  284.     }
  285.  
  286.     #endif
  287.  
  288.     #if SS_LINE_SEGMENTS == 4
  289.  
  290.     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))
  291.     {
  292.         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);
  293.     }
  294.     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))
  295.     {
  296.         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);
  297.     }
  298.  
  299.     #endif
  300.  
  301.     if (distance < 0.24)
  302.     {
  303.         if (vid == g_GetVehicleID[pid]) // Make sure surprise tire pops don't occur
  304.         {
  305.             new
  306.                 data1,
  307.                 data2,
  308.                 data3,
  309.                 data4;
  310.             GetVehicleDamageStatus(vid, data1, data2, data3, data4);
  311.             UpdateVehicleDamageStatus(vid, data1, data2, data3, (data4 | tire)); // Pop
  312.             #if SS_USE_CALLBACK
  313.            
  314.             CallRemoteFunction("OnSpikeStripPopTire", "iiii", sid, vid, pid, tire);
  315.            
  316.             #endif
  317.         }
  318.     }
  319.     return 1;
  320. }
  321.  
  322. stock SS_GetTireState(vid)
  323. {
  324.     new
  325.         data;
  326.     GetVehicleDamageStatus(vid, data, data, data, data);
  327.     return data;
  328. }
  329.  
  330. stock SS_GetTireCount(mid)
  331. {
  332.     static const
  333.         tire_data[] =
  334.     {
  335.         4, 4, 4, 6, 4, 4, 4, 4, 6, 4,
  336.         4, 4, 4, 4, 4, 4, 4, 0, 4, 4,
  337.         4, 4, 4, 4, 4, 0, 4, 4, 4, 4,
  338.         0, 6, 4, 6, 4, 4, 4, 6, 4, 4,
  339.         4, 0, 4, 6, 4, 4, 0, 0, 2, 0,
  340.         4, 4, 0, 0, 0, 6, 4, 4, 4, 4,
  341.         0, 2, 2, 2, 0, 0, 4, 4, 2, 0,
  342.         4, 4, 0, 0, 4, 4, 0, 4, 4, 4,
  343.         4, 0, 4, 4, 0, 4, 4, 0, 0, 4,
  344.         4, 4, 4, 0, 4, 4, 4, 0, 4, 4,
  345.         4, 0, 4, 4, 4, 4, 4, 4, 4, 0,
  346.         0, 0, 0, 0, 6, 6, 4, 4, 4, 0,
  347.         0, 2, 2, 2, 6, 4, 4, 4, 4, 4,
  348.         4, 4, 6, 4, 4, 4, 4, 0, 0, 0,
  349.         4, 4, 4, 4, 4, 4, 4, 4, 0, 4,
  350.         4, 4, 4, 0, 4, 4, 4, 4, 4, 4,
  351.         4, 4, 4, 0, 0, 4, 4, 4, 4, 0,
  352.         0, 4, 4, 4, 4, 4, 4, 0, 6, 4,
  353.         4, 2, 4, 4, 4, 4, 2, 4, 4, 4,
  354.         0, 4, 0, 0, 0, 0, 4, 4, 4, 4,
  355.         4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
  356.         4, 4
  357.     };
  358.     // Aircraft, boats, bicycles, trains
  359.     // and RC vehicles return zero tires
  360.     return tire_data[mid - 400];
  361. }
  362.  
  363. stock SS_GetTireSize(mid, tire, &Float:size)
  364. {
  365.     static const
  366.         Float:tire_size_R[] =
  367.     {
  368.         // Rear wheel size (from vehicles.ide)
  369.         0.7680, 0.7749, 0.6999, 1.1000, 0.6600, 0.6999, 2.2799, 1.0000, 1.0599, 0.7500,
  370.         0.8000, 0.6999, 0.6999, 0.7200, 0.7599, 0.6800, 0.8640, 0.0000, 0.6999, 0.6399,
  371.         0.7879, 0.6499, 0.6999, 0.6999, 0.9200, 0.0000, 0.6999, 0.9359, 0.9139, 0.6999,
  372.         0.0000, 1.0000, 1.2999, 1.2000, 0.8000, 1.1000, 0.6999, 1.0000, 0.6999, 0.6999,
  373.         0.6999, 0.0000, 0.6800, 1.0820, 1.5000, 0.6800, 0.0000, 0.0000, 0.4639, 0.0000,
  374.         1.1000, 0.7500, 0.0000, 0.0000, 0.0000, 1.2000, 0.8399, 0.5000, 0.7200, 0.6999,
  375.         0.0000, 0.6700, 0.4639, 0.5600, 0.0000, 0.0000, 0.6999, 0.6999, 0.6200, 0.0000,
  376.         0.8939, 0.6000, 0.0000, 0.0000, 0.6999, 0.6999, 0.0000, 0.7599, 0.6999, 0.6999,
  377.         0.6999, 0.0000, 0.6999, 0.6600, 0.0000, 0.6000, 1.5000, 0.0000, 0.0000, 0.8999,
  378.         0.9200, 0.6499, 0.6999, 0.0000, 0.8199, 0.9720, 0.6999, 0.0000, 0.7599, 0.8000,
  379.         0.8000, 0.0000, 0.8199, 0.8199, 0.6999, 0.8999, 0.7730, 0.6999, 0.8000, 0.0000,
  380.         0.0000, 0.0000, 0.0000, 0.0000, 1.1059, 1.1799, 0.7500, 0.7500, 0.6600, 0.0000,
  381.         0.0000, 0.6800, 0.6800, 0.6700, 1.0000, 0.9200, 0.6999, 0.6999, 0.8500, 0.6999,
  382.         0.4499, 1.2999, 1.0000, 0.6999, 0.6999, 0.7400, 0.6999, 0.0000, 0.0000, 0.0000,
  383.         0.6999, 1.0000, 0.7400, 0.6999, 1.0000, 0.6999, 0.6999, 0.6999, 0.0000, 0.6840,
  384.         0.7599, 0.7500, 0.8399, 0.0000, 0.8399, 0.6999, 1.5000, 1.5000, 0.7879, 0.6999,
  385.         0.8700, 0.6999, 0.6800, 0.0000, 0.0000, 0.6399, 0.6999, 0.6999, 0.6999, 0.0000,
  386.         0.0000, 0.2599, 0.5600, 1.1399, 0.5000, 0.6999, 0.6999, 0.0000, 1.0000, 0.8999,
  387.         0.7799, 0.6800, 0.7699, 0.7500, 1.1200, 0.7400, 0.6539, 0.6999, 0.8600, 0.7400,
  388.         0.0000, 1.1000, 0.0000, 0.0000, 0.0000, 0.0000, 0.6999, 0.6999, 0.6999, 0.9499,
  389.         0.6999, 1.3660, 0.6999, 0.6999, 0.6999, 0.6999, 0.6000, 0.6000, 0.6000, 0.7599,
  390.         0.3199, 0.6800
  391.     };
  392.     if (tire & (e_TIRE_RR | e_TIRE_RL))
  393.     {
  394.         size = tire_size_R[mid - 400];
  395.         return 1;
  396.     }
  397.     static const
  398.         Float:tire_size_F[] =
  399.     {
  400.         // Front wheel size (from vehicles.ide)
  401.         0.7680, 0.7749, 0.6999, 1.1000, 0.6600, 0.6999, 2.2799, 1.0000, 1.0599, 0.7500,
  402.         0.8000, 0.6999, 0.6999, 0.7200, 0.7599, 0.6800, 0.8640, 0.0000, 0.6999, 0.6399,
  403.         0.7879, 0.6499, 0.6999, 0.6999, 0.8399, 0.0000, 0.6999, 0.9359, 0.9139, 0.6999,
  404.         0.0000, 1.0000, 1.2999, 1.2000, 0.7200, 1.1000, 0.6999, 1.0000, 0.6999, 0.6999,
  405.         0.6999, 0.0000, 0.6800, 1.0820, 1.5000, 0.6800, 0.0000, 0.0000, 0.4639, 0.0000,
  406.         1.1000, 0.6999, 0.0000, 0.0000, 0.0000, 1.2000, 0.8399, 0.5000, 0.7200, 0.6999,
  407.         0.0000, 0.6700, 0.4639, 0.7799, 0.0000, 0.0000, 0.6999, 0.6999, 0.6800, 0.0000,
  408.         0.8939, 0.6000, 0.0000, 0.0000, 0.6999, 0.6999, 0.0000, 0.7599, 0.6999, 0.6999,
  409.         0.6999, 0.0000, 0.6999, 0.6600, 0.0000, 0.6000, 1.5000, 0.0000, 0.0000, 0.8999,
  410.         0.9200, 0.6499, 0.6999, 0.0000, 0.8199, 0.9720, 0.6999, 0.0000, 0.7599, 0.8000,
  411.         0.8000, 0.0000, 0.8199, 0.8199, 0.6999, 0.8999, 0.7730, 0.6999, 0.8000, 0.0000,
  412.         0.0000, 0.0000, 0.0000, 0.0000, 1.1059, 1.1799, 0.7500, 0.7500, 0.6600, 0.0000,
  413.         0.0000, 0.6800, 0.6800, 0.6700, 1.1200, 0.9200, 0.6999, 0.6999, 0.8500, 0.6999,
  414.         0.4499, 0.6800, 0.5879, 0.6999, 0.6999, 0.7400, 0.6999, 0.0000, 0.0000, 0.0000,
  415.         0.6999, 1.0000, 0.7400, 0.6999, 1.0000, 0.6999, 0.6999, 0.6999, 0.0000, 0.6840,
  416.         0.7599, 0.7500, 0.8399, 0.0000, 0.8399, 0.6999, 1.5000, 1.5000, 0.7879, 0.6999,
  417.         0.8700, 0.6999, 0.6800, 0.0000, 0.0000, 0.6399, 0.6999, 0.6999, 0.5500, 0.0000,
  418.         0.0000, 0.2599, 0.4799, 1.1399, 0.5000, 0.6999, 0.6999, 0.0000, 1.0000, 0.8999,
  419.         0.7799, 0.6800, 0.7699, 0.6600, 1.1200, 0.7400, 0.6539, 0.6999, 0.8600, 0.7400,
  420.         0.0000, 1.1000, 0.0000, 0.0000, 0.0000, 0.0000, 0.6999, 0.6999, 0.6999, 0.9499,
  421.         0.6999, 1.3660, 0.6999, 0.6999, 0.6999, 0.6999, 0.6000, 0.6000, 0.6000, 0.7599,
  422.         0.3199, 0.6800
  423.     };
  424.     if (tire & (e_TIRE_FR | e_TIRE_FL))
  425.     {
  426.         size = tire_size_F[mid - 400];
  427.         return 1;
  428.     }
  429.     return 0;
  430. }
  431.  
  432. stock SS_GetTirePos(vid, &Float:px, &Float:py, &Float:pz, Float:ox, Float:oy, Float:oz, Float:matrix3x3[])
  433. {
  434.     GetVehiclePos(vid, px, py, pz);
  435.     px = px + ox * (1 - 2 * (matrix3x3[4] + matrix3x3[7])) + oy * (2 * (matrix3x3[1] + matrix3x3[8])) + oz * (2 * (matrix3x3[2] - matrix3x3[6])),
  436.     py = py + ox * (2 * (matrix3x3[1] - matrix3x3[8])) + oy * (1 - 2 * (matrix3x3[0] + matrix3x3[7])) + oz * (2 * (matrix3x3[5] + matrix3x3[3])),
  437.     pz = pz + ox * (2 * (matrix3x3[2] + matrix3x3[6])) + oy * (2 * (matrix3x3[5] - matrix3x3[3])) + oz * (1 - 2 * (matrix3x3[0] + matrix3x3[4]));
  438.     return 1;
  439. }
  440.  
  441. stock SS_GetVehicleRotationMatrix(vid, Float:matrix3x3[])
  442. {
  443.     new
  444.         Float:qw,
  445.         Float:qx,
  446.         Float:qy,
  447.         Float:qz;
  448.     GetVehicleRotationQuat(vid, qw, qx, qy, qz);
  449.     matrix3x3[0] = qx * qx, matrix3x3[1] = qx * qy, matrix3x3[2] = qx * qz,
  450.     matrix3x3[3] = qx * qw, matrix3x3[4] = qy * qy, matrix3x3[5] = qy * qz,
  451.     matrix3x3[6] = qy * qw, matrix3x3[7] = qz * qz, matrix3x3[8] = qz * qw;
  452.     return 1;
  453. }
  454.  
  455. /*
  456. This function checks if two line segments intersect (2D space)
  457. */
  458. stock SS_SegmentsIntersect_2D(Float:x1, Float:y1, Float:x2, Float:y2, Float:x3, Float:y3, Float:x4, Float:y4)
  459. {
  460.     new
  461.         Float:xA = x2 - x1,
  462.         Float:yA = y2 - y1,
  463.         Float:xB = x4 - x3,
  464.         Float:yB = y4 - y3,
  465.         Float:d  = xA * yB - yA * xB;
  466.     if (!d)
  467.     {
  468.         // Lines are parallel, or one or
  469.         // both segments are zero-length
  470.         return 0;
  471.     }
  472.     new
  473.         Float:xC = x3 - x1,
  474.         Float:yC = y3 - y1,
  475.         Float:pA = (xC * yB - yC * xB) / d,
  476.         Float:pB = (xC * yA - yC * xA) / d;
  477.     if (pA < 0 || pA > 1 || pB < 0 || pB > 1)
  478.     {
  479.         return 0;
  480.     }
  481.     // Compute the intersection point
  482.     // xi = x1 + pA * xA
  483.     // yi = y1 + pA * yA
  484.     return 1;
  485. }
  486.  
  487. /*
  488. This function computes the shortest distance between two lines (3D space)
  489. */
  490. 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)
  491. {
  492.     new
  493.         Float:ux = x2 - x1,
  494.         Float:uy = y2 - y1,
  495.         Float:uz = z2 - z1,
  496.         Float:vx = x4 - x3,
  497.         Float:vy = y4 - y3,
  498.         Float:vz = z4 - z3,
  499.         Float:wx = x1 - x3,
  500.         Float:wy = y1 - y3,
  501.         Float:wz = z1 - z3,
  502.         Float:uu = ux * ux + uy * uy + uz * uz,
  503.         Float:uv = ux * vx + uy * vy + uz * vz,
  504.         Float:uw = ux * wx + uy * wy + uz * wz,
  505.         Float:vv = vx * vx + vy * vy + vz * vz,
  506.         Float:vw = vx * wx + vy * wy + vz * wz,
  507.         Float:d  = uu * vv - uv * uv,
  508.         Float:pA = (uv * vw - vv * uw) / d,
  509.         Float:pB = (uu * vw - uv * uw) / d,
  510.         // The difference of the two closest points
  511.         Float:dx = wx + pA * ux - pB * vx,
  512.         Float:dy = wy + pA * uy - pB * vy,
  513.         Float:dz = wz + pA * uz - pB * vz;
  514.     distance = floatsqroot(dx * dx + dy * dy + dz * dz);
  515.     return 1;
  516. }
  517.  
  518. #if !SS_USE_STREAMER
  519.     #define SS_CreateObject(%0) \
  520.         CreateObject(%0, 200.0)
  521.     #define SS_DestroyObject \
  522.         DestroyObject
  523. #else
  524.     #include <streamer>
  525.     #define SS_CreateObject \
  526.         CreateDynamicObject
  527.     #define SS_DestroyObject \
  528.         DestroyDynamicObject
  529. #endif
  530.  
  531. /*
  532. native Stinger_Create(mid, Float:x, Float:y, Float:z, Float:a);
  533. */
  534.  
  535. stock Stinger_Create(mid, Float:x, Float:y, Float:z, Float:a)
  536. {
  537.     new
  538.         idx = Iter_Free(g_Spike);
  539.     if (idx != -1)
  540.     {
  541.         new
  542.             Float:adjust,
  543.             Float:length;
  544.         switch (mid)
  545.         {
  546.             case 2892:
  547.             {
  548.                 length = 5.0;
  549.             }
  550.             case 2899:
  551.             {
  552.                 length = 2.5;
  553.                 adjust = 0.118;
  554.             }
  555.             default:
  556.             {
  557.                 return INVALID_OBJECT_ID;
  558.             }
  559.         }
  560.         new
  561.             id = SS_CreateObject(mid, x, y, z + adjust, 0.0, 0.0, a - 90.0);
  562.         if (id != INVALID_OBJECT_ID)
  563.         {
  564.             a = -a;
  565.             Iter_Add(g_Spike, idx);
  566.             g_SpikeStrip[idx] = id;
  567.  
  568.             #if SS_LINE_SEGMENTS == 1
  569.  
  570.             g_Spike_x1[idx] = x + length * floatsin(a - 90.0, degrees);
  571.             g_Spike_y1[idx] = y + length * floatcos(a - 90.0, degrees);
  572.             g_Spike_x2[idx] = x - length * floatsin(a - 90.0, degrees);
  573.             g_Spike_y2[idx] = y - length * floatcos(a - 90.0, degrees);
  574.  
  575.             #endif
  576.  
  577.             #if SS_LINE_SEGMENTS >= 2
  578.  
  579.             new
  580.                 value;
  581.             mid != 2892 && (value = 10) || (value = 5);
  582.             g_Spike_x1[idx] = x + length * floatsin(a - (90.0 + value), degrees);
  583.             g_Spike_y1[idx] = y + length * floatcos(a - (90.0 + value), degrees);
  584.             g_Spike_x3[idx] = x + length * floatsin(a - (90.0 - value), degrees);
  585.             g_Spike_y3[idx] = y + length * floatcos(a - (90.0 - value), degrees);
  586.  
  587.             #if SS_LINE_SEGMENTS == 2
  588.  
  589.             g_Spike_x2[idx] = x - length * floatsin(a - (90.0 + value), degrees);
  590.             g_Spike_y2[idx] = y - length * floatcos(a - (90.0 + value), degrees);
  591.             g_Spike_x4[idx] = x - length * floatsin(a - (90.0 - value), degrees);
  592.             g_Spike_y4[idx] = y - length * floatcos(a - (90.0 - value), degrees);
  593.  
  594.             #endif
  595.  
  596.             #if SS_LINE_SEGMENTS == 4
  597.  
  598.             g_Spike_x2[idx] = x - length * floatsin(a - (90.0 - value), degrees);
  599.             g_Spike_y2[idx] = y - length * floatcos(a - (90.0 - value), degrees);
  600.             g_Spike_x4[idx] = x - length * floatsin(a - (90.0 + value), degrees);
  601.             g_Spike_y4[idx] = y - length * floatcos(a - (90.0 + value), degrees);
  602.  
  603.             #endif
  604.  
  605.             #endif
  606.  
  607.             g_Spike_zA[idx] = z;
  608.             return idx;
  609.         }
  610.     }
  611.     return INVALID_OBJECT_ID;
  612. }
  613.  
  614. #define SpikeStrip_Create Stinger_Create
  615.  
  616. /*
  617. native Stinger_Delete(sid);
  618. */
  619.  
  620. stock Stinger_Delete(sid)
  621. {
  622.     if (Iter_Contains(g_Spike, sid))
  623.     {
  624.         SS_DestroyObject(g_SpikeStrip[sid]);
  625.         Iter_Remove(g_Spike, sid);
  626.     }
  627.     return 1;
  628. }
  629.  
  630. #define SpikeStrip_Delete Stinger_Delete
  631.  
  632. /*
  633. native Stinger_DeleteAll();
  634. */
  635.  
  636. stock Stinger_DeleteAll()
  637. {
  638.     foreach (new i : g_Spike)
  639.     {
  640.         SS_DestroyObject(g_SpikeStrip[i]);
  641.         Iter_SafeRemove(g_Spike, i, i);
  642.     }
  643.     return 1;
  644. }
  645.  
  646. #define SpikeStrip_DeleteAll Stinger_DeleteAll
  647.  
  648. /*
  649. native Stinger_IsValid(sid);
  650. */
  651.  
  652. stock Stinger_IsValid(sid)
  653. {
  654.     return Iter_Contains(g_Spike, sid);
  655. }
  656.  
  657. #define SpikeStrip_IsValid Stinger_IsValid
  658.  
  659. /*
  660. native Stinger_SetGhost(pid, bool:toggle);
  661. */
  662.  
  663. stock Stinger_SetGhost(pid, bool:toggle)
  664. {
  665.     g_GetVehicleID[pid] = 0;
  666.     g_GetGhostMode{pid} = toggle;
  667.     return 1;
  668. }
  669.  
  670. #define SpikeStrip_SetGhost Stinger_SetGhost
  671.  
  672. /*
  673. native Stinger_IsGhost(pid);
  674. */
  675.  
  676. stock Stinger_IsGhost(pid)
  677. {
  678.     return g_GetGhostMode{pid};
  679. }
  680.  
  681. #define SpikeStrip_IsGhost Stinger_IsGhost
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement