Ripped a part utility folder and shoved it into a lib. Changed a lot of Utility prefixes to the modules name. This contains breaking changes. Scripts that use 0.2.0 will need to update to match the new format
169 lines
7.1 KiB
Lua
169 lines
7.1 KiB
Lua
Scaleform = Scaleform or Require("client/scaleform.lua")
|
|
Utility = Utility or Require("client/utility.lua")
|
|
Gizmo = Gizmo or Require("client/gizmo.lua")
|
|
|
|
PlaceableObject = PlaceableObject or {}
|
|
local data = {
|
|
entity = nil,
|
|
placing = false,
|
|
}
|
|
|
|
function PlaceableObject.Eyetrace(depth, disableSphere)
|
|
local screenX = GetDisabledControlNormal(0, 239)
|
|
local screenY = GetDisabledControlNormal(0, 240)
|
|
|
|
local world, normal = GetWorldCoordFromScreenCoord(screenX, screenY)
|
|
local playerPos = GetEntityCoords(PlayerPedId())
|
|
local target = playerPos + normal * depth
|
|
if not disableSphere then
|
|
DrawSphere(target.x, target.y, target.z, 0.5, 255, 0, 0, 0.5)
|
|
end
|
|
return target
|
|
end
|
|
|
|
-- Creates a placeable object in the game world.
|
|
-- @param model (string) The model of the object to create.
|
|
-- @param onConfirm (function) [optional] The callback function to execute when the object is confirmed.
|
|
-- @param onUpdate (function) [optional] The callback function to execute when the object is moved.
|
|
-- @param onCancel (function) [optional] The callback function to execute when the object is canceled.
|
|
-- @param settings (table) [optional] Additional settings for the placeable object.
|
|
-- - depthMin (number) The minimum depth for the object placement. Default is 2.0.
|
|
-- - depthMax (number) The maximum depth for the object placement. Default is 10.0.
|
|
-- - rotationStep (number) The rotation step for the object. Default is 15.0.
|
|
-- - depthStep (number) The depth step for the object. Default is 1.0.
|
|
function PlaceableObject.Create(data, model, onConfirm, onUpdate, onCancel, settings, config)
|
|
local settings = settings or {}
|
|
local depthMin = settings.depthMin or 2.0
|
|
depthMax = settings.depthMax or 10.0
|
|
rotationStep = settings.rotationStep or 15.0
|
|
depthStep = settings.depthStep or 1.0
|
|
local depth = settings.depth or 10.0
|
|
print(depth)
|
|
data.placing = true
|
|
data.paused = false
|
|
local initialPos = nil
|
|
local placeOnGround = true
|
|
|
|
--scaleform
|
|
local scaleform = Scaleform.SetupInstructionalButtons({
|
|
{type = "CLEAR_ALL"},
|
|
{type = "SET_CLEAR_SPACE", int = 200},
|
|
{type = "SET_DATA_SLOT", name = config?.place_object?.name or 'Place Object:', keyIndex = config?.place_object?.key or {223}, int = 5},
|
|
{type = "SET_DATA_SLOT", name = config?.cancel_placement?.name or 'Cancel Placement:', keyIndex = config?.cancel_placement?.key or {222}, int = 4},
|
|
{type = "SET_DATA_SLOT", name = config?.snap_to_ground?.name or 'Snap to Ground:', keyIndex = config?.snap_to_ground?.key or {19}, int = 1},
|
|
{type = "SET_DATA_SLOT", name = config?.rotate?.name or 'Rotate:', keyIndex = config?.rotate?.key or {14, 15}, int = 2},
|
|
{type = "SET_DATA_SLOT", name = config?.distance?.name or 'Distance:', keyIndex = config?.distance?.key or {14,15,36}, int = 3},
|
|
{type = "SET_DATA_SLOT", name = config?.toggle_placement?.name or 'Toggle Placement:', keyIndex = config?.toggle_placement?.key or {199}, int = 0},
|
|
{type = "SET_DATA_SLOT", name = config?.gizmo?.name or 'Toggle Gizmo:', keyIndex = config?.gizmo?.key or {38}, int = 6},
|
|
{type = "DRAW_INSTRUCTIONAL_BUTTONS"},
|
|
{type = "SET_BACKGROUND_COLOUR"},
|
|
})
|
|
CreateThread(function()
|
|
local heading = -GetEntityHeading(PlayerPedId())
|
|
|
|
local pos = PlaceableObject.Eyetrace(depth)
|
|
if not data.spawned and model then
|
|
--get player heading
|
|
local obj = Utility.CreateProp(model, pos, vector3(0, 0, heading), nil)
|
|
data.spawned = obj
|
|
end
|
|
assert(data.spawned, "Failed to create object")
|
|
SetEntityCollision(data.spawned, false, false)
|
|
SetEntityAlpha(data.spawned, 150, false)
|
|
|
|
SetPedConfigFlag(PlayerPedId(), 146, true)
|
|
SetCanClimbOnEntity(data.spawned, false)
|
|
SetEntityCompletelyDisableCollision(data.spawned, true, false)
|
|
SetEntityNoCollisionEntity(PlayerPedId(), data.spawned, false)
|
|
|
|
while data.placing do
|
|
if data.paused then goto continue end
|
|
DrawScaleformMovieFullscreen(scaleform, 255, 255, 255, 255, 0)
|
|
DisableControlAction(0, 24, true) -- Attack
|
|
DisableControlAction(0, 25, true) -- Aim
|
|
DisableControlAction(0, 36, true) -- INPUT_DUCK.
|
|
|
|
if IsControlJustPressed(0, 223) then -- left click
|
|
if onConfirm and type(onConfirm) == 'function' then onConfirm(data.spawned, pos, heading) end
|
|
data.placing = false
|
|
end
|
|
|
|
if IsControlJustPressed(0, 222) then -- right click
|
|
data.placing = false
|
|
if onCancel and type(onCancel) == 'function' then
|
|
onCancel(data.spawned, pos, heading)
|
|
else
|
|
DeleteEntity(data.spawned)
|
|
end
|
|
return
|
|
end
|
|
|
|
if IsControlPressed(0,19) then
|
|
placeOnGround = not (placeOnGround or false)
|
|
end
|
|
|
|
if IsControlJustPressed(0, 38) then -- TAB key to switch to gizmo
|
|
data.placing = false
|
|
return Gizmo.UseGizmo(data.spawned, onConfirm, onUpdate, onCancel)
|
|
end
|
|
|
|
if IsControlPressed(0,224) then -- left ctrl
|
|
if IsControlJustPressed(0, 261) then -- scroll up
|
|
depth = depth + depthStep
|
|
if depth > depthMax then
|
|
depth = depthMax
|
|
end
|
|
end
|
|
|
|
if IsControlJustPressed(0, 262) then -- scroll down
|
|
depth = depth - depthStep
|
|
if depth < depthMin then
|
|
depth = depthMin
|
|
end
|
|
end
|
|
else
|
|
if IsControlJustPressed(0, 261) then -- scroll up
|
|
heading = heading + rotationStep
|
|
if heading > 360 then
|
|
heading = 0
|
|
end
|
|
end
|
|
if IsControlJustPressed(0, 262) then -- scroll down
|
|
heading = heading - rotationStep
|
|
if heading < 0 then
|
|
heading = 360
|
|
end
|
|
end
|
|
end
|
|
|
|
pos = PlaceableObject.Eyetrace(depth)
|
|
if data.spawned then
|
|
SetEntityCoords(data.spawned, pos.x, pos.y, pos.z)
|
|
SetEntityHeading(data.spawned, heading)
|
|
if placeOnGround then
|
|
PlaceObjectOnGroundProperly(data.spawned)
|
|
pos = GetEntityCoords(data.spawned)
|
|
end
|
|
end
|
|
if onUpdate and type(onUpdate) == 'function' then onUpdate(data.spawned, pos, heading) end
|
|
::continue::
|
|
if IsControlJustPressed(0, 199) then -- home
|
|
data.paused = not data.paused
|
|
end
|
|
Wait(1)
|
|
end
|
|
end)
|
|
end
|
|
|
|
|
|
|
|
RegisterCommand("testers", function()
|
|
PlaceableObject.Create({}, "prop_beachflag_01", function(entity, pos, heading)
|
|
|
|
end, function(entity, pos, heading)
|
|
|
|
end, function(entity, pos, heading)
|
|
|
|
end)
|
|
end)
|