Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
188 changes: 82 additions & 106 deletions [editor]/move_cursor/move_cursor.lua
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ local ignoreElementWalls = true -- 'false' not supported yet

local isEnabled = false

local root = getRootElement()

local camX, camY, camZ

local selectedElement
Expand All @@ -36,27 +34,12 @@ local hasRotation = {
ped = true,
}

-- PRIVATE
local onClientMouseMove

local mta_getElementRotation = getElementRotation
local function getElementRotation(element)
local elementType = getElementType(element)
if elementType == "player" or elementType == "ped" then
return 0,0,getPedRotation(element)
elseif elementType == "object" then
return mta_getElementRotation(element)
elseif elementType == "vehicle" then
return mta_getElementRotation(element)
end
end

local function getCoordsWithBoundingBox(origX, origY, origZ)
if (not collisionless) then
local newX, newY, newZ = origX, origY, origZ
if (not ignoreElementWalls) then
-- hard stuff
else
if ignoreElementWalls then
local surfaceFound, surfaceX, surfaceY, surfaceZ, element = processLineOfSight(origX, origY, origZ + SURFACE_ERROR_CORRECTION_OFFSET, origX, origY, origZ + minZ, true, true, true, true, true, true, false, true, selectedElement)
if (surfaceFound) then
newZ = surfaceZ + centerToBaseDistance
Expand All @@ -68,87 +51,88 @@ local function getCoordsWithBoundingBox(origX, origY, origZ)
end
end

local function processCursorMove (absoluteX,absoluteY)
if not absoluteX then
local relX,relY = getCursorPosition()
absoluteX,absoluteY = relX*g_screenX,relY*g_screenY
local function processCursorMove(absoluteX, absoluteY)
if not absoluteX or not absoluteY then
local relX, relY = getCursorPosition()
absoluteX, absoluteY = relX*g_screenX, relY*g_screenY
end
-- process line, checking for water and surfaces
local worldX, worldY, worldZ = getWorldFromScreenPosition(absoluteX, absoluteY, MAX_DISTANCE )
-- make sure there is a camera position
if (not camX) then return end
local surfaceFound, surfaceX, surfaceY, surfaceZ, element = processLineOfSight(camX, camY, camZ, worldX, worldY, worldZ, true, true, true, true, true, true, false, true, selectedElement)
local waterFound, waterX, waterY, waterZ = testLineAgainstWater(camX, camY, camZ, worldX, worldY, worldZ)

-- check if surfaces are not too far
local surfaceDistance
local waterDistance
if (surfaceFound) then
surfaceDistance = math.sqrt((surfaceX - camX)^2 + (surfaceY - camY)^2 + (surfaceZ - camZ)^2)
if (surfaceDistance > maxMoveDistance) then
surfaceFound = false
end
end
if (waterFound) then
waterDistance = math.sqrt((waterX - camX)^2 + (waterY - camY)^2 + (waterZ - camZ)^2)
if (waterDistance > maxMoveDistance) then
waterFound = false
end
end
if camX and camY then
local surfaceFound, surfaceX, surfaceY, surfaceZ, element = processLineOfSight(camX, camY, camZ, worldX, worldY, worldZ, true, true, true, true, true, true, false, true, selectedElement)
local waterFound, waterX, waterY, waterZ = testLineAgainstWater(camX, camY, camZ, worldX, worldY, worldZ)

-- raise height if pickup or a marker
if (getElementType(selectedElement) == "pickup") or (getElementType(selectedElement) == "marker") then
-- check if surfaces are not too far
local surfaceDistance
local waterDistance
if (surfaceFound) then
surfaceZ = surfaceZ + 1
surfaceDistance = math.sqrt((surfaceX - camX)^2 + (surfaceY - camY)^2 + (surfaceZ - camZ)^2)
if (surfaceDistance > maxMoveDistance) then
surfaceFound = false
end
end
if (waterFound) then
waterZ = waterZ + 1
waterDistance = math.sqrt((waterX - camX)^2 + (waterY - camY)^2 + (waterZ - camZ)^2)
if (waterDistance > maxMoveDistance) then
waterFound = false
end
end
end

