SA-MP Forums

Go Back   SA-MP Forums > SA-MP Scripting and Plugins > Filterscripts > Includes

Reply
 
Thread Tools Display Modes
Old 22/07/2013, 10:33 PM   #1
iggy1
High-roller
 
iggy1's Avatar
 
Join Date: Mar 2009
Location: One past the end.
Posts: 2,421
Reputation: 271
Default Arrow.inc Create And Point Arrows At Stuff

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 Code:
//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 Code:
/*
    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 Code:
/*
    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 Code:
/*
    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 Code:
/*
    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 Code:
#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 Code:
#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 Code:
#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:
Code:
<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]
Attached Images
File Type: jpg sa-mp-001.jpg (195.6 KB, 442 views)
File Type: jpg sa-mp-002.jpg (195.3 KB, 359 views)

Last edited by iggy1; 27/07/2013 at 09:14 AM.
iggy1 is offline   Reply With Quote
Old 22/07/2013, 10:35 PM   #2
Kyle
High-roller
 
Join Date: Mar 2009
Location: United Kingdom
Posts: 2,277
Reputation: 330
Default Re: Arrow.inc Create And Point Arrows At Stuff

Screenshots please?
Kyle is offline   Reply With Quote
Old 22/07/2013, 10:41 PM   #3
Kar
Banned
 
Join Date: May 2010
Location: Black Asylum
Posts: 2,992
Reputation: 538
Default Re: Arrow.inc Create And Point Arrows At Stuff

What about attaching? You'll need some extra rotation patches if you add that through, otherwise this is simple and nice, especially for beginners ^ who have problems with points
Kar is offline   Reply With Quote
Old 22/07/2013, 10:56 PM   #4
iggy1
High-roller
 
iggy1's Avatar
 
Join Date: Mar 2009
Location: One past the end.
Posts: 2,421
Reputation: 271
Default Re: Arrow.inc Create And Point Arrows At Stuff

I did a system for attaching but it meant constantly updating the arrows position above the players head (or other offset) constantly. That was quite inefficient, so i thought i'd leave it to the end user. I couldn't get it working with AttachObject because rotating the object doesn't work.

If you have any ideas how to get it to attach to the player and still be able to point it at things, please let me know. (if it's not what i describe above)
iggy1 is offline   Reply With Quote
Old 23/07/2013, 01:35 AM   #5
ToiletDuck
Huge Clucker
 
ToiletDuck's Avatar
 
Join Date: Apr 2012
Location: Philippines, Lucena City
Posts: 398
Reputation: 43
Default Re: Arrow.inc Create And Point Arrows At Stuff

In creating this arrow is this Object? or something that checkpoint?
ToiletDuck is offline   Reply With Quote
Old 23/07/2013, 02:01 AM   #6
Pottus
High-roller
 
Pottus's Avatar
 
Join Date: Jun 2012
Posts: 4,851
Reputation: 1292
Default Re: Arrow.inc Create And Point Arrows At Stuff

You should use a variable to store the object id's and return the index the coding looks good but lacks checking when doing actions which could lead to the potential of modifying objects that are not even part of the system. That is what I would do to it so you have some fail safes in place when something goes wrong.

http://pastebin.com/ndL2hxWr

Last edited by Pottus; 23/07/2013 at 02:54 AM.
Pottus is offline   Reply With Quote
Old 23/07/2013, 02:02 AM   #7
Kar
Banned
 
Join Date: May 2010
Location: Black Asylum
Posts: 2,992
Reputation: 538
Default Re: Arrow.inc Create And Point Arrows At Stuff

here you go

pawn Code:
new Float:x, Float:y, Float:z;
GetVehiclePos(vehicleid, x, y, z);
GetVehicleZAngle(vehicleid, angle);
new Float:r_Z = atan2(y - DestY, x - DestX) - angle;

Credits to RyDeR`, he thought me about angles with some functions he gave me.
Kar is offline   Reply With Quote
Old 23/07/2013, 06:27 AM   #8
iggy1
High-roller
 
iggy1's Avatar
 
Join Date: Mar 2009
Location: One past the end.
Posts: 2,421
Reputation: 271
Default Re: Arrow.inc Create And Point Arrows At Stuff

Quote:
Originally Posted by [uL]Pottus View Post
You should use a variable to store the object id's and return the index the coding looks good but lacks checking when doing actions which could lead to the potential of modifying objects that are not even part of the system. That is what I would do to it so you have some fail safes in place when something goes wrong.
I didn't want to introduce limits, using variables would have to have "MAX_ARROWS" defined and i didn't want to do that. This include has a very small footprint (0 global variables), using variables to store info on 10000 (i know thats a lot but you never know) arrows would munch up lot's of space. It is up to the end user to use this correctly. It's very simple to use, and if people have trouble using the correct objectid.... they should give their head a wobble. I suggested GetObjectModelID in Suggestions for future SA:MP updates, for that reason. I do get where your coming from though.
Quote:
Originally Posted by Kar
Here you go...
Thanks pal, i have a very busy day today so i will test this out tonight. If it works accurately i will use that and give credit. Seems like that would be a lot faster than the method I'm using.

EDIT: @ToiletDuck please read the first sentence in the thread, and look at screenies.

Thanks all for your input.
iggy1 is offline   Reply With Quote
Old 23/07/2013, 03:36 PM   #9
Pottus
High-roller
 
Pottus's Avatar
 
Join Date: Jun 2012
Posts: 4,851
Reputation: 1292
Default Re: Arrow.inc Create And Point Arrows At Stuff

10,000 takes up an insignificant amount also you can't expect the user to use it correctly and when something does go wrong the absolute last thing you want is your system to be setting arbitrary actions on random objects the user will have no idea how it's happening. Less code does not mean it's better code any dynamic should index it's associated components always cutting corners like you did is bad practice.
Pottus is offline   Reply With Quote
Old 23/07/2013, 04:21 PM   #10
wups
High-roller
 
wups's Avatar
 
Join Date: Apr 2010
Posts: 1,217
Reputation: 141
Default Re: Arrow.inc Create And Point Arrows At Stuff

Why is there no target z?
wups is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
How to create a drift point thing. Gangster-rocks Scripting Help 7 22/05/2012 03:06 PM
An Arrow to a Point blackybecks Scripting Help 2 29/01/2012 01:37 AM
Pickup point, exit/enter point - Virtual worlds Chivava Help Archive 4 27/12/2010 02:55 PM
Random Point to Point Missions? External-Life Help Archive 7 08/08/2010 09:26 PM
Create a red point? krawN Help Archive 7 12/07/2009 06:45 PM


All times are GMT. The time now is 10:45 PM.


Powered by vBulletin® Version 3.8.6
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.