Advertisement
Guest User

SA-MP Polygonal Boundaries

a guest
Dec 10th, 2018
186
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pawn 9.19 KB | None | 0 0
  1. #include <a_samp>
  2.  
  3. #define B_MAXLENGTH 15
  4. #define B_NUMBER 1
  5. #define B_XY 0.2
  6. #define B_XY_LIGHT_PLANES 0.5
  7. #define B_ANGV_LIGHT_PLANES 2.0
  8. #define B_XY_HEAVY_PLANES 6.0
  9. #define B_ANGV_HEAVY_PLANES 8.0
  10. #define B_Z 0.1
  11. #define B_MAXXY 5000
  12. #define B_TXT_SHOW_DELAY 7000
  13. #define B_TXT_HIDE_DELAY 2500
  14. #define B_DELAY 1000
  15. #define B_NONE -1
  16.  
  17. new Text: b_textdraw;
  18.  
  19. new Float: b_p1x[B_NUMBER][B_MAXLENGTH];
  20. new Float: b_p1y[B_NUMBER][B_MAXLENGTH];
  21. new Float: b_p2x[B_NUMBER][B_MAXLENGTH];
  22. new Float: b_p2y[B_NUMBER][B_MAXLENGTH];
  23. new b_players[MAX_PLAYERS] = { B_NONE, ... };
  24.  
  25. new b_length[B_NUMBER];
  26. new b_maxid;
  27.  
  28. new Float: b_vx[MAX_PLAYERS];
  29. new Float: b_vy[MAX_PLAYERS];
  30. new b_isoutside[MAX_PLAYERS];
  31. new b_showtimers[MAX_PLAYERS];
  32.  
  33. forward BoundariesTextdrawShowTimer(playerid);
  34. forward BoundariesTextdrawHideTimer(playerid);
  35. forward BoundariesTimer(playerid);
  36.  
  37. public BoundariesTextdrawShowTimer(playerid) {
  38.     TextDrawShowForPlayer(playerid, b_textdraw);
  39.     SetTimerEx("BoundariesTextdrawHideTimer", B_TXT_HIDE_DELAY, false, "d", playerid);
  40. }
  41.  
  42. public BoundariesTextdrawHideTimer(playerid) {
  43.     TextDrawHideForPlayer(playerid, b_textdraw);
  44. }
  45.  
  46. public BoundariesTimer() {
  47.     for (new playerid = 0; playerid < MAX_PLAYERS; playerid++) if (b_isoutside[playerid]) CalculateVelocity(playerid);
  48. }
  49.  
  50. stock EdgeCrossesLine(Float: e1p1x, Float: e1p1y, Float: e1p2x, Float: e1p2y, Float: e2p1x, Float: e2p1y, Float: e2p2x, Float: e2p2y) {
  51.     new Float: etmpx = e1p2x - e1p1x, Float: etmpy = e1p2y - e1p1y,
  52.         Float: product1 = etmpx * (e2p1y - e1p1y) - (e2p1x - e1p1x) * etmpy, Float: product2 = etmpx * (e2p2y - e1p1y) - (e2p2x - e1p1x) * etmpy;
  53.    
  54.     return (floatabs(product1) < EPS) || (floatabs(product2) < EPS) || ((product1 < 0) ^ (product2 < 0));
  55. }
  56.  
  57. stock BoxesIntersect(Float: e1p1x, Float: e1p1y, Float: e1p2x, Float: e1p2y, Float: e2p1x, Float: e2p1y, Float: e2p2x, Float: e2p2y) {                  
  58.     return (e1p1x < e1p2x ? e1p1x : e1p2x) <= (e2p1x > e2p2x ? e2p1x : e2p2x) && (e1p1x > e1p2x ? e1p1x : e1p2x) >= (e2p1x < e2p2x ? e2p1x : e2p2x) &&
  59.            (e1p1y < e1p2y ? e1p1y : e1p2y) <= (e2p1y > e2p2y ? e2p1y : e2p2y) && (e1p1y > e1p2y ? e1p1y : e1p2y) >= (e2p1y < e2p2y ? e2p1y : e2p2y);
  60. }
  61.  
  62. stock Intersect(Float: e1p1x, Float: e1p1y, Float: e1p2x, Float: e1p2y, Float: e2p1x, Float: e2p1y, Float: e2p2x, Float: e2p2y) {
  63.     return BoxesIntersect(e1p1x, e1p1y, e1p2x, e1p2y, e2p1x, e2p1y, e2p2x, e2p2y) && EdgeCrossesLine(e1p1x, e1p1y, e1p2x, e1p2y, e2p1x, e2p1y, e2p2x, e2p2y) &&
  64.            EdgeCrossesLine(e2p1x, e2p1y, e2p2x, e2p2y, e1p1x, e1p1y, e1p2x, e1p2y);
  65. }
  66.  
  67. stock PlayerWithinBoundaries(playerid, bid) {
  68.     new Float: x, Float: y, Float: rayy;
  69.     new i, ctr = 0, flag = 0;
  70.    
  71.     GetPlayerPos(playerid, x, y, rayy);
  72.     rayy = y;
  73.    
  74.     for (i = 0; i < b_length[bid]; i++) {
  75.         if (floatabs(b_p1y[bid][i] - y) < EPS || floatabs(b_p2y[bid][i] - y) < EPS) { flag = 1; rayy += EPS; }
  76.         if (Intersect(x, rayy, B_MAXXY, rayy, b_p1x[bid][i], b_p1y[bid][i], b_p2x[bid][i], b_p2y[bid][i])) ctr++;
  77.         if (flag) { flag = 0; rayy -= EPS; }
  78.     }
  79.     return ctr%2;
  80. }
  81.  
  82. stock InitBoundaries() {
  83.     b_textdraw = TextDrawCreate(320, 216, "STAY WITHIN THE ~r~WORLD BOUNDRIES");
  84.     TextDrawAlignment(b_textdraw, 2);
  85.     TextDrawSetShadow(b_textdraw, 0);
  86.     TextDrawSetOutline(b_textdraw, 2);
  87.     TextDrawLetterSize(b_textdraw, 0.6, 2.9);
  88.     TextDrawFont(b_textdraw, 2);
  89.    
  90.     SetTimer("BoundariesTimer", B_DELAY, true);
  91. }
  92.  
  93. stock AssignBoundaries(playerid, bid) {
  94.     if (b_players[playerid] != B_NONE) {
  95.         TextDrawHideForPlayer(playerid, b_textdraw);
  96.         KillTimer(b_showtimers[playerid]);
  97.     }
  98.     b_vx[playerid] = b_vy[playerid] = b_isoutside[playerid] = b_showtimers[playerid] = 0;
  99.     b_players[playerid] = bid;
  100. }
  101.  
  102. stock RemoveBoundaries(playerid) {
  103.     AssignBoundaries(playerid, B_NONE);
  104. }
  105.  
  106. stock CreateBoundaries(Float: array[], points) {
  107.     if (b_maxid >= B_NUMBER || points < 6) return B_NONE;
  108.    
  109.     b_length[b_maxid] = points/2;
  110.     for (new i = 0; i < b_length[b_maxid] - 1; i++) {
  111.         b_p1x[b_maxid][i] = array[i*2];
  112.         b_p1y[b_maxid][i] = array[i*2 + 1];
  113.         b_p2x[b_maxid][i] = array[(i + 1)*2];
  114.         b_p2y[b_maxid][i] = array[(i + 1)*2 + 1];
  115.     }
  116.     b_p1x[b_maxid][b_length[b_maxid] - 1] = array[b_length[b_maxid]*2 - 2];
  117.     b_p1y[b_maxid][b_length[b_maxid] - 1] = array[b_length[b_maxid]*2 - 1];
  118.     b_p2x[b_maxid][b_length[b_maxid] - 1] = array[0];
  119.     b_p2y[b_maxid][b_length[b_maxid] - 1] = array[1];
  120.    
  121.     return b_maxid++;
  122. }
  123.  
  124. stock CalculateVelocity(playerid, Float: b_xy = B_XY) {
  125.     new Float: x, Float: y, Float: z, Float: clx, Float: cly, Float: clx_tmp, Float: cly_tmp, Float: mindistance = B_MAXXY*B_MAXXY, Float: distance;
  126.    
  127.     GetPlayerPos(playerid, x, y, z);
  128.     for (new i = 0; i < b_length[b_players[playerid]]; i++) {
  129.         if (floatabs(b_p2x[b_players[playerid]][i] - b_p1x[b_players[playerid]][i]) < EPS) {
  130.             clx_tmp = b_p1x[b_players[playerid]][i];
  131.             cly_tmp = y;
  132.         }
  133.         else if (floatabs(b_p2y[b_players[playerid]][i] - b_p1y[b_players[playerid]][i]) < EPS) {
  134.             clx_tmp = x;
  135.             cly_tmp = b_p1y[b_players[playerid]][i];
  136.         }
  137.         else {
  138.             new Float: k1, Float: k2, Float: b1, Float: b2;
  139.  
  140.             k1 = (b_p2y[b_players[playerid]][i] - b_p1y[b_players[playerid]][i])/(b_p2x[b_players[playerid]][i] -
  141.                 b_p1x[b_players[playerid]][i]);
  142.             b1 = b_p1y[b_players[playerid]][i] - k1*b_p1x[b_players[playerid]][i];
  143.             k2 = -1/k1;
  144.             b2 = y - k2*x;
  145.             clx_tmp = (b2 - b1)/(k1 - k2);
  146.             cly_tmp = k2*clx_tmp + b2;
  147.         }
  148.  
  149.         if (clx_tmp < (b_p1x[b_players[playerid]][i] < b_p2x[b_players[playerid]][i] ? b_p1x[b_players[playerid]][i] :
  150.                 b_p2x[b_players[playerid]][i]) ||
  151.             clx_tmp > (b_p1x[b_players[playerid]][i] > b_p2x[b_players[playerid]][i] ? b_p1x[b_players[playerid]][i] :
  152.                 b_p2x[b_players[playerid]][i]) ||
  153.             cly_tmp < (b_p1y[b_players[playerid]][i] < b_p2y[b_players[playerid]][i] ? b_p1y[b_players[playerid]][i] :
  154.                 b_p2y[b_players[playerid]][i]) ||
  155.             cly_tmp > (b_p1y[b_players[playerid]][i] > b_p2y[b_players[playerid]][i] ? b_p1y[b_players[playerid]][i] :
  156.                 b_p2y[b_players[playerid]][i])) {
  157.                     distance = (x - b_p1x[b_players[playerid]][i])*(x - b_p1x[b_players[playerid]][i]) +
  158.                         (y - b_p1y[b_players[playerid]][i])*(y - b_p1y[b_players[playerid]][i]);
  159.                     z = (x - b_p2x[b_players[playerid]][i])*(x - b_p2x[b_players[playerid]][i]) +
  160.                         (y - b_p2y[b_players[playerid]][i])*(y - b_p2y[b_players[playerid]][i]);
  161.                     if (distance < z) {
  162.                         clx_tmp = b_p1x[b_players[playerid]][i];
  163.                         cly_tmp = b_p1y[b_players[playerid]][i];
  164.                     }
  165.                     else {
  166.                         distance = z;
  167.                         clx_tmp = b_p2x[b_players[playerid]][i];
  168.                         cly_tmp = b_p2y[b_players[playerid]][i];
  169.                     }
  170.         }
  171.         else distance = (x - clx_tmp)*(x - clx_tmp) + (y - cly_tmp)*(y - cly_tmp);
  172.        
  173.         if (distance < mindistance) {
  174.             mindistance = distance;
  175.             clx = clx_tmp;
  176.             cly = cly_tmp;
  177.         }
  178.     }
  179.    
  180.     if (floatabs(x - clx) > floatabs(y - cly)) {
  181.         if (x > clx) b_vx[playerid] = -b_xy;
  182.         else b_vx[playerid] = b_xy;
  183.         if (y > cly) b_vy[playerid] = -floatabs((y - cly)/(x - clx))*b_xy;
  184.         else b_vy[playerid] = floatabs((y - cly)/(x - clx))*b_xy;
  185.     }
  186.     else {
  187.         if (y > cly) b_vy[playerid] = -b_xy;
  188.         else b_vy[playerid] = b_xy;
  189.         if (x > clx) b_vx[playerid] = -floatabs((x - clx)/(y - cly))*b_xy;
  190.         else b_vx[playerid] = floatabs((x - clx)/(y - cly))*b_xy;
  191.     }
  192. }
  193.  
  194. stock ProcessBoundaries(playerid) {
  195.     if (PlayerWithinBoundaries(playerid, b_players[playerid])) {
  196.         if (b_isoutside[playerid]) {
  197.             b_isoutside[playerid] = false;
  198.             b_vx[playerid] = b_vy[playerid] = 0;
  199.             KillTimer(b_showtimers[playerid]);
  200.         }
  201.     }
  202.     else {
  203.         if (!b_isoutside[playerid]) {
  204.             new vid = GetPlayerVehicleID(playerid);
  205.             new vm = GetVehicleModel(vid);
  206.            
  207.             b_isoutside[playerid] = true;
  208.             TextDrawShowForPlayer(playerid, b_textdraw);
  209.             SetTimerEx("BoundariesTextdrawHideTimer", B_TXT_HIDE_DELAY, false, "d", playerid);
  210.             b_showtimers[playerid] = SetTimerEx("BoundariesTextdrawShowTimer", B_TXT_SHOW_DELAY, true, "d", playerid);
  211.             if (vm && (vm == 460 || vm == 476 || vm == 511 || vm == 512 || vm == 513 || vm == 519 || vm == 520 || vm == 553 || vm == 577 || vm == 592 || vm == 593)) {
  212.                 new Float: x, Float: y, Float: z, Float: angv, Float: b_xy;
  213.                
  214.                 if (vm == 511 || vm == 553 || vm == 577 || vm == 592) {
  215.                     angv = B_ANGV_HEAVY_PLANES;
  216.                     b_xy = B_XY_HEAVY_PLANES;
  217.                 }
  218.                 else {
  219.                     angv = B_ANGV_LIGHT_PLANES;
  220.                     b_xy = B_XY_LIGHT_PLANES;
  221.                 }
  222.                
  223.                 GetVehicleVelocity(vid, x, y, z);
  224.                 CalculateVelocity(playerid, b_xy);
  225.                 if (atan2(x*b_vy[playerid] - y*b_vx[playerid], x*b_vx[playerid] + y*b_vy[playerid]) > 0) SetVehicleAngularVelocity(vid, 0.0, 0.0, angv);
  226.                 else SetVehicleAngularVelocity(vid, 0.0, 0.0, -angv);
  227.             }
  228.             else {
  229.                 new s_veh = GetPlayerSurfingVehicleID(playerid);
  230.                 new s_mod = GetVehicleModel(s_veh);
  231.                
  232.                 if (s_veh != INVALID_VEHICLE_ID && (s_mod == 449 || s_mod == 537 || s_mod == 538 || s_mod == 569 || s_mod == 570)) {
  233.                     new Float: x, Float: y, Float: z;
  234.                    
  235.                     GetPlayerPos(playerid, x, y, z);
  236.                     SetPlayerPos(playerid, x, y, z + 2);
  237.                 }
  238.                 CalculateVelocity(playerid);
  239.             }
  240.         }
  241.        
  242.         if (IsPlayerInAnyVehicle(playerid)) SetVehicleVelocity(GetPlayerVehicleID(playerid), b_vx[playerid], b_vy[playerid], B_Z);
  243.         else SetPlayerVelocity(playerid, b_vx[playerid], b_vy[playerid], B_Z);
  244.     }
  245. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement