//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);
/*
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
/*
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)
/*
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)
/*
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)
#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;
}
#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;
}
}
#define ARROW_NO_STREAMER
#include <arrow>
<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.
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;
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.
|
Originally Posted by Kar
Here you go...
|
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.
|
if(arrowid < 0 || arrowid >= MAX_ARROWS)
{
printf("Error: Arrows.Inc::FunctionName()::OOB arrowid reference Arrowid: %i", arrowid);
return INVALID_ARROW_ID;
}
Or if you want it a bit cleaner
#define OOBCheck(%0,%1); if(%0 < 0 || %0 >= MAX_ARROWS) { \
printf("Error: Arrows.Inc::%s Arrowid: %i", %1, %0); \
return INVALID_ARROW_ID; }
becomes
OOBCheck(arrowid, "Error: Arrows.Inc::FunctionName()::OOB arrowid reference");
// x,y,z arrow position; ax,ay,az, target position
stock Float:GetYRotation(Float:x,Float:y,Float:z, Float:ax, Float:ay, Float:az)
{
new Float:Yoff;
new Float:xd = ax - x;
new Float:yd = ay - y;
new Float:zd = az - z;
new Float:dist = floatsqroot(xd*xd+yd*yd+zd*zd);
Yoff = acos((az-z)/dist);
return Yoff-180;
}
stock Float:GetYRotation(Float:x,Float:y,Float:z, Float:ax, Float:ay, Float:az)
{
new Float:xd = ax - x;
new Float:yd = ay - y;
new Float:dist = floatsqroot(xd*xd+yd*yd);
new Float:Yoff = atan((z-az)/dist);
return Yoff-90;
}
arw:CreateArrow(...)
CreateArrow(Float: x, Float: y, Float: z, Float: target_x, Float: target_y, Float: target_z, Float: stream_dist = DEFAULT_ARROW_DRAW_DISTANCE);
PointArrowAtPoint(arrowid, Float: x, Float: y, Float: z);
native 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, arrowid, Float: x, Float: y, Float: z);
native DestroyPlayerArrow(playerid, arrowid);
native SetPlayerArrowPos(playerid, arrowid, Float: x, Float: y, Float: z);
native GetPlayerArrowPos(playerid, arrowid, &Float: x, &Float: y, &Float: z);
native GetPlayerArrowRot(playerid, arrowid, &Float: rx, &Float: ry, &Float: rz);
native PointPlayerArrowAtPlayer(playerid, arrowid, playerid);
native PointPlayerArrowAtVehicle(playerid, arrowid, vehicleid);
native PointPlayerArrowAtObject(playerid, arrowid, objectid);
native PointPlayerArrowAtPlayerObject(playerid, arrowid, targetplayerid, targetobjectid);
native SetPlayerArrowColor(playerid, arrowid, argb_color);
#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;
}
//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);//new func in 1.3
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);//new func in 1.3
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);