[Include] Arrow.inc Create And Point Arrows At Stuff
#1

arrow.inc


Description
This include allows you to create arrows (white arrow modelid: 1318) and easily point them at things. This could be very useful for GPS systems among other things.

Functions

pawn Код:
//global arrows
native Arrow:CreateArrow(Float: x, Float: y, Float: z, Float: target_x, Float: target_y, Float: target_z, Float: stream_dist = DEFAULT_ARROW_DRAW_DISTANCE);
native PointArrowAtPoint(Arrow:arrowid, Float: x, Float: y, Float: z);
native DestroyArrow(Arrow:arrowid);
native SetArrowPos(Arrow:arrowid, Float: x, Float: y, Float: z);
native GetArrowPos(Arrow:arrowid, &Float: x, &Float: y, &Float: z);
native GetArrowRot(Arrow:arrowid, &Float: rx, &Float: ry, &Float: rz);
native SetArrowRot(Arrow:arrowid, Float: rx, Float: ry, Float: rz);
native PointArrowAtPlayer(Arrow:arrowid, playerid);
native PointArrowAtVehicle(Arrow:arrowid, vehicleid);
native PointArrowAtObject(Arrow:arrowid, objectid);
native SetArrowColor(Arrow:arrowid, argb_color);
//player arrows
native Arrow:CreatePlayerArrow(playerid, Float: x, Float: y, Float: z, Float: target_x, Float: target_y, Float: target_z, Float: stream_dist = DEFAULT_ARROW_DRAW_DISTANCE);
native PointPlayerArrowAtPoint(playerid, Arrow:arrowid, Float: x, Float: y, Float: z);
native DestroyPlayerArrow(playerid, Arrow:arrowid);
native SetPlayerArrowPos(playerid, Arrow:arrowid, Float: x, Float: y, Float: z);
native GetPlayerArrowPos(playerid, Arrow:arrowid, &Float: x, &Float: y, &Float: z);
native GetPlayerArrowRot(playerid, Arrow:arrowid, &Float: rx, &Float: ry, &Float: rz);
native SetPlayerArrowRot(playerid, Arrow:arrowid, Float: rx, Float: ry, Float: rz);
native PointPlayerArrowAtPlayer(playerid, Arrow:arrowid, playerid);
native PointPlayerArrowAtVehicle(playerid, Arrow:arrowid, vehicleid);
native PointPlayerArrowAtObject(playerid, Arrow:arrowid, objectid);
native PointPlayerArrowAtPlayerObject(playerid, Arrow:arrowid, targetplayerid, targetobjectid);
native SetPlayerArrowColor(playerid, Arrow:arrowid, argb_color);
Most of those functions are very self explanatory, but here are a few explained.

CreateArrow
pawn Код:
/*
    Function:
        CreateArrow
    Description:
        Creates an arrow at the given point, pointing to a target location.
    Param(s):
        x, y, z      - Position to create the arrow.
        target_x/y/z - Position to point the arrow at
        stream_dist  - stream distance for the arrow (default DEFAULT_ARROW_DRAW_DISTANCE)
    Returns:
        Arrowid for the newly created arrow. (returned by CreateObject or CreateDynamicObject

*/

