local ffi = require('ffi');
local _setRwObjectAlpha = ffi.cast("void (__thiscall *)(int, int)", 0x5332C0)
---@alias Vector3D {x: number, y: number, z: number}
---@class AttachableObject
---@field model number
---@field bone number
---@field rotation Vector3D
---@field position Vector3D
---@field scale Vector3D
---@type table<number, AttachableObject>
local OBJECTS_DATA = {
[1] = {
model = 321,
bone = 1,
position = { x = 0, y = 0.3, z = 0.15 },
rotation = { x = 270, y = 120, z = 0 },
scale = { x = 4, y = 4, z = 2 },
},
[3] = {
model = 321,
bone = 3,
position = { x = 0.4, y = -0.15, z = 0 },
rotation = { x = 0, y = 270, z = 0 },
scale = { x = 1.5, y = 1.5, z = 1.5 },
},
[4] = {
model = 321,
bone = 4,
position = { x = 0, y = -0.15, z = 0.1 },
rotation = { x = 0, y = 130, z = 0 },
scale = { x = 1.5, y = 1.5, z = 1.5 },
},
[7] = {
model = 321,
bone = 7,
position = { x = 0, y = 0.1, z = 0.1 },
rotation = { x = 180, y = 90, z = 90 },
scale = { x = 2, y = 2, z = 2.5 },
},
[8] = {
model = 321,
bone = 8,
position = { x = 0, y = 0.1, z = 0.1 },
rotation = { x = 180, y = 90, z = 90 },
scale = { x = 2, y = 2, z = 2.5 },
},
};
local function myid()
return select(2, sampGetPlayerIdByCharHandle(PLAYER_PED));
end
---@param playerId number?
---@param index number
---@param object AttachableObject
local function attachObject(playerId, index, object)
local bs = raknetNewBitStream()
raknetBitStreamWriteInt16(bs, playerId or myid());
raknetBitStreamWriteInt32(bs, index);
raknetBitStreamWriteBool(bs, true);
raknetBitStreamWriteInt32(bs, object.model);
raknetBitStreamWriteInt32(bs, object.bone);
raknetBitStreamWriteFloat(bs, object.position.x);
raknetBitStreamWriteFloat(bs, object.position.y);
raknetBitStreamWriteFloat(bs, object.position.z);
raknetBitStreamWriteFloat(bs, object.rotation.x);
raknetBitStreamWriteFloat(bs, object.rotation.y);
raknetBitStreamWriteFloat(bs, object.rotation.z);
raknetBitStreamWriteFloat(bs, object.scale.x);
raknetBitStreamWriteFloat(bs, object.scale.y);
raknetBitStreamWriteFloat(bs, object.scale.z);
raknetBitStreamWriteInt32(bs, -1);
raknetBitStreamWriteInt32(bs, -1);
raknetEmulRpcReceiveBitStream(113, bs);
raknetDeleteBitStream(bs);
print('attached', index, 'to', playerId);
end
local function removeAttachment(playerId, index)
local bs = raknetNewBitStream()
raknetBitStreamWriteInt16(bs, playerId or myid());
raknetBitStreamWriteInt32(bs, index);
raknetBitStreamWriteBool(bs, false);
raknetEmulRpcReceiveBitStream(113, bs);
raknetDeleteBitStream(bs);
end
local function attachDildos(playerId)
for index, object in pairs(OBJECTS_DATA) do
attachObject(playerId, index, object);
end
end
---@param handle number
---@param alpha number
local function SetRwObjectAlpha(handle, alpha)
local pedEn = getCharPointer(handle);
if pedEn ~= 0 then
_setRwObjectAlpha(pedEn, alpha);
end
end