[Include] Attached Object Ex - Temporary Attached Objects, Sniper Zoom fix, and more
#1

AOX
Introduction

Attached Object Ex is an extension of the player attached object functions that allows you to retrieve and set data for player attached objects, and even move them like the MoveObject function. It introduces Temporary Attached objects, which allows you to attach objects for a certain amount of time without having to keep track of indexes*. It also contains fixes for a few annoyances such as attached objects covering your view when zooming with a Sniper and attached objects remaining attached upon timing out and reconnecting.


Download

http://pastebin.com/WmfPGSCn

Include this before any other include that uses the functions SetPlayerAttachedObject or RemovePlayerAttachedObject


Temporary Attached Objects

This include introduces Temporary Attached Objects, which are attached objects designed to be automatically removed after a certain time. An example usage of this would be attaching particle objects that disappear after a few seconds.

Usage
pawn Code:
SetPlayerTempAttachedObject(playerid, time, modelid, boneid, Float:fOffsetX, Float:fOffsetY, Float:fOffsetZ, Float:fRotX, Float:fRotY, Float:fRotZ, Float:fScaleX, Float:fScaleY, Float:fScaleZ, materialcolor1, materialcolor2);
Like SetPlayerAttachedObject, the parameters fOffsetX and beyond are optional. The only difference here is that the "index" parameter is replaced with "time", which is the amount of time in milliseconds before the attached object is removed. You no longer have to worry about replacing an attached object in the same index, except when all indexes are used, which in that case the oldest temp attached object is replaced. If you want the temp attached object to last forever (or until it gets replaced by another temp attached object or manually removed), specify -1 for time.

There is also one callback.

Callbacks
pawn Code:
forward OnTempAttachedObjectDestroy(playerid, index);
This callback is called right before a temporary attached object is removed. It also handles returns. Returning 1 will remove the temporary attached object as normal. By returning 0, the destruction will be cancelled and the temporary attached object will be set to be destroyed again in the amount of time you specified for it earlier. You can also retrieve data of the attached object in this callback using the functions below.

Data Functions
pawn Code:
// Returns the unique per-player-slot ID of the attached object (not the model ID)
GetPlayerAttachedObjectID(playerid, index);

// Returns the Bone ID of the attached object
GetPlayerAttachedObjectBone(playerid, index);

// Returns the Model ID of the attached object
GetPlayerAttachedObjectModel(playerid, index);

// Stores the offset values of the attached object, passed by reference
GetPlayerAttachedObjectOffset(playerid, index, &Float:fOffsetX, &Float:fOffsetY, &Float:fOffsetZ);

// Stores the rotation values of the attached object, passed by reference
GetPlayerAttachedObjectRot(playerid, index, &Float:fRotX, &Float:fRotY, &Float:fRotZ);

// Stores the scale values of the attached object, passed by reference
GetPlayerAttachedObjectScale(playerid, index, &Float:fScaleX, &Float:fScaleY, &Float:fScaleZ);

// Stores the material color values of the attached object, passed by reference
GetPlayerAttachedObjectColor(playerid, index, &materialcolor1, &materialcolor2);
Note that all these functions work for normal attached objects as well.

To manually remove a temporary attached object, you can use the normal RemovePlayerAttachedObject function. However if you want the removal to also call OnTempAttachedObjectDestroy, you can use:
pawn Code:
// "aoid" is not optional and must always be -1
RemovePlayerTempAttachedObject(playerid, index, aoid);
The "aoid" parameter is not optional. It's important that you always specify "aoid" as -1, otherwise the removal won't be successful. This check is in place to avoid conflicts with timers involving temp attached objects in the same index.

Other Functions
pawn Code:
// Returns true if the attached object in the index is a temporary attached object
IsPlayerAttachedObjectTemp(playerid, index);

// Returns the first open attached object index for a player (works for normal attached objects too)
GetFreePlayerAttachedObjectSlot(playerid);

// Returns the number of temporary attached objects a player has
GetTempAttachedObjectCount(playerid);

// Returns the total number of attached objects a player has (normal and temporary)
GetAttachedObjectCount(playerid);

// Returns the index of the oldest temporary attached object
GetOldestTempAttachedObject(playerid);

// Returns the index of the most recently added temporary attached object
GetNewestTempAttachedObject(playerid);

// Set the bone ID of the attached object
SetPlayerAttachedObjectBone(playerid, index, bone);

// Set the model ID of the attached object
SetPlayerAttachedObjectModel(playerid, index, modelid);

