Thread Tools Display Modes
05/24/14, 12:19 PM   #1
Sharlikran
 
Sharlikran's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 588
Get position of Target

I have been trying to figure out a better way to calculate the position of the target under the reticle in relation to the position of the player. I found a mod named RangeReticle that uses GetMapPlayerPosition('reticleover') and a rather complex bit of equations to determine the distance of the NPC from the player.

So I figured then GetMapPlayerPosition('player') is obviously the player. I would think GetMapPlayerPosition('reticleover') would return values for anything my reticle is over. For example, a harvest node, an NPC, a barrel, a Fishing hole, anything. However, it only seems to register and X and Y value when my reticle is over an NPC.

Is there anything else I can use to get the position of anything, not just an NPC, that is under my reticle?

Last edited by Sharlikran : 05/24/14 at 12:26 PM.
  Reply With Quote
05/24/14, 12:31 PM   #2
thelegendaryof
 
thelegendaryof's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 161
Not as far as I know - rectileover is an 2D object on your UI that only holds X and Y variables and as such doesn't have no depth / z-var. They obvisiously did that to keep people from writing automated combat and similiar with the official API.
  Reply With Quote
05/24/14, 01:35 PM   #3
Tar000un
 
Tar000un's Avatar
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 47
I think you need to get your position and the target's position in order to get the distance.

Reading the wiki, i saw a (API) Global:ComputeStringDistance(), may that could help.
  Reply With Quote
05/24/14, 02:24 PM   #4
Sharlikran
 
Sharlikran's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 588
That makes sense, sure they don't want players exploiting the API. I only need X and Y, I don't need Z. Say the player's position is [X] = 0.467469, [Y] = 0.409835 and the position of the target is [X] = 0.415760, [Y] = 0.427441. At the moment, if someone were to make a combat mod, it is returning X and Y for NPCs, so it's not really protected to prevent misuse.

At the moment most of the equations I have seen for calculating the distance of a harvest node, a Crate, a barrel, an NPC seem to use just the difference of x1 and x2, then y1 and y2. HarvestMap, uses more of what I am looking for.



Standard Form: (x-a)2 + (y-b)2 = r2

HarvestMap:

dx = entry[1] - x
dy = entry[2] - y
dx * dx + dy * dy < 0.000025 ( 0.005 ^ 2 )

Say the NPC, Barrel, Crate, Sack, is at the center (a,b) and the player is at (x,y). I want to calculate that distance. Basically that is what is happening in RangeReticle. I tossed in a plethora of d("") lines to print out information. The mod successfully returned my distance from the center of the circle (a,b) in meters.

I could have been standing on the circle the same "r" distance from (a,b) and RangeReticle calculated the distance correctly. However, when I went to use GetMapPlayerPosition('reticleover') to get the position of what my reticle was on, all the values were 0, not just the Z value, but X and Y also.

Which is why I am wondering if there is another option.

Warning: Spoiler

That is the function I used from RangeReticle to test with. I basically turned it into a function I could pass the arguments to of the Node. So say the Node is a fishing hole, I was passing the locations of all the fishing holes to that function.

Lua Code:
  1. for i = 1, #sv do
  2.         local item = sv[i]
  3.        
  4.         d("Range of loot : " .. getTargetDistance(item[1], item[2]).range)
  5.     end
Just to see what the values were, and what it returned. It returns a nice neat distance of 0 to, oh say 48 meters.

Well that is a lot to calculate, and I could ask permission to use the code, but I want to use my own code. In fact all I really want to use is Standard Form of (x-a)2 + (y-b)2 = r2. I can't get (a,b) from GetMapPlayerPosition('reticleover') unless it's an NPC.

Last edited by Sharlikran : 05/24/14 at 02:27 PM.
  Reply With Quote
05/24/14, 02:26 PM   #5
Sharlikran
 
Sharlikran's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 588
Originally Posted by Tar000un View Post
I think you need to get your position and the target's position in order to get the distance.

