, &Float:y, &Float:z, &Float:rx, &Float:ry, &Float:rz)|
StartX,StartY,StartZ Start position of ray cast. EndX,EndY,EndZ Endposition of ray cast. &x,&y,&z Collision position is stored in these references. &rx,&ry,&rz Rotation of surface of collision. |
|
Directly under a player? I believe sa-mp's skin heights are all(or almost all) the same being 1.8 or 2.0, so you could get the player'pos and just create an object 0.9-1.0 below the z you get, and it will be directly under him, however if you want to create the object on the land/object under him, you need to either use MapAndreas or ColAndreas(recommended).
|

new Float: x, Float: y, Float: z, Float:a;
GetPlayerFacingAngle(playerid, a);
GetPlayerPos(playerid, x, y, z);
MapAndreas_FindZ_For2DCoord(x, y, z);
stock ObjectRotateZ(Float:RX, Float:RY, Float:RZ, Float:rot_z, &Float:NewRX, &Float:NewRY, &Float:NewRZ)
{
new
Float:sinx,
Float:siny,
Float:sinz,
Float:cosx,
Float:cosy,
Float:cosz;
FloatConvertValue(RX, RY, RZ, sinx, siny, sinz, cosx, cosy, cosz);
// Convert from one euler angle sequence (ZXY) to another and add the rotation
FloatConvertValue(asin(cosx * cosy), atan2(sinx, cosx * siny) + rot_z, atan2(cosy * cosz * sinx - siny * sinz, cosz * siny - cosy * sinx * -sinz),
sinx, siny, sinz, cosx, cosy, cosz);
// Convert back to the original euler angle sequence and apply the new rotation to the object
NewRX = asin(cosx * siny),
NewRY = atan2(cosx * cosy, sinx),
NewRZ = atan2(cosz * sinx * siny - cosy * sinz, cosy * cosz + sinx * siny * sinz);
return 1;
}
stock FloatConvertValue(Float:rot_x, Float:rot_y, Float:rot_z, &Float:sinx, &Float:siny, &Float:sinz, &Float:cosx, &Float:cosy, &Float:cosz)
{
sinx = floatsin(rot_x, degrees);
siny = floatsin(rot_y, degrees);
sinz = floatsin(rot_z, degrees);
cosx = floatcos(rot_x, degrees);
cosy = floatcos(rot_y, degrees);
cosz = floatcos(rot_z, degrees);
return 1;
}
|
Yeah you need ColAndreas it will give you the surface angle but you still need to figure out offsets. Once you have your angles you can rotate the object on the z-axis and still maintain the correct angle with this function.
Код:
stock ObjectRotateZ(Float:RX, Float:RY, Float:RZ, Float:rot_z, &Float:NewRX, &Float:NewRY, &Float:NewRZ)
{
new
Float:sinx,
Float:siny,
Float:sinz,
Float:cosx,
Float:cosy,
Float:cosz;
FloatConvertValue(RX, RY, RZ, sinx, siny, sinz, cosx, cosy, cosz);
// Convert from one euler angle sequence (ZXY) to another and add the rotation
FloatConvertValue(asin(cosx * cosy), atan2(sinx, cosx * siny) + rot_z, atan2(cosy * cosz * sinx - siny * sinz, cosz * siny - cosy * sinx * -sinz),
sinx, siny, sinz, cosx, cosy, cosz);
// Convert back to the original euler angle sequence and apply the new rotation to the object
NewRX = asin(cosx * siny),
NewRY = atan2(cosx * cosy, sinx),
NewRZ = atan2(cosz * sinx * siny - cosy * sinz, cosy * cosz + sinx * siny * sinz);
return 1;
}
stock FloatConvertValue(Float:rot_x, Float:rot_y, Float:rot_z, &Float:sinx, &Float:siny, &Float:sinz, &Float:cosx, &Float:cosy, &Float:cosz)
{
sinx = floatsin(rot_x, degrees);
siny = floatsin(rot_y, degrees);
sinz = floatsin(rot_z, degrees);
cosx = floatcos(rot_x, degrees);
cosy = floatcos(rot_y, degrees);
cosz = floatcos(rot_z, degrees);
return 1;
}
|
ObjectRotateZ(Float:RX, Float:RY, Float:RZ, Float:rot_z, &Float:NewRX, &Float:NewRY, &Float:NewRZ)