-- check if water or surface was found
if (surfaceFound and waterFound) then
-- if both found, compare distances
if (waterDistance >= surfaceDistance) then
-- raise height if pickup or a marker
if (getElementType(selectedElement) == "pickup") or (getElementType(selectedElement) == "marker") then
if (surfaceFound) then
surfaceZ = surfaceZ + 1
end
if (waterFound) then
waterZ = waterZ + 1
end
end

-- check if water or surface was found
if (surfaceFound and waterFound) then
-- if both found, compare distances
if (waterDistance >= surfaceDistance) then
if (not collisionless) then
centerToBaseDistance = exports.edf:edfGetElementDistanceToBase(selectedElement)
local finalX, finalY, finalZ = getCoordsWithBoundingBox(surfaceX, surfaceY, surfaceZ)
setElementPosition(selectedElement, finalX, finalY, finalZ)
else
setElementPosition(selectedElement, surfaceX, surfaceY, surfaceZ)
end
else
if (not collisionless) then
centerToBaseDistance = exports.edf:edfGetElementDistanceToBase(selectedElement)
local finalX, finalY, finalZ = getCoordsWithBoundingBox(waterX, waterY, waterZ)
setElementPosition(selectedElement, finalX, finalY, finalZ)
else
setElementPosition(selectedElement, waterX, waterY, waterZ)
end
end
elseif (surfaceFound) then
if (not collisionless) then
centerToBaseDistance = exports.edf:edfGetElementDistanceToBase(selectedElement)
local finalX, finalY, finalZ = getCoordsWithBoundingBox(surfaceX, surfaceY, surfaceZ)
setElementPosition(selectedElement, finalX, finalY, finalZ)
else
setElementPosition(selectedElement, surfaceX, surfaceY, surfaceZ)
end
else
elseif (waterFound) then
if (not collisionless) then
centerToBaseDistance = exports.edf:edfGetElementDistanceToBase(selectedElement)
local finalX, finalY, finalZ = getCoordsWithBoundingBox(waterX, waterY, waterZ)
setElementPosition(selectedElement, finalX, finalY, finalZ)
else
setElementPosition(selectedElement, waterX, waterY, waterZ)
end
else -- in air
local tempDistance = math.sqrt((worldX - camX)^2 + (worldY - camY)^2 + (worldZ - camZ)^2)
local distanceRatio = maxMoveDistance / tempDistance
local x = camX + (worldX - camX) * distanceRatio
local y = camY + (worldY - camY) * distanceRatio
local z = camZ + (worldZ - camZ) * distanceRatio
setElementPosition(selectedElement, x, y, z)
end
elseif (surfaceFound) then
if (not collisionless) then
centerToBaseDistance = exports.edf:edfGetElementDistanceToBase(selectedElement)
local finalX, finalY, finalZ = getCoordsWithBoundingBox(surfaceX, surfaceY, surfaceZ)
setElementPosition(selectedElement, finalX, finalY, finalZ)
else
setElementPosition(selectedElement, surfaceX, surfaceY, surfaceZ)
end
elseif (waterFound) then
if (not collisionless) then
centerToBaseDistance = exports.edf:edfGetElementDistanceToBase(selectedElement)
local finalX, finalY, finalZ = getCoordsWithBoundingBox(waterX, waterY, waterZ)
setElementPosition(selectedElement, finalX, finalY, finalZ)
else
setElementPosition(selectedElement, waterX, waterY, waterZ)
end
else -- in air
local tempDistance = math.sqrt((worldX - camX)^2 + (worldY - camY)^2 + (worldZ - camZ)^2)
local distanceRatio = maxMoveDistance / tempDistance
local x = camX + (worldX - camX) * distanceRatio
local y = camY + (worldY - camY) * distanceRatio
local z = camZ + (worldZ - camZ) * distanceRatio
setElementPosition(selectedElement, x, y, z)
end
end

Expand All @@ -163,17 +147,16 @@ local function zoomWithMouseWheel(key, keyState)
speed = zoomSpeed.medium
end