Reading the wiki, i saw a (API) Global:ComputeStringDistance(), may that could help.
I saw that too but everything I tried to pass to it gave me specific integers. Like 10, 11, 14, 17. I think 11 was when I had no target. I have no idea what the arguments are.
  Reply With Quote
05/24/14, 02:51 PM   #6
Sharlikran
 
Sharlikran's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 588
I knew if I got my thoughts out in writing it would dawn on me. The player should be (a,b) because that is the reliable position. Only when (x,y) is xxx meters from (a,b) should the action take place.


I need an equation to see if the target is A, which is outside the circle, or B which is inside the circle, and C which is the max distance.


i wonder if i can use teh Heading to determine the segment, and whether or not that is overkill.

Last edited by Sharlikran : 05/24/14 at 02:58 PM.
  Reply With Quote
05/24/14, 03:02 PM   #7
SinusPi
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 18
Originally Posted by Tar000un View Post
Reading the wiki, i saw a (API) Global:ComputeStringDistance(), may that could help.
That's a total red herring - string distance is the difference between two strings, like "tortoise" and "turquoise" would have like 3 differences.
  Reply With Quote
05/24/14, 03:17 PM   #8
Tar000un
 
Tar000un's Avatar
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 47
Originally Posted by SinusPi View Post
That's a total red herring - string distance is the difference between two strings, like "tortoise" and "turquoise" would have like 3 differences.
Olol...
thanks x)

***

If an edge of the sector is the center, you could use a trigo functions.

Originally Posted by Sharlikran View Post

I need an equation to see if the target is A, which is outside the circle, or B which is inside the circle, and C which is the max distance.
Like i understood you, you want to check if A,B,C are in or out range.


And other thing i just got in mind : if you know a A position, which isnt a NPC and disabling the reticleover way, you may try to create a metatable of a Unit, to get a virtual npc with the approriate coords.

But imnt sure if that's possible, because i started to learn metatable today. x)

Last edited by Tar000un : 05/24/14 at 03:40 PM.
  Reply With Quote
05/24/14, 03:45 PM   #9
Garkin
 
Garkin's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 832
You are still talking about meters, but there is no such function that will tell you range in meters. All functions returns normalized position on the selected map - numbers between 0 and 1:
Code:
0,0 --- 0,1
 |       |
 |       |
1,0 --- 1,1
Each map texture has different scale, so you can't use texture size or number of tiles to calculate distance in meters.

I do not know if it is reliable, but you can try to get position relative to the world map. In this case you will need just one scale:
Lua Code:
  1. SetMapToPlayerLocation()
  2. local mapId = GetCurrentMapIndex()
  3. --if current map is subzone or dungeon, mapId is nil
  4. if mapId == nil then
  5.    --select parent map
  6.    MapZoomOut()
  7.    --parent map of both dungeons and subzones is always zone with defined mapId
  8.    --but I never tried it on main quest or guild maps
  9.    mapId = GetCurrentMapIndex()
  10. end
  11.  
  12. local worldsize
  13. --if mapId is 23 it means that current world map is Coldharbour
  14. if mapId ~= 23 then
  15.    --select Tamriel world map. I could use MapZoomOut() once more, but I think this is safer way how to select map
  16.    SetMapToMapListIndex(1)
  17.    worldsize = 33440   --Tamriel size in meters
  18. else
  19.    worldsize = 6000    --Coldharbour size in meters
  20.    --size is untested, I have found it in Zygor's addon
  21. end
  22. local playerX, playerY = GetMapPlayerPosition("player")
  23. local targetX, targetY = GetMapPlayerPosition("reticleover")
  24. --return map back to player
  25. SetMapToPlayerLocation()
  26.  
  27. local dX = targetX - playerX
  28. local dY = targetY - playerY
  29.  
  30. local normalizedDistance = zo_sqrt(dX*dX + dY*dY)
  31.  
  32. local distance = normalizedDistance * worldsize
  33.  
  34. d(zo_strformat("Distance is: <<1>>m", zo_round(distance))
(completely untested code, I have typed it without testing)

Last edited by Garkin : 05/24/14 at 03:48 PM.
  Reply With Quote
05/24/14, 03:53 PM   #10
SinusPi
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 18
Also, the code depending on ZO_WorldMapContainer:GetDimensions() is oddly red-herringed, too - that function simply returns a map's size in pixels, according to the current zoom level, NOT the map's ranges in meters or any other reasonable distance unit.

The solution to all this map-distance trouble is getting each map's (each map texture's, to be exact) dimensions in meters. One can try to gauge that by standing at exactly the range of some known distanced spell, and checking the sqrt((x1-x2)^2+(y1-y2)^2) against that. From there it's possible to approximate the zone's sizes. Or, if you zoom to the world - the world sizes, since GetTargetPosition() still works fine there.

