Jump to content

Small maths help.


pa3ck

Recommended Posts

Hey.

I just started to develop a builder resource for DayZ but the thing is, I'm not the best at maths. What I want to do is, move an object using keys. The problem is, I don't know how to calculate the X and Y positions when the player is not at a 0 degrees angle on the map. Any help or advice would be appreciated, thanks!

Link to comment
  • 3 weeks later...
  • MTA Team

Get the player's position.

Get the object's position.

Calculate the angle between those positions (FindRotation) and use that angle with combination with math.cos and math.sin to calculate a position from the object's position at some distance. (x0 + math.cos(angle [in rad]) * distance)

Note: That will only move the object relative to the player (not camera) and it won't move the object up or down.

Link to comment

Since I'll be doing something similar in the future, I tried to throw something together a bit fast - I'm not sure if this is what you're asking for, but if it is, feel free to edit it to your hearts desire!

Client:

-- Variables 
local isBuildModeActive = false; 
local selectedObject = nil; 
  
-- Functions 
function startBuildMode_Handler() 
    if(isPedInVehicle(localPlayer) == false) then 
        if(isBuildModeActive == false) then 
            isBuildModeActive = true; 
            outputChatBox("#696969[server]: #00BB00Building Mode has been activated!", 0, 0, 0, true); 
        elseif(isBuildModeActive == true) then 
            isBuildModeActive = false; 
            outputChatBox("#696969[server]: #BB0000Building Mode has been de-activated!", 0, 0, 0, true); 
        end 
    else 
        outputChatBox("#696969[server]: #BB0000You can not enter Build Mode whilst in a vehicle!", 0, 0, 0, true); 
    end 
end 
addCommandHandler("Build", startBuildMode_Handler, false); 
  
function selectObjectCommand_Handler(theCMD, arg1) 
    local stringPattern = "[%a%p%s%c]"; 
    if(isBuildModeActive == true) then 
        if(string.match(arg1, stringPattern)) then 
            outputChatBox("#696969[server]: #BB0000Invalid input detected! #FF2626("..tostring(arg1)..")", 0, 0, 0, true); 
            outputChatBox("#696969[server]: #BB0000Syntax: /Select [ObjectID] (/Select 2898)", 0, 0, 0, true); 
        else 
            local objectID = tonumber(arg1); 
            outputChatBox("#696969[server]: #00BB00Selected Object ID #26FF26("..(tostring(arg1))..")", 0, 0, 0, true); 
            local pX, pY, pZ = getElementPosition(localPlayer); 
            local pRX, pRY, pRZ = getElementRotation(localPlayer); 
            local oX, oY = (pX+4*math.cos(math.rad(pRZ+90))), (pY+4*math.sin(math.rad(pRZ+90))); 
            local theObject = createObject(objectID, oX, oY, pZ); 
            selectedObject = theObject; 
            addEventHandler("onClientPreRender", root, updateObjectLocation_Handler); 
        end  
    else 
        outputChatBox("#696969[server]: #BB0000Building Mode is not activated!", 0, 0, 0, true); 
    end 
end 
addCommandHandler("Select", selectObjectCommand_Handler, false); 
  
function updateObjectLocation_Handler() 
    if(selectedObject ~= nil) then 
        local pX, pY, pZ = getElementPosition(localPlayer); 
        local pRX, pRY, pRZ = getElementRotation(localPlayer); 
        local oX, oY = (pX+4*math.cos(math.rad(pRZ+90))), (pY+4*math.sin(math.rad(pRZ+90))); 
        setElementPosition(selectedObject, oX, oY, pZ); 
    end 
end 

Usage:

/Build - Enters Building Mode

/Select [iD] - Creates the specified object.

As I said, I threw this together in less than half an hour. So it's not perfect :P

Link to comment
  • MTA Team

You could remove the calculation from the "Select" command handler or call the function updateObjectLocation_Handler().

You could also add some other handy functionality for the height (optional, the object should stick to the ground all the time):

  
function updateObjectLocation_Handler() 
    if(selectedObject ~= nil) then 
        local pX, pY, pZ = getElementPosition(localPlayer); 
        local pRX, pRY, pRZ = getElementRotation(localPlayer); 
        local pD = getElementDistanceFromCentreOfMassToBaseOfModel(localPlayer); 
        local oX, oY = (pX+4*math.cos(math.rad(pRZ+90))), (pY+4*math.sin(math.rad(pRZ+90))); 
        local oZ = (pZ - pD + getElementDistanceFromCentreOfMassToBaseOfModel(selectedObject)); 
        setElementPosition(selectedObject, oX, oY, oZ); 
    end 
end 
  

Edit: I am not sure if the - pD is neccessary

Link to comment
You could remove the calculation from the "Select" command handler or call the function updateObjectLocation_Handler().

You could also add some other handy functionality for the height (optional, the object should stick to the ground all the time):

  
function updateObjectLocation_Handler() 
    if(selectedObject ~= nil) then 
        local pX, pY, pZ = getElementPosition(localPlayer); 
        local pRX, pRY, pRZ = getElementRotation(localPlayer); 
        local pD = getElementDistanceFromCentreOfMassToBaseOfModel(localPlayer); 
        local oX, oY = (pX+4*math.cos(math.rad(pRZ+90))), (pY+4*math.sin(math.rad(pRZ+90))); 
        local oZ = (pZ - pD + getElementDistanceFromCentreOfMassToBaseOfModel(selectedObject)); 
        setElementPosition(selectedObject, oX, oY, oZ); 
    end 
end 
  

Edit: I am not sure if the - pD is neccessary

Of course it could be improved, it was just pieced together in a few minutes in hopes it would assist him in what he was looking for. Trigonometry has always been my one true enemy, so any feedback on how to improve it is of course welcome. :D

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...