Attach Object To Vehicle ( I can pay for help : PM me )
#1

Ok guys i've been workin on this script for a while now. I just can't figure out how to attach my edited object on vehicle. So the script goes like this :

Defines
Код:
new Ctoyslot[MAX_PLAYERS];
	pCToyModel[3],
	Float:pCToyX[3],
	Float:pCToyY[3],
	Float:pCToyZ[3],
	Float:pCToyRX[3],
	Float:pCToyRY[3],
	Float:pCToyRZ[3],
 	Float:pCToySX[3],
    Float:pCToySY[3],
    Float:pCToySZ[3],
Код:
    for(new i=0; i<3; i++) // Toys
    {
    	PlayerInfo[playerid][pCToyModel][i] = 0;
        PlayerInfo[playerid][pCToyX][i] = 0;
		PlayerInfo[playerid][pCToyY][i] = 0;
		PlayerInfo[playerid][pCToyZ][i] = 0;
		PlayerInfo[playerid][pCToyRX][i] = 0;
		PlayerInfo[playerid][pCToyRY][i] = 0;
		PlayerInfo[playerid][pCToyRZ][i] = 0;
	 	PlayerInfo[playerid][pCToySX][i] = 0;
	    PlayerInfo[playerid][pCToySY][i] = 0;
	    PlayerInfo[playerid][pCToySZ][i] = 0;
You use /buycartoys , get a toy and it saves in your files.
Код:
CMD:buycartoys(playerid, params[])
{
 	new option, index, model, idx = GetPlayerVirtualWorld(playerid)-100, string[128];
	if(!IsPlayerLoggedIn(playerid) || PlayerInfo[playerid][pAsshole] == 1) return SendClientMessage(playerid, COLOR_GREY, "You are not allowed to use command.");
	if (IsPlayerInRangeOfPoint(playerid, 3.0, 1891.9252, -2328.7129, 13.5469)) return SendClientMessage(playerid, COLOR_GREY, "You are not inside a Garage.");
	if(sscanf(params, "ii", option, index))
	{
		ShowPlayerDialog(playerid, 9999, DIALOG_STYLE_MSGBOX, "USAGE: /buycartoys [Item Number] [Toy slot (0-3)]", "Surfboard = 1 | Snowplow = 2 | GM454 (Motor) = 3", "Close", "Close");
	    return 1;
	}
	if(index < 0 || index > 3) return SendClientMessage(playerid, COLOR_GREY, "Slots are between 0 and 3.");
	switch(option)
	{
	    case 1 : model = 2404; case 2 : model = 19601; case 3 : model = 19917;
	}
	if(PlayerInfo[playerid][pMoney] < 300) return SendClientMessage(playerid, COLOR_GREY, "You don't have enough money to do this.");
	PlayerInfo[playerid][pCToyModel][index] = model;	GiveDodMoney(playerid, -300);
	format(string, sizeof(string), "* %s has bought a car toy for $300.", RPN(playerid), params);
 	SendNearbyMessage(playerid, 15, string, COLOR_PURPLE, COLOR_PURPLE, COLOR_PURPLE, COLOR_PURPLE, COLOR_PURPLE);
 	SendClientMessage(playerid, COLOR_WHITE, " You can view and edit your toys using /cartoys.");
	return 1;
}
Then you use /cartoys to show, edit or hide your car toys
Код:
CMD:cartoys(playerid, params[])
{
	if(!IsPlayerLoggedIn(playerid) || PlayerInfo[playerid][pAsshole] == 1) return SendClientMessage(playerid, COLOR_GREY, "You are not allowed to use command.");
	{
		ShowDialog(playerid, 231);
	}
	return 1;
}
Here is the Dialog 231

Код:
else if(dialogid == 231)
	{
	    if(response)
	    {
	        switch(listitem)
	        {
	            case 0: Ctoyslot[playerid] = 0; case 1: Ctoyslot[playerid] = 1; case 2: Ctoyslot[playerid] = 2;
	        }
	        new index = Ctoyslot[playerid];
		    if(PlayerInfo[playerid][pCToyModel][index] == 0)
		    {
		        ShowDialog(playerid, 231);
		    }
		    else
		    {
	        	ShowDialog(playerid, 241);
	        }
	    }
	}
	else if(dialogid == 241)
	{
	    if(response)
	    {
			switch(listitem)
			{
				case 0:
				{
					if(!IsPlayerAttachedObjectSlotUsed(playerid, Ctoyslot[playerid]))
					{
					    ShowDialog(playerid, 251);
					}
			    	else
			    	{
			    	    RemovePlayerAttachedObject(playerid, Ctoyslot[playerid]);
			    	    
			    	}
				}
				case 1:
				{
				    EditAttachedObject(playerid, Ctoyslot[playerid]);
				}
			}
	    }
	    else ShowDialog(playerid, 231);
	}
	else if(dialogid == 251)
	{
	    if(response)
	    {
			new bone, index = Ctoyslot[playerid];
	        switch(listitem)
	        {
	            case 0: bone = 1; case 1: bone = 1;
	        }
	        SetPlayerAttachedObject(playerid, index, PlayerInfo[playerid][pCToyModel][index], bone, Float:PlayerInfo[playerid][pCToyX][index], Float:PlayerInfo[playerid][pCToyY][index], Float:PlayerInfo[playerid][pCToyZ][index], Float:PlayerInfo[playerid][pCToyRX][index], Float:PlayerInfo[playerid][pToyRY][index], Float:PlayerInfo[playerid][pCToyRZ][index], Float:PlayerInfo[playerid][pCToySX][index], Float:PlayerInfo[playerid][pCToySY][index], Float:PlayerInfo[playerid][pCToySZ][index]);
	        new vehicle;
			vehicle = GetPlayerVehicleID(playerid);
			
			AttachPlayerObjectToVehicle(playerid, PlayerInfo[playerid][pCToyModel][index], vehicle, Float:PlayerInfo[playerid][pToyX][index], Float:PlayerInfo[playerid][pToyY][index], Float:PlayerInfo[playerid][pToyZ][index], Float:PlayerInfo[playerid][pToyRX][index], Float:PlayerInfo[playerid][pToyRY][index], Float:PlayerInfo[playerid][pToyRZ][index]);
	    }
	    else ShowDialog(playerid, 241);
	}
Here are the dialog callbacks

Код:
		case 231: // Car Toys
		{
			// 1 SurfBoard, 2 Snowplow, 3 GM 454 Motor

		    format(string, sizeof(string), "Slot 0 (%s)\nSlot 1 (%s)\nSlot 2 (%s)", RCTN(playerid, 0), RCTN(playerid, 1), RCTN(playerid, 2));
			ShowPlayerDialog(playerid, 231, DIALOG_STYLE_LIST, "Your car toys", string, "Choose", "Cancel");
		}
		case 241: // Toy Add/Remove/Edit
		{
		    new info[16], type[16];
		    if(!IsPlayerAttachedObjectSlotUsed(playerid, Ctoyslot[playerid])) format(info, sizeof(info), "Show Car Toy");
		    else format(info, sizeof(info), "Hide Car Toy");
		    format(string, sizeof(string), "%s\nEdit Car Toy", info);
		    format(type, sizeof(type), "Car Toy Slot %d", Ctoyslot[playerid]);
		    ShowPlayerDialog(playerid, 241, DIALOG_STYLE_LIST, type, string, "Choose", "Back");
		}
		case 251: // Car Toy adding bones
		{
		    ShowPlayerDialog(playerid, 251, DIALOG_STYLE_LIST, "Confirm Car Toy Spawn", "Yes\nNo", "Choose", "Back");
		}
Here is the onplayereditattachedobject

Код:
public OnPlayerEditAttachedObject(playerid, response, index, modelid, boneid, Float:fOffsetX, Float:fOffsetY, Float:fOffsetZ, Float:fRotX, Float:fRotY, Float:fRotZ, Float:fScaleX, Float:fScaleY, Float:fScaleZ)
{
 	SetPlayerAttachedObject(playerid, index, modelid, boneid, Float:fOffsetX, Float:fOffsetY, Float:fOffsetZ, Float:fRotX, Float:fRotY, Float:fRotZ, Float:fScaleX, Float:fScaleY, Float:fScaleZ);
	PlayerInfo[playerid][pCToyX][index] = fOffsetX;
	PlayerInfo[playerid][pCToyY][index] = fOffsetY;
	PlayerInfo[playerid][pCToyZ][index] = fOffsetZ;
	PlayerInfo[playerid][pCToyRX][index] = fRotX;
	PlayerInfo[playerid][pCToyRY][index] = fRotY;
	PlayerInfo[playerid][pCToyRZ][index] = fRotZ;
    PlayerInfo[playerid][pCToySX][index] = fScaleX;
    PlayerInfo[playerid][pCToySY][index] = fScaleY;
    PlayerInfo[playerid][pCToySZ][index] = fScaleZ;


    return 1;
}
Here are the model names for the dialogs

Код:
stock RCTN(playerid, slot)
{
    new name[241], Ctoy = PlayerInfo[playerid][pCToyModel][slot];
    format(name, sizeof(name), "None");
    // Model assigning
	if(Ctoy >= 2403 && Ctoy <= 2405) format(name, sizeof(name), "Surfboard");
	else if(Ctoy >= 19600 && Ctoy <= 19602) format(name, sizeof(name), "Snowplow");
	else if(Ctoy >= 19916 && Ctoy <= 19918) format(name, sizeof(name), "GM 454");
	return name;
}
So yeah the items saves well and all but what I want to do is use /cartoys to edit the item ( must be in a car so I can get CarId ) and then when the player has finished positioning his item then it is no longer attached to the player but to the vehicle. I know it can be done by getting item's location and sending it back to AttachPlayerObjectToVehicle but still I'm unable to do it. I can pay for help and ANY help is much appreciated ! Thanks to you guys
Reply
#2

One more person that confused on attachobject functions, i have to say again that:
SetPlayerAttachedObject functions are SEPARATED from CreateObject/CreatePlayerObject pools
That's mean, it's different type of object, so you can't use the same function. You can't use AttachObjectToVehicle with object set from SetPlayerAttachedObject, SetPlayerAttachedObject are "attached object on player character/skin" previously know as Holding Object or also known as Clothes, CreateObject are global objects created for the world map (san andreas).

Global objects = global and visible to anything, id is returned with CreateObject (you can't set id number)
Player objects = like global objects, but only visible to the player, id is returned with CreatePlayerObject (you can't set id number)
Attached Object = attached on player skin, visible to every streamed in player, does not have id, but uses 10 slots numbered from 0 to 9, it is non solid and the scale can be changed, always attached on the skin bone (e.g. on head, so if the players rotate their head, then the attached object will follow).

Functions:
DescriptionObjectPlayer ObjectAttached Object
Create withCreateObjectCreatePlayerObject-
Set with--SetPlayerAttachedObject
Destroy withDestroyObjectDestroyPlayerObject-
Remove with--RemovePlayerAttachedObject
Select with (cursor)SelectObjectSelectObject-
Check if valid withIsValidObjectIsValidPlayerObjectIsPlayerAttachedObjectSlotUsed
Edit withEditObjectEditPlayerObjectEditAttachedObject
Set pos withSetObjectPosSetPlayerObjectPosSetPlayerAttachedObject
Set rot withSetObjectRotSetPlayerObjectRotSetPlayerAttachedObject
Set material withSetObjectMaterialSetPlayerObjectMaterialSetPlayerAttachedObject (only color at index 0 and 1)
Set material text withSetObjectMaterialTextSetPlayerObjectMaterialText-
Move withMoveObjectMovePlayerObject-
Attach to object withAttachObjectToObject--
Attach to player withAttachObjectToPlayerAttachPlayerObjectToPlayerSetPlayerAttachedObject
Attach to vehicle withAttachObjectToVehicleAttachPlayerObjectToVehicle-
Attach camera withAttachCameraToObjectAttachCameraToPlayerObject-
Callbacks:
ObjectPlayer ObjectAttached Object
OnObjectMovedOnPlayerObjectMoved-
OnPlayerEditObjectOnPlayerEditObjectOnPlayerEditAttachedObject
OnPlayerSelectObjectOnPlayerSelectObject-
So i don't know how to help you to solve this problem as you are using wrong functions.
Therefore, this code:
Код:
SetPlayerAttachedObject(playerid, index, PlayerInfo[playerid][pCToyModel][index], bone, Float:PlayerInfo[playerid][pCToyX][index], Float:PlayerInfo[playerid][pCToyY][index], Float:PlayerInfo[playerid][pCToyZ][index], Float:PlayerInfo[playerid][pCToyRX][index], Float:PlayerInfo[playerid][pToyRY][index], Float:PlayerInfo[playerid][pCToyRZ][index], Float:PlayerInfo[playerid][pCToySX][index], Float:PlayerInfo[playerid][pCToySY][index], Float:PlayerInfo[playerid][pCToySZ][index]);
	        new vehicle;
			vehicle = GetPlayerVehicleID(playerid);
			
			AttachPlayerObjectToVehicle(playerid, PlayerInfo[playerid][pCToyModel][index], vehicle, Float:PlayerInfo[playerid][pToyX][index], Float:PlayerInfo[playerid][pToyY][index], Float:PlayerInfo[playerid][pToyZ][index], Float:PlayerInfo[playerid][pToyRX][index], Float:PlayerInfo[playerid][pToyRY][index], Float:PlayerInfo[playerid][pToyRZ][index]);
Means you are trying to attach a object model ID as stored in pCToyModel at index number 0 to 2 on the playerid.
But you are trying to attach a PLAYER OBJECT (which is not made yet) to a vehicle with the attached object SLOT (not id returned by CreatePlayerObject) which is number 0 to 2.

As you can see in the table above, for instance, you use CreateObject you will use MoveObject instead of MovePlayerObject as this function category/object type is different.
Now if you have understand the functions above, you must correct your functions by using CreatePlayerObject instead of SetPlayerAttachedObject. Therefore you need to change almost all things (variables, callbacks, functions) that you used for the object.

Sorry again because i don't get what you mean with (you better explain more), as it will be really different if i try to help you before the functions are corrected. Hope that helps.
Reply
#3

Thanks for the answer ! I didn't know that those functions couldn't be used together but still: I am convinced that it can be made this way : Spawn the object at the player's position then get the player/vehicle position and then use the EditAttachedObject function to move it around. Also, when it's finished use the AttachObjectToVehicle on the coordinates returned by EditAttachedObject

I'll explain it again in other words so we don't get misunderstood : Lets say the player creates an object ; then this object positions are saved on a file ( so float x , y , z , rx, ry, and rz ( no sizes ) ) and that editplayerobject also read and save those files.

Then , lets say that when the object is done editing , it creates an object ( like you said with the good function ) and then reads from previously saved positions .

I dont know if im mistaken or if you understand what i mean.

Thanks a lot by the way
Reply
#4

Well, you can't unfortunately. You have to use these functions sequentially: CreateObject, EditObject (OnPlayerEditObject), AttachObjectToVehicle. You have to edit before it's attached, once you attach it, you cannot move the object with EditObject. That's mean you have to create the object by getting the vehicle position, and track the position change inside OnPlayerEditObject, calculate the distance of object to vehicle, if the object position is being edited too far, you have to cancel the edit and revert its position. After the player is done with editing it, Attach the object on vehicle, this object will attach on the center of vehicle, so the x,y,z value are relative to vehicle position. Read this wiki page: https://sampwiki.blast.hk/wiki/AttachObjectToVehicle

You cannot use AttachedObject function (SetPlayerAttachedObject and EditAttachedObject) as a preview, the position are not same, because attachedobject is relative to player character bone, not player position nor vehicle position.

Please note that, once the vehicle is destroyed, you have to Destroy the Object as it wont be destroyed (and will stay on its last position), also it will get attached to the same vehicle id (e.g. player was having vehicle id 111, then it's destroyed, another vehicle is spawning with id 111, the object will reattach to that id). OnVehicleDeath is one callback that detects it, but not all.

Please note that since it uses CreateObject (Global objects), it will have limits, so try using dynamic object (streamer plugin) in case you allow this for many players. https://sampforum.blast.hk/showthread.php?tid=102865
Reply
#5

Quote:
Originally Posted by Mikeydoo
Посмотреть сообщение
Thanks for the answer ! I didn't know that those functions couldn't be used together but still: I am convinced that it can be made this way : Spawn the object at the player's position then get the player/vehicle position and then use the EditAttachedObject function to move it around. Also, when it's finished use the AttachObjectToVehicle on the coordinates returned by EditAttachedObject

I'll explain it again in other words so we don't get misunderstood : Lets say the player creates an object ; then this object positions are saved on a file ( so float x , y , z , rx, ry, and rz ( no sizes ) ) and that editplayerobject also read and save those files.

Then , lets say that when the object is done editing , it creates an object ( like you said with the good function ) and then reads from previously saved positions .

I dont know if im mistaken or if you understand what i mean.

Thanks a lot by the way
If I'm understanding this correctly you want to use EditAttachedObject just for calculations of the right pos.
Yes it's possible, but you need to do a little math, and thats pretty much bane of scripting, people are too lazy to do the math, EditAttachedObject returns offsets of item to player, you need offset to the vehicle, therefore you should get player's offset to vehicle, and calculate veh to object from those 2 numbers you have, then destroy the player object, createobject n attach it to veh.
PS: I just noticed that Robo mentioned bones, yes the offset is relative to bone, but I think the spine bone's offset is 0,0,0 might be wrong tho.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)