diff --git a/[editor]/move_cursor/move_cursor.lua b/[editor]/move_cursor/move_cursor.lua index c138d91e3..d1c3a1fff 100644 --- a/[editor]/move_cursor/move_cursor.lua +++ b/[editor]/move_cursor/move_cursor.lua @@ -14,8 +14,6 @@ local ignoreElementWalls = true -- 'false' not supported yet local isEnabled = false -local root = getRootElement() - local camX, camY, camZ local selectedElement @@ -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 @@ -68,48 +51,65 @@ 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) @@ -117,7 +117,7 @@ local function processCursorMove (absoluteX,absoluteY) 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) @@ -125,30 +125,14 @@ local function processCursorMove (absoluteX,absoluteY) 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 @@ -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 @@ -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) @@ -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 @@ -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() @@ -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