Advertisement
Guest User

[SAMP] GetPlayerAimedBodyPart inc v2.0 by Dinnozor

a guest
Jan 6th, 2013
2,373
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.95 KB | None | 0 0
  1.  
  2. /*
  3.  
  4. GetPlayerAimedBodyPart include (v1.01) by Dinnozor
  5.  
  6. Detects if you shoot the head/arm/leg/torso of a player !
  7.  
  8. Feel free to share but please don't remove credits.
  9.  
  10. Credits :
  11.     -wups for GetDistanceFromPointToLine                                                        
  12.     -Double-O-Seven for CrossProduct system
  13.     -Nero3D for GetPlayerCameraWeaponVector
  14.  
  15. Thanks also to TheArcher, wups, Nanory for their help and contribution.
  16.  
  17. v2.0 :
  18. -finally got this working as a real include
  19. -greatly improved the accuracy thanks to Nero_3D GetPlayerCameraWeaponVector include that let me take the correct offset with Widescreen ON
  20. -/widescreen command to let the player take the Widescreen ON/OFF mode. Being in Widescreen ON mode is no longer a problem since it doesn't make it easier to do headshots. Indeed, the script now checks if the player aims a point, no more just the coord on Z axis. Please note it is still working better with Widescreen OFF mode.
  21.  
  22. v1.01:
  23. -made it easier to shoot the arm, which was almost impossible in the 1.0
  24. -kind of found a solution about the widescreen on/off problem (thanks to Nanory on Samp Forums for reporting) : the script checks if the player has an "overcorrection" with the GetPlayerCameraFrontVector Z-coord (which was the case when the player used Widescreen). If so, it will put the player in a "Widescreen" mode.
  25. Also (since all the values were got experimentally), it will make the inverse check with angle correction (still about the GetPlayerCameraFrontVector inaccuracy with other weapons than sniper rifle) to check if the player lacks of correction. So basically, if the player is not in Widescreen but the script detected so (because of any bug or a wrong calculation), the script will automatically put the player back in non-Widescreen mode.
  26. Added some calculation to do that, and a PVar "Widescreen".
  27. Moreover, please note the script will be more accurate without Widescreen.
  28.  
  29. More info here : http://forum.sa-mp.com/showthread.php?t=403713
  30. Video here : http://www.youtube.com/watch?v=2Y4ngd_wpzY
  31.  
  32. */
  33.  
  34. #include <a_samp>
  35.  
  36. #if defined GPABP
  37. #endinput
  38. #endif
  39. #define GPABP
  40.  
  41. #define BP_HEAD 1
  42. #define BP_BODY 0
  43. #define BP_ARM 3
  44. #define BP_LEG 2
  45.  
  46. #if !defined COLOR_LIGHTRED
  47. #define COLOR_LIGHTRED 0xFF6347AA
  48. #endif
  49.  
  50. forward Float:DistanceGPABP(Float:xA,Float:yA,Float:zA,Float:xB,Float:yB,Float:zB);
  51.  
  52. forward OnPlayerHeadshot(playerid,targetid,weaponid);
  53. forward OnPlayerLegshot(playerid,targetid,weaponid);
  54. forward OnPlayerArmshot(playerid,targetid,weaponid);
  55.  
  56. static
  57. bool:GPA_OPC,
  58. bool:GPA_OPTD,
  59. bool:GPA_OPCT;
  60.  
  61. public OnPlayerCommandText(playerid,cmdtext[])
  62. {
  63.     if(!strcmp(cmdtext,"/widescreen",true))
  64.     {
  65.         //Let the player toggle the Widescreen mode ON/OFF, according to his settings.
  66.         new ws=GetPVarInt(playerid,"Widescreen");
  67.         if(ws==0)
  68.         {
  69.             SetPVarInt(playerid,"Widescreen",1);
  70.             SendClientMessage(playerid,COLOR_LIGHTRED,"Widescreen ON");
  71.            
  72.         }
  73.         else
  74.         {
  75.             SetPVarInt(playerid,"Widescreen",0);
  76.             SendClientMessage(playerid,COLOR_LIGHTRED,"Widescreen OFF");
  77.            
  78.         }
  79.         return 1;
  80.        
  81.     }
  82.     if(GPA_OPCT)
  83.     {
  84.         return CallLocalFunction("GPA_OnPlayerCommandText","is",playerid,cmdtext);
  85.        
  86.     }
  87.     return 0;
  88. }
  89.  
  90. #if defined _ALS_OnPlayerCommandText
  91. #undef OnPlayerCommandText
  92. #else
  93. #define _ALS_OnPlayerCommandText
  94. #endif
  95. #define OnPlayerCommandText GPA_OnPlayerCommandText
  96.  
  97. forward GPA_OnPlayerCommandText(playerid,cmdtext[]);
  98.  
  99. public Float:DistanceGPABP(Float:xA,Float:yA,Float:zA,Float:xB,Float:yB,Float:zB)
  100. {
  101.     new Float:Dist=floatsqroot((xB-xA)*(xB-xA)+(yB-yA)*(yB-yA)+(zB-zA)*(zB-zA));
  102.     return Dist;
  103. }
  104.  
  105. stock AdjustVector(& Float: vX, & Float: vY, & Float: vZ, Float: oX, Float: oY, const Float: oZ)
  106. {
  107.     // Credits Nero_3D
  108.     static
  109.     Float: Angle;
  110.     Angle = -atan2(vX, vY);
  111.     if(45.0 < Angle)
  112.     {
  113.         oX ^= oY;
  114.         oY ^= oX;
  115.         oX ^= oY;
  116.         if(90.0 < Angle)
  117.         {
  118.             oX *= -1;
  119.             if(135.0 < Angle)
  120.             {
  121.                 oX *= -1;
  122.                 oX ^= oY;
  123.                 oY ^= oX;
  124.                 oX ^= oY;
  125.                 oX *= -1;
  126.                
  127.             }
  128.            
  129.         }
  130.        
  131.     }
  132.     else if(Angle < 0.0)
  133.     {
  134.         oY *= -1;
  135.         if(Angle < -45.0)
  136.         {
  137.             oX *= -1;
  138.             oX ^= oY;
  139.             oY ^= oX;
  140.             oX ^= oY;
  141.             oX *= -1;
  142.             if(Angle < -90.0)
  143.             {
  144.                 oX *= -1;
  145.                 if(Angle < -135.0)
  146.                 {
  147.                     oX ^= oY;
  148.                     oY ^= oX;
  149.                     oX ^= oY;
  150.                    
  151.                 }
  152.                
  153.             }
  154.            
  155.         }
  156.        
  157.     }
  158.     vX += oX,
  159.     vY += oY;
  160.     vZ += oZ;
  161.     return false;
  162. }
  163.  
  164. stock GetPlayerCameraWeaponVector(playerid, & Float: vX, & Float: vY, & Float: vZ)
  165. {
  166.     // Credits Nero_3D. I just added the offset for Widescreen ON players
  167.     static
  168.     weapon;
  169.     if(21 < (weapon = GetPlayerWeapon(playerid)) < 39)
  170.     {
  171.         GetPlayerCameraFrontVector(playerid, vX, vY, vZ);
  172.         switch(weapon)
  173.         {
  174.             case WEAPON_SNIPER, WEAPON_ROCKETLAUNCHER, WEAPON_HEATSEEKER:
  175.             {
  176.             }
  177.             case WEAPON_RIFLE:
  178.             {
  179.                 if(GetPVarInt(playerid,"Widescreen")==0) AdjustVector(vX, vY, vZ, 0.016204, 0.009899, 0.047177);
  180.                 else AdjustVector(vX, vY, vZ, 0.015085, 0.010467, 0.035687);
  181.                
  182.                
  183.             }
  184.            
  185.             case WEAPON_AK47, WEAPON_M4:
  186.             {
  187.                 if(GetPVarInt(playerid,"Widescreen")==0) AdjustVector(vX, vY, vZ, 0.026461, 0.013070, 0.069079);
  188.                 else AdjustVector(vX, vY, vZ, 0.024255, 0.013714, 0.053342);
  189.                
  190.                
  191.             }
  192.            
  193.             default:
  194.             {
  195.                 if(GetPVarInt(playerid,"Widescreen")==0) AdjustVector(vX, vY, vZ, 0.043949, 0.015922, 0.103412);
  196.                 else AdjustVector(vX, vY, vZ, 0.041103, 0.014111, 0.079249);
  197.                
  198.                
  199.             }
  200.            
  201.         }
  202.         return true;
  203.        
  204.     }
  205.     else
  206.     GetPlayerCameraFrontVector(playerid, vX, vY, vZ);
  207.     return false;
  208. }
  209.  
  210. stock crossp(Float:v1x, Float:v1y, Float:v1z, Float:v2x, Float:v2y, Float:v2z, &Float:output)
  211. {
  212.     new
  213.     Float:c1 = (v1y * v2z) - (v1z * v2y),
  214.     Float:c2 = (v1z * v2x) - (v1x * v2z),
  215.     Float:c3 = (v1x * v2y) - (v1y * v2x);
  216.     output = floatsqroot ((c1 * c1) + (c2 * c2) + (c3 * c3));
  217.     return 0;
  218. }
  219. stock GetDistanceFromPointToLine(&Float:distance, Float:line_vector_x, Float:line_vector_y, Float:line_vector_z, Float:line_x, Float:line_y, Float:line_z, Float:point_x, Float:point_y, Float:point_z)
  220. {
  221.     //A line is defined by a point (which is on the line (line_x/y/z)) and a vector which defines the direction (line_vector_x/y/z).
  222.     static Float:output;
  223.     crossp(line_vector_x, line_vector_y, line_vector_z, point_x - line_x, point_y - line_y, point_z - line_z, output);//Cross product of 2 vectors.
  224.     distance = output / floatsqroot ((line_vector_x * line_vector_x) + (line_vector_y * line_vector_y) + (line_vector_z * line_vector_z));
  225.     return 0;
  226. }
  227.  
  228. stock GetPlayerAimedBodyPart(playerid, targetid, Float:range)
  229. {
  230.     new Float:xv,Float:yv,Float:zv,Float:xc,Float:yc,Float:zc,Float:zt,Float:X2,Float:Y2,Float:Z2;
  231.     new Float:AngleP,Float:xP,Float:yP,Float:zP;
  232.     new Float:DistH,Float:DistL,Float:DistA;
  233.     GetPlayerPos(targetid,X2,Y2,Z2);
  234.     GetPlayerPos(playerid,xP,yP,zP);
  235.     GetPlayerCameraPos(playerid,xc,yc,zc);
  236.     GetPlayerCameraWeaponVector(playerid,xv,yv,zv);
  237.     GetPlayerFacingAngle(targetid,AngleP);
  238.    
  239.     zt=range*zv+zc;
  240.    
  241.     if(GetPlayerSpecialAction(targetid)==1)
  242.     {
  243.         GetDistanceFromPointToLine(DistH,xv,yv,zv,xc,yc,zc,X2,Y2,Z2-0.1);
  244.         GetDistanceFromPointToLine(DistA,xv,yv,zv,xc,yc,zc,0.5*floatcos(-AngleP,degrees)+X2,Y2-0.5*floatsin(-AngleP,degrees),Z2-0.55);
  245.         if(DistH<=0.2) return BP_HEAD;
  246.         else if(DistA<=0.3) return BP_ARM;
  247.        
  248.     }
  249.     else if(GetPlayerState(targetid)!=1)
  250.     {
  251.         if(Z2+0.4<=zt) return BP_HEAD;
  252.        
  253.     }
  254.     else
  255.     {
  256.         GetDistanceFromPointToLine(DistH,xv,yv,zv,xc,yc,zc,X2,Y2,Z2+0.6);
  257.         GetDistanceFromPointToLine(DistL,xv,yv,zv,xc,yc,zc,X2,Y2,Z2-0.4);
  258.         GetDistanceFromPointToLine(DistA,xv,yv,zv,xc,yc,zc,0.5*floatcos(-AngleP,degrees)+X2,Y2-0.5*floatsin(-AngleP,degrees),Z2);
  259.         if(DistH<=0.2) return BP_HEAD;
  260.         else if(DistL<=0.5) return BP_LEG;
  261.         else if(DistA<=0.4) return BP_ARM;
  262.        
  263.     }
  264.     return BP_BODY;
  265. }
  266.  
  267. public OnPlayerTakeDamage(playerid, issuerid, Float:amount, weaponid)
  268. {
  269.     new Float:Xt,Float:Yt,Float:Zt;
  270.     GetPlayerPos(playerid,Xt,Yt,Zt);
  271.     if(issuerid!=INVALID_PLAYER_ID)
  272.    
  273.     {
  274.         new Float:xc,Float:yc,Float:zc,Float:DistC;
  275.         GetPlayerCameraPos(issuerid,xc,yc,zc);
  276.         DistC=DistanceGPABP(xc,yc,zc,Xt,Yt,Zt);
  277.        
  278.         switch(GetPlayerAimedBodyPart(issuerid,playerid,DistC))
  279.        
  280.         {
  281.             case BP_HEAD:CallLocalFunction("OnPlayerHeadshot", "ddd", issuerid,playerid,weaponid);
  282.             case BP_LEG:CallLocalFunction("OnPlayerLegshot", "ddd", issuerid,playerid,weaponid);
  283.             case BP_ARM:CallLocalFunction("OnPlayerArmshot", "ddd", issuerid,playerid,weaponid);
  284.             //Create a call back for torso shots if you want : use default here
  285.            
  286.            
  287.         }
  288.        
  289.        
  290.        
  291.     }
  292.     if(GPA_OPTD)
  293.     {
  294.         return CallLocalFunction("GPA_OnPlayerTakeDamage","ddfd",playerid,issuerid,amount,weaponid);
  295.        
  296.     }
  297.     return 1;
  298. }
  299.  
  300. #if defined _ALS_OnPlayerTakeDamage
  301. #undef OnPlayerTakeDamage
  302. #else
  303. #define _ALS_OnPlayerTakeDamage
  304. #endif
  305. #define OnPlayerTakeDamage GPA_OnPlayerTakeDamage
  306.  
  307. forward GPA_OnPlayerTakeDamage(playerid,issuerid,Float:amount,weaponid);
  308.  
  309. public OnPlayerConnect(playerid)
  310. {
  311.     //Let's tell the people to check their Display settings. You can also save this var in a file, if you don't want to make them check everytime...
  312.     SendClientMessage(playerid,COLOR_LIGHTRED,"Use /widescreen command to set your aim (if you use Widescreen ON). See your advanced display settings.");
  313.     SetPVarInt(playerid,"Widescreen",0);//Assuming most of the people don't use Widescreen
  314.     if(GPA_OPC)
  315.     {
  316.         return CallLocalFunction("GPA_OnPlayerConnect","d",playerid);
  317.        
  318.     }
  319.     return 1;
  320. }
  321.  
  322. #if defined _ALS_OnPlayerConnect
  323. #undef OnPlayerConnect
  324. #else
  325. #define _ALS_OnPlayerConnect
  326. #endif
  327. #define OnPlayerConnect GPA_OnPlayerConnect
  328.  
  329. forward GPA_OnPlayerConnect(playerid);
  330.  
  331. public OnGameModeInit()
  332.  
  333. {
  334.     GPA_OPC=funcidx("GPA_OnPlayerConnect")!=-1;
  335.     GPA_OPTD=funcidx("GPA_OnPlayerTakeDamage")!=-1;
  336.     GPA_OPCT=funcidx("GPA_OnPlayerCommandText")!=-1;
  337.     if(funcidx("GPA_OnGameModeInit")!=-1)
  338.     {
  339.         return CallLocalFunction("GPA_OnGameModeInit","");
  340.        
  341.     }
  342.     return 1;
  343.    
  344. }
  345. #if defined _ALS_OnGameModeInit
  346. #undef OnGameModeInit
  347. #else
  348. #define _ALS_OnGameModeInit
  349. #endif
  350. #define OnGameModeInit GPA_OnGameModeInit
  351.  
  352. forward GPA_OnGameModeInit();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement