{"id":22283470,"url":"https://github.com/y-less/samp-distance","last_synced_at":"2026-01-06T01:40:18.791Z","repository":{"id":142753095,"uuid":"177310718","full_name":"Y-Less/samp-distance","owner":"Y-Less","description":null,"archived":false,"fork":false,"pushed_at":"2022-11-28T11:20:08.000Z","size":127,"stargazers_count":19,"open_issues_count":0,"forks_count":3,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-30T17:39:22.682Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Pawn","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Y-Less.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-03-23T16:09:46.000Z","updated_at":"2024-12-26T23:34:41.000Z","dependencies_parsed_at":null,"dependency_job_id":"23b476ad-5302-407b-a6c3-8e3b9cc82a12","html_url":"https://github.com/Y-Less/samp-distance","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Y-Less%2Fsamp-distance","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Y-Less%2Fsamp-distance/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Y-Less%2Fsamp-distance/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Y-Less%2Fsamp-distance/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Y-Less","download_url":"https://codeload.github.com/Y-Less/samp-distance/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245535405,"owners_count":20631293,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-03T16:40:33.955Z","updated_at":"2026-01-06T01:40:18.737Z","avatar_url":"https://github.com/Y-Less.png","language":"Pawn","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SA-MP Distance Functions\n\n[![sampctl](https://shields.southcla.ws/badge/sampctl-samp--distance-2f2f2f.svg?style=for-the-badge)](https://github.com/kristoisberg/samp-distance)\n\nThis library offers a bunch of functions for getting the distance between various entities (2D/3D points, players, vehicles), performing proximity/distance checks between them and finding the closest entities to other entities. The idea for this library came after seeing a discussion on this topic on the forums and realising that there is no widely adopted library for performing these tasks and the homebrewed implementations often have major issues. Some of the issues this library addresses:\n\n* **Incorrect return values** - If a distance check fails because an entity does not exist, the result of the check is `NaN`, not `0.0` as the standard library would return, `9999.9999`, `-1.0` or any other nonsense. As you might know, comparing `NaN` to any value, even itself, always returns `false`, making it easy to distinguish if the function failed and avoiding incorrect behaviour in code using those functions.\n* **Inconsistent and non-descriptive function names** - A function name I saw in the topic mentioned above is `IsCoordNearCoord`, which has a similar behaviour to `IsPlayerInRangeOfPoint` from the standard library, but a completely different name structure. Some other examples are `GetClosestPlayer` and `GetClosestVehicle`, commonly used names for functions returning the closest player/vehicle to a player. The more you read the previous sentence, the more you will realise that the names are missing something...\n\nHuge thanks to Y_Less for his contributions to this library and the productive conversations with him!\n\n\n## Installation\n\nSimply install to your project:\n\n```bash\nsampctl package install kristoisberg/samp-distance\n```\n\nInclude in your code and begin using the library:\n\n```pawn\n#include \u003csamp-distance\u003e\n```\n\n## Changes to the standard library\n\nThis library hooks the `GetPlayerDistanceFromPoint` and `GetVehicleDistanceFromPoint` functions to return `NaN` instead of `0.0` when the functions fail (the player/vehicle does not exist). These changes should not affect any existing code since it should be checking for invalid players/vehicles before using these functions anyway.\n\n\n## Function Naming\n\nThe functions in this library have several basic forms:\n\n* `Get\u003cA\u003eDistanceTo\u003cB\u003e` - Get the distance between `A` and `B`.\n* `Is\u003cA\u003eInRangeOf\u003cB\u003e` - Is the distance between `A` and `B` lower than some threshold?\n* `GetClosest\u003cA\u003eTo\u003cB\u003e` - Get the closest `A` to `B`.\n\nPlus a few \"Point\" functions which take an `x/y` pair or `x/y/z` triple instead of another entity:\n\n* `Get\u003cA\u003eDistanceToPoint2D` - Get the distance between `A` and an `x/y` point.\n* `Is\u003cA\u003eInRangeOfPoint2D` - Is the distance between `A` and an `x/y` point lower than some threshold?\n* `Get\u003cA\u003eDistanceToPoint3D` - Get the distance between `A` and an `x/y/z` point.\n* `Is\u003cA\u003eInRangeOfPoint3D` - Is the distance between `A` and an `x/y/z` point lower than some threshold?\n\nAnd the overloaded versions that are determined by parameter count:\n\n* `Get\u003cA\u003eDistanceToPoint` - Get the distance between `A` and an `x/y(/z)` point.\n* `Is\u003cA\u003eInRangeOfPoint` - Is the distance between `A` and an `x/y(/z)` point lower than some threshold?\n\nFor each of these functions `A` and `B` can be any of the following entity types:\n\n* `Player`\n* `Vehicle`\n* `Object`\n* `DynObject` (with the streamer plugin).\n* `Actor`\n\nSo for example, to check if a vehicle (`A`) is near a given streamer object (`B`) use:\n\n```pawn\nif (IsVehicleInRangeOfDynObject(vehicleid, objectid, 50.0))\n{\n\t// Yes.\n}\n```\n\nThere are also two generic point functions:\n\n```pawn\nstock Float:GetPointDistanceToPoint(Float:x1, Float:y1, Float:z1, Float:x2, Float:y2 = FLOAT_NAN, Float:z2 = FLOAT_NAN);\nstock bool:IsPointInRangeOfPoint(Float:range, Float:x1, Float:y1, Float:z1, Float:x2, Float:y2 = FLOAT_NAN, Float:z2 = FLOAT_NAN);\n```\n\nThese can be invoked as 2D (with four/five parameters) or 3D (with six/seven parameters).\n\nIn many cases a function is overloaded on the number of parameters:\n\n```pawn\nif (IsVehicleInRangeOfPoint(vehicleid, 4.0, 5.0, 10.0)) // 2D check.\n{\n}\n\nif (IsVehicleInRangeOfPoint(vehicleid, 4.0, 5.0, 6.0, 10.0)) // 3D check.\n{\n}\n```\n\nYou can specify which with `IsVehicleInRangeOfPoint2D` and `IsVehicleInRangeOfPoint3D`, the underlying implementations, as listed below.\n\n\n## All Functions\n\nFunctions that return `Float:` will return `FLOAT_NAN` if they fail.  If, for example, one of the input entities doesn't exist.\n\n### Point - Point\n\n```pawn\nFloat:GetPointDistanceToPoint(Float:x1, Float:y1, Float:z1, Float:x2, Float:y2 = FLOAT_NAN, Float:z2 = FLOAT_NAN);\n\nbool:IsPointInRangeOfPoint(Float:range, Float:x1, Float:y1, Float:z1, Float:x2, Float:y2 = FLOAT_NAN, Float:z2 = FLOAT_NAN);\n```\n\n### Player - Point\n\n```pawn\nFloat:GetPlayerDistanceToPoint2D(playerid, Float:x, Float:y);\n\nbool:IsPlayerInRangeOfPoint2D(playerid, Float:range, Float:x, Float:y);\n\nFloat:GetPlayerDistanceToPoint3D(playerid, Float:x, Float:y, Float:z);\n\nbool:IsPlayerInRangeOfPoint3D(playerid, Float:range, Float:x, Float:y, Float:z);\n```\n\n### Player - Player\n\n```pawn\nFloat:GetPlayerDistanceToPlayer(playerid, targetid);\n\nbool:IsPlayerInRangeOfPlayer(playerid, targetid, Float:range, bool:ignoreVW = false, bool:ignoreInterior = false);\n\nGetClosestPlayerToPlayer(playerid, bool:ignoreVW = false, bool:ignoreInterior = false);\n```\n\n### Vehicle - Point\n\n```pawn\nFloat:GetVehicleDistanceToPoint2D(vehicleid, Float:x, Float:y);\n\nbool:IsVehicleInRangeOfPoint2D(vehicleid, Float:range, Float:x, Float:y);\n\nFloat:GetVehicleDistanceToPoint3D(vehicleid, Float:x, Float:y, Float:z);\n\nbool:IsVehicleInRangeOfPoint3D(vehicleid, Float:range, Float:x, Float:y, Float:z);\n```\n\n### Vehicle - Vehicle\n\n```pawn\nFloat:GetVehicleDistanceToVehicle(vehicleid, targetid);\n\nbool:IsVehicleInRangeOfVehicle(vehicleid, targetid, Float:range, bool:ignoreVW = false);\n\nGetClosestVehicleToVehicle(vehicleid, bool:ignoreVW = false);\n```\n\n### Object - Point\n\n```pawn\nFloat:GetObjectDistanceToPoint2D(objectid, Float:x, Float:y);\n\nbool:IsObjectInRangeOfPoint2D(objectid, Float:range, Float:x, Float:y);\n\nFloat:GetObjectDistanceToPoint3D(objectid, Float:x, Float:y, Float:z);\n\nbool:IsObjectInRangeOfPoint3D(objectid, Float:range, Float:x, Float:y, Float:z);\n```\n\n### Object - Object\n\n```pawn\nFloat:GetObjectDistanceToObject(objectid, targetid);\n\nbool:IsObjectInRangeOfObject(objectid, targetid, Float:range);\n\nGetClosestObjectToObject(objectid);\n```\n\n### DynObject - Point\n\n```pawn\nFloat:GetDynObjectDistanceToPoint2D(STREAMER_TAG_OBJECT:objectid, Float:x, Float:y);\n\nbool:IsDynObjectInRangeOfPoint2D(STREAMER_TAG_OBJECT:objectid, Float:range, Float:x, Float:y);\n\nFloat:GetDynObjectDistanceToPoint3D(STREAMER_TAG_OBJECT:objectid, Float:x, Float:y, Float:z);\n\nbool:IsDynObjectInRangeOfPoint3D(STREAMER_TAG_OBJECT:objectid, Float:range, Float:x, Float:y, Float:z);\n```\n\n### DynObject - DynObject\n\n```pawn\nFloat:GetDynObjectDistanceToDynObject(STREAMER_TAG_OBJECT:objectid, STREAMER_TAG_OBJECT:targetid);\n\nbool:IsDynObjectInRangeOfDynObject(STREAMER_TAG_OBJECT:objectid, STREAMER_TAG_OBJECT:targetid, Float:range);\n\nSTREAMER_TAG_OBJECT:GetClosestDynObjectToDynObject(STREAMER_TAG_OBJECT:objectid);\n```\n\n### Player - Vehicle\n\n```pawn\nFloat:GetVehicleDistanceToPlayer(vehicleid, playerid);\n\nbool:IsVehicleInRangeOfPlayer(vehicleid, playerid, Float:range, bool:ignoreVW = false);\n\nGetClosestVehicleToPlayer(playerid, bool:ignoreVW = false);\n\nFloat:GetPlayerDistanceToVehicle(playerid, vehicleid);\n\nbool:IsPlayerInRangeOfVehicle(playerid, vehicleid, Float:range, bool:ignoreVW = false);\n\nGetClosestPlayerToVehicle(vehicleid, bool:ignoreVW = false);\n```\n\n### Player - Object\n\n```pawn\nFloat:GetPlayerDistanceToObject(playerid, objectid);\n\nbool:IsPlayerInRangeOfObject(playerid, objectid, Float:range);\n\nGetClosestPlayerToObject(objectid);\n\nFloat:GetObjectDistanceToPlayer(objectid, playerid);\n\nbool:IsObjectInRangeOfPlayer(objectid, playerid, Float:range);\n\nGetClosestObjectToPlayer(playerid);\n```\n\n### Object - Vehicle\n\n```pawn\nFloat:GetObjectDistanceToVehicle(objectid, vehicleid);\n\nbool:IsObjectInRangeOfVehicle(objectid, vehicleid, Float:range);\n\nGetClosestObjectToVehicle(vehicleid);\n\nFloat:GetVehicleDistanceToObject(vehicleid, objectid);\n\nbool:IsVehicleInRangeOfObject(vehicleid, objectid, Float:range);\n\nGetClosestVehicleToObject(objectid);\n```\n\n### DynObject - Player\n\n```pawn\nFloat:GetDynObjectDistanceToPlayer(STREAMER_TAG_OBJECT:objectid, playerid);\n\nbool:IsDynObjectInRangeOfPlayer(STREAMER_TAG_OBJECT:objectid, playerid, Float:range);\n\nSTREAMER_TAG_OBJECT:GetClosestDynObjectToPlayer(playerid);\n\nFloat:GetPlayerDistanceToDynObject(playerid, STREAMER_TAG_OBJECT:objectid);\n\nbool:IsPlayerInRangeOfDynObject(playerid, STREAMER_TAG_OBJECT:objectid, Float:range);\n\nGetClosestPlayerToDynObject(STREAMER_TAG_OBJECT:objectid);\n```\n\n### DynObject - Object\n\n```pawn\nFloat:GetDynObjectDistanceToObject(STREAMER_TAG_OBJECT:objectid, targetid);\n\nbool:IsDynObjectInRangeOfObject(STREAMER_TAG_OBJECT:objectid, targetid, Float:range);\n\nSTREAMER_TAG_OBJECT:GetClosestDynObjectToObject(objectid);\n\nFloat:GetObjectDistanceToDynObject(objectid, STREAMER_TAG_OBJECT:targetid);\n\nbool:IsObjectInRangeOfDynObject(objectid, STREAMER_TAG_OBJECT:targetid, Float:range);\n\nGetClosestObjectToDynObject(STREAMER_TAG_OBJECT:objectid);\n```\n\n### DynObject - Vehicle\n\n```pawn\nFloat:GetDynObjectDistanceToVehicle(STREAMER_TAG_OBJECT:objectid, vehicleid);\n\nbool:IsDynObjectInRangeOfVehicle(STREAMER_TAG_OBJECT:objectid, vehicleid, Float:range);\n\nSTREAMER_TAG_OBJECT:GetClosestDynObjectToVehicle(vehicleid);\n\nFloat:GetVehicleDistanceToDynObject(vehicleid, STREAMER_TAG_OBJECT:objectid);\n\nbool:IsVehicleInRangeOfDynObject(vehicleid, STREAMER_TAG_OBJECT:objectid, Float:range);\n\nGetClosestVehicleToDynObject(STREAMER_TAG_OBJECT:objectid);\n```\n\n### Actor - Point\n\n```pawn\nFloat:GetActorDistanceToPoint2D(actorid, Float:x, Float:y);\n\nbool:IsActorInRangeOfPoint2D(actorid, Float:range, Float:x, Float:y);\n\nFloat:GetActorDistanceToPoint3D(actorid, Float:x, Float:y, Float:z);\n\nbool:IsActorInRangeOfPoint3D(actorid, Float:range, Float:x, Float:y, Float:z);\n```\n\n### Actor - Actor\n\n```pawn\nFloat:GetActorDistanceToActor(actorid, targetid);\n\nbool:IsActorInRangeOfActor(actorid, targetid, Float:range, bool:ignoreVW = false);\n\nGetClosestActorToActor(actorid, bool:ignoreVW = false);\n```\n\n### Player - Actor\n\n```pawn\nFloat:GetActorDistanceToPlayer(actorid, playerid);\n\nbool:IsActorInRangeOfPlayer(actorid, playerid, Float:range, bool:ignoreVW = false);\n\nGetClosestActorToPlayer(playerid, bool:ignoreVW = false);\n\nFloat:GetPlayerDistanceToActor(playerid, actorid);\n\nbool:IsPlayerInRangeOfActor(playerid, actorid, Float:range, bool:ignoreVW = false);\n\nGetClosestPlayerToActor(actorid, bool:ignoreVW = false);\n```\n\n### Object - Actor\n\n```pawn\nFloat:GetObjectDistanceToActor(objectid, actorid);\n\nbool:IsObjectInRangeOfActor(objectid, actorid, Float:range);\n\nGetClosestObjectToActor(actorid);\n\nFloat:GetActorDistanceToObject(actorid, objectid);\n\nbool:IsActorInRangeOfObject(actorid, objectid, Float:range);\n\nGetClosestActorToObject(objectid);\n```\n\n### Actor - Vehicle\n\n```pawn\nFloat:GetActorDistanceToVehicle(vehicleid, targetid);\n\nbool:IsActorInRangeOfVehicle(vehicleid, targetid, Float:range);\n\nGetClosestActorToVehicle(vehicleid);\n\nFloat:GetVehicleDistanceToActor(vehicleid, targetid);\n\nbool:IsVehicleInRangeOfActor(vehicleid, targetid, Float:range);\n\nGetClosestVehicleToActor(vehicleid);\n```\n\n### DynObject - Actor\n\n```pawn\nFloat:GetDynObjectDistanceToActor(STREAMER_TAG_OBJECT:objectid, actorid);\n\nbool:IsDynObjectInRangeOfActor(STREAMER_TAG_OBJECT:objectid, actorid, Float:range);\n\nSTREAMER_TAG_OBJECT:GetClosestDynObjectToActor(actorid);\n\nFloat:GetActorDistanceToDynObject(actorid, STREAMER_TAG_OBJECT:objectid);\n\nbool:IsActorInRangeOfDynObject(actorid, STREAMER_TAG_OBJECT:objectid, Float:range);\n\nGetClosestActorToDynObject(STREAMER_TAG_OBJECT:objectid);\n```\n\n\n**Note:** The functions with an asterisk (*) next to them only support the `ignoreInterior` argument if the `GetVehicleInterior` function is available (added by YSF, some other library or by a new SA-MP version (yeah, right)). \n\n\n## Examples\n\n```pawn\nCMD:pay(playerid, params[])\n{\n\tnew playerid2, amount;\n\n\tif (sscanf(params, \"ui\", playerid2, amount))\n\t{\n\t\treturn SendClientMessage(playerid, COLOR_WHITE, \"USAGE: /pay \u003cPlayer name/ID\u003e \u003cAmount\u003e\");\n\t}\n\n\tif (!IsPlayerInRangeOfPlayer(playerid, playerid2, 5.0))\n\t{\n\t\t// fails if the other player is not connected or not near enough to the player\n\t\treturn SendClientMessage(playerid, COLOR_RED, \"The specified player is not near you!\");\n\t}\n\n\tGivePlayerMoney(playerid, -amount);\n\tGivePlayerMoney(playerid2, amount);\n\treturn 1;\n}\n```\n\n```pawn\nCMD:fixtires(playerid)\n{\n\tnew vehicleid = GetClosestVehicleToPlayer(playerid);\n\n\tif (!IsPlayerInRangeOfVehicle(playerid, vehicleid, 10.0))\n\t{\n\t\t// fails if no vehicle was found in the same interior and virtual world as the player or the closest one is not near enough to the player\n\t\treturn SendClientMessage(playerid, COLOR_RED, \"You are not near any vehicle!\");\n\t}\n\n\tnew panels, doors, lights, tires;\n\tGetVehicleDamageStatus(vehicleid, panels, doors, lights, tires);\n\tSetVehicleDamageStatus(vehicleid, panels, doors, lights, 0);\n\treturn 1;\n}\n```\n\n\n## Testing\n\nThe library is not fully tested as of now because there is no fully working version of `ut_mock_player`/`y_mock` right now (I will be working on one soon). Right now, the tests only check whether the library compiles and the functions in the `Point-Point` section return the correct values. To test, simply run the package:\n\n```bash\nsampctl package run\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fy-less%2Fsamp-distance","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fy-less%2Fsamp-distance","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fy-less%2Fsamp-distance/lists"}