stock Arrow:CreateArrow(Float: x, Float: y, Float: z, Float: target_x, Float: target_y, Float: target_z, Float: stream_dist = DEFAULT_ARROW_DRAW_DISTANCE
PointArrowAtPoint
pawn Код:
/*
    Function:
        PointArrowAtPoint
    Description:
        Points the given arrow at the given point
    Param(s):
        arrowid  - The arrowid returned by "CreateArrow" function.
        x, y, z  - The point, to point the arrow at
    Returns:
        This function does not return a value

*/

stock PointArrowAtPoint(Arrow:arrowid, Float: x, Float: y, Float: z)
DestroyArrow
pawn Код:
/*
    Function:
        DestroyArrow
    Description:
        Destroys the given arrow.
    Param(s):
        arrowid - The arrowid returned by "CreateArrow" function
    Returns:
        Value returned by DestroyObject or DestroyDynamicObject

*/

stock DestroyArrow(Arrow:arrowid)
SetArrowPos
pawn Код:
/*
    Function:
        SetArrowPos
    Description:
        Sets a new position for the given arrow.
    Param(s):
        arrowid - The arrowid returned by "CreateArrow" function.
        x, y, z - The new position for the arrow to be placed.
    Returns:
        Value returned by SetObjectPos or SetDynamicObjectPos

*/

stock SetArrowPos(Arrow:arrowid, Float: x, Float: y, Float: z)
Basic Usage

A simple command to create a player arrow and point it at a player, This command deletes the arrow when used a second time.
pawn Код:
#include <arrow>
#include <zcmd>

new Arrow:gArrows[MAX_PLAYERS];//arrow ids now have the Arrow: tag.
new bool:gPlayerHasArrow[MAX_PLAYERS];

COMMAND:arrow(playerid, params[])
{
    if( !gPlayerHasArrow[ playerid ] )
    {
        new
            targetplayerid = strval(params),
            Float: x, Float: y, Float: z
        ;
       
        GetPlayerPos(playerid, x, y, z);
       
        //create a player arrow at playerids location pointing to 0.0, 0.0, 0.0
        gArrows[playerid] = CreatePlayerArrow(playerid, x, y, z, 0.0, 0.0, 0.0);//assign arrowid to var
       
        //NOTE: colours are in ARGB format
        SetArrowColor( gArrows[playerid], 0xAAFF0000 );//set arrow color to red
       
        //point the arrow at a target player
        PointPlayerArrowAtPlayer( playerid, gArrows[playerid], targetplayerid );
        gPlayerHasArrow[ playerid ] = true;
    }
    else
    {
        DestroyPlayerArrow( playerid, gArrows[playerid] );
        gPlayerHasArrow[ playerid ] = false;
    }
    return 1;
}
Basic Usage 2
A small script i wrote fast that adds a /locate <playername/id> command. This creates an arrow above the players head that points at a player.
pawn Код:
#define FILTERSCRIPT

#include <a_samp>
#include <zcmd>//Credit Zeex
#include <sscanf2>//credit ******
#include <arrow>

#define ARROW_UPDATE_TIME           (50) //how often locator arrows position updates (ms)

enum E_PLAYER_DATA
{
    Arrow: e_LOCATOR_ARROW,
   
    bool: e_IS_LOCATING,
   
    e_LOCATOR_TIMER_ID,
    e_LOCATOR_TARGETID,
}

new gPlayerData[ MAX_PLAYERS ][ E_PLAYER_DATA ];


//simple timer function to update the arrows position and point it to target
forward public OnArrowUpdate(playerid);    

public OnFilterScriptInit()
{
    print("\n--------------------------------------");
    print(" arrow.inc example");
    print("--------------------------------------\n");
   
    for( new i=0; i < MAX_PLAYERS; ++i )
    {
        gPlayerData[ i ][ e_LOCATOR_TIMER_ID ] = -1;
        gPlayerData[i][e_LOCATOR_ARROW] = INVALID_ARROW_ID;
        gPlayerData[i][ e_IS_LOCATING ] = false;
        gPlayerData[ i ][ e_LOCATOR_TARGETID ] = INVALID_PLAYER_ID;
    }
    return 1;
}

public OnFilterScriptExit()
{
    //clean up arrows
    for( new i=0; i < MAX_PLAYERS; ++i )
    {
        KillArrowTimer( i );
    }
    return 1;
}

public OnPlayerDisconnect(playerid, reason)
{
    KillArrowTimer( playerid );
    return 1;
}

COMMAND:locate(playerid, params[])
{
    if( !gPlayerData[ playerid ][ e_IS_LOCATING ] )
    {
        new
            iTargetID = INVALID_PLAYER_ID
        ;
       
        if( sscanf(params, "u", iTargetID ) )
        {
            SendClientMessage(playerid, -1, "<Syntax Error>: Usage /locate <username/id>");
            return 1;
        }
        else
        {
            if( iTargetID != INVALID_PLAYER_ID )
            {
                //now target is online, so get both players position
                //set variables, create arrow and start timer.
           
                new
                    Float: ax, Float: ay, Float: az,//arrow position
                    Float: tx, Float: ty, Float: tz//target position
                ;
               
                GetPlayerPos(playerid, ax, ay, az);
                GetPlayerPos(iTargetID, tx, ty, tz);
               
                gPlayerData[ playerid ][ e_LOCATOR_TARGETID ] = iTargetID;
               
                gPlayerData[ playerid ][ e_IS_LOCATING ] = true;
               
                //create and assign the arrow, pointint to target player
                gPlayerData[ playerid ][ e_LOCATOR_ARROW ] = CreatePlayerArrow(playerid, ax, ay, az+1.2, tx, ty, tz);
               
                gPlayerData[ playerid ][ e_LOCATOR_TIMER_ID ] = SetTimerEx("OnArrowUpdate", ARROW_UPDATE_TIME, true, "d", playerid);
            }
        }
    }
    else
    {
        //player already locating, so stop this one.
        KillArrowTimer( playerid );
        SendClientMessage(playerid, -1, "<Player Locator>: Finished locating target.");
    }
    return 1;
}

public OnArrowUpdate(playerid)
{
    static
        Float: _s_px = 0.0, Float: _s_py = 0.0, Float: _s_pz = 0.0
    ;
   
    if( !IsPlayerConnected( gPlayerData[ playerid ][ e_LOCATOR_TARGETID ] ) )
    {
        KillArrowTimer( playerid );
        SendClientMessage(playerid, -1, "<Player Locator>: Finished locating target. (target disconnected)");
        return 1;
    }
   
    if( GetPlayerPos( playerid, _s_px, _s_py, _s_pz ) )
    {
        //both player connected, set pos and rotation of arrow..
        SetPlayerArrowPos( playerid, gPlayerData[ playerid ][ e_LOCATOR_ARROW ], _s_px, _s_py, _s_pz+1.2 );//1.2 == slightly avove ped head
        PointPlayerArrowAtPlayer( playerid, gPlayerData[ playerid ][ e_LOCATOR_ARROW ], gPlayerData[ playerid ][ e_LOCATOR_TARGETID ] );
    }
    else
    {
        //make sure timer dies if player isn't connected
        KillArrowTimer( playerid );
    }
    return 1;
}

stock KillArrowTimer( playerid )
{
    if( gPlayerData[ playerid][ e_LOCATOR_TIMER_ID ] != -1 )
    {
        KillTimer(gPlayerData[ playerid ][ e_LOCATOR_TIMER_ID ]);
        gPlayerData[ playerid][ e_LOCATOR_TIMER_ID ] = -1;
        DestroyPlayerArrow(playerid, gPlayerData[ playerid ][ e_LOCATOR_ARROW ]);
        gPlayerData[playerid][e_LOCATOR_ARROW] = INVALID_ARROW_ID;
        gPlayerData[playerid][ e_IS_LOCATING ] = false;
        gPlayerData[ playerid ][ e_LOCATOR_TARGETID ] = INVALID_PLAYER_ID;
    }
}
Streamer config
Because the streamer plugin is very popular and allows you to create more objects, this include uses it by default. If you don't use the streamer plugin, please make the following definition BEFORE including arrow.inc.

EG:
pawn Код:
#define ARROW_NO_STREAMER
#include <arrow>
NOTES
  • All arrowids now have the Arrow: tag.
  • When setting an arrows colour please use the ARGB format, not RGBA like SendClientMessage.
  • PointArrowAtPoint is an expensive function, as there is a lot of floating point arithmetic, so do speed tests on your system before calling it for example in OnPlayerUpdate every update (not a good idea).
Changelog:
Код:
<27/07/13 v1.3>	
	* Values returned by CreateArrow now have the Arrow: tag, to avoid confusion with normal objectids.
	* All function headers expecting an arrowid have changed to accept the new Arrow: tag.
	* Added functions:
		SetArrowRot
		SetPlayerArrowRot
		
	* Fixed more comment errors.
		
24/07/13 v1.2:
	*Player arrows added.
	* Added functions:
		CreatePlayerArrow
		PointPlayerArrowAtPoint
		DestroyPlayerArrow
		SetPlayerArrowPos
		GetPlayerArrowPos
		GetPlayerArrowRot
		PointPlayerArrowAtPlayer
		PointPlayerArrowAtVehicle
		PointPlayerArrowAtObject
		PointPlayerArrowAtPlayerObject
		SetPlayerArrowColor
		
	*Functions changed
		PointArrowAtPoint   - No loner does rotation calculations if the arrow isn't a valid object. And returns 0 on failure.
	
	*Fixed some comment errors.
		
23/07/13 v1.1:
	*Arrows now rotate along the Y-Axis, so they an point vertically. (Antonio144)
22/07/13 v1.0:
	*Initial release.
Credits
Incoginto - Streamer plugin
Antonio144 - GetYRotation function
Sa:mp Team - Sa:mp

Download
Pastebin
Solidfiles
Dropbox

[ame]www.youtube.com/watch?v=Bj5uTvZu2_A[/ame]
Reply


Messages In This Thread

Forum Jump:


Users browsing this thread: 1 Guest(s)