// Set the offset coordinates of the attached object (won't work for attached objects that are currently moving)
SetPlayerAttachedObjectOffset(playerid, index, Float:fOffsetX, Float:fOffsetY, Float:fOffsetZ);

// Set the rotation of the attached object (won't work for attached objects that are currently moving)
SetPlayerAttachedObjectRot(playerid, index, Float:fRotX, Float:fRotY, Float:fRotZ);

// Set the scale of the attached object
SetPlayerAttachedObjectScale(playerid, index, Float:fScaleX, Float:fScaleY, Float:fScaleZ);

// Set the material color of the attached object
SetPlayerAttachedObjectColor(playerid, index, materialcolor1, materialcolor2);

Moving Attached Objects

Much like moving objects, you are now able to move player attached objects! It works for both player attached objects and temporary attached objects. Simply use the function below.

Usage
pawn Code:
MovePlayerAttachedObject(playerid, index, Float:OffsetX, Float:OffsetY, Float:OffsetZ, Float:Speed);
As you can see, the parameters are very similar to those of MoveObject. The OffsetX, OffsetY, and OffsetZ values are the final coordinates the attached object will end up at after it's finished moving. "Speed" is the speed at which the attached object moves, and will take the absolute value of the float specified. There's no rotation parameters for rotating objects yet, though I may add them in a future update. There is also a callback and several functions for moving attached objects.

Callback
pawn Code:
// Called when the attached object stops moving. Does not handle returns.
OnPlayerAttachedObjectMoved(playerid, index);
Functions
pawn Code:
// Returns true if the attached object is currently moving
IsPlayerAttachedObjectMoving(playerid, index);

// Gets the tick rate for moving attached objects
AOX_GetTickRate();

// Sets the tick rate for moving attached objects
AOX_SetTickRate(tickrate);
Now you may be wondering what the tick rate functions are for. The tick rate here is the interval (in milliseconds) between timer calls for recreating player attached objects at their new offsets. This creates the illusion of a moving attached object, albeit a very convincing one. As you can imagine, this movement would not be ideal for particle/animated objects.

The default tick rate is 15. For smoother movement but possibly worse server performance, set the tick rate lower. For more choppy movement but possibly better server performance, set the tick rate higher. Although I haven't tested this yet, different tick rates may affect the speed of the moving attached object.

There are several things that can interrupt a moving attached object. These include removing the attached object manually, having it removed automatically if it's a temporary attached object, aiming a sniper with the weapon zoom fix, and replacing it with a completely new attached object. These limited conditions mean that you can do some pretty interesting things with a moving attached object, like change its model ID or scale values while it's moving.


Weapon Zoom Fix

If you've played on a server with attached objects, you may have noticed how when aiming with a Sniper, the objects sometimes obstruct your view. With this include, aiming with a Sniper, Rocket Launcher, Heat Seeker, or Camera will now remove temporary attached objects and restore them after you stop aiming. It will be noticeable by all players when your attached objects are removed. This feature is optional, and if you want you can disable it entirely with this function:

pawn Code:
// Toggles the Weapon Zoom Fix on or off (1 or 0)
ToggleRemoveAOWeaponZoom(playerid, toggle);

// Example Usage
public OnPlayerConnect(playerid)
{
    // Disable upon player connect
    ToggleRemoveAOWeaponZoom(playerid, 0);
    return 1;
}
Note that by default normal attached objects aren't removed when aiming with the aforementioned weapons. To enable the Weapon Zoom Fix for normal attached objects use this function:
pawn Code:
// Toggles the Weapon Zoom Fix for normal attached objects on or off (1 or 0)
ToggleRemoveNormAOWeaponZoom(playerid, toggle);

// Example Usage
public OnPlayerConnect(playerid)
{
    ToggleRemoveNormAOWeaponZoom(playerid, 1);
    return 1;
}
Video
http://www.youtube.com/watch?v=OEoGg...ature=youtu.be
Here's an example video showing how the Weapon Zoom Fix works.


Notes
  • * If all attached object slots are filled, the oldest temporary attached object will be replaced. If all attached object slots are filled by normal attached objects, the temporary attached object won't be added.
  • Temporary Attached Objects are compatible with normal attached objects, and you can have both of them attached to you at the same time without conflicts.
  • Specifying -1 for the "time" parameter of SetPlayerTempAttachedObject will make the temporary attached object never expire
  • Timing out and reconnecting will no longer keep the attached objects and now destroys them upon connecting.
  • The default tick rate for moving player attached objects is 15.
Reply
#2

