10.04.2010, 13:19
This function uses RedShirt's "DistanceCameraTargetToLocation" and modified GetPlayerFacingAngleToPoint, which I have altered to GetPointAngleToPoint.
When you want to detect, if a player is aiming at any position, you don't need only camera pos and camera front vector, since the crosshair position is not correlating the camera vector. I've set the function IsPlayerAimingAt so it reflects all angle (both horizontal and vertical) differences upon the weapons.
You need to implement all these functions. IsPlayerAimingAt is then used to detect where players are aiming their crosshair. The accuracy is circa 98%.
This function detects, if player is aiming at another player.
And this one should reliably detect a headshot (I haven't tested this one though).
When you want to detect, if a player is aiming at any position, you don't need only camera pos and camera front vector, since the crosshair position is not correlating the camera vector. I've set the function IsPlayerAimingAt so it reflects all angle (both horizontal and vertical) differences upon the weapons.
Код:
Float:DistanceCameraTargetToLocation(Float:CamX, Float:CamY, Float:CamZ, Float:ObjX, Float:ObjY, Float:ObjZ, Float:FrX, Float:FrY, Float:FrZ) { new Float:TGTDistance; TGTDistance = floatsqroot((CamX - ObjX) * (CamX - ObjX) + (CamY - ObjY) * (CamY - ObjY) + (CamZ - ObjZ) * (CamZ - ObjZ)); new Float:tmpX, Float:tmpY, Float:tmpZ; tmpX = FrX * TGTDistance + CamX; tmpY = FrY * TGTDistance + CamY; tmpZ = FrZ * TGTDistance + CamZ; return floatsqroot((tmpX - ObjX) * (tmpX - ObjX) + (tmpY - ObjY) * (tmpY - ObjY) + (tmpZ - ObjZ) * (tmpZ - ObjZ)); } stock Float:GetPointAngleToPoint(Float:x2, Float:y2, Float:X, Float:Y) { new Float:DX, Float:DY; new Float:angle; DX = floatabs(floatsub(x2,X)); DY = floatabs(floatsub(y2,Y)); if (DY == 0.0 || DX == 0.0) { if(DY == 0 && DX > 0) angle = 0.0; else if(DY == 0 && DX < 0) angle = 180.0; else if(DY > 0 && DX == 0) angle = 90.0; else if(DY < 0 && DX == 0) angle = 270.0; else if(DY == 0 && DX == 0) angle = 0.0; } else { angle = atan(DX/DY); if(X > x2 && Y <= y2) angle += 90.0; else if(X <= x2 && Y < y2) angle = floatsub(90.0, angle); else if(X < x2 && Y >= y2) angle -= 90.0; else if(X >= x2 && Y > y2) angle = floatsub(270.0, angle); } return floatadd(angle, 90.0); } stock GetXYInFrontOfPoint(&Float:x, &Float:y, Float:angle, Float:distance) { x += (distance * floatsin(-angle, degrees)); y += (distance * floatcos(-angle, degrees)); } stock IsPlayerAimingAt(playerid, Float:x, Float:y, Float:z, Float:radius) { new Float:camera_x,Float:camera_y,Float:camera_z,Float:vector_x,Float:vector_y,Float:vector_z; GetPlayerCameraPos(playerid, camera_x, camera_y, camera_z); GetPlayerCameraFrontVector(playerid, vector_x, vector_y, vector_z); new Float:vertical, Float:horizontal; switch (GetPlayerWeapon(playerid)) { case 34,35,36: { if (DistanceCameraTargetToLocation(camera_x, camera_y, camera_z, x, y, z, vector_x, vector_y, vector_z) < radius) return true; return false; } case 30,31: {vertical = 4.0; horizontal = -1.6;} case 33: {vertical = 2.7; horizontal = -1.0;} default: {vertical = 6.0; horizontal = -2.2;} } new Float:angle = GetPointAngleToPoint(0, 0, floatsqroot(vector_x*vector_x+vector_y*vector_y), vector_z) - 270.0; new Float:resize_x, Float:resize_y, Float:resize_z = floatsin(angle+vertical, degrees); GetXYInFrontOfPoint(resize_x, resize_y, GetPointAngleToPoint(0, 0, vector_x, vector_y)+horizontal, floatcos(angle+vertical, degrees)); if (DistanceCameraTargetToLocation(camera_x, camera_y, camera_z, x, y, z, resize_x, resize_y, resize_z) < radius) return true; return false; }
Код:
stock IsPlayerAimingAtPlayer(playerid, targetplayerid) { new Float:x, Float:y, Float:z; GetPlayerPos(targetplayerid, x, y, z); return IsPlayerAimingAt(playerid, x, y, z, 1.1); }
Код:
stock IsHeadshot(playerid, targetplayerid) { new Float:x, Float:y, Float:z; GetPlayerPos(targetplayerid, x, y, z); return IsPlayerAimingAt(playerid, x, y, z+0.8, 0.2); }