(EDIT) Ah-ha, I see you've found the Zygor distances. They're not perfect, mind you, but work more-or-less. They were found exactly using the above method.
  Reply With Quote
05/24/14, 04:44 PM   #11
Sharlikran
 
Sharlikran's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 588
While you guys were posting your suggestions I was playing with things. I reset the database so I had no data in it. Then I stood in the middle, or what I thought was the middle, and then moved my reticle onto the node to record it. I made it imposible to record another one so I won't have duplicates.



Then I tried to get as far away as I could from it and the range is just the x,y coordinates. I am approximately 0.0002638 distance from that fishing node. The modified function from RangeReticle says I am about 66 meters away from it. Now, Garkin mentioned something I was aware of in that the maps are just 0,0 and 1,1 basically. The current idea you guys have is to get the scale of the map somehow and use that to define the range. So I like that idea.

Since there is no definition in meters I'll take your advice Garkin and try not to use meters. Just for the sake of argument, if there was a way to define it in meters then 66 meters away is too far in my opinion. A user should be much closer before the node is recorded.

Lua Code:
  1. local multiplier = 5.0
  2.         if mapContentType == MAP_CONTENT_NONE then
  3.                 if mapType == MAPTYPE_SUBZONE then
  4.                 elseif mapType == MAPTYPE_ZONE then
  5.                 end
  6.         elseif mapContentType == MAP_CONTENT_AVA then
  7.                 if mapType == MAPTYPE_SUBZONE then
  8.                 elseif mapType == MAPTYPE_ZONE then
  9.                     multiplier = 12.0
  10.                 end
  11.         elseif mapContentType == MAP_CONTENT_DUNGEON then
  12.                 if mapType == MAPTYPE_SUBZONE then
  13.                     dimensionsX, dimensionsY = ZO_WorldMapContainer1:GetDimensions()
  14.                     multiplier = 1.0
  15.                 elseif mapType == MAPTYPE_ZONE then
  16.                 end
  17.         end

That code is taken from RangeReticle also and it does what you guys are suggesting. Depending on the map type there is a modifier for the range. I am going to play with Garkin's code, and this code to see which map types I can use and try to multiply the minDistance by the multiplier based on the map type.

Lua Code:
  1. local mapType = GetMapType()
  2.     local mapContentType = GetMapContentType()
  3.     if (mapType == MAPTYPE_SUBZONE) or (mapContentType == MAP_CONTENT_DUNGEON) then
  4.         Harvest.minDist = 0.00005  -- Larger value for minDist since map is smaller
  5.     elseif (mapContentType == MAP_CONTENT_AVA) then
  6.         Harvest.minDist = 0.00001 -- Smaller value for minDist since map is larger
  7.     else
  8.         Harvest.minDist = 0.000025 -- This is the default value for minDist
  9.     end
Wmrojer suggest this code. Hopefully there is some way to help make small maps and large maps require you to be about the same distance from the object you are interacting with before it's recorded. I wonder if there are like, 10 different map types, but only three different sizes.