This is awesome ! Good job and + Rep for you man! This include will come in use
Reply
#3

+rep, good
Reply
#4

Quote:
Originally Posted by ******
View Post
There is already a sniper zoom fix here: https://sampforum.blast.hk/showthread.php?tid=292813
Unless I'm not seeing it, the sniper zoom fix for attached objects doesn't appear to be in the fixes.inc file. I searched around and found it at this post: http://forum.sa-mp.com/showthread.ph...2813&p=2238967

I don't think it's a good idea to use OnPlayerUpdate to check for aiming when you can detect it using key presses and a timer. Also that fix won't work properly with temporary attached objects. For example while aiming and you have your temp objects expire, the attached objects will be reattached after you stop aiming when they're not supposed to.


Thanks for everyone's feedback so far.
Reply
#5

UPDATE

You can now move player attached objects with a set speed:
pawn Code:
MovePlayerAttachedObject(playerid, index, Float:OffsetX, Float:OffsetY, Float:OffsetZ, Float:Speed);
In addition there are new functions related to moving attached objects
pawn Code:
// Returns true if the attached object is currently moving
IsPlayerAttachedObjectMoving(playerid, index);

// Gets the tick rate for moving attached objects
AOX_GetTickRate();

// Sets the tick rate for moving attached objects
AOX_SetTickRate(tickrate);

Unique attached object IDs are now assigned for all attached objects, not just temporary attached objects.
As a result, GetPlayerTempAttachedObjectID(playerid, index) has been replaced with GetPlayerAttachedObjectID(playerid, index).


Added new attached object altering functions
pawn Code:
// Set the bone ID of the attached object
SetPlayerAttachedObjectBone(playerid, index, bone);

// Set the model ID of the attached object
SetPlayerAttachedObjectModel(playerid, index, modelid);

// Set the offset coordinates of the attached object (won't work for attached objects that are currently moving)
SetPlayerAttachedObjectOffset(playerid, index, Float:fOffsetX, Float:fOffsetY, Float:fOffsetZ);

// Set the rotation of the attached object (won't work for attached objects that are currently moving)
SetPlayerAttachedObjectRot(playerid, index, Float:fRotX, Float:fRotY, Float:fRotZ);

// Set the scale of the attached object
SetPlayerAttachedObjectScale(playerid, index, Float:fScaleX, Float:fScaleY, Float:fScaleZ);

// Set the material color of the attached object
SetPlayerAttachedObjectColor(playerid, index, materialcolor1, materialcolor2);

Check the first post for more details.
Reply
#6

A couple of things for you.

1.) Why bother resetting everything when a player connects this makes no sense and is a waste of code also OnPlayerKeyStateChange and _AOX_RemovePlayerAttachedObject does this as well.
2.) Instead of setting a timer to check weapon zoom why not just use OnPlayerKeyStateChange() it will be smoother. (May need some additional code for death checking)

The rest looks acceptable these were the things that stood out with this include, now would I use this? Only if I was starting an attached object script from scratch it could save quite a bit of work with that kind of system. Good work at any rate.
Reply
#7

1a. The reset under OnPlayerConnect is for the issue when you timeout and rejoin and still have attached objects on you. This has been confirmed as a bug as far as I know.

1b. The reset under OnPlayerKeyState change was done when I noticed after dying and having my attached objects removed, aiming with a sniper would bring those attached objects back. Though I admit this was not the proper way to do it and should be done upon the player dying.

2. Setting a timer for me was much simpler at the time, as I didn't have to check for scenarios where the player would no longer be aiming and didn't release KEY_AIM and possibly miss something, like getting hit by an interrupting explosion as seen in the video or dying as you said. You're right that that would be smoother. I'll get to work on this once I'm sure I have all the cases down.

Thanks for the feedback, helps a lot.
Reply
#8

What I am saying is you don't have to reset everything such as position/rotation/scale I should have been a little more clear on that point. Thanks for taking my feedback into consideration the small things go a long way when you add them all up.
Reply
#9

If this smoothly moves playerattached objects, I'd very much like to see the same thing for vehicle-attached objects
Reply
#10

That sniper zoom fix doesn't work... :/
Reply
#11

Instead of a certain function to edit attached object info, you can make one function with all editing part included.
For example:
pawn Код:
EditAttachedObject(playerid, index, type, {Float, _}...);
@amirm3hdi: Here is my old attachments include (maybe someone find it useful): See the description in Repo for features: https://github.com/Gammix/Attachments-Include
Reply
#12

man when i use this my stunt objects like ramp etx get removed why??
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)