if getCommandState"zoom_in" then
if getCommandState("zoom_in") then
maxMoveDistance = math.max(maxMoveDistance - speed, MIN_DISTANCE)
processCursorMove ()
processCursorMove()
else --if key == "zoom_out"
maxMoveDistance = math.min(maxMoveDistance + speed, MAX_DISTANCE)
processCursorMove ()
processCursorMove()
end
end
end


local function onClientCursorMove_cursor(_, _, absoluteX, absoluteY )
if (selectedElement) then
if ignoreFirst then
Expand All @@ -184,7 +167,6 @@ local function onClientCursorMove_cursor(_, _, absoluteX, absoluteY )
end
end


local function rotateWithMouseWheel(key, keyState)
if (not rotationless) and getCommandState("mod_rotate") then
rotX, rotY, rotZ = getElementRotation(selectedElement)
Expand Down Expand Up @@ -292,10 +274,10 @@ function detachElement()

-- sync position/rotation
local tempPosX, tempPosY, tempPosZ = getElementPosition(selectedElement)
triggerServerEvent("syncProperty", getLocalPlayer(), "position", {tempPosX, tempPosY, tempPosZ}, exports.edf:edfGetAncestor(selectedElement))
triggerServerEvent("syncProperty", localPlayer, "position", {tempPosX, tempPosY, tempPosZ}, exports.edf:edfGetAncestor(selectedElement))
if hasRotation[getElementType(selectedElement)] then
rotX, rotY, rotZ = getElementRotation(selectedElement)
triggerServerEvent("syncProperty", getLocalPlayer(), "rotation", {rotX, rotY, rotZ}, exports.edf:edfGetAncestor(selectedElement))
triggerServerEvent("syncProperty", localPlayer, "rotation", {rotX, rotY, rotZ}, exports.edf:edfGetAncestor(selectedElement))
end
selectedElement = nil

Expand Down Expand Up @@ -330,11 +312,7 @@ function setZoomSpeeds(slow, medium, fast)
end

function getAttachedElement()
if (selectedElement) then
return selectedElement
else
return false
end
return selectedElement
end

function getMaxMoveDistance()
Expand All @@ -350,29 +328,27 @@ function getZoomSpeeds()
end

function disable()
if (not isEnabled) then
return false
if isEnabled then
removeEventHandler("onClientCursorMove", root, onClientCursorMove_cursor)
unbindControl("quick_rotate_increase", "down", rotateWithMouseWheel)
unbindControl("quick_rotate_decrease", "down", rotateWithMouseWheel)
unbindControl("zoom_in", "down", zoomWithMouseWheel)
unbindControl("zoom_out", "down", zoomWithMouseWheel)
isEnabled = false
end
-- remove events, unbind keys
removeEventHandler("onClientCursorMove", root, onClientCursorMove_cursor)
unbindControl("quick_rotate_increase", "down", rotateWithMouseWheel)
unbindControl("quick_rotate_decrease", "down", rotateWithMouseWheel)
unbindControl("zoom_in", "down", zoomWithMouseWheel)
unbindControl("zoom_out", "down", zoomWithMouseWheel)
isEnabled = false
return true
end

function enable()
if isEnabled then
return false
if not isEnabled then
ignoreFirst = true
addEventHandler("onClientCursorMove", root, onClientCursorMove_cursor)
bindControl("quick_rotate_increase", "down", rotateWithMouseWheel)
bindControl("quick_rotate_decrease", "down", rotateWithMouseWheel)
bindControl("zoom_in", "down", zoomWithMouseWheel)
bindControl("zoom_out", "down", zoomWithMouseWheel)
setTimer(processCursorMove, 50, 1) --Lazy but we have to wait for MTA to switch modes
isEnabled = true
end
-- add events, bind keys
ignoreFirst = true
addEventHandler("onClientCursorMove", root, onClientCursorMove_cursor)
bindControl("quick_rotate_increase", "down", rotateWithMouseWheel) --rotate left
bindControl("quick_rotate_decrease", "down", rotateWithMouseWheel) --rotate right
bindControl("zoom_in", "down", zoomWithMouseWheel) --zoom in
bindControl("zoom_out", "down", zoomWithMouseWheel) --zoom out
setTimer ( processCursorMove, 50, 1 ) --Lazy but we have to wait for MTA to switch modes
isEnabled = true
return true
end