Last edited by Sharlikran : 05/24/14 at 04:53 PM.
  Reply With Quote
05/24/14, 05:13 PM   #12
SinusPi
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 18
You'll need every single map scaled differently for that to work, though - the "map type" isn't enough for scaling.
  Reply With Quote
05/25/14, 03:40 PM   #13
lyravega
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 93
Off-topic

Not just the API, but all the code is exposed due to shoddy coding... fyi
  Reply With Quote
05/26/14, 02:18 PM   #14
SinusPi
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 18
Originally Posted by lyravega View Post
Not just the API, but all the code is exposed due to shoddy coding... fyi
Off-topic indeed, and care to elaborate?
  Reply With Quote
10/24/23, 05:19 AM   #15
sinnereso
AddOn Author - Click to view addons
Join Date: Oct 2022
Posts: 243
Question

This is an extreme necro but its the only relevant thread that comes up in google.

Im looking to detect the range of a group unit for mounting purposes. Specifically needing know if theyre within approx 8-10m range but not exactly sure yet until I can properly calculate this. I've been exploring some of the samples listed above and some other stuff I found in a couple other addons but havent got anything to give me a distance only positions.

so far the easiest setup using reticle target for testing I found in an addon "Shadow image range" but doesn't work either.

Code:
local selfZone, selfX, selfY, selfZ = GetUnitWorldPosition('player')
local targetZone, targetX, targetY, targetZ = GetUnitWorldPosition('reticle')
local distance = zo_distance3D(targetX, targetY, targetZ, selfX, selfY, selfZ) / 100
df(tostring(zo_round(distance)))
SetRangeTracker has very similar setup but with this calculation instead:
Code:
local distance = zo_sqrt((selfX - targetX) ^ 2 + (selfY - targetY) ^ 2 + (selfZ - targetZ) ^ 2) / 100
any suggestions?

Last edited by sinnereso : 10/24/23 at 05:43 AM.
  Reply With Quote
10/24/23, 08:28 AM   #16
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,874
Check my accessibility addon FCOAccessibility, function getDistanceToLocalCoords(locX, locY, playerOffsetX, playerOffsetY)
It determines the distance to a group member to write it to the chat for visibly impaired players, so the screen/chat reader reads it out to them.

It uses LibGPS.
e.g. check function getGroupLeaderDistance() to see how it calculates the distance to the group leader.
Should be adoptable for the other group members/unit tags too then.

if you spy and/or use code please provide credit (also to WayshrineIt addon as I have taken my idea from it's code) in your addon description.

Last edited by Baertram : 10/24/23 at 08:31 AM.
  Reply With Quote
10/26/23, 11:47 AM   #17
sinnereso
AddOn Author - Click to view addons
Join Date: Oct 2022
Posts: 243
As an update I've managed to get what I needed working for group members in every zone tested so far with these.

Code:
CHECKING FOR MOUNTABLE:
local isMountable = false
for iD = 1, GetGroupSize() do
		local playerID = GetGroupUnitTagByIndex(iD)
		local playerCharName = GetUnitName(playerID)
		local playerDisplayName = GetUnitDisplayName(playerID)
		local mountedState, hasEnabledGroupMount, hasFreePassengerSlot = GetTargetMountedStateInfo(playerDisplayName)
		if mountedState == MOUNTED_STATE_MOUNT_RIDER and hasEnabledGroupMount and hasFreePassengerSlot then isMountable = true else isMountable = false end
Code:
CHECKING FOR RANGE:
local _, selfX, selfY, selfH = GetUnitWorldPosition("player")
local _, targetX, targetY, targetH = GetUnitWorldPosition(unitID)
local nDistance = zo_distance3D(targetX, targetY, targetH, selfX, selfY, selfH) / 100
Appears to be working flawlessly all day so far

Last edited by sinnereso : 10/26/23 at 12:02 PM.
  Reply With Quote

ESOUI » Developer Discussions » Lua/XML Help » Get position